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.
- {Shapely-1.2.2 → Shapely-1.2.4}/CHANGES.txt +12 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/PKG-INFO +1 -1
- {Shapely-1.2.2 → Shapely-1.2.4}/Shapely.egg-info/PKG-INFO +1 -1
- {Shapely-1.2.2 → Shapely-1.2.4}/Shapely.egg-info/SOURCES.txt +3 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/docs/_build/html/_sources/manual.txt +27 -10
- {Shapely-1.2.2 → Shapely-1.2.4}/docs/manual.txt +27 -5
- {Shapely-1.2.2 → Shapely-1.2.4}/setup.py +1 -1
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/ctypes_declarations.py +3 -3
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/__init__.py +2 -2
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/base.py +12 -5
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/geo.py +4 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geos.py +29 -35
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/impl.py +27 -1
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/prepared.py +6 -2
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/__init__.py +4 -0
- Shapely-1.2.4/shapely/tests/test_delegated.py +22 -0
- Shapely-1.2.4/shapely/tests/test_dlls.py +14 -0
- Shapely-1.2.4/shapely/tests/test_mapping.py +11 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/validation.py +1 -1
- {Shapely-1.2.2 → Shapely-1.2.4}/CREDITS.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/LICENSE.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/MANIFEST.in +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/README.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/Shapely.egg-info/dependency_links.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/Shapely.egg-info/top_level.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/examples/dissolve.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/examples/intersect.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/setup.cfg +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/__init__.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/coords.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/collection.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/linestring.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/multilinestring.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/multipoint.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/multipolygon.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/point.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/polygon.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/geometry/proxy.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/iterops.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/linref.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/ops.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/predicates.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/Array.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/GeoInterface.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/IterOps.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/LineString.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/MultiLineString.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/MultiPoint.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/MultiPolygon.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/Operations.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/Persist.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/Point.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/Polygon.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/Predicates.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/attribute-chains.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/binascii_hex.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/cascaded_union.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/dimensions.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/invalid_intersection.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/linear-referencing.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/linemerge.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/polygonize.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_collection.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_doctests.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_emptiness.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_equality.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_geomseq.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_prepared.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_singularity.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_validation.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/test_xy.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/threading_test.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/tests/wkt_locale.txt +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/topology.py +0 -0
- {Shapely-1.2.2 → Shapely-1.2.4}/shapely/wkb.py +0 -0
- {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.
|
|
@@ -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.
|
|
7
|
-
:Date:
|
|
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
|
|
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
|
|
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.
|
|
7
|
-
:Date:
|
|
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
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
|
@@ -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 =
|
|
30
|
-
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
|
-
|
|
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
|
-
|
|
45
|
-
|
|
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
|
-
|
|
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
|
-
|
|
85
|
-
|
|
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)
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|