shapely 1.0__py2.4.egg → 1.0a7__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 CHANGED
@@ -1,16 +1,16 @@
1
1
  Metadata-Version: 1.0
2
2
  Name: Shapely
3
- Version: 1.0
3
+ Version: 1.0a7
4
4
  Summary: Geospatial geometries, predicates, and operations
5
- Home-page: http://trac.gispython.org/projects/PCL/wiki/Shapely
5
+ Home-page: http://trac.gispython.org/projects/PCL/wiki/ShapeLy
6
6
  Author: Sean Gillies
7
7
  Author-email: sgillies@frii.com
8
- License: BSD
8
+ License: LGPL
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
12
+ Shapely is a Python package for programming with geospatial geometries. It is
13
+ based on GEOS (http://geos.refractions.net). Shapely 1.0 is ignorant about
14
14
  coordinate and reference systems. Projection responsibility is left to specific
15
15
  applications. For more information, see:
16
16
 
@@ -20,22 +20,21 @@ Description: Shapely
20
20
  Shapely requires Python 2.4+. (I've also begun to port it to Python 3.0:
21
21
  http://zcologia.com/news/564/shapely-for-python-3-0/.)
22
22
 
23
+ .. _wiki: http://trac.gispython.org/projects/PCL/wiki/Shapely
24
+ .. _manual: http://trac.gispython.org/projects/PCL/wiki/ShapelyManual
23
25
 
24
26
  Dependencies
25
27
  ------------
26
28
 
27
- * libgeos_c (2.2.3 or 3.0.0+)
29
+ * libgeos_c (2.2.3, also reported to work with 3.0 after small modifications.)
28
30
  * Python ctypes_ (standard in Python 2.5+)
29
31
 
30
32
  .. _ctypes: http://pypi.python.org/pypi/ctypes/
31
33
 
32
-
33
34
  Installation
34
35
  ------------
35
36
 
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::
37
+ Shapely can be installed from the Python package index::
39
38
 
40
39
  $ sudo easy_install Shapely
41
40
 
@@ -43,29 +42,26 @@ Description: Shapely
43
42
 
44
43
  $ sudo python setup.py install
45
44
 
46
- or by using the development buildout on Linux, which also provides libgeos_c::
45
+ or by using the development buildout, which also provides libgeos_c::
47
46
 
48
47
  $ svn co http://svn.gispython.org/svn/gispy/buildout/shapely.buildout/trunk shapely.buildout
49
48
  $ cd shapely.buildout
50
49
  $ python bootstrap.py
51
50
  $ ./bin/buildout
52
51
 
53
-
54
52
  Usage
55
53
  -----
56
54
 
57
- To buffer a point::
55
+ Buffer a point::
58
56
 
59
57
  >>> from shapely.geometry import Point
60
58
  >>> point = Point(-106.0, 40.0) # longitude, latitude
61
59
  >>> point.buffer(10.0)
62
60
  <shapely.geometry.polygon.Polygon object at ...>
63
61
 
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
-
62
+ See Operations.txt and Predicates.txt under tests/ for more examples of the
63
+ spatial operations and predicates provided by Shapely. Also see Point.txt,
64
+ LineString.txt, etc for examples of the geometry APIs.
69
65
 
70
66
  Numpy integration
71
67
  -----------------
@@ -87,7 +83,6 @@ Description: Shapely
87
83
  >>> line.wkt
88
84
  'LINESTRING (1.0000000000000000 2.0000000000000000, 3.0000000000000000 4.0000000000000000)'
89
85
 
90
-
91
86
  Python Geo Interface
92
87
  --------------------
93
88
 
@@ -115,7 +110,6 @@ Description: Shapely
115
110
  See http://trac.gispython.org/projects/PCL/wiki/PythonGeoInterface for more
116
111
  details on the interface.
117
112
 
118
-
119
113
  Testing
120
114
  -------
121
115
 
@@ -125,49 +119,15 @@ Description: Shapely
125
119
  $ python point.py
126
120
 
127
121
  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).
122
+ zope.testing. runalldoctests.py does not.
163
123
 
164
124
 
165
125
  Keywords: geometry topology
166
126
  Platform: UNKNOWN
167
- Classifier: Development Status :: 5 - Production/Stable
127
+ Classifier: Development Status :: 3 - Alpha
168
128
  Classifier: Intended Audience :: Developers
169
129
  Classifier: Intended Audience :: Science/Research
170
- Classifier: License :: OSI Approved :: BSD License
130
+ Classifier: License :: OSI Approved :: GNU Library or Lesser General Public License (LGPL)
171
131
  Classifier: Operating System :: OS Independent
172
132
  Classifier: Programming Language :: Python
173
133
  Classifier: Topic :: Scientific/Engineering :: GIS
EGG-INFO/SOURCES.txt CHANGED
@@ -1,10 +1,6 @@
1
- CHANGES.txt
2
1
  CREDITS.txt
3
- HISTORY.txt
4
- LICENSE.txt
5
2
  README.txt
6
3
  setup.py
7
- setup_windows.py
8
4
  Shapely.egg-info/PKG-INFO
9
5
  Shapely.egg-info/SOURCES.txt
10
6
  Shapely.egg-info/dependency_links.txt
@@ -12,8 +8,6 @@ Shapely.egg-info/requires.txt
12
8
  Shapely.egg-info/top_level.txt
13
9
  examples/geoms.py
14
10
  examples/world.py
15
- manual/manual.txt
16
- manual/style.css
17
11
  shapely/__init__.py
18
12
  shapely/geos.py
19
13
  shapely/iterops.py
@@ -45,8 +39,7 @@ tests/Point.txt
45
39
  tests/Polygon.txt
46
40
  tests/Predicates.txt
47
41
  tests/__init__.py
48
- tests/binascii_hex.txt
49
- tests/invalid_intersection.txt
42
+ tests/runalldoctests.py
50
43
  tests/rungrind.dist
44
+ tests/runtests.dist
51
45
  tests/test_doctests.py
52
- tests/valgrind-python.supp
shapely/geometry/base.py CHANGED
@@ -3,36 +3,17 @@ Base geometry class and utilities.
3
3
  """
4
4
 
5
5
  from ctypes import string_at, byref, c_int, c_size_t, c_char_p, c_double
6
- import sys
7
6
 
8
- from shapely.geos import lgeos, free, allocated_c_char_p
7
+ from shapely.geos import lgeos
9
8
  from shapely.predicates import BinaryPredicate, UnaryPredicate
10
9
  from shapely.topology import BinaryTopologicalOp, UnaryTopologicalOp
11
10
 
12
11
 
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
12
  # Abstract geometry factory for use with topological methods below
30
13
 
31
14
  def geom_factory(g):
32
- if not g:
33
- raise ValueError, "No Shapely geometry can be created from this null value"
34
15
  ob = BaseGeometry()
35
- geom_type = geometry_type_name(g)
16
+ geom_type = string_at(lgeos.GEOSGeomType(g))
36
17
  # TODO: check cost of dynamic import by profiling
37
18
  mod = __import__(
38
19
  'shapely.geometry',
@@ -158,42 +139,23 @@ class GeometrySequence(object):
158
139
  max = l
159
140
 
160
141
 
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
142
  class BaseGeometry(object):
181
143
 
182
144
  """Provides GEOS spatial predicates and topological operations.
183
145
  """
184
146
 
185
- __geom = None # See _geom property below
147
+ _geom = None
186
148
  _ctypes_data = None
187
149
  _ndim = None
188
150
  _crs = None
189
151
  _owned = False
190
152
 
191
153
  def __init__(self):
192
- self.__geom = None
154
+ self._geom = lgeos.GEOSGeomFromWKT(c_char_p('GEOMETRYCOLLECTION EMPTY'))
193
155
 
194
156
  def __del__(self):
195
- if self.__geom is not None and not self._owned:
196
- lgeos.GEOSGeom_destroy(self.__geom)
157
+ if self._geom is not None and not self._owned:
158
+ lgeos.GEOSGeom_destroy(self._geom)
197
159
 
198
160
  def __str__(self):
199
161
  return self.to_wkt()
@@ -210,20 +172,11 @@ class BaseGeometry(object):
210
172
  return (self.__class__, (), self.to_wkb())
211
173
 
212
174
  def __setstate__(self, state):
213
- self.__geom = lgeos.GEOSGeomFromWKB_buf(
175
+ self._geom = lgeos.GEOSGeomFromWKB_buf(
214
176
  c_char_p(state),
215
177
  c_size_t(len(state))
216
178
  )
217
179
 
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
180
  # Array and ctypes interfaces
228
181
 
229
182
  @property
@@ -233,26 +186,11 @@ class BaseGeometry(object):
233
186
  To be overridden by extension classes."""
234
187
  raise NotImplementedError
235
188
 
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
189
  @property
251
190
  def __array_interface__(self):
252
191
  """Provide the Numpy array protocol."""
253
192
  raise NotImplementedError
254
193
 
255
- @exceptNull
256
194
  def get_coords(self):
257
195
  return CoordinateSequence(self)
258
196
 
@@ -274,34 +212,19 @@ class BaseGeometry(object):
274
212
 
275
213
  # Type of geometry and its representations
276
214
 
277
- @exceptNull
278
215
  def geometryType(self):
279
216
  """Returns a string representing the geometry type, e.g. 'Polygon'."""
280
- return geometry_type_name(self._geom)
217
+ return string_at(lgeos.GEOSGeomType(self._geom))
281
218
 
282
- @exceptNull
283
219
  def to_wkb(self):
284
220
  """Returns a WKB byte string representation of the geometry."""
285
- func = lgeos.GEOSGeomToWKB_buf
286
221
  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
222
+ bytes = lgeos.GEOSGeomToWKB_buf(self._geom, byref(size))
223
+ return string_at(bytes, size.value)
224
+
295
225
  def to_wkt(self):
296
226
  """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)
227
+ return string_at(lgeos.GEOSGeomToWKT(self._geom))
305
228
 
306
229
  geom_type = property(geometryType)
307
230
  wkt = property(to_wkt)
@@ -310,20 +233,17 @@ class BaseGeometry(object):
310
233
  # Basic geometry properties
311
234
 
312
235
  @property
313
- @exceptNull
314
236
  def area(self):
315
237
  a = c_double()
316
238
  retval = lgeos.GEOSArea(self._geom, byref(a))
317
239
  return a.value
318
240
 
319
241
  @property
320
- @exceptNull
321
242
  def length(self):
322
243
  len = c_double()
323
244
  retval = lgeos.GEOSLength(self._geom, byref(len))
324
245
  return len.value
325
246
 
326
- @exceptEitherNull
327
247
  def distance(self, other):
328
248
  d = c_double()
329
249
  retval = lgeos.GEOSDistance(self._geom, other._geom, byref(d))
@@ -344,22 +264,15 @@ class BaseGeometry(object):
344
264
  centroid = UnaryTopologicalOp(lgeos.GEOSGetCentroid, geom_factory)
345
265
 
346
266
  # Buffer has a unique distance argument, so not a descriptor
347
- @exceptNull
348
267
  def buffer(self, distance, quadsegs=16):
349
268
  return geom_factory(
350
269
  lgeos.GEOSBuffer(self._geom, c_double(distance), c_int(quadsegs))
351
270
  )
352
271
 
353
272
  # Relate has a unique string return value
354
- @exceptNull
355
273
  def relate(self, other):
356
274
  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
275
+ func.restype = c_char_p
363
276
  return lgeos.GEOSRelate(self._geom, other._geom)
364
277
 
365
278
  # Binary predicates
@@ -387,7 +300,6 @@ class BaseGeometry(object):
387
300
  has_z = UnaryPredicate(lgeos.GEOSHasZ)
388
301
 
389
302
  @property
390
- @exceptNull
391
303
  def bounds(self):
392
304
  env = self.envelope
393
305
  if env.geom_type != 'Polygon':
shapely/geometry/base.pyc CHANGED
Binary file
@@ -6,7 +6,7 @@ from ctypes import byref, c_double, c_int, cast, POINTER, pointer
6
6
  from ctypes import ArgumentError
7
7
 
8
8
  from shapely.geos import lgeos
9
- from shapely.geometry.base import BaseGeometry, exceptNull
9
+ from shapely.geometry.base import BaseGeometry
10
10
 
11
11
 
12
12
  def geos_linestring_from_py(ob, update_geom=None, update_ndim=0):
@@ -86,7 +86,7 @@ def geos_linestring_from_py(ob, update_geom=None, update_ndim=0):
86
86
  if update_geom is not None:
87
87
  return None
88
88
  else:
89
- return lgeos.GEOSGeom_createLineString(cs), n
89
+ return (lgeos.GEOSGeom_createLineString(cs), n)
90
90
 
91
91
  def update_linestring_from_py(geom, ob):
92
92
  geos_linestring_from_py(ob, geom._geom, geom._ndim)
@@ -118,9 +118,7 @@ class LineString(BaseGeometry):
118
118
  Each result in a line string from (0.0, 0.0) to (1.0, 2.0).
119
119
  """
120
120
  BaseGeometry.__init__(self)
121
- self._init_geom(coordinates)
122
121
 
123
- def _init_geom(self, coordinates):
124
122
  if coordinates is None:
125
123
  # allow creation of null lines, to support unpickling
126
124
  pass
@@ -135,7 +133,6 @@ class LineString(BaseGeometry):
135
133
  }
