shapely 1.2.2__tar.gz → 1.2.4__tar.gz

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 (76) hide show
  1. {Shapely-1.2.2 → Shapely-1.2.4}/CHANGES.txt +12 -0
  2. {Shapely-1.2.2 → Shapely-1.2.4}/PKG-INFO +1 -1
  3. {Shapely-1.2.2 → Shapely-1.2.4}/Shapely.egg-info/PKG-INFO +1 -1
  4. {Shapely-1.2.2 → Shapely-1.2.4}/Shapely.egg-info/SOURCES.txt +3 -0
  5. {Shapely-1.2.2 → Shapely-1.2.4}/docs/_build/html/_sources/manual.txt +27 -10
  6. {Shapely-1.2.2 → Shapely-1.2.4}/docs/manual.txt +27 -5
  7. {Shapely-1.2.2 → Shapely-1.2.4}/setup.py +1 -1
  8. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/ctypes_declarations.py +3 -3
  9. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/__init__.py +2 -2
  10. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/base.py +12 -5
  11. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/geo.py +4 -0
  12. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geos.py +29 -35
  13. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/impl.py +27 -1
  14. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/prepared.py +6 -2
  15. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/__init__.py +4 -0
  16. Shapely-1.2.4/shapely/tests/test_delegated.py +22 -0
  17. Shapely-1.2.4/shapely/tests/test_dlls.py +14 -0
  18. Shapely-1.2.4/shapely/tests/test_mapping.py +11 -0
  19. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/validation.py +1 -1
  20. {Shapely-1.2.2 → Shapely-1.2.4}/CREDITS.txt +0 -0
  21. {Shapely-1.2.2 → Shapely-1.2.4}/LICENSE.txt +0 -0
  22. {Shapely-1.2.2 → Shapely-1.2.4}/MANIFEST.in +0 -0
  23. {Shapely-1.2.2 → Shapely-1.2.4}/README.txt +0 -0
  24. {Shapely-1.2.2 → Shapely-1.2.4}/Shapely.egg-info/dependency_links.txt +0 -0
  25. {Shapely-1.2.2 → Shapely-1.2.4}/Shapely.egg-info/top_level.txt +0 -0
  26. {Shapely-1.2.2 → Shapely-1.2.4}/examples/dissolve.py +0 -0
  27. {Shapely-1.2.2 → Shapely-1.2.4}/examples/intersect.py +0 -0
  28. {Shapely-1.2.2 → Shapely-1.2.4}/setup.cfg +0 -0
  29. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/__init__.py +0 -0
  30. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/coords.py +0 -0
  31. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/collection.py +0 -0
  32. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/linestring.py +0 -0
  33. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/multilinestring.py +0 -0
  34. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/multipoint.py +0 -0
  35. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/multipolygon.py +0 -0
  36. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/point.py +0 -0
  37. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/polygon.py +0 -0
  38. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/proxy.py +0 -0
  39. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/iterops.py +0 -0
  40. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/linref.py +0 -0
  41. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/ops.py +0 -0
  42. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/predicates.py +0 -0
  43. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/Array.txt +0 -0
  44. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/GeoInterface.txt +0 -0
  45. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/IterOps.txt +0 -0
  46. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/LineString.txt +0 -0
  47. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/MultiLineString.txt +0 -0
  48. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/MultiPoint.txt +0 -0
  49. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/MultiPolygon.txt +0 -0
  50. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/Operations.txt +0 -0
  51. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/Persist.txt +0 -0
  52. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/Point.txt +0 -0
  53. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/Polygon.txt +0 -0
  54. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/Predicates.txt +0 -0
  55. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/attribute-chains.txt +0 -0
  56. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/binascii_hex.txt +0 -0
  57. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/cascaded_union.txt +0 -0
  58. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/dimensions.txt +0 -0
  59. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/invalid_intersection.txt +0 -0
  60. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/linear-referencing.txt +0 -0
  61. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/linemerge.txt +0 -0
  62. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/polygonize.txt +0 -0
  63. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_collection.py +0 -0
  64. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_doctests.py +0 -0
  65. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_emptiness.py +0 -0
  66. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_equality.py +0 -0
  67. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_geomseq.py +0 -0
  68. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_prepared.py +0 -0
  69. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_singularity.py +0 -0
  70. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_validation.py +0 -0
  71. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_xy.py +0 -0
  72. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/threading_test.py +0 -0
  73. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/wkt_locale.txt +0 -0
  74. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/topology.py +0 -0
  75. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/wkb.py +0 -0
  76. {Shapely-1.2.2 → Shapely-1.2.4}/shapely/wkt.py +0 -0
