shapely 1.0__py2.4.egg
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- EGG-INFO/PKG-INFO +173 -0
- EGG-INFO/SOURCES.txt +52 -0
- EGG-INFO/dependency_links.txt +1 -0
- EGG-INFO/not-zip-safe +1 -0
- EGG-INFO/requires.txt +2 -0
- EGG-INFO/top_level.txt +1 -0
- shapely/__init__.py +1 -0
- shapely/__init__.pyc +0 -0
- shapely/geometry/__init__.py +9 -0
- shapely/geometry/__init__.pyc +0 -0
- shapely/geometry/base.py +415 -0
- shapely/geometry/base.pyc +0 -0
- shapely/geometry/collection.py +24 -0
- shapely/geometry/collection.pyc +0 -0
- shapely/geometry/geo.py +35 -0
- shapely/geometry/geo.pyc +0 -0
- shapely/geometry/linestring.py +234 -0
- shapely/geometry/linestring.pyc +0 -0
- shapely/geometry/multilinestring.py +157 -0
- shapely/geometry/multilinestring.pyc +0 -0
- shapely/geometry/multipoint.py +187 -0
- shapely/geometry/multipoint.pyc +0 -0
- shapely/geometry/multipolygon.py +143 -0
- shapely/geometry/multipolygon.pyc +0 -0
- shapely/geometry/point.py +259 -0
- shapely/geometry/point.pyc +0 -0
- shapely/geometry/polygon.py +429 -0
- shapely/geometry/polygon.pyc +0 -0
- shapely/geos.py +80 -0
- shapely/geos.pyc +0 -0
- shapely/iterops.py +56 -0
- shapely/iterops.pyc +0 -0
- shapely/kml.py +0 -0
- shapely/kml.pyc +0 -0
- shapely/predicates.py +58 -0
- shapely/predicates.pyc +0 -0
- shapely/topology.py +66 -0
- shapely/topology.pyc +0 -0
- shapely/wkb.py +40 -0
- shapely/wkb.pyc +0 -0
- shapely/wkt.py +40 -0
- shapely/wkt.pyc +0 -0
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Multi-part collection of polygons.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from ctypes import byref, c_double, c_int, c_void_p, cast, POINTER, pointer
|
|
6
|
+
|
|
7
|
+
from shapely.geos import lgeos
|
|
8
|
+
from shapely.geometry.base import BaseGeometry, GeometrySequence, exceptNull
|
|
9
|
+
from shapely.geometry.polygon import Polygon, geos_polygon_from_py
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def geos_multipolygon_from_py(ob):
|
|
13
|
+
"""ob must be either a sequence or array of sequences or arrays."""
|
|
14
|
+
L = len(ob)
|
|
15
|
+
N = len(ob[0][0][0])
|
|
16
|
+
assert L >= 1
|
|
17
|
+
assert N == 2 or N == 3
|
|
18
|
+
|
|
19
|
+
subs = (c_void_p * L)()
|
|
20
|
+
for l in xrange(L):
|
|
21
|
+
geom, ndims = geos_polygon_from_py(ob[l][0], ob[l][1])
|
|
22
|
+
subs[l] = cast(geom, c_void_p)
|
|
23
|
+
|
|
24
|
+
return (lgeos.GEOSGeom_createCollection(6, subs, L), N)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class MultiPolygon(BaseGeometry):
|
|
28
|
+
|
|
29
|
+
"""a multiple polygon geometry.
|
|
30
|
+
"""
|
|
31
|
+
|
|
32
|
+
def __init__(self, polygons=None):
|
|
33
|
+
"""Initialize.
|
|
34
|
+
|
|
35
|
+
Parameters
|
|
36
|
+
----------
|
|
37
|
+
|
|
38
|
+
polygons : sequence
|
|
39
|
+
A sequence of (shell, holes) tuples where shell is the sequence
|
|
40
|
+
representation of a linear ring (see linearring.py) and holes is
|
|
41
|
+
a sequence of such linear rings.
|
|
42
|
+
|
|
43
|
+
Example
|
|
44
|
+
-------
|
|
45
|
+
>>> geom = MultiPolygon( [
|
|
46
|
+
... (
|
|
47
|
+
... ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)),
|
|
48
|
+
... [((0.1,0.1), (0.1,0.2), (0.2,0.2), (0.2,0.1))]
|
|
49
|
+
... )
|
|
50
|
+
... ] )
|
|
51
|
+
"""
|
|
52
|
+
BaseGeometry.__init__(self)
|
|
53
|
+
|
|
54
|
+
if polygons is None:
|
|
55
|
+
# allow creation of null collections, to support unpickling
|
|
56
|
+
pass
|
|
57
|
+
else:
|
|
58
|
+
self._geom, self._ndim = geos_multipolygon_from_py(polygons)
|
|
59
|
+
|
|
60
|
+
@property
|
|
61
|
+
def __geo_interface__(self):
|
|
62
|
+
allcoords = []
|
|
63
|
+
for geom in self.geoms:
|
|
64
|
+
coords = []
|
|
65
|
+
coords.append(tuple(geom.exterior.coords))
|
|
66
|
+
for hole in geom.interiors:
|
|
67
|
+
coords.append(tuple(hole.coords))
|
|
68
|
+
allcoords.append(coords)
|
|
69
|
+
return {
|
|
70
|
+
'type': 'MultiPolygon',
|
|
71
|
+
'coordinates': allcoords
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
@property
|
|
75
|
+
def ctypes(self):
|
|
76
|
+
raise NotImplementedError, \
|
|
77
|
+
"Multi-part geometries have no ctypes representations"
|
|
78
|
+
|
|
79
|
+
@property
|
|
80
|
+
def __array_interface__(self):
|
|
81
|
+
"""Provide the Numpy array protocol."""
|
|
82
|
+
raise NotImplementedError, \
|
|
83
|
+
"Multi-part geometries do not themselves provide the array interface"
|
|
84
|
+
|
|
85
|
+
@property
|
|
86
|
+
def coords(self):
|
|
87
|
+
raise NotImplementedError, \
|
|
88
|
+
"Multi-part geometries do not provide a coordinate sequence"
|
|
89
|
+
|
|
90
|
+
@property
|
|
91
|
+
@exceptNull
|
|
92
|
+
def geoms(self):
|
|
93
|
+
return GeometrySequence(self, Polygon)
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class MultiPolygonAdapter(MultiPolygon):
|
|
97
|
+
|
|
98
|
+
"""Adapts sequences of sequences or numpy arrays to the multipolygon
|
|
99
|
+
interface.
|
|
100
|
+
"""
|
|
101
|
+
|
|
102
|
+
context = None
|
|
103
|
+
__geom = None
|
|
104
|
+
_owned = False
|
|
105
|
+
|
|
106
|
+
def __init__(self, context):
|
|
107
|
+
self.context = context
|
|
108
|
+
|
|
109
|
+
@property
|
|
110
|
+
def _ndim(self):
|
|
111
|
+
try:
|
|
112
|
+
# From array protocol
|
|
113
|
+
array = self.context[0][0].__array_interface__
|
|
114
|
+
n = array['shape'][1]
|
|
115
|
+
assert n == 2 or n == 3
|
|
116
|
+
return n
|
|
117
|
+
except AttributeError:
|
|
118
|
+
# Fall back on list
|
|
119
|
+
return len(self.context[0][0][0])
|
|
120
|
+
|
|
121
|
+
@property
|
|
122
|
+
def _geom(self):
|
|
123
|
+
"""Keeps the GEOS geometry in synch with the context."""
|
|
124
|
+
if self.__geom is not None:
|
|
125
|
+
lgeos.GEOSGeom_destroy(self.__geom)
|
|
126
|
+
self.__geom = geos_multipolygon_from_py(self.context)[0]
|
|
127
|
+
return self.__geom
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def asMultiPolygon(context):
|
|
131
|
+
"""Factory for MultiLineStringAdapter instances."""
|
|
132
|
+
return MultiPolygonAdapter(context)
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# Test runner
|
|
136
|
+
def _test():
|
|
137
|
+
import doctest
|
|
138
|
+
doctest.testmod()
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
if __name__ == "__main__":
|
|
142
|
+
_test()
|
|
143
|
+
|
|
Binary file
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Points.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from ctypes import string_at, create_string_buffer, \
|
|
6
|
+
c_char_p, c_double, c_float, c_int, c_uint, c_size_t, c_ubyte, \
|
|
7
|
+
c_void_p, byref
|
|
8
|
+
from ctypes import cast, POINTER
|
|
9
|
+
|
|
10
|
+
from shapely.geos import lgeos, DimensionError
|
|
11
|
+
from shapely.geometry.base import BaseGeometry, CoordinateSequence
|
|
12
|
+
from shapely.geometry.base import exceptNull
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def geos_point_from_py(ob, update_geom=None, update_ndim=0):
|
|
16
|
+
"""Create a GEOS geom from an object that is a coordinate sequence
|
|
17
|
+
or that provides the array interface.
|
|
18
|
+
|
|
19
|
+
Returns the GEOS geometry and the number of its dimensions.
|
|
20
|
+
"""
|
|
21
|
+
try:
|
|
22
|
+
# From array protocol
|
|
23
|
+
array = ob.__array_interface__
|
|
24
|
+
assert len(array['shape']) == 1
|
|
25
|
+
n = array['shape'][0]
|
|
26
|
+
assert n == 2 or n == 3
|
|
27
|
+
|
|
28
|
+
cdata = array['data'][0]
|
|
29
|
+
cp = cast(cdata, POINTER(c_double))
|
|
30
|
+
dx = c_double(cp[0])
|
|
31
|
+
dy = c_double(cp[1])
|
|
32
|
+
dz = None
|
|
33
|
+
if n == 3:
|
|
34
|
+
dz = c_double(cp[2])
|
|
35
|
+
ndim = 3
|
|
36
|
+
except AttributeError:
|
|
37
|
+
# Fall back on the case of Python sequence data
|
|
38
|
+
# Accept either (x, y) or [(x, y)]
|
|
39
|
+
if type(ob[0]) == type(tuple()):
|
|
40
|
+
coords = ob[0]
|
|
41
|
+
else:
|
|
42
|
+
coords = ob
|
|
43
|
+
n = len(coords)
|
|
44
|
+
dx = c_double(coords[0])
|
|
45
|
+
dy = c_double(coords[1])
|
|
46
|
+
dz = None
|
|
47
|
+
if n == 3:
|
|
48
|
+
dz = c_double(coords[2])
|
|
49
|
+
|
|
50
|
+
if update_geom:
|
|
51
|
+
cs = lgeos.GEOSGeom_getCoordSeq(update_geom)
|
|
52
|
+
if n != update_ndim:
|
|
53
|
+
raise ValueError, \
|
|
54
|
+
"Wrong coordinate dimensions; this geometry has dimensions: %d" \
|
|
55
|
+
% update_ndim
|
|
56
|
+
else:
|
|
57
|
+
cs = lgeos.GEOSCoordSeq_create(1, n)
|
|
58
|
+
|
|
59
|
+
# Because of a bug in the GEOS C API, always set X before Y
|
|
60
|
+
lgeos.GEOSCoordSeq_setX(cs, 0, dx)
|
|
61
|
+
lgeos.GEOSCoordSeq_setY(cs, 0, dy)
|
|
62
|
+
if n == 3:
|
|
63
|
+
lgeos.GEOSCoordSeq_setZ(cs, 0, dz)
|
|
64
|
+
|
|
65
|
+
if update_geom:
|
|
66
|
+
return None
|
|
67
|
+
else:
|
|
68
|
+
return lgeos.GEOSGeom_createPoint(cs), n
|
|
69
|
+
|
|
70
|
+
def update_point_from_py(geom, ob):
|
|
71
|
+
geos_point_from_py(ob, geom._geom, geom._ndim)
|
|
72
|
+
|
|
73
|
+
|
|
74
|
+
class Point(BaseGeometry):
|
|
75
|
+
|
|
76
|
+
"""A point geometry.
|
|
77
|
+
|
|
78
|
+
Attributes
|
|
79
|
+
----------
|
|
80
|
+
x, y, z : float
|
|
81
|
+
Coordinate values
|
|
82
|
+
|
|
83
|
+
Example
|
|
84
|
+
-------
|
|
85
|
+
>>> p = Point(1.0, -1.0)
|
|
86
|
+
>>> str(p)
|
|
87
|
+
'POINT (1.0000000000000000 -1.0000000000000000)'
|
|
88
|
+
>>> p.y = 0.0
|
|
89
|
+
>>> p.y
|
|
90
|
+
0.0
|
|
91
|
+
>>> p.x
|
|
92
|
+
1.0
|
|
93
|
+
>>> p.array
|
|
94
|
+
[[1.0, 0.0]]
|
|
95
|
+
"""
|
|
96
|
+
|
|
97
|
+
def __init__(self, *args):
|
|
98
|
+
"""This *copies* the given data to a new GEOS geometry.
|
|
99
|
+
|
|
100
|
+
Parameters
|
|
101
|
+
----------
|
|
102
|
+
|
|
103
|
+
There are 2 cases:
|
|
104
|
+
|
|
105
|
+
1) 1 parameter: this must satisfy the numpy array protocol.
|
|
106
|
+
2) 2 or more parameters: x, y, z : float
|
|
107
|
+
Easting, northing, and elevation.
|
|
108
|
+
"""
|
|
109
|
+
BaseGeometry.__init__(self)
|
|
110
|
+
self._init_geom(*args)
|
|
111
|
+
|
|
112
|
+
def _init_geom(self, *args):
|
|
113
|
+
if len(args) == 0:
|
|
114
|
+
# allow creation of null points, to support unpickling
|
|
115
|
+
pass
|
|
116
|
+
else:
|
|
117
|
+
if len(args) == 1:
|
|
118
|
+
self._geom, self._ndim = geos_point_from_py(args[0])
|
|
119
|
+
else:
|
|
120
|
+
self._geom, self._ndim = geos_point_from_py(tuple(args))
|
|
121
|
+
|
|
122
|
+
# Coordinate getters and setters
|
|
123
|
+
|
|
124
|
+
@property
|
|
125
|
+
@exceptNull
|
|
126
|
+
def x(self):
|
|
127
|
+
"""Return x coordinate."""
|
|
128
|
+
cs = lgeos.GEOSGeom_getCoordSeq(self._geom)
|
|
129
|
+
d = c_double()
|
|
130
|
+
lgeos.GEOSCoordSeq_getX(cs, 0, byref(d))
|
|
131
|
+
return d.value
|
|
132
|
+
|
|
133
|
+
@property
|
|
134
|
+
@exceptNull
|
|
135
|
+
def y(self):
|
|
136
|
+
"""Return y coordinate."""
|
|
137
|
+
cs = lgeos.GEOSGeom_getCoordSeq(self._geom)
|
|
138
|
+
d = c_double()
|
|
139
|
+
lgeos.GEOSCoordSeq_getY(cs, 0, byref(d))
|
|
140
|
+
return d.value
|
|
141
|
+
|
|
142
|
+
@property
|
|
143
|
+
@exceptNull
|
|
144
|
+
def z(self):
|
|
145
|
+
"""Return z coordinate."""
|
|
146
|
+
if self._ndim != 3:
|
|
147
|
+
raise DimensionError, "This point has no z coordinate."
|
|
148
|
+
cs = lgeos.GEOSGeom_getCoordSeq(self._geom)
|
|
149
|
+
d = c_double()
|
|
150
|
+
lgeos.GEOSCoordSeq_getZ(cs, 0, byref(d))
|
|
151
|
+
return d.value
|
|
152
|
+
|
|
153
|
+
@property
|
|
154
|
+
@exceptNull
|
|
155
|
+
def __geo_interface__(self):
|
|
156
|
+
return {
|
|
157
|
+
'type': 'Point',
|
|
158
|
+
'coordinates': self.coords[0]
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
@property
|
|
162
|
+
@exceptNull
|
|
163
|
+
def ctypes(self):
|
|
164
|
+
if not self._ctypes_data:
|
|
165
|
+
array_type = c_double * self._ndim
|
|
166
|
+
array = array_type()
|
|
167
|
+
array[0] = self.x
|
|
168
|
+
array[1] = self.y
|
|
169
|
+
if self._ndim == 3:
|
|
170
|
+
array[2] = self.z
|
|
171
|
+
self._ctypes_data = array
|
|
172
|
+
return self._ctypes_data
|
|
173
|
+
|
|
174
|
+
def array_interface(self):
|
|
175
|
+
"""Provide the Numpy array protocol."""
|
|
176
|
+
ai = self.array_interface_base
|
|
177
|
+
ai.update({'shape': (self._ndim,)})
|
|
178
|
+
return ai
|
|
179
|
+
__array_interface__ = property(array_interface)
|
|
180
|
+
|
|
181
|
+
@property
|
|
182
|
+
@exceptNull
|
|
183
|
+
def bounds(self):
|
|
184
|
+
cs = lgeos.GEOSGeom_getCoordSeq(self._geom)
|
|
185
|
+
x = c_double()
|
|
186
|
+
y = c_double()
|
|
187
|
+
lgeos.GEOSCoordSeq_getX(cs, 0, byref(x))
|
|
188
|
+
lgeos.GEOSCoordSeq_getY(cs, 0, byref(y))
|
|
189
|
+
return (x.value, y.value, x.value, y.value)
|
|
190
|
+
|
|
191
|
+
# Coordinate access
|
|
192
|
+
|
|
193
|
+
def set_coords(self, coordinates):
|
|
194
|
+
if self._geom is None:
|
|
195
|
+
self._init_geom(coordinates)
|
|
196
|
+
else:
|
|
197
|
+
update_point_from_py(self, coordinates)
|
|
198
|
+
|
|
199
|
+
coords = property(BaseGeometry.get_coords, set_coords)
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
class PointAdapter(Point):
|
|
203
|
+
|
|
204
|
+
"""Adapts a Python coordinate pair or a numpy array to the point interface.
|
|
205
|
+
"""
|
|
206
|
+
|
|
207
|
+
context = None
|
|
208
|
+
__geom = None
|
|
209
|
+
_owned = False
|
|
210
|
+
|
|
211
|
+
def __init__(self, context):
|
|
212
|
+
self.context = context
|
|
213
|
+
|
|
214
|
+
@property
|
|
215
|
+
def _ndim(self):
|
|
216
|
+
try:
|
|
217
|
+
# From array protocol
|
|
218
|
+
array = self.context.__array_interface__
|
|
219
|
+
n = array['shape'][0]
|
|
220
|
+
assert n == 2 or n == 3
|
|
221
|
+
return n
|
|
222
|
+
except AttributeError:
|
|
223
|
+
# Fall back on list
|
|
224
|
+
return len(self.context)
|
|
225
|
+
|
|
226
|
+
@property
|
|
227
|
+
def _geom(self):
|
|
228
|
+
"""Keeps the GEOS geometry in synch with the context."""
|
|
229
|
+
if self.__geom is not None:
|
|
230
|
+
lgeos.GEOSGeom_destroy(self.__geom)
|
|
231
|
+
self.__geom, n = geos_point_from_py(self.context)
|
|
232
|
+
return self.__geom
|
|
233
|
+
|
|
234
|
+
# TODO: reimplement x, y, z properties without calling invoking _geom
|
|
235
|
+
|
|
236
|
+
@property
|
|
237
|
+
def __array_interface__(self):
|
|
238
|
+
"""Provide the Numpy array protocol."""
|
|
239
|
+
try:
|
|
240
|
+
return self.context.__array_interface__
|
|
241
|
+
except AttributeError:
|
|
242
|
+
return self.array_interface()
|
|
243
|
+
|
|
244
|
+
coords = property(BaseGeometry.get_coords)
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def asPoint(context):
|
|
248
|
+
"""Factory for PointAdapter instances."""
|
|
249
|
+
return PointAdapter(context)
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
# Test runner
|
|
253
|
+
def _test():
|
|
254
|
+
import doctest
|
|
255
|
+
doctest.testmod()
|
|
256
|
+
|
|
257
|
+
if __name__ == "__main__":
|
|
258
|
+
_test()
|
|
259
|
+
|
|
Binary file
|