136
134
 
137
135
  @property
138
- @exceptNull
139
136
  def ctypes(self):
140
137
  if not self._ctypes_data:
141
138
  cs = lgeos.GEOSGeom_getCoordSeq(self._geom)
@@ -157,18 +154,19 @@ class LineString(BaseGeometry):
157
154
  self._ctypes_data = data
158
155
  return self._ctypes_data
159
156
 
160
- def array_interface(self):
157
+ @property
158
+ def __array_interface__(self):
161
159
  """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)
160
+ return {
161
+ 'version': 3,
162
+ 'shape': (len(self.coords), self._ndim),
163
+ 'typestr': '<f8',
164
+ 'data': self.ctypes,
165
+ }
166
166
 
167
167
  # Coordinate access
168
168
 
169
169
  def set_coords(self, coordinates):
170
- if self._geom is None:
171
- self._init_geom(coordinates)
172
170
  update_linestring_from_py(self, coordinates)
173
171
 
174
172
  coords = property(BaseGeometry.get_coords, set_coords)
@@ -181,12 +179,14 @@ class LineStringAdapter(LineString):
181
179
  """
182
180
 
183
181
  context = None
184
- __geom = None
185
- _owned = False
186
182
 
187
183
  def __init__(self, context):
188
184
  self.context = context
