shapely 1.2.7__py2.5-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,230 @@
1
+ """Line strings and related utilities
2
+ """
3
+
4
+ from ctypes import c_double, cast, POINTER
5
+ from ctypes import ArgumentError
6
+
7
+ from shapely.geos import lgeos
8
+ from shapely.geometry.base import BaseGeometry
9
+ from shapely.geometry.proxy import CachingGeometryProxy
10
+
11
+ __all__ = ['LineString', 'asLineString']
12
+
13
+
14
+ class LineString(BaseGeometry):
15
+ """
16
+ A one-dimensional figure comprising one or more line segments
17
+
18
+ A LineString has non-zero length and zero area. It may approximate a curve
19
+ and need not be straight. Unlike a LinearRing, a LineString is not closed.
20
+ """
21
+
22
+ def __init__(self, coordinates=None):
23
+ """
24
+ Parameters
25
+ ----------
26
+ coordinates : sequence
27
+ A sequence of (x, y [,z]) numeric coordinate pairs or triples or
28
+ an object that provides the numpy array interface, including another
29
+ instance of LineString.
30
+
31
+ Example
32
+ -------
33
+ Create a line with two segments
34
+
35
+ >>> a = LineString([[0, 0], [1, 0], [1, 1]])
36
+ >>> a.length
37
+ 2.0
38
+ """
39
+ BaseGeometry.__init__(self)
40
+ if coordinates is not None:
41
+ self._set_coords(coordinates)
42
+
43
+ @property
44
+ def __geo_interface__(self):
45
+ return {
46
+ 'type': 'LineString',
47
+ 'coordinates': tuple(self.coords)
48
+ }
49
+
50
+ @property
51
+ def ctypes(self):
52
+ if not self._ctypes_data:
53
+ self._ctypes_data = self.coords.ctypes
54
+ return self._ctypes_data
55
+
56
+ def array_interface(self):
57
+ """Provide the Numpy array protocol."""
58
+ return self.coords.array_interface()
59
+
60
+ __array_interface__ = property(array_interface)
61
+
62
+ # Coordinate access
63
+ def _set_coords(self, coordinates):
64
+ self.empty()
65
+ self._geom, self._ndim = geos_linestring_from_py(coordinates)
66
+
67
+ coords = property(BaseGeometry._get_coords, _set_coords)
68
+
69
+ @property
70
+ def xy(self):
71
+ """Separate arrays of X and Y coordinate values
72
+
73
+ Example:
74
+
75
+ >>> x, y = LineString(((0, 0), (1, 1))).xy
76
+ >>> list(x)
77
+ [0.0, 1.0]
78
+ >>> list(y)
79
+ [0.0, 1.0]
80
+ """
81
+ return self.coords.xy
82
+
83
+
84
+ class LineStringAdapter(CachingGeometryProxy, LineString):
85
+
86
+ def __init__(self, context):
87
+ self.context = context
88
+ self.factory = geos_linestring_from_py
89
+
90
+ @property
91
+ def _ndim(self):
92
+ try:
93
+ # From array protocol
94
+ array = self.context.__array_interface__
95
+ n = array['shape'][1]
96
+ assert n == 2 or n == 3
97
+ return n
98
+ except AttributeError:
99
+ # Fall back on list
100
+ return len(self.context[0])
101
+
102
+ @property
103
+ def __array_interface__(self):
104
+ """Provide the Numpy array protocol."""
105
+ try:
106
+ return self.context.__array_interface__
107
+ except AttributeError:
108
+ return self.array_interface()
109
+
110
+ _get_coords = BaseGeometry._get_coords
111
+
112
+ def _set_coords(self, ob):
113
+ raise NotImplementedError(
114
+ "Adapters can not modify their coordinate sources")
115
+
116
+ coords = property(_get_coords)
117
+
118
+
119
+ def asLineString(context):
120
+ """Adapt an object the LineString interface"""
121
+ return LineStringAdapter(context)
122
+
123
+
124
+ def geos_linestring_from_py(ob, update_geom=None, update_ndim=0):
125
+ try:
126
+ # From array protocol
127
+ array = ob.__array_interface__
128
+ assert len(array['shape']) == 2
129
+ m = array['shape'][0]
130
+ if m < 2:
131
+ raise ValueError(
132
+ "LineStrings must have at least 2 coordinate tuples")
133
+ try:
134
+ n = array['shape'][1]
135
+ except IndexError:
136
+ raise ValueError(
137
+ "Input %s is the wrong shape for a LineString" % str(ob))
138
+ assert n == 2 or n == 3
139
+
140
+ # Make pointer to the coordinate array
141
+ try:
142
+ cp = cast(array['data'][0], POINTER(c_double))
143
+ except ArgumentError:
144
+ cp = array['data']
145
+
146
+ # Create a coordinate sequence
147
+ if update_geom is not None:
148
+ cs = lgeos.GEOSGeom_getCoordSeq(update_geom)
149
+ if n != update_ndim:
150
+ raise ValueError(
151
+ "Wrong coordinate dimensions; this geometry has dimensions: %d" \
152
+ % update_ndim)
153
+ else:
154
+ cs = lgeos.GEOSCoordSeq_create(m, n)
155
+
156
+ # add to coordinate sequence
157
+ for i in xrange(m):
158
+ dx = c_double(cp[n*i])
159
+ dy = c_double(cp[n*i+1])
160
+ dz = None
161
+ if n == 3:
162
+ try:
163
+ dz = c_double(cp[n*i+2])
164
+ except IndexError:
165
+ raise ValueError("Inconsistent coordinate dimensionality")
166
+
167
+ # Because of a bug in the GEOS C API,
168
+ # always set X before Y
169
+ lgeos.GEOSCoordSeq_setX(cs, i, dx)
170
+ lgeos.GEOSCoordSeq_setY(cs, i, dy)
171
+ if n == 3:
172
+ lgeos.GEOSCoordSeq_setZ(cs, i, dz)
173
+
174
+ except AttributeError:
175
+ # Fall back on list
176
+ m = len(ob)
177
+ if m < 2:
178
+ raise ValueError(
179
+ "LineStrings must have at least 2 coordinate tuples")
180
+ try:
181
+ n = len(ob[0])
182
+ except TypeError:
183
+ raise ValueError(
184
+ "Input %s is the wrong shape for a LineString" % str(ob))
185
+ assert n == 2 or n == 3
186
+
187
+ # Create a coordinate sequence
188
+ if update_geom is not None:
189
+ cs = lgeos.GEOSGeom_getCoordSeq(update_geom)
190
+ if n != update_ndim:
191
+ raise ValueError(
192
+ "Wrong coordinate dimensions; this geometry has dimensions: %d" \
193
+ % update_ndim)
194
+ else:
195
+ cs = lgeos.GEOSCoordSeq_create(m, n)
196
+
197
+ # add to coordinate sequence
198
+ for i in xrange(m):
199
+ coords = ob[i]
200
+ dx = c_double(coords[0])
201
+ dy = c_double(coords[1])
202
+ dz = None
203
+ if n == 3:
204
+ try:
205
+ dz = c_double(coords[2])
206
+ except IndexError:
207
+ raise ValueError("Inconsistent coordinate dimensionality")
208
+
209
+ # Because of a bug in the GEOS C API,
210
+ # always set X before Y
211
+ lgeos.GEOSCoordSeq_setX(cs, i, dx)
212
+ lgeos.GEOSCoordSeq_setY(cs, i, dy)
213
+ if n == 3:
214
+ lgeos.GEOSCoordSeq_setZ(cs, i, dz)
215
+
216
+ if update_geom is not None:
217
+ return None
218
+ else:
219
+ return lgeos.GEOSGeom_createLineString(cs), n
220
+
221
+ def update_linestring_from_py(geom, ob):
222
+ geos_linestring_from_py(ob, geom._geom, geom._ndim)
223
+
224
+ # Test runner
225
+ def _test():
226
+ import doctest
227
+ doctest.testmod()
228
+
229
+ if __name__ == "__main__":
230
+ _test()
Binary file
@@ -0,0 +1,133 @@
1
+ """Collections of linestrings and related utilities
2
+ """
3
+
4
+ from ctypes import c_double, c_void_p, cast, POINTER
5
+
6
+ from shapely.geos import lgeos
7
+ from shapely.geometry.base import BaseMultipartGeometry
8
+ from shapely.geometry.linestring import LineString, geos_linestring_from_py
9
+ from shapely.geometry.proxy import CachingGeometryProxy
10
+
11
+ __all__ = ['MultiLineString', 'asMultiLineString']
12
+
13
+
14
+ class MultiLineString(BaseMultipartGeometry):
15
+ """
16
+ A collection of one or more line strings
17
+
18
+ A MultiLineString has non-zero length and zero area.
19
+
20
+ Attributes
21
+ ----------
22
+ geoms : sequence
23
+ A sequence of LineStrings
24
+ """
25
+
26
+ def __init__(self, lines=None):
27
+ """
28
+ Parameters
29
+ ----------
30
+ lines : sequence
31
+ A sequence of line-like coordinate sequences or objects that
32
+ provide the numpy array interface, including instances of
33
+ LineString.
34
+
35
+ Example
36
+ -------
37
+ Construct a collection containing one line string.
38
+
39
+ >>> lines = MultiLineString( [[[0.0, 0.0], [1.0, 2.0]]] )
40
+ """
41
+ super(MultiLineString, self).__init__()
42
+
43
+ if lines is None:
44
+ # allow creation of null lines, to support unpickling
45
+ pass
46
+ else:
47
+ self._geom, self._ndim = geos_multilinestring_from_py(lines)
48
+
49
+ def shape_factory(self, *args):
50
+ return LineString(*args)
51
+
52
+ @property
53
+ def __geo_interface__(self):
54
+ return {
55
+ 'type': 'MultiLineString',
56
+ 'coordinates': tuple(tuple(c for c in g.coords) for g in self.geoms)
57
+ }
58
+
59
+
60
+ class MultiLineStringAdapter(CachingGeometryProxy, MultiLineString):
61
+
62
+ context = None
63
+ _owned = False
64
+
65
+ def __init__(self, context):
66
+ self.context = context
67
+ self.factory = geos_multilinestring_from_py
68
+
69
+ @property
70
+ def _ndim(self):
71
+ try:
72
+ # From array protocol
73
+ array = self.context[0].__array_interface__
74
+ n = array['shape'][1]
75
+ assert n == 2 or n == 3
76
+ return n
77
+ except AttributeError:
78
+ # Fall back on list
79
+ return len(self.context[0][0])
80
+
81
+
82
+ def asMultiLineString(context):
83
+ """Adapts a sequence of objects to the MultiLineString interface"""
84
+ return MultiLineStringAdapter(context)
85
+
86
+
87
+ def geos_multilinestring_from_py(ob):
88
+ # ob must be either a sequence or array of sequences or arrays
89
+ try:
90
+ # From array protocol
91
+ array = ob.__array_interface__
92
+ assert len(array['shape']) == 1
93
+ L = array['shape'][0]
94
+ assert L >= 1
95
+
96
+ # Make pointer to the coordinate array
97
+ cp = cast(array['data'][0], POINTER(c_double))
98
+
99
+ # Array of pointers to sub-geometries
100
+ subs = (c_void_p * L)()
101
+
102
+ for l in xrange(L):
103
+ geom, ndims = geos_linestring_from_py(array['data'][l])
104
+ subs[i] = cast(geom, c_void_p)
105
+ N = lgeos.GEOSGeom_getDimensions(subs[0])
106
+ except (NotImplementedError, AttributeError):
107
+ obs = getattr(ob, 'geoms', ob)
108
+ L = len(obs)
109
+ exemplar = obs[0]
110
+ try:
111
+ N = len(exemplar[0])
112
+ except TypeError:
113
+ N = exemplar._ndim
114
+ assert L >= 1
115
+ assert N == 2 or N == 3
116
+
117
+ # Array of pointers to point geometries
118
+ subs = (c_void_p * L)()
119
+
120
+ # add to coordinate sequence
121
+ for l in xrange(L):
122
+ geom, ndims = geos_linestring_from_py(obs[l])
123
+ subs[l] = cast(geom, c_void_p)
124
+
125
+ return (lgeos.GEOSGeom_createCollection(5, subs, L), N)
126
+
127
+ # Test runner
128
+ def _test():
129
+ import doctest
130
+ doctest.testmod()
131
+
132
+ if __name__ == "__main__":
133
+ _test()
Binary file
@@ -0,0 +1,180 @@
1
+ """Collections of points and related utilities
2
+ """
3
+
4
+ from ctypes import byref, c_double, c_void_p, cast, POINTER
5
+ from ctypes import ArgumentError
6
+
7
+ from shapely.geos import lgeos
8
+ from shapely.geometry.base import BaseMultipartGeometry, exceptNull
9
+ from shapely.geometry.point import Point, geos_point_from_py
10
+ from shapely.geometry.proxy import CachingGeometryProxy
11
+
12
+ __all__ = ['MultiPoint', 'asMultiPoint']
13
+
14
+
15
+ class MultiPoint(BaseMultipartGeometry):
16
+
17
+ """A collection of one or more points
18
+
19
+ A MultiPoint has zero area and zero length.
20
+
21
+ Attributes
22
+ ----------
23
+ geoms : sequence
24
+ A sequence of Points
25
+ """
26
+
27
+ def __init__(self, points=None):
28
+ """
29
+ Parameters
30
+ ----------
31
+ points : sequence
32
+ A sequence of (x, y [,z]) numeric coordinate pairs or triples or a
33
+ sequence of objects that implement the numpy array interface,
34
+ including instaces of Point.
35
+
36
+ Example
37
+ -------
38
+ Construct a 2 point collection
39
+
40
+ >>> ob = MultiPoint([[0.0, 0.0], [1.0, 2.0]])
41
+ >>> len(ob.geoms)
42
+ 2
43
+ >>> type(ob.geoms[0]) == Point
44
+ True
45
+ """
46
+ super(MultiPoint, self).__init__()
47
+
48
+ if points is None:
49
+ # allow creation of empty multipoints, to support unpickling
50
+ pass
51
+ else:
52
+ self._geom, self._ndim = geos_multipoint_from_py(points)
53
+
54
+ def shape_factory(self, *args):
55
+ return Point(*args)
56
+
57
+ @property
58
+ def __geo_interface__(self):
59
+ return {
60
+ 'type': 'MultiPoint',
61
+ 'coordinates': tuple([g.coords[0] for g in self.geoms])
62
+ }
63
+
64
+ @property
65
+ @exceptNull
66
+ def ctypes(self):
67
+ if not self._ctypes_data:
68
+ temp = c_double()
69
+ n = self._ndim
70
+ m = len(self.geoms)
71
+ array_type = c_double * (m * n)
72
+ data = array_type()
73
+ for i in xrange(m):
74
+ g = self.geoms[i]._geom
75
+ cs = lgeos.GEOSGeom_getCoordSeq(g)
76
+ lgeos.GEOSCoordSeq_getX(cs, 0, byref(temp))
77
+ data[n*i] = temp.value
78
+ lgeos.GEOSCoordSeq_getY(cs, 0, byref(temp))
79
+ data[n*i+1] = temp.value
80
+ if n == 3: # TODO: use hasz
81
+ lgeos.GEOSCoordSeq_getZ(cs, 0, byref(temp))
82
+ data[n*i+2] = temp.value
83
+ self._ctypes_data = data
84
+ return self._ctypes_data
85
+
86
+ @exceptNull
87
+ def array_interface(self):
88
+ """Provide the Numpy array protocol."""
89
+ ai = self.array_interface_base
90
+ ai.update({'shape': (len(self.geoms), self._ndim)})
91
+ return ai
92
+ __array_interface__ = property(array_interface)
93
+
94
+
95
+ class MultiPointAdapter(CachingGeometryProxy, MultiPoint):
96
+
97
+ context = None
98
+ _owned = False
99
+
100
+ def __init__(self, context):
101
+ self.context = context
102
+ self.factory = geos_multipoint_from_py
103
+
104
+ @property
105
+ def _ndim(self):
106
+ try:
107
+ # From array protocol
108
+ array = self.context.__array_interface__
109
+ n = array['shape'][1]
110
+ assert n == 2 or n == 3
111
+ return n
112
+ except AttributeError:
113
+ # Fall back on list
114
+ return len(self.context[0])
115
+
116
+ @property
117
+ def __array_interface__(self):
118
+ """Provide the Numpy array protocol."""
119
+ try:
120
+ return self.context.__array_interface__
121
+ except AttributeError:
122
+ return self.array_interface()
123
+
124
+
125
+ def asMultiPoint(context):
126
+ """Adapt a sequence of objects to the MultiPoint interface"""
127
+ return MultiPointAdapter(context)
128
+
129
+
130
+ def geos_multipoint_from_py(ob):
131
+ try:
132
+ # From array protocol
133
+ array = ob.__array_interface__
134
+ assert len(array['shape']) == 2
135
+ m = array['shape'][0]
136
+ n = array['shape'][1]
137
+ assert m >= 1
138
+ assert n == 2 or n == 3
139
+
140
+ # Make pointer to the coordinate array
141
+ try:
142
+ cp = cast(array['data'][0], POINTER(c_double))
143
+ except ArgumentError:
144
+ cp = array['data']
145
+
146
+ # Array of pointers to sub-geometries
147
+ subs = (c_void_p * m)()
148
+
149
+ for i in xrange(m):
150
+ geom, ndims = geos_point_from_py(cp[n*i:n*i+2])
151
+ subs[i] = cast(geom, c_void_p)
152
+
153
+ except AttributeError:
154
+ # Fall back on list
155
+ m = len(ob)
156
+ try:
157
+ n = len(ob[0])
158
+ except TypeError:
159
+ n = ob[0]._ndim
160
+ assert n == 2 or n == 3
161
+
162
+ # Array of pointers to point geometries
163
+ subs = (c_void_p * m)()
164
+
165
+ # add to coordinate sequence
166
+ for i in xrange(m):
167
+ coords = ob[i]
168
+ geom, ndims = geos_point_from_py(coords)
169
+ subs[i] = cast(geom, c_void_p)
170
+
171
+ return lgeos.GEOSGeom_createCollection(4, subs, m), n
172
+
173
+ # Test runner
174
+ def _test():
175
+ import doctest
176
+ doctest.testmod()
177
+
178
+
179
+ if __name__ == "__main__":
180
+ _test()
Binary file
@@ -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