mirror of
https://github.com/django/django.git
synced 2025-07-03 17:29:12 +00:00
gis: geos: GEOSGeometry
objects may now be pickled; added the clone
keyword to transform
which returns a cloned transformed geometry rather than transforming in-place.
git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@7404 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
4a636ec3a3
commit
147bd6ac36
@ -87,6 +87,11 @@ class GEOSGeometry(object):
|
||||
else:
|
||||
raise GEOSException('Could not initialize GEOS Geometry with given input.')
|
||||
|
||||
# Post-initialization setup.
|
||||
self._post_init(srid)
|
||||
|
||||
def _post_init(self, srid):
|
||||
"Helper routine for performing post-initialization setup."
|
||||
# Setting the SRID, if given.
|
||||
if srid and isinstance(srid, int): self.srid = srid
|
||||
|
||||
@ -139,6 +144,20 @@ class GEOSGeometry(object):
|
||||
"Short-hand representation because WKT may be very large."
|
||||
return '<%s object at %s>' % (self.geom_type, hex(addressof(self.ptr)))
|
||||
|
||||
# Pickling support
|
||||
def __getstate__(self):
|
||||
# The pickled state is simply a tuple of the WKB (in string form)
|
||||
# and the SRID.
|
||||
return str(self.wkb), self.srid
|
||||
|
||||
def __setstate__(self, state):
|
||||
# Instantiating from the tuple state that was pickled.
|
||||
wkb, srid = state
|
||||
ptr = from_wkb(wkb, len(wkb))
|
||||
if not ptr: raise GEOSException('Invalid Geometry loaded from pickled state.')
|
||||
self._ptr = ptr
|
||||
self._post_init(srid)
|
||||
|
||||
# Comparison operators
|
||||
def __eq__(self, other):
|
||||
"""
|
||||
@ -413,23 +432,32 @@ class GEOSGeometry(object):
|
||||
"Alias for `srs` property."
|
||||
return self.srs
|
||||
|
||||
def transform(self, ct):
|
||||
"Transforms this Geometry; only works with GDAL."
|
||||
def transform(self, ct, clone=False):
|
||||
"""
|
||||
Requires GDAL. Transforms the geometry according to the given
|
||||
transformation object, which may be an integer SRID, and WKT or
|
||||
PROJ.4 string. By default, the geometry is transformed in-place and
|
||||
nothing is returned. However if the `clone` keyword is set, then this
|
||||
geometry will not be modified and a transformed clone will be returned
|
||||
instead.
|
||||
"""
|
||||
srid = self.srid
|
||||
if HAS_GDAL and srid:
|
||||
g = OGRGeometry(self.wkb, srid)
|
||||
g.transform(ct)
|
||||
wkb = str(g.wkb)
|
||||
ptr = from_wkb(wkb, len(wkb))
|
||||
if clone:
|
||||
# User wants a cloned transformed geometry returned.
|
||||
return GEOSGeometry(ptr, srid=g.srid)
|
||||
if ptr:
|
||||
# Reassigning pointer, and getting the new coordinate sequence pointer.
|
||||
# Reassigning pointer, and performing post-initialization setup
|
||||
# again due to the reassignment.
|
||||
destroy_geom(self.ptr)
|
||||
self._ptr = ptr
|
||||
self._set_cs()
|
||||
|
||||
# Some coordinate transformations do not have an SRID associated
|
||||
# with them; only set if one exists.
|
||||
if g.srid: self.srid = g.srid
|
||||
self._post_init(g.srid)
|
||||
else:
|
||||
raise GEOSException('Transformed WKB was invalid.')
|
||||
|
||||
#### Topology Routines ####
|
||||
def _topology(self, gptr):
|
||||
|
@ -703,8 +703,15 @@ class GEOSTest(unittest.TestCase):
|
||||
t2.transform(SpatialReference('EPSG:2774'))
|
||||
ct = CoordTransform(SpatialReference('WGS84'), SpatialReference(2774))
|
||||
t3.transform(ct)
|
||||
|
||||
# Testing use of the `clone` keyword.
|
||||
k1 = orig.clone()
|
||||
k2 = k1.transform(trans.srid, clone=True)
|
||||
self.assertEqual(k1, orig)
|
||||
self.assertNotEqual(k1, k2)
|
||||
|
||||
prec = 3
|
||||
for p in (t1, t2, t3):
|
||||
for p in (t1, t2, t3, k2):
|
||||
self.assertAlmostEqual(trans.x, p.x, prec)
|
||||
self.assertAlmostEqual(trans.y, p.y, prec)
|
||||
|
||||
@ -724,6 +731,27 @@ class GEOSTest(unittest.TestCase):
|
||||
xmax, ymax = max(x), max(y)
|
||||
self.assertEqual((xmin, ymin, xmax, ymax), poly.extent)
|
||||
|
||||
def test25_pickle(self):
|
||||
"Testing pickling and unpickling support."
|
||||
# Using both pickle and cPickle -- just 'cause.
|
||||
import pickle, cPickle
|
||||
|
||||
# Creating a list of test geometries for pickling,
|
||||
# and setting the SRID on some of them.
|
||||
def get_geoms(lst, srid=None):
|
||||
return [GEOSGeometry(tg.wkt, srid) for tg in lst]
|
||||
tgeoms = get_geoms(points)
|
||||
tgeoms.extend(get_geoms(multilinestrings, 4326))
|
||||
tgeoms.extend(get_geoms(polygons, 3084))
|
||||
tgeoms.extend(get_geoms(multipolygons, 900913))
|
||||
|
||||
for geom in tgeoms:
|
||||
s1, s2 = cPickle.dumps(geom), pickle.dumps(geom)
|
||||
g1, g2 = cPickle.loads(s1), pickle.loads(s2)
|
||||
for tmpg in (g1, g2):
|
||||
self.assertEqual(geom, tmpg)
|
||||
self.assertEqual(geom.srid, tmpg.srid)
|
||||
|
||||
def suite():
|
||||
s = unittest.TestSuite()
|
||||
s.addTest(unittest.makeSuite(GEOSTest))
|
||||
|
Loading…
x
Reference in New Issue
Block a user