From cc0cc9fa088b4fb61226a4b2443921fe329e8f2c Mon Sep 17 00:00:00 2001 From: Justin Bronn Date: Tue, 4 Dec 2007 15:09:06 +0000 Subject: [PATCH] gis: geos: Added support for EWKT (SRID only), and a `transform` routine that uses the GDAL facilities to transform the GEOS geometry. git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@6884 bcc190cf-cafb-0310-a4f2-bffc1f526a37 --- django/contrib/gis/geos/base.py | 34 +++++++++++++++++++++++---- django/contrib/gis/tests/test_geos.py | 10 ++++++++ 2 files changed, 39 insertions(+), 5 deletions(-) diff --git a/django/contrib/gis/geos/base.py b/django/contrib/gis/geos/base.py index 1a2555bc16..51a3e366db 100644 --- a/django/contrib/gis/geos/base.py +++ b/django/contrib/gis/geos/base.py @@ -29,7 +29,7 @@ except: # to prevent potentially malicious input from reaching the underlying C # library. Not a substitute for good web security programming practices. hex_regex = re.compile(r'^[0-9A-F]+$', re.I) -wkt_regex = re.compile(r'^(POINT|LINESTRING|LINEARRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION)[ACEGIMLONPSRUTY\d,\.\-\(\) ]+$', re.I) +wkt_regex = re.compile(r'^(SRID=(?P\d+);)?(?P(POINT|LINESTRING|LINEARRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION)[ACEGIMLONPSRUTY\d,\.\-\(\) ]+)$', re.I) class GEOSGeometry(object): "A class that, generally, encapsulates a GEOS geometry." @@ -57,11 +57,13 @@ class GEOSGeometry(object): if hex_regex.match(geo_input): # If the regex matches, the geometry is in HEX form. g = from_hex(geo_input, len(geo_input)) - elif wkt_regex.match(geo_input): - # Otherwise, the geometry is in WKT form. - g = from_wkt(geo_input) else: - raise ValueError('String or unicode input unrecognized as WKT or HEXEWKB.') + m = wkt_regex.match(geo_input) + if m: + if m.group('srid'): srid = int(m.group('srid')) + g = from_wkt(m.group('wkt')) + else: + raise ValueError('String or unicode input unrecognized as WKT EWKT, and HEXEWKB.') elif isinstance(geo_input, GEOM_PTR): # When the input is a pointer to a geomtry (GEOM_PTR). g = geo_input @@ -303,6 +305,12 @@ class GEOSGeometry(object): srid = property(get_srid, set_srid) #### Output Routines #### + @property + def ewkt(self): + "Returns the EWKT (WKT + SRID) of the Geometry." + if self.get_srid(): return 'SRID=%s;%s' % (self.srid, self.wkt) + else: return self.wkt + @property def wkt(self): "Returns the WKT (Well-Known Text) of the Geometry." @@ -356,6 +364,22 @@ class GEOSGeometry(object): "Alias for `srs` property." return self.srs + def transform(self, ct): + "Transforms this Geometry; only works with GDAL." + 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 ptr: + # Reassigning pointer, and resetting the SRID. + destroy_geom(self._ptr) + self._ptr = ptr + self.srid = g.srid + else: + pass + #### Topology Routines #### def _topology(self, gptr): "Helper routine to return Geometry from the given pointer." diff --git a/django/contrib/gis/tests/test_geos.py b/django/contrib/gis/tests/test_geos.py index 8a864e447f..6a255c7c4f 100644 --- a/django/contrib/gis/tests/test_geos.py +++ b/django/contrib/gis/tests/test_geos.py @@ -78,6 +78,16 @@ class GEOSTest(unittest.TestCase): # we need to do this so decimal places get normalised geom_t = fromstr(g.wkt) self.assertEqual(geom_t.wkt, geom_h.wkt) + + def test01h_ewkt(self): + "Testing EWKT." + srid = 32140 + for p in polygons: + ewkt = 'SRID=%d;%s' % (srid, p.wkt) + poly = fromstr(ewkt) + self.assertEqual(srid, poly.srid) + self.assertEqual(srid, poly.shell.srid) + self.assertEqual(srid, fromstr(poly.ewkt).srid) # Checking export def test02a_points(self): "Testing Point objects."