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.
Files changed (58) hide show
  1. DLLs/geos.dll +0 -0
  2. DLLs/geos_c.dll +0 -0
  3. EGG-INFO/PKG-INFO +173 -0
  4. EGG-INFO/not-zip-safe +1 -0
  5. EGG-INFO/scripts/dissolve.py +53 -0
  6. EGG-INFO/scripts/intersect.py +81 -0
  7. shapely/__init__.py +1 -0
  8. shapely/__init__.pyc +0 -0
  9. shapely/coords.py +167 -0
  10. shapely/coords.pyc +0 -0
  11. shapely/ctypes_declarations.py +279 -0
  12. shapely/ctypes_declarations.pyc +0 -0
  13. shapely/ftools.py +78 -0
  14. shapely/ftools.pyc +0 -0
  15. shapely/geometry/__init__.py +20 -0
  16. shapely/geometry/__init__.pyc +0 -0
  17. shapely/geometry/base.py +595 -0
  18. shapely/geometry/base.pyc +0 -0
  19. shapely/geometry/collection.py +43 -0
  20. shapely/geometry/collection.pyc +0 -0
  21. shapely/geometry/geo.py +68 -0
  22. shapely/geometry/geo.pyc +0 -0
  23. shapely/geometry/linestring.py +259 -0
  24. shapely/geometry/linestring.pyc +0 -0
  25. shapely/geometry/multilinestring.py +133 -0
  26. shapely/geometry/multilinestring.pyc +0 -0
  27. shapely/geometry/multipoint.py +180 -0
  28. shapely/geometry/multipoint.pyc +0 -0
  29. shapely/geometry/multipolygon.py +154 -0
  30. shapely/geometry/multipolygon.pyc +0 -0
  31. shapely/geometry/point.py +241 -0
  32. shapely/geometry/point.pyc +0 -0
  33. shapely/geometry/polygon.py +449 -0
  34. shapely/geometry/polygon.pyc +0 -0
  35. shapely/geometry/proxy.py +54 -0
  36. shapely/geometry/proxy.pyc +0 -0
  37. shapely/geos.py +373 -0
  38. shapely/geos.pyc +0 -0
  39. shapely/impl.py +119 -0
  40. shapely/impl.pyc +0 -0
  41. shapely/iterops.py +53 -0
  42. shapely/iterops.pyc +0 -0
  43. shapely/linref.py +26 -0
  44. shapely/linref.pyc +0 -0
  45. shapely/ops.py +87 -0
  46. shapely/ops.pyc +0 -0
  47. shapely/predicates.py +24 -0
  48. shapely/predicates.pyc +0 -0
  49. shapely/prepared.py +58 -0
  50. shapely/prepared.pyc +0 -0
  51. shapely/topology.py +62 -0
  52. shapely/topology.pyc +0 -0
  53. shapely/validation.py +7 -0
  54. shapely/validation.pyc +0 -0
  55. shapely/wkb.py +39 -0
  56. shapely/wkb.pyc +0 -0
  57. shapely/wkt.py +34 -0
  58. shapely/wkt.pyc +0 -0
