shapely 1.0__py2.4.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 +173 -0
- EGG-INFO/SOURCES.txt +52 -0
- EGG-INFO/dependency_links.txt +1 -0
- EGG-INFO/not-zip-safe +1 -0
- EGG-INFO/requires.txt +2 -0
- EGG-INFO/top_level.txt +1 -0
- shapely/__init__.py +1 -0
- shapely/__init__.pyc +0 -0
- shapely/geometry/__init__.py +9 -0
- shapely/geometry/__init__.pyc +0 -0
- shapely/geometry/base.py +415 -0
- shapely/geometry/base.pyc +0 -0
- shapely/geometry/collection.py +24 -0
- shapely/geometry/collection.pyc +0 -0
- shapely/geometry/geo.py +35 -0
- shapely/geometry/geo.pyc +0 -0
- shapely/geometry/linestring.py +234 -0
- shapely/geometry/linestring.pyc +0 -0
- shapely/geometry/multilinestring.py +157 -0
- shapely/geometry/multilinestring.pyc +0 -0
- shapely/geometry/multipoint.py +187 -0
- shapely/geometry/multipoint.pyc +0 -0
- shapely/geometry/multipolygon.py +143 -0
- shapely/geometry/multipolygon.pyc +0 -0
- shapely/geometry/point.py +259 -0
- shapely/geometry/point.pyc +0 -0
- shapely/geometry/polygon.py +429 -0
- shapely/geometry/polygon.pyc +0 -0
- shapely/geos.py +80 -0
- shapely/geos.pyc +0 -0
- shapely/iterops.py +56 -0
- shapely/iterops.pyc +0 -0
- shapely/kml.py +0 -0
- shapely/kml.pyc +0 -0
- shapely/predicates.py +58 -0
- shapely/predicates.pyc +0 -0
- shapely/topology.py +66 -0
- shapely/topology.pyc +0 -0
- shapely/wkb.py +40 -0
- shapely/wkb.pyc +0 -0
- shapely/wkt.py +40 -0
- shapely/wkt.pyc +0 -0
EGG-INFO/PKG-INFO
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
Metadata-Version: 1.0
|
|
2
|
+
Name: Shapely
|
|
3
|
+
Version: 1.0
|
|
4
|
+
Summary: Geospatial geometries, predicates, and operations
|
|
5
|
+
Home-page: http://trac.gispython.org/projects/PCL/wiki/Shapely
|
|
6
|
+
Author: Sean Gillies
|
|
7
|
+
Author-email: sgillies@frii.com
|
|
8
|
+
License: BSD
|
|
9
|
+
Description: Shapely
|
|
10
|
+
=======
|
|
11
|
+
|
|
12
|
+
Shapely is a Python package for programming with 2D geospatial geometries. It
|
|
13
|
+
is based on GEOS (http://geos.refractions.net). Shapely 1.0 is ignorant about
|
|
14
|
+
coordinate and reference systems. Projection responsibility is left to specific
|
|
15
|
+
applications. For more information, see:
|
|
16
|
+
|
|
17
|
+
* Shapely wiki_
|
|
18
|
+
* Shapely manual_
|
|
19
|
+
|
|
20
|
+
Shapely requires Python 2.4+. (I've also begun to port it to Python 3.0:
|
|
21
|
+
http://zcologia.com/news/564/shapely-for-python-3-0/.)
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
Dependencies
|
|
25
|
+
------------
|
|
26
|
+
|
|
27
|
+
* libgeos_c (2.2.3 or 3.0.0+)
|
|
28
|
+
* Python ctypes_ (standard in Python 2.5+)
|
|
29
|
+
|
|
30
|
+
.. _ctypes: http://pypi.python.org/pypi/ctypes/
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
Installation
|
|
34
|
+
------------
|
|
35
|
+
|
|
36
|
+
Windows users should use the executable installer, which contains the required
|
|
37
|
+
GEOS DLL. Other users should acquire libgeos_c by any means, make sure that it
|
|
38
|
+
is on the system library path, and install from the Python package index::
|
|
39
|
+
|
|
40
|
+
$ sudo easy_install Shapely
|
|
41
|
+
|
|
42
|
+
with the setup script::
|
|
43
|
+
|
|
44
|
+
$ sudo python setup.py install
|
|
45
|
+
|
|
46
|
+
or by using the development buildout on Linux, which also provides libgeos_c::
|
|
47
|
+
|
|
48
|
+
$ svn co http://svn.gispython.org/svn/gispy/buildout/shapely.buildout/trunk shapely.buildout
|
|
49
|
+
$ cd shapely.buildout
|
|
50
|
+
$ python bootstrap.py
|
|
51
|
+
$ ./bin/buildout
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
Usage
|
|
55
|
+
-----
|
|
56
|
+
|
|
57
|
+
To buffer a point::
|
|
58
|
+
|
|
59
|
+
>>> from shapely.geometry import Point
|
|
60
|
+
>>> point = Point(-106.0, 40.0) # longitude, latitude
|
|
61
|
+
>>> point.buffer(10.0)
|
|
62
|
+
<shapely.geometry.polygon.Polygon object at ...>
|
|
63
|
+
|
|
64
|
+
See the manual_ for comprehensive examples of usage. See also Operations.txt
|
|
65
|
+
and Predicates.txt under tests/ for more examples of the spatial operations and
|
|
66
|
+
predicates provided by Shapely. See also Point.txt, LineString.txt, etc for
|
|
67
|
+
examples of the geometry APIs.
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
Numpy integration
|
|
71
|
+
-----------------
|
|
72
|
+
|
|
73
|
+
All Shapely geometry instances provide the Numpy array interface::
|
|
74
|
+
|
|
75
|
+
>>> from numpy import asarray
|
|
76
|
+
>>> a = asarray(point)
|
|
77
|
+
>>> a.size
|
|
78
|
+
3
|
|
79
|
+
>>> a.shape
|
|
80
|
+
(2,)
|
|
81
|
+
|
|
82
|
+
Numpy arrays can also be adapted to Shapely points and linestrings::
|
|
83
|
+
|
|
84
|
+
>>> from shapely.geometry import asLineString
|
|
85
|
+
>>> a = array([[1.0, 2.0], [3.0, 4.0]])
|
|
86
|
+
>>> line = asLineString(a)
|
|
87
|
+
>>> line.wkt
|
|
88
|
+
'LINESTRING (1.0000000000000000 2.0000000000000000, 3.0000000000000000 4.0000000000000000)'
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
Python Geo Interface
|
|
92
|
+
--------------------
|
|
93
|
+
|
|
94
|
+
Any object that provides the Python geo interface can be adapted to a Shapely
|
|
95
|
+
geometry with the asShape factory::
|
|
96
|
+
|
|
97
|
+
>>> d = {"type": "Point", "coordinates": (0.0, 0.0)}
|
|
98
|
+
>>> from shapely.geometry import asShape
|
|
99
|
+
>>> shape = asShape(d)
|
|
100
|
+
>>> shape.geom_type
|
|
101
|
+
'Point'
|
|
102
|
+
>>> tuple(shape.coords)
|
|
103
|
+
((0.0, 0.0),)
|
|
104
|
+
|
|
105
|
+
>>> class GeoThing(object):
|
|
106
|
+
... def __init__(self, d):
|
|
107
|
+
... self.__geo_interface__ = d
|
|
108
|
+
>>> thing = GeoThing({"type": "Point", "coordinates": (0.0, 0.0)})
|
|
109
|
+
>>> shape = asShape(thing)
|
|
110
|
+
>>> shape.geom_type
|
|
111
|
+
'Point'
|
|
112
|
+
>>> tuple(shape.coords)
|
|
113
|
+
((0.0, 0.0),)
|
|
114
|
+
|
|
115
|
+
See http://trac.gispython.org/projects/PCL/wiki/PythonGeoInterface for more
|
|
116
|
+
details on the interface.
|
|
117
|
+
|
|
118
|
+
|
|
119
|
+
Testing
|
|
120
|
+
-------
|
|
121
|
+
|
|
122
|
+
Several of the modules have docstring doctests::
|
|
123
|
+
|
|
124
|
+
$ cd shapely
|
|
125
|
+
$ python point.py
|
|
126
|
+
|
|
127
|
+
There are also two test runners under tests/. test_doctests.py requires
|
|
128
|
+
zope.testing. runalldoctests.py does not. Perhaps the easiest way to run the
|
|
129
|
+
tests is::
|
|
130
|
+
|
|
131
|
+
$ python setup.py test
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
Support
|
|
135
|
+
-------
|
|
136
|
+
|
|
137
|
+
For current information about this project, see the wiki_.
|
|
138
|
+
|
|
139
|
+
.. _wiki: http://trac.gispython.org/projects/PCL/wiki/Shapely
|
|
140
|
+
.. _manual: http://gispython.org/shapely/manual.html
|
|
141
|
+
|
|
142
|
+
If you have questions, please consider joining our community list:
|
|
143
|
+
|
|
144
|
+
http://trac.gispython.org/projects/PCL/wiki/CommunityList
|
|
145
|
+
|
|
146
|
+
|
|
147
|
+
Credits
|
|
148
|
+
-------
|
|
149
|
+
|
|
150
|
+
* Sean Gillies (Pleiades)
|
|
151
|
+
* Howard Butler (Hobu, Inc.)
|
|
152
|
+
* Kai Lautaportti (Hexagon IT)
|
|
153
|
+
* Fr |eaigue| d |eaigue| ric Junod (Camptocamp SA)
|
|
154
|
+
* Eric Lemoine (Camptocamp SA)
|
|
155
|
+
* Justin Bronn (GeoDjango) for ctypes inspiration
|
|
156
|
+
* Artem Pavlenko (Mapnik) for help with GEOS DLLs
|
|
157
|
+
|
|
158
|
+
.. |eaigue| unicode:: U+00E9
|
|
159
|
+
:trim:
|
|
160
|
+
|
|
161
|
+
Major portions of this work were supported by a grant (to Pleiades) from the
|
|
162
|
+
U.S. National Endowment for the Humanities (http://www.neh.gov).
|
|
163
|
+
|
|
164
|
+
|
|
165
|
+
Keywords: geometry topology
|
|
166
|
+
Platform: UNKNOWN
|
|
167
|
+
Classifier: Development Status :: 5 - Production/Stable
|
|
168
|
+
Classifier: Intended Audience :: Developers
|
|
169
|
+
Classifier: Intended Audience :: Science/Research
|
|
170
|
+
Classifier: License :: OSI Approved :: BSD License
|
|
171
|
+
Classifier: Operating System :: OS Independent
|
|
172
|
+
Classifier: Programming Language :: Python
|
|
173
|
+
Classifier: Topic :: Scientific/Engineering :: GIS
|
EGG-INFO/SOURCES.txt
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
CHANGES.txt
|
|
2
|
+
CREDITS.txt
|
|
3
|
+
HISTORY.txt
|
|
4
|
+
LICENSE.txt
|
|
5
|
+
README.txt
|
|
6
|
+
setup.py
|
|
7
|
+
setup_windows.py
|
|
8
|
+
Shapely.egg-info/PKG-INFO
|
|
9
|
+
Shapely.egg-info/SOURCES.txt
|
|
10
|
+
Shapely.egg-info/dependency_links.txt
|
|
11
|
+
Shapely.egg-info/requires.txt
|
|
12
|
+
Shapely.egg-info/top_level.txt
|
|
13
|
+
examples/geoms.py
|
|
14
|
+
examples/world.py
|
|
15
|
+
manual/manual.txt
|
|
16
|
+
manual/style.css
|
|
17
|
+
shapely/__init__.py
|
|
18
|
+
shapely/geos.py
|
|
19
|
+
shapely/iterops.py
|
|
20
|
+
shapely/kml.py
|
|
21
|
+
shapely/predicates.py
|
|
22
|
+
shapely/topology.py
|
|
23
|
+
shapely/wkb.py
|
|
24
|
+
shapely/wkt.py
|
|
25
|
+
shapely/geometry/__init__.py
|
|
26
|
+
shapely/geometry/base.py
|
|
27
|
+
shapely/geometry/collection.py
|
|
28
|
+
shapely/geometry/geo.py
|
|
29
|
+
shapely/geometry/linestring.py
|
|
30
|
+
shapely/geometry/multilinestring.py
|
|
31
|
+
shapely/geometry/multipoint.py
|
|
32
|
+
shapely/geometry/multipolygon.py
|
|
33
|
+
shapely/geometry/point.py
|
|
34
|
+
shapely/geometry/polygon.py
|
|
35
|
+
tests/Array.txt
|
|
36
|
+
tests/GeoInterface.txt
|
|
37
|
+
tests/IterOps.txt
|
|
38
|
+
tests/LineString.txt
|
|
39
|
+
tests/MultiLineString.txt
|
|
40
|
+
tests/MultiPoint.txt
|
|
41
|
+
tests/MultiPolygon.txt
|
|
42
|
+
tests/Operations.txt
|
|
43
|
+
tests/Persist.txt
|
|
44
|
+
tests/Point.txt
|
|
45
|
+
tests/Polygon.txt
|
|
46
|
+
tests/Predicates.txt
|
|
47
|
+
tests/__init__.py
|
|
48
|
+
tests/binascii_hex.txt
|
|
49
|
+
tests/invalid_intersection.txt
|
|
50
|
+
tests/rungrind.dist
|
|
51
|
+
tests/test_doctests.py
|
|
52
|
+
tests/valgrind-python.supp
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
EGG-INFO/not-zip-safe
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
EGG-INFO/requires.txt
ADDED
EGG-INFO/top_level.txt
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
shapely
|
shapely/__init__.py
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#
|
shapely/__init__.pyc
ADDED
|
Binary file
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
from geo import asShape
|
|
2
|
+
from point import Point, asPoint
|
|
3
|
+
from linestring import LineString, asLineString
|
|
4
|
+
from polygon import Polygon, asPolygon
|
|
5
|
+
from multipoint import MultiPoint, asMultiPoint
|
|
6
|
+
from multilinestring import MultiLineString, asMultiLineString
|
|
7
|
+
from multipolygon import MultiPolygon, asMultiPolygon
|
|
8
|
+
from collection import GeometryCollection
|
|
9
|
+
|
|
Binary file
|
shapely/geometry/base.py
ADDED
|
@@ -0,0 +1,415 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Base geometry class and utilities.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from ctypes import string_at, byref, c_int, c_size_t, c_char_p, c_double
|
|
6
|
+
import sys
|
|
7
|
+
|
|
8
|
+
from shapely.geos import lgeos, free, allocated_c_char_p
|
|
9
|
+
from shapely.predicates import BinaryPredicate, UnaryPredicate
|
|
10
|
+
from shapely.topology import BinaryTopologicalOp, UnaryTopologicalOp
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
GEOMETRY_TYPES = [
|
|
14
|
+
'Point',
|
|
15
|
+
'LineString',
|
|
16
|
+
'LinearRing',
|
|
17
|
+
'Polygon',
|
|
18
|
+
'MultiPoint',
|
|
19
|
+
'MultiLineString',
|
|
20
|
+
'MultiPolygon',
|
|
21
|
+
'GeometryCollection'
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
def geometry_type_name(g):
|
|
25
|
+
if g is None:
|
|
26
|
+
raise ValueError, "Null geometry has no type"
|
|
27
|
+
return GEOMETRY_TYPES[lgeos.GEOSGeomTypeId(g)]
|
|
28
|
+
|
|
29
|
+
# Abstract geometry factory for use with topological methods below
|
|
30
|
+
|
|
31
|
+
def geom_factory(g):
|
|
32
|
+
if not g:
|
|
33
|
+
raise ValueError, "No Shapely geometry can be created from this null value"
|
|
34
|
+
ob = BaseGeometry()
|
|
35
|
+
geom_type = geometry_type_name(g)
|
|
36
|
+
# TODO: check cost of dynamic import by profiling
|
|
37
|
+
mod = __import__(
|
|
38
|
+
'shapely.geometry',
|
|
39
|
+
globals(),
|
|
40
|
+
locals(),
|
|
41
|
+
[geom_type],
|
|
42
|
+
)
|
|
43
|
+
ob.__class__ = getattr(mod, geom_type)
|
|
44
|
+
ob._geom = g
|
|
45
|
+
ob._ndim = 2 # callers should be all from 2D worlds
|
|
46
|
+
return ob
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
class CoordinateSequence(object):
|
|
50
|
+
|
|
51
|
+
_cseq = None
|
|
52
|
+
_ndim = None
|
|
53
|
+
_length = 0
|
|
54
|
+
index = 0
|
|
55
|
+
|
|
56
|
+
def __init__(self, geom):
|
|
57
|
+
self._cseq = lgeos.GEOSGeom_getCoordSeq(geom._geom)
|
|
58
|
+
self._ndim = geom._ndim
|
|
59
|
+
|
|
60
|
+
def __iter__(self):
|
|
61
|
+
self.index = 0
|
|
62
|
+
self._length = self.__len__()
|
|
63
|
+
return self
|
|
64
|
+
|
|
65
|
+
def next(self):
|
|
66
|
+
dx = c_double()
|
|
67
|
+
dy = c_double()
|
|
68
|
+
dz = c_double()
|
|
69
|
+
i = self.index
|
|
70
|
+
if i < self._length:
|
|
71
|
+
lgeos.GEOSCoordSeq_getX(self._cseq, i, byref(dx))
|
|
72
|
+
lgeos.GEOSCoordSeq_getY(self._cseq, i, byref(dy))
|
|
73
|
+
if self._ndim == 3: # TODO: use hasz
|
|
74
|
+
lgeos.GEOSCoordSeq_getZ(self._cseq, i, byref(dz))
|
|
75
|
+
self.index += 1
|
|
76
|
+
return (dx.value, dy.value, dz.value)
|
|
77
|
+
else:
|
|
78
|
+
self.index += 1
|
|
79
|
+
return (dx.value, dy.value)
|
|
80
|
+
else:
|
|
81
|
+
raise StopIteration
|
|
82
|
+
|
|
83
|
+
def __len__(self):
|
|
84
|
+
cs_len = c_int(0)
|
|
85
|
+
lgeos.GEOSCoordSeq_getSize(self._cseq, byref(cs_len))
|
|
86
|
+
return cs_len.value
|
|
87
|
+
|
|
88
|
+
def __getitem__(self, i):
|
|
89
|
+
M = self.__len__()
|
|
90
|
+
if i + M < 0 or i >= M:
|
|
91
|
+
raise IndexError, "index out of range"
|
|
92
|
+
if i < 0:
|
|
93
|
+
ii = M + i
|
|
94
|
+
else:
|
|
95
|
+
ii = i
|
|
96
|
+
dx = c_double()
|
|
97
|
+
dy = c_double()
|
|
98
|
+
dz = c_double()
|
|
99
|
+
lgeos.GEOSCoordSeq_getX(self._cseq, ii, byref(dx))
|
|
100
|
+
lgeos.GEOSCoordSeq_getY(self._cseq, ii, byref(dy))
|
|
101
|
+
if self._ndim == 3: # TODO: use hasz
|
|
102
|
+
lgeos.GEOSCoordSeq_getZ(self._cseq, ii, byref(dz))
|
|
103
|
+
return (dx.value, dy.value, dz.value)
|
|
104
|
+
else:
|
|
105
|
+
return (dx.value, dy.value)
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class GeometrySequence(object):
|
|
109
|
+
|
|
110
|
+
_factory = None
|
|
111
|
+
_geom = None
|
|
112
|
+
_ndim = None
|
|
113
|
+
_index = 0
|
|
114
|
+
_length = 0
|
|
115
|
+
|
|
116
|
+
def __init__(self, geom, type):
|
|
117
|
+
self._factory = type
|
|
118
|
+
self._geom = geom._geom
|
|
119
|
+
self._ndim = geom._ndim
|
|
120
|
+
|
|
121
|
+
def __iter__(self):
|
|
122
|
+
self._index = 0
|
|
123
|
+
self._length = self.__len__()
|
|
124
|
+
return self
|
|
125
|
+
|
|
126
|
+
def next(self):
|
|
127
|
+
if self._index < self.__len__():
|
|
128
|
+
g = self._factory()
|
|
129
|
+
g._owned = True
|
|
130
|
+
g._geom = lgeos.GEOSGetGeometryN(self._geom, self._index)
|
|
131
|
+
self._index += 1
|
|
132
|
+
return g
|
|
133
|
+
else:
|
|
134
|
+
raise StopIteration
|
|
135
|
+
|
|
136
|
+
def __len__(self):
|
|
137
|
+
return lgeos.GEOSGetNumGeometries(self._geom)
|
|
138
|
+
|
|
139
|
+
def __getitem__(self, i):
|
|
140
|
+
M = self.__len__()
|
|
141
|
+
if i + M < 0 or i >= M:
|
|
142
|
+
raise IndexError, "index out of range"
|
|
143
|
+
if i < 0:
|
|
144
|
+
ii = M + i
|
|
145
|
+
else:
|
|
146
|
+
ii = i
|
|
147
|
+
g = self._factory()
|
|
148
|
+
g._owned = True
|
|
149
|
+
g._geom = lgeos.GEOSGetGeometryN(self._geom, ii)
|
|
150
|
+
return g
|
|
151
|
+
|
|
152
|
+
@property
|
|
153
|
+
def _longest(self):
|
|
154
|
+
max = 0
|
|
155
|
+
for g in iter(self):
|
|
156
|
+
l = len(g.coords)
|
|
157
|
+
if l > max:
|
|
158
|
+
max = l
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
def exceptNull(func):
|
|
162
|
+
"""Decorator which helps avoid GEOS operations on null pointers."""
|
|
163
|
+
def wrapper(*args, **kwargs):
|
|
164
|
+
# self is the first arg
|
|
165
|
+
if args[0]._geom is None:
|
|
166
|
+
raise ValueError, "Null geometry supports no operations"
|
|
167
|
+
return func(*args, **kwargs)
|
|
168
|
+
return wrapper
|
|
169
|
+
|
|
170
|
+
def exceptEitherNull(func):
|
|
171
|
+
"""Decorator which avoids GEOS operations on one or more null pointers."""
|
|
172
|
+
def wrapper(*args, **kwargs):
|
|
173
|
+
# self is the first arg
|
|
174
|
+
if args[0]._geom is None or args[1]._geom is None:
|
|
175
|
+
raise ValueError, "Null geometry supports no operations"
|
|
176
|
+
return func(*args, **kwargs)
|
|
177
|
+
return wrapper
|
|
178
|
+
|
|
179
|
+
|
|
180
|
+
class BaseGeometry(object):
|
|
181
|
+
|
|
182
|
+
"""Provides GEOS spatial predicates and topological operations.
|
|
183
|
+
"""
|
|
184
|
+
|
|
185
|
+
__geom = None # See _geom property below
|
|
186
|
+
_ctypes_data = None
|
|
187
|
+
_ndim = None
|
|
188
|
+
_crs = None
|
|
189
|
+
_owned = False
|
|
190
|
+
|
|
191
|
+
def __init__(self):
|
|
192
|
+
self.__geom = None
|
|
193
|
+
|
|
194
|
+
def __del__(self):
|
|
195
|
+
if self.__geom is not None and not self._owned:
|
|
196
|
+
lgeos.GEOSGeom_destroy(self.__geom)
|
|
197
|
+
|
|
198
|
+
def __str__(self):
|
|
199
|
+
return self.to_wkt()
|
|
200
|
+
|
|
201
|
+
def __eq__(self, other):
|
|
202
|
+
return self.equals(other)
|
|
203
|
+
|
|
204
|
+
def __ne__(self, other):
|
|
205
|
+
return not self.equals(other)
|
|
206
|
+
|
|
207
|
+
# To support pickling
|
|
208
|
+
|
|
209
|
+
def __reduce__(self):
|
|
210
|
+
return (self.__class__, (), self.to_wkb())
|
|
211
|
+
|
|
212
|
+
def __setstate__(self, state):
|
|
213
|
+
self.__geom = lgeos.GEOSGeomFromWKB_buf(
|
|
214
|
+
c_char_p(state),
|
|
215
|
+
c_size_t(len(state))
|
|
216
|
+
)
|
|
217
|
+
|
|
218
|
+
# _geom has been made a property with the GEOS geometry pointer stored
|
|
219
|
+
# in __geom so that geometries and geometry adapters can share __del__
|
|
220
|
+
|
|
221
|
+
def get_geom(self):
|
|
222
|
+
return self.__geom
|
|
223
|
+
def set_geom(self, val):
|
|
224
|
+
self.__geom = val
|
|
225
|
+
_geom = property(get_geom, set_geom)
|
|
226
|
+
|
|
227
|
+
# Array and ctypes interfaces
|
|
228
|
+
|
|
229
|
+
@property
|
|
230
|
+
def ctypes(self):
|
|
231
|
+
"""Return a ctypes representation.
|
|
232
|
+
|
|
233
|
+
To be overridden by extension classes."""
|
|
234
|
+
raise NotImplementedError
|
|
235
|
+
|
|
236
|
+
@property
|
|
237
|
+
def array_interface_base(self):
|
|
238
|
+
if sys.byteorder == 'little':
|
|
239
|
+
typestr = '<f8'
|
|
240
|
+
elif sys.byteorder == 'big':
|
|
241
|
+
typestr = '>f8'
|
|
242
|
+
else:
|
|
243
|
+
raise ValueError, "Unsupported byteorder: neither little nor big-endian"
|
|
244
|
+
return {
|
|
245
|
+
'version': 3,
|
|
246
|
+
'typestr': typestr,
|
|
247
|
+
'data': self.ctypes,
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
@property
|
|
251
|
+
def __array_interface__(self):
|
|
252
|
+
"""Provide the Numpy array protocol."""
|
|
253
|
+
raise NotImplementedError
|
|
254
|
+
|
|
255
|
+
@exceptNull
|
|
256
|
+
def get_coords(self):
|
|
257
|
+
return CoordinateSequence(self)
|
|
258
|
+
|
|
259
|
+
def set_coords(self, ob):
|
|
260
|
+
raise NotImplementedError, \
|
|
261
|
+
"set_coords must be provided by derived classes"
|
|
262
|
+
|
|
263
|
+
coords = property(get_coords, set_coords)
|
|
264
|
+
|
|
265
|
+
# Python feature protocol
|
|
266
|
+
|
|
267
|
+
@property
|
|
268
|
+
def __geo_interface__(self):
|
|
269
|
+
raise NotImplementedError
|
|
270
|
+
|
|
271
|
+
@property
|
|
272
|
+
def type(self):
|
|
273
|
+
return self.geometryType()
|
|
274
|
+
|
|
275
|
+
# Type of geometry and its representations
|
|
276
|
+
|
|
277
|
+
@exceptNull
|
|
278
|
+
def geometryType(self):
|
|
279
|
+
"""Returns a string representing the geometry type, e.g. 'Polygon'."""
|
|
280
|
+
return geometry_type_name(self._geom)
|
|
281
|
+
|
|
282
|
+
@exceptNull
|
|
283
|
+
def to_wkb(self):
|
|
284
|
+
"""Returns a WKB byte string representation of the geometry."""
|
|
285
|
+
func = lgeos.GEOSGeomToWKB_buf
|
|
286
|
+
size = c_int()
|
|
287
|
+
def errcheck(result, func, argtuple):
|
|
288
|
+
retval = string_at(result, size.value)[:]
|
|
289
|
+
free(result)
|
|
290
|
+
return retval
|
|
291
|
+
func.errcheck = errcheck
|
|
292
|
+
return func(self._geom, byref(size))
|
|
293
|
+
|
|
294
|
+
@exceptNull
|
|
295
|
+
def to_wkt(self):
|
|
296
|
+
"""Returns a WKT string representation of the geometry."""
|
|
297
|
+
func = lgeos.GEOSGeomToWKT
|
|
298
|
+
def errcheck(result, func, argtuple):
|
|
299
|
+
retval = result.value
|
|
300
|
+
free(result)
|
|
301
|
+
return retval
|
|
302
|
+
func.restype = allocated_c_char_p
|
|
303
|
+
func.errcheck = errcheck
|
|
304
|
+
return lgeos.GEOSGeomToWKT(self._geom)
|
|
305
|
+
|
|
306
|
+
geom_type = property(geometryType)
|
|
307
|
+
wkt = property(to_wkt)
|
|
308
|
+
wkb = property(to_wkb)
|
|
309
|
+
|
|
310
|
+
# Basic geometry properties
|
|
311
|
+
|
|
312
|
+
@property
|
|
313
|
+
@exceptNull
|
|
314
|
+
def area(self):
|
|
315
|
+
a = c_double()
|
|
316
|
+
retval = lgeos.GEOSArea(self._geom, byref(a))
|
|
317
|
+
return a.value
|
|
318
|
+
|
|
319
|
+
@property
|
|
320
|
+
@exceptNull
|
|
321
|
+
def length(self):
|
|
322
|
+
len = c_double()
|
|
323
|
+
retval = lgeos.GEOSLength(self._geom, byref(len))
|
|
324
|
+
return len.value
|
|
325
|
+
|
|
326
|
+
@exceptEitherNull
|
|
327
|
+
def distance(self, other):
|
|
328
|
+
d = c_double()
|
|
329
|
+
retval = lgeos.GEOSDistance(self._geom, other._geom, byref(d))
|
|
330
|
+
return d.value
|
|
331
|
+
|
|
332
|
+
# Topology operations
|
|
333
|
+
#
|
|
334
|
+
# These use descriptors to reduce the amount of boilerplate.
|
|
335
|
+
|
|
336
|
+
envelope = UnaryTopologicalOp(lgeos.GEOSEnvelope, geom_factory)
|
|
337
|
+
intersection = BinaryTopologicalOp(lgeos.GEOSIntersection, geom_factory)
|
|
338
|
+
convex_hull = UnaryTopologicalOp(lgeos.GEOSConvexHull, geom_factory)
|
|
339
|
+
difference = BinaryTopologicalOp(lgeos.GEOSDifference, geom_factory)
|
|
340
|
+
symmetric_difference = BinaryTopologicalOp(lgeos.GEOSSymDifference,
|
|
341
|
+
geom_factory)
|
|
342
|
+
boundary = UnaryTopologicalOp(lgeos.GEOSBoundary, geom_factory)
|
|
343
|
+
union = BinaryTopologicalOp(lgeos.GEOSUnion, geom_factory)
|
|
344
|
+
centroid = UnaryTopologicalOp(lgeos.GEOSGetCentroid, geom_factory)
|
|
345
|
+
|
|
346
|
+
# Buffer has a unique distance argument, so not a descriptor
|
|
347
|
+
@exceptNull
|
|
348
|
+
def buffer(self, distance, quadsegs=16):
|
|
349
|
+
return geom_factory(
|
|
350
|
+
lgeos.GEOSBuffer(self._geom, c_double(distance), c_int(quadsegs))
|
|
351
|
+
)
|
|
352
|
+
|
|
353
|
+
# Relate has a unique string return value
|
|
354
|
+
@exceptNull
|
|
355
|
+
def relate(self, other):
|
|
356
|
+
func = lgeos.GEOSRelate
|
|
357
|
+
def errcheck(result, func, argtuple):
|
|
358
|
+
retval = result.value
|
|
359
|
+
free(result)
|
|
360
|
+
return retval
|
|
361
|
+
func.restype = allocated_c_char_p
|
|
362
|
+
func.errcheck = errcheck
|
|
363
|
+
return lgeos.GEOSRelate(self._geom, other._geom)
|
|
364
|
+
|
|
365
|
+
# Binary predicates
|
|
366
|
+
#
|
|
367
|
+
# These use descriptors to reduce the amount of boilerplate.
|
|
368
|
+
|
|
369
|
+
# TODO: Relate Pattern?
|
|
370
|
+
disjoint = BinaryPredicate(lgeos.GEOSDisjoint)
|
|
371
|
+
touches = BinaryPredicate(lgeos.GEOSTouches)
|
|
372
|
+
intersects = BinaryPredicate(lgeos.GEOSIntersects)
|
|
373
|
+
crosses = BinaryPredicate(lgeos.GEOSCrosses)
|
|
374
|
+
within = BinaryPredicate(lgeos.GEOSWithin)
|
|
375
|
+
contains = BinaryPredicate(lgeos.GEOSContains)
|
|
376
|
+
overlaps = BinaryPredicate(lgeos.GEOSOverlaps)
|
|
377
|
+
equals = BinaryPredicate(lgeos.GEOSEquals)
|
|
378
|
+
|
|
379
|
+
# Unary predicates
|
|
380
|
+
#
|
|
381
|
+
# These use descriptors to reduce the amount of boilerplate.
|
|
382
|
+
|
|
383
|
+
is_empty = UnaryPredicate(lgeos.GEOSisEmpty)
|
|
384
|
+
is_valid = UnaryPredicate(lgeos.GEOSisValid)
|
|
385
|
+
is_simple = UnaryPredicate(lgeos.GEOSisSimple)
|
|
386
|
+
is_ring = UnaryPredicate(lgeos.GEOSisRing)
|
|
387
|
+
has_z = UnaryPredicate(lgeos.GEOSHasZ)
|
|
388
|
+
|
|
389
|
+
@property
|
|
390
|
+
@exceptNull
|
|
391
|
+
def bounds(self):
|
|
392
|
+
env = self.envelope
|
|
393
|
+
if env.geom_type != 'Polygon':
|
|
394
|
+
raise ValueError, env.wkt
|
|
395
|
+
cs = lgeos.GEOSGeom_getCoordSeq(env.exterior._geom)
|
|
396
|
+
cs_len = c_int(0)
|
|
397
|
+
lgeos.GEOSCoordSeq_getSize(cs, byref(cs_len))
|
|
398
|
+
|
|
399
|
+
minx = 1.e+20
|
|
400
|
+
maxx = -1e+20
|
|
401
|
+
miny = 1.e+20
|
|
402
|
+
maxy = -1e+20
|
|
403
|
+
temp = c_double()
|
|
404
|
+
for i in xrange(cs_len.value):
|
|
405
|
+
lgeos.GEOSCoordSeq_getX(cs, i, byref(temp))
|
|
406
|
+
x = temp.value
|
|
407
|
+
if x < minx: minx = x
|
|
408
|
+
if x > maxx: maxx = x
|
|
409
|
+
lgeos.GEOSCoordSeq_getY(cs, i, byref(temp))
|
|
410
|
+
y = temp.value
|
|
411
|
+
if y < miny: miny = y
|
|
412
|
+
if y > maxy: maxy = y
|
|
413
|
+
|
|
414
|
+
return (minx, miny, maxx, maxy)
|
|
415
|
+
|
|
Binary file
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Geometry collections.
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from shapely.geometry.base import BaseGeometry
|
|
6
|
+
|
|
7
|
+
class GeometryCollection(BaseGeometry):
|
|
8
|
+
|
|
9
|
+
"""A geometry collection.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
def __init__(self):
|
|
13
|
+
BaseGeometry.__init__(self)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# Test runner
|
|
17
|
+
def _test():
|
|
18
|
+
import doctest
|
|
19
|
+
doctest.testmod()
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
if __name__ == "__main__":
|
|
23
|
+
_test()
|
|
24
|
+
|
|
Binary file
|