189
185
 
186
+ # Override base class __del__
187
+ def __del__(self):
188
+ pass
189
+
190
190
  @property
191
191
  def _ndim(self):
192
192
  try:
@@ -202,10 +202,7 @@ class LineStringAdapter(LineString):
202
202
  @property
203
203
  def _geom(self):
204
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
205
+ return geos_linestring_from_py(self.context)[0]
209
206
 
210
207
  @property
211
208
  def __array_interface__(self):
@@ -213,7 +210,12 @@ class LineStringAdapter(LineString):
213
210
  try:
214
211
  return self.context.__array_interface__
215
212
  except AttributeError:
216
- return self.array_interface()
213
+ return {
214
+ 'version': 3,
215
+ 'shape': (self._ndim,),
216
+ 'typestr': '<f8',
217
+ 'data': self.ctypes,
218
+ }
217
219
 
218
220
  coords = property(BaseGeometry.get_coords)
219
221
 
Binary file
@@ -5,7 +5,7 @@ Multi-part collection of linestrings.
5
5
  from ctypes import byref, c_double, c_int, c_void_p, cast, POINTER, pointer
6
6
 
7
7
  from shapely.geos import lgeos
8
- from shapely.geometry.base import BaseGeometry, GeometrySequence, exceptNull
8
+ from shapely.geometry.base import BaseGeometry, GeometrySequence
9
9
  from shapely.geometry.linestring import LineString, geos_linestring_from_py
10
10
 
11
11
 
@@ -102,7 +102,6 @@ class MultiLineString(BaseGeometry):
102
102
  "Multi-part geometries do not provide a coordinate sequence"
103
103
 
104
104
  @property
105
- @exceptNull
106
105
  def geoms(self):
107
106
  return GeometrySequence(self, LineString)
108
107
 
