shapely 1.0rc2__tar.gz → 1.0.2__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.
Files changed (59) hide show
  1. Shapely-1.0.2/CHANGES.txt +7 -0
  2. Shapely-1.0.2/HISTORY.txt +24 -0
  3. {Shapely-1.0rc2 → Shapely-1.0.2}/PKG-INFO +13 -5
  4. {Shapely-1.0rc2 → Shapely-1.0.2}/README.txt +12 -4
  5. {Shapely-1.0rc2 → Shapely-1.0.2}/Shapely.egg-info/PKG-INFO +13 -5
  6. {Shapely-1.0rc2 → Shapely-1.0.2}/Shapely.egg-info/SOURCES.txt +1 -0
  7. Shapely-1.0.2/Shapely.egg-info/requires.txt +1 -0
  8. {Shapely-1.0rc2 → Shapely-1.0.2}/setup.py +1 -1
  9. {Shapely-1.0rc2 → Shapely-1.0.2}/setup_windows.py +1 -1
  10. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/geometry/base.py +71 -21
  11. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/geometry/linestring.py +17 -28
  12. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/geometry/multilinestring.py +13 -5
  13. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/geometry/multipoint.py +13 -5
  14. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/geometry/multipolygon.py +13 -5
  15. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/geometry/point.py +9 -3
  16. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/geometry/polygon.py +36 -20
  17. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/geos.py +15 -3
  18. Shapely-1.0.2/tests/LineString.txt +130 -0
  19. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/Polygon.txt +12 -0
  20. Shapely-1.0.2/tests/attribute-chains.txt +27 -0
  21. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/test_doctests.py +1 -1
  22. Shapely-1.0rc2/CHANGES.txt +0 -0
  23. Shapely-1.0rc2/HISTORY.txt +0 -11
  24. Shapely-1.0rc2/Shapely.egg-info/requires.txt +0 -2
  25. Shapely-1.0rc2/tests/LineString.txt +0 -124
  26. {Shapely-1.0rc2 → Shapely-1.0.2}/CREDITS.txt +0 -0
  27. {Shapely-1.0rc2 → Shapely-1.0.2}/LICENSE.txt +0 -0
  28. {Shapely-1.0rc2 → Shapely-1.0.2}/Shapely.egg-info/dependency_links.txt +0 -0
  29. {Shapely-1.0rc2 → Shapely-1.0.2}/Shapely.egg-info/top_level.txt +0 -0
  30. {Shapely-1.0rc2 → Shapely-1.0.2}/examples/geoms.py +0 -0
  31. {Shapely-1.0rc2 → Shapely-1.0.2}/examples/world.py +0 -0
  32. {Shapely-1.0rc2 → Shapely-1.0.2}/manual/manual.txt +0 -0
  33. {Shapely-1.0rc2 → Shapely-1.0.2}/manual/style.css +0 -0
  34. {Shapely-1.0rc2 → Shapely-1.0.2}/setup.cfg +0 -0
  35. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/__init__.py +0 -0
  36. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/geometry/__init__.py +0 -0
  37. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/geometry/collection.py +0 -0
  38. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/geometry/geo.py +0 -0
  39. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/iterops.py +0 -0
  40. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/kml.py +0 -0
  41. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/predicates.py +0 -0
  42. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/topology.py +0 -0
  43. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/wkb.py +0 -0
  44. {Shapely-1.0rc2 → Shapely-1.0.2}/shapely/wkt.py +0 -0
  45. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/Array.txt +0 -0
  46. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/GeoInterface.txt +0 -0
  47. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/IterOps.txt +0 -0
  48. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/MultiLineString.txt +0 -0
  49. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/MultiPoint.txt +0 -0
  50. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/MultiPolygon.txt +0 -0
  51. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/Operations.txt +0 -0
  52. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/Persist.txt +0 -0
  53. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/Point.txt +0 -0
  54. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/Predicates.txt +0 -0
  55. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/__init__.py +0 -0
  56. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/binascii_hex.txt +0 -0
  57. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/invalid_intersection.txt +0 -0
  58. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/rungrind.dist +0 -0
  59. {Shapely-1.0rc2 → Shapely-1.0.2}/tests/valgrind-python.supp +0 -0
