shapely 1.0.2__tar.gz → 1.0.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.0.4/CHANGES.txt +18 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/PKG-INFO +1 -1
- {Shapely-1.0.2 → Shapely-1.0.4}/Shapely.egg-info/PKG-INFO +1 -1
- {Shapely-1.0.2 → Shapely-1.0.4}/Shapely.egg-info/SOURCES.txt +2 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/setup.py +1 -1
- {Shapely-1.0.2 → Shapely-1.0.4}/setup_windows.py +1 -1
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/geometry/__init__.py +1 -1
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/geometry/base.py +3 -7
- Shapely-1.0.4/shapely/geometry/geo.py +61 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/geometry/linestring.py +3 -11
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/geometry/multilinestring.py +3 -11
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/geometry/multipoint.py +3 -11
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/geometry/multipolygon.py +3 -11
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/geometry/point.py +3 -12
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/geometry/polygon.py +6 -15
- Shapely-1.0.4/shapely/geometry/proxy.py +48 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/geos.py +5 -5
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/topology.py +2 -2
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/LineString.txt +2 -2
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/MultiPoint.txt +2 -2
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/Point.txt +4 -4
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/Predicates.txt +1 -7
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/attribute-chains.txt +7 -3
- Shapely-1.0.4/tests/test_threads.py +33 -0
- Shapely-1.0.2/CHANGES.txt +0 -7
- Shapely-1.0.2/shapely/geometry/geo.py +0 -35
- {Shapely-1.0.2 → Shapely-1.0.4}/CREDITS.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/HISTORY.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/LICENSE.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/README.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/Shapely.egg-info/dependency_links.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/Shapely.egg-info/requires.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/Shapely.egg-info/top_level.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/examples/geoms.py +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/examples/world.py +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/manual/manual.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/manual/style.css +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/setup.cfg +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/__init__.py +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/geometry/collection.py +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/iterops.py +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/kml.py +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/predicates.py +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/wkb.py +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/shapely/wkt.py +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/Array.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/GeoInterface.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/IterOps.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/MultiLineString.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/MultiPolygon.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/Operations.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/Persist.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/Polygon.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/__init__.py +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/binascii_hex.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/invalid_intersection.txt +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/rungrind.dist +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/test_doctests.py +0 -0
- {Shapely-1.0.2 → Shapely-1.0.4}/tests/valgrind-python.supp +0 -0
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
All tickets are children of http://trac.gispython.org/projects/PCL/ticket/
|
|
2
|
+
|
|
3
|
+
1.0.4 (2008-05-01)
|
|
4
|
+
------------------
|
|
5
|
+
- Disentangle Python and topological equality (#163).
|
|
6
|
+
- Add shape(), a factory that copies coordinates from a geo interface provider.
|
|
7
|
+
To be used instead of asShape() unless you really need to store coordinates
|
|
8
|
+
outside shapely for efficient use in other code.
|
|
9
|
+
- Cache GEOS geometries in adapters (#163).
|
|
10
|
+
|
|
11
|
+
1.0.3 (2008-04-09)
|
|
12
|
+
------------------
|
|
13
|
+
- Do not release GIL when calling GEOS functions (#158).
|
|
14
|
+
- Prevent faults when chaining multiple GEOS operators (#159).
|
|
15
|
+
|
|
16
|
+
1.0.2 (2008-02-26)
|
|
17
|
+
------------------
|
|
18
|
+
- Fix loss of dimensionality in polygon rings (#155).
|
|
@@ -32,6 +32,7 @@ shapely/geometry/multipoint.py
|
|
|
32
32
|
shapely/geometry/multipolygon.py
|
|
33
33
|
shapely/geometry/point.py
|
|
34
34
|
shapely/geometry/polygon.py
|
|
35
|
+
shapely/geometry/proxy.py
|
|
35
36
|
tests/Array.txt
|
|
36
37
|
tests/GeoInterface.txt
|
|
37
38
|
tests/IterOps.txt
|
|
@@ -50,4 +51,5 @@ tests/binascii_hex.txt
|
|
|
50
51
|
tests/invalid_intersection.txt
|
|
51
52
|
tests/rungrind.dist
|
|
52
53
|
tests/test_doctests.py
|
|
54
|
+
tests/test_threads.py
|
|
53
55
|
tests/valgrind-python.supp
|
|
@@ -11,7 +11,7 @@ if version_info[:2] < (2,5):
|
|
|
11
11
|
readme_text = file('README.txt', 'rb').read()
|
|
12
12
|
|
|
13
13
|
setup(name = 'Shapely',
|
|
14
|
-
version = '1.0.
|
|
14
|
+
version = '1.0.4',
|
|
15
15
|
description = 'Geospatial geometries, predicates, and operations',
|
|
16
16
|
license = 'BSD',
|
|
17
17
|
keywords = 'geometry topology',
|
|
@@ -11,7 +11,7 @@ if version_info[:2] < (2,5):
|
|
|
11
11
|
readme_text = file('README.txt', 'rb').read()
|
|
12
12
|
|
|
13
13
|
setup(name = 'Shapely',
|
|
14
|
-
version = '1.0.
|
|
14
|
+
version = '1.0.3',
|
|
15
15
|
description = 'Geospatial geometries, predicates, and operations',
|
|
16
16
|
license = 'BSD',
|
|
17
17
|
keywords = 'geometry topology',
|
|
@@ -28,7 +28,7 @@ def geometry_type_name(g):
|
|
|
28
28
|
|
|
29
29
|
# Abstract geometry factory for use with topological methods below
|
|
30
30
|
|
|
31
|
-
def geom_factory(g):
|
|
31
|
+
def geom_factory(g, parent=None):
|
|
32
32
|
if not g:
|
|
33
33
|
raise ValueError, "No Shapely geometry can be created from this null value"
|
|
34
34
|
ob = BaseGeometry()
|
|
@@ -42,6 +42,7 @@ def geom_factory(g):
|
|
|
42
42
|
)
|
|
43
43
|
ob.__class__ = getattr(mod, geom_type)
|
|
44
44
|
ob.__geom__ = g
|
|
45
|
+
ob.__p__ = parent
|
|
45
46
|
ob._ndim = 2 # callers should be all from 2D worlds
|
|
46
47
|
return ob
|
|
47
48
|
|
|
@@ -231,6 +232,7 @@ class BaseGeometry(object):
|
|
|
231
232
|
"""
|
|
232
233
|
|
|
233
234
|
__geom__ = None # See _geom property below
|
|
235
|
+
__p__ = None
|
|
234
236
|
_ctypes_data = None
|
|
235
237
|
_ndim = None
|
|
236
238
|
_crs = None
|
|
@@ -246,12 +248,6 @@ class BaseGeometry(object):
|
|
|
246
248
|
def __str__(self):
|
|
247
249
|
return self.to_wkt()
|
|
248
250
|
|
|
249
|
-
def __eq__(self, other):
|
|
250
|
-
return self.equals(other)
|
|
251
|
-
|
|
252
|
-
def __ne__(self, other):
|
|
253
|
-
return not self.equals(other)
|
|
254
|
-
|
|
255
251
|
# To support pickling
|
|
256
252
|
|
|
257
253
|
def __reduce__(self):
|
|
@@ -0,0 +1,61 @@
|
|
|
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, 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"])
|
|
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
|
+
geom_type = ob.get("type").lower()
|
|
47
|
+
|
|
48
|
+
if geom_type == "point":
|
|
49
|
+
return asPoint(ob["coordinates"])
|
|
50
|
+
elif geom_type == "linestring":
|
|
51
|
+
return asLineString(ob["coordinates"])
|
|
52
|
+
elif geom_type == "polygon":
|
|
53
|
+
return asPolygon(ob["coordinates"][0], ob["coordinates"][1:])
|
|
54
|
+
elif geom_type == "multipoint":
|
|
55
|
+
return asMultiPoint(ob["coordinates"])
|
|
56
|
+
elif geom_type == "multilinestring":
|
|
57
|
+
return asMultiLineString(ob["coordinates"])
|
|
58
|
+
elif geom_type == "multipolygon":
|
|
59
|
+
return asMultiPolygon(ob["coordinates"])
|
|
60
|
+
else:
|
|
61
|
+
raise ValueError, "Unknown geometry type: %s" % geom_type
|
|
@@ -7,6 +7,7 @@ from ctypes import ArgumentError
|
|
|
7
7
|
|
|
8
8
|
from shapely.geos import lgeos
|
|
9
9
|
from shapely.geometry.base import BaseGeometry, exceptNull
|
|
10
|
+
from shapely.geometry.proxy import CachingGeometryProxy
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def geos_linestring_from_py(ob, update_geom=None, update_ndim=0):
|
|
@@ -157,18 +158,18 @@ class LineString(BaseGeometry):
|
|
|
157
158
|
coords = property(BaseGeometry._get_coords, _set_coords)
|
|
158
159
|
|
|
159
160
|
|
|
160
|
-
class LineStringAdapter(LineString):
|
|
161
|
+
class LineStringAdapter(CachingGeometryProxy, LineString):
|
|
161
162
|
|
|
162
163
|
"""Adapts a Python coordinate pair or a numpy array to the line string
|
|
163
164
|
interface.
|
|
164
165
|
"""
|
|
165
166
|
|
|
166
167
|
context = None
|
|
167
|
-
#__geom = None
|
|
168
168
|
_owned = False
|
|
169
169
|
|
|
170
170
|
def __init__(self, context):
|
|
171
171
|
self.context = context
|
|
172
|
+
self.factory = geos_linestring_from_py
|
|
172
173
|
|
|
173
174
|
@property
|
|
174
175
|
def _ndim(self):
|
|
@@ -182,14 +183,6 @@ class LineStringAdapter(LineString):
|
|
|
182
183
|
# Fall back on list
|
|
183
184
|
return len(self.context[0])
|
|
184
185
|
|
|
185
|
-
@property
|
|
186
|
-
def _geom(self):
|
|
187
|
-
"""Keeps the GEOS geometry in synch with the context."""
|
|
188
|
-
if self.__geom__ is not None:
|
|
189
|
-
lgeos.GEOSGeom_destroy(self.__geom__)
|
|
190
|
-
self.__geom__, n = geos_linestring_from_py(self.context)
|
|
191
|
-
return self.__geom__
|
|
192
|
-
|
|
193
186
|
@property
|
|
194
187
|
def __array_interface__(self):
|
|
195
188
|
"""Provide the Numpy array protocol."""
|
|
@@ -220,4 +213,3 @@ def _test():
|
|
|
220
213
|
|
|
221
214
|
if __name__ == "__main__":
|
|
222
215
|
_test()
|
|
223
|
-
|
|
@@ -7,6 +7,7 @@ from ctypes import byref, c_double, c_int, c_void_p, cast, POINTER, pointer
|
|
|
7
7
|
from shapely.geos import lgeos
|
|
8
8
|
from shapely.geometry.base import BaseGeometry, GeometrySequence, exceptNull
|
|
9
9
|
from shapely.geometry.linestring import LineString, geos_linestring_from_py
|
|
10
|
+
from shapely.geometry.proxy import CachingGeometryProxy
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def geos_multilinestring_from_py(ob):
|
|
@@ -115,18 +116,18 @@ class MultiLineString(BaseGeometry):
|
|
|
115
116
|
return GeometrySequence(self, LineString)
|
|
116
117
|
|
|
117
118
|
|
|
118
|
-
class MultiLineStringAdapter(MultiLineString):
|
|
119
|
+
class MultiLineStringAdapter(CachingGeometryProxy, MultiLineString):
|
|
119
120
|
|
|
120
121
|
"""Adapts sequences of sequences or numpy arrays to the multilinestring
|
|
121
122
|
interface.
|
|
122
123
|
"""
|
|
123
124
|
|
|
124
125
|
context = None
|
|
125
|
-
#__geom = None
|
|
126
126
|
_owned = False
|
|
127
127
|
|
|
128
128
|
def __init__(self, context):
|
|
129
129
|
self.context = context
|
|
130
|
+
self.factory = geos_multilinestring_from_py
|
|
130
131
|
|
|
131
132
|
@property
|
|
132
133
|
def _ndim(self):
|
|
@@ -140,14 +141,6 @@ class MultiLineStringAdapter(MultiLineString):
|
|
|
140
141
|
# Fall back on list
|
|
141
142
|
return len(self.context[0][0])
|
|
142
143
|
|
|
143
|
-
@property
|
|
144
|
-
def _geom(self):
|
|
145
|
-
"""Keeps the GEOS geometry in synch with the context."""
|
|
146
|
-
if self.__geom__ is not None:
|
|
147
|
-
lgeos.GEOSGeom_destroy(self.__geom__)
|
|
148
|
-
self.__geom__ = geos_multilinestring_from_py(self.context)[0]
|
|
149
|
-
return self.__geom__
|
|
150
|
-
|
|
151
144
|
|
|
152
145
|
def asMultiLineString(context):
|
|
153
146
|
"""Factory for MultiLineStringAdapter instances."""
|
|
@@ -162,4 +155,3 @@ def _test():
|
|
|
162
155
|
|
|
163
156
|
if __name__ == "__main__":
|
|
164
157
|
_test()
|
|
165
|
-
|
|
@@ -7,6 +7,7 @@ from ctypes import byref, c_double, c_int, c_void_p, cast, POINTER, pointer
|
|
|
7
7
|
from shapely.geos import lgeos
|
|
8
8
|
from shapely.geometry.base import BaseGeometry, GeometrySequence, exceptNull
|
|
9
9
|
from shapely.geometry.point import Point, geos_point_from_py
|
|
10
|
+
from shapely.geometry.proxy import CachingGeometryProxy
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def geos_multipoint_from_py(ob):
|
|
@@ -137,18 +138,18 @@ class MultiPoint(BaseGeometry):
|
|
|
137
138
|
return GeometrySequence(self, Point)
|
|
138
139
|
|
|
139
140
|
|
|
140
|
-
class MultiPointAdapter(MultiPoint):
|
|
141
|
+
class MultiPointAdapter(CachingGeometryProxy, MultiPoint):
|
|
141
142
|
|
|
142
143
|
"""Adapts a Python coordinate pair or a numpy array to the multipoint
|
|
143
144
|
interface.
|
|
144
145
|
"""
|
|
145
146
|
|
|
146
147
|
context = None
|
|
147
|
-
#__geom__ = None
|
|
148
148
|
_owned = False
|
|
149
149
|
|
|
150
150
|
def __init__(self, context):
|
|
151
151
|
self.context = context
|
|
152
|
+
self.factory = geos_multipoint_from_py
|
|
152
153
|
|
|
153
154
|
@property
|
|
154
155
|
def _ndim(self):
|
|
@@ -162,14 +163,6 @@ class MultiPointAdapter(MultiPoint):
|
|
|
162
163
|
# Fall back on list
|
|
163
164
|
return len(self.context[0])
|
|
164
165
|
|
|
165
|
-
@property
|
|
166
|
-
def _geom(self):
|
|
167
|
-
"""Keeps the GEOS geometry in synch with the context."""
|
|
168
|
-
if self.__geom__ is not None:
|
|
169
|
-
lgeos.GEOSGeom_destroy(self.__geom__)
|
|
170
|
-
self.__geom__, n = geos_multipoint_from_py(self.context)
|
|
171
|
-
return self.__geom__
|
|
172
|
-
|
|
173
166
|
@property
|
|
174
167
|
def __array_interface__(self):
|
|
175
168
|
"""Provide the Numpy array protocol."""
|
|
@@ -192,4 +185,3 @@ def _test():
|
|
|
192
185
|
|
|
193
186
|
if __name__ == "__main__":
|
|
194
187
|
_test()
|
|
195
|
-
|
|
@@ -7,6 +7,7 @@ from ctypes import byref, c_double, c_int, c_void_p, cast, POINTER, pointer
|
|
|
7
7
|
from shapely.geos import lgeos
|
|
8
8
|
from shapely.geometry.base import BaseGeometry, GeometrySequence, exceptNull
|
|
9
9
|
from shapely.geometry.polygon import Polygon, geos_polygon_from_py
|
|
10
|
+
from shapely.geometry.proxy import CachingGeometryProxy
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def geos_multipolygon_from_py(ob):
|
|
@@ -101,18 +102,18 @@ class MultiPolygon(BaseGeometry):
|
|
|
101
102
|
return GeometrySequence(self, Polygon)
|
|
102
103
|
|
|
103
104
|
|
|
104
|
-
class MultiPolygonAdapter(MultiPolygon):
|
|
105
|
+
class MultiPolygonAdapter(CachingGeometryProxy, MultiPolygon):
|
|
105
106
|
|
|
106
107
|
"""Adapts sequences of sequences or numpy arrays to the multipolygon
|
|
107
108
|
interface.
|
|
108
109
|
"""
|
|
109
110
|
|
|
110
111
|
context = None
|
|
111
|
-
#__geom = None
|
|
112
112
|
_owned = False
|
|
113
113
|
|
|
114
114
|
def __init__(self, context):
|
|
115
115
|
self.context = context
|
|
116
|
+
self.factory = geos_multipolygon_from_py
|
|
116
117
|
|
|
117
118
|
@property
|
|
118
119
|
def _ndim(self):
|
|
@@ -126,14 +127,6 @@ class MultiPolygonAdapter(MultiPolygon):
|
|
|
126
127
|
# Fall back on list
|
|
127
128
|
return len(self.context[0][0][0])
|
|
128
129
|
|
|
129
|
-
@property
|
|
130
|
-
def _geom(self):
|
|
131
|
-
"""Keeps the GEOS geometry in synch with the context."""
|
|
132
|
-
if self.__geom__ is not None:
|
|
133
|
-
lgeos.GEOSGeom_destroy(self.__geom__)
|
|
134
|
-
self.__geom__ = geos_multipolygon_from_py(self.context)[0]
|
|
135
|
-
return self.__geom__
|
|
136
|
-
|
|
137
130
|
|
|
138
131
|
def asMultiPolygon(context):
|
|
139
132
|
"""Factory for MultiLineStringAdapter instances."""
|
|
@@ -148,4 +141,3 @@ def _test():
|
|
|
148
141
|
|
|
149
142
|
if __name__ == "__main__":
|
|
150
143
|
_test()
|
|
151
|
-
|
|
@@ -10,6 +10,7 @@ from ctypes import cast, POINTER
|
|
|
10
10
|
from shapely.geos import lgeos, DimensionError
|
|
11
11
|
from shapely.geometry.base import BaseGeometry, CoordinateSequence
|
|
12
12
|
from shapely.geometry.base import exceptNull
|
|
13
|
+
from shapely.geometry.proxy import CachingGeometryProxy
|
|
13
14
|
|
|
14
15
|
|
|
15
16
|
def geos_point_from_py(ob, update_geom=None, update_ndim=0):
|
|
@@ -199,17 +200,16 @@ class Point(BaseGeometry):
|
|
|
199
200
|
coords = property(BaseGeometry._get_coords, _set_coords)
|
|
200
201
|
|
|
201
202
|
|
|
202
|
-
class PointAdapter(Point):
|
|
203
|
+
class PointAdapter(CachingGeometryProxy, Point):
|
|
203
204
|
|
|
204
205
|
"""Adapts a Python coordinate pair or a numpy array to the point interface.
|
|
205
206
|
"""
|
|
206
207
|
|
|
207
|
-
context = None
|
|
208
|
-
__geom = None
|
|
209
208
|
_owned = False
|
|
210
209
|
|
|
211
210
|
def __init__(self, context):
|
|
212
211
|
self.context = context
|
|
212
|
+
self.factory = geos_point_from_py
|
|
213
213
|
|
|
214
214
|
@property
|
|
215
215
|
def _ndim(self):
|
|
@@ -223,14 +223,6 @@ class PointAdapter(Point):
|
|
|
223
223
|
# Fall back on list
|
|
224
224
|
return len(self.context)
|
|
225
225
|
|
|
226
|
-
@property
|
|
227
|
-
def _geom(self):
|
|
228
|
-
"""Keeps the GEOS geometry in synch with the context."""
|
|
229
|
-
if self.__geom is not None:
|
|
230
|
-
lgeos.GEOSGeom_destroy(self.__geom)
|
|
231
|
-
self.__geom, n = geos_point_from_py(self.context)
|
|
232
|
-
return self.__geom
|
|
233
|
-
|
|
234
226
|
# TODO: reimplement x, y, z properties without calling invoking _geom
|
|
235
227
|
|
|
236
228
|
@property
|
|
@@ -262,4 +254,3 @@ def _test():
|
|
|
262
254
|
|
|
263
255
|
if __name__ == "__main__":
|
|
264
256
|
_test()
|
|
265
|
-
|
|
@@ -7,6 +7,7 @@ from ctypes import byref, c_double, c_int, c_void_p, cast, POINTER, pointer
|
|
|
7
7
|
from shapely.geos import lgeos
|
|
8
8
|
from shapely.geometry.base import BaseGeometry, exceptNull
|
|
9
9
|
from shapely.geometry.linestring import LineString, LineStringAdapter
|
|
10
|
+
from shapely.geometry.proxy import PolygonProxy
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def geos_linearring_from_py(ob, update_geom=None, update_ndim=0):
|
|
@@ -76,7 +77,7 @@ def geos_linearring_from_py(ob, update_geom=None, update_ndim=0):
|
|
|
76
77
|
m = len(ob)
|
|
77
78
|
n = len(ob[0])
|
|
78
79
|
assert m >= 2
|
|
79
|
-
assert n == 2 or n == 3
|
|
80
|
+
assert (n == 2 or n == 3)
|
|
80
81
|
|
|
81
82
|
# Add closing coordinates if not provided
|
|
82
83
|
if ob[0][0] != ob[-1][0] or ob[0][1] != ob[-1][1]:
|
|
@@ -282,10 +283,7 @@ def geos_polygon_from_py(shell, holes=None):
|
|
|
282
283
|
if holes:
|
|
283
284
|
ob = holes
|
|
284
285
|
L = len(ob)
|
|
285
|
-
|
|
286
|
-
N = len(ob[0][0])
|
|
287
|
-
except:
|
|
288
|
-
import pdb; pdb.set_trace()
|
|
286
|
+
N = len(ob[0][0])
|
|
289
287
|
assert L >= 1
|
|
290
288
|
assert N == 2 or N == 3
|
|
291
289
|
|
|
@@ -395,7 +393,7 @@ class Polygon(BaseGeometry):
|
|
|
395
393
|
}
|
|
396
394
|
|
|
397
395
|
|
|
398
|
-
class PolygonAdapter(Polygon):
|
|
396
|
+
class PolygonAdapter(PolygonProxy, Polygon):
|
|
399
397
|
|
|
400
398
|
"""Adapts sequences of sequences or numpy arrays to the polygon
|
|
401
399
|
interface.
|
|
@@ -408,6 +406,8 @@ class PolygonAdapter(Polygon):
|
|
|
408
406
|
def __init__(self, shell, holes=None):
|
|
409
407
|
self.shell = shell
|
|
410
408
|
self.holes = holes
|
|
409
|
+
self.context = (shell, holes)
|
|
410
|
+
self.factory = geos_polygon_from_py
|
|
411
411
|
|
|
412
412
|
@property
|
|
413
413
|
def _ndim(self):
|
|
@@ -421,14 +421,6 @@ class PolygonAdapter(Polygon):
|
|
|
421
421
|
# Fall back on list
|
|
422
422
|
return len(self.shell[0])
|
|
423
423
|
|
|
424
|
-
@property
|
|
425
|
-
def _geom(self):
|
|
426
|
-
"""Keeps the GEOS geometry in synch with the context."""
|
|
427
|
-
if self.__geom__ is not None:
|
|
428
|
-
lgeos.GEOSGeom_destroy(self.__geom__)
|
|
429
|
-
self.__geom__ = geos_polygon_from_py(self.shell, self.holes)[0]
|
|
430
|
-
return self.__geom__
|
|
431
|
-
|
|
432
424
|
|
|
433
425
|
def asPolygon(shell, holes=None):
|
|
434
426
|
"""Factory for PolygonAdapter instances."""
|
|
@@ -442,4 +434,3 @@ def _test():
|
|
|
442
434
|
|
|
443
435
|
if __name__ == "__main__":
|
|
444
436
|
_test()
|
|
445
|
-
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Proxy for coordinates stored outside Shapely geometries.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from shapely.geos import lgeos
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
class CachingGeometryProxy(object):
|
|
9
|
+
|
|
10
|
+
context = None
|
|
11
|
+
factory = None
|
|
12
|
+
__geom__ = None
|
|
13
|
+
_gtag = None
|
|
14
|
+
|
|
15
|
+
def __init__(self, context):
|
|
16
|
+
self.context = context
|
|
17
|
+
|
|
18
|
+
@property
|
|
19
|
+
def _geom(self):
|
|
20
|
+
"""Keeps the GEOS geometry in synch with the context."""
|
|
21
|
+
gtag = self.gtag()
|
|
22
|
+
if gtag != self._gtag:
|
|
23
|
+
if self.__geom__ is not None:
|
|
24
|
+
lgeos.GEOSGeom_destroy(self.__geom__)
|
|
25
|
+
self.__geom__, n = self.factory(self.context)
|
|
26
|
+
elif self.__geom__ is None:
|
|
27
|
+
self.__geom__, n = self.factory(self.context)
|
|
28
|
+
self._gtag = gtag
|
|
29
|
+
return self.__geom__
|
|
30
|
+
|
|
31
|
+
def gtag(self):
|
|
32
|
+
return hash(repr(self.context))
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
class PolygonProxy(CachingGeometryProxy):
|
|
36
|
+
|
|
37
|
+
@property
|
|
38
|
+
def _geom(self):
|
|
39
|
+
"""Keeps the GEOS geometry in synch with the context."""
|
|
40
|
+
gtag = self.gtag()
|
|
41
|
+
if gtag != self._gtag:
|
|
42
|
+
if self.__geom__ is not None:
|
|
43
|
+
lgeos.GEOSGeom_destroy(self.__geom__)
|
|
44
|
+
self.__geom__, n = self.factory(self.context[0], self.context[1])
|
|
45
|
+
elif self.__geom__ is None:
|
|
46
|
+
self.__geom__, n = self.factory(self.context[0], self.context[1])
|
|
47
|
+
self._gtag = gtag
|
|
48
|
+
return self.__geom__
|
|
@@ -3,7 +3,7 @@ Exports the libgeos_c shared lib, GEOS-specific exceptions, and utilities.
|
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
5
|
import atexit
|
|
6
|
-
from ctypes import cdll, CDLL, CFUNCTYPE, c_char_p
|
|
6
|
+
from ctypes import cdll, CDLL, pydll, PyDLL, CFUNCTYPE, c_char_p
|
|
7
7
|
from ctypes.util import find_library
|
|
8
8
|
import os
|
|
9
9
|
import sys
|
|
@@ -15,7 +15,7 @@ if sys.platform == 'win32':
|
|
|
15
15
|
local_dlls = os.path.abspath(os.__file__ + "../../../DLLs")
|
|
16
16
|
original_path = os.environ['PATH']
|
|
17
17
|
os.environ['PATH'] = "%s;%s" % (local_dlls, original_path)
|
|
18
|
-
lgeos =
|
|
18
|
+
lgeos = PyDLL("geos.dll")
|
|
19
19
|
except (ImportError, WindowsError):
|
|
20
20
|
raise
|
|
21
21
|
def free(m):
|
|
@@ -38,14 +38,14 @@ elif sys.platform == 'darwin':
|
|
|
38
38
|
break
|
|
39
39
|
else:
|
|
40
40
|
raise ImportError, "Could not find geos_c library"
|
|
41
|
-
lgeos =
|
|
41
|
+
lgeos = PyDLL(lib)
|
|
42
42
|
free = CDLL(find_library('libc')).free
|
|
43
43
|
else:
|
|
44
44
|
# Try the major versioned name first, falling back on the unversioned name.
|
|
45
45
|
try:
|
|
46
|
-
lgeos =
|
|
46
|
+
lgeos = PyDLL('libgeos_c.so.1')
|
|
47
47
|
except (OSError, ImportError):
|
|
48
|
-
lgeos =
|
|
48
|
+
lgeos = PyDLL('libgeos_c.so')
|
|
49
49
|
except:
|
|
50
50
|
raise
|
|
51
51
|
free = CDLL('libc.so.6').free
|
|
@@ -38,7 +38,7 @@ class BinaryTopologicalOp(object):
|
|
|
38
38
|
raise TopologicalError, \
|
|
39
39
|
"The operation '%s' produced a null geometry. Likely cause is invalidity of the 'other' geometry %s" % (self.fn.__name__, repr(other))
|
|
40
40
|
|
|
41
|
-
return self.factory(product)
|
|
41
|
+
return self.factory(product, self.context)
|
|
42
42
|
|
|
43
43
|
|
|
44
44
|
class UnaryTopologicalOp(object):
|
|
@@ -59,7 +59,7 @@ class UnaryTopologicalOp(object):
|
|
|
59
59
|
def __get__(self, obj, objtype=None):
|
|
60
60
|
if obj._geom is None:
|
|
61
61
|
raise ValueError, "Null geometry supports no operations"
|
|
62
|
-
return self.factory(self.fn(obj._geom))
|
|
62
|
+
return self.factory(self.fn(obj._geom), obj)
|
|
63
63
|
|
|
64
64
|
def __set__(self, obj, value=None):
|
|
65
65
|
raise AttributeError, "Attribute is read-only"
|
|
@@ -99,8 +99,8 @@ Adapter
|
|
|
99
99
|
>>> pa.__array_interface__ == pa.context.__array_interface__
|
|
100
100
|
True
|
|
101
101
|
>>> from numpy import asarray
|
|
102
|
-
>>>
|
|
103
|
-
>>>
|
|
102
|
+
>>> pas = asarray(pa)
|
|
103
|
+
>>> pas
|
|
104
104
|
array([ 1., 2.])
|
|
105
105
|
|
|
106
106
|
Adapt a coordinate list to a point
|
|
@@ -123,8 +123,8 @@ Adapter
|
|
|
123
123
|
Now, the inverse
|
|
124
124
|
|
|
125
125
|
>>> ai = pa.__array_interface__
|
|
126
|
-
>>>
|
|
127
|
-
>>>
|
|
126
|
+
>>> pas = asarray(pa)
|
|
127
|
+
>>> pas
|
|
128
128
|
array([ 1., 4.])
|
|
129
129
|
|
|
130
130
|
Test Non-operability of Null geometry
|
|
@@ -28,13 +28,7 @@ Binary Predicates
|
|
|
28
28
|
>>> point.equals(Point(-1.0, -1.0))
|
|
29
29
|
False
|
|
30
30
|
|
|
31
|
-
>>> point
|
|
32
|
-
True
|
|
33
|
-
|
|
34
|
-
>>> point == Point(-1.0, -1.0)
|
|
35
|
-
False
|
|
36
|
-
|
|
37
|
-
>>> point != Point(-1.0, -1.0)
|
|
31
|
+
>>> point.equals(Point(0.0, 0.0))
|
|
38
32
|
True
|
|
39
33
|
|
|
40
34
|
Unary Predicates
|
|
@@ -9,7 +9,7 @@ See also ticket #151.
|
|
|
9
9
|
[(0.0, 0.0), (0.0, 1.0), (-1.0, 1.0), (-1.0, 0.0), (0.0, 0.0)]
|
|
10
10
|
|
|
11
11
|
>>> print list(p.buffer(1).exterior.coords)
|
|
12
|
-
[(
|
|
12
|
+
[(0.0, -1.0), (-1.0, -1.0), ...
|
|
13
13
|
|
|
14
14
|
Test chained access to interiors
|
|
15
15
|
|
|
@@ -22,6 +22,10 @@ Test chained access to interiors
|
|
|
22
22
|
>>> print list(p.interiors[0].coords)
|
|
23
23
|
[(-0.25, 0.25), (-0.25, 0.75), (-0.75, 0.75), (-0.75, 0.25), (-0.25, 0.25)]
|
|
24
24
|
>>> print list(p.interiors[0].buffer(1).exterior.coords)
|
|
25
|
-
[(-0.
|
|
26
|
-
|
|
25
|
+
[(-0.25, -0.75), (-0.75, -0.75), ...
|
|
26
|
+
|
|
27
|
+
Test multiple operators, boundary of a buffer
|
|
28
|
+
|
|
29
|
+
>>> print list(p.buffer(1).boundary.coords)
|
|
30
|
+
[(0.0, -1.0), (-1.0, -1.0), ...
|
|
27
31
|
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
|
|
3
|
+
def main():
|
|
4
|
+
num_threads = 4
|
|
5
|
+
use_threads = True
|
|
6
|
+
|
|
7
|
+
if not use_threads:
|
|
8
|
+
# Run core code
|
|
9
|
+
runShapelyBuilding()
|
|
10
|
+
else:
|
|
11
|
+
threads = [threading.Thread(target=runShapelyBuilding) for x in range(num_threads)]
|
|
12
|
+
for t in threads:
|
|
13
|
+
t.start()
|
|
14
|
+
for t in threads:
|
|
15
|
+
t.join()
|
|
16
|
+
|
|
17
|
+
def runShapelyBuilding():
|
|
18
|
+
import shapely.wkt
|
|
19
|
+
import shapely.wkb
|
|
20
|
+
|
|
21
|
+
print "Running shapely tests on wkb"
|
|
22
|
+
|
|
23
|
+
wkb = shapely.wkt.loads("POINT (0 0)").wkb
|
|
24
|
+
|
|
25
|
+
for i in xrange(1000):
|
|
26
|
+
obj = shapely.wkb.loads(wkb)
|
|
27
|
+
|
|
28
|
+
print "Done"
|
|
29
|
+
|
|
30
|
+
# Run main
|
|
31
|
+
if __name__ == '__main__':
|
|
32
|
+
main()
|
|
33
|
+
|
Shapely-1.0.2/CHANGES.txt
DELETED
|
@@ -1,35 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
from point import PointAdapter
|
|
3
|
-
from linestring import LineStringAdapter
|
|
4
|
-
from polygon import PolygonAdapter
|
|
5
|
-
from multipoint import MultiPointAdapter
|
|
6
|
-
from multilinestring import MultiLineStringAdapter
|
|
7
|
-
from multipolygon import MultiPolygonAdapter
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def asShape(context):
|
|
11
|
-
"""Adapts the context to a geometry interface. The coordinates remain
|
|
12
|
-
stored in the context.
|
|
13
|
-
"""
|
|
14
|
-
if hasattr(context, "__geo_interface__"):
|
|
15
|
-
ob = context.__geo_interface__
|
|
16
|
-
else:
|
|
17
|
-
ob = context
|
|
18
|
-
|
|
19
|
-
geom_type = ob.get("type").lower()
|
|
20
|
-
|
|
21
|
-
if geom_type == "point":
|
|
22
|
-
return PointAdapter(ob["coordinates"])
|
|
23
|
-
elif geom_type == "linestring":
|
|
24
|
-
return LineStringAdapter(ob["coordinates"])
|
|
25
|
-
elif geom_type == "polygon":
|
|
26
|
-
return PolygonAdapter(ob["coordinates"][0], ob["coordinates"][1:])
|
|
27
|
-
elif geom_type == "multipoint":
|
|
28
|
-
return MultiPointAdapter(ob["coordinates"])
|
|
29
|
-
elif geom_type == "multilinestring":
|
|
30
|
-
return MultiLineStringAdapter(ob["coordinates"])
|
|
31
|
-
elif geom_type == "multipolygon":
|
|
32
|
-
return MultiPolygonAdapter(ob["coordinates"])
|
|
33
|
-
else:
|
|
34
|
-
raise ValueError, "Unknown geometry type: %s" % geom_type
|
|
35
|
-
|
|
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
|