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 ADDED
@@ -0,0 +1,173 @@
1
+ Metadata-Version: 1.0
2
+ Name: Shapely
3
+ Version: 1.0
4
+ Summary: Geospatial geometries, predicates, and operations
5
+ Home-page: http://trac.gispython.org/projects/PCL/wiki/Shapely
6
+ Author: Sean Gillies
7
+ Author-email: sgillies@frii.com
8
+ License: BSD
9
+ Description: Shapely
10
+ =======
11
+
12
+ Shapely is a Python package for programming with 2D geospatial geometries. It
13
+ is based on GEOS (http://geos.refractions.net). Shapely 1.0 is ignorant about
14
+ coordinate and reference systems. Projection responsibility is left to specific
15
+ applications. For more information, see:
16
+
17
+ * Shapely wiki_
18
+ * Shapely manual_
19
+
20
+ Shapely requires Python 2.4+. (I've also begun to port it to Python 3.0:
21
+ http://zcologia.com/news/564/shapely-for-python-3-0/.)
22
+
23
+
24
+ Dependencies
25
+ ------------
26
+
27
+ * libgeos_c (2.2.3 or 3.0.0+)
28
+ * Python ctypes_ (standard in Python 2.5+)
29
+
30
+ .. _ctypes: http://pypi.python.org/pypi/ctypes/
31
+
32
+
33
+ Installation
34
+ ------------
35
+
36
+ Windows users should use the executable installer, which contains the required
37
+ GEOS DLL. Other users should acquire libgeos_c by any means, make sure that it
38
+ is on the system library path, and install from the Python package index::
39
+
40
+ $ sudo easy_install Shapely
41
+
42
+ with the setup script::
43
+
44
+ $ sudo python setup.py install
45
+
46
+ or by using the development buildout on Linux, which also provides libgeos_c::
47
+
48
+ $ svn co http://svn.gispython.org/svn/gispy/buildout/shapely.buildout/trunk shapely.buildout
49
+ $ cd shapely.buildout
50
+ $ python bootstrap.py
51
+ $ ./bin/buildout
52
+
53
+
54
+ Usage
55
+ -----
56
+
57
+ To buffer a point::
58
+
59
+ >>> from shapely.geometry import Point
60
+ >>> point = Point(-106.0, 40.0) # longitude, latitude
61
+ >>> point.buffer(10.0)
62
+ <shapely.geometry.polygon.Polygon object at ...>
63
+
64
+ See the manual_ for comprehensive examples of usage. See also Operations.txt
65
+ and Predicates.txt under tests/ for more examples of the spatial operations and
66
+ predicates provided by Shapely. See also Point.txt, LineString.txt, etc for
67
+ examples of the geometry APIs.
68
+
69
+
70
+ Numpy integration
71
+ -----------------
72
+
73
+ All Shapely geometry instances provide the Numpy array interface::
74
+
75
+ >>> from numpy import asarray
76
+ >>> a = asarray(point)
77
+ >>> a.size
78
+ 3
79
+ >>> a.shape
80
+ (2,)
81
+
82
+ Numpy arrays can also be adapted to Shapely points and linestrings::
83
+
84
+ >>> from shapely.geometry import asLineString
85
+ >>> a = array([[1.0, 2.0], [3.0, 4.0]])
86
+ >>> line = asLineString(a)
87
+ >>> line.wkt
88
+ 'LINESTRING (1.0000000000000000 2.0000000000000000, 3.0000000000000000 4.0000000000000000)'
89
+
90
+
91
+ Python Geo Interface
92
+ --------------------
93
+
94
+ Any object that provides the Python geo interface can be adapted to a Shapely
95
+ geometry with the asShape factory::
96
+
97
+ >>> d = {"type": "Point", "coordinates": (0.0, 0.0)}
98
+ >>> from shapely.geometry import asShape
99
+ >>> shape = asShape(d)
100
+ >>> shape.geom_type
101
+ 'Point'
102
+ >>> tuple(shape.coords)
103
+ ((0.0, 0.0),)
104
+
105
+ >>> class GeoThing(object):
106
+ ... def __init__(self, d):
107
+ ... self.__geo_interface__ = d
108
+ >>> thing = GeoThing({"type": "Point", "coordinates": (0.0, 0.0)})
109
+ >>> shape = asShape(thing)
110
+ >>> shape.geom_type
111
+ 'Point'
112
+ >>> tuple(shape.coords)
113
+ ((0.0, 0.0),)
114
+
115
+ See http://trac.gispython.org/projects/PCL/wiki/PythonGeoInterface for more
116
+ details on the interface.
117
+
118
+
119
+ Testing
120
+ -------
121
+
122
+ Several of the modules have docstring doctests::
123
+
124
+ $ cd shapely
125
+ $ python point.py
126
+
127
+ There are also two test runners under tests/. test_doctests.py requires
128
+ zope.testing. runalldoctests.py does not. Perhaps the easiest way to run the
129
+ tests is::
130
+
131
+ $ python setup.py test
132
+
133
+
134
+ Support
135
+ -------
136
+
137
+ For current information about this project, see the wiki_.
138
+
139
+ .. _wiki: http://trac.gispython.org/projects/PCL/wiki/Shapely
140
+ .. _manual: http://gispython.org/shapely/manual.html
141
+
142
+ If you have questions, please consider joining our community list:
143
+
144
+ http://trac.gispython.org/projects/PCL/wiki/CommunityList
145
+
146
+
147
+ Credits
148
+ -------
149
+
150
+ * Sean Gillies (Pleiades)
151
+ * Howard Butler (Hobu, Inc.)
152
+ * Kai Lautaportti (Hexagon IT)
153
+ * Fr |eaigue| d |eaigue| ric Junod (Camptocamp SA)
154
+ * Eric Lemoine (Camptocamp SA)
155
+ * Justin Bronn (GeoDjango) for ctypes inspiration
156
+ * Artem Pavlenko (Mapnik) for help with GEOS DLLs
157
+
158
+ .. |eaigue| unicode:: U+00E9
159
+ :trim:
160
+
161
+ Major portions of this work were supported by a grant (to Pleiades) from the
162
+ U.S. National Endowment for the Humanities (http://www.neh.gov).
163
+
164
+
165
+ Keywords: geometry topology
166
+ Platform: UNKNOWN
167
+ Classifier: Development Status :: 5 - Production/Stable
168
+ Classifier: Intended Audience :: Developers
169
+ Classifier: Intended Audience :: Science/Research
170
+ Classifier: License :: OSI Approved :: BSD License
171
+ Classifier: Operating System :: OS Independent
172
+ Classifier: Programming Language :: Python
173
+ Classifier: Topic :: Scientific/Engineering :: GIS
EGG-INFO/SOURCES.txt ADDED
@@ -0,0 +1,52 @@
1
+ CHANGES.txt
2
+ CREDITS.txt
3
+ HISTORY.txt
4
+ LICENSE.txt
5
+ README.txt
6
+ setup.py
7
+ setup_windows.py
8
+ Shapely.egg-info/PKG-INFO
9
+ Shapely.egg-info/SOURCES.txt
10
+ Shapely.egg-info/dependency_links.txt
11
+ Shapely.egg-info/requires.txt
12
+ Shapely.egg-info/top_level.txt
13
+ examples/geoms.py
14
+ examples/world.py
15
+ manual/manual.txt
16
+ manual/style.css
17
+ shapely/__init__.py
18
+ shapely/geos.py
19
+ shapely/iterops.py
20
+ shapely/kml.py
21
+ shapely/predicates.py
22
+ shapely/topology.py
23
+ shapely/wkb.py
24
+ shapely/wkt.py
25
+ shapely/geometry/__init__.py
26
+ shapely/geometry/base.py
27
+ shapely/geometry/collection.py
28
+ shapely/geometry/geo.py
29
+ shapely/geometry/linestring.py
30
+ shapely/geometry/multilinestring.py
31
+ shapely/geometry/multipoint.py
32
+ shapely/geometry/multipolygon.py
33
+ shapely/geometry/point.py
34
+ shapely/geometry/polygon.py
35
+ tests/Array.txt
36
+ tests/GeoInterface.txt
37
+ tests/IterOps.txt
38
+ tests/LineString.txt
39
+ tests/MultiLineString.txt
40
+ tests/MultiPoint.txt
41
+ tests/MultiPolygon.txt
42
+ tests/Operations.txt
43
+ tests/Persist.txt
44
+ tests/Point.txt
45
+ tests/Polygon.txt
46
+ tests/Predicates.txt
47
+ tests/__init__.py
48
+ tests/binascii_hex.txt
49
+ tests/invalid_intersection.txt
50
+ tests/rungrind.dist
51
+ tests/test_doctests.py
52
+ tests/valgrind-python.supp
@@ -0,0 +1 @@
1
+
EGG-INFO/not-zip-safe ADDED
@@ -0,0 +1 @@
1
+
EGG-INFO/requires.txt ADDED
@@ -0,0 +1,2 @@
1
+ setuptools
2
+ ctypes
EGG-INFO/top_level.txt ADDED
@@ -0,0 +1 @@
1
+ shapely
shapely/__init__.py ADDED
@@ -0,0 +1 @@
1
+ #
shapely/__init__.pyc ADDED
Binary file
@@ -0,0 +1,9 @@
1
+ from geo import asShape
2
+ from point import Point, asPoint
3
+ from linestring import LineString, asLineString
4
+ from polygon import Polygon, asPolygon
5
+ from multipoint import MultiPoint, asMultiPoint
6
+ from multilinestring import MultiLineString, asMultiLineString
7
+ from multipolygon import MultiPolygon, asMultiPolygon
8
+ from collection import GeometryCollection
9
+
Binary file
@@ -0,0 +1,415 @@
1
+ """
2
+ Base geometry class and utilities.
3
+ """
4
+
5
+ from ctypes import string_at, byref, c_int, c_size_t, c_char_p, c_double
6
+ import sys
7
+
8
+ from shapely.geos import lgeos, free, allocated_c_char_p
9
+ from shapely.predicates import BinaryPredicate, UnaryPredicate
10
+ from shapely.topology import BinaryTopologicalOp, UnaryTopologicalOp
11
+
12
+
13
+ GEOMETRY_TYPES = [
14
+ 'Point',
15
+ 'LineString',
16
+ 'LinearRing',
17
+ 'Polygon',
18
+ 'MultiPoint',
19
+ 'MultiLineString',
20
+ 'MultiPolygon',
21
+ 'GeometryCollection'
22
+ ]
23
+
24
+ def geometry_type_name(g):
25
+ if g is None:
26
+ raise ValueError, "Null geometry has no type"
27
+ return GEOMETRY_TYPES[lgeos.GEOSGeomTypeId(g)]
28
+
29
+ # Abstract geometry factory for use with topological methods below
30
+
31
+ def geom_factory(g):
32
+ if not g:
33
+ raise ValueError, "No Shapely geometry can be created from this null value"
34
+ ob = BaseGeometry()
35
+ geom_type = geometry_type_name(g)
36
+ # TODO: check cost of dynamic import by profiling
37
+ mod = __import__(
38
+ 'shapely.geometry',
39
+ globals(),
40
+ locals(),
41
+ [geom_type],
42
+ )
43
+ ob.__class__ = getattr(mod, geom_type)
44
+ ob._geom = g
45
+ ob._ndim = 2 # callers should be all from 2D worlds
46
+ return ob
47
+
48
+
49
+ class CoordinateSequence(object):
50
+
51
+ _cseq = None
52
+ _ndim = None
53
+ _length = 0
54
+ index = 0
55
+
56
+ def __init__(self, geom):
57
+ self._cseq = lgeos.GEOSGeom_getCoordSeq(geom._geom)
58
+ self._ndim = geom._ndim
59
+
60
+ def __iter__(self):
61
+ self.index = 0
62
+ self._length = self.__len__()
63
+ return self
64
+
65
+ def next(self):
66
+ dx = c_double()
67
+ dy = c_double()
68
+ dz = c_double()
69
+ i = self.index
70
+ if i < self._length:
71
+ lgeos.GEOSCoordSeq_getX(self._cseq, i, byref(dx))
72
+ lgeos.GEOSCoordSeq_getY(self._cseq, i, byref(dy))
73
+ if self._ndim == 3: # TODO: use hasz
74
+ lgeos.GEOSCoordSeq_getZ(self._cseq, i, byref(dz))
75
+ self.index += 1
76
+ return (dx.value, dy.value, dz.value)
77
+ else:
78
+ self.index += 1
79
+ return (dx.value, dy.value)
80
+ else:
81
+ raise StopIteration
82
+
83
+ def __len__(self):
84
+ cs_len = c_int(0)
85
+ lgeos.GEOSCoordSeq_getSize(self._cseq, byref(cs_len))
86
+ return cs_len.value
87
+
88
+ def __getitem__(self, i):
89
+ M = self.__len__()
90
+ if i + M < 0 or i >= M:
91
+ raise IndexError, "index out of range"
92
+ if i < 0:
93
+ ii = M + i
94
+ else:
95
+ ii = i
96
+ dx = c_double()
97
+ dy = c_double()
98
+ dz = c_double()
99
+ lgeos.GEOSCoordSeq_getX(self._cseq, ii, byref(dx))
100
+ lgeos.GEOSCoordSeq_getY(self._cseq, ii, byref(dy))
101
+ if self._ndim == 3: # TODO: use hasz
102
+ lgeos.GEOSCoordSeq_getZ(self._cseq, ii, byref(dz))
103
+ return (dx.value, dy.value, dz.value)
104
+ else:
105
+ return (dx.value, dy.value)
106
+
107
+
108
+ class GeometrySequence(object):
109
+
110
+ _factory = None
111
+ _geom = None
112
+ _ndim = None
113
+ _index = 0
114
+ _length = 0
115
+
116
+ def __init__(self, geom, type):
117
+ self._factory = type
118
+ self._geom = geom._geom
119
+ self._ndim = geom._ndim
120
+
121
+ def __iter__(self):
122
+ self._index = 0
123
+ self._length = self.__len__()
124
+ return self
125
+
126
+ def next(self):
127
+ if self._index < self.__len__():
128
+ g = self._factory()
129
+ g._owned = True
130
+ g._geom = lgeos.GEOSGetGeometryN(self._geom, self._index)
131
+ self._index += 1
132
+ return g
133
+ else:
134
+ raise StopIteration
135
+
136
+ def __len__(self):
137
+ return lgeos.GEOSGetNumGeometries(self._geom)
138
+
139
+ def __getitem__(self, i):
140
+ M = self.__len__()
141
+ if i + M < 0 or i >= M:
142
+ raise IndexError, "index out of range"
143
+ if i < 0:
144
+ ii = M + i
145
+ else:
146
+ ii = i
147
+ g = self._factory()
148
+ g._owned = True
149
+ g._geom = lgeos.GEOSGetGeometryN(self._geom, ii)
150
+ return g
151
+
152
+ @property
153
+ def _longest(self):
154
+ max = 0
155
+ for g in iter(self):
156
+ l = len(g.coords)
157
+ if l > max:
158
+ max = l
159
+
160
+
161
+ def exceptNull(func):
162
+ """Decorator which helps avoid GEOS operations on null pointers."""
163
+ def wrapper(*args, **kwargs):
164
+ # self is the first arg
165
+ if args[0]._geom is None:
166
+ raise ValueError, "Null geometry supports no operations"
167
+ return func(*args, **kwargs)
168
+ return wrapper
169
+
170
+ def exceptEitherNull(func):
171
+ """Decorator which avoids GEOS operations on one or more null pointers."""
172
+ def wrapper(*args, **kwargs):
173
+ # self is the first arg
174
+ if args[0]._geom is None or args[1]._geom is None:
175
+ raise ValueError, "Null geometry supports no operations"
176
+ return func(*args, **kwargs)
177
+ return wrapper
178
+
179
+
180
+ class BaseGeometry(object):
181
+
182
+ """Provides GEOS spatial predicates and topological operations.
183
+ """
184
+
185
+ __geom = None # See _geom property below
186
+ _ctypes_data = None
187
+ _ndim = None
188
+ _crs = None
189
+ _owned = False
190
+
191
+ def __init__(self):
192
+ self.__geom = None
193
+
194
+ def __del__(self):
195
+ if self.__geom is not None and not self._owned:
196
+ lgeos.GEOSGeom_destroy(self.__geom)
197
+
198
+ def __str__(self):
199
+ return self.to_wkt()
200
+
201
+ def __eq__(self, other):
202
+ return self.equals(other)
203
+
204
+ def __ne__(self, other):
205
+ return not self.equals(other)
206
+
207
+ # To support pickling
208
+
209
+ def __reduce__(self):
210
+ return (self.__class__, (), self.to_wkb())
211
+
212
+ def __setstate__(self, state):
213
+ self.__geom = lgeos.GEOSGeomFromWKB_buf(
214
+ c_char_p(state),
215
+ c_size_t(len(state))
216
+ )
217
+
218
+ # _geom has been made a property with the GEOS geometry pointer stored
219
+ # in __geom so that geometries and geometry adapters can share __del__
220
+
221
+ def get_geom(self):
222
+ return self.__geom
223
+ def set_geom(self, val):
224
+ self.__geom = val
225
+ _geom = property(get_geom, set_geom)
226
+
227
+ # Array and ctypes interfaces
228
+
229
+ @property
230
+ def ctypes(self):
231
+ """Return a ctypes representation.
232
+
233
+ To be overridden by extension classes."""
234
+ raise NotImplementedError
235
+
236
+ @property
237
+ def array_interface_base(self):
238
+ if sys.byteorder == 'little':
239
+ typestr = '<f8'
240
+ elif sys.byteorder == 'big':
241
+ typestr = '>f8'
242
+ else:
243
+ raise ValueError, "Unsupported byteorder: neither little nor big-endian"
244
+ return {
245
+ 'version': 3,
246
+ 'typestr': typestr,
247
+ 'data': self.ctypes,
248
+ }
249
+
250
+ @property
251
+ def __array_interface__(self):
252
+ """Provide the Numpy array protocol."""
253
+ raise NotImplementedError
254
+
255
+ @exceptNull
256
+ def get_coords(self):
257
+ return CoordinateSequence(self)
258
+
259
+ def set_coords(self, ob):
260
+ raise NotImplementedError, \
261
+ "set_coords must be provided by derived classes"
262
+
263
+ coords = property(get_coords, set_coords)
264
+
265
+ # Python feature protocol
266
+
267
+ @property
268
+ def __geo_interface__(self):
269
+ raise NotImplementedError
270
+
271
+ @property
272
+ def type(self):
273
+ return self.geometryType()
274
+
275
+ # Type of geometry and its representations
276
+
277
+ @exceptNull
278
+ def geometryType(self):
279
+ """Returns a string representing the geometry type, e.g. 'Polygon'."""
280
+ return geometry_type_name(self._geom)
281
+
282
+ @exceptNull
283
+ def to_wkb(self):
284
+ """Returns a WKB byte string representation of the geometry."""
285
+ func = lgeos.GEOSGeomToWKB_buf
286
+ size = c_int()
287
+ def errcheck(result, func, argtuple):
288
+ retval = string_at(result, size.value)[:]
289
+ free(result)
290
+ return retval
291
+ func.errcheck = errcheck
292
+ return func(self._geom, byref(size))
293
+
294
+ @exceptNull
295
+ def to_wkt(self):
296
+ """Returns a WKT string representation of the geometry."""
297
+ func = lgeos.GEOSGeomToWKT
298
+ def errcheck(result, func, argtuple):
299
+ retval = result.value
300
+ free(result)
301
+ return retval
302
+ func.restype = allocated_c_char_p
303
+ func.errcheck = errcheck
304
+ return lgeos.GEOSGeomToWKT(self._geom)
305
+
306
+ geom_type = property(geometryType)
307
+ wkt = property(to_wkt)
308
+ wkb = property(to_wkb)
309
+
310
+ # Basic geometry properties
311
+
312
+ @property
313
+ @exceptNull
314
+ def area(self):
315
+ a = c_double()
316
+ retval = lgeos.GEOSArea(self._geom, byref(a))
317
+ return a.value
318
+
319
+ @property
320
+ @exceptNull
321
+ def length(self):
322
+ len = c_double()
323
+ retval = lgeos.GEOSLength(self._geom, byref(len))
324
+ return len.value
325
+
326
+ @exceptEitherNull
327
+ def distance(self, other):
328
+ d = c_double()
329
+ retval = lgeos.GEOSDistance(self._geom, other._geom, byref(d))
330
+ return d.value
331
+
332
+ # Topology operations
333
+ #
334
+ # These use descriptors to reduce the amount of boilerplate.
335
+
336
+ envelope = UnaryTopologicalOp(lgeos.GEOSEnvelope, geom_factory)
337
+ intersection = BinaryTopologicalOp(lgeos.GEOSIntersection, geom_factory)
338
+ convex_hull = UnaryTopologicalOp(lgeos.GEOSConvexHull, geom_factory)
339
+ difference = BinaryTopologicalOp(lgeos.GEOSDifference, geom_factory)
340
+ symmetric_difference = BinaryTopologicalOp(lgeos.GEOSSymDifference,
341
+ geom_factory)
342
+ boundary = UnaryTopologicalOp(lgeos.GEOSBoundary, geom_factory)
343
+ union = BinaryTopologicalOp(lgeos.GEOSUnion, geom_factory)
344
+ centroid = UnaryTopologicalOp(lgeos.GEOSGetCentroid, geom_factory)
345
+
346
+ # Buffer has a unique distance argument, so not a descriptor
347
+ @exceptNull
348
+ def buffer(self, distance, quadsegs=16):
349
+ return geom_factory(
350
+ lgeos.GEOSBuffer(self._geom, c_double(distance), c_int(quadsegs))
351
+ )
352
+
353
+ # Relate has a unique string return value
354
+ @exceptNull
355
+ def relate(self, other):
356
+ func = lgeos.GEOSRelate
357
+ def errcheck(result, func, argtuple):
358
+ retval = result.value
359
+ free(result)
360
+ return retval
361
+ func.restype = allocated_c_char_p
362
+ func.errcheck = errcheck
363
+ return lgeos.GEOSRelate(self._geom, other._geom)
364
+
365
+ # Binary predicates
366
+ #
367
+ # These use descriptors to reduce the amount of boilerplate.
368
+
369
+ # TODO: Relate Pattern?
370
+ disjoint = BinaryPredicate(lgeos.GEOSDisjoint)
371
+ touches = BinaryPredicate(lgeos.GEOSTouches)
372
+ intersects = BinaryPredicate(lgeos.GEOSIntersects)
373
+ crosses = BinaryPredicate(lgeos.GEOSCrosses)
374
+ within = BinaryPredicate(lgeos.GEOSWithin)
375
+ contains = BinaryPredicate(lgeos.GEOSContains)
376
+ overlaps = BinaryPredicate(lgeos.GEOSOverlaps)
377
+ equals = BinaryPredicate(lgeos.GEOSEquals)
378
+
379
+ # Unary predicates
380
+ #
381
+ # These use descriptors to reduce the amount of boilerplate.
382
+
383
+ is_empty = UnaryPredicate(lgeos.GEOSisEmpty)
384
+ is_valid = UnaryPredicate(lgeos.GEOSisValid)
385
+ is_simple = UnaryPredicate(lgeos.GEOSisSimple)
386
+ is_ring = UnaryPredicate(lgeos.GEOSisRing)
387
+ has_z = UnaryPredicate(lgeos.GEOSHasZ)
388
+
389
+ @property
390
+ @exceptNull
391
+ def bounds(self):
392
+ env = self.envelope
393
+ if env.geom_type != 'Polygon':
394
+ raise ValueError, env.wkt
395
+ cs = lgeos.GEOSGeom_getCoordSeq(env.exterior._geom)
396
+ cs_len = c_int(0)
397
+ lgeos.GEOSCoordSeq_getSize(cs, byref(cs_len))
398
+
399
+ minx = 1.e+20
400
+ maxx = -1e+20
401
+ miny = 1.e+20
402
+ maxy = -1e+20
403
+ temp = c_double()
404
+ for i in xrange(cs_len.value):
405
+ lgeos.GEOSCoordSeq_getX(cs, i, byref(temp))
406
+ x = temp.value
407
+ if x < minx: minx = x
408
+ if x > maxx: maxx = x
409
+ lgeos.GEOSCoordSeq_getY(cs, i, byref(temp))
410
+ y = temp.value
411
+ if y < miny: miny = y
412
+ if y > maxy: maxy = y
413
+
414
+ return (minx, miny, maxx, maxy)
415
+
Binary file
@@ -0,0 +1,24 @@
1
+ """
2
+ Geometry collections.
3
+ """
4
+
5
+ from shapely.geometry.base import BaseGeometry
6
+
7
+ class GeometryCollection(BaseGeometry):
8
+
9
+ """A geometry collection.
10
+ """
11
+
12
+ def __init__(self):
13
+ BaseGeometry.__init__(self)
14
+
15
+
16
+ # Test runner
17
+ def _test():
18
+ import doctest
19
+ doctest.testmod()
20
+
21
+
22
+ if __name__ == "__main__":
23
+ _test()
24
+
Binary file