@@ -114,12 +113,14 @@ class MultiLineStringAdapter(MultiLineString):
114
113
  """
115
114
 
116
115
  context = None
117
- __geom = None
118
- _owned = False
119
116
 
120
117
  def __init__(self, context):
121
118
  self.context = context
122
119
 
120
+ # Override base class __del__
121
+ def __del__(self):
122
+ pass
123
+
123
124
  @property
124
125
  def _ndim(self):
125
126
  try:
@@ -135,10 +136,7 @@ class MultiLineStringAdapter(MultiLineString):
135
136
  @property
136
137
  def _geom(self):
137
138
  """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
139
+ return geos_multilinestring_from_py(self.context)[0]
142
140
 
143
141
 
144
142
  def asMultiLineString(context):
Binary file
@@ -5,7 +5,7 @@ Multiple points.
5
5
  from ctypes import byref, c_double, c_int, c_void_p, cast, POINTER, pointer
6
6
 
7
7
  from shapely.geos import lgeos
8
- from shapely.geometry.base import BaseGeometry, GeometrySequence, exceptNull
8
+ from shapely.geometry.base import BaseGeometry, GeometrySequence
9
9
  from shapely.geometry.point import Point, geos_point_from_py
10
10
 
11
11
 
@@ -44,7 +44,7 @@ def geos_multipoint_from_py(ob):
44
44
  geom, ndims = geos_point_from_py(coords)
45
45
  subs[i] = cast(geom, c_void_p)
46
46
 
47
- return lgeos.GEOSGeom_createCollection(4, subs, m), n
47
+ return (lgeos.GEOSGeom_createCollection(4, subs, m), n)
48
48
 
49
49
 
50
50
  class MultiPoint(BaseGeometry):
@@ -81,7 +81,6 @@ class MultiPoint(BaseGeometry):
81
81
 
82
82
 
83
83
  @property
84
- @exceptNull
85
84
  def __geo_interface__(self):
86
85
  return {
87
86
  'type': 'MultiPoint',
@@ -89,7 +88,6 @@ class MultiPoint(BaseGeometry):
89
88
  }
90
89
 
91
90
  @property
92
- @exceptNull
93
91
  def ctypes(self):
94
92
  if not self._ctypes_data:
95
93
  temp = c_double()
@@ -110,13 +108,15 @@ class MultiPoint(BaseGeometry):
110
108
  self._ctypes_data = data
111
109
  return self._ctypes_data
112
110
 
113
- @exceptNull
114
- def array_interface(self):
111
+ @property
112
+ def __array_interface__(self):
115
113
  """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)
114
+ return {
115
+ 'version': 3,
116
+ 'shape': (len(self.geoms), self._ndim),
117
+ 'typestr': '<f8',
118
+ 'data': self.ctypes,
119
+ }
120
120
 
121
121
  @property
122
122
  def coords(self):
@@ -124,7 +124,6 @@ class MultiPoint(BaseGeometry):
124
124
  "Multipart geometries do not themselves provide coordinate sequences"
125
125
 
126
126
  @property
127
- @exceptNull
128
127
  def geoms(self):
129
128
  return GeometrySequence(self, Point)
130
129
 
@@ -136,12 +135,14 @@ class MultiPointAdapter(MultiPoint):
136
135
  """
137
136
 
138
137
  context = None
139
- __geom = None
140
- _owned = False
141
138
 
142
139
  def __init__(self, context):
143
140
  self.context = context
144
141
 
142
+ # Override base class __del__
143
+ def __del__(self):
144
+ pass
145
+
145
146
  @property
146
147
  def _ndim(self):
147
148
  try:
@@ -157,10 +158,7 @@ class MultiPointAdapter(MultiPoint):
157
158
  @property
158
159
  def _geom(self):
159
160
  """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
161
+ return geos_multipoint_from_py(self.context)[0]
164
162
 
165
163
  @property
166
164
  def __array_interface__(self):
@@ -168,7 +166,12 @@ class MultiPointAdapter(MultiPoint):
168
166
  try:
169
167
  return self.context.__array_interface__
170
168
  except AttributeError:
171
- return self.array_interface()
169
+ return {
170
+ 'version': 3,
171
+ 'shape': (self._ndim,),
172
+ 'typestr': '<f8',
173
+ 'data': self.ctypes,
174
+ }
172
175
 
173
176
 
174
177
  def asMultiPoint(context):
Binary file
@@ -5,7 +5,7 @@ Multi-part collection of polygons.
5
5
  from ctypes import byref, c_double, c_int, c_void_p, cast, POINTER, pointer
6
6
 
7
7
  from shapely.geos import lgeos
8
- from shapely.geometry.base import BaseGeometry, GeometrySequence, exceptNull
8
+ from shapely.geometry.base import BaseGeometry, GeometrySequence
9
9
  from shapely.geometry.polygon import Polygon, geos_polygon_from_py
10
10
 
11
11
 
@@ -88,7 +88,6 @@ class MultiPolygon(BaseGeometry):
88
88
  "Multi-part geometries do not provide a coordinate sequence"
89
89
 
90
90
  @property
91
- @exceptNull
92
91
  def geoms(self):
93
92
  return GeometrySequence(self, Polygon)
94
93
 
@@ -100,12 +99,14 @@ class MultiPolygonAdapter(MultiPolygon):
100
99
  """
101
100
 
102
101
  context = None
103
- __geom = None
104
- _owned = False
105
102
 
106
103
  def __init__(self, context):
107
104
  self.context = context
108
105
 
106
+ # Override base class __del__
107
+ def __del__(self):
108
+ pass
109
+
109
110
  @property
110
111
  def _ndim(self):
111
112
  try:
@@ -121,10 +122,7 @@ class MultiPolygonAdapter(MultiPolygon):
121
122
  @property
122
123
  def _geom(self):
123
124
  """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
125
+ return geos_multipolygon_from_py(self.context)[0]
128
126
 
129
127
 
130
128
  def asMultiPolygon(context):
Binary file
shapely/geometry/point.py CHANGED
@@ -9,7 +9,6 @@ from ctypes import cast, POINTER
9
9
 
10
10
  from shapely.geos import lgeos, DimensionError
11
11
  from shapely.geometry.base import BaseGeometry, CoordinateSequence
12
- from shapely.geometry.base import exceptNull
13
12
 
14
13
 
15
14
  def geos_point_from_py(ob, update_geom=None, update_ndim=0):
@@ -34,12 +33,8 @@ def geos_point_from_py(ob, update_geom=None, update_ndim=0):
34
33
  dz = c_double(cp[2])
35
34
  ndim = 3
36
35
  except AttributeError:
37
- # Fall back on the case of Python sequence data
38
- # Accept either (x, y) or [(x, y)]
39
- if type(ob[0]) == type(tuple()):
40
- coords = ob[0]
41
- else:
42
- coords = ob
36
+ # Fall back on list
37
+ coords = ob
43
38
  n = len(coords)
44
39
  dx = c_double(coords[0])
45
40
  dy = c_double(coords[1])
@@ -65,7 +60,7 @@ def geos_point_from_py(ob, update_geom=None, update_ndim=0):
65
60
  if update_geom:
66
61
  return None
67
62
  else:
68
- return lgeos.GEOSGeom_createPoint(cs), n
63
+ return (lgeos.GEOSGeom_createPoint(cs), n)
69
64
 
70
65
  def update_point_from_py(geom, ob):
71
66
  geos_point_from_py(ob, geom._geom, geom._ndim)
@@ -107,9 +102,7 @@ class Point(BaseGeometry):
107
102
  Easting, northing, and elevation.
108
103
  """
109
104
  BaseGeometry.__init__(self)
110
- self._init_geom(*args)
111
105
 
112
- def _init_geom(self, *args):
113
106
  if len(args) == 0:
114
107
  # allow creation of null points, to support unpickling
115
108
  pass
@@ -122,7 +115,6 @@ class Point(BaseGeometry):
122
115
  # Coordinate getters and setters
123
116
 
124
117
  @property
125
- @exceptNull
126
118
  def x(self):
127
119
  """Return x coordinate."""
128
120
  cs = lgeos.GEOSGeom_getCoordSeq(self._geom)
@@ -131,7 +123,6 @@ class Point(BaseGeometry):
131
123
  return d.value
132
124
 
133
125
  @property
134
- @exceptNull
135
126
  def y(self):
136
127
  """Return y coordinate."""
137
128
  cs = lgeos.GEOSGeom_getCoordSeq(self._geom)
@@ -140,7 +131,6 @@ class Point(BaseGeometry):
140
131
  return d.value
141
132
 
142
133
  @property
143
- @exceptNull
144
134
  def z(self):
145
135
  """Return z coordinate."""
146
136
  if self._ndim != 3:
@@ -151,7 +141,6 @@ class Point(BaseGeometry):
151
141
  return d.value
152
142
 
153
143
  @property
154
- @exceptNull
155
144
  def __geo_interface__(self):
156
145
  return {
157
146
  'type': 'Point',
@@ -159,7 +148,6 @@ class Point(BaseGeometry):
159
148
  }
160
149
 
161
150
  @property
162
- @exceptNull
163
151
  def ctypes(self):
164
152
  if not self._ctypes_data:
165
153
  array_type = c_double * self._ndim
@@ -171,15 +159,17 @@ class Point(BaseGeometry):
171
159
  self._ctypes_data = array
172
160
  return self._ctypes_data
173
161
 
174
- def array_interface(self):
162
+ @property
163
+ def __array_interface__(self):
175
164
  """Provide the Numpy array protocol."""
176
- ai = self.array_interface_base
177
- ai.update({'shape': (self._ndim,)})
178
- return ai
179
- __array_interface__ = property(array_interface)
165
+ return {
166
+ 'version': 3,
167
+ 'shape': (self._ndim,),
168
+ 'typestr': '<f8',
169
+ 'data': self.ctypes,
170
+ }
180
171
 
181
172
  @property
182
- @exceptNull
183
173
  def bounds(self):
184
174
  cs = lgeos.GEOSGeom_getCoordSeq(self._geom)
185
175
  x = c_double()
@@ -191,10 +181,7 @@ class Point(BaseGeometry):
191
181
  # Coordinate access
192
182
 
193
183
  def set_coords(self, coordinates):
194
- if self._geom is None:
195
- self._init_geom(coordinates)
196
- else:
197
- update_point_from_py(self, coordinates)
184
+ update_point_from_py(self, coordinates)
198
185
 
199
186
  coords = property(BaseGeometry.get_coords, set_coords)
200
187
 
@@ -205,12 +192,14 @@ class PointAdapter(Point):
205
192
  """
206
193
 
207
194
  context = None
208
- __geom = None
209
- _owned = False
210
195
 
211
196
  def __init__(self, context):
212
197
  self.context = context
213
198
 
199
+ # Override base class __del__
200
+ def __del__(self):
201
+ pass
202
+
214
203
  @property
215
204
  def _ndim(self):
216
205
  try:
@@ -226,10 +215,7 @@ class PointAdapter(Point):
226
215
  @property
227
216
  def _geom(self):
228
217
  """Keeps the GEOS geometry in synch with the context."""
229
- if self.__geom is not None:
230
- lgeos.GEOSGeom_destroy(self.__geom)
231
- self.__geom, n = geos_point_from_py(self.context)
232
- return self.__geom
218
+ return geos_point_from_py(self.context)[0]
233
219
 
234
220
  # TODO: reimplement x, y, z properties without calling invoking _geom
235
221
 
@@ -239,11 +225,15 @@ class PointAdapter(Point):
239
225
  try:
240
226
  return self.context.__array_interface__
241
227
  except AttributeError:
242
- return self.array_interface()
228
+ return {
229
+ 'version': 3,
230
+ 'shape': (self._ndim,),
231
+ 'typestr': '<f8',
232
+ 'data': self.ctypes,
233
+ }
243
234
 
244
235
  coords = property(BaseGeometry.get_coords)
245
236
 
246
-
247
237
  def asPoint(context):
248
238
  """Factory for PointAdapter instances."""
249
239
  return PointAdapter(context)
Binary file
@@ -5,7 +5,7 @@ Polygons and their linear ring components.
5
5
  from ctypes import byref, c_double, c_int, c_void_p, cast, POINTER, pointer
6
6
 
7
7
  from shapely.geos import lgeos
8
- from shapely.geometry.base import BaseGeometry, exceptNull
8
+ from shapely.geometry.base import BaseGeometry
9
9
  from shapely.geometry.linestring import LineString, LineStringAdapter
10
10
 
11
11
 
@@ -129,7 +129,7 @@ def geos_linearring_from_py(ob, update_geom=None, update_ndim=0):
129
129
  if update_geom is not None:
130
130
  return None
131
131
  else:
132
- return lgeos.GEOSGeom_createLinearRing(cs), n
132
+ return (lgeos.GEOSGeom_createLinearRing(cs), n)
133
133
 
134
134
  def update_linearring_from_py(geom, ob):
135
135
  geos_linearring_from_py(ob, geom._geom, geom._ndim)
@@ -141,8 +141,6 @@ class LinearRing(LineString):
141
141
  """
142
142
 
143
143
  _ndim = 2
144
- __geom = None
145
- _owned = False
146
144
 
147
145
  def __init__(self, coordinates=None):
148
146
  """Initialize.
@@ -164,9 +162,7 @@ class LinearRing(LineString):
164
162
  Produces a 1x1 square.
165
163
  """
166
164
  BaseGeometry.__init__(self)
167
- self._init_geom(coordinates)
168
165
 
169
- def _init_geom(self, coordinates):
170
166
  if coordinates is None:
171
167
  # allow creation of null lines, to support unpickling
172
168
  pass
@@ -183,8 +179,6 @@ class LinearRing(LineString):
183
179
  # Coordinate access
184
180
 
185
181
  def set_coords(self, coordinates):
186
- if self._geom is None:
187
- self._init_geom(coordinates)
188
182
  update_linearring_from_py(self, coordinates)
189
183
 
190
184
  coords = property(BaseGeometry.get_coords, set_coords)
@@ -192,17 +186,10 @@ class LinearRing(LineString):
192
186
 
193
187
  class LinearRingAdapter(LineStringAdapter):
194
188
 
195
- context = None
196
- __geom = None
197
- _owned = False
198
-
199
189
  @property
200
190
  def _geom(self):
201
191
  """Keeps the GEOS geometry in synch with the context."""
202
- if self.__geom is not None:
203
- lgeos.GEOSGeom_destroy(self.__geom)
204
- self.__geom, n = geos_linearring_from_py(self.context)
205
- return self.__geom
192
+ return geos_linearring_from_py(self.context)[0]
206
193
 
207
194
  @property
208
195
  def __geo_interface__(self):
@@ -273,6 +260,9 @@ class InteriorRingSequence(object):
273
260
  def geos_polygon_from_py(shell, holes=None):
274
261
  if shell is not None:
275
262
  geos_shell, ndims = geos_linearring_from_py(shell)
263
+ ## Polygon geometry takes ownership of the ring
264
+ #self._exterior._owned = True
265
+
276
266
  if holes:
277
267
  ob = holes
278
268
  L = len(ob)
@@ -312,8 +302,6 @@ class Polygon(BaseGeometry):
312
302
  _exterior = None
313
303
  _interiors = []
314
304
  _ndim = 2
315
- __geom = None
316
- _owned = False
317
305
 
318
306
  def __init__(self, shell=None, holes=None):
319
307
  """Initialize.
@@ -336,7 +324,6 @@ class Polygon(BaseGeometry):
336
324
  self._geom, self._ndims = geos_polygon_from_py(shell, holes)
337
325
 
338
326
  @property
339
- @exceptNull
340
327
  def exterior(self):
341
328
  if self._exterior is None:
342
329
  # A polygon created from the abstract factory will have a null
@@ -348,7 +335,6 @@ class Polygon(BaseGeometry):
348
335
  return self._exterior
349
336
 
350
337
  @property
351
- @exceptNull
352
338
  def interiors(self):
353
339
  return InteriorRingSequence(self)
354
340
 
@@ -386,13 +372,15 @@ class PolygonAdapter(Polygon):
386
372
  """
387
373
 
388
374
  context = None
389
- __geom = None
390
- _owned = False
391
375
 
392
376
  def __init__(self, shell, holes=None):
393
377
  self.shell = shell
394
378
  self.holes = holes
395
379
 
380
+ # Override base class __del__
381
+ def __del__(self):
382
+ pass
383
+
396
384
  @property
397
385
  def _ndim(self):
398
386
  try:
@@ -408,13 +396,10 @@ class PolygonAdapter(Polygon):
408
396
  @property
409
397
  def _geom(self):
410
398
  """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
399
+ return geos_polygon_from_py(self.shell, self.holes)[0]
415
400
 
416
401
 
417
- def asPolygon(shell, holes=None):
402
+ def asPolygon(shell, holes):
418
403
  """Factory for PolygonAdapter instances."""
419
404
  return PolygonAdapter(shell, holes)
420
405
 
Binary file
shapely/geos.py CHANGED
@@ -3,31 +3,21 @@ Exports the libgeos_c shared lib, GEOS-specific exceptions, and utilities.
3
3
  """
4
4
 
5
5
  import atexit
6
- from ctypes import cdll, CDLL, CFUNCTYPE, c_char_p
6
+ from ctypes import CDLL, CFUNCTYPE, c_char_p
7
7
  from ctypes.util import find_library
8
- import os
9
8
  import sys
10
9
 
11
- import shapely
12
-
13
10
  if sys.platform == 'win32':
14
11
  try:
15
- local_dlls = os.path.abspath(os.__file__ + "../../../DLLs")
16
- original_path = os.environ['PATH']
17
- os.environ['PATH'] = "%s;%s" % (local_dlls, original_path)
18
- lgeos = CDLL("geos.dll")
12
+ lgeos = CDLL('libgeos_c.dll')
19
13
  except (ImportError, WindowsError):
14
+ # Try GEOS DLL from the Windows PostGIS installer for
15
+ # PostgreSQL 8.2 before failing
16
+ lgeos = CDLL('libgeos_c-1.dll')
17
+ except:
20
18
  raise
21
- def free(m):
22
- try:
23
- cdll.msvcrt.free(m)
24
- except WindowsError:
25
- # XXX: See http://trac.gispython.org/projects/PCL/ticket/149
26
- pass
27
-
28
19
  elif sys.platform == 'darwin':
29
20
  lgeos = CDLL(find_library('geos_c'))
30
- free = CDLL(find_library('libc')).free
31
21
  else:
32
22
  # Try the major versioned name first, falling back on the unversioned name.
33
23
  try:
@@ -36,12 +26,6 @@ else:
36
26
  lgeos = CDLL('libgeos_c.so')
37
27
  except:
38
28
  raise
39
- free = CDLL('libc.so.6').free
40
-
41
-
42
- class allocated_c_char_p(c_char_p):
43
- pass
44
-
45
29
 
46
30
  # Exceptions
47
31
 
