shapely 1.2.7__py2.7-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,595 @@
1
+ """Base geometry class and utilities
2
+ """
3
+
4
+ from functools import wraps
5
+ import sys
6
+ import warnings
7
+
8
+ from shapely.coords import CoordinateSequence
9
+ from shapely.geos import lgeos
10
+ from shapely.impl import DefaultImplementation, delegated
11
+ from shapely import wkb, wkt
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
+ def geom_factory(g, parent=None):
30
+ # Abstract geometry factory for use with topological methods below
31
+ if not g:
32
+ raise ValueError("No Shapely geometry can be created from null value")
33
+ ob = BaseGeometry()
34
+ geom_type = geometry_type_name(g)
35
+ # TODO: check cost of dynamic import by profiling
36
+ mod = __import__(
37
+ 'shapely.geometry',
38
+ globals(),
39
+ locals(),
40
+ [geom_type],
41
+ )
42
+ ob.__class__ = getattr(mod, geom_type)
43
+ ob.__geom__ = g
44
+ ob.__p__ = parent
45
+ if lgeos.methods['has_z'](g):
46
+ ob._ndim = 3
47
+ else:
48
+ ob._ndim = 2
49
+ return ob
50
+
51
+ def exceptNull(func):
52
+ """Decorator which helps avoid GEOS operations on null pointers."""
53
+ @wraps(func)
54
+ def wrapper(*args, **kwargs):
55
+ if not args[0]._geom or args[0].is_empty:
56
+ raise ValueError("Null/empty geometry supports no operations")
57
+ return func(*args, **kwargs)
58
+ return wrapper
59
+
60
+ EMPTY = wkb.deserialize('010700000000000000'.decode('hex'))
61
+
62
+ class BaseGeometry(object):
63
+ """
64
+ Provides GEOS spatial predicates and topological operations.
65
+
66
+ """
67
+
68
+ # Attributes
69
+ # ----------
70
+ # __geom__ : c_void_p
71
+ # Cached ctypes pointer to GEOS geometry. Not to be accessed.
72
+ # _geom : c_void_p
73
+ # Property by which the GEOS geometry is accessed.
74
+ # __p__ : object
75
+ # Parent (Shapely) geometry
76
+ # _ctypes_data : object
77
+ # Cached ctypes data buffer
78
+ # _ndim : int
79
+ # Number of dimensions (2 or 3, generally)
80
+ # _crs : object
81
+ # Coordinate reference system. Available for Shapely extensions, but
82
+ # not implemented here.
83
+ # _owned : bool
84
+ # True if this object's GEOS geometry is owned by another as in the case
85
+ # of a multipart geometry member.
86
+ __geom__ = EMPTY
87
+ __p__ = None
88
+ _ctypes_data = None
89
+ _ndim = None
90
+ _crs = None
91
+ _owned = False
92
+
93
+ # Backend config
94
+ impl = DefaultImplementation
95
+
96
+ @property
97
+ def _is_empty(self):
98
+ return self.__geom__ in [EMPTY, None]
99
+
100
+ # a reference to the so/dll proxy to preserve access during clean up
101
+ _lgeos = lgeos
102
+
103
+ def empty(self):
104
+ # TODO: defer cleanup to the implementation. We shouldn't be
105
+ # explicitly calling a lgeos method here.
106
+ if not (self._owned or self._is_empty):
107
+ self._lgeos.GEOSGeom_destroy(self.__geom__)
108
+ self.__geom__ = EMPTY
109
+
110
+ def __del__(self):
111
+ self.empty()
112
+ self.__geom__ = None
113
+ self.__p__ = None
114
+
115
+ def __str__(self):
116
+ return self.to_wkt()
117
+
118
+ # To support pickling
119
+ def __reduce__(self):
120
+ return (self.__class__, (), self.to_wkb())
121
+
122
+ def __setstate__(self, state):
123
+ self.empty()
124
+ self.__geom__ = wkb.deserialize(state)
125
+
126
+ # The _geom property
127
+ def _get_geom(self):
128
+ return self.__geom__
129
+ def _set_geom(self, val):
130
+ self.empty()
131
+ self.__geom__ = val
132
+ _geom = property(_get_geom, _set_geom)
133
+
134
+ # Array and ctypes interfaces
135
+ # ---------------------------
136
+
137
+ @property
138
+ def ctypes(self):
139
+ """Return ctypes buffer"""
140
+ raise NotImplementedError
141
+
142
+ @property
143
+ def array_interface_base(self):
144
+ if sys.byteorder == 'little':
145
+ typestr = '<f8'
146
+ elif sys.byteorder == 'big':
147
+ typestr = '>f8'
148
+ else:
149
+ raise ValueError(
150
+ "Unsupported byteorder: neither little nor big-endian")
151
+ return {
152
+ 'version': 3,
153
+ 'typestr': typestr,
154
+ 'data': self.ctypes,
155
+ }
156
+
157
+ @property
158
+ def __array_interface__(self):
159
+ """Provide the Numpy array protocol."""
160
+ raise NotImplementedError
161
+
162
+ # Coordinate access
163
+ # -----------------
164
+
165
+ def _get_coords(self):
166
+ """Access to geometry's coordinates (CoordinateSequence)"""
167
+ if self.is_empty:
168
+ return []
169
+ return CoordinateSequence(self)
170
+
171
+ def _set_coords(self, ob):
172
+ raise NotImplementedError(
173
+ "set_coords must be provided by derived classes")
174
+
175
+ coords = property(_get_coords, _set_coords)
176
+
177
+ @property
178
+ def xy(self):
179
+ """Separate arrays of X and Y coordinate values"""
180
+ raise NotImplementedError
181
+
182
+ # Python feature protocol
183
+
184
+ @property
185
+ def __geo_interface__(self):
186
+ """Dictionary representation of the geometry"""
187
+ raise NotImplementedError
188
+
189
+ # Type of geometry and its representations
190
+ # ----------------------------------------
191
+
192
+ def geometryType(self):
193
+ return geometry_type_name(self._geom)
194
+
195
+ @property
196
+ def type(self):
197
+ return self.geometryType()
198
+
199
+ def to_wkb(self):
200
+ return wkb.dumps(self)
201
+
202
+ def to_wkt(self):
203
+ return wkt.dumps(self)
204
+
205
+ geom_type = property(geometryType,
206
+ doc="""Name of the geometry's type, such as 'Point'"""
207
+ )
208
+ wkt = property(to_wkt,
209
+ doc="""WKT representation of the geometry""")
210
+ wkb = property(to_wkb,
211
+ doc="""WKB representation of the geometry""")
212
+
213
+ # Real-valued properties and methods
214
+ # ----------------------------------
215
+
216
+ @property
217
+ def area(self):
218
+ """Unitless area of the geometry (float)"""
219
+ return self.impl['area'](self)
220
+
221
+ def distance(self, other):
222
+ """Unitless distance to other geometry (float)"""
223
+ return self.impl['distance'](self, other)
224
+
225
+ @property
226
+ def length(self):
227
+ """Unitless length of the geometry (float)"""
228
+ return self.impl['length'](self)
229
+
230
+ # Topological properties
231
+ # ----------------------
232
+
233
+ @property
234
+ def boundary(self):
235
+ """Returns a lower dimension geometry that bounds the object
236
+
237
+ The boundary of a polygon is a line, the boundary of a line is a
238
+ collection of points. The boundary of a point is an empty (null)
239
+ collection.
240
+ """
241
+ return geom_factory(self.impl['boundary'](self))
242
+
243
+ @property
244
+ def bounds(self):
245
+ """Returns minimum bounding region (minx, miny, maxx, maxy)"""
246
+ if self.is_empty:
247
+ return ()
248
+ else:
249
+ return self.impl['bounds'](self)
250
+
251
+ @property
252
+ def centroid(self):
253
+ """Returns the geometric center of the object"""
254
+ return geom_factory(self.impl['centroid'](self))
255
+
256
+ @delegated
257
+ def representative_point(self):
258
+ """Returns a point guaranteed to be within the object, cheaply."""
259
+ return geom_factory(self.impl['representative_point'](self))
260
+
261
+ @property
262
+ def convex_hull(self):
263
+ """Imagine an elastic band stretched around the geometry: that's a
264
+ convex hull, more or less
265
+
266
+ The convex hull of a three member multipoint, for example, is a
267
+ triangular polygon.
268
+ """
269
+ return geom_factory(self.impl['convex_hull'](self))
270
+
271
+ @property
272
+ def envelope(self):
273
+ """A figure that envelopes the geometry"""
274
+ return geom_factory(self.impl['envelope'](self))
275
+
276
+ def buffer(self, distance, resolution=16, quadsegs=None):
277
+ """Returns a geometry with an envelope at a distance from the object's
278
+ envelope
279
+
280
+ A negative distance has a "shrink" effect. A zero distance may be used
281
+ to "tidy" a polygon. The resolution of the buffer around each vertex of
282
+ the object increases by increasing the resolution keyword parameter
283
+ or second positional parameter. Note: the use of a `quadsegs` parameter
284
+ is deprecated and will be gone from the next major release.
285
+
286
+ Example:
287
+
288
+ >>> from shapely.wkt import loads
289
+ >>> g = loads('POINT (0.0 0.0)')
290
+ >>> g.buffer(1.0).area # 16-gon approx of a unit radius circle
291
+ 3.1365484905459389
292
+ >>> g.buffer(1.0, 128).area # 128-gon approximation
293
+ 3.1415138011443009
294
+ >>> g.buffer(1.0, 3).area # triangle approximation
295
+ 3.0
296
+ """
297
+ if quadsegs is not None:
298
+ warnings.warn(
299
+ "The `quadsegs` argument is deprecated. Use `resolution`.",
300
+ DeprecationWarning)
301
+ res = quadsegs
302
+ else:
303
+ res = resolution
304
+ return geom_factory(self.impl['buffer'](self, distance, res))
305
+
306
+ @delegated
307
+ def simplify(self, tolerance, preserve_topology=True):
308
+ """Returns a simplified geometry produced by the Douglas-Puecker
309
+ algorithm
310
+
311
+ Coordinates of the simplified geometry will be no more than the
312
+ tolerance distance from the original. Unless the topology preserving
313
+ option is used, the algorithm may produce self-intersecting or
314
+ otherwise invalid geometries.
315
+ """
316
+ if preserve_topology:
317
+ op = self.impl['topology_preserve_simplify']
318
+ else:
319
+ op = self.impl['simplify']
320
+ return geom_factory(op(self, tolerance))
321
+
322
+ # Binary operations
323
+ # -----------------
324
+
325
+ def difference(self, other):
326
+ """Returns the difference of the geometries"""
327
+ return geom_factory(self.impl['difference'](self, other))
328
+
329
+ def intersection(self, other):
330
+ """Returns the intersection of the geometries"""
331
+ return geom_factory(self.impl['intersection'](self, other))
332
+
333
+ def symmetric_difference(self, other):
334
+ """Returns the symmetric difference of the geometries
335
+ (Shapely geometry)"""
336
+ return geom_factory(self.impl['symmetric_difference'](self, other))
337
+
338
+ def union(self, other):
339
+ """Returns the union of the geometries (Shapely geometry)"""
340
+ return geom_factory(self.impl['union'](self, other))
341
+
342
+ # Unary predicates
343
+ # ----------------
344
+
345
+ @property
346
+ def has_z(self):
347
+ """True if the geometry's coordinate sequence(s) have z values (are
348
+ 3-dimensional)"""
349
+ return bool(self.impl['has_z'](self))
350
+
351
+ @property
352
+ def is_empty(self):
353
+ """True if the set of points in this geometry is empty, else False"""
354
+ return bool(self.impl['is_empty'](self)) or (self._geom is None)
355
+
356
+ @property
357
+ def is_ring(self):
358
+ """True if the geometry is a closed ring, else False"""
359
+ return bool(self.impl['is_ring'](self))
360
+
361
+ @property
362
+ def is_simple(self):
363
+ """True if the geometry is simple, meaning that any self-intersections
364
+ are only at boundary points, else False"""
365
+ return bool(self.impl['is_simple'](self))
366
+
367
+ @property
368
+ def is_valid(self):
369
+ """True if the geometry is valid (definition depends on sub-class),
370
+ else False"""
371
+ return bool(self.impl['is_valid'](self))
372
+
373
+ # Binary predicates
374
+ # -----------------
375
+
376
+ def relate(self, other):
377
+ """Returns the DE-9IM intersection matrix for the two geometries
378
+ (string)"""
379
+ return self.impl['relate'](self, other)
380
+
381
+ def contains(self, other):
382
+ """Returns True if the geometry contains the other, else False"""
383
+ return bool(self.impl['contains'](self, other))
384
+
385
+ def crosses(self, other):
386
+ """Returns True if the geometries cross, else False"""
387
+ return bool(self.impl['crosses'](self, other))
388
+
389
+ def disjoint(self, other):
390
+ """Returns True if geometries are disjoint, else False"""
391
+ return bool(self.impl['disjoint'](self, other))
392
+
393
+ def equals(self, other):
394
+ """Returns True if geometries are equal, else False"""
395
+ return bool(self.impl['equals'](self, other))
396
+
397
+ def intersects(self, other):
398
+ """Returns True if geometries intersect, else False"""
399
+ return bool(self.impl['intersects'](self, other))
400
+
401
+ def overlaps(self, other):
402
+ """Returns True if geometries overlap, else False"""
403
+ return bool(self.impl['overlaps'](self, other))
404
+
405
+ def touches(self, other):
406
+ """Returns True if geometries touch, else False"""
407
+ return bool(self.impl['touches'](self, other))
408
+
409
+ def within(self, other):
410
+ """Returns True if geometry is within the other, else False"""
411
+ return bool(self.impl['within'](self, other))
412
+
413
+ def equals_exact(self, other, tolerance):
414
+ """Returns True if geometries are equal to within a specified
415
+ tolerance"""
416
+ # return BinaryPredicateOp('equals_exact', self)(other, tolerance)
417
+ return bool(self.impl['equals_exact'](self, other, tolerance))
418
+
419
+ def almost_equals(self, other, decimal=6):
420
+ """Returns True if geometries are equal at all coordinates to a
421
+ specified decimal place"""
422
+ return self.equals_exact(other, 0.5 * 10**(-decimal))
423
+
424
+ # Linear referencing
425
+ # ------------------
426
+
427
+ @delegated
428
+ def project(self, other, normalized=False):
429
+ """Returns the distance along this geometry to a point nearest the
430
+ specified point
431
+
432
+ If the normalized arg is True, return the distance normalized to the
433
+ length of the linear geometry.
434
+ """
435
+ if normalized:
436
+ op = self.impl['project_normalized']
437
+ else:
438
+ op = self.impl['project']
439
+ return op(self, other)
440
+
441
+ @delegated
442
+ def interpolate(self, distance, normalized=False):
443
+ """Return a point at the specified distance along a linear geometry
444
+
445
+ If the normalized arg is True, the distance will be interpreted as a
446
+ fraction of the geometry's length.
447
+ """
448
+ if normalized:
449
+ op = self.impl['interpolate_normalized']
450
+ else:
451
+ op = self.impl['interpolate']
452
+ return geom_factory(op(self, distance))
453
+
454
+
455
+ class BaseMultipartGeometry(BaseGeometry):
456
+
457
+ def shape_factory(self, *args):
458
+ # Factory for part instances, usually a geometry class
459
+ raise NotImplementedError("To be implemented by derived classes")
460
+
461
+ @property
462
+ def ctypes(self):
463
+ raise NotImplementedError(
464
+ "Multi-part geometries have no ctypes representations")
465
+
466
+ @property
467
+ def __array_interface__(self):
468
+ """Provide the Numpy array protocol."""
469
+ raise NotImplementedError(
470
+ "Multi-part geometries do not themselves provide the array interface")
471
+
472
+ def _get_coords(self):
473
+ raise NotImplementedError(
474
+ "Sub-geometries may have coordinate sequences, but collections do not")
475
+
476
+ def _set_coords(self, ob):
477
+ raise NotImplementedError(
478
+ "Sub-geometries may have coordinate sequences, but collections do not")
479
+
480
+ @property
481
+ def coords(self):
482
+ raise NotImplementedError(
483
+ "Multi-part geometries do not provide a coordinate sequence")
484
+
485
+ @property
486
+ def geoms(self):
487
+ if self.is_empty:
488
+ return []
489
+ return GeometrySequence(self, self.shape_factory)
490
+
491
+ def __iter__(self):
492
+ if not self.is_empty:
493
+ return iter(self.geoms)
494
+ else:
495
+ return iter([])
496
+
497
+ def __len__(self):
498
+ if not self.is_empty:
499
+ return len(self.geoms)
500
+ else:
501
+ return 0
502
+
503
+ def __getitem__(self, index):
504
+ if not self.is_empty:
505
+ return self.geoms[index]
506
+ else:
507
+ return ()[index]
508
+
509
+
510
+ class GeometrySequence(object):
511
+ """
512
+ Iterative access to members of a homogeneous multipart geometry.
513
+ """
514
+
515
+ # Attributes
516
+ # ----------
517
+ # _factory : callable
518
+ # Returns instances of Shapely geometries
519
+ # _geom : c_void_p
520
+ # Ctypes pointer to the parent's GEOS geometry
521
+ # _ndim : int
522
+ # Number of dimensions (2 or 3, generally)
523
+ # __p__ : object
524
+ # Parent (Shapely) geometry
525
+ shape_factory = None
526
+ _geom = None
527
+ __p__ = None
528
+ _ndim = None
529
+
530
+ def __init__(self, parent, type):
531
+ self.shape_factory = type
532
+ self.__p__ = parent
533
+
534
+ def _update(self):
535
+ self._geom = self.__p__._geom
536
+ self._ndim = self.__p__._ndim
537
+
538
+ def _get_geom_item(self, i):
539
+ g = self.shape_factory()
540
+ g._owned = True
541
+ g._geom = lgeos.GEOSGetGeometryN(self._geom, i)
542
+ g._ndim = self._ndim
543
+ g.__p__ = self
544
+ return g
545
+
546
+ def __iter__(self):
547
+ self._update()
548
+ for i in range(self.__len__()):
549
+ yield self._get_geom_item(i)
550
+
551
+ def __len__(self):
552
+ self._update()
553
+ return lgeos.GEOSGetNumGeometries(self._geom)
554
+
555
+ def __getitem__(self, i):
556
+ self._update()
557
+ M = self.__len__()
558
+ if i + M < 0 or i >= M:
559
+ raise IndexError("index out of range")
560
+ if i < 0:
561
+ ii = M + i
562
+ else:
563
+ ii = i
564
+ return self._get_geom_item(i)
565
+
566
+ @property
567
+ def _longest(self):
568
+ max = 0
569
+ for g in iter(self):
570
+ l = len(g.coords)
571
+ if l > max:
572
+ max = l
573
+
574
+
575
+ class HeterogeneousGeometrySequence(GeometrySequence):
576
+ """
577
+ Iterative access to a heterogeneous sequence of geometries.
578
+ """
579
+
580
+ def __init__(self, parent):
581
+ super(HeterogeneousGeometrySequence, self).__init__(parent, None)
582
+
583
+ def _get_geom_item(self, i):
584
+ sub = lgeos.GEOSGetGeometryN(self._geom, i)
585
+ g = geom_factory(sub)
586
+ g._owned = True
587
+ return g
588
+
589
+ # Test runner
590
+ def _test():
591
+ import doctest
592
+ doctest.testmod()
593
+
594
+ if __name__ == "__main__":
595
+ _test()
Binary file
@@ -0,0 +1,43 @@
1
+ """Multi-part collections of geometries
2
+ """
3
+
4
+ from shapely.geometry.base import BaseMultipartGeometry
5
+ from shapely.geometry.base import HeterogeneousGeometrySequence
6
+
7
+
8
+ class GeometryCollection(BaseMultipartGeometry):
9
+
10
+ """A heterogenous collection of geometries
11
+
12
+ Attributes
13
+ ----------
14
+ geoms : sequence
15
+ A sequence of Shapely geometry instances
16
+ """
17
+
18
+ def __init__(self):
19
+ BaseMultipartGeometry.__init__(self)
20
+
21
+ @property
22
+ def __geo_interface__(self):
23
+ geometries = []
24
+ for geom in self.geoms:
25
+ geometries.append(geom.__geo_interface__)
26
+ return dict(type='GeometryCollection', geometries=geometries)
27
+
28
+ @property
29
+ def geoms(self):
30
+ if self.is_empty:
31
+ return []
32
+ return HeterogeneousGeometrySequence(self)
33
+
34
+
35
+ # Test runner
36
+ def _test():
37
+ import doctest
38
+ doctest.testmod()
39
+
40
+
41
+ if __name__ == "__main__":
42
+ _test()
43
+
Binary file
@@ -0,0 +1,68 @@
1
+ """
2
+ Geometry factories based on the geo interface
3
+ """
4
+
5
+ from point import Point, asPoint
6
+ from linestring import LineString, asLineString
7
+ from polygon import Polygon, asPolygon
8
+ from multipoint import MultiPoint, asMultiPoint
9
+ from multilinestring import MultiLineString, asMultiLineString
10
+ from multipolygon import MultiPolygon, MultiPolygonAdapter, asMultiPolygon
11
+
12
+
13
+ def shape(context):
14
+ """Return a new, independent geometry with coordinates *copied* from the
15
+ context.
16
+ """
17
+ if hasattr(context, "__geo_interface__"):
18
+ ob = context.__geo_interface__
19
+ else:
20
+ ob = context
21
+ geom_type = ob.get("type").lower()
22
+ if geom_type == "point":
23
+ return Point(ob["coordinates"])
24
+ elif geom_type == "linestring":
25
+ return LineString(ob["coordinates"])
26
+ elif geom_type == "polygon":
27
+ return Polygon(ob["coordinates"][0], ob["coordinates"][1:])
28
+ elif geom_type == "multipoint":
29
+ return MultiPoint(ob["coordinates"])
30
+ elif geom_type == "multilinestring":
31
+ return MultiLineString(ob["coordinates"])
32
+ elif geom_type == "multipolygon":
33
+ return MultiPolygon(ob["coordinates"], context_type='geojson')
34
+ else:
35
+ raise ValueError("Unknown geometry type: %s" % geom_type)
36
+
37
+ def asShape(context):
38
+ """Adapts the context to a geometry interface. The coordinates remain
39
+ stored in the context.
40
+ """
41
+ if hasattr(context, "__geo_interface__"):
42
+ ob = context.__geo_interface__
43
+ else:
44
+ ob = context
45
+
46
+ try:
47
+ geom_type = ob.get("type").lower()
48
+ except AttributeError:
49
+ raise ValueError("Context does not provide geo interface")
50
+
51
+ if geom_type == "point":
52
+ return asPoint(ob["coordinates"])
53
+ elif geom_type == "linestring":
54
+ return asLineString(ob["coordinates"])
55
+ elif geom_type == "polygon":
56
+ return asPolygon(ob["coordinates"][0], ob["coordinates"][1:])
57
+ elif geom_type == "multipoint":
58
+ return asMultiPoint(ob["coordinates"])
59
+ elif geom_type == "multilinestring":
60
+ return asMultiLineString(ob["coordinates"])
61
+ elif geom_type == "multipolygon":
62
+ return MultiPolygonAdapter(ob["coordinates"], context_type='geojson')
63
+ else:
64
+ raise ValueError("Unknown geometry type: %s" % geom_type)
65
+
66
+ def mapping(ob):
67
+ """Returns a GeoJSON-like mapping"""
68
+ return ob.__geo_interface__
Binary file