shapely 1.2b3__tar.gz → 1.2b5__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.2b3 → Shapely-1.2b5}/CHANGES.txt +12 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/PKG-INFO +13 -7
- {Shapely-1.2b3 → Shapely-1.2b5}/README.txt +12 -6
- {Shapely-1.2b3 → Shapely-1.2b5}/Shapely.egg-info/PKG-INFO +13 -7
- {Shapely-1.2b3 → Shapely-1.2b5}/setup.py +4 -2
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/geometry/base.py +15 -6
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/geometry/linestring.py +108 -120
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/geometry/multilinestring.py +54 -60
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/geometry/multipoint.py +57 -57
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/geometry/multipolygon.py +48 -43
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/geometry/point.py +81 -76
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/geometry/polygon.py +178 -180
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/geos.py +41 -17
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/LineString.txt +10 -6
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/MultiLineString.txt +18 -1
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/MultiPoint.txt +17 -1
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/MultiPolygon.txt +17 -1
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/Point.txt +10 -10
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/Polygon.txt +3 -7
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/test_geomseq.py +2 -5
- {Shapely-1.2b3 → Shapely-1.2b5}/CREDITS.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/LICENSE.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/MANIFEST.in +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/Shapely.egg-info/SOURCES.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/Shapely.egg-info/dependency_links.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/Shapely.egg-info/top_level.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/examples/dissolve.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/examples/intersect.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/setup.cfg +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/__init__.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/coords.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/ctypes_declarations.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/geometry/__init__.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/geometry/collection.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/geometry/geo.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/geometry/proxy.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/geoms.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/impl.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/iterops.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/linref.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/ops.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/predicates.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/prepared.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/Array.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/GeoInterface.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/IterOps.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/Operations.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/Persist.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/Predicates.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/__init__.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/attribute-chains.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/binascii_hex.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/dimensions.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/invalid_intersection.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/linear-referencing.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/linemerge.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/polygonize.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/test_doctests.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/test_equality.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/test_prepared.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/test_xy.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/threading_test.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/tests/wkt_locale.txt +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/topology.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/wkb.py +0 -0
- {Shapely-1.2b3 → Shapely-1.2b5}/shapely/wkt.py +0 -0
|
@@ -1,5 +1,17 @@
|
|
|
1
1
|
All tickets are children of http://trac.gispython.org/lab/ticket.
|
|
2
2
|
|
|
3
|
+
1.2b5 (2010-04-09)
|
|
4
|
+
------------------
|
|
5
|
+
- Objects can be constructed from others of the same type, thereby making
|
|
6
|
+
copies. Collections can be constructed from sequences of objects, also making
|
|
7
|
+
copies.
|
|
8
|
+
- Collections are now iterators over their component objects.
|
|
9
|
+
- New code for manual figures, using the descartes package.
|
|
10
|
+
|
|
11
|
+
1.2b4 (2010-03-19)
|
|
12
|
+
------------------
|
|
13
|
+
- Adds support for the "sunos5" platform.
|
|
14
|
+
|
|
3
15
|
1.2b3 (2010-02-28)
|
|
4
16
|
------------------
|
|
5
17
|
- Only provide simplification implementations for GEOS C API >= 1.5.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 1.0
|
|
2
2
|
Name: Shapely
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2b5
|
|
4
4
|
Summary: Planar geometries, predicates, and operations
|
|
5
5
|
Home-page: http://trac.gispython.org/lab/wiki/Shapely
|
|
6
6
|
Author: Sean Gillies
|
|
@@ -124,14 +124,20 @@ Description:
|
|
|
124
124
|
|
|
125
125
|
Shapely is written by:
|
|
126
126
|
|
|
127
|
-
* Sean Gillies
|
|
127
|
+
* Sean Gillies
|
|
128
128
|
* Aron Bierbaum
|
|
129
|
-
*
|
|
130
|
-
* Kai Lautaportti (Hexagon IT)
|
|
131
|
-
* Fr |eaigue| d |eaigue| ric Junod (Camptocamp SA)
|
|
132
|
-
* Eric Lemoine (Camptocamp SA)
|
|
129
|
+
* Kai Lautaportti
|
|
133
130
|
|
|
134
|
-
|
|
131
|
+
Patches contributed by:
|
|
132
|
+
|
|
133
|
+
* Howard Butler
|
|
134
|
+
* Fr |eaigue| d |eaigue| ric Junod
|
|
135
|
+
* Eric Lemoine
|
|
136
|
+
* Jonathan Tartley
|
|
137
|
+
* Kristian Thy
|
|
138
|
+
* Oliver Tonnhofer
|
|
139
|
+
|
|
140
|
+
Additional help from:
|
|
135
141
|
|
|
136
142
|
* Justin Bronn (GeoDjango) for ctypes inspiration
|
|
137
143
|
* Martin Davis (JTS)
|
|
@@ -116,14 +116,20 @@ Credits
|
|
|
116
116
|
|
|
117
117
|
Shapely is written by:
|
|
118
118
|
|
|
119
|
-
* Sean Gillies
|
|
119
|
+
* Sean Gillies
|
|
120
120
|
* Aron Bierbaum
|
|
121
|
-
*
|
|
122
|
-
* Kai Lautaportti (Hexagon IT)
|
|
123
|
-
* Fr |eaigue| d |eaigue| ric Junod (Camptocamp SA)
|
|
124
|
-
* Eric Lemoine (Camptocamp SA)
|
|
121
|
+
* Kai Lautaportti
|
|
125
122
|
|
|
126
|
-
|
|
123
|
+
Patches contributed by:
|
|
124
|
+
|
|
125
|
+
* Howard Butler
|
|
126
|
+
* Fr |eaigue| d |eaigue| ric Junod
|
|
127
|
+
* Eric Lemoine
|
|
128
|
+
* Jonathan Tartley
|
|
129
|
+
* Kristian Thy
|
|
130
|
+
* Oliver Tonnhofer
|
|
131
|
+
|
|
132
|
+
Additional help from:
|
|
127
133
|
|
|
128
134
|
* Justin Bronn (GeoDjango) for ctypes inspiration
|
|
129
135
|
* Martin Davis (JTS)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 1.0
|
|
2
2
|
Name: Shapely
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.2b5
|
|
4
4
|
Summary: Planar geometries, predicates, and operations
|
|
5
5
|
Home-page: http://trac.gispython.org/lab/wiki/Shapely
|
|
6
6
|
Author: Sean Gillies
|
|
@@ -124,14 +124,20 @@ Description:
|
|
|
124
124
|
|
|
125
125
|
Shapely is written by:
|
|
126
126
|
|
|
127
|
-
* Sean Gillies
|
|
127
|
+
* Sean Gillies
|
|
128
128
|
* Aron Bierbaum
|
|
129
|
-
*
|
|
130
|
-
* Kai Lautaportti (Hexagon IT)
|
|
131
|
-
* Fr |eaigue| d |eaigue| ric Junod (Camptocamp SA)
|
|
132
|
-
* Eric Lemoine (Camptocamp SA)
|
|
129
|
+
* Kai Lautaportti
|
|
133
130
|
|
|
134
|
-
|
|
131
|
+
Patches contributed by:
|
|
132
|
+
|
|
133
|
+
* Howard Butler
|
|
134
|
+
* Fr |eaigue| d |eaigue| ric Junod
|
|
135
|
+
* Eric Lemoine
|
|
136
|
+
* Jonathan Tartley
|
|
137
|
+
* Kristian Thy
|
|
138
|
+
* Oliver Tonnhofer
|
|
139
|
+
|
|
140
|
+
Additional help from:
|
|
135
141
|
|
|
136
142
|
* Justin Bronn (GeoDjango) for ctypes inspiration
|
|
137
143
|
* Martin Davis (JTS)
|
|
@@ -4,7 +4,9 @@ try:
|
|
|
4
4
|
from distribute_setup import use_setuptools
|
|
5
5
|
use_setuptools()
|
|
6
6
|
except:
|
|
7
|
-
warnings.warn(
|
|
7
|
+
warnings.warn(
|
|
8
|
+
"Failed to import distribute_setup, continuing without distribute.",
|
|
9
|
+
Warning)
|
|
8
10
|
|
|
9
11
|
from setuptools import setup, find_packages
|
|
10
12
|
import sys
|
|
@@ -14,7 +16,7 @@ readme_text = file('README.txt', 'rb').read()
|
|
|
14
16
|
setup_args = dict(
|
|
15
17
|
metadata_version = '1.2',
|
|
16
18
|
name = 'Shapely',
|
|
17
|
-
version = '1.
|
|
19
|
+
version = '1.2b5',
|
|
18
20
|
requires_python = '>=2.5,<3',
|
|
19
21
|
requires_external = 'libgeos_c (>=3.1)',
|
|
20
22
|
description = 'Planar geometries, predicates, and operations',
|
|
@@ -48,8 +48,8 @@ def exceptNull(func):
|
|
|
48
48
|
"""Decorator which helps avoid GEOS operations on null pointers."""
|
|
49
49
|
@wraps(func)
|
|
50
50
|
def wrapper(*args, **kwargs):
|
|
51
|
-
if not args[0]._geom:
|
|
52
|
-
raise ValueError("Null geometry supports no operations")
|
|
51
|
+
if not args[0]._geom or args[0].is_empty:
|
|
52
|
+
raise ValueError("Null/empty geometry supports no operations")
|
|
53
53
|
return func(*args, **kwargs)
|
|
54
54
|
return wrapper
|
|
55
55
|
|
|
@@ -84,12 +84,12 @@ class BaseGeometry(object):
|
|
|
84
84
|
_ndim = None
|
|
85
85
|
_crs = None
|
|
86
86
|
_owned = False
|
|
87
|
-
|
|
87
|
+
|
|
88
88
|
# Backend config
|
|
89
89
|
impl = DefaultImplementation
|
|
90
90
|
|
|
91
91
|
def __init__(self):
|
|
92
|
-
self.__geom__ =
|
|
92
|
+
self.__geom__ = wkb.deserialize('010700000000000000'.decode('hex'))
|
|
93
93
|
|
|
94
94
|
def __del__(self):
|
|
95
95
|
if self.__geom__ is not None and not self._owned:
|
|
@@ -227,8 +227,11 @@ class BaseGeometry(object):
|
|
|
227
227
|
@property
|
|
228
228
|
def bounds(self):
|
|
229
229
|
"""Returns minimum bounding region (minx, miny, maxx, maxy)"""
|
|
230
|
-
|
|
231
|
-
|
|
230
|
+
if self.is_empty:
|
|
231
|
+
return ()
|
|
232
|
+
else:
|
|
233
|
+
return self.impl['bounds'](self)
|
|
234
|
+
|
|
232
235
|
@property
|
|
233
236
|
def centroid(self):
|
|
234
237
|
"""Returns the geometric center of the polygon"""
|
|
@@ -451,6 +454,12 @@ class BaseMultipartGeometry(BaseGeometry):
|
|
|
451
454
|
def geoms(self):
|
|
452
455
|
return GeometrySequence(self, self.shape_factory)
|
|
453
456
|
|
|
457
|
+
def __iter__(self):
|
|
458
|
+
if not self.is_empty:
|
|
459
|
+
return iter(self.geoms)
|
|
460
|
+
else:
|
|
461
|
+
return iter([])
|
|
462
|
+
|
|
454
463
|
|
|
455
464
|
class GeometrySequence(object):
|
|
456
465
|
"""
|
|
@@ -11,107 +11,6 @@ from shapely.geometry.proxy import CachingGeometryProxy
|
|
|
11
11
|
__all__ = ['LineString', 'asLineString']
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def geos_linestring_from_py(ob, update_geom=None, update_ndim=0):
|
|
15
|
-
try:
|
|
16
|
-
# From array protocol
|
|
17
|
-
array = ob.__array_interface__
|
|
18
|
-
assert len(array['shape']) == 2
|
|
19
|
-
m = array['shape'][0]
|
|
20
|
-
if m < 2:
|
|
21
|
-
raise ValueError(
|
|
22
|
-
"LineStrings must have at least 2 coordinate tuples")
|
|
23
|
-
try:
|
|
24
|
-
n = array['shape'][1]
|
|
25
|
-
except IndexError:
|
|
26
|
-
raise ValueError(
|
|
27
|
-
"Input %s is the wrong shape for a LineString" % str(ob))
|
|
28
|
-
assert n == 2 or n == 3
|
|
29
|
-
|
|
30
|
-
# Make pointer to the coordinate array
|
|
31
|
-
try:
|
|
32
|
-
cp = cast(array['data'][0], POINTER(c_double))
|
|
33
|
-
except ArgumentError:
|
|
34
|
-
cp = array['data']
|
|
35
|
-
|
|
36
|
-
# Create a coordinate sequence
|
|
37
|
-
if update_geom is not None:
|
|
38
|
-
cs = lgeos.GEOSGeom_getCoordSeq(update_geom)
|
|
39
|
-
if n != update_ndim:
|
|
40
|
-
raise ValueError(
|
|
41
|
-
"Wrong coordinate dimensions; this geometry has dimensions: %d" \
|
|
42
|
-
% update_ndim)
|
|
43
|
-
else:
|
|
44
|
-
cs = lgeos.GEOSCoordSeq_create(m, n)
|
|
45
|
-
|
|
46
|
-
# add to coordinate sequence
|
|
47
|
-
for i in xrange(m):
|
|
48
|
-
dx = c_double(cp[n*i])
|
|
49
|
-
dy = c_double(cp[n*i+1])
|
|
50
|
-
dz = None
|
|
51
|
-
if n == 3:
|
|
52
|
-
try:
|
|
53
|
-
dz = c_double(cp[n*i+2])
|
|
54
|
-
except IndexError:
|
|
55
|
-
raise ValueError("Inconsistent coordinate dimensionality")
|
|
56
|
-
|
|
57
|
-
# Because of a bug in the GEOS C API,
|
|
58
|
-
# always set X before Y
|
|
59
|
-
lgeos.GEOSCoordSeq_setX(cs, i, dx)
|
|
60
|
-
lgeos.GEOSCoordSeq_setY(cs, i, dy)
|
|
61
|
-
if n == 3:
|
|
62
|
-
lgeos.GEOSCoordSeq_setZ(cs, i, dz)
|
|
63
|
-
|
|
64
|
-
except AttributeError:
|
|
65
|
-
# Fall back on list
|
|
66
|
-
m = len(ob)
|
|
67
|
-
if m < 2:
|
|
68
|
-
raise ValueError(
|
|
69
|
-
"LineStrings must have at least 2 coordinate tuples")
|
|
70
|
-
try:
|
|
71
|
-
n = len(ob[0])
|
|
72
|
-
except TypeError:
|
|
73
|
-
raise ValueError(
|
|
74
|
-
"Input %s is the wrong shape for a LineString" % str(ob))
|
|
75
|
-
assert n == 2 or n == 3
|
|
76
|
-
|
|
77
|
-
# Create a coordinate sequence
|
|
78
|
-
if update_geom is not None:
|
|
79
|
-
cs = lgeos.GEOSGeom_getCoordSeq(update_geom)
|
|
80
|
-
if n != update_ndim:
|
|
81
|
-
raise ValueError(
|
|
82
|
-
"Wrong coordinate dimensions; this geometry has dimensions: %d" \
|
|
83
|
-
% update_ndim)
|
|
84
|
-
else:
|
|
85
|
-
cs = lgeos.GEOSCoordSeq_create(m, n)
|
|
86
|
-
|
|
87
|
-
# add to coordinate sequence
|
|
88
|
-
for i in xrange(m):
|
|
89
|
-
coords = ob[i]
|
|
90
|
-
dx = c_double(coords[0])
|
|
91
|
-
dy = c_double(coords[1])
|
|
92
|
-
dz = None
|
|
93
|
-
if n == 3:
|
|
94
|
-
try:
|
|
95
|
-
dz = c_double(coords[2])
|
|
96
|
-
except IndexError:
|
|
97
|
-
raise ValueError("Inconsistent coordinate dimensionality")
|
|
98
|
-
|
|
99
|
-
# Because of a bug in the GEOS C API,
|
|
100
|
-
# always set X before Y
|
|
101
|
-
lgeos.GEOSCoordSeq_setX(cs, i, dx)
|
|
102
|
-
lgeos.GEOSCoordSeq_setY(cs, i, dy)
|
|
103
|
-
if n == 3:
|
|
104
|
-
lgeos.GEOSCoordSeq_setZ(cs, i, dz)
|
|
105
|
-
|
|
106
|
-
if update_geom is not None:
|
|
107
|
-
return None
|
|
108
|
-
else:
|
|
109
|
-
return lgeos.GEOSGeom_createLineString(cs), n
|
|
110
|
-
|
|
111
|
-
def update_linestring_from_py(geom, ob):
|
|
112
|
-
geos_linestring_from_py(ob, geom._geom, geom._ndim)
|
|
113
|
-
|
|
114
|
-
|
|
115
14
|
class LineString(BaseGeometry):
|
|
116
15
|
"""
|
|
117
16
|
A one-dimensional figure comprising one or more line segments
|
|
@@ -121,29 +20,21 @@ class LineString(BaseGeometry):
|
|
|
121
20
|
"""
|
|
122
21
|
|
|
123
22
|
def __init__(self, coordinates=None):
|
|
124
|
-
"""
|
|
125
|
-
|
|
23
|
+
"""
|
|
126
24
|
Parameters
|
|
127
25
|
----------
|
|
128
|
-
|
|
129
26
|
coordinates : sequence
|
|
130
|
-
A sequence of (x, y [,z]) numeric coordinate pairs or triples
|
|
27
|
+
A sequence of (x, y [,z]) numeric coordinate pairs or triples or
|
|
28
|
+
an object that provides the numpy array interface, including another
|
|
29
|
+
instance of LineString.
|
|
131
30
|
|
|
132
31
|
Example
|
|
133
32
|
-------
|
|
134
|
-
|
|
135
33
|
Create a line with two segments
|
|
136
34
|
|
|
137
35
|
>>> a = LineString([[0, 0], [1, 0], [1, 1]])
|
|
138
36
|
>>> a.length
|
|
139
37
|
2.0
|
|
140
|
-
|
|
141
|
-
Copy it by exploiting API symmetry
|
|
142
|
-
|
|
143
|
-
>>> b = LineString(a.coords)
|
|
144
|
-
>>> b.equals(a)
|
|
145
|
-
True
|
|
146
|
-
|
|
147
38
|
"""
|
|
148
39
|
BaseGeometry.__init__(self)
|
|
149
40
|
self._init_geom(coordinates)
|
|
@@ -177,6 +68,9 @@ class LineString(BaseGeometry):
|
|
|
177
68
|
# Coordinate access
|
|
178
69
|
|
|
179
70
|
def _set_coords(self, coordinates):
|
|
71
|
+
if self.is_empty:
|
|
72
|
+
lgeos.GEOSGeom_destroy(self.__geom__)
|
|
73
|
+
self.__geom__ = None
|
|
180
74
|
if self._geom is None:
|
|
181
75
|
self._init_geom(coordinates)
|
|
182
76
|
update_linestring_from_py(self, coordinates)
|
|
@@ -194,17 +88,12 @@ class LineString(BaseGeometry):
|
|
|
194
88
|
[0.0, 1.0]
|
|
195
89
|
>>> list(y)
|
|
196
90
|
[0.0, 1.0]
|
|
197
|
-
|
|
198
91
|
"""
|
|
199
92
|
return self.coords.xy
|
|
200
93
|
|
|
201
94
|
|
|
202
95
|
class LineStringAdapter(CachingGeometryProxy, LineString):
|
|
203
96
|
|
|
204
|
-
"""Adapts Python coordinate pairs or a numpy array to the line string
|
|
205
|
-
interface
|
|
206
|
-
"""
|
|
207
|
-
|
|
208
97
|
context = None
|
|
209
98
|
_owned = False
|
|
210
99
|
|
|
@@ -242,15 +131,114 @@ class LineStringAdapter(CachingGeometryProxy, LineString):
|
|
|
242
131
|
|
|
243
132
|
|
|
244
133
|
def asLineString(context):
|
|
245
|
-
"""
|
|
134
|
+
"""Adapt an object the LineString interface"""
|
|
246
135
|
return LineStringAdapter(context)
|
|
247
136
|
|
|
137
|
+
|
|
138
|
+
def geos_linestring_from_py(ob, update_geom=None, update_ndim=0):
|
|
139
|
+
try:
|
|
140
|
+
# From array protocol
|
|
141
|
+
array = ob.__array_interface__
|
|
142
|
+
assert len(array['shape']) == 2
|
|
143
|
+
m = array['shape'][0]
|
|
144
|
+
if m < 2:
|
|
145
|
+
raise ValueError(
|
|
146
|
+
"LineStrings must have at least 2 coordinate tuples")
|
|
147
|
+
try:
|
|
148
|
+
n = array['shape'][1]
|
|
149
|
+
except IndexError:
|
|
150
|
+
raise ValueError(
|
|
151
|
+
"Input %s is the wrong shape for a LineString" % str(ob))
|
|
152
|
+
assert n == 2 or n == 3
|
|
153
|
+
|
|
154
|
+
# Make pointer to the coordinate array
|
|
155
|
+
try:
|
|
156
|
+
cp = cast(array['data'][0], POINTER(c_double))
|
|
157
|
+
except ArgumentError:
|
|
158
|
+
cp = array['data']
|
|
159
|
+
|
|
160
|
+
# Create a coordinate sequence
|
|
161
|
+
if update_geom is not None:
|
|
162
|
+
cs = lgeos.GEOSGeom_getCoordSeq(update_geom)
|
|
163
|
+
if n != update_ndim:
|
|
164
|
+
raise ValueError(
|
|
165
|
+
"Wrong coordinate dimensions; this geometry has dimensions: %d" \
|
|
166
|
+
% update_ndim)
|
|
167
|
+
else:
|
|
168
|
+
cs = lgeos.GEOSCoordSeq_create(m, n)
|
|
169
|
+
|
|
170
|
+
# add to coordinate sequence
|
|
171
|
+
for i in xrange(m):
|
|
172
|
+
dx = c_double(cp[n*i])
|
|
173
|
+
dy = c_double(cp[n*i+1])
|
|
174
|
+
dz = None
|
|
175
|
+
if n == 3:
|
|
176
|
+
try:
|
|
177
|
+
dz = c_double(cp[n*i+2])
|
|
178
|
+
except IndexError:
|
|
179
|
+
raise ValueError("Inconsistent coordinate dimensionality")
|
|
180
|
+
|
|
181
|
+
# Because of a bug in the GEOS C API,
|
|
182
|
+
# always set X before Y
|
|
183
|
+
lgeos.GEOSCoordSeq_setX(cs, i, dx)
|
|
184
|
+
lgeos.GEOSCoordSeq_setY(cs, i, dy)
|
|
185
|
+
if n == 3:
|
|
186
|
+
lgeos.GEOSCoordSeq_setZ(cs, i, dz)
|
|
187
|
+
|
|
188
|
+
except AttributeError:
|
|
189
|
+
# Fall back on list
|
|
190
|
+
m = len(ob)
|
|
191
|
+
if m < 2:
|
|
192
|
+
raise ValueError(
|
|
193
|
+
"LineStrings must have at least 2 coordinate tuples")
|
|
194
|
+
try:
|
|
195
|
+
n = len(ob[0])
|
|
196
|
+
except TypeError:
|
|
197
|
+
raise ValueError(
|
|
198
|
+
"Input %s is the wrong shape for a LineString" % str(ob))
|
|
199
|
+
assert n == 2 or n == 3
|
|
200
|
+
|
|
201
|
+
# Create a coordinate sequence
|
|
202
|
+
if update_geom is not None:
|
|
203
|
+
cs = lgeos.GEOSGeom_getCoordSeq(update_geom)
|
|
204
|
+
if n != update_ndim:
|
|
205
|
+
raise ValueError(
|
|
206
|
+
"Wrong coordinate dimensions; this geometry has dimensions: %d" \
|
|
207
|
+
% update_ndim)
|
|
208
|
+
else:
|
|
209
|
+
cs = lgeos.GEOSCoordSeq_create(m, n)
|
|
210
|
+
|
|
211
|
+
# add to coordinate sequence
|
|
212
|
+
for i in xrange(m):
|
|
213
|
+
coords = ob[i]
|
|
214
|
+
dx = c_double(coords[0])
|
|
215
|
+
dy = c_double(coords[1])
|
|
216
|
+
dz = None
|
|
217
|
+
if n == 3:
|
|
218
|
+
try:
|
|
219
|
+
dz = c_double(coords[2])
|
|
220
|
+
except IndexError:
|
|
221
|
+
raise ValueError("Inconsistent coordinate dimensionality")
|
|
222
|
+
|
|
223
|
+
# Because of a bug in the GEOS C API,
|
|
224
|
+
# always set X before Y
|
|
225
|
+
lgeos.GEOSCoordSeq_setX(cs, i, dx)
|
|
226
|
+
lgeos.GEOSCoordSeq_setY(cs, i, dy)
|
|
227
|
+
if n == 3:
|
|
228
|
+
lgeos.GEOSCoordSeq_setZ(cs, i, dz)
|
|
248
229
|
|
|
230
|
+
if update_geom is not None:
|
|
231
|
+
return None
|
|
232
|
+
else:
|
|
233
|
+
return lgeos.GEOSGeom_createLineString(cs), n
|
|
234
|
+
|
|
235
|
+
def update_linestring_from_py(geom, ob):
|
|
236
|
+
geos_linestring_from_py(ob, geom._geom, geom._ndim)
|
|
237
|
+
|
|
249
238
|
# Test runner
|
|
250
239
|
def _test():
|
|
251
240
|
import doctest
|
|
252
241
|
doctest.testmod()
|
|
253
242
|
|
|
254
|
-
|
|
255
243
|
if __name__ == "__main__":
|
|
256
244
|
_test()
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"""
|
|
1
|
+
"""Collections of linestrings and related utilities
|
|
2
2
|
"""
|
|
3
3
|
|
|
4
4
|
from ctypes import c_double, c_void_p, cast, POINTER
|
|
@@ -11,47 +11,9 @@ from shapely.geometry.proxy import CachingGeometryProxy
|
|
|
11
11
|
__all__ = ['MultiLineString', 'asMultiLineString']
|
|
12
12
|
|
|
13
13
|
|
|
14
|
-
def geos_multilinestring_from_py(ob):
|
|
15
|
-
"""ob must be either a sequence or array of sequences or arrays."""
|
|
16
|
-
try:
|
|
17
|
-
# From array protocol
|
|
18
|
-
array = ob.__array_interface__
|
|
19
|
-
assert len(array['shape']) == 1
|
|
20
|
-
L = array['shape'][0]
|
|
21
|
-
assert L >= 1
|
|
22
|
-
|
|
23
|
-
# Make pointer to the coordinate array
|
|
24
|
-
cp = cast(array['data'][0], POINTER(c_double))
|
|
25
|
-
|
|
26
|
-
# Array of pointers to sub-geometries
|
|
27
|
-
subs = (c_void_p * L)()
|
|
28
|
-
|
|
29
|
-
for l in xrange(L):
|
|
30
|
-
geom, ndims = geos_linestring_from_py(array['data'][l])
|
|
31
|
-
subs[i] = cast(geom, c_void_p)
|
|
32
|
-
N = lgeos.GEOSGeom_getDimensions(subs[0])
|
|
33
|
-
|
|
34
|
-
except AttributeError:
|
|
35
|
-
# Fall back on list
|
|
36
|
-
L = len(ob)
|
|
37
|
-
N = len(ob[0][0])
|
|
38
|
-
assert L >= 1
|
|
39
|
-
assert N == 2 or N == 3
|
|
40
|
-
|
|
41
|
-
# Array of pointers to point geometries
|
|
42
|
-
subs = (c_void_p * L)()
|
|
43
|
-
|
|
44
|
-
# add to coordinate sequence
|
|
45
|
-
for l in xrange(L):
|
|
46
|
-
geom, ndims = geos_linestring_from_py(ob[l])
|
|
47
|
-
subs[l] = cast(geom, c_void_p)
|
|
48
|
-
|
|
49
|
-
return (lgeos.GEOSGeom_createCollection(5, subs, L), N)
|
|
50
|
-
|
|
51
|
-
|
|
52
14
|
class MultiLineString(BaseMultipartGeometry):
|
|
53
|
-
|
|
54
|
-
|
|
15
|
+
"""
|
|
16
|
+
A collection of one or more line strings
|
|
55
17
|
|
|
56
18
|
A MultiLineString has non-zero length and zero area.
|
|
57
19
|
|
|
@@ -61,31 +23,28 @@ class MultiLineString(BaseMultipartGeometry):
|
|
|
61
23
|
A sequence of LineStrings
|
|
62
24
|
"""
|
|
63
25
|
|
|
64
|
-
def __init__(self,
|
|
65
|
-
"""
|
|
66
|
-
|
|
26
|
+
def __init__(self, lines=None):
|
|
27
|
+
"""
|
|
67
28
|
Parameters
|
|
68
29
|
----------
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
30
|
+
lines : sequence
|
|
31
|
+
A sequence of line-like coordinate sequences or objects that
|
|
32
|
+
provide the numpy array interface, including instances of
|
|
33
|
+
LineString.
|
|
73
34
|
|
|
74
35
|
Example
|
|
75
36
|
-------
|
|
37
|
+
Construct a collection containing one line string.
|
|
76
38
|
|
|
77
|
-
|
|
78
|
-
>>> geom = MultiLineString( [ array([[0.0, 0.0], [1.0, 2.0]]) ] )
|
|
79
|
-
|
|
80
|
-
Each result in a collection containing one line string.
|
|
39
|
+
>>> lines = MultiLineString( [[[0.0, 0.0], [1.0, 2.0]]] )
|
|
81
40
|
"""
|
|
82
41
|
super(MultiLineString, self).__init__()
|
|
83
42
|
|
|
84
|
-
if
|
|
43
|
+
if lines is None:
|
|
85
44
|
# allow creation of null lines, to support unpickling
|
|
86
45
|
pass
|
|
87
46
|
else:
|
|
88
|
-
self._geom, self._ndim = geos_multilinestring_from_py(
|
|
47
|
+
self._geom, self._ndim = geos_multilinestring_from_py(lines)
|
|
89
48
|
|
|
90
49
|
def shape_factory(self, *args):
|
|
91
50
|
return LineString(*args)
|
|
@@ -99,10 +58,6 @@ class MultiLineString(BaseMultipartGeometry):
|
|
|
99
58
|
|
|
100
59
|
|
|
101
60
|
class MultiLineStringAdapter(CachingGeometryProxy, MultiLineString):
|
|
102
|
-
|
|
103
|
-
"""Adapts sequences of sequences or numpy arrays to the multilinestring
|
|
104
|
-
interface.
|
|
105
|
-
"""
|
|
106
61
|
|
|
107
62
|
context = None
|
|
108
63
|
_owned = False
|
|
@@ -125,15 +80,54 @@ class MultiLineStringAdapter(CachingGeometryProxy, MultiLineString):
|
|
|
125
80
|
|
|
126
81
|
|
|
127
82
|
def asMultiLineString(context):
|
|
128
|
-
"""
|
|
83
|
+
"""Adapts a sequence of objects to the MultiLineString interface"""
|
|
129
84
|
return MultiLineStringAdapter(context)
|
|
130
85
|
|
|
131
86
|
|
|
87
|
+
def geos_multilinestring_from_py(ob):
|
|
88
|
+
# ob must be either a sequence or array of sequences or arrays
|
|
89
|
+
try:
|
|
90
|
+
# From array protocol
|
|
91
|
+
array = ob.__array_interface__
|
|
92
|
+
assert len(array['shape']) == 1
|
|
93
|
+
L = array['shape'][0]
|
|
94
|
+
assert L >= 1
|
|
95
|
+
|
|
96
|
+
# Make pointer to the coordinate array
|
|
97
|
+
cp = cast(array['data'][0], POINTER(c_double))
|
|
98
|
+
|
|
99
|
+
# Array of pointers to sub-geometries
|
|
100
|
+
subs = (c_void_p * L)()
|
|
101
|
+
|
|
102
|
+
for l in xrange(L):
|
|
103
|
+
geom, ndims = geos_linestring_from_py(array['data'][l])
|
|
104
|
+
subs[i] = cast(geom, c_void_p)
|
|
105
|
+
N = lgeos.GEOSGeom_getDimensions(subs[0])
|
|
106
|
+
except (NotImplementedError, AttributeError):
|
|
107
|
+
obs = getattr(ob, 'geoms', ob)
|
|
108
|
+
L = len(obs)
|
|
109
|
+
exemplar = obs[0]
|
|
110
|
+
try:
|
|
111
|
+
N = len(exemplar[0])
|
|
112
|
+
except TypeError:
|
|
113
|
+
N = exemplar._ndim
|
|
114
|
+
assert L >= 1
|
|
115
|
+
assert N == 2 or N == 3
|
|
116
|
+
|
|
117
|
+
# Array of pointers to point geometries
|
|
118
|
+
subs = (c_void_p * L)()
|
|
119
|
+
|
|
120
|
+
# add to coordinate sequence
|
|
121
|
+
for l in xrange(L):
|
|
122
|
+
geom, ndims = geos_linestring_from_py(obs[l])
|
|
123
|
+
subs[l] = cast(geom, c_void_p)
|
|
124
|
+
|
|
125
|
+
return (lgeos.GEOSGeom_createCollection(5, subs, L), N)
|
|
126
|
+
|
|
132
127
|
# Test runner
|
|
133
128
|
def _test():
|
|
134
129
|
import doctest
|
|
135
130
|
doctest.testmod()
|
|
136
131
|
|
|
137
|
-
|
|
138
132
|
if __name__ == "__main__":
|
|
139
133
|
_test()
|