@@ -0,0 +1,449 @@
1
+ """Polygons and their linear ring components
2
+ """
3
+
4
+ from ctypes import c_double, c_void_p, cast, POINTER
5
+ from ctypes import ArgumentError
6
+ import weakref
7
+ from shapely.geos import lgeos
8
+ from shapely.geometry.base import BaseGeometry
9
+ from shapely.geometry.linestring import LineString, LineStringAdapter
10
+ from shapely.geometry.proxy import PolygonProxy
11
+
12
+ __all__ = ['Polygon', 'asPolygon', 'LinearRing', 'asLinearRing']
13
+
14
+
15
+ class LinearRing(LineString):
16
+ """
17
+ A closed one-dimensional feature comprising one or more line segments
18
+
19
+ A LinearRing that crosses itself or touches itself at a single point is
20
+ invalid and operations on it may fail.
21
+ """
22
+
23
+ def __init__(self, coordinates=None):
24
+ """
25
+ Parameters
26
+ ----------
27
+ coordinates : sequence
28
+ A sequence of (x, y [,z]) numeric coordinate pairs or triples
29
+
30
+ Rings are implicitly closed. There is no need to specific a final
31
+ coordinate pair identical to the first.
32
+
33
+ Example
34
+ -------
35
+ Construct a square ring.
36
+
37
+ >>> ring = LinearRing( ((0, 0), (0, 1), (1 ,1 ), (1 , 0)) )
38
+ >>> ring.is_closed
39
+ True
40
+ >>> ring.length
41
+ 4.0
42
+ """
43
+ BaseGeometry.__init__(self)
44
+ if coordinates is not None:
45
+ self._set_coords(coordinates)
46
+
47
+ @property
48
+ def __geo_interface__(self):
49
+ return {
50
+ 'type': 'LinearRing',
51
+ 'coordinates': tuple(self.coords)
52
+ }
53
+
54
+ # Coordinate access
55
+
56
+ _get_coords = BaseGeometry._get_coords
57
+
58
+ def _set_coords(self, coordinates):
59
+ self.empty()
60
+ self._geom, self._ndim = geos_linearring_from_py(coordinates)
61
+
62
+ coords = property(_get_coords, _set_coords)
63
+
64
+
65
+ class LinearRingAdapter(LineStringAdapter):
66
+
67
+ __p__ = None
68
+
69
+ def __init__(self, context):
70
+ self.context = context
71
+ self.factory = geos_linearring_from_py
72
+
73
+ @property
74
+ def __geo_interface__(self):
75
+ return {
76
+ 'type': 'LinearRing',
77
+ 'coordinates': tuple(self.coords)
78
+ }
79
+
80
+ coords = property(BaseGeometry._get_coords)
81
+
82
+
83
+ def asLinearRing(context):
84
+ """Adapt an object to the LinearRing interface"""
85
+ return LinearRingAdapter(context)
86
+
87
+
88
+ class InteriorRingSequence(object):
89
+
90
+ _factory = None
91
+ _geom = None
92
+ __p__ = None
93
+ _ndim = None
94
+ _index = 0
95
+ _length = 0
96
+ __rings__ = None
97
+ _gtag = None
98
+
99
+ def __init__(self, parent):
100
+ self.__p__ = parent
101
+ self._geom = parent._geom
102
+ self._ndim = parent._ndim
103
+
104
+ def __iter__(self):
105
+ self._index = 0
106
+ self._length = self.__len__()
107
+ return self
108
+
109
+ def next(self):
110
+ if self._index < self._length:
111
+ ring = self._get_ring(self._index)
112
+ self._index += 1
113
+ return ring
114
+ else:
115
+ raise StopIteration
116
+
117
+ def __len__(self):
118
+ return lgeos.GEOSGetNumInteriorRings(self._geom)
119
+
120
+ def __getitem__(self, i):
121
+ M = self.__len__()
122
+ if i + M < 0 or i >= M:
123
+ raise IndexError("index out of range")
124
+ if i < 0:
125
+ ii = M + i
126
+ else:
127
+ ii = i
128
+ return self._get_ring(i)
129
+
130
+ @property
131
+ def _longest(self):
132
+ max = 0
133
+ for g in iter(self):
134
+ l = len(g.coords)
135
+ if l > max:
136
+ max = l
137
+
138
+ def gtag(self):
139
+ return hash(repr(self.__p__))
140
+
141
+ def _get_ring(self, i):
142
+ gtag = self.gtag()
143
+ if gtag != self._gtag:
144
+ self.__rings__ = {}
145
+ if i not in self.__rings__:
146
+ g = lgeos.GEOSGetInteriorRingN(self._geom, i)
147
+ ring = LinearRing()
148
+ ring.__geom__ = g
149
+ ring.__p__ = self
150
+ ring._owned = True
151
+ ring._ndim = self._ndim
152
+ self.__rings__[i] = weakref.ref(ring)
153
+ return self.__rings__[i]()
154
+
155
+
156
+ class Polygon(BaseGeometry):
157
+ """
158
+ A two-dimensional figure bounded by a linear ring
159
+
160
+ A polygon has a non-zero area. It may have one or more negative-space
161
+ "holes" which are also bounded by linear rings. If any rings cross each
162
+ other, the feature is invalid and operations on it may fail.
163
+
164
+ Attributes
165
+ ----------
166
+ exterior : LinearRing
167
+ The ring which bounds the positive space of the polygon.
168
+ interiors : sequence
169
+ A sequence of rings which bound all existing holes.
170
+ """
171
+
172
+ _exterior = None
173
+ _interiors = []
174
+ _ndim = 2
175
+
176
+ def __init__(self, shell=None, holes=None):
177
+ """
178
+ Parameters
179
+ ----------
180
+ shell : sequence
181
+ A sequence of (x, y [,z]) numeric coordinate pairs or triples
182
+ holes : sequence
183
+ A sequence of objects which satisfy the same requirements as the
184
+ shell parameters above
185
+
186
+ Example
187
+ -------
188
+ Create a square polygon with no holes
189
+
190
+ >>> coords = ((0., 0.), (0., 1.), (1., 1.), (1., 0.), (0., 0.))
191
+ >>> polygon = Polygon(coords)
192
+ >>> polygon.area
193
+ 1.0
194
+ """
195
+ BaseGeometry.__init__(self)
196
+
197
+ if shell is not None:
198
+ self._geom, self._ndim = geos_polygon_from_py(shell, holes)
199
+
200
+ @property
201
+ def exterior(self):
202
+ if self.is_empty:
203
+ return None
204
+ elif self._exterior is None or self._exterior() is None:
205
+ g = lgeos.GEOSGetExteriorRing(self._geom)
206
+ ring = LinearRing()
207
+ ring.__geom__ = g
208
+ ring.__p__ = self
209
+ ring._owned = True
210
+ ring._ndim = self._ndim
211
+ self._exterior = weakref.ref(ring)
212
+ return self._exterior()
213
+
214
+ @property
215
+ def interiors(self):
216
+ if self.is_empty:
217
+ return []
218
+ return InteriorRingSequence(self)
219
+
220
+ @property
221
+ def ctypes(self):
222
+ if not self._ctypes_data:
223
+ self._ctypes_data = self.exterior.ctypes
224
+ return self._ctypes_data
225
+
226
+ @property
227
+ def __array_interface__(self):
228
+ raise NotImplementedError(
229
+ "A polygon does not itself provide the array interface. Its rings do.")
230
+
231
+ def _get_coords(self):
232
+ raise NotImplementedError(
233
+ "Component rings have coordinate sequences, but the polygon does not")
234
+
235
+ def _set_coords(self, ob):
236
+ raise NotImplementedError(
237
+ "Component rings have coordinate sequences, but the polygon does not")
238
+
239
+ @property
240
+ def coords(self):
241
+ raise NotImplementedError(
242
+ "Component rings have coordinate sequences, but the polygon does not")
243
+
244
+ @property
245
+ def __geo_interface__(self):
246
+ coords = [tuple(self.exterior.coords)]
247
+ for hole in self.interiors:
248
+ coords.append(tuple(hole.coords))
249
+ return {
250
+ 'type': 'Polygon',
251
+ 'coordinates': tuple(coords)
252
+ }
253
+
254
+
255
+ class PolygonAdapter(PolygonProxy, Polygon):
256
+
257
+ def __init__(self, shell, holes=None):
258
+ self.shell = shell
259
+ self.holes = holes
260
+ self.context = (shell, holes)
261
+ self.factory = geos_polygon_from_py
262
+
263
+ @property
264
+ def _ndim(self):
265
+ try:
266
+ # From array protocol
267
+ array = self.shell.__array_interface__
268
+ n = array['shape'][1]
269
+ assert n == 2 or n == 3
270
+ return n
271
+ except AttributeError:
272
+ # Fall back on list
273
+ return len(self.shell[0])
274
+
275
+
276
+ def asPolygon(shell, holes=None):
277
+ """Adapt objects to the Polygon interface"""
278
+ return PolygonAdapter(shell, holes)
279
+
280
+
281
+ def geos_linearring_from_py(ob, update_geom=None, update_ndim=0):
282
+ try:
283
+ # From array protocol
284
+ array = ob.__array_interface__
285
+ assert len(array['shape']) == 2
286
+ m = array['shape'][0]
287
+ n = array['shape'][1]
288
+ if m < 3:
289
+ raise ValueError(
290
+ "A LinearRing must have at least 3 coordinate tuples")
291
+ assert n == 2 or n == 3
292
+
293
+ # Make pointer to the coordinate array
294
+ try:
295
+ cp = cast(array['data'][0], POINTER(c_double))
296
+ except ArgumentError:
297
+ cp = array['data']
298
+
299
+ # Add closing coordinates to sequence?
300
+ if cp[0] != cp[m*n-n] or cp[1] != cp[m*n-n+1]:
301
+ M = m + 1
302
+ else:
303
+ M = m
304
+
305
+ # Create a coordinate sequence
306
+ if update_geom is not None:
307
+ cs = lgeos.GEOSGeom_getCoordSeq(update_geom)
308
+ if n != update_ndim:
309
+ raise ValueError(
310
+ "Wrong coordinate dimensions; this geometry has dimensions: %d" \
311
+ % update_ndim)
312
+ else:
313
+ cs = lgeos.GEOSCoordSeq_create(M, n)
314
+
315
+ # add to coordinate sequence
316
+ for i in xrange(m):
317
+ dx = c_double(cp[n*i])
318
+ dy = c_double(cp[n*i+1])
319
+ dz = None
320
+ if n == 3:
321
+ dz = c_double(cp[n*i+2])
322
+
323
+ # Because of a bug in the GEOS C API,
324
+ # always set X before Y
325
+ lgeos.GEOSCoordSeq_setX(cs, i, dx)
326
+ lgeos.GEOSCoordSeq_setY(cs, i, dy)
327
+ if n == 3:
328
+ lgeos.GEOSCoordSeq_setZ(cs, i, dz)
329
+
330
+ # Add closing coordinates to sequence?
331
+ if M > m:
332
+ dx = c_double(cp[0])
333
+ dy = c_double(cp[1])
334
+ dz = None
335
+ if n == 3:
336
+ dz = c_double(cp[2])
337
+
338
+ # Because of a bug in the GEOS C API,
339
+ # always set X before Y
340
+ lgeos.GEOSCoordSeq_setX(cs, M-1, dx)
341
+ lgeos.GEOSCoordSeq_setY(cs, M-1, dy)
342
+ if n == 3:
343
+ lgeos.GEOSCoordSeq_setZ(cs, M-1, dz)
344
+
345
+ except AttributeError:
346
+ # Fall back on list
347
+ m = len(ob)
348
+ n = len(ob[0])
349
+ if m < 3:
350
+ raise ValueError(
351
+ "A LinearRing must have at least 3 coordinate tuples")
352
+ assert (n == 2 or n == 3)
353
+
354
+ # Add closing coordinates if not provided
355
+ if m == 3 or ob[0][0] != ob[-1][0] or ob[0][1] != ob[-1][1]:
356
+ M = m + 1
357
+ else:
358
+ M = m
359
+
360
+ # Create a coordinate sequence
361
+ if update_geom is not None:
362
+ cs = lgeos.GEOSGeom_getCoordSeq(update_geom)
363
+ if n != update_ndim:
364
+ raise ValueError(
365
+ "Wrong coordinate dimensions; this geometry has dimensions: %d" \
366
+ % update_ndim)
367
+ else:
368
+ cs = lgeos.GEOSCoordSeq_create(M, n)
369
+
370
+ # add to coordinate sequence
371
+ for i in xrange(m):
372
+ coords = ob[i]
373
+ dx = c_double(coords[0])
374
+ dy = c_double(coords[1])
375
+ dz = None
376
+ if n == 3:
377
+ dz = c_double(coords[2])
378
+
379
+ # Because of a bug in the GEOS C API,
380
+ # always set X before Y
381
+ lgeos.GEOSCoordSeq_setX(cs, i, dx)
382
+ lgeos.GEOSCoordSeq_setY(cs, i, dy)
383
+ if n == 3:
384
+ lgeos.GEOSCoordSeq_setZ(cs, i, dz)
385
+
386
+ # Add closing coordinates to sequence?
387
+ if M > m:
388
+ coords = ob[0]
389
+ dx = c_double(coords[0])
390
+ dy = c_double(coords[1])
391
+ dz = None
392
+ if n == 3:
393
+ dz = c_double(coords[2])
394
+
395
+ # Because of a bug in the GEOS C API,
396
+ # always set X before Y
397
+ lgeos.GEOSCoordSeq_setX(cs, M-1, dx)
398
+ lgeos.GEOSCoordSeq_setY(cs, M-1, dy)
399
+ if n == 3:
400
+ lgeos.GEOSCoordSeq_setZ(cs, M-1, dz)
401
+
402
+ if update_geom is not None:
403
+ return None
404
+ else:
405
+ return lgeos.GEOSGeom_createLinearRing(cs), n
406
+
407
+ def update_linearring_from_py(geom, ob):
408
+ geos_linearring_from_py(ob, geom._geom, geom._ndim)
409
+
410
+ def geos_polygon_from_py(shell, holes=None):
411
+ if shell is not None:
412
+ geos_shell, ndim = geos_linearring_from_py(shell)
413
+ if holes:
414
+ ob = holes
415
+ L = len(ob)
416
+ exemplar = ob[0]
417
+ try:
418
+ N = len(exemplar[0])
419
+ except TypeError:
420
+ N = exemplar._ndim
421
+ assert L >= 1
422
+ assert N == 2 or N == 3
423
+
424
+ # Array of pointers to ring geometries
425
+ geos_holes = (c_void_p * L)()
426
+
427
+ # add to coordinate sequence
428
+ for l in xrange(L):
429
+ geom, ndim = geos_linearring_from_py(ob[l])
430
+ geos_holes[l] = cast(geom, c_void_p)
431
+ else:
432
+ geos_holes = POINTER(c_void_p)()
433
+ L = 0
434
+ return (
435
+ lgeos.GEOSGeom_createPolygon(
436
+ c_void_p(geos_shell),
437
+ geos_holes,
438
+ L
439
+ ),
440
+ ndim
441
+ )
442
+
443
+ # Test runner
444
+ def _test():
445
+ import doctest
446
+ doctest.testmod()
447
+
448
+ if __name__ == "__main__":
449
+ _test()
Binary file
@@ -0,0 +1,54 @@
1
+ """Proxy for coordinates stored outside Shapely geometries
2
+ """
3
+
4
+ from shapely.geos import lgeos
5
+ from shapely import wkb
6
+
7
+ EMPTY = wkb.deserialize('010700000000000000'.decode('hex'))
8
+
9
+
10
+ class CachingGeometryProxy(object):
11
+
12
+ context = None
13
+ factory = None
14
+ __geom__ = EMPTY
15
+ _gtag = None
16
+
17
+ def __init__(self, context):
18
+ self.context = context
19
+
20
+ @property
21
+ def _is_empty(self):
22
+ return self.__geom__ in [EMPTY, None]
23
+
24
+ def empty(self):
25
+ if not self._is_empty:
26
+ from shapely.geos import lgeos
27
+ lgeos.GEOSGeom_destroy(self.__geom__)
28
+ self.__geom__ = EMPTY
29
+
30
+ @property
31
+ def _geom(self):
32
+ """Keeps the GEOS geometry in synch with the context."""
33
+ gtag = self.gtag()
34
+ if gtag != self._gtag or self._is_empty:
35
+ self.empty()
36
+ self.__geom__, n = self.factory(self.context)
37
+ self._gtag = gtag
38
+ return self.__geom__
39
+
40
+ def gtag(self):
41
+ return hash(repr(self.context))
42
+
43
+
44
+ class PolygonProxy(CachingGeometryProxy):
45
+
46
+ @property
47
+ def _geom(self):
48
+ """Keeps the GEOS geometry in synch with the context."""
49
+ gtag = self.gtag()
50
+ if gtag != self._gtag or self._is_empty:
51
+ self.empty()
52
+ self.__geom__, n = self.factory(self.context[0], self.context[1])
53
+ self._gtag = gtag
54
+ return self.__geom__
Binary file