shapely 1.2.7__py2.6-win32.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 (56) hide show
  1. DLLs/geos.dll +0 -0
  2. DLLs/libgeos-3-2-2.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 +276 -0
  12. shapely/ctypes_declarations.pyc +0 -0
  13. shapely/geometry/__init__.py +20 -0
  14. shapely/geometry/__init__.pyc +0 -0
  15. shapely/geometry/base.py +595 -0
  16. shapely/geometry/base.pyc +0 -0
  17. shapely/geometry/collection.py +43 -0
  18. shapely/geometry/collection.pyc +0 -0
  19. shapely/geometry/geo.py +68 -0
  20. shapely/geometry/geo.pyc +0 -0
  21. shapely/geometry/linestring.py +230 -0
  22. shapely/geometry/linestring.pyc +0 -0
  23. shapely/geometry/multilinestring.py +133 -0
  24. shapely/geometry/multilinestring.pyc +0 -0
  25. shapely/geometry/multipoint.py +180 -0
  26. shapely/geometry/multipoint.pyc +0 -0
  27. shapely/geometry/multipolygon.py +154 -0
  28. shapely/geometry/multipolygon.pyc +0 -0
  29. shapely/geometry/point.py +241 -0
  30. shapely/geometry/point.pyc +0 -0
  31. shapely/geometry/polygon.py +449 -0
  32. shapely/geometry/polygon.pyc +0 -0
  33. shapely/geometry/proxy.py +54 -0
  34. shapely/geometry/proxy.pyc +0 -0
  35. shapely/geos.py +370 -0
  36. shapely/geos.pyc +0 -0
  37. shapely/impl.py +118 -0
  38. shapely/impl.pyc +0 -0
  39. shapely/iterops.py +53 -0
  40. shapely/iterops.pyc +0 -0
  41. shapely/linref.py +26 -0
  42. shapely/linref.pyc +0 -0
  43. shapely/ops.py +87 -0
  44. shapely/ops.pyc +0 -0
  45. shapely/predicates.py +24 -0
  46. shapely/predicates.pyc +0 -0
  47. shapely/prepared.py +58 -0
  48. shapely/prepared.pyc +0 -0
  49. shapely/topology.py +62 -0
  50. shapely/topology.pyc +0 -0
  51. shapely/validation.py +7 -0
  52. shapely/validation.pyc +0 -0
  53. shapely/wkb.py +39 -0
  54. shapely/wkb.pyc +0 -0
  55. shapely/wkt.py +34 -0
  56. shapely/wkt.pyc +0 -0
@@ -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
@@ -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