shapely 1.2.8__py2.7-win-amd64.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.
- DLLs/geos.dll +0 -0
- DLLs/geos_c.dll +0 -0
- EGG-INFO/PKG-INFO +173 -0
- EGG-INFO/not-zip-safe +1 -0
- EGG-INFO/scripts/dissolve.py +53 -0
- EGG-INFO/scripts/intersect.py +81 -0
- shapely/__init__.py +1 -0
- shapely/__init__.pyc +0 -0
- shapely/coords.py +167 -0
- shapely/coords.pyc +0 -0
- shapely/ctypes_declarations.py +279 -0
- shapely/ctypes_declarations.pyc +0 -0
- shapely/ftools.py +78 -0
- shapely/ftools.pyc +0 -0
- shapely/geometry/__init__.py +20 -0
- shapely/geometry/__init__.pyc +0 -0
- shapely/geometry/base.py +595 -0
- shapely/geometry/base.pyc +0 -0
- shapely/geometry/collection.py +43 -0
- shapely/geometry/collection.pyc +0 -0
- shapely/geometry/geo.py +68 -0
- shapely/geometry/geo.pyc +0 -0
- shapely/geometry/linestring.py +259 -0
- shapely/geometry/linestring.pyc +0 -0
- shapely/geometry/multilinestring.py +133 -0
- shapely/geometry/multilinestring.pyc +0 -0
- shapely/geometry/multipoint.py +180 -0
- shapely/geometry/multipoint.pyc +0 -0
- shapely/geometry/multipolygon.py +154 -0
- shapely/geometry/multipolygon.pyc +0 -0
- shapely/geometry/point.py +241 -0
- shapely/geometry/point.pyc +0 -0
- shapely/geometry/polygon.py +449 -0
- shapely/geometry/polygon.pyc +0 -0
- shapely/geometry/proxy.py +54 -0
- shapely/geometry/proxy.pyc +0 -0
- shapely/geos.py +373 -0
- shapely/geos.pyc +0 -0
- shapely/impl.py +119 -0
- shapely/impl.pyc +0 -0
- shapely/iterops.py +53 -0
- shapely/iterops.pyc +0 -0
- shapely/linref.py +26 -0
- shapely/linref.pyc +0 -0
- shapely/ops.py +87 -0
- shapely/ops.pyc +0 -0
- shapely/predicates.py +24 -0
- shapely/predicates.pyc +0 -0
- shapely/prepared.py +58 -0
- shapely/prepared.pyc +0 -0
- shapely/topology.py +62 -0
- shapely/topology.pyc +0 -0
- shapely/validation.py +7 -0
- shapely/validation.pyc +0 -0
- shapely/wkb.py +39 -0
- shapely/wkb.pyc +0 -0
- shapely/wkt.py +34 -0
- shapely/wkt.pyc +0 -0
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
"""Collections of polygons and related utilities
|
|
2
|
+
"""
|
|
3
|
+
|
|
4
|
+
from ctypes import c_void_p, cast
|
|
5
|
+
|
|
6
|
+
from shapely.geos import lgeos
|
|
7
|
+
from shapely.geometry.base import BaseMultipartGeometry
|
|
8
|
+
from shapely.geometry.polygon import Polygon, geos_polygon_from_py
|
|
9
|
+
from shapely.geometry.proxy import CachingGeometryProxy
|
|
10
|
+
|
|
11
|
+
__all__ = ['MultiPolygon', 'asMultiPolygon']
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class MultiPolygon(BaseMultipartGeometry):
|
|
15
|
+
|
|
16
|
+
"""A collection of one or more polygons
|
|
17
|
+
|
|
18
|
+
If component polygons overlap the collection is `invalid` and some
|
|
19
|
+
operations on it may fail.
|
|
20
|
+
|
|
21
|
+
Attributes
|
|
22
|
+
----------
|
|
23
|
+
geoms : sequence
|
|
24
|
+
A sequence of `Polygon` instances
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
def __init__(self, polygons=None, context_type='polygons'):
|
|
28
|
+
"""
|
|
29
|
+
Parameters
|
|
30
|
+
----------
|
|
31
|
+
polygons : sequence
|
|
32
|
+
A sequence of (shell, holes) tuples where shell is the sequence
|
|
33
|
+
representation of a linear ring (see linearring.py) and holes is
|
|
34
|
+
a sequence of such linear rings
|
|
35
|
+
|
|
36
|
+
Example
|
|
37
|
+
-------
|
|
38
|
+
Construct a collection from a sequence of coordinate tuples
|
|
39
|
+
|
|
40
|
+
>>> ob = MultiPolygon( [
|
|
41
|
+
... (
|
|
42
|
+
... ((0.0, 0.0), (0.0, 1.0), (1.0, 1.0), (1.0, 0.0)),
|
|
43
|
+
... [((0.1,0.1), (0.1,0.2), (0.2,0.2), (0.2,0.1))]
|
|
44
|
+
... )
|
|
45
|
+
... ] )
|
|
46
|
+
>>> len(ob.geoms)
|
|
47
|
+
1
|
|
48
|
+
>>> type(ob.geoms[0]) == Polygon
|
|
49
|
+
True
|
|
50
|
+
"""
|
|
51
|
+
super(MultiPolygon, self).__init__()
|
|
52
|
+
|
|
53
|
+
if polygons is None:
|
|
54
|
+
# allow creation of null collections, to support unpickling
|
|
55
|
+
pass
|
|
56
|
+
elif context_type == 'polygons':
|
|
57
|
+
self._geom, self._ndim = geos_multipolygon_from_polygons(polygons)
|
|
58
|
+
elif context_type == 'geojson':
|
|
59
|
+
self._geom, self._ndim = geos_multipolygon_from_py(polygons)
|
|
60
|
+
|
|
61
|
+
def shape_factory(self, *args):
|
|
62
|
+
return Polygon(*args)
|
|
63
|
+
|
|
64
|
+
@property
|
|
65
|
+
def __geo_interface__(self):
|
|
66
|
+
allcoords = []
|
|
67
|
+
for geom in self.geoms:
|
|
68
|
+
coords = []
|
|
69
|
+
coords.append(tuple(geom.exterior.coords))
|
|
70
|
+
for hole in geom.interiors:
|
|
71
|
+
coords.append(tuple(hole.coords))
|
|
72
|
+
allcoords.append(coords)
|
|
73
|
+
return {
|
|
74
|
+
'type': 'MultiPolygon',
|
|
75
|
+
'coordinates': allcoords
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
class MultiPolygonAdapter(CachingGeometryProxy, MultiPolygon):
|
|
80
|
+
|
|
81
|
+
context = None
|
|
82
|
+
_owned = False
|
|
83
|
+
|
|
84
|
+
def __init__(self, context, context_type='polygons'):
|
|
85
|
+
self.context = context
|
|
86
|
+
if context_type == 'geojson':
|
|
87
|
+
self.factory = geos_multipolygon_from_py
|
|
88
|
+
elif context_type == 'polygons':
|
|
89
|
+
self.factory = geos_multipolygon_from_polygons
|
|
90
|
+
|
|
91
|
+
@property
|
|
92
|
+
def _ndim(self):
|
|
93
|
+
try:
|
|
94
|
+
# From array protocol
|
|
95
|
+
array = self.context[0][0].__array_interface__
|
|
96
|
+
n = array['shape'][1]
|
|
97
|
+
assert n == 2 or n == 3
|
|
98
|
+
return n
|
|
99
|
+
except AttributeError:
|
|
100
|
+
# Fall back on list
|
|
101
|
+
return len(self.context[0][0][0])
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
def asMultiPolygon(context):
|
|
105
|
+
"""Adapts a sequence of objects to the MultiPolygon interface"""
|
|
106
|
+
return MultiPolygonAdapter(context)
|
|
107
|
+
|
|
108
|
+
|
|
109
|
+
def geos_multipolygon_from_py(ob):
|
|
110
|
+
"""ob must provide Python geo interface coordinates."""
|
|
111
|
+
L = len(ob)
|
|
112
|
+
N = len(ob[0][0][0])
|
|
113
|
+
assert L >= 1
|
|
114
|
+
assert N == 2 or N == 3
|
|
115
|
+
|
|
116
|
+
subs = (c_void_p * L)()
|
|
117
|
+
for l in xrange(L):
|
|
118
|
+
geom, ndims = geos_polygon_from_py(ob[l][0], ob[l][1:])
|
|
119
|
+
subs[l] = cast(geom, c_void_p)
|
|
120
|
+
|
|
121
|
+
return (lgeos.GEOSGeom_createCollection(6, subs, L), N)
|
|
122
|
+
|
|
123
|
+
def geos_multipolygon_from_polygons(ob):
|
|
124
|
+
"""ob must be either a sequence or array of sequences or arrays."""
|
|
125
|
+
obs = getattr(ob, 'geoms', None) or ob
|
|
126
|
+
L = len(obs)
|
|
127
|
+
exemplar = obs[0]
|
|
128
|
+
try:
|
|
129
|
+
N = len(exemplar[0][0])
|
|
130
|
+
except TypeError:
|
|
131
|
+
N = exemplar._ndim
|
|
132
|
+
assert L >= 1
|
|
133
|
+
assert N == 2 or N == 3
|
|
134
|
+
|
|
135
|
+
subs = (c_void_p * L)()
|
|
136
|
+
for l in xrange(L):
|
|
137
|
+
shell = getattr(obs[l], 'exterior', None)
|
|
138
|
+
if shell is None:
|
|
139
|
+
shell = obs[l][0]
|
|
140
|
+
holes = getattr(obs[l], 'interiors', None)
|
|
141
|
+
if holes is None:
|
|
142
|
+
holes = obs[l][1]
|
|
143
|
+
geom, ndims = geos_polygon_from_py(shell, holes)
|
|
144
|
+
subs[l] = cast(geom, c_void_p)
|
|
145
|
+
|
|
146
|
+
return (lgeos.GEOSGeom_createCollection(6, subs, L), N)
|
|
147
|
+
|
|
148
|
+
# Test runner
|
|
149
|
+
def _test():
|
|
150
|
+
import doctest
|
|
151
|
+
doctest.testmod()
|
|
152
|
+
|
|
153
|
+
if __name__ == "__main__":
|
|
154
|
+
_test()
|
|
Binary file
|
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
"""Points and related utilities
|
|
2
|
+
"""
|
|
3
|
+
|
|
4
|
+
from ctypes import c_double
|
|
5
|
+
from ctypes import cast, POINTER
|
|
6
|
+
|
|
7
|
+
from shapely.geos import lgeos, DimensionError
|
|
8
|
+
from shapely.geometry.base import BaseGeometry
|
|
9
|
+
from shapely.geometry.proxy import CachingGeometryProxy
|
|
10
|
+
|
|
11
|
+
__all__ = ['Point', 'asPoint']
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class Point(BaseGeometry):
|
|
15
|
+
"""
|
|
16
|
+
A zero dimensional feature
|
|
17
|
+
|
|
18
|
+
A point has zero length and zero area.
|
|
19
|
+
|
|
20
|
+
Attributes
|
|
21
|
+
----------
|
|
22
|
+
x, y, z : float
|
|
23
|
+
Coordinate values
|
|
24
|
+
|
|
25
|
+
Example
|
|
26
|
+
-------
|
|
27
|
+
|
|
28
|
+
>>> p = Point(1.0, -1.0)
|
|
29
|
+
>>> print p
|
|
30
|
+
POINT (1.0000000000000000 -1.0000000000000000)
|
|
31
|
+
>>> p.y
|
|
32
|
+
-1.0
|
|
33
|
+
>>> p.x
|
|
34
|
+
1.0
|
|
35
|
+
"""
|
|
36
|
+
|
|
37
|
+
def __init__(self, *args):
|
|
38
|
+
"""
|
|
39
|
+
Parameters
|
|
40
|
+
----------
|
|
41
|
+
There are 2 cases:
|
|
42
|
+
|
|
43
|
+
1) 1 parameter: this must satisfy the numpy array protocol.
|
|
44
|
+
2) 2 or more parameters: x, y, z : float
|
|
45
|
+
Easting, northing, and elevation.
|
|
46
|
+
"""
|
|
47
|
+
BaseGeometry.__init__(self)
|
|
48
|
+
if len(args) > 0:
|
|
49
|
+
self._set_coords(*args)
|
|
50
|
+
|
|
51
|
+
# Coordinate getters and setters
|
|
52
|
+
|
|
53
|
+
@property
|
|
54
|
+
def x(self):
|
|
55
|
+
"""Return x coordinate."""
|
|
56
|
+
return self.coords[0][0]
|
|
57
|
+
|
|
58
|
+
@property
|
|
59
|
+
def y(self):
|
|
60
|
+
"""Return y coordinate."""
|
|
61
|
+
return self.coords[0][1]
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def z(self):
|
|
65
|
+
"""Return z coordinate."""
|
|
66
|
+
if self._ndim != 3:
|
|
67
|
+
raise DimensionError("This point has no z coordinate.")
|
|
68
|
+
return self.coords[0][2]
|
|
69
|
+
|
|
70
|
+
@property
|
|
71
|
+
def __geo_interface__(self):
|
|
72
|
+
return {
|
|
73
|
+
'type': 'Point',
|
|
74
|
+
'coordinates': self.coords[0]
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
@property
|
|
78
|
+
def ctypes(self):
|
|
79
|
+
if not self._ctypes_data:
|
|
80
|
+
array_type = c_double * self._ndim
|
|
81
|
+
array = array_type()
|
|
82
|
+
xy = self.coords[0]
|
|
83
|
+
array[0] = xy[0]
|
|
84
|
+
array[1] = xy[1]
|
|
85
|
+
if self._ndim == 3:
|
|
86
|
+
array[2] = xy[2]
|
|
87
|
+
self._ctypes_data = array
|
|
88
|
+
return self._ctypes_data
|
|
89
|
+
|
|
90
|
+
def array_interface(self):
|
|
91
|
+
"""Provide the Numpy array protocol."""
|
|
92
|
+
ai = self.array_interface_base
|
|
93
|
+
ai.update({'shape': (self._ndim,)})
|
|
94
|
+
return ai
|
|
95
|
+
__array_interface__ = property(array_interface)
|
|
96
|
+
|
|
97
|
+
@property
|
|
98
|
+
def bounds(self):
|
|
99
|
+
xy = self.coords[0]
|
|
100
|
+
return (xy[0], xy[1], xy[0], xy[1])
|
|
101
|
+
|
|
102
|
+
# Coordinate access
|
|
103
|
+
|
|
104
|
+
def _set_coords(self, *args):
|
|
105
|
+
self.empty()
|
|
106
|
+
if len(args) == 1:
|
|
107
|
+
self._geom, self._ndim = geos_point_from_py(args[0])
|
|
108
|
+
else:
|
|
109
|
+
self._geom, self._ndim = geos_point_from_py(tuple(args))
|
|
110
|
+
|
|
111
|
+
coords = property(BaseGeometry._get_coords, _set_coords)
|
|
112
|
+
|
|
113
|
+
@property
|
|
114
|
+
def xy(self):
|
|
115
|
+
"""Separate arrays of X and Y coordinate values
|
|
116
|
+
|
|
117
|
+
Example:
|
|
118
|
+
|
|
119
|
+
>>> x, y = Point(0, 0).xy
|
|
120
|
+
>>> list(x)
|
|
121
|
+
[0.0]
|
|
122
|
+
>>> list(y)
|
|
123
|
+
[0.0]
|
|
124
|
+
"""
|
|
125
|
+
return self.coords.xy
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
class PointAdapter(CachingGeometryProxy, Point):
|
|
129
|
+
|
|
130
|
+
_owned = False
|
|
131
|
+
|
|
132
|
+
def __init__(self, context):
|
|
133
|
+
self.context = context
|
|
134
|
+
self.factory = geos_point_from_py
|
|
135
|
+
|
|
136
|
+
@property
|
|
137
|
+
def _ndim(self):
|
|
138
|
+
try:
|
|
139
|
+
# From array protocol
|
|
140
|
+
array = self.context.__array_interface__
|
|
141
|
+
n = array['shape'][0]
|
|
142
|
+
assert n == 2 or n == 3
|
|
143
|
+
return n
|
|
144
|
+
except AttributeError:
|
|
145
|
+
# Fall back on list
|
|
146
|
+
return len(self.context)
|
|
147
|
+
|
|
148
|
+
@property
|
|
149
|
+
def __array_interface__(self):
|
|
150
|
+
"""Provide the Numpy array protocol."""
|
|
151
|
+
try:
|
|
152
|
+
return self.context.__array_interface__
|
|
153
|
+
except AttributeError:
|
|
154
|
+
return self.array_interface()
|
|
155
|
+
|
|
156
|
+
_get_coords = BaseGeometry._get_coords
|
|
157
|
+
|
|
158
|
+
def _set_coords(self, ob):
|
|
159
|
+
raise NotImplementedError("Adapters can not modify their sources")
|
|
160
|
+
|
|
161
|
+
coords = property(_get_coords)
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
def asPoint(context):
|
|
165
|
+
"""Adapt an object to the Point interface"""
|
|
166
|
+
return PointAdapter(context)
|
|
167
|
+
|
|
168
|
+
|
|
169
|
+
def geos_point_from_py(ob, update_geom=None, update_ndim=0):
|
|
170
|
+
"""Create a GEOS geom from an object that is a coordinate sequence
|
|
171
|
+
or that provides the array interface.
|
|
172
|
+
|
|
173
|
+
Returns the GEOS geometry and the number of its dimensions.
|
|
174
|
+
"""
|
|
175
|
+
try:
|
|
176
|
+
# From array protocol
|
|
177
|
+
array = ob.__array_interface__
|
|
178
|
+
assert len(array['shape']) == 1
|
|
179
|
+
n = array['shape'][0]
|
|
180
|
+
assert n == 2 or n == 3
|
|
181
|
+
|
|
182
|
+
dz = None
|
|
183
|
+
da = array['data']
|
|
184
|
+
if type(da) == type((0,)):
|
|
185
|
+
cdata = da[0]
|
|
186
|
+
cp = cast(cdata, POINTER(c_double))
|
|
187
|
+
dx = c_double(cp[0])
|
|
188
|
+
dy = c_double(cp[1])
|
|
189
|
+
if n == 3:
|
|
190
|
+
dz = c_double(cp[2])
|
|
191
|
+
ndim = 3
|
|
192
|
+
else:
|
|
193
|
+
dx, dy = da[0:2]
|
|
194
|
+
if n == 3:
|
|
195
|
+
dz = da[2]
|
|
196
|
+
ndim = 3
|
|
197
|
+
|
|
198
|
+
except AttributeError:
|
|
199
|
+
# Fall back on the case of Python sequence data
|
|
200
|
+
# Accept either (x, y) or [(x, y)]
|
|
201
|
+
if type(ob[0]) == type(tuple()):
|
|
202
|
+
coords = ob[0]
|
|
203
|
+
else:
|
|
204
|
+
coords = ob
|
|
205
|
+
n = len(coords)
|
|
206
|
+
dx = c_double(coords[0])
|
|
207
|
+
dy = c_double(coords[1])
|
|
208
|
+
dz = None
|
|
209
|
+
if n == 3:
|
|
210
|
+
dz = c_double(coords[2])
|
|
211
|
+
|
|
212
|
+
if update_geom:
|
|
213
|
+
cs = lgeos.GEOSGeom_getCoordSeq(update_geom)
|
|
214
|
+
if n != update_ndim:
|
|
215
|
+
raise ValueError(
|
|
216
|
+
"Wrong coordinate dimensions; this geometry has dimensions: %d" \
|
|
217
|
+
% update_ndim)
|
|
218
|
+
else:
|
|
219
|
+
cs = lgeos.GEOSCoordSeq_create(1, n)
|
|
220
|
+
|
|
221
|
+
# Because of a bug in the GEOS C API, always set X before Y
|
|
222
|
+
lgeos.GEOSCoordSeq_setX(cs, 0, dx)
|
|
223
|
+
lgeos.GEOSCoordSeq_setY(cs, 0, dy)
|
|
224
|
+
if n == 3:
|
|
225
|
+
lgeos.GEOSCoordSeq_setZ(cs, 0, dz)
|
|
226
|
+
|
|
227
|
+
if update_geom:
|
|
228
|
+
return None
|
|
229
|
+
else:
|
|
230
|
+
return lgeos.GEOSGeom_createPoint(cs), n
|
|
231
|
+
|
|
232
|
+
def update_point_from_py(geom, ob):
|
|
233
|
+
geos_point_from_py(ob, geom._geom, geom._ndim)
|
|
234
|
+
|
|
235
|
+
# Test runner
|
|
236
|
+
def _test():
|
|
237
|
+
import doctest
|
|
238
|
+
doctest.testmod()
|
|
239
|
+
|
|
240
|
+
if __name__ == "__main__":
|
|
241
|
+
_test()
|
|
Binary file
|