@@ -1,5 +1,17 @@
1
1
  All tickets are children of http://trac.gispython.org/lab/ticket.
2
2
 
3
+ 1.2.4 (2010-09-09)
4
+ ------------------
5
+ - Raise AttributeError when there's no backend support for a method.
6
+ - Raise OSError if libgeos_c.so (or variants) can't be found and loaded.
7
+ - Add geos_c DLL loading support for linux platforms where find_library
8
+ doesn't work.
9
+
10
+ 1.2.3 (2010-08-17)
11
+ ------------------
12
+ - Add mapping function.
13
+ - Fix problem with GEOSisValidReason symbol for GEOS < 3.1.
14
+
3
15
  1.2.2 (2010-07-23)
4
16
  ------------------
5
17
  - Add representative_point method.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.0
2
2
  Name: Shapely
3
- Version: 1.2.2
3
+ Version: 1.2.4
4
4
  Summary: Geometric objects, predicates, and operations
5
5
  Home-page: http://trac.gispython.org/lab/wiki/Shapely
6
6
  Author: Sean Gillies
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.0
2
2
  Name: Shapely
3
- Version: 1.2.2
3
+ Version: 1.2.4
4
4
  Summary: Geometric objects, predicates, and operations
5
5
  Home-page: http://trac.gispython.org/lab/wiki/Shapely
6
6
  Author: Sean Gillies
@@ -60,10 +60,13 @@ shapely/tests/linear-referencing.txt
60
60
  shapely/tests/linemerge.txt
61
61
  shapely/tests/polygonize.txt
62
62
  shapely/tests/test_collection.py
63
+ shapely/tests/test_delegated.py
64
+ shapely/tests/test_dlls.py
63
65
  shapely/tests/test_doctests.py
64
66
  shapely/tests/test_emptiness.py
65
67
  shapely/tests/test_equality.py
66
68
  shapely/tests/test_geomseq.py
69
+ shapely/tests/test_mapping.py
67
70
  shapely/tests/test_prepared.py
68
71
  shapely/tests/test_singularity.py
69
72
  shapely/tests/test_validation.py
@@ -3,8 +3,8 @@ The Shapely 1.2 User Manual (Preview)
3
3
  =====================================
4
4
 
5
5
  :Author: Sean Gillies, <sean.gillies@gmail.com>
6
- :Revision: 1.2.1
7
- :Date: 13 July 2010
6
+ :Revision: 1.2.3
7
+ :Date: 19 August 2010
8
8
  :Copyright:
9
9
  This work is licensed under a `Creative Commons Attribution 3.0
10
10
  United States License`__.
@@ -214,7 +214,7 @@ General Attributes and Methods
214
214
  geometric object.
215
215
 
216
216
  .. note::
217
- This is not in the general the same as the centroid.
217
+ This is not in general the same as the centroid.
218
218
 
219
219
  .. sourcecode:: pycon
220
220
 
@@ -224,11 +224,6 @@ General Attributes and Methods
224
224
  >>> donut.representative_point().wkt
225
225
  'POINT (-1.5000000000000000 0.0000000000000000)'
226
226
 
227
- .. sourcecode:: pycon
228
-
229
- >>> Point(0,0).distance(Point(1,1))
230
- 1.4142135623730951
231
-
232
227
  .. _points:
233
228
 
234
229
  Points
@@ -1387,8 +1382,8 @@ Figure 1. Convex hull (blue) of 2 points (left) and of 6 points (right).
1387
1382
 
1388
1383
  .. attribute:: object.envelope
1389
1384
 