@@ -0,0 +1,7 @@
1
+ All ticket numbers are rooted at http://trac.gispython.org/projects/PCL/ticket/
2
+
3
+ 1.0.2: 26 February 2008
4
+ -----------------------
5
+ - Fix loss of dimensionality in polygon rings (#155).
6
+
7
+
@@ -0,0 +1,24 @@
1
+ All ticket numbers are rooted at http://trac.gispython.org/projects/PCL/ticket/
2
+
3
+ 1.0.1: 8 February 2008
4
+ ----------------------
5
+ - Allow chaining expressions involving coordinate sequences and geometry parts
6
+ (#151).
7
+ - Protect against abnormal use of coordinate accessors (#152).
8
+ - Coordinate sequences now implement the numpy array protocol (#153).
9
+
10
+
11
+ 1.0: 18 January 2008
12
+ --------------------
13
+ - Final release.
14
+
15
+
16
+ 1.0 RC2: 16 January 2008
17
+ ------------------------
18
+ - Added temporary solution for #149.
19
+
20
+
21
+ 1.0 RC1: 14 January 2008
22
+ ------------------------
23
+ - First release candidate
24
+
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.0
2
2
  Name: Shapely
3
- Version: 1.0rc2
3
+ Version: 1.0.2
4
4
  Summary: Geospatial geometries, predicates, and operations
5
5
  Home-page: http://trac.gispython.org/projects/PCL/wiki/Shapely
6
6
  Author: Sean Gillies
@@ -9,10 +9,11 @@ License: BSD
9
9
  Description: Shapely
10
10
  =======
11
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:
12
+ Shapely is a Python package for manipulation and analysis of 2D geospatial
13
+ geometries. It is based on GEOS (http://geos.refractions.net). Shapely 1.0 is
14
+ not concerned with data formats or coordinate reference systems.
15
+ Responsibility for reading and writing data and projecting coordinates is left
16
+ to other packages like WorldMill_ and pyproj_. For more information, see:
16
17
 
17
18
  * Shapely wiki_
18
19
  * Shapely manual_
@@ -20,6 +21,13 @@ Description: Shapely
20
21
  Shapely requires Python 2.4+. (I've also begun to port it to Python 3.0:
21
22
  http://zcologia.com/news/564/shapely-for-python-3-0/.)
22
23
 
24
+ See also CHANGES.txt_ and HISTORY.txt_.
25
+
26
+ .. _CHANGES.txt: http://trac.gispython.org/projects/PCL/browser/Shapely/trunk/CHANGES.txt
27
+ .. _HISTORY.txt: http://trac.gispython.org/projects/PCL/browser/Shapely/trunk/HISTORY.txt
28
+ .. _WorldMill: http://pypi.python.org/pypi/WorldMill
29
+ .. _pyproj: http://pypi.python.org/pypi/pyproj
30
+
23
31
 
24
32
  Dependencies
25
33
  ------------
@@ -1,10 +1,11 @@
1
1
  Shapely
2
2
  =======
3
3
 
4
- Shapely is a Python package for programming with 2D geospatial geometries. It
5
- is based on GEOS (http://geos.refractions.net). Shapely 1.0 is ignorant about
6
- coordinate and reference systems. Projection responsibility is left to specific
7
- applications. For more information, see:
4
+ Shapely is a Python package for manipulation and analysis of 2D geospatial
5
+ geometries. It is based on GEOS (http://geos.refractions.net). Shapely 1.0 is
6
+ not concerned with data formats or coordinate reference systems.
7
+ Responsibility for reading and writing data and projecting coordinates is left
8
+ to other packages like WorldMill_ and pyproj_. For more information, see:
8
9
 
9
10
  * Shapely wiki_
10
11
  * Shapely manual_
@@ -12,6 +13,13 @@ applications. For more information, see:
12
13
  Shapely requires Python 2.4+. (I've also begun to port it to Python 3.0:
13
14
  http://zcologia.com/news/564/shapely-for-python-3-0/.)
14
15
 
16
+ See also CHANGES.txt_ and HISTORY.txt_.
17
+
18
+ .. _CHANGES.txt: http://trac.gispython.org/projects/PCL/browser/Shapely/trunk/CHANGES.txt
19
+ .. _HISTORY.txt: http://trac.gispython.org/projects/PCL/browser/Shapely/trunk/HISTORY.txt
20
+ .. _WorldMill: http://pypi.python.org/pypi/WorldMill
21
+ .. _pyproj: http://pypi.python.org/pypi/pyproj
22
+
15
23
 
16
24
  Dependencies
17
25
  ------------
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 1.0
2
2
  Name: Shapely
3
- Version: 1.0rc2
3
+ Version: 1.0.2
4
4
  Summary: Geospatial geometries, predicates, and operations
5
5
  Home-page: http://trac.gispython.org/projects/PCL/wiki/Shapely
6
6
  Author: Sean Gillies
@@ -9,10 +9,11 @@ License: BSD
9
9
  Description: Shapely
10
10
  =======
11
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:
12
+ Shapely is a Python package for manipulation and analysis of 2D geospatial
13
+ geometries. It is based on GEOS (http://geos.refractions.net). Shapely 1.0 is
14
+ not concerned with data formats or coordinate reference systems.
15
+ Responsibility for reading and writing data and projecting coordinates is left
16
+ to other packages like WorldMill_ and pyproj_. For more information, see:
16
17
 
17
18
  * Shapely wiki_
18
19
  * Shapely manual_
@@ -20,6 +21,13 @@ Description: Shapely
20
21
  Shapely requires Python 2.4+. (I've also begun to port it to Python 3.0:
21
22
  http://zcologia.com/news/564/shapely-for-python-3-0/.)
22
23
 
24
+ See also CHANGES.txt_ and HISTORY.txt_.
25
+
26
+ .. _CHANGES.txt: http://trac.gispython.org/projects/PCL/browser/Shapely/trunk/CHANGES.txt
27
+ .. _HISTORY.txt: http://trac.gispython.org/projects/PCL/browser/Shapely/trunk/HISTORY.txt
28
+ .. _WorldMill: http://pypi.python.org/pypi/WorldMill
29
+ .. _pyproj: http://pypi.python.org/pypi/pyproj
30
+
23
31
 
24
32
  Dependencies
25
33
  ------------
@@ -45,6 +45,7 @@ tests/Point.txt
45
45
  tests/Polygon.txt
46
46
  tests/Predicates.txt
47
47
  tests/__init__.py
48
+ tests/attribute-chains.txt
48
49
  tests/binascii_hex.txt
49
50
  tests/invalid_intersection.txt
50
51
  tests/rungrind.dist
@@ -0,0 +1 @@
1
+ setuptools
@@ -11,7 +11,7 @@ if version_info[:2] < (2,5):
11
11
  readme_text = file('README.txt', 'rb').read()
12
12
 
13
13
  setup(name = 'Shapely',
14
- version = '1.0rc2',
14
+ version = '1.0.2',
15
15
  description = 'Geospatial geometries, predicates, and operations',
16
16
  license = 'BSD',
17
17
  keywords = 'geometry topology',
@@ -11,7 +11,7 @@ if version_info[:2] < (2,5):
11
11
  readme_text = file('README.txt', 'rb').read()
12
12
 
13
13
  setup(name = 'Shapely',
14
- version = '1.0rc2',
14
+ version = '1.0.2',
15
15
  description = 'Geospatial geometries, predicates, and operations',
16
16
  license = 'BSD',
17
17
  keywords = 'geometry topology',
@@ -41,24 +41,32 @@ def geom_factory(g):
41
41
  [geom_type],
42
42
  )
43
43
  ob.__class__ = getattr(mod, geom_type)
44
- ob._geom = g
44
+ ob.__geom__ = g
45
45
  ob._ndim = 2 # callers should be all from 2D worlds
46
46
  return ob
47
47
 
48
48
 
49
49
  class CoordinateSequence(object):
50
-
50
+
51
+ _geom = None
51
52
  _cseq = None
52
53
  _ndim = None
53
54
  _length = 0
54
55
  index = 0
56
+ __p__ = None
55
57
 
56
- def __init__(self, geom):
57
- self._cseq = lgeos.GEOSGeom_getCoordSeq(geom._geom)
58
- self._ndim = geom._ndim
58
+ def __init__(self, parent):
59
+ self.__p__ = parent
60
+ self._geom = parent._geom
61
+ self._ndim = parent._ndim
62
+ self.update_cseq()
59
63
 
64
+ def update_cseq(self):
65
+ self._cseq = lgeos.GEOSGeom_getCoordSeq(self._geom)
66
+
60
67
  def __iter__(self):
61
68
  self.index = 0
69
+ self.update_cseq()
62
70
  self._length = self.__len__()
63
71
  return self
64
72
 
@@ -86,6 +94,7 @@ class CoordinateSequence(object):
86
94
  return cs_len.value
87
95
 
88
96
  def __getitem__(self, i):
97
+ self.update_cseq()
89
98
  M = self.__len__()
90
99
  if i + M < 0 or i >= M:
91
100
  raise IndexError, "index out of range"
@@ -104,19 +113,58 @@ class CoordinateSequence(object):
104
113
  else:
105
114
  return (dx.value, dy.value)
106
115
 
116
+ @property
117
+ def ctypes(self):
118
+ self.update_cseq()
119
+ n = self._ndim
120
+ m = self.__len__()
121
+ array_type = c_double * (m * n)
122
+ data = array_type()
123
+ temp = c_double()
124
+
125
+ for i in xrange(m):
126
+ lgeos.GEOSCoordSeq_getX(self._cseq, i, byref(temp))
127
+ data[n*i] = temp.value
128
+ lgeos.GEOSCoordSeq_getY(self._cseq, i, byref(temp))
129
+ data[n*i+1] = temp.value
130
+ if n == 3: # TODO: use hasz
131
+ lgeos.GEOSCoordSeq_getZ(self._cseq, i, byref(temp))
132
+ data[n*i+2] = temp.value
133
+ return data
134
+
135
+ def array_interface(self):
136
+ """Provide the Numpy array protocol."""
137
+ if sys.byteorder == 'little':
138
+ typestr = '<f8'
139
+ elif sys.byteorder == 'big':
140
+ typestr = '>f8'
141
+ else:
142
+ raise ValueError, \
143
+ "Unsupported byteorder: neither little nor big-endian"
144
+ ai = {
145
+ 'version': 3,
146
+ 'typestr': typestr,
147
+ 'data': self.ctypes,
148
+ }
149
+ ai.update({'shape': (len(self), self._ndim)})
150
+ return ai
151
+ __array_interface__ = property(array_interface)
152
+
107
153
 
108
154
  class GeometrySequence(object):
109
155
 
110
156
  _factory = None
111
157
  _geom = None
158
+ __p__ = None
112
159
  _ndim = None
113
160
  _index = 0
114
161
  _length = 0
115
162
 
116
- def __init__(self, geom, type):
163
+ def __init__(self, parent, type):
117
164
  self._factory = type
118
- self._geom = geom._geom
119
- self._ndim = geom._ndim
165
+ self.__p__ = parent
166
+ self._geom = parent._geom
167
+ self._ndim = parent._ndim
120
168
 
121
169
  def __iter__(self):
122
170
  self._index = 0
@@ -182,18 +230,18 @@ class BaseGeometry(object):
182
230
  """Provides GEOS spatial predicates and topological operations.
183
231
  """
184
232
 
185
- __geom = None # See _geom property below
233
+ __geom__ = None # See _geom property below
186
234
  _ctypes_data = None
187
235
  _ndim = None
188
236
  _crs = None
189
237
  _owned = False
190
238
 
191
239
  def __init__(self):
192
- self.__geom = None
240
+ self.__geom__ = None
193
241
 
194
242
  def __del__(self):
195
- if self.__geom is not None and not self._owned:
196
- lgeos.GEOSGeom_destroy(self.__geom)
243
+ if self.__geom__ is not None and not self._owned:
244
+ lgeos.GEOSGeom_destroy(self.__geom__)
197
245
 
198
246
  def __str__(self):
199
247
  return self.to_wkt()
@@ -210,7 +258,7 @@ class BaseGeometry(object):
210
258
  return (self.__class__, (), self.to_wkb())
211
259
 
212
260
  def __setstate__(self, state):
213
- self.__geom = lgeos.GEOSGeomFromWKB_buf(
261
+ self.__geom__ = lgeos.GEOSGeomFromWKB_buf(
214
262
  c_char_p(state),
215
263
  c_size_t(len(state))
216
264
  )
@@ -218,11 +266,13 @@ class BaseGeometry(object):
218
266
  # _geom has been made a property with the GEOS geometry pointer stored
219
267
  # in __geom so that geometries and geometry adapters can share __del__
220
268
 
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)
269
+ def _get_geom(self):
270
+ return self.__geom__
271
+
272
+ def _set_geom(self, val):
273
+ self.__geom__ = val
274
+
275
+ _geom = property(_get_geom, _set_geom)
226
276
 
227
277
  # Array and ctypes interfaces
228
278
 
@@ -253,14 +303,14 @@ class BaseGeometry(object):
253
303
  raise NotImplementedError
254
304
 
255
305
  @exceptNull
256
- def get_coords(self):
306
+ def _get_coords(self):
257
307
  return CoordinateSequence(self)
258
308
 
259
- def set_coords(self, ob):
309
+ def _set_coords(self, ob):
260
310
  raise NotImplementedError, \
261
311
  "set_coords must be provided by derived classes"
262
312
 
263
- coords = property(get_coords, set_coords)
313
+ coords = property(_get_coords, _set_coords)
264
314
 
265
315
  # Python feature protocol
266
316
 
@@ -138,40 +138,23 @@ class LineString(BaseGeometry):
138
138
  @exceptNull
139
139
  def ctypes(self):
140
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
141
+ self._ctypes_data = self.coords.ctypes
158
142
  return self._ctypes_data
159
143
 
160
144
  def array_interface(self):
161
145
  """Provide the Numpy array protocol."""
162
- ai = self.array_interface_base
163
- ai.update({'shape': (len(self.coords), self._ndim)})
164
- return ai
146
+ return self.coords.array_interface()
147
+
165
148
  __array_interface__ = property(array_interface)
166
149
 
167
150
  # Coordinate access
168
151
 
169
- def set_coords(self, coordinates):
152
+ def _set_coords(self, coordinates):
170
153
  if self._geom is None:
171
154
  self._init_geom(coordinates)
172
155
  update_linestring_from_py(self, coordinates)
173
156
 
174
- coords = property(BaseGeometry.get_coords, set_coords)
157
+ coords = property(BaseGeometry._get_coords, _set_coords)
175
158
 
176
159
 
177
160
  class LineStringAdapter(LineString):
@@ -181,7 +164,7 @@ class LineStringAdapter(LineString):
181
164
  """
182
165
 
183
166
  context = None
184
- __geom = None
167
+ #__geom = None
185
168
  _owned = False
186
169
 
187
170
  def __init__(self, context):
@@ -202,10 +185,10 @@ class LineStringAdapter(LineString):
202
185
  @property
203
186
  def _geom(self):
204
187
  """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
188
+ if self.__geom__ is not None:
189
+ lgeos.GEOSGeom_destroy(self.__geom__)
190
+ self.__geom__, n = geos_linestring_from_py(self.context)
191
+ return self.__geom__
209
192
 
210
193
  @property
211
194
  def __array_interface__(self):
@@ -215,7 +198,13 @@ class LineStringAdapter(LineString):
215
198
  except AttributeError:
216
199
  return self.array_interface()
217
200
 
218
- coords = property(BaseGeometry.get_coords)
201
+ _get_coords = BaseGeometry._get_coords
202
+
203
+ def _set_coords(self, ob):
204
+ raise NotImplementedError, \
205
+ "Component rings have coordinate sequences, but the polygon does not"
206
+
207
+ coords = property(_get_coords)
219
208
 
220
209
 
221
210
  def asLineString(context):
@@ -96,6 +96,14 @@ class MultiLineString(BaseGeometry):
96
96
  raise NotImplementedError, \
97
97
  "Multi-part geometries do not themselves provide the array interface"
98
98
 
99
+ def _get_coords(self):
100
+ raise NotImplementedError, \
101
+ "Component rings have coordinate sequences, but the polygon does not"
102
+
103
+ def _set_coords(self, ob):
104
+ raise NotImplementedError, \
105
+ "Component rings have coordinate sequences, but the polygon does not"
106
+
99
107
  @property
100
108
  def coords(self):
101
109
  raise NotImplementedError, \
@@ -114,7 +122,7 @@ class MultiLineStringAdapter(MultiLineString):
114
122
  """
115
123
 
116
124
  context = None
117
- __geom = None
125
+ #__geom = None
118
126
  _owned = False
119
127
 
120
128
  def __init__(self, context):
@@ -135,10 +143,10 @@ class MultiLineStringAdapter(MultiLineString):
135
143
  @property
136
144
  def _geom(self):
137
145
  """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
146
+ if self.__geom__ is not None:
147
+ lgeos.GEOSGeom_destroy(self.__geom__)
148
+ self.__geom__ = geos_multilinestring_from_py(self.context)[0]
149
+ return self.__geom__
142
150
 
143
151
 
144
152
  def asMultiLineString(context):
@@ -118,6 +118,14 @@ class MultiPoint(BaseGeometry):
118
118
  return ai
119
119
  __array_interface__ = property(array_interface)
120
120
 
121
+ def _get_coords(self):
122
+ raise NotImplementedError, \
123
+ "Component rings have coordinate sequences, but the polygon does not"
124
+
125
+ def _set_coords(self, ob):
126
+ raise NotImplementedError, \
127
+ "Component rings have coordinate sequences, but the polygon does not"
128
+
121
129
  @property
122
130
  def coords(self):
123
131
  raise NotImplementedError, \
@@ -136,7 +144,7 @@ class MultiPointAdapter(MultiPoint):
136
144
  """
137
145
 
138
146
  context = None
139
- __geom = None
147
+ #__geom__ = None
140
148
  _owned = False
141
149
 
142
150
  def __init__(self, context):
@@ -157,10 +165,10 @@ class MultiPointAdapter(MultiPoint):
157
165
  @property
158
166
  def _geom(self):
159
167
  """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
168
+ if self.__geom__ is not None:
169
+ lgeos.GEOSGeom_destroy(self.__geom__)
170
+ self.__geom__, n = geos_multipoint_from_py(self.context)
171
+ return self.__geom__
164
172
 
165
173
  @property
166
174
  def __array_interface__(self):
@@ -82,6 +82,14 @@ class MultiPolygon(BaseGeometry):
82
82
  raise NotImplementedError, \
83
83
  "Multi-part geometries do not themselves provide the array interface"
84
84
 
85
+ def _get_coords(self):
86
+ raise NotImplementedError, \
87
+ "Component rings have coordinate sequences, but the polygon does not"
88
+
89
+ def _set_coords(self, ob):
90
+ raise NotImplementedError, \
91
+ "Component rings have coordinate sequences, but the polygon does not"
92
+
85
93
  @property
86
94
  def coords(self):
87
95
  raise NotImplementedError, \
@@ -100,7 +108,7 @@ class MultiPolygonAdapter(MultiPolygon):
100
108
  """
101
109
 
102
110
  context = None
103
- __geom = None
111
+ #__geom = None
104
112
  _owned = False
105
113
 
106
114
  def __init__(self, context):
@@ -121,10 +129,10 @@ class MultiPolygonAdapter(MultiPolygon):
121
129
  @property
122
130
  def _geom(self):
123
131
  """Keeps the GEOS geometry in synch with the context."""
124
- if self.__geom is not None:
125
- lgeos.GEOSGeom_destroy(self.__geom)
126
- self.__geom = geos_multipolygon_from_py(self.context)[0]
127
- return self.__geom
132
+ if self.__geom__ is not None:
133
+ lgeos.GEOSGeom_destroy(self.__geom__)
134
+ self.__geom__ = geos_multipolygon_from_py(self.context)[0]
135
+ return self.__geom__
128
136
 
129
137
 
130
138
  def asMultiPolygon(context):
@@ -190,13 +190,13 @@ class Point(BaseGeometry):
190
190
 
191
191
  # Coordinate access
192
192
 
193
- def set_coords(self, coordinates):
193
+ def _set_coords(self, coordinates):
194
194
  if self._geom is None:
195
195
  self._init_geom(coordinates)
196
196
  else:
197
197
  update_point_from_py(self, coordinates)
198
198
 
199
- coords = property(BaseGeometry.get_coords, set_coords)
199
+ coords = property(BaseGeometry._get_coords, _set_coords)
200
200
 
201
201
 
202
202
  class PointAdapter(Point):
@@ -241,7 +241,13 @@ class PointAdapter(Point):
241
241
  except AttributeError:
242
242
  return self.array_interface()
243
243
 
244
- coords = property(BaseGeometry.get_coords)
244
+ _get_coords = BaseGeometry._get_coords
245
+
246
+ def _set_coords(self, ob):
247
+ raise NotImplementedError, \
248
+ "Component rings have coordinate sequences, but the polygon does not"
249
+
250
+ coords = property(_get_coords)
245
251
 
246
252
 
247
253
  def asPoint(context):
@@ -141,7 +141,8 @@ class LinearRing(LineString):
141
141
  """
142
142
 
143
143
  _ndim = 2
144
- __geom = None
144
+ __geom__ = None
145
+ __p__ = None
145
146
  _owned = False
146
147
 
147
148
  def __init__(self, coordinates=None):
@@ -171,7 +172,7 @@ class LinearRing(LineString):
171
172
  # allow creation of null lines, to support unpickling
172
173
  pass
173
174
  else:
174
- self._geom, self._ndims = geos_linearring_from_py(coordinates)
175
+ self._geom, self._ndim = geos_linearring_from_py(coordinates)
175
176
 
176
177
  @property
177
178
  def __geo_interface__(self):
@@ -182,24 +183,27 @@ class LinearRing(LineString):
182
183
 
183
184
  # Coordinate access
184
185
 
185
- def set_coords(self, coordinates):
186
+ _get_coords = BaseGeometry._get_coords
187
+
188
+ def _set_coords(self, coordinates):
186
189
  if self._geom is None:
187
190
  self._init_geom(coordinates)
188
191
  update_linearring_from_py(self, coordinates)
189
192
 
190
- coords = property(BaseGeometry.get_coords, set_coords)
193
+ coords = property(_get_coords, _set_coords)
191
194
 
192
195
 
193
196
  class LinearRingAdapter(LineStringAdapter):
194
197
 
195
198
  context = None
196
- __geom = None
199
+ __geom__ = None
200
+ __p__ = None
197
201
  _owned = False
198
202
 
199
203
  @property
200
204
  def _geom(self):
201
205
  """Keeps the GEOS geometry in synch with the context."""
202
- if self.__geom is not None:
206
+ if self.__geom__ is not None:
203
207
  lgeos.GEOSGeom_destroy(self.__geom)
204
208
  self.__geom, n = geos_linearring_from_py(self.context)
205
209
  return self.__geom
@@ -211,7 +215,7 @@ class LinearRingAdapter(LineStringAdapter):
211
215
  'coordinates': tuple(self.coords)
212
216
  }
213
217
 
214
- coords = property(BaseGeometry.get_coords)
218
+ coords = property(BaseGeometry._get_coords)
215
219
 
216
220
 
217
221
  def asLinearRing(context):
@@ -222,13 +226,15 @@ class InteriorRingSequence(object):
222
226
 
223
227
  _factory = None
224
228
  _geom = None
229
+ __p__ = None
225
230
  _ndim = None
226
231
  _index = 0
227
232
  _length = 0
228
233
 
229
- def __init__(self, geom):
230
- self._geom = geom._geom
231
- self._ndim = geom._ndim
234
+ def __init__(self, parent):
235
+ self.__p__ = parent
236
+ self._geom = parent._geom
237
+ self._ndim = parent._ndim
232
238
 
233
239
  def __iter__(self):
234
240
  self._index = 0
@@ -272,7 +278,7 @@ class InteriorRingSequence(object):
272
278
 
273
279
  def geos_polygon_from_py(shell, holes=None):
274
280
  if shell is not None:
275
- geos_shell, ndims = geos_linearring_from_py(shell)
281
+ geos_shell, ndim = geos_linearring_from_py(shell)
276
282
  if holes:
277
283
  ob = holes
278
284
  L = len(ob)
@@ -288,7 +294,7 @@ def geos_polygon_from_py(shell, holes=None):
288
294
 
289
295
  # add to coordinate sequence
290
296
  for l in xrange(L):
291
- geom, ndims = geos_linearring_from_py(ob[l])
297
+ geom, ndim = geos_linearring_from_py(ob[l])
292
298
  geos_holes[l] = cast(geom, c_void_p)
293
299
 
294
300
  else:
@@ -301,7 +307,7 @@ def geos_polygon_from_py(shell, holes=None):
301
307
  geos_holes,
302
308
  L
303
309
  ),
304
- ndims
310
+ ndim
305
311
  )
306
312
 
307
313
  class Polygon(BaseGeometry):
@@ -312,7 +318,7 @@ class Polygon(BaseGeometry):
312
318
  _exterior = None
313
319
  _interiors = []
314
320
  _ndim = 2
315
- __geom = None
321
+ __geom__ = None
316
322
  _owned = False
317
323
 
318
324
  def __init__(self, shell=None, holes=None):
@@ -333,7 +339,7 @@ class Polygon(BaseGeometry):
333
339
  BaseGeometry.__init__(self)
334
340
 
335
341
  if shell is not None:
336
- self._geom, self._ndims = geos_polygon_from_py(shell, holes)
342
+ self._geom, self._ndim = geos_polygon_from_py(shell, holes)
337
343
 
338
344
  @property
339
345
  @exceptNull
@@ -344,6 +350,8 @@ class Polygon(BaseGeometry):
344
350
  ring = lgeos.GEOSGetExteriorRing(self._geom)
345
351
  self._exterior = LinearRing()
346
352
  self._exterior._geom = ring
353
+ # The ring needs to hold an extra ref to the polygon
354
+ self.__p__ = self
347
355
  self._exterior._owned = True
348
356
  return self._exterior
349
357
 
@@ -363,6 +371,14 @@ class Polygon(BaseGeometry):
363
371
  raise NotImplementedError, \
364
372
  "A polygon does not itself provide the array interface. Its rings do."
365
373
 
374
+ def _get_coords(self):
375
+ raise NotImplementedError, \
376
+ "Component rings have coordinate sequences, but the polygon does not"
377
+
378
+ def _set_coords(self, ob):
379
+ raise NotImplementedError, \
380
+ "Component rings have coordinate sequences, but the polygon does not"
381
+
366
382
  @property
367
383
  def coords(self):
368
384
  raise NotImplementedError, \
@@ -386,7 +402,7 @@ class PolygonAdapter(Polygon):
386
402
  """
387
403
 
388
404
  context = None
389
- __geom = None
405
+ __geom__ = None
390
406
  _owned = False
391
407
 
392
408
  def __init__(self, shell, holes=None):
@@ -408,10 +424,10 @@ class PolygonAdapter(Polygon):
408
424
  @property
409
425
  def _geom(self):
410
426
  """Keeps the GEOS geometry in synch with the context."""
411
- if self.__geom is not None:
412
- lgeos.GEOSGeom_destroy(self.__geom)
413
- self.__geom = geos_polygon_from_py(self.shell, self.holes)[0]
414
- return self.__geom
427
+ if self.__geom__ is not None:
428
+ lgeos.GEOSGeom_destroy(self.__geom__)
429
+ self.__geom__ = geos_polygon_from_py(self.shell, self.holes)[0]
430
+ return self.__geom__
415
431
 
416
432
 
417
433
  def asPolygon(shell, holes=None):
@@ -24,15 +24,27 @@ if sys.platform == 'win32':
24
24
  except WindowsError:
25
25
  # XXX: See http://trac.gispython.org/projects/PCL/ticket/149
26
26
  pass
27
-
28
27
  elif sys.platform == 'darwin':
29
- lgeos = CDLL(find_library('geos_c'))
28
+ lib = find_library('geos_c')
29
+ if lib is None:
30
+ ## try a few more locations
31
+ lib_paths = [
32
+ # The Framework build from Kyng Chaos:
33
+ "/Library/Frameworks/GEOS.framework/Versions/Current/GEOS",
34
+ ]
35
+ for path in lib_paths:
36
+ if os.path.exists(path):
37
+ lib = path
38
+ break
39
+ else:
40
+ raise ImportError, "Could not find geos_c library"
41
+ lgeos = CDLL(lib)
30
42
  free = CDLL(find_library('libc')).free
31
43
  else:
32
44
  # Try the major versioned name first, falling back on the unversioned name.
33
45
  try:
34
46
  lgeos = CDLL('libgeos_c.so.1')
35
- except ImportError:
47
+ except (OSError, ImportError):
36
48
  lgeos = CDLL('libgeos_c.so')
37
49
  except:
38
50
  raise
@@ -0,0 +1,130 @@
1
+ LineStrings
2
+ ===========
3
+
4
+ Initialization
5
+ --------------
6
+
7
+ >>> from shapely.geometry import LineString
8
+
9
+ Construct from a numpy array
10
+
11
+ >>> from numpy import array
12
+ >>> line = LineString(array([[0.0, 0.0], [1.0, 2.0]]))
13
+ >>> len(line.coords)
14
+ 2
15
+ >>> line.wkt
16
+ 'LINESTRING (0.0000000000000000 0.0000000000000000, 1.0000000000000000 2.0000000000000000)'
17
+
18
+ From coordinate tuples
19
+
20
+ >>> line = LineString(((1.0, 2.0), (3.0, 4.0)))
21
+ >>> len(line.coords)
22
+ 2
23
+ >>> line.wkt
24
+ 'LINESTRING (1.0000000000000000 2.0000000000000000, 3.0000000000000000 4.0000000000000000)'
25
+
26
+
27
+ Numpy Support
28
+ -------------
29
+
30
+ >>> from numpy import asarray
31
+ >>> la = asarray(line)
32
+ >>> la
33
+ array([[ 1., 2.],
34
+ [ 3., 4.]])
35
+ >>> la[0]
36
+ array([ 1., 2.])
37
+
38
+ Coordinate sequences can be adapted as well
39
+
40
+ >>> asarray(line.coords)
41
+ array([[ 1., 2.],
42
+ [ 3., 4.]])
43
+
44
+ Bounds
45
+ ------
46
+
47
+ >>> line.bounds
48
+ (1.0, 2.0, 3.0, 4.0)
49
+
50
+ Coordinate Access
51
+ -----------------
52
+
53
+ >>> tuple(line.coords)
54
+ ((1.0, 2.0), (3.0, 4.0))
55
+
56
+ >>> line.coords[0]
57
+ (1.0, 2.0)
58
+ >>> line.coords[1]
59
+ (3.0, 4.0)
60
+ >>> line.coords[2]
61
+ Traceback (most recent call last):
62
+ ...
63
+ IndexError: index out of range
64
+
65
+ Geo interface
66
+ -------------
67
+
68
+ >>> line.__geo_interface__
69
+ {'type': 'LineString', 'coordinates': ((1.0, 2.0), (3.0, 4.0))}
70
+
71
+
72
+ Coordinate modification
73
+ -----------------------
74
+
75
+ >>> line.coords = ((-1.0, -1.0), (1.0, 1.0))
76
+ >>> line.__geo_interface__
77
+ {'type': 'LineString', 'coordinates': ((-1.0, -1.0), (1.0, 1.0))}
78
+
79
+
80
+ Adapter
81
+ -------
82
+
83
+ >>> from shapely.geometry import asLineString
84
+
85
+ Adapt a Numpy array to a line string
86
+
87
+ >>> a = array([[1.0, 2.0], [3.0, 4.0]])
88
+ >>> la = asLineString(a)
89
+ >>> la.context
90
+ array([[ 1., 2.],
91
+ [ 3., 4.]])
92
+
93
+ >>> la.wkt
94
+ 'LINESTRING (1.0000000000000000 2.0000000000000000, 3.0000000000000000 4.0000000000000000)'
95
+
96
+ Now, the inverse
97
+
98
+ >>> la.__array_interface__ == la.context.__array_interface__
99
+ True
100
+ >>> as = asarray(la)
101
+ >>> as
102
+ array([[ 1., 2.],
103
+ [ 3., 4.]])
104
+
105
+ Adapt a coordinate list to a line string
106
+
107
+ >>> coords = [[5.0, 6.0], [7.0, 8.0]]
108
+ >>> la = asLineString(coords)
109
+ >>> la.wkt
110
+ 'LINESTRING (5.0000000000000000 6.0000000000000000, 7.0000000000000000 8.0000000000000000)'
111
+
112
+ Test Non-operability of Null geometry
113
+
114
+ >>> l_null = LineString()
115
+ >>> l_null.wkt # doctest: +ELLIPSIS
116
+ Traceback (most recent call last):
117
+ ...
118
+ ValueError: Null geometry supports no operations
119
+
120
+ >>> l_null.length # doctest: +ELLIPSIS
121
+ Traceback (most recent call last):
122
+ ...
123
+ ValueError: Null geometry supports no operations
124
+
125
+ Check that we can set coordinates of a null geometry
126
+
127
+ >>> l_null.coords = [(0, 0), (1, 1)]
128
+ >>> print l_null.length # doctest: +ELLIPSIS
129
+ 1.414...
130
+
@@ -88,6 +88,17 @@ Interior rings (holes)
88
88
  ...
89
89
  IndexError: index out of range
90
90
 
91
+ Coordinate getters and setters raise exceptions
92
+
93
+ >>> polygon._get_coords()
94
+ Traceback (most recent call last):
95
+ ...
96
+ NotImplementedError: Component rings have coordinate sequences, but the polygon does not
97
+ >>> polygon.coords
98
+ Traceback (most recent call last):
99
+ ...
100
+ NotImplementedError: Component rings have coordinate sequences, but the polygon does not
101
+
91
102
 
92
103
  Geo interface
93
104
  -------------
@@ -128,3 +139,4 @@ Check that we can set coordinates of a null geometry
128
139
  >>> print r_null.length # doctest: +ELLIPSIS
129
140
  3.414...
130
141
 
142
+
@@ -0,0 +1,27 @@
1
+ Attribute Chaining
2
+ ==================
3
+
4
+ See also ticket #151.
5
+
6
+ >>> from shapely.geometry import Polygon
7
+ >>> p = Polygon(((0.0, 0.0), (0.0, 1.0), (-1.0, 1.0), (-1.0, 0.0)))
8
+ >>> list(p.boundary.coords)
9
+ [(0.0, 0.0), (0.0, 1.0), (-1.0, 1.0), (-1.0, 0.0), (0.0, 0.0)]
10
+
11
+ >>> print list(p.buffer(1).exterior.coords)
12
+ [(-0.99999999999999989, 2.0), (0.0, 2.0)...
13
+
14
+ Test chained access to interiors
15
+
16
+ >>> p = Polygon(
17
+ ... ((0.0, 0.0), (0.0, 1.0), (-1.0, 1.0), (-1.0, 0.0)),
18
+ ... [((-0.25, 0.25), (-0.25, 0.75), (-0.75, 0.75), (-0.75, 0.25))]
19
+ ... )
20
+ >>> p.area
21
+ 0.75
22
+ >>> print list(p.interiors[0].coords)
23
+ [(-0.25, 0.25), (-0.25, 0.75), (-0.75, 0.75), (-0.75, 0.25), (-0.25, 0.25)]
24
+ >>> print list(p.interiors[0].buffer(1).exterior.coords)
25
+ [(-0.24999999999999986, -0.75), (-0.25, -0.75)...
26
+
27
+
@@ -30,5 +30,5 @@ def test_suite():
30
30
  in list_doctests()])
31
31
 
32
32
  if __name__ == "__main__":
33
- runner = unittest.TextTestRunner()
33
+ runner = unittest.TextTestRunner(verbosity=1)
34
34
  runner.run(test_suite())
File without changes
@@ -1,11 +0,0 @@
1
- All ticket numbers are rooted at http://trac.gispython.org/projects/PCL/ticket/
2
-
3
- 1.0 RC2: 16 January 2008
4
- ------------------------
5
- - Added temporary solution for #149.
6
-
7
-
8
- 1.0 RC1: 14 January 2008
9
- ------------------------
10
- - First release candidate
11
-
@@ -1,2 +0,0 @@
1
- setuptools
2
- ctypes
@@ -1,124 +0,0 @@
1
- LineStrings
2
- ===========
3
-
4
- Initialization
5
- --------------
6
-
7
- >>> from shapely.geometry import LineString
8
-
9
- Construct from a numpy array
10
-
11
- >>> from numpy import array
12
- >>> line = LineString(array([[0.0, 0.0], [1.0, 2.0]]))
13
- >>> len(line.coords)
14
- 2
15
- >>> line.wkt
16
- 'LINESTRING (0.0000000000000000 0.0000000000000000, 1.0000000000000000 2.0000000000000000)'
17
-
18
- From coordinate tuples
19
-
20
- >>> line = LineString(((1.0, 2.0), (3.0, 4.0)))
21
- >>> len(line.coords)
22
- 2
23
- >>> line.wkt
24
- 'LINESTRING (1.0000000000000000 2.0000000000000000, 3.0000000000000000 4.0000000000000000)'
25
-
26
-
27
- Numpy Support
28
- -------------
29
-
30
- >>> from numpy import asarray
31
- >>> la = asarray(line)
32
- >>> la
33
- array([[ 1., 2.],
34
- [ 3., 4.]])
35
- >>> la[0]
36
- array([ 1., 2.])
37
-
38
- Bounds
39
- ------
40
-
41
- >>> line.bounds
42
- (1.0, 2.0, 3.0, 4.0)
43
-
44
- Coordinate Access
45
- -----------------
46
-
47
- >>> tuple(line.coords)
48
- ((1.0, 2.0), (3.0, 4.0))
49
-
50
- >>> line.coords[0]
51
- (1.0, 2.0)
52
- >>> line.coords[1]
53
- (3.0, 4.0)
54
- >>> line.coords[2]
55
- Traceback (most recent call last):
56
- ...
57
- IndexError: index out of range
58
-
59
- Geo interface
60
- -------------
61
-
62
- >>> line.__geo_interface__
63
- {'type': 'LineString', 'coordinates': ((1.0, 2.0), (3.0, 4.0))}
64
-
65
-
66
- Coordinate modification
67
- -----------------------
68
-
69
- >>> line.coords = ((-1.0, -1.0), (1.0, 1.0))
70
- >>> line.__geo_interface__
71
- {'type': 'LineString', 'coordinates': ((-1.0, -1.0), (1.0, 1.0))}
72
-
73
-
74
- Adapter
75
- -------
76
-
77
- >>> from shapely.geometry import asLineString
78
-
79
- Adapt a Numpy array to a line string
80
-
81
- >>> a = array([[1.0, 2.0], [3.0, 4.0]])
82
- >>> la = asLineString(a)
83
- >>> la.context
84
- array([[ 1., 2.],
85
- [ 3., 4.]])
86
-
87
- >>> la.wkt
88
- 'LINESTRING (1.0000000000000000 2.0000000000000000, 3.0000000000000000 4.0000000000000000)'
89
-
90
- Now, the inverse
91
-
92
- >>> la.__array_interface__ == la.context.__array_interface__
93
- True
94
- >>> as = asarray(la)
95
- >>> as
96
- array([[ 1., 2.],
97
- [ 3., 4.]])
98
-
99
- Adapt a coordinate list to a line string
100
-
101
- >>> coords = [[5.0, 6.0], [7.0, 8.0]]
102
- >>> la = asLineString(coords)
103
- >>> la.wkt
104
- 'LINESTRING (5.0000000000000000 6.0000000000000000, 7.0000000000000000 8.0000000000000000)'
105
-
106
- Test Non-operability of Null geometry
107
-
108
- >>> l_null = LineString()
109
- >>> l_null.wkt # doctest: +ELLIPSIS
110
- Traceback (most recent call last):
111
- ...
112
- ValueError: Null geometry supports no operations
113
-
114
- >>> l_null.length # doctest: +ELLIPSIS
115
- Traceback (most recent call last):
116
- ...
117
- ValueError: Null geometry supports no operations
118
-
119
- Check that we can set coordinates of a null geometry
120
-
121
- >>> l_null.coords = [(0, 0), (1, 1)]
122
- >>> print l_null.length # doctest: +ELLIPSIS
123
- 1.414...
124
-
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes