shapely 1.2.7__py2.7-win32.egg
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- DLLs/geos.dll +0 -0
- DLLs/libgeos-3-2-2.dll +0 -0
- EGG-INFO/PKG-INFO +173 -0
- EGG-INFO/not-zip-safe +1 -0
- EGG-INFO/scripts/dissolve.py +53 -0
- EGG-INFO/scripts/intersect.py +81 -0
- shapely/__init__.py +1 -0
- shapely/__init__.pyc +0 -0
- shapely/coords.py +167 -0
- shapely/coords.pyc +0 -0
- shapely/ctypes_declarations.py +276 -0
- shapely/ctypes_declarations.pyc +0 -0
- shapely/geometry/__init__.py +20 -0
- shapely/geometry/__init__.pyc +0 -0
- shapely/geometry/base.py +595 -0
- shapely/geometry/base.pyc +0 -0
- shapely/geometry/collection.py +43 -0
- shapely/geometry/collection.pyc +0 -0
- shapely/geometry/geo.py +68 -0
- shapely/geometry/geo.pyc +0 -0
- shapely/geometry/linestring.py +230 -0
- shapely/geometry/linestring.pyc +0 -0
- shapely/geometry/multilinestring.py +133 -0
- shapely/geometry/multilinestring.pyc +0 -0
- shapely/geometry/multipoint.py +180 -0
- shapely/geometry/multipoint.pyc +0 -0
- shapely/geometry/multipolygon.py +154 -0
- shapely/geometry/multipolygon.pyc +0 -0
- shapely/geometry/point.py +241 -0
- shapely/geometry/point.pyc +0 -0
- shapely/geometry/polygon.py +449 -0
- shapely/geometry/polygon.pyc +0 -0
- shapely/geometry/proxy.py +54 -0
- shapely/geometry/proxy.pyc +0 -0
- shapely/geos.py +370 -0
- shapely/geos.pyc +0 -0
- shapely/impl.py +118 -0
- shapely/impl.pyc +0 -0
- shapely/iterops.py +53 -0
- shapely/iterops.pyc +0 -0
- shapely/linref.py +26 -0
- shapely/linref.pyc +0 -0
- shapely/ops.py +87 -0
- shapely/ops.pyc +0 -0
- shapely/predicates.py +24 -0
- shapely/predicates.pyc +0 -0
- shapely/prepared.py +58 -0
- shapely/prepared.pyc +0 -0
- shapely/topology.py +62 -0
- shapely/topology.pyc +0 -0
- shapely/validation.py +7 -0
- shapely/validation.pyc +0 -0
- shapely/wkb.py +39 -0
- shapely/wkb.pyc +0 -0
- shapely/wkt.py +34 -0
- shapely/wkt.pyc +0 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
"""Proxy for coordinates stored outside Shapely geometries
|
|
2
|
+
"""
|
|
3
|
+
|
|
4
|
+
from shapely.geos import lgeos
|
|
5
|
+
from shapely import wkb
|
|
6
|
+
|
|
7
|
+
EMPTY = wkb.deserialize('010700000000000000'.decode('hex'))
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class CachingGeometryProxy(object):
|
|
11
|
+
|
|
12
|
+
context = None
|
|
13
|
+
factory = None
|
|
14
|
+
__geom__ = EMPTY
|
|
15
|
+
_gtag = None
|
|
16
|
+
|
|
17
|
+
def __init__(self, context):
|
|
18
|
+
self.context = context
|
|
19
|
+
|
|
20
|
+
@property
|
|
21
|
+
def _is_empty(self):
|
|
22
|
+
return self.__geom__ in [EMPTY, None]
|
|
23
|
+
|
|
24
|
+
def empty(self):
|
|
25
|
+
if not self._is_empty:
|
|
26
|
+
from shapely.geos import lgeos
|
|
27
|
+
lgeos.GEOSGeom_destroy(self.__geom__)
|
|
28
|
+
self.__geom__ = EMPTY
|
|
29
|
+
|
|
30
|
+
@property
|
|
31
|
+
def _geom(self):
|
|
32
|
+
"""Keeps the GEOS geometry in synch with the context."""
|
|
33
|
+
gtag = self.gtag()
|
|
34
|
+
if gtag != self._gtag or self._is_empty:
|
|
35
|
+
self.empty()
|
|
36
|
+
self.__geom__, n = self.factory(self.context)
|
|
37
|
+
self._gtag = gtag
|
|
38
|
+
return self.__geom__
|
|
39
|
+
|
|
40
|
+
def gtag(self):
|
|
41
|
+
return hash(repr(self.context))
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class PolygonProxy(CachingGeometryProxy):
|
|
45
|
+
|
|
46
|
+
@property
|
|
47
|
+
def _geom(self):
|
|
48
|
+
"""Keeps the GEOS geometry in synch with the context."""
|
|
49
|
+
gtag = self.gtag()
|
|
50
|
+
if gtag != self._gtag or self._is_empty:
|
|
51
|
+
self.empty()
|
|
52
|
+
self.__geom__, n = self.factory(self.context[0], self.context[1])
|
|
53
|
+
self._gtag = gtag
|
|
54
|
+
return self.__geom__
|
|
Binary file
|
shapely/geos.py
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Proxies for the libgeos_c shared lib, GEOS-specific exceptions, and utilities
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
import atexit
|
|
6
|
+
import functools
|
|
7
|
+
import logging
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
import time
|
|
11
|
+
import threading
|
|
12
|
+
import ctypes
|
|
13
|
+
from ctypes import cdll, CDLL, PyDLL, CFUNCTYPE, c_char_p, c_void_p, string_at
|
|
14
|
+
from ctypes.util import find_library
|
|
15
|
+
|
|
16
|
+
from ctypes_declarations import prototype
|
|
17
|
+
|
|
18
|
+
# Begin by creating a do-nothing handler and adding to this module's logger.
|
|
19
|
+
class NullHandler(logging.Handler):
|
|
20
|
+
def emit(self, record):
|
|
21
|
+
pass
|
|
22
|
+
LOG = logging.getLogger(__name__)
|
|
23
|
+
LOG.addHandler(NullHandler())
|
|
24
|
+
|
|
25
|
+
# Find and load the GEOS and C libraries
|
|
26
|
+
# If this ever gets any longer, we'll break it into separate modules
|
|
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
|
+
|
|
45
|
+
if sys.platform == 'linux2':
|
|
46
|
+
_lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so'])
|
|
47
|
+
free = load_dll('c').free
|
|
48
|
+
free.argtypes = [c_void_p]
|
|
49
|
+
free.restype = None
|
|
50
|
+
|
|
51
|
+
elif sys.platform == 'darwin':
|
|
52
|
+
alt_paths = [
|
|
53
|
+
# The Framework build from Kyng Chaos:
|
|
54
|
+
"/Library/Frameworks/GEOS.framework/Versions/Current/GEOS",
|
|
55
|
+
# macports
|
|
56
|
+
'/opt/local/lib/libgeos_c.dylib',
|
|
57
|
+
]
|
|
58
|
+
_lgeos = load_dll('geos_c', fallbacks=alt_paths)
|
|
59
|
+
free = load_dll('c').free
|
|
60
|
+
free.argtypes = [c_void_p]
|
|
61
|
+
free.restype = None
|
|
62
|
+
|
|
63
|
+
elif sys.platform == 'win32':
|
|
64
|
+
try:
|
|
65
|
+
egg_dlls = os.path.abspath(os.path.join(os.path.dirname(__file__),
|
|
66
|
+
r"..\DLLs"))
|
|
67
|
+
wininst_dlls = os.path.abspath(os.__file__ + "../../../DLLs")
|
|
68
|
+
original_path = os.environ['PATH']
|
|
69
|
+
os.environ['PATH'] = "%s;%s;%s" % (egg_dlls, wininst_dlls, original_path)
|
|
70
|
+
_lgeos = CDLL("geos.dll")
|
|
71
|
+
except (ImportError, WindowsError, OSError):
|
|
72
|
+
raise
|
|
73
|
+
def free(m):
|
|
74
|
+
try:
|
|
75
|
+
cdll.msvcrt.free(m)
|
|
76
|
+
except WindowsError:
|
|
77
|
+
# XXX: See http://trac.gispython.org/projects/PCL/ticket/149
|
|
78
|
+
pass
|
|
79
|
+
|
|
80
|
+
elif sys.platform == 'sunos5':
|
|
81
|
+
_lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so'])
|
|
82
|
+
free = CDLL('libc.so.1').free
|
|
83
|
+
free.argtypes = [c_void_p]
|
|
84
|
+
free.restype = None
|
|
85
|
+
|
|
86
|
+
else: # other *nix systems
|
|
87
|
+
_lgeos = load_dll('geos_c', fallbacks=['libgeos_c.so.1', 'libgeos_c.so'])
|
|
88
|
+
free = load_dll('c', fallbacks=['libc.so.6']).free
|
|
89
|
+
free.argtypes = [c_void_p]
|
|
90
|
+
free.restype = None
|
|
91
|
+
|
|
92
|
+
def _geos_c_version():
|
|
93
|
+
func = _lgeos.GEOSversion
|
|
94
|
+
func.restype = c_char_p
|
|
95
|
+
v = func().split('-')[2]
|
|
96
|
+
return tuple(int(n) for n in v.split('.'))
|
|
97
|
+
|
|
98
|
+
geos_capi_version = geos_c_version = _geos_c_version()
|
|
99
|
+
|
|
100
|
+
# If we have the new interface, then record a baseline so that we know what
|
|
101
|
+
# additional functions are declared in ctypes_declarations.
|
|
102
|
+
if geos_c_version >= (1,5,0):
|
|
103
|
+
start_set = set(_lgeos.__dict__)
|
|
104
|
+
|
|
105
|
+
# Apply prototypes for the libgeos_c functions
|
|
106
|
+
prototype(_lgeos, geos_c_version)
|
|
107
|
+
|
|
108
|
+
# If we have the new interface, automatically detect all function
|
|
109
|
+
# declarations, and declare their re-entrant counterpart.
|
|
110
|
+
if geos_c_version >= (1,5,0):
|
|
111
|
+
end_set = set(_lgeos.__dict__)
|
|
112
|
+
new_func_names = end_set - start_set
|
|
113
|
+
|
|
114
|
+
for func_name in new_func_names:
|
|
115
|
+
new_func_name = "%s_r" % func_name
|
|
116
|
+
if hasattr(_lgeos, new_func_name):
|
|
117
|
+
new_func = getattr(_lgeos, new_func_name)
|
|
118
|
+
old_func = getattr(_lgeos, func_name)
|
|
119
|
+
new_func.restype = old_func.restype
|
|
120
|
+
if old_func.argtypes is None:
|
|
121
|
+
# Handle functions that didn't take an argument before,
|
|
122
|
+
# finishGEOS.
|
|
123
|
+
new_func.argtypes = [c_void_p]
|
|
124
|
+
else:
|
|
125
|
+
new_func.argtypes = [c_void_p] + old_func.argtypes
|
|
126
|
+
if old_func.errcheck is not None:
|
|
127
|
+
new_func.errcheck = old_func.errcheck
|
|
128
|
+
|
|
129
|
+
# Handle special case.
|
|
130
|
+
_lgeos.initGEOS_r.restype = c_void_p
|
|
131
|
+
_lgeos.initGEOS_r.argtypes = [c_void_p, c_void_p]
|
|
132
|
+
_lgeos.finishGEOS_r.argtypes = [c_void_p]
|
|
133
|
+
|
|
134
|
+
# Exceptions
|
|
135
|
+
|
|
136
|
+
class ReadingError(Exception):
|
|
137
|
+
pass
|
|
138
|
+
|
|
139
|
+
class DimensionError(Exception):
|
|
140
|
+
pass
|
|
141
|
+
|
|
142
|
+
class TopologicalError(Exception):
|
|
143
|
+
pass
|
|
144
|
+
|
|
145
|
+
class PredicateError(Exception):
|
|
146
|
+
pass
|
|
147
|
+
|
|
148
|
+
def error_handler(fmt, list):
|
|
149
|
+
LOG.error("%s", list)
|
|
150
|
+
error_h = CFUNCTYPE(None, c_char_p, c_char_p)(error_handler)
|
|
151
|
+
|
|
152
|
+
def notice_handler(fmt, list):
|
|
153
|
+
LOG.warning("%s", list)
|
|
154
|
+
notice_h = CFUNCTYPE(None, c_char_p, c_char_p)(notice_handler)
|
|
155
|
+
|
|
156
|
+
def cleanup():
|
|
157
|
+
if _lgeos is not None :
|
|
158
|
+
_lgeos.finishGEOS()
|
|
159
|
+
|
|
160
|
+
atexit.register(cleanup)
|
|
161
|
+
|
|
162
|
+
# Errcheck functions
|
|
163
|
+
|
|
164
|
+
def errcheck_wkb(result, func, argtuple):
|
|
165
|
+
if not result:
|
|
166
|
+
return None
|
|
167
|
+
size_ref = argtuple[-1]
|
|
168
|
+
size = size_ref._obj
|
|
169
|
+
retval = ctypes.string_at(result, size.value)[:]
|
|
170
|
+
lgeos.GEOSFree(result)
|
|
171
|
+
return retval
|
|
172
|
+
|
|
173
|
+
def errcheck_just_free(result, func, argtuple):
|
|
174
|
+
retval = string_at(result)
|
|
175
|
+
lgeos.GEOSFree(result)
|
|
176
|
+
return retval
|
|
177
|
+
|
|
178
|
+
def errcheck_predicate(result, func, argtuple):
|
|
179
|
+
if result == 2:
|
|
180
|
+
raise PredicateError("Failed to evaluate %s" % repr(func))
|
|
181
|
+
return result
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
class LGEOSBase(threading.local):
|
|
185
|
+
"""Proxy for the GEOS_C DLL/SO
|
|
186
|
+
|
|
187
|
+
This is a base class. Do not instantiate.
|
|
188
|
+
"""
|
|
189
|
+
methods = {}
|
|
190
|
+
def __init__(self, dll):
|
|
191
|
+
self._lgeos = dll
|
|
192
|
+
self.geos_handle = None
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
class LGEOS14(LGEOSBase):
|
|
196
|
+
"""Proxy for the GEOS_C DLL/SO API version 1.4
|
|
197
|
+
"""
|
|
198
|
+
geos_capi_version = (1, 4, 0)
|
|
199
|
+
def __init__(self, dll):
|
|
200
|
+
super(LGEOS14, self).__init__(dll)
|
|
201
|
+
self.geos_handle = self._lgeos.initGEOS(notice_h, error_h)
|
|
202
|
+
keys = self._lgeos.__dict__.keys()
|
|
203
|
+
for key in keys:
|
|
204
|
+
setattr(self, key, getattr(self._lgeos, key))
|
|
205
|
+
self.GEOSFree = self._lgeos.free
|
|
206
|
+
self.GEOSGeomToWKB_buf.errcheck = errcheck_wkb
|
|
207
|
+
self.GEOSGeomToWKT.errcheck = errcheck_just_free
|
|
208
|
+
self.GEOSRelate.errcheck = errcheck_just_free
|
|
209
|
+
for pred in ( self.GEOSDisjoint,
|
|
210
|
+
self.GEOSTouches,
|
|
211
|
+
self.GEOSIntersects,
|
|
212
|
+
self.GEOSCrosses,
|
|
213
|
+
self.GEOSWithin,
|
|
214
|
+
self.GEOSContains,
|
|
215
|
+
self.GEOSOverlaps,
|
|
216
|
+
self.GEOSEquals,
|
|
217
|
+
self.GEOSEqualsExact,
|
|
218
|
+
self.GEOSisEmpty,
|
|
219
|
+
self.GEOSisValid,
|
|
220
|
+
self.GEOSisSimple,
|
|
221
|
+
self.GEOSisRing,
|
|
222
|
+
self.GEOSHasZ
|
|
223
|
+
):
|
|
224
|
+
pred.errcheck = errcheck_predicate
|
|
225
|
+
|
|
226
|
+
self.methods['area'] = self.GEOSArea
|
|
227
|
+
self.methods['boundary'] = self.GEOSBoundary
|
|
228
|
+
self.methods['buffer'] = self.GEOSBuffer
|
|
229
|
+
self.methods['centroid'] = self.GEOSGetCentroid
|
|
230
|
+
self.methods['representative_point'] = self.GEOSPointOnSurface
|
|
231
|
+
self.methods['convex_hull'] = self.GEOSConvexHull
|
|
232
|
+
self.methods['distance'] = self.GEOSDistance
|
|
233
|
+
self.methods['envelope'] = self.GEOSEnvelope
|
|
234
|
+
self.methods['length'] = self.GEOSLength
|
|
235
|
+
self.methods['has_z'] = self.GEOSHasZ
|
|
236
|
+
self.methods['is_empty'] = self.GEOSisEmpty
|
|
237
|
+
self.methods['is_ring'] = self.GEOSisRing
|
|
238
|
+
self.methods['is_simple'] = self.GEOSisSimple
|
|
239
|
+
self.methods['is_valid'] = self.GEOSisValid
|
|
240
|
+
self.methods['disjoint'] = self.GEOSDisjoint
|
|
241
|
+
self.methods['touches'] = self.GEOSTouches
|
|
242
|
+
self.methods['intersects'] = self.GEOSIntersects
|
|
243
|
+
self.methods['crosses'] = self.GEOSCrosses
|
|
244
|
+
self.methods['within'] = self.GEOSWithin
|
|
245
|
+
self.methods['contains'] = self.GEOSContains
|
|
246
|
+
self.methods['overlaps'] = self.GEOSOverlaps
|
|
247
|
+
self.methods['equals'] = self.GEOSEquals
|
|
248
|
+
self.methods['equals_exact'] = self.GEOSEqualsExact
|
|
249
|
+
self.methods['relate'] = self.GEOSRelate
|
|
250
|
+
self.methods['difference'] = self.GEOSDifference
|
|
251
|
+
self.methods['symmetric_difference'] = self.GEOSSymDifference
|
|
252
|
+
self.methods['union'] = self.GEOSUnion
|
|
253
|
+
self.methods['intersection'] = self.GEOSIntersection
|
|
254
|
+
self.methods['simplify'] = self.GEOSSimplify
|
|
255
|
+
self.methods['topology_preserve_simplify'] = \
|
|
256
|
+
self.GEOSTopologyPreserveSimplify
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
class LGEOS15(LGEOSBase):
|
|
260
|
+
"""Proxy for the reentrant GEOS_C DLL/SO API version 1.5
|
|
261
|
+
"""
|
|
262
|
+
geos_capi_version = (1, 5, 0)
|
|
263
|
+
def __init__(self, dll):
|
|
264
|
+
super(LGEOS15, self).__init__(dll)
|
|
265
|
+
self.geos_handle = self._lgeos.initGEOS_r(notice_h, error_h)
|
|
266
|
+
keys = self._lgeos.__dict__.keys()
|
|
267
|
+
for key in filter(lambda x: not x.endswith('_r'), keys):
|
|
268
|
+
if key + '_r' in keys:
|
|
269
|
+
reentr_func = getattr(self._lgeos, key + '_r')
|
|
270
|
+
attr = functools.partial(reentr_func, self.geos_handle)
|
|
271
|
+
attr.__name__ = reentr_func.__name__
|
|
272
|
+
setattr(self, key, attr)
|
|
273
|
+
else:
|
|
274
|
+
setattr(self, key, getattr(self._lgeos, key))
|
|
275
|
+
if not hasattr(self, 'GEOSFree'):
|
|
276
|
+
self.GEOSFree = self._lgeos.free
|
|
277
|
+
self.GEOSGeomToWKB_buf.func.errcheck = errcheck_wkb
|
|
278
|
+
self.GEOSGeomToWKT.func.errcheck = errcheck_just_free
|
|
279
|
+
self.GEOSRelate.func.errcheck = errcheck_just_free
|
|
280
|
+
for pred in ( self.GEOSDisjoint,
|
|
281
|
+
self.GEOSTouches,
|
|
282
|
+
self.GEOSIntersects,
|
|
283
|
+
self.GEOSCrosses,
|
|
284
|
+
self.GEOSWithin,
|
|
285
|
+
self.GEOSContains,
|
|
286
|
+
self.GEOSOverlaps,
|
|
287
|
+
self.GEOSEquals,
|
|
288
|
+
self.GEOSEqualsExact,
|
|
289
|
+
self.GEOSisEmpty,
|
|
290
|
+
self.GEOSisValid,
|
|
291
|
+
self.GEOSisSimple,
|
|
292
|
+
self.GEOSisRing,
|
|
293
|
+
self.GEOSHasZ
|
|
294
|
+
):
|
|
295
|
+
pred.func.errcheck = errcheck_predicate
|
|
296
|
+
|
|
297
|
+
self.GEOSisValidReason.func.errcheck = errcheck_just_free
|
|
298
|
+
|
|
299
|
+
self.methods['area'] = self.GEOSArea
|
|
300
|
+
self.methods['boundary'] = self.GEOSBoundary
|
|
301
|
+
self.methods['buffer'] = self.GEOSBuffer
|
|
302
|
+
self.methods['centroid'] = self.GEOSGetCentroid
|
|
303
|
+
self.methods['representative_point'] = self.GEOSPointOnSurface
|
|
304
|
+
self.methods['convex_hull'] = self.GEOSConvexHull
|
|
305
|
+
self.methods['distance'] = self.GEOSDistance
|
|
306
|
+
self.methods['envelope'] = self.GEOSEnvelope
|
|
307
|
+
self.methods['length'] = self.GEOSLength
|
|
308
|
+
self.methods['has_z'] = self.GEOSHasZ
|
|
309
|
+
self.methods['is_empty'] = self.GEOSisEmpty
|
|
310
|
+
self.methods['is_ring'] = self.GEOSisRing
|
|
311
|
+
self.methods['is_simple'] = self.GEOSisSimple
|
|
312
|
+
self.methods['is_valid'] = self.GEOSisValid
|
|
313
|
+
self.methods['disjoint'] = self.GEOSDisjoint
|
|
314
|
+
self.methods['touches'] = self.GEOSTouches
|
|
315
|
+
self.methods['intersects'] = self.GEOSIntersects
|
|
316
|
+
self.methods['crosses'] = self.GEOSCrosses
|
|
317
|
+
self.methods['within'] = self.GEOSWithin
|
|
318
|
+
self.methods['contains'] = self.GEOSContains
|
|
319
|
+
self.methods['overlaps'] = self.GEOSOverlaps
|
|
320
|
+
self.methods['equals'] = self.GEOSEquals
|
|
321
|
+
self.methods['equals_exact'] = self.GEOSEqualsExact
|
|
322
|
+
self.methods['relate'] = self.GEOSRelate
|
|
323
|
+
self.methods['difference'] = self.GEOSDifference
|
|
324
|
+
self.methods['symmetric_difference'] = self.GEOSSymDifference
|
|
325
|
+
self.methods['union'] = self.GEOSUnion
|
|
326
|
+
self.methods['intersection'] = self.GEOSIntersection
|
|
327
|
+
self.methods['prepared_intersects'] = self.GEOSPreparedIntersects
|
|
328
|
+
self.methods['prepared_contains'] = self.GEOSPreparedContains
|
|
329
|
+
self.methods['prepared_contains_properly'] = \
|
|
330
|
+
self.GEOSPreparedContainsProperly
|
|
331
|
+
self.methods['prepared_covers'] = self.GEOSPreparedCovers
|
|
332
|
+
self.methods['simplify'] = self.GEOSSimplify
|
|
333
|
+
self.methods['topology_preserve_simplify'] = \
|
|
334
|
+
self.GEOSTopologyPreserveSimplify
|
|
335
|
+
|
|
336
|
+
class LGEOS16(LGEOS15):
|
|
337
|
+
"""Proxy for the reentrant GEOS_C DLL/SO API version 1.6
|
|
338
|
+
"""
|
|
339
|
+
geos_capi_version = (1, 6, 0)
|
|
340
|
+
def __init__(self, dll):
|
|
341
|
+
super(LGEOS16, self).__init__(dll)
|
|
342
|
+
|
|
343
|
+
|
|
344
|
+
class LGEOS16LR(LGEOS16):
|
|
345
|
+
"""Proxy for the reentrant GEOS_C DLL/SO API version 1.6 with linear
|
|
346
|
+
referencing
|
|
347
|
+
"""
|
|
348
|
+
geos_capi_version = geos_c_version
|
|
349
|
+
def __init__(self, dll):
|
|
350
|
+
super(LGEOS16LR, self).__init__(dll)
|
|
351
|
+
|
|
352
|
+
self.methods['project'] = self.GEOSProject
|
|
353
|
+
self.methods['project_normalized'] = self.GEOSProjectNormalized
|
|
354
|
+
self.methods['interpolate'] = self.GEOSInterpolate
|
|
355
|
+
self.methods['interpolate_normalized'] = \
|
|
356
|
+
self.GEOSInterpolateNormalized
|
|
357
|
+
|
|
358
|
+
|
|
359
|
+
if geos_c_version >= (1, 6, 0):
|
|
360
|
+
if hasattr(_lgeos, 'GEOSProject'):
|
|
361
|
+
L = LGEOS16LR
|
|
362
|
+
else:
|
|
363
|
+
L = LGEOS16
|
|
364
|
+
elif geos_c_version >= (1, 5, 0):
|
|
365
|
+
L = LGEOS15
|
|
366
|
+
else:
|
|
367
|
+
L = LGEOS14
|
|
368
|
+
|
|
369
|
+
lgeos = L(_lgeos)
|
|
370
|
+
|
shapely/geos.pyc
ADDED
|
Binary file
|
shapely/impl.py
ADDED
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
"""Implementation of the intermediary layer between Shapely and GEOS
|
|
2
|
+
|
|
3
|
+
This is layer number 2 from the list below.
|
|
4
|
+
|
|
5
|
+
1) geometric objects: the Python OO API.
|
|
6
|
+
2) implementation map: an abstraction that permits different backends.
|
|
7
|
+
3) backend: callable objects that take Shapely geometric objects as arguments
|
|
8
|
+
and, with GEOS as a backend, translate them to C data structures.
|
|
9
|
+
4) GEOS library: algorithms implemented in C++.
|
|
10
|
+
|
|
11
|
+
Shapely 1.2 includes a GEOS backend and it is the default.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
from functools import wraps
|
|
15
|
+
|
|
16
|
+
from shapely.coords import BoundsOp
|
|
17
|
+
from shapely.geos import lgeos
|
|
18
|
+
from shapely.linref import ProjectOp, InterpolateOp
|
|
19
|
+
from shapely.predicates import BinaryPredicate, UnaryPredicate
|
|
20
|
+
from shapely.topology import BinaryRealProperty, BinaryTopologicalOp
|
|
21
|
+
from shapely.topology import UnaryRealProperty, UnaryTopologicalOp
|
|
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
|
|
34
|
+
|
|
35
|
+
# Map geometry methods to their GEOS delegates
|
|
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
|
+
|
|
50
|
+
IMPL14 = {
|
|
51
|
+
'area': (UnaryRealProperty, 'area'),
|
|
52
|
+
'distance': (BinaryRealProperty, 'distance'),
|
|
53
|
+
'length': (UnaryRealProperty, 'length'),
|
|
54
|
+
#
|
|
55
|
+
'boundary': (UnaryTopologicalOp, 'boundary'),
|
|
56
|
+
'bounds': (BoundsOp, None),
|
|
57
|
+
'centroid': (UnaryTopologicalOp, 'centroid'),
|
|
58
|
+
'representative_point': (UnaryTopologicalOp, 'representative_point'),
|
|
59
|
+
'envelope': (UnaryTopologicalOp, 'envelope'),
|
|
60
|
+
'convex_hull': (UnaryTopologicalOp, 'convex_hull'),
|
|
61
|
+
'buffer': (UnaryTopologicalOp, 'buffer'),
|
|
62
|
+
#
|
|
63
|
+
'difference': (BinaryTopologicalOp, 'difference'),
|
|
64
|
+
'intersection': (BinaryTopologicalOp, 'intersection'),
|
|
65
|
+
'symmetric_difference': (BinaryTopologicalOp, 'symmetric_difference'),
|
|
66
|
+
'union': (BinaryTopologicalOp, 'union'),
|
|
67
|
+
#
|
|
68
|
+
'has_z': (UnaryPredicate, 'has_z'),
|
|
69
|
+
'is_empty': (UnaryPredicate, 'is_empty'),
|
|
70
|
+
'is_ring': (UnaryPredicate, 'is_ring'),
|
|
71
|
+
'is_simple': (UnaryPredicate, 'is_simple'),
|
|
72
|
+
'is_valid': (UnaryPredicate, 'is_valid'),
|
|
73
|
+
#
|
|
74
|
+
'relate': (BinaryPredicate, 'relate'),
|
|
75
|
+
'contains': (BinaryPredicate, 'contains'),
|
|
76
|
+
'crosses': (BinaryPredicate, 'crosses'),
|
|
77
|
+
'disjoint': (BinaryPredicate, 'disjoint'),
|
|
78
|
+
'equals': (BinaryPredicate, 'equals'),
|
|
79
|
+
'intersects': (BinaryPredicate, 'intersects'),
|
|
80
|
+
'overlaps': (BinaryPredicate, 'overlaps'),
|
|
81
|
+
'touches': (BinaryPredicate, 'touches'),
|
|
82
|
+
'within': (BinaryPredicate, 'within'),
|
|
83
|
+
'equals_exact': (BinaryPredicate, 'equals_exact'),
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
IMPL15 = {
|
|
87
|
+
'simplify': (UnaryTopologicalOp, 'simplify'),
|
|
88
|
+
'topology_preserve_simplify':
|
|
89
|
+
(UnaryTopologicalOp, 'topology_preserve_simplify'),
|
|
90
|
+
'prepared_intersects': (BinaryPredicate, 'prepared_intersects'),
|
|
91
|
+
'prepared_contains': (BinaryPredicate, 'prepared_contains'),
|
|
92
|
+
'prepared_contains_properly':
|
|
93
|
+
(BinaryPredicate, 'prepared_contains_properly'),
|
|
94
|
+
'prepared_covers': (BinaryPredicate, 'prepared_covers'),
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
IMPL16 = {
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
IMPL16LR = {
|
|
101
|
+
'project_normalized': (ProjectOp, 'project_normalized'),
|
|
102
|
+
'project': (ProjectOp, 'project'),
|
|
103
|
+
'interpolate_normalized': (InterpolateOp, 'interpolate_normalized'),
|
|
104
|
+
'interpolate': (InterpolateOp, 'interpolate'),
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
def impl_items(defs):
|
|
108
|
+
return [(k, v[0](v[1])) for k, v in defs.items()]
|
|
109
|
+
|
|
110
|
+
imp = GEOSImpl(dict(impl_items(IMPL14)))
|
|
111
|
+
if lgeos.geos_capi_version >= (1, 5, 0):
|
|
112
|
+
imp.update(impl_items(IMPL15))
|
|
113
|
+
if lgeos.geos_capi_version >= (1, 6, 0):
|
|
114
|
+
imp.update(impl_items(IMPL16))
|
|
115
|
+
if 'project' in lgeos.methods:
|
|
116
|
+
imp.update(impl_items(IMPL16LR))
|
|
117
|
+
|
|
118
|
+
DefaultImplementation = imp
|
shapely/impl.pyc
ADDED
|
Binary file
|
shapely/iterops.py
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Iterative forms of operations
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from ctypes import c_char_p, c_size_t
|
|
6
|
+
from shapely.geos import lgeos, free
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
def geos_from_geometry(geom):
|
|
10
|
+
data = geom.to_wkb()
|
|
11
|
+
return lgeos.GEOSGeomFromWKB_buf(
|
|
12
|
+
c_char_p(data),
|
|
13
|
+
c_size_t(len(data))
|
|
14
|
+
)
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class IterOp(object):
|
|
18
|
+
|
|
19
|
+
"""A generating non-data descriptor.
|
|
20
|
+
"""
|
|
21
|
+
|
|
22
|
+
def __init__(self, fn):
|
|
23
|
+
self.fn = fn
|
|
24
|
+
|
|
25
|
+
def __call__(self, context, iterator, value=True):
|
|
26
|
+
if context._geom is None:
|
|
27
|
+
raise ValueError("Null geometry supports no operations")
|
|
28
|
+
for item in iterator:
|
|
29
|
+
try:
|
|
30
|
+
this_geom, ob = item
|
|
31
|
+
except TypeError:
|
|
32
|
+
this_geom = item
|
|
33
|
+
ob = this_geom
|
|
34
|
+
if not this_geom._geom:
|
|
35
|
+
raise ValueError("Null geometry supports no operations")
|
|
36
|
+
retval = self.fn(context._geom, this_geom._geom)
|
|
37
|
+
if retval == 2:
|
|
38
|
+
raise PredicateError(
|
|
39
|
+
"Failed to evaluate %s" % repr(self.fn))
|
|
40
|
+
elif bool(retval) == value:
|
|
41
|
+
yield ob
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
# utilities
|
|
45
|
+
disjoint = IterOp(lgeos.GEOSDisjoint)
|
|
46
|
+
touches = IterOp(lgeos.GEOSTouches)
|
|
47
|
+
intersects = IterOp(lgeos.GEOSIntersects)
|
|
48
|
+
crosses = IterOp(lgeos.GEOSCrosses)
|
|
49
|
+
within = IterOp(lgeos.GEOSWithin)
|
|
50
|
+
contains = IterOp(lgeos.GEOSContains)
|
|
51
|
+
overlaps = IterOp(lgeos.GEOSOverlaps)
|
|
52
|
+
equals = IterOp(lgeos.GEOSEquals)
|
|
53
|
+
|
shapely/iterops.pyc
ADDED
|
Binary file
|
shapely/linref.py
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"""Linear referencing
|
|
2
|
+
"""
|
|
3
|
+
|
|
4
|
+
from shapely.topology import Delegating
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class LinearRefBase(Delegating):
|
|
8
|
+
def _validate_line(self, ob):
|
|
9
|
+
super(LinearRefBase, self)._validate(ob)
|
|
10
|
+
try:
|
|
11
|
+
assert ob.geom_type in ['LineString', 'MultiLineString']
|
|
12
|
+
except AssertionError:
|
|
13
|
+
raise TypeError("Only linear types support this operation")
|
|
14
|
+
|
|
15
|
+
class ProjectOp(LinearRefBase):
|
|
16
|
+
def __call__(self, this, other):
|
|
17
|
+
self._validate_line(this)
|
|
18
|
+
self._validate(other)
|
|
19
|
+
return self.fn(this._geom, other._geom)
|
|
20
|
+
|
|
21
|
+
class InterpolateOp(LinearRefBase):
|
|
22
|
+
def __call__(self, this, distance):
|
|
23
|
+
self._validate_line(this)
|
|
24
|
+
return self.fn(this._geom, distance)
|
|
25
|
+
|
|
26
|
+
|
shapely/linref.pyc
ADDED
|
Binary file
|