shapely 1.2.13__py2.6-win-amd64.egg → 1.2.18__py2.6-win-amd64.egg
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- EGG-INFO/PKG-INFO +451 -376
- EGG-INFO/native_libs.txt +2 -0
- EGG-INFO/not-zip-safe +1 -1
- shapely/DLLs/geos.dll +0 -0
- shapely/DLLs/geos_c.dll +0 -0
- shapely/__init__.py +1 -2
- shapely/__init__.pyc +0 -0
- shapely/affinity.py +252 -0
- shapely/affinity.pyc +0 -0
- shapely/algorithms/__init__.pyc +0 -0
- shapely/algorithms/cga.pyc +0 -0
- shapely/coords.py +53 -21
- shapely/coords.pyc +0 -0
- shapely/ctypes_declarations.py +16 -3
- shapely/ctypes_declarations.pyc +0 -0
- shapely/examples/__init__.pyc +0 -0
- shapely/examples/dissolve.pyc +0 -0
- shapely/examples/geoms.pyc +0 -0
- shapely/examples/intersect.pyc +0 -0
- shapely/examples/world.pyc +0 -0
- shapely/ftools.pyc +0 -0
- shapely/geometry/__init__.py +4 -4
- shapely/geometry/__init__.pyc +0 -0
- shapely/geometry/base.py +155 -54
- shapely/geometry/base.pyc +0 -0
- shapely/geometry/collection.pyc +0 -0
- shapely/geometry/geo.py +2 -2
- shapely/geometry/geo.pyc +0 -0
- shapely/geometry/linestring.py +24 -19
- shapely/geometry/linestring.pyc +0 -0
- shapely/geometry/multilinestring.py +2 -2
- shapely/geometry/multilinestring.pyc +0 -0
- shapely/geometry/multipoint.py +4 -0
- shapely/geometry/multipoint.pyc +0 -0
- shapely/geometry/multipolygon.py +8 -5
- shapely/geometry/multipolygon.pyc +0 -0
- shapely/geometry/point.py +7 -0
- shapely/geometry/point.pyc +0 -0
- shapely/geometry/polygon.py +28 -9
- shapely/geometry/polygon.pyc +0 -0
- shapely/geometry/proxy.py +1 -3
- shapely/geometry/proxy.pyc +0 -0
- shapely/geos.py +45 -14
- shapely/geos.pyc +0 -0
- shapely/impl.py +8 -5
- shapely/impl.pyc +0 -0
- shapely/iterops.pyc +0 -0
- shapely/linref.pyc +0 -0
- shapely/ops.py +125 -3
- shapely/ops.pyc +0 -0
- shapely/predicates.pyc +0 -0
- shapely/prepared.pyc +0 -0
- shapely/speedups/__init__.pyc +0 -0
- shapely/speedups/_speedups.c +5201 -0
- shapely/speedups/_speedups.pyc +0 -0
- shapely/speedups/_speedups.pyd +0 -0
- shapely/tests/Array.txt +86 -0
- shapely/tests/GeoInterface.txt +69 -0
- shapely/tests/IterOps.txt +31 -0
- shapely/tests/LineString.txt +134 -0
- shapely/tests/MultiLineString.txt +81 -0
- shapely/tests/MultiPoint.txt +101 -0
- shapely/tests/MultiPolygon.txt +71 -0
- shapely/tests/Operations.txt +89 -0
- shapely/tests/Operators.txt +18 -0
- shapely/tests/Persist.txt +35 -0
- shapely/tests/Point.txt +148 -0
- shapely/tests/Polygon.txt +143 -0
- shapely/tests/Predicates.txt +51 -0
- shapely/tests/__init__.py +10 -1
- shapely/tests/__init__.pyc +0 -0
- shapely/tests/attribute-chains.txt +38 -0
- shapely/tests/binascii_hex.txt +47 -0
- shapely/tests/cascaded_union.txt +26 -0
- shapely/tests/dimensions.txt +17 -0
- shapely/tests/invalid_intersection.txt +29 -0
- shapely/tests/linemerge.txt +61 -0
- shapely/tests/polygonize.txt +40 -0
- shapely/tests/test_affinity.py +239 -0
- shapely/tests/test_affinity.pyc +0 -0
- shapely/tests/test_box.pyc +0 -0
- shapely/tests/test_cga.pyc +0 -0
- shapely/tests/test_collection.py +15 -0
- shapely/tests/test_collection.pyc +0 -0
- shapely/tests/test_delegated.pyc +0 -0
- shapely/tests/test_dlls.py +1 -1
- shapely/tests/test_dlls.pyc +0 -0
- shapely/tests/test_doctests.pyc +0 -0
- shapely/tests/test_emptiness.py +41 -8
- shapely/tests/test_emptiness.pyc +0 -0
- shapely/tests/test_equality.pyc +0 -0
- shapely/tests/test_geomseq.pyc +0 -0
- shapely/tests/test_getitem.py +113 -0
- shapely/tests/test_getitem.pyc +0 -0
- shapely/tests/test_linear_referencing.pyc +0 -0
- shapely/tests/test_mapping.pyc +0 -0
- shapely/tests/test_ndarrays.py +35 -0
- shapely/tests/test_ndarrays.pyc +0 -0
- shapely/tests/test_pickle.py +15 -0
- shapely/tests/test_pickle.pyc +0 -0
- shapely/tests/test_prepared.pyc +0 -0
- shapely/tests/test_products_z.pyc +0 -0
- shapely/tests/test_singularity.pyc +0 -0
- shapely/tests/test_speedups.pyc +0 -0
- shapely/tests/test_styles.py +17 -0
- shapely/tests/test_styles.pyc +0 -0
- shapely/tests/test_transform.py +61 -0
- shapely/tests/test_transform.pyc +0 -0
- shapely/tests/test_unary_union.py +40 -0
- shapely/tests/test_unary_union.pyc +0 -0
- shapely/tests/test_validation.pyc +0 -0
- shapely/tests/test_xy.pyc +0 -0
- shapely/tests/threading_test.pyc +0 -0
- shapely/tests/wkt_locale.txt +28 -0
- shapely/topology.pyc +0 -0
- shapely/validation.pyc +0 -0
- shapely/wkb.py +3 -17
- shapely/wkb.pyc +0 -0
- shapely/wkt.py +3 -13
- shapely/wkt.pyc +0 -0
- DLLs/geos.dll +0 -0
- DLLs/geos_c.dll +0 -0
shapely/geometry/point.py
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
from ctypes import c_double
|
|
5
5
|
from ctypes import cast, POINTER
|
|
6
6
|
|
|
7
|
+
from shapely.coords import required
|
|
7
8
|
from shapely.geos import lgeos, DimensionError
|
|
8
9
|
from shapely.geometry.base import BaseGeometry
|
|
9
10
|
from shapely.geometry.proxy import CachingGeometryProxy
|
|
@@ -172,6 +173,9 @@ def geos_point_from_py(ob, update_geom=None, update_ndim=0):
|
|
|
172
173
|
|
|
173
174
|
Returns the GEOS geometry and the number of its dimensions.
|
|
174
175
|
"""
|
|
176
|
+
# If numpy is present, we use numpy.require to ensure that we have a
|
|
177
|
+
# C-continguous array that owns its data. View data will be copied.
|
|
178
|
+
ob = required(ob)
|
|
175
179
|
try:
|
|
176
180
|
# From array protocol
|
|
177
181
|
array = ob.__array_interface__
|
|
@@ -183,6 +187,9 @@ def geos_point_from_py(ob, update_geom=None, update_ndim=0):
|
|
|
183
187
|
da = array['data']
|
|
184
188
|
if type(da) == type((0,)):
|
|
185
189
|
cdata = da[0]
|
|
190
|
+
# If we had numpy, we would do
|
|
191
|
+
# from numpy.ctypeslib import as_ctypes
|
|
192
|
+
# cp = as_ctypes(ob) - check that code?
|
|
186
193
|
cp = cast(cdata, POINTER(c_double))
|
|
187
194
|
dx = c_double(cp[0])
|
|
188
195
|
dy = c_double(cp[1])
|
shapely/geometry/point.pyc
CHANGED
|
Binary file
|
shapely/geometry/polygon.py
CHANGED
|
@@ -6,6 +6,7 @@ from ctypes import ArgumentError
|
|
|
6
6
|
import weakref
|
|
7
7
|
|
|
8
8
|
from shapely.algorithms.cga import signed_area
|
|
9
|
+
from shapely.coords import required
|
|
9
10
|
from shapely.geos import lgeos
|
|
10
11
|
from shapely.geometry.base import BaseGeometry
|
|
11
12
|
from shapely.geometry.linestring import LineString, LineStringAdapter
|
|
@@ -65,9 +66,15 @@ class LinearRing(LineString):
|
|
|
65
66
|
|
|
66
67
|
@property
|
|
67
68
|
def is_ccw(self):
|
|
68
|
-
"""
|
|
69
|
+
"""True is the ring is oriented counter clock-wise"""
|
|
69
70
|
return bool(self.impl['is_ccw'](self))
|
|
70
71
|
|
|
72
|
+
@property
|
|
73
|
+
def is_simple(self):
|
|
74
|
+
"""True if the geometry is simple, meaning that any self-intersections
|
|
75
|
+
are only at boundary points, else False"""
|
|
76
|
+
return LineString(self).is_simple
|
|
77
|
+
|
|
71
78
|
|
|
72
79
|
class LinearRingAdapter(LineStringAdapter):
|
|
73
80
|
|
|
@@ -124,15 +131,24 @@ class InteriorRingSequence(object):
|
|
|
124
131
|
def __len__(self):
|
|
125
132
|
return lgeos.GEOSGetNumInteriorRings(self._geom)
|
|
126
133
|
|
|
127
|
-
def __getitem__(self,
|
|
128
|
-
|
|
129
|
-
if
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
134
|
+
def __getitem__(self, key):
|
|
135
|
+
m = self.__len__()
|
|
136
|
+
if isinstance(key, int):
|
|
137
|
+
if key + m < 0 or key >= m:
|
|
138
|
+
raise IndexError("index out of range")
|
|
139
|
+
if key < 0:
|
|
140
|
+
i = m + key
|
|
141
|
+
else:
|
|
142
|
+
i = key
|
|
143
|
+
return self._get_ring(i)
|
|
144
|
+
elif isinstance(key, slice):
|
|
145
|
+
res = []
|
|
146
|
+
start, stop, stride = key.indices(m)
|
|
147
|
+
for i in xrange(start, stop, stride):
|
|
148
|
+
res.append(self._get_ring(i))
|
|
149
|
+
return res
|
|
133
150
|
else:
|
|
134
|
-
|
|
135
|
-
return self._get_ring(i)
|
|
151
|
+
raise TypeError("key must be an index or slice")
|
|
136
152
|
|
|
137
153
|
@property
|
|
138
154
|
def _longest(self):
|
|
@@ -300,6 +316,9 @@ def orient(polygon, sign=1.0):
|
|
|
300
316
|
return Polygon(rings[0], rings[1:])
|
|
301
317
|
|
|
302
318
|
def geos_linearring_from_py(ob, update_geom=None, update_ndim=0):
|
|
319
|
+
# If numpy is present, we use numpy.require to ensure that we have a
|
|
320
|
+
# C-continguous array that owns its data. View data will be copied.
|
|
321
|
+
ob = required(ob)
|
|
303
322
|
try:
|
|
304
323
|
# From array protocol
|
|
305
324
|
array = ob.__array_interface__
|
shapely/geometry/polygon.pyc
CHANGED
|
Binary file
|
shapely/geometry/proxy.py
CHANGED
|
@@ -1,10 +1,8 @@
|
|
|
1
1
|
"""Proxy for coordinates stored outside Shapely geometries
|
|
2
2
|
"""
|
|
3
3
|
|
|
4
|
+
from shapely.geometry.base import deserialize_wkb, EMPTY
|
|
4
5
|
from shapely.geos import lgeos
|
|
5
|
-
from shapely import wkb
|
|
6
|
-
|
|
7
|
-
EMPTY = wkb.deserialize('010700000000000000'.decode('hex'))
|
|
8
6
|
|
|
9
7
|
|
|
10
8
|
class CachingGeometryProxy(object):
|
shapely/geometry/proxy.pyc
CHANGED
|
Binary file
|
shapely/geos.py
CHANGED
|
@@ -42,7 +42,7 @@ def load_dll(libname, fallbacks=None):
|
|
|
42
42
|
raise OSError(
|
|
43
43
|
"Could not find library %s or load any of its variants %s" % (
|
|
44
44
|
libname, fallbacks or []))
|
|
45
|
-
|
|
45
|
+
|
|
46
46
|
if sys.platform.startswith('linux'):
|
|
47
47
|
_lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so'])
|
|
48
48
|
free = load_dll('c').free
|
|
@@ -64,7 +64,7 @@ elif sys.platform == 'darwin':
|
|
|
64
64
|
elif sys.platform == 'win32':
|
|
65
65
|
try:
|
|
66
66
|
egg_dlls = os.path.abspath(os.path.join(os.path.dirname(__file__),
|
|
67
|
-
|
|
67
|
+
r"DLLs"))
|
|
68
68
|
wininst_dlls = os.path.abspath(os.__file__ + "../../../DLLs")
|
|
69
69
|
original_path = os.environ['PATH']
|
|
70
70
|
os.environ['PATH'] = "%s;%s;%s" % (egg_dlls, wininst_dlls, original_path)
|
|
@@ -94,10 +94,15 @@ def _geos_c_version():
|
|
|
94
94
|
func = _lgeos.GEOSversion
|
|
95
95
|
func.argtypes = []
|
|
96
96
|
func.restype = c_char_p
|
|
97
|
-
v = func()
|
|
98
|
-
|
|
97
|
+
v = func()
|
|
98
|
+
c_ver = v.split('-')[2]
|
|
99
|
+
# Ditch any SVN revision numbering that may have crept in without (ftm)
|
|
100
|
+
# importing `re`.
|
|
101
|
+
c_ver = c_ver.split()[0]
|
|
102
|
+
return tuple(int(n) for n in c_ver.split('.')), v
|
|
99
103
|
|
|
100
|
-
geos_capi_version
|
|
104
|
+
geos_capi_version, geos_version_string = _geos_c_version()
|
|
105
|
+
geos_c_version = geos_capi_version
|
|
101
106
|
|
|
102
107
|
# If we have the new interface, then record a baseline so that we know what
|
|
103
108
|
# additional functions are declared in ctypes_declarations.
|
|
@@ -112,7 +117,7 @@ prototype(_lgeos, geos_c_version)
|
|
|
112
117
|
if geos_c_version >= (1,5,0):
|
|
113
118
|
end_set = set(_lgeos.__dict__)
|
|
114
119
|
new_func_names = end_set - start_set
|
|
115
|
-
|
|
120
|
+
|
|
116
121
|
for func_name in new_func_names:
|
|
117
122
|
new_func_name = "%s_r" % func_name
|
|
118
123
|
if hasattr(_lgeos, new_func_name):
|
|
@@ -127,7 +132,7 @@ if geos_c_version >= (1,5,0):
|
|
|
127
132
|
new_func.argtypes = [c_void_p] + old_func.argtypes
|
|
128
133
|
if old_func.errcheck is not None:
|
|
129
134
|
new_func.errcheck = old_func.errcheck
|
|
130
|
-
|
|
135
|
+
|
|
131
136
|
# Handle special case.
|
|
132
137
|
_lgeos.initGEOS_r.restype = c_void_p
|
|
133
138
|
_lgeos.initGEOS_r.argtypes = [EXCEPTION_HANDLER_FUNCTYPE, EXCEPTION_HANDLER_FUNCTYPE]
|
|
@@ -192,9 +197,9 @@ class LGEOSBase(threading.local):
|
|
|
192
197
|
def __init__(self, dll):
|
|
193
198
|
self._lgeos = dll
|
|
194
199
|
self.geos_handle = None
|
|
195
|
-
|
|
196
200
|
|
|
197
|
-
|
|
201
|
+
|
|
202
|
+
class LGEOS14(LGEOSBase):
|
|
198
203
|
"""Proxy for the GEOS_C DLL/SO API version 1.4
|
|
199
204
|
"""
|
|
200
205
|
geos_capi_version = (1, 4, 0)
|
|
@@ -256,12 +261,13 @@ class LGEOS14(LGEOSBase):
|
|
|
256
261
|
self.methods['simplify'] = self.GEOSSimplify
|
|
257
262
|
self.methods['topology_preserve_simplify'] = \
|
|
258
263
|
self.GEOSTopologyPreserveSimplify
|
|
264
|
+
self.methods['cascaded_union'] = self.GEOSUnionCascaded
|
|
259
265
|
|
|
260
266
|
|
|
261
|
-
class LGEOS15(LGEOSBase):
|
|
267
|
+
class LGEOS15(LGEOSBase):
|
|
262
268
|
"""Proxy for the reentrant GEOS_C DLL/SO API version 1.5
|
|
263
269
|
"""
|
|
264
|
-
geos_capi_version = (1, 5, 0)
|
|
270
|
+
geos_capi_version = (1, 5, 0)
|
|
265
271
|
def __init__(self, dll):
|
|
266
272
|
super(LGEOS15, self).__init__(dll)
|
|
267
273
|
self.geos_handle = self._lgeos.initGEOS_r(notice_h, error_h)
|
|
@@ -297,7 +303,7 @@ class LGEOS15(LGEOSBase):
|
|
|
297
303
|
pred.func.errcheck = errcheck_predicate
|
|
298
304
|
|
|
299
305
|
self.GEOSisValidReason.func.errcheck = errcheck_just_free
|
|
300
|
-
|
|
306
|
+
|
|
301
307
|
self.methods['area'] = self.GEOSArea
|
|
302
308
|
self.methods['boundary'] = self.GEOSBoundary
|
|
303
309
|
self.methods['buffer'] = self.GEOSBuffer
|
|
@@ -334,6 +340,8 @@ class LGEOS15(LGEOSBase):
|
|
|
334
340
|
self.methods['simplify'] = self.GEOSSimplify
|
|
335
341
|
self.methods['topology_preserve_simplify'] = \
|
|
336
342
|
self.GEOSTopologyPreserveSimplify
|
|
343
|
+
self.methods['cascaded_union'] = self.GEOSUnionCascaded
|
|
344
|
+
|
|
337
345
|
|
|
338
346
|
class LGEOS16(LGEOS15):
|
|
339
347
|
"""Proxy for the reentrant GEOS_C DLL/SO API version 1.6
|
|
@@ -342,8 +350,10 @@ class LGEOS16(LGEOS15):
|
|
|
342
350
|
def __init__(self, dll):
|
|
343
351
|
super(LGEOS16, self).__init__(dll)
|
|
344
352
|
|
|
353
|
+
self.methods['buffer_with_style'] = self.GEOSBufferWithStyle
|
|
345
354
|
|
|
346
|
-
|
|
355
|
+
|
|
356
|
+
class LGEOS16LR(LGEOS16):
|
|
347
357
|
"""Proxy for the reentrant GEOS_C DLL/SO API version 1.6 with linear
|
|
348
358
|
referencing
|
|
349
359
|
"""
|
|
@@ -359,7 +369,28 @@ class LGEOS16LR(LGEOS16):
|
|
|
359
369
|
self.GEOSInterpolateNormalized
|
|
360
370
|
|
|
361
371
|
|
|
362
|
-
|
|
372
|
+
class LGEOS17(LGEOS16LR):
|
|
373
|
+
"""Proxy for the reentrant GEOS_C DLL/SO API version 1.7
|
|
374
|
+
"""
|
|
375
|
+
geos_capi_version = (1, 7, 0)
|
|
376
|
+
def __init__(self, dll):
|
|
377
|
+
super(LGEOS17, self).__init__(dll)
|
|
378
|
+
|
|
379
|
+
# GEOS 3.3.8 from homebrew has, but doesn't advertise
|
|
380
|
+
# GEOSPolygonize_full. We patch it in explicitly here.
|
|
381
|
+
key = 'GEOSPolygonize_full'
|
|
382
|
+
func = getattr(self._lgeos, key + '_r')
|
|
383
|
+
attr = ftools.partial(func, self.geos_handle)
|
|
384
|
+
attr.__name__ = func.__name__
|
|
385
|
+
setattr(self, key, attr)
|
|
386
|
+
|
|
387
|
+
self.methods['unary_union'] = self.GEOSUnaryUnion
|
|
388
|
+
self.methods['cascaded_union'] = self.methods['unary_union']
|
|
389
|
+
|
|
390
|
+
|
|
391
|
+
if geos_c_version >= (1, 7, 0):
|
|
392
|
+
L = LGEOS17
|
|
393
|
+
elif geos_c_version >= (1, 6, 0):
|
|
363
394
|
if hasattr(_lgeos, 'GEOSProject'):
|
|
364
395
|
L = LGEOS16LR
|
|
365
396
|
else:
|
shapely/geos.pyc
CHANGED
|
Binary file
|
shapely/impl.py
CHANGED
|
@@ -4,7 +4,7 @@ This is layer number 2 from the list below.
|
|
|
4
4
|
|
|
5
5
|
1) geometric objects: the Python OO API.
|
|
6
6
|
2) implementation map: an abstraction that permits different backends.
|
|
7
|
-
3) backend: callable objects that take Shapely geometric objects as arguments
|
|
7
|
+
3) backend: callable objects that take Shapely geometric objects as arguments
|
|
8
8
|
and, with GEOS as a backend, translate them to C data structures.
|
|
9
9
|
4) GEOS library: algorithms implemented in C++.
|
|
10
10
|
|
|
@@ -22,7 +22,7 @@ from shapely.topology import BinaryRealProperty, BinaryTopologicalOp
|
|
|
22
22
|
from shapely.topology import UnaryRealProperty, UnaryTopologicalOp
|
|
23
23
|
|
|
24
24
|
def delegated(func):
|
|
25
|
-
"""A delegated method raises AttributeError in the absence of backend
|
|
25
|
+
"""A delegated method raises AttributeError in the absence of backend
|
|
26
26
|
support."""
|
|
27
27
|
@wraps(func)
|
|
28
28
|
def wrapper(*args, **kwargs):
|
|
@@ -42,6 +42,8 @@ class BaseImpl(object):
|
|
|
42
42
|
self.map.update(values)
|
|
43
43
|
def __getitem__(self, key):
|
|
44
44
|
return self.map[key]
|
|
45
|
+
def __contains__(self, key):
|
|
46
|
+
return key in self.map
|
|
45
47
|
|
|
46
48
|
class GEOSImpl(BaseImpl):
|
|
47
49
|
def __repr__(self):
|
|
@@ -82,23 +84,24 @@ IMPL14 = {
|
|
|
82
84
|
'touches': (BinaryPredicate, 'touches'),
|
|
83
85
|
'within': (BinaryPredicate, 'within'),
|
|
84
86
|
'equals_exact': (BinaryPredicate, 'equals_exact'),
|
|
85
|
-
|
|
87
|
+
|
|
86
88
|
# First pure Python implementation
|
|
87
89
|
'is_ccw': (cga.is_ccw_impl, 'is_ccw'),
|
|
88
90
|
}
|
|
89
91
|
|
|
90
92
|
IMPL15 = {
|
|
91
93
|
'simplify': (UnaryTopologicalOp, 'simplify'),
|
|
92
|
-
'topology_preserve_simplify':
|
|
94
|
+
'topology_preserve_simplify':
|
|
93
95
|
(UnaryTopologicalOp, 'topology_preserve_simplify'),
|
|
94
96
|
'prepared_intersects': (BinaryPredicate, 'prepared_intersects'),
|
|
95
97
|
'prepared_contains': (BinaryPredicate, 'prepared_contains'),
|
|
96
|
-
'prepared_contains_properly':
|
|
98
|
+
'prepared_contains_properly':
|
|
97
99
|
(BinaryPredicate, 'prepared_contains_properly'),
|
|
98
100
|
'prepared_covers': (BinaryPredicate, 'prepared_covers'),
|
|
99
101
|
}
|
|
100
102
|
|
|
101
103
|
IMPL16 = {
|
|
104
|
+
'buffer_with_style': (UnaryTopologicalOp, 'buffer_with_style'),
|
|
102
105
|
}
|
|
103
106
|
|
|
104
107
|
IMPL16LR = {
|
shapely/impl.pyc
CHANGED
|
Binary file
|
shapely/iterops.pyc
CHANGED
|
Binary file
|
shapely/linref.pyc
CHANGED
|
Binary file
|
shapely/ops.py
CHANGED
|
@@ -2,13 +2,14 @@
|
|
|
2
2
|
"""
|
|
3
3
|
|
|
4
4
|
from ctypes import byref, c_void_p
|
|
5
|
+
from itertools import izip
|
|
5
6
|
|
|
6
7
|
from shapely.geos import lgeos
|
|
7
8
|
from shapely.geometry.base import geom_factory, BaseGeometry
|
|
8
9
|
from shapely.geometry import asShape, asLineString, asMultiLineString
|
|
9
10
|
|
|
10
|
-
__all__= ['
|
|
11
|
-
|
|
11
|
+
__all__= ['cascaded_union', 'linemerge', 'operator', 'polygonize',
|
|
12
|
+
'polygonize_full', 'transform', 'unary_union']
|
|
12
13
|
|
|
13
14
|
class CollectionOperator(object):
|
|
14
15
|
|
|
@@ -41,6 +42,41 @@ class CollectionOperator(object):
|
|
|
41
42
|
g._owned = False
|
|
42
43
|
yield g
|
|
43
44
|
|
|
45
|
+
def polygonize_full(self, lines):
|
|
46
|
+
"""Creates polygons from a source of lines, returning the polygons
|
|
47
|
+
and leftover geometries.
|
|
48
|
+
|
|
49
|
+
The source may be a MultiLineString, a sequence of LineString objects,
|
|
50
|
+
or a sequence of objects than can be adapted to LineStrings.
|
|
51
|
+
|
|
52
|
+
Returns a tuple of objects: (polygons, dangles, cut edges, invalid ring
|
|
53
|
+
lines). Each are a geometry collection.
|
|
54
|
+
|
|
55
|
+
Dangles are edges which have one or both ends which are not incident on
|
|
56
|
+
another edge endpoint. Cut edges are connected at both ends but do not
|
|
57
|
+
form part of polygon. Invalid ring lines form rings which are invalid
|
|
58
|
+
(bowties, etc).
|
|
59
|
+
"""
|
|
60
|
+
source = getattr(lines, 'geoms', None) or lines
|
|
61
|
+
obs = [self.shapeup(l) for l in source]
|
|
62
|
+
|
|
63
|
+
L = len(obs)
|
|
64
|
+
subs = (c_void_p * L)()
|
|
65
|
+
for i, g in enumerate(obs):
|
|
66
|
+
subs[i] = g._geom
|
|
67
|
+
collection = lgeos.GEOSGeom_createCollection(5, subs, L)
|
|
68
|
+
dangles = c_void_p()
|
|
69
|
+
cuts = c_void_p()
|
|
70
|
+
invalids = c_void_p()
|
|
71
|
+
product = lgeos.GEOSPolygonize_full(
|
|
72
|
+
collection, byref(dangles), byref(cuts), byref(invalids))
|
|
73
|
+
return (
|
|
74
|
+
geom_factory(product),
|
|
75
|
+
geom_factory(dangles),
|
|
76
|
+
geom_factory(cuts),
|
|
77
|
+
geom_factory(invalids)
|
|
78
|
+
)
|
|
79
|
+
|
|
44
80
|
def linemerge(self, lines):
|
|
45
81
|
"""Merges all connected lines from a source
|
|
46
82
|
|
|
@@ -71,13 +107,28 @@ class CollectionOperator(object):
|
|
|
71
107
|
for i, g in enumerate(geoms):
|
|
72
108
|
subs[i] = g._geom
|
|
73
109
|
collection = lgeos.GEOSGeom_createCollection(6, subs, L)
|
|
74
|
-
return geom_factory(lgeos.
|
|
110
|
+
return geom_factory(lgeos.methods['cascaded_union'](collection))
|
|
75
111
|
|
|
112
|
+
def unary_union(self, geoms):
|
|
113
|
+
"""Returns the union of a sequence of geometries
|
|
114
|
+
|
|
115
|
+
This method replaces :meth:`cascaded_union` as the
|
|
116
|
+
prefered method for dissolving many polygons.
|
|
117
|
+
|
|
118
|
+
"""
|
|
119
|
+
L = len(geoms)
|
|
120
|
+
subs = (c_void_p * L)()
|
|
121
|
+
for i, g in enumerate(geoms):
|
|
122
|
+
subs[i] = g._geom
|
|
123
|
+
collection = lgeos.GEOSGeom_createCollection(6, subs, L)
|
|
124
|
+
return geom_factory(lgeos.methods['unary_union'](collection))
|
|
76
125
|
|
|
77
126
|
operator = CollectionOperator()
|
|
78
127
|
polygonize = operator.polygonize
|
|
128
|
+
polygonize_full = operator.polygonize_full
|
|
79
129
|
linemerge = operator.linemerge
|
|
80
130
|
cascaded_union = operator.cascaded_union
|
|
131
|
+
unary_union = operator.unary_union
|
|
81
132
|
|
|
82
133
|
class ValidateOp(object):
|
|
83
134
|
def __call__(self, this):
|
|
@@ -85,3 +136,74 @@ class ValidateOp(object):
|
|
|
85
136
|
|
|
86
137
|
validate = ValidateOp()
|
|
87
138
|
|
|
139
|
+
def transform(func, geom):
|
|
140
|
+
"""Applies `func` to all coordinates of `geom` and returns a new
|
|
141
|
+
geometry of the same type from the transformed coordinates.
|
|
142
|
+
|
|
143
|
+
`func` maps x, y, and optionally z to output xp, yp, zp. The input
|
|
144
|
+
parameters may iterable types like lists or arrays or single values.
|
|
145
|
+
The output shall be of the same type. Scalars in, scalars out.
|
|
146
|
+
Lists in, lists out.
|
|
147
|
+
|
|
148
|
+
For example, here is an identity function applicable to both types
|
|
149
|
+
of input.
|
|
150
|
+
|
|
151
|
+
def id_func(x, y, z=None):
|
|
152
|
+
return tuple(filter(None, [x, y, z]))
|
|
153
|
+
|
|
154
|
+
g2 = transform(id_func, g1)
|
|
155
|
+
|
|
156
|
+
A partially applied transform function from pyproj satisfies the
|
|
157
|
+
requirements for `func`.
|
|
158
|
+
|
|
159
|
+
from functools import partial
|
|
160
|
+
import pyproj
|
|
161
|
+
|
|
162
|
+
project = partial(
|
|
163
|
+
pyproj.transform,
|
|
164
|
+
pyproj.Proj(init='espg:4326'),
|
|
165
|
+
pyproj.Proj(init='epsg:26913'))
|
|
166
|
+
|
|
167
|
+
g2 = transform(project, g1)
|
|
168
|
+
|
|
169
|
+
Lambda expressions such as the one in
|
|
170
|
+
|
|
171
|
+
g2 = transform(lambda x, y, z=None: (x+1.0, y+1.0), g1)
|
|
172
|
+
|
|
173
|
+
also satisfy the requirements for `func`.
|
|
174
|
+
"""
|
|
175
|
+
|
|
176
|
+
if geom.type in ('Point', 'LineString', 'Polygon'):
|
|
177
|
+
|
|
178
|
+
# First we try to apply func to x, y, z sequences. When func is
|
|
179
|
+
# optimized for sequences, this is the fastest, though zipping
|
|
180
|
+
# the results up to go back into the geometry constructors adds
|
|
181
|
+
# extra cost.
|
|
182
|
+
try:
|
|
183
|
+
if geom.type in ('Point', 'LineString'):
|
|
184
|
+
return type(geom)(zip(*func(*izip(*geom.coords))))
|
|
185
|
+
elif geom.type == 'Polygon':
|
|
186
|
+
shell = type(geom.exterior)(
|
|
187
|
+
zip(*func(*izip(*geom.exterior.coords))))
|
|
188
|
+
holes = list(type(ring)(zip(*func(*izip(*ring.coords)))) for
|
|
189
|
+
ring in geom.interiors)
|
|
190
|
+
return type(geom)(shell, holes)
|
|
191
|
+
|
|
192
|
+
# A func that assumes x, y, z are single values will likely raise a
|
|
193
|
+
# TypeError, in which case we'll try again.
|
|
194
|
+
except TypeError:
|
|
195
|
+
if geom.type in ('Point', 'LineString'):
|
|
196
|
+
return type(geom)([func(*c) for c in geom.coords])
|
|
197
|
+
elif geom.type == 'Polygon':
|
|
198
|
+
shell = type(geom.exterior)(
|
|
199
|
+
[func(*c) for c in geom.exterior.coords])
|
|
200
|
+
holes = list(type(ring)(
|
|
201
|
+
[func(*c) for c in ring.coords]) for
|
|
202
|
+
ring in geom.interiors)
|
|
203
|
+
return type(geom)(shell, holes)
|
|
204
|
+
|
|
205
|
+
elif geom.type.startswith('Multi') or geom.type == 'GeometryCollection':
|
|
206
|
+
return type(geom)([transform(func, part) for part in geom.geoms])
|
|
207
|
+
else:
|
|
208
|
+
raise ValueError('Type %r not recognized' % geom.type)
|
|
209
|
+
|
shapely/ops.pyc
CHANGED
|
Binary file
|
shapely/predicates.pyc
CHANGED
|
Binary file
|
shapely/prepared.pyc
CHANGED
|
Binary file
|
shapely/speedups/__init__.pyc
CHANGED
|
Binary file
|