shapely/geos.pyc CHANGED
Binary file
shapely/iterops.py CHANGED
@@ -2,7 +2,7 @@
2
2
  """
3
3
 
4
4
  from ctypes import c_char_p, c_size_t
5
- from shapely.geos import lgeos, free
5
+ from shapely.geos import lgeos
6
6
 
7
7
 
8
8
  def geos_from_geometry(geom):
@@ -28,22 +28,20 @@ class BinaryPredicateIterator(object):
28
28
  return self
29
29
 
30
30
  def __call__(self, geom, iterator, value=True):
31
- if geom._geom is None:
32
- raise ValueError, "Null geometry supports no operations"
31
+ geos_geom = geos_from_geometry(geom)
33
32
  for item in iterator:
34
33
  try:
35
- this_geom, ob = item
34
+ geom, ob = item
36
35
  except TypeError:
37
- this_geom = item
38
- ob = this_geom
39
- if this_geom._geom is None:
40
- raise ValueError, "Null geometry supports no operations"
41
- retval = self.fn(geom._geom, this_geom._geom)
36
+ geom = item
37
+ ob = geom
38
+ retval = self.fn(geos_geom, geos_from_geometry(geom))
42
39
  if retval == 2:
43
40
  raise PredicateError, "Failed to evaluate %s" % repr(self.fn)
44
41
  elif bool(retval) == value:
45
42
  yield ob
46
43
 
44
+
47
45
  # utilities
48
46
  disjoint = BinaryPredicateIterator(lgeos.GEOSDisjoint)
49
47
  touches = BinaryPredicateIterator(lgeos.GEOSTouches)
shapely/iterops.pyc CHANGED
Binary file
shapely/json.py ADDED
@@ -0,0 +1,47 @@
1
+ """
2
+ Load/dump geometries using JSON.
3
+
4
+ Includes a JSON-based abstract geometry factory.
5
+ """
6
+
7
+ import geojson
8
+
9
+ def json_factory(ob):
10
+ """Attempts to create a geometry from JSON.
11
+
12
+ Else, returns the original data.
13
+ """
14
+ try:
15
+ coords = ob.get('coordinates', [])
16
+ geom_type = str(ob.get('type'))
17
+ mod = __import__(
18
+ 'shapely.geometry',
19
+ globals(),
20
+ locals(),
21
+ [geom_type],
22
+ )
23
+ geom_class = getattr(mod, geom_type)
24
+ return geom_class(*coords)
25
+ except (KeyError, TypeError):
26
+ raise
27
+ return ob
28
+
29
+ # Pickle-like convenience functions
30
+
31
+ def loads(data):
32
+ """Load a geometry from a GeoJSON representation."""
33
+ return geojson.loads(data, json_factory)
34
+
35
+ def load(fp):
36
+ """Load a geometry from an open file."""
37
+ data = fp.read()
38
+ return loads(data)
39
+
40
+ def dumps(ob):
41
+ """Dump a GeoJSON representation of a geometry to a string."""
42
+ return geojson.dumps(ob)
43
+
44
+ def dump(ob, fp):
45
+ """Dump a geometry to an open file."""
46
+ fp.write(dumps(ob))
47
+
shapely/json.pyc ADDED
Binary file
shapely/predicates.py CHANGED
@@ -16,20 +16,16 @@ class BinaryPredicate(object):
16
16
 
17
17
  def __init__(self, fn):
18
18
  self.fn = fn
19
- def errcheck(result, func, argtuple):
20
- if result == 2:
21
- raise PredicateError, "Failed to evaluate %s" % repr(self.fn)
22
- return result
23
- self.fn.errcheck = errcheck
24
19
 
25
20
  def __get__(self, obj, objtype=None):
26
21
  self.context = obj
27
22
  return self
28
23
 
29
24
  def __call__(self, other):
30
- if self.context._geom is None or other._geom is None:
31
- raise ValueError, "Null geometry supports no operations"
32
- return bool(self.fn(self.context._geom, other._geom))
25
+ retval = self.fn(self.context._geom, other._geom)
26
+ if retval == 2:
27
+ raise PredicateError, "Failed to evaluate %s" % repr(self.fn)
28
+ return bool(retval)
33
29
 
34
30
 
35
31
  # A data descriptor
@@ -42,16 +38,12 @@ class UnaryPredicate(object):
42
38
 
43
39
  def __init__(self, fn):
44
40
  self.fn = fn
45
- def errcheck(result, func, argtuple):
46
- if result == 2:
47
- raise PredicateError, "Failed to evaluate %s" % repr(self.fn)
48
- return result
49
- self.fn.errcheck = errcheck
50
41
 
51
42
  def __get__(self, obj, objtype=None):
52
- if obj._geom is None:
53
- raise ValueError, "Null geometry supports no operations"
54
- return bool(self.fn(obj._geom))
43
+ retval = self.fn(obj._geom)
44
+ if retval == 2:
45
+ raise PredicateError, "Failed to evaluate %s" % repr(self.fn)
46
+ return bool(retval)
55
47
 
56
48
  def __set__(self, obj, value=None):
57
49
  raise AttributeError, "Attribute is read-only"
shapely/predicates.pyc CHANGED
Binary file
shapely/topology.py CHANGED
@@ -26,19 +26,7 @@ class BinaryTopologicalOp(object):
26
26
  return self
27
27
 
28
28
  def __call__(self, other):
29
- if self.context._geom is None or other._geom is None:
30
- raise ValueError, "Null geometry supports no operations"
31
- product = self.fn(self.context._geom, other._geom)
32
- if not product:
33
- # Check validity of geometries
34
- if not self.context.is_valid:
35
- raise TopologicalError, \
36
- "The operation '%s' produced a null geometry. Likely cause is invalidity of the geometry %s" % (self.fn.__name__, repr(self.context))
37
- elif not other.is_valid:
38
- raise TopologicalError, \
39
- "The operation '%s' produced a null geometry. Likely cause is invalidity of the 'other' geometry %s" % (self.fn.__name__, repr(other))
40
-
41
- return self.factory(product)
29
+ return self.factory(self.fn(self.context._geom, other._geom))
42
30
 
43
31
 
44
32
  class UnaryTopologicalOp(object):
@@ -57,8 +45,6 @@ class UnaryTopologicalOp(object):
57
45
  self.factory = factory
58
46
 
59
47
  def __get__(self, obj, objtype=None):
60
- if obj._geom is None:
61
- raise ValueError, "Null geometry supports no operations"
62
48
  return self.factory(self.fn(obj._geom))
63
49
 
64
50
  def __set__(self, obj, value=None):
shapely/topology.pyc CHANGED
Binary file
shapely/wkb.py CHANGED
@@ -4,7 +4,7 @@ Load/dump geometries using the well-known binary (WKB) format.
4
4
 
5
5
  from ctypes import byref, c_int, c_size_t, c_char_p, string_at
6
6
 
7
- from shapely.geos import lgeos, free, ReadingError
7
+ from shapely.geos import lgeos, ReadingError
8
8
  from shapely.geometry.base import geom_factory
9
9
 
10
10
 
@@ -25,14 +25,9 @@ def load(fp):
25
25
 
26
26
  def dumps(ob):
27
27
  """Dump a WKB representation of a geometry to a byte string."""
28
- func = lgeos.GEOSGeomToWKB_buf
29
28
  size = c_int()
30
- def errcheck(result, func, argtuple):
31
- retval = string_at(result, size.value)[:]
32
- free(result)
33
- return retval
34
- func.errcheck = errcheck
35
- return func(ob._geom, byref(size))
29
+ bytes = lgeos.GEOSGeomToWKB_buf(ob._geom, byref(size))
30
+ return string_at(bytes, size.value)
36
31
 
37
32
  def dump(ob, fp):
38
33
  """Dump a geometry to an open file."""
shapely/wkb.pyc CHANGED
Binary file
shapely/wkt.py CHANGED
@@ -4,7 +4,7 @@ Load/dump geometries using the well-known text (WKT) format.
4
4
 
5
5
  from ctypes import byref, c_int, c_size_t, c_char_p, string_at
6
6
 
7
- from shapely.geos import lgeos, free, allocated_c_char_p, ReadingError
7
+ from shapely.geos import lgeos, ReadingError
8
8
  from shapely.geometry.base import geom_factory
9
9
 
10
10
 
@@ -25,14 +25,7 @@ def load(fp):
25
25
 
26
26
  def dumps(ob):
27
27
  """Dump a WKB representation of a geometry to a byte string."""
28
- func = lgeos.GEOSGeomToWKT
29
- def errcheck(result, func, argtuple):
30
- retval = result.value
31
- free(result)
32
- return retval
33
- func.restype = allocated_c_char_p
34
- func.errcheck = errcheck
35
- return lgeos.GEOSGeomToWKT(ob._geom)
28
+ return string_at(lgeos.GEOSGeomToWKT(ob._geom))
36
29
 
37
30
  def dump(ob, fp):
38
31
  """Dump a geometry to an open file."""
shapely/wkt.pyc CHANGED
Binary file
File without changes