1390
- Returns a representation of the point or smallest rectangular polygon that
1391
- contains the object.
1385
+ Returns a representation of the point or smallest rectangular polygon (with
1386
+ sides parallel to the coordinate axes) that contains the object.
1392
1387
 
1393
1388
  .. sourcecode:: pycon
1394
1389
 
@@ -1714,6 +1709,28 @@ Or a simple placemark-type object:
1714
1709
  >>> list(shape.coords)
1715
1710
  [(0.0, 0.0)]
1716
1711
 
1712
+ The GeoJSON-like mapping of a geometric object can be obtained using
1713
+ :func:`shapely.geometry.mapping`.
1714
+
1715
+ .. function:: shapely.geometry.mapping(ob)
1716
+
1717
+ Return a new, independent geometry with coordinates `copied` from the
1718
+ context.
1719
+
1720
+ `New in version 1.2.3`.
1721
+
1722
+ For example, using the same `GeoThing` class:
1723
+
1724
+ .. sourcecode:: pycon
1725
+
1726
+ >>> from shapely.geometry import mapping
1727
+ >>> thing = GeoThing({"type": "Point", "coordinates": (0.0, 0.0)})
1728
+ >>> m = mapping(thing)
1729
+ >>> m['type']
1730
+ 'Point'
1731
+ >>> m['coordinates']
1732
+ (0.0, 0.0)}
1733
+
1717
1734
  Conclusion
1718
1735
  ==========
1719
1736
 
@@ -3,8 +3,8 @@ The Shapely 1.2 User Manual (Preview)
3
3
  =====================================
4
4
 
5
5
  :Author: Sean Gillies, <sean.gillies@gmail.com>
6
- :Revision: 1.2.1
7
- :Date: 13 July 2010
6
+ :Revision: 1.2.3
7
+ :Date: 19 August 2010
8
8
  :Copyright:
9
9
  This work is licensed under a `Creative Commons Attribution 3.0
10
10
  United States License`__.
@@ -214,7 +214,7 @@ General Attributes and Methods
214
214
  geometric object.
215
215
 
216
216
  .. note::
217
- This is not in the general the same as the centroid.
217
+ This is not in general the same as the centroid.
218
218
 
219
219
  .. sourcecode:: pycon
220
220
 
@@ -1382,8 +1382,8 @@ Figure 1. Convex hull (blue) of 2 points (left) and of 6 points (right).
1382
1382
 
1383
1383
  .. attribute:: object.envelope
1384
1384
 
1385
- Returns a representation of the point or smallest rectangular polygon that
1386
- contains the object.
1385
+ Returns a representation of the point or smallest rectangular polygon (with
1386
+ sides parallel to the coordinate axes) that contains the object.
1387
1387
 
1388
1388
  .. sourcecode:: pycon
1389
1389
 
@@ -1709,6 +1709,28 @@ Or a simple placemark-type object:
1709
1709
  >>> list(shape.coords)
1710
1710
  [(0.0, 0.0)]
1711
1711
 
1712
+ The GeoJSON-like mapping of a geometric object can be obtained using
1713
+ :func:`shapely.geometry.mapping`.
1714
+
1715
+ .. function:: shapely.geometry.mapping(ob)
1716
+
1717
+ Return a new, independent geometry with coordinates `copied` from the
1718
+ context.
1719
+
1720
+ `New in version 1.2.3`.
1721
+
1722
+ For example, using the same `GeoThing` class:
1723
+
1724
+ .. sourcecode:: pycon
1725
+
1726
+ >>> from shapely.geometry import mapping
1727
+ >>> thing = GeoThing({"type": "Point", "coordinates": (0.0, 0.0)})
1728
+ >>> m = mapping(thing)
1729
+ >>> m['type']
1730
+ 'Point'
1731
+ >>> m['coordinates']
1732
+ (0.0, 0.0)}
1733
+
1712
1734
  Conclusion
1713
1735
  ==========
1714
1736
 
