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.
@@ -0,0 +1,35 @@
1
+
2
+ from point import PointAdapter
3
+ from linestring import LineStringAdapter
4
+ from polygon import PolygonAdapter
5
+ from multipoint import MultiPointAdapter
6
+ from multilinestring import MultiLineStringAdapter
7
+ from multipolygon import MultiPolygonAdapter
8
+
9
+
10
+ def asShape(context):
11
+ """Adapts the context to a geometry interface. The coordinates remain
12
+ stored in the context.
13
+ """
14
+ if hasattr(context, "__geo_interface__"):
15
+ ob = context.__geo_interface__
16
+ else:
17
+ ob = context
18
+
19
+ geom_type = ob.get("type").lower()
20
+
21
+ if geom_type == "point":
22
+ return PointAdapter(ob["coordinates"])
23
+ elif geom_type == "linestring":
24
+ return LineStringAdapter(ob["coordinates"])
25
+ elif geom_type == "polygon":
26
+ return PolygonAdapter(ob["coordinates"][0], ob["coordinates"][1:])
27
+ elif geom_type == "multipoint":
28
+ return MultiPointAdapter(ob["coordinates"])
29
+ elif geom_type == "multilinestring":
30
+ return MultiLineStringAdapter(ob["coordinates"])
31
+ elif geom_type == "multipolygon":
32
+ return MultiPolygonAdapter(ob["coordinates"])
33
+ else:
34
+ raise ValueError, "Unknown geometry type: %s" % geom_type
35
+
Binary file
@@ -0,0 +1,234 @@
1
+ """
2
+ Line strings.
3
+ """
4
+
5
+ from ctypes import byref, c_double, c_int, cast, POINTER, pointer
6
+ from ctypes import ArgumentError
7
+
8
+ from shapely.geos import lgeos
9
+ from shapely.geometry.base import BaseGeometry, exceptNull
10
+
11
+
12
+ def geos_linestring_from_py(ob, update_geom=None, update_ndim=0):
13
+ try:
14
+ # From array protocol
15
+ array = ob.__array_interface__
16
+ assert len(array['shape']) == 2
17
+ m = array['shape'][0]
18
+ n = array['shape'][1]
19
+ assert m >= 2
20
+ assert n == 2 or n == 3
21
+
22
+ # Make pointer to the coordinate array
23
+ try:
24
+ cp = cast(array['data'][0], POINTER(c_double))
25
+ except ArgumentError:
26
+ cp = array['data']
27
+
28
+ # Create a coordinate sequence
29
+ if update_geom is not None:
30
+ cs = lgeos.GEOSGeom_getCoordSeq(update_geom)
31
+ if n != update_ndim:
32
+ raise ValueError, \
33
+ "Wrong coordinate dimensions; this geometry has dimensions: %d" \
34
+ % update_ndim
35
+ else:
36
+ cs = lgeos.GEOSCoordSeq_create(m, n)
37
+
38
+ # add to coordinate sequence
39
+ for i in xrange(m):
40
+ dx = c_double(cp[n*i])
41
+ dy = c_double(cp[n*i+1])
42
+ dz = None
43
+ if n == 3:
44
+ dz = c_double(cp[n*i+2])
45
+
46
+ # Because of a bug in the GEOS C API,
47
+ # always set X before Y
48
+ lgeos.GEOSCoordSeq_setX(cs, i, dx)
49
+ lgeos.GEOSCoordSeq_setY(cs, i, dy)
50
+ if n == 3:
51
+ lgeos.GEOSCoordSeq_setZ(cs, i, dz)
52
+
53
+ except AttributeError:
54
+ # Fall back on list
55
+ m = len(ob)
56
+ n = len(ob[0])
57
+ assert m >= 2
58
+ assert n == 2 or n == 3
59
+
60
+ # Create a coordinate sequence
61
+ if update_geom is not None:
62
+ cs = lgeos.GEOSGeom_getCoordSeq(update_geom)
63
+ if n != update_ndim:
64
+ raise ValueError, \
65
+ "Wrong coordinate dimensions; this geometry has dimensions: %d" \
66
+ % update_ndim
67
+ else:
68
+ cs = lgeos.GEOSCoordSeq_create(m, n)
69
+
70
+ # add to coordinate sequence
71
+ for i in xrange(m):
72
+ coords = ob[i]
73
+ dx = c_double(coords[0])
74
+ dy = c_double(coords[1])
75
+ dz = None
76
+ if n == 3:
77
+ dz = c_double(coords[2])
78
+
79
+ # Because of a bug in the GEOS C API,
80
+ # always set X before Y
81
+ lgeos.GEOSCoordSeq_setX(cs, i, dx)
82
+ lgeos.GEOSCoordSeq_setY(cs, i, dy)
83
+ if n == 3:
84
+ lgeos.GEOSCoordSeq_setZ(cs, i, dz)
85
+
86
+ if update_geom is not None:
87
+ return None
88
+ else:
89
+ return lgeos.GEOSGeom_createLineString(cs), n
90
+
91
+ def update_linestring_from_py(geom, ob):
92
+ geos_linestring_from_py(ob, geom._geom, geom._ndim)
93
+
94
+
95
+ class LineString(BaseGeometry):
96
+
97
+ """A line string, also known as a polyline.
98
+
99
+ """
100
+
101
+ def __init__(self, coordinates=None):
102
+ """Initialize.
103
+
104
+ Parameters
105
+ ----------
106
+
107
+ coordinates : sequence or array
108
+ This may be an object that satisfies the numpy array protocol,
109
+ providing an M x 2 or M x 3 (with z) array, or it may be a sequence
110
+ of x, y (,z) coordinate sequences.
111
+
112
+ Example
113
+ -------
114
+
115
+ >>> line = LineString([[0.0, 0.0], [1.0, 2.0]])
116
+ >>> line = LineString(array([[0.0, 0.0], [1.0, 2.0]]))
117
+
118
+ Each result in a line string from (0.0, 0.0) to (1.0, 2.0).
119
+ """
120
+ BaseGeometry.__init__(self)
121
+ self._init_geom(coordinates)
122
+
123
+ def _init_geom(self, coordinates):
124
+ if coordinates is None:
125
+ # allow creation of null lines, to support unpickling
126
+ pass
127
+ else:
128
+ self._geom, self._ndim = geos_linestring_from_py(coordinates)
129
+
130
+ @property
131
+ def __geo_interface__(self):
132
+ return {
133
+ 'type': 'LineString',
134
+ 'coordinates': tuple(self.coords)
135
+ }
136
+
137
+ @property
138
+ @exceptNull
139
+ def ctypes(self):
140
+ if not self._ctypes_data:
141
+ cs = lgeos.GEOSGeom_getCoordSeq(self._geom)
142
+ cs_len = c_int(0)
143
+ lgeos.GEOSCoordSeq_getSize(cs, byref(cs_len))
144
+ temp = c_double()
145
+ n = self._ndim
146
+ m = cs_len.value
147
+ array_type = c_double * (m * n)
148
+ data = array_type()
149
+ for i in xrange(m):
150
+ lgeos.GEOSCoordSeq_getX(cs, i, byref(temp))
151
+ data[n*i] = temp.value
152
+ lgeos.GEOSCoordSeq_getY(cs, i, byref(temp))
153
+ data[n*i+1] = temp.value
154
+ if n == 3: # TODO: use hasz
155
+ lgeos.GEOSCoordSeq_getZ(cs, i, byref(temp))
156
+ data[n*i+2] = temp.value
157
+ self._ctypes_data = data
158
+ return self._ctypes_data
159
+
160
+ def array_interface(self):
161
+ """Provide the Numpy array protocol."""
162
+ ai = self.array_interface_base
163
+ ai.update({'shape': (len(self.coords), self._ndim)})
164
+ return ai
165
+ __array_interface__ = property(array_interface)
166
+
167
+ # Coordinate access
168
+
169
+ def set_coords(self, coordinates):
170
+ if self._geom is None:
171
+ self._init_geom(coordinates)
172
+ update_linestring_from_py(self, coordinates)
173
+
174
+ coords = property(BaseGeometry.get_coords, set_coords)
175
+
176
+
177
+ class LineStringAdapter(LineString):
178
+
179
+ """Adapts a Python coordinate pair or a numpy array to the line string
180
+ interface.
181
+ """
182
+
183
+ context = None
184
+ __geom = None
185
+ _owned = False
186
+
187
+ def __init__(self, context):
188
+ self.context = context
189
+
190
+ @property
191
+ def _ndim(self):
192
+ try:
193
+ # From array protocol
194
+ array = self.context.__array_interface__
195
+ n = array['shape'][1]
196
+ assert n == 2 or n == 3
197
+ return n
198
+ except AttributeError:
199
+ # Fall back on list
200
+ return len(self.context[0])
201
+
202
+ @property
203
+ def _geom(self):
204
+ """Keeps the GEOS geometry in synch with the context."""
205
+ if self.__geom is not None:
206
+ lgeos.GEOSGeom_destroy(self.__geom)
207
+ self.__geom, n = geos_linestring_from_py(self.context)
208
+ return self.__geom
209
+
210
+ @property
211
+ def __array_interface__(self):
212
+ """Provide the Numpy array protocol."""
213
+ try:
214
+ return self.context.__array_interface__
215
+ except AttributeError:
216
+ return self.array_interface()
217
+
218
+ coords = property(BaseGeometry.get_coords)
219
+
220
+
221
+ def asLineString(context):
222
+ """Factory for PointAdapter instances."""
223
+ return LineStringAdapter(context)
224
+
225
+
226
+ # Test runner
227
+ def _test():
228
+ import doctest
229
+ doctest.testmod()
230
+
231
+
232
+ if __name__ == "__main__":
233
+ _test()
234
+
Binary file
@@ -0,0 +1,157 @@
1
+ """
2
+ Multi-part collection of linestrings.
3
+ """
4
+
5
+ from ctypes import byref, c_double, c_int, c_void_p, cast, POINTER, pointer
6
+
7
+ from shapely.geos import lgeos
8
+ from shapely.geometry.base import BaseGeometry, GeometrySequence, exceptNull
9
+ from shapely.geometry.linestring import LineString, geos_linestring_from_py
10
+
11
+
12
+ def geos_multilinestring_from_py(ob):
13
+ """ob must be either a sequence or array of sequences or arrays."""
14
+ try:
15
+ # From array protocol
16
+ array = ob.__array_interface__
17
+ assert len(array['shape']) == 1
18
+ L = array['shape'][0]
19
+ assert L >= 1
20
+
21
+ # Make pointer to the coordinate array
22
+ cp = cast(array['data'][0], POINTER(c_double))
23
+
24
+ # Array of pointers to sub-geometries
25
+ subs = (c_void_p * L)()
26
+
27
+ for l in xrange(L):
28
+ geom, ndims = geos_linestring_from_py(array['data'][l])
29
+ subs[i] = cast(geom, c_void_p)
30
+ N = lgeos.GEOSGeom_getDimensions(subs[0])
31
+
32
+ except AttributeError:
33
+ # Fall back on list
34
+ L = len(ob)
35
+ N = len(ob[0][0])
36
+ assert L >= 1
37
+ assert N == 2 or N == 3
38
+
39
+ # Array of pointers to point geometries
40
+ subs = (c_void_p * L)()
41
+
42
+ # add to coordinate sequence
43
+ for l in xrange(L):
44
+ geom, ndims = geos_linestring_from_py(ob[l])
45
+ subs[l] = cast(geom, c_void_p)
46
+
47
+ return (lgeos.GEOSGeom_createCollection(5, subs, L), N)
48
+
49
+
50
+ class MultiLineString(BaseGeometry):
51
+
52
+ """a multiple linestring geometry.
53
+ """
54
+
55
+ def __init__(self, coordinates=None):
56
+ """Initialize.
57
+
58
+ Parameters
59
+ ----------
60
+
61
+ coordinates : sequence
62
+ Contains coordinate sequences or objects that provide the numpy
63
+ array protocol, providing an M x 2 or M x 3 (with z) array.
64
+
65
+ Example
66
+ -------
67
+
68
+ >>> geom = MultiLineString( [[[0.0, 0.0], [1.0, 2.0]]] )
69
+ >>> geom = MultiLineString( [ array([[0.0, 0.0], [1.0, 2.0]]) ] )
70
+
71
+ Each result in a collection containing one line string.
72
+ """
73
+ BaseGeometry.__init__(self)
74
+
75
+ if coordinates is None:
76
+ # allow creation of null lines, to support unpickling
77
+ pass
78
+ else:
79
+ self._geom, self._ndim = geos_multilinestring_from_py(coordinates)
80
+
81
+ @property
82
+ def __geo_interface__(self):
83
+ return {
84
+ 'type': 'MultiLineString',
85
+ 'coordinates': tuple(tuple(c for c in g.coords) for g in self.geoms)
86
+ }
87
+
88
+ @property
89
+ def ctypes(self):
90
+ raise NotImplementedError, \
91
+ "Multi-part geometries have no ctypes representations"
92
+
93
+ @property
94
+ def __array_interface__(self):
95
+ """Provide the Numpy array protocol."""
96
+ raise NotImplementedError, \
97
+ "Multi-part geometries do not themselves provide the array interface"
98
+
99
+ @property
100
+ def coords(self):
101
+ raise NotImplementedError, \
102
+ "Multi-part geometries do not provide a coordinate sequence"
103
+
104
+ @property
105
+ @exceptNull
106
+ def geoms(self):
107
+ return GeometrySequence(self, LineString)
108
+
109
+
110
+ class MultiLineStringAdapter(MultiLineString):
111
+
112
+ """Adapts sequences of sequences or numpy arrays to the multilinestring
113
+ interface.
114
+ """
115
+
116
+ context = None
117
+ __geom = None
118
+ _owned = False
119
+
120
+ def __init__(self, context):
121
+ self.context = context
122
+
123
+ @property
124
+ def _ndim(self):
125
+ try:
126
+ # From array protocol
127
+ array = self.context[0].__array_interface__
128
+ n = array['shape'][1]
129
+ assert n == 2 or n == 3
130
+ return n
131
+ except AttributeError:
132
+ # Fall back on list
133
+ return len(self.context[0][0])
134
+
135
+ @property
136
+ def _geom(self):
137
+ """Keeps the GEOS geometry in synch with the context."""
138
+ if self.__geom is not None:
139
+ lgeos.GEOSGeom_destroy(self.__geom)
140
+ self.__geom = geos_multilinestring_from_py(self.context)[0]
141
+ return self.__geom
142
+
143
+
144
+ def asMultiLineString(context):
145
+ """Factory for MultiLineStringAdapter instances."""
146
+ return MultiLineStringAdapter(context)
147
+
148
+
149
+ # Test runner
150
+ def _test():
151
+ import doctest
152
+ doctest.testmod()
153
+
154
+
155
+ if __name__ == "__main__":
156
+ _test()
157
+
Binary file
@@ -0,0 +1,187 @@
1
+ """
2
+ Multiple points.
3
+ """
4
+
5
+ from ctypes import byref, c_double, c_int, c_void_p, cast, POINTER, pointer
6
+
7
+ from shapely.geos import lgeos
8
+ from shapely.geometry.base import BaseGeometry, GeometrySequence, exceptNull
9
+ from shapely.geometry.point import Point, geos_point_from_py
10
+
11
+
12
+ def geos_multipoint_from_py(ob):
13
+ try:
14
+ # From array protocol
15
+ array = ob.__array_interface__
16
+ assert len(array['shape']) == 2
17
+ m = array['shape'][0]
18
+ n = array['shape'][1]
19
+ assert m >= 1
20
+ assert n == 2 or n == 3
21
+
22
+ # Make pointer to the coordinate array
23
+ cp = cast(array['data'][0], POINTER(c_double))
24
+
25
+ # Array of pointers to sub-geometries
26
+ subs = (c_void_p * m)()
27
+
28
+ for i in xrange(m):
29
+ geom, ndims = geos_point_from_py(cp[n*i:n*i+2])
30
+ subs[i] = cast(geom, c_void_p)
31
+
32
+ except AttributeError:
33
+ # Fall back on list
34
+ m = len(ob)
35
+ n = len(ob[0])
36
+ assert n == 2 or n == 3
37
+
38
+ # Array of pointers to point geometries
39
+ subs = (c_void_p * m)()
40
+
41
+ # add to coordinate sequence
42
+ for i in xrange(m):
43
+ coords = ob[i]
44
+ geom, ndims = geos_point_from_py(coords)
45
+ subs[i] = cast(geom, c_void_p)
46
+
47
+ return lgeos.GEOSGeom_createCollection(4, subs, m), n
48
+
49
+
50
+ class MultiPoint(BaseGeometry):
51
+
52
+ """A multiple point geometry.
53
+ """
54
+
55
+ def __init__(self, coordinates=None):
56
+ """Initialize.
57
+
58
+ Parameters
59
+ ----------
60
+
61
+ coordinates : sequence or array
62
+ This may be an object that satisfies the numpy array protocol,
63
+ providing an M x 2 or M x 3 (with z) array, or it may be a sequence
64
+ of x, y (,z) coordinate sequences.
65
+
66
+ Example
67
+ -------
68
+
69
+ >>> geom = MultiPoint([[0.0, 0.0], [1.0, 2.0]])
70
+ >>> geom = MultiPoint(array([[0.0, 0.0], [1.0, 2.0]]))
71
+
72
+ Each result in a line string from (0.0, 0.0) to (1.0, 2.0).
73
+ """
74
+ BaseGeometry.__init__(self)
75
+
76
+ if coordinates is None:
77
+ # allow creation of null lines, to support unpickling
78
+ pass
79
+ else:
80
+ self._geom, self._ndim = geos_multipoint_from_py(coordinates)
81
+
82
+
83
+ @property
84
+ @exceptNull
85
+ def __geo_interface__(self):
86
+ return {
87
+ 'type': 'MultiPoint',
88
+ 'coordinates': tuple([g.coords[0] for g in self.geoms])
89
+ }
90
+
91
+ @property
92
+ @exceptNull
93
+ def ctypes(self):
94
+ if not self._ctypes_data:
95
+ temp = c_double()
96
+ n = self._ndim
97
+ m = len(self.geoms)
98
+ array_type = c_double * (m * n)
99
+ data = array_type()
100
+ for i in xrange(m):
101
+ g = self.geoms[i]._geom
102
+ cs = lgeos.GEOSGeom_getCoordSeq(g)
103
+ lgeos.GEOSCoordSeq_getX(cs, 0, byref(temp))
104
+ data[n*i] = temp.value
105
+ lgeos.GEOSCoordSeq_getY(cs, 0, byref(temp))
106
+ data[n*i+1] = temp.value
107
+ if n == 3: # TODO: use hasz
108
+ lgeos.GEOSCoordSeq_getZ(cs, 0, byref(temp))
109
+ data[n*i+2] = temp.value
110
+ self._ctypes_data = data
111
+ return self._ctypes_data
112
+
113
+ @exceptNull
114
+ def array_interface(self):
115
+ """Provide the Numpy array protocol."""
116
+ ai = self.array_interface_base
117
+ ai.update({'shape': (len(self.geoms), self._ndim)})
118
+ return ai
119
+ __array_interface__ = property(array_interface)
120
+
121
+ @property
122
+ def coords(self):
123
+ raise NotImplementedError, \
124
+ "Multipart geometries do not themselves provide coordinate sequences"
125
+
126
+ @property
127
+ @exceptNull
128
+ def geoms(self):
129
+ return GeometrySequence(self, Point)
130
+
131
+
132
+ class MultiPointAdapter(MultiPoint):
133
+
134
+ """Adapts a Python coordinate pair or a numpy array to the multipoint
135
+ interface.
136
+ """
137
+
138
+ context = None
139
+ __geom = None
140
+ _owned = False
141
+
142
+ def __init__(self, context):
143
+ self.context = context
144
+
145
+ @property
146
+ def _ndim(self):
147
+ try:
148
+ # From array protocol
149
+ array = self.context.__array_interface__
150
+ n = array['shape'][1]
151
+ assert n == 2 or n == 3
152
+ return n
153
+ except AttributeError:
154
+ # Fall back on list
155
+ return len(self.context[0])
156
+
157
+ @property
158
+ def _geom(self):
159
+ """Keeps the GEOS geometry in synch with the context."""
160
+ if self.__geom is not None:
161
+ lgeos.GEOSGeom_destroy(self.__geom)
162
+ self.__geom, n = geos_multipoint_from_py(self.context)
163
+ return self.__geom
164
+
165
+ @property
166
+ def __array_interface__(self):
167
+ """Provide the Numpy array protocol."""
168
+ try:
169
+ return self.context.__array_interface__
170
+ except AttributeError:
171
+ return self.array_interface()
172
+
173
+
174
+ def asMultiPoint(context):
175
+ """Factory for MultiPointAdapter instances."""
176
+ return MultiPointAdapter(context)
177
+
178
+
179
+ # Test runner
180
+ def _test():
181
+ import doctest
182
+ doctest.testmod()
183
+
184
+
185
+ if __name__ == "__main__":
186
+ _test()
187
+
Binary file