@@ -16,7 +16,7 @@ readme_text = file('README.txt', 'rb').read()
16
16
  setup_args = dict(
17
17
  metadata_version = '1.2',
18
18
  name = 'Shapely',
19
- version = '1.2.2',
19
+ version = '1.2.4',
20
20
  requires_python = '>=2.5,<3',
21
21
  requires_external = 'libgeos_c (>=3.1)',
22
22
  description = 'Geometric objects, predicates, and operations',
@@ -167,9 +167,6 @@ def prototype(lgeos, geosVersion):
167
167
  lgeos.GEOSisValid.restype = ctypes.c_byte
168
168
  lgeos.GEOSisValid.argtypes = [ctypes.c_void_p]
169
169
 
170
- lgeos.GEOSisValidReason.restype = allocated_c_char_p
171
- lgeos.GEOSisValidReason.argtypes = [ctypes.c_void_p]
172
-
173
170
  lgeos.GEOSisSimple.restype = ctypes.c_byte
174
171
  lgeos.GEOSisSimple.argtypes = [ctypes.c_void_p]
175
172
 
@@ -249,6 +246,9 @@ def prototype(lgeos, geosVersion):
249
246
  lgeos.GEOSPreparedCovers.restype = ctypes.c_int
250
247
  lgeos.GEOSPreparedCovers.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
251
248
 
249
+ lgeos.GEOSisValidReason.restype = allocated_c_char_p
250
+ lgeos.GEOSisValidReason.argtypes = [ctypes.c_void_p]
251
+
252
252
  # Other, GEOS C API 1.5.0+
253
253
  if geosVersion >= (1, 5, 0):
254
254
  lgeos.GEOSUnionCascaded.restype = ctypes.c_void_p
@@ -1,7 +1,7 @@
1
1
  """Geometry classes and factories
2
2
  """
3
3
 
4
- from geo import shape, asShape
4
+ from geo import shape, asShape, mapping
5
5
  from point import Point, asPoint
6
6
  from linestring import LineString, asLineString
7
7
  from polygon import Polygon, asPolygon
@@ -14,7 +14,7 @@ __all__ = [
14
14
  'shape', 'asShape', 'Point', 'asPoint', 'LineString', 'asLineString',
15
15
  'Polygon', 'asPolygon', 'MultiPoint', 'asMultiPoint',
16
16
  'MultiLineString', 'asMultiLineString', 'MultiPolygon', 'asMultiPolygon',
17
- 'GeometryCollection'
17
+ 'GeometryCollection', 'mapping'
18
18
  ]
19
19
 
20
20
 
@@ -7,7 +7,7 @@ import warnings
7
7
 
8
8
  from shapely.coords import CoordinateSequence
9
9
  from shapely.geos import lgeos
10
- from shapely.impl import DefaultImplementation
10
+ from shapely.impl import DefaultImplementation, delegated
11
11
  from shapely import wkb, wkt
12
12
 
13
13
  GEOMETRY_TYPES = [
@@ -94,10 +94,14 @@ class BaseGeometry(object):
94
94
  def _is_empty(self):
95
95
  return self.__geom__ in [EMPTY, None]
96
96
 
97
+ # a reference to the so/dll proxy to preserve access during clean up
98
+ _lgeos = lgeos
99
+
97
100
  def empty(self):
101
+ # TODO: defer cleanup to the implementation. We shouldn't be
102
+ # explicitly calling a lgeos method here.
98
103
  if not (self._owned or self._is_empty):
99
- from shapely.geos import lgeos
100
- lgeos.GEOSGeom_destroy(self.__geom__)
104
+ self._lgeos.GEOSGeom_destroy(self.__geom__)
101
105
  self.__geom__ = EMPTY
102
106
 
103
107
  def __del__(self):
@@ -246,6 +250,7 @@ class BaseGeometry(object):
246
250
  """Returns the geometric center of the object"""
247
251
  return geom_factory(self.impl['centroid'](self))
248
252
 
253
+ @delegated
249
254
  def representative_point(self):
250
255
  """Returns a point guaranteed to be within the object, cheaply."""
251
256
  return geom_factory(self.impl['representative_point'](self))
@@ -295,6 +300,7 @@ class BaseGeometry(object):
295
300
  res = resolution
296
301
  return geom_factory(self.impl['buffer'](self, distance, res))
297
302
 
303
+ @delegated
298
304
  def simplify(self, tolerance, preserve_topology=True):
299
305
  """Returns a simplified geometry produced by the Douglas-Puecker
300
306
  algorithm
@@ -415,6 +421,7 @@ class BaseGeometry(object):
415
421
  # Linear referencing
416
422
  # ------------------
417
423
 
424
+ @delegated
418
425
  def project(self, other, normalized=False):
419
426
  """Returns the distance along this geometry to a point nearest the
420
427
  specified point
@@ -427,7 +434,8 @@ class BaseGeometry(object):
427
434
  else:
428
435
  op = self.impl['project']
429
436
  return op(self, other)
430
-
437
+
438
+ @delegated
431
439
  def interpolate(self, distance, normalized=False):
432
440
  """Return a point at the specified distance along a linear geometry
433
441
 
@@ -574,7 +582,6 @@ class HeterogeneousGeometrySequence(GeometrySequence):
574
582
  g._owned = True
575
583
  return g
576
584
 
577
-
578
585
  # Test runner
579
586
  def _test():
580
587
  import doctest
@@ -62,3 +62,7 @@ def asShape(context):
62
62
  return MultiPolygonAdapter(ob["coordinates"], context_type='geojson')
63
63
  else:
64
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__
@@ -25,30 +25,38 @@ LOG.addHandler(NullHandler())
25
25
  # Find and load the GEOS and C libraries
26
26
  # If this ever gets any longer, we'll break it into separate modules
27
27
 
28
+ def load_dll(libname, fallbacks=None):
29
+ lib = find_library(libname)
30
+ if lib is not None:
31
+ return CDLL(lib)
32
+ else:
33
+ if fallbacks is not None:
34
+ for name in fallbacks:
35
+ try:
36
+ return CDLL(name)
37
+ except OSError:
38
+ # move on to the next fallback
39
+ pass
40
+ # the end
41
+ raise OSError(
42
+ "Could not find library %s or load any of its variants %s" % (
43
+ libname, fallbacks or []))
44
+
28
45
  if sys.platform == 'linux2':
29
- _lgeos = CDLL(find_library('geos_c'))
30
- free = CDLL(find_library('c')).free
46
+ _lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so'])
47
+ free = load_dll('c').free
31
48
  free.argtypes = [c_void_p]
32
49
  free.restype = None
33
50
 
34
51
  elif sys.platform == 'darwin':
35
- lib = find_library('geos_c')
36
- if lib is None:
37
- ## try a few more locations
38
- lib_paths = [
52
+ alt_paths = [
39
53
  # The Framework build from Kyng Chaos:
40
54
  "/Library/Frameworks/GEOS.framework/Versions/Current/GEOS",
41
55
  # macports
42
56
  '/opt/local/lib/libgeos_c.dylib',
43
- ]
44
- for path in lib_paths:
45
- if os.path.exists(path):
46
- lib = path
47
- break
48
- if lib is None:
49
- raise ImportError("Could not find geos_c library")
50
- _lgeos = CDLL(lib)
51
- free = CDLL(find_library('c')).free
57
+ ]
58
+ _lgeos = load_dll('geos_c', fallbacks=alt_paths)
59
+ free = load_dll('c').free
52
60
  free.argtypes = [c_void_p]
53
61
  free.restype = None
54
62
 
@@ -58,7 +66,7 @@ elif sys.platform == 'win32':
58
66
  original_path = os.environ['PATH']
59
67
  os.environ['PATH'] = "%s;%s" % (local_dlls, original_path)
60
68
  _lgeos = CDLL("geos.dll")
61
- except (ImportError, WindowsError):
69
+ except (ImportError, WindowsError, OSError):
62
70
  raise
63
71
  def free(m):
64
72
  try:
@@ -68,28 +76,14 @@ elif sys.platform == 'win32':
68
76
  pass
69
77
 
70
78
  elif sys.platform == 'sunos5':
71
- # Try the major versioned name first, falling back on the unversioned
72
- # name.
73
- try:
74
- _lgeos = CDLL('libgeos_c.so.1')
75
- except (OSError, ImportError):
76
- _lgeos = CDLL('libgeos_c.so')
77
- except:
78
- raise
79
+ _lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so'])
79
80
  free = CDLL('libc.so.1').free
80
81
  free.argtypes = [c_void_p]
81
82
  free.restype = None
82
83
 
83
84
  else: # other *nix systems
84
- # Try the major versioned name first, falling back on the unversioned
85
- # name.
86
- try:
87
- _lgeos = CDLL('libgeos_c.so.1')
88
- except (OSError, ImportError):
89
- _lgeos = CDLL('libgeos_c.so')
90
- except:
91
- raise
92
- free = CDLL('libc.so.6').free
85
+ _lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so'])
86
+ free = load_dll('c', fallbacks=['libc.so.6']).free
93
87
  free.argtypes = [c_void_p]
94
88
  free.restype = None
95
89
 
@@ -298,6 +292,8 @@ class LGEOS15(LGEOSBase):
298
292
  ):
299
293
  pred.func.errcheck = errcheck_predicate
300
294
 
295
+ self.GEOSisValidReason.func.errcheck = errcheck_just_free
296
+
301
297
  self.methods['area'] = self.GEOSArea
302
298
  self.methods['boundary'] = self.GEOSBoundary
303
299
  self.methods['buffer'] = self.GEOSBuffer
@@ -351,8 +347,6 @@ class LGEOS16LR(LGEOS16):
351
347
  def __init__(self, dll):
352
348
  super(LGEOS16LR, self).__init__(dll)
353
349
 
354
- self.GEOSisValidReason.func.errcheck = errcheck_just_free
355
-
356
350
  self.methods['project'] = self.GEOSProject
357
351
  self.methods['project_normalized'] = self.GEOSProjectNormalized
358
352
  self.methods['interpolate'] = self.GEOSInterpolate
@@ -11,6 +11,8 @@ This is layer number 2 from the list below.
11
11
  Shapely 1.2 includes a GEOS backend and it is the default.
12
12
  """
13
13
 
14
+ from functools import wraps
15
+
14
16
  from shapely.coords import BoundsOp
15
17
  from shapely.geos import lgeos
16
18
  from shapely.linref import ProjectOp, InterpolateOp
@@ -18,9 +20,33 @@ from shapely.predicates import BinaryPredicate, UnaryPredicate
18
20
  from shapely.topology import BinaryRealProperty, BinaryTopologicalOp
19
21
  from shapely.topology import UnaryRealProperty, UnaryTopologicalOp
20
22
 
23
+ def delegated(func):
24
+ """A delegated method raises AttributeError in the absence of backend
25
+ support."""
26
+ @wraps(func)
27
+ def wrapper(*args, **kwargs):
28
+ try:
29
+ return func(*args, **kwargs)
30
+ except KeyError:
31
+ raise AttributeError, "Method '%s' is not supported by %s" % (
32
+ func.__name__, repr(args[0].impl))
33
+ return wrapper
21
34
 
22
35
  # Map geometry methods to their GEOS delegates
23
36
 
37
+ class BaseImpl(object):
38
+ def __init__(self, values):
39
+ self.map = dict(values)
40
+ def update(self, values):
41
+ self.map.update(values)
42
+ def __getitem__(self, key):
43
+ return self.map[key]
44
+
45
+ class GEOSImpl(BaseImpl):
46
+ def __repr__(self):
47
+ return '<GEOSImpl object: GEOS C API version %s>' % (
48
+ lgeos.geos_capi_version,)
49
+
24
50
  IMPL14 = {
25
51
  'area': (UnaryRealProperty, 'area'),
26
52
  'distance': (BinaryRealProperty, 'distance'),
@@ -81,7 +107,7 @@ IMPL16LR = {
81
107
  def impl_items(defs):
82
108
  return [(k, v[0](v[1])) for k, v in defs.items()]
83
109
 
84
- imp = dict(impl_items(IMPL14))
110
+ imp = GEOSImpl(dict(impl_items(IMPL14)))
85
111
  if lgeos.geos_capi_version >= (1, 5, 0):
86
112
  imp.update(impl_items(IMPL15))
87
113
  if lgeos.geos_capi_version >= (1, 6, 0):
@@ -3,7 +3,7 @@ Support for GEOS prepared geometry operations.
3
3
  """
4
4
 
5
5
  from shapely.geos import lgeos
6
- from shapely.impl import DefaultImplementation
6
+ from shapely.impl import DefaultImplementation, delegated
7
7
 
8
8
 
9
9
  class PreparedGeometry(object):
@@ -34,16 +34,20 @@ class PreparedGeometry(object):
34
34
  @property
35
35
  def _geom(self):
36
36
  return self.__geom__
37
-
37
+
38
+ @delegated
38
39
  def intersects(self, other):
39
40
  return bool(self.impl['prepared_intersects'](self, other))
40
41
 
42
+ @delegated
41
43
  def contains(self, other):
42
44
  return bool(self.impl['prepared_contains'](self, other))
43
45
 
46
+ @delegated
44
47
  def contains_properly(self, other):
45
48
  return bool(self.impl['prepared_contains_properly'](self, other))
46
49
 
50
+ @delegated
47
51
  def covers(self, other):
48
52
  return bool(self.impl['prepared_covers'](self, other))
49
53
 
@@ -2,6 +2,7 @@ from unittest import TestSuite
2
2
 
3
3
  import test_doctests, test_prepared, test_equality, test_geomseq, test_xy
4
4
  import test_collection, test_emptiness, test_singularity, test_validation
5
+ import test_mapping, test_delegated, test_dlls
5
6
 
6
7
  def test_suite():
7
8
  suite = TestSuite()
@@ -14,5 +15,8 @@ def test_suite():
14
15
  suite.addTest(test_collection.test_suite())
15
16
  suite.addTest(test_singularity.test_suite())
16
17
  suite.addTest(test_validation.test_suite())
18
+ suite.addTest(test_mapping.test_suite())
19
+ suite.addTest(test_delegated.test_suite())
20
+ suite.addTest(test_dlls.test_suite())
17
21
  return suite
18
22
 
@@ -0,0 +1,22 @@
1
+ import unittest
2
+ from shapely.geometry import Point
3
+ from shapely.impl import BaseImpl
4
+ from shapely.geometry.base import delegated
5
+
6
+ class Geometry(object):
7
+ impl = BaseImpl({})
8
+ @property
9
+ @delegated
10
+ def foo(self):
11
+ return self.impl['foo']()
12
+
13
+ class WrapperTestCase(unittest.TestCase):
14
+ """When the backend has no support for a method, we get an AttributeError"""
15
+ def test_delegated(self):
16
+ self.assertRaises(AttributeError, getattr, Geometry(), 'foo')
17
+ def test_defaultimpl(self):
18
+ del Point.impl.map['project']
19
+ self.assertRaises(AttributeError, Point(0, 0).project, 1.0)
20
+
21
+ def test_suite():
22
+ return unittest.TestLoader().loadTestsFromTestCase(WrapperTestCase)
@@ -0,0 +1,14 @@
1
+ import os
2
+ import sys
3
+ import unittest
4
+
5
+ from shapely.geos import load_dll
6
+
7
+ class LoadingTestCase(unittest.TestCase):
8
+ def test_load(self):
9
+ self.assertRaises(OSError, load_dll, 'geosh_c')
10
+ def test_fallbacks(self):
11
+ a = load_dll('geosh_c', fallbacks=['/opt/local/lib/libgeos_c.dylib'])
12
+
13
+ def test_suite():
14
+ return unittest.TestLoader().loadTestsFromTestCase(LoadingTestCase)
@@ -0,0 +1,11 @@
1
+ import unittest
2
+ from shapely.geometry import Point, mapping
3
+
4
+ class MappingTestCase(unittest.TestCase):
5
+ def test_point(self):
6
+ m = mapping(Point(0, 0))
7
+ self.failUnlessEqual(m['type'], 'Point')
8
+ self.failUnlessEqual(m['coordinates'], (0.0, 0.0))
9
+
10
+ def test_suite():
11
+ return unittest.TestLoader().loadTestsFromTestCase(MappingTestCase)
@@ -1,4 +1,4 @@
1
- #
1
+ # TODO: allow for implementations using other than GEOS
2
2
 
3
3
  from shapely.geos import lgeos
4
4
 
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes