--- a/web/lib/django/contrib/gis/geos/geometry.py Wed May 19 17:43:59 2010 +0200
+++ b/web/lib/django/contrib/gis/geos/geometry.py Tue May 25 02:43:45 2010 +0200
@@ -21,11 +21,12 @@
# the underlying GEOS library.
from django.contrib.gis.geos import prototypes as capi
-# Regular expression for recognizing HEXEWKB and WKT. A prophylactic measure
-# 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'^(SRID=(?P<srid>\d+);)?(?P<wkt>(POINT|LINESTRING|LINEARRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON|GEOMETRYCOLLECTION)[ACEGIMLONPSRUTY\d,\.\-\(\) ]+)$', re.I)
+# These functions provide access to a thread-local instance
+# of their corresponding GEOS I/O class.
+from django.contrib.gis.geos.prototypes.io import wkt_r, wkt_w, wkb_r, wkb_w, ewkb_w, ewkb_w3d
+
+# For recognizing geometry input.
+from django.contrib.gis.geometry.regex import hex_regex, wkt_regex, json_regex
class GEOSGeometry(GEOSBase, ListMixin):
"A class that, generally, encapsulates a GEOS geometry."
@@ -61,13 +62,13 @@
if wkt_m:
# Handling WKT input.
if wkt_m.group('srid'): srid = int(wkt_m.group('srid'))
- g = wkt_r.read(wkt_m.group('wkt'))
+ g = wkt_r().read(wkt_m.group('wkt'))
elif hex_regex.match(geo_input):
# Handling HEXEWKB input.
- g = wkb_r.read(geo_input)
- elif gdal.GEOJSON and gdal.geometries.json_regex.match(geo_input):
+ g = wkb_r().read(geo_input)
+ elif gdal.GEOJSON and json_regex.match(geo_input):
# Handling GeoJSON input.
- g = wkb_r.read(gdal.OGRGeometry(geo_input).wkb)
+ g = wkb_r().read(gdal.OGRGeometry(geo_input).wkb)
else:
raise ValueError('String or unicode input unrecognized as WKT EWKT, and HEXEWKB.')
elif isinstance(geo_input, GEOM_PTR):
@@ -75,7 +76,7 @@
g = geo_input
elif isinstance(geo_input, buffer):
# When the input is a buffer (WKB).
- g = wkb_r.read(geo_input)
+ g = wkb_r().read(geo_input)
elif isinstance(geo_input, GEOSGeometry):
g = capi.geom_clone(geo_input.ptr)
else:
@@ -142,7 +143,7 @@
def __setstate__(self, state):
# Instantiating from the tuple state that was pickled.
wkb, srid = state
- ptr = capi.from_wkb(wkb, len(wkb))
+ ptr = wkb_r().read(buffer(wkb))
if not ptr: raise GEOSException('Invalid Geometry loaded from pickled state.')
self.ptr = ptr
self._post_init(srid)
@@ -357,25 +358,45 @@
#### Output Routines ####
@property
def ewkt(self):
- "Returns the EWKT (WKT + SRID) of the Geometry."
+ """
+ Returns the EWKT (WKT + SRID) of the Geometry. Note that Z values
+ are *not* included in this representation because GEOS does not yet
+ support serializing them.
+ """
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."
- return wkt_w.write(self)
+ "Returns the WKT (Well-Known Text) representation of this Geometry."
+ return wkt_w().write(self)
@property
def hex(self):
"""
- Returns the HEX of the Geometry -- please note that the SRID is not
- included in this representation, because the GEOS C library uses
- -1 by default, even if the SRID is set.
+ Returns the WKB of this Geometry in hexadecimal form. Please note
+ that the SRID and Z values are not included in this representation
+ because it is not a part of the OGC specification (use the `hexewkb`
+ property instead).
"""
# A possible faster, all-python, implementation:
# str(self.wkb).encode('hex')
- return wkb_w.write_hex(self)
+ return wkb_w().write_hex(self)
+
+ @property
+ def hexewkb(self):
+ """
+ Returns the EWKB of this Geometry in hexadecimal form. This is an
+ extension of the WKB specification that includes SRID and Z values
+ that are a part of this geometry.
+ """
+ if self.hasz:
+ if not GEOS_PREPARE:
+ # See: http://trac.osgeo.org/geos/ticket/216
+ raise GEOSException('Upgrade GEOS to 3.1 to get valid 3D HEXEWKB.')
+ return ewkb_w3d().write_hex(self)
+ else:
+ return ewkb_w().write_hex(self)
@property
def json(self):
@@ -383,7 +404,7 @@
Returns GeoJSON representation of this Geometry if GDAL 1.5+
is installed.
"""
- if gdal.GEOJSON:
+ if gdal.GEOJSON:
return self.ogr.json
else:
raise GEOSException('GeoJSON output only supported on GDAL 1.5+.')
@@ -391,8 +412,27 @@
@property
def wkb(self):
- "Returns the WKB of the Geometry as a buffer."
- return wkb_w.write(self)
+ """
+ Returns the WKB (Well-Known Binary) representation of this Geometry
+ as a Python buffer. SRID and Z values are not included, use the
+ `ewkb` property instead.
+ """
+ return wkb_w().write(self)
+
+ @property
+ def ewkb(self):
+ """
+ Return the EWKB representation of this Geometry as a Python buffer.
+ This is an extension of the WKB specification that includes any SRID
+ and Z values that are a part of this geometry.
+ """
+ if self.hasz:
+ if not GEOS_PREPARE:
+ # See: http://trac.osgeo.org/geos/ticket/216
+ raise GEOSException('Upgrade GEOS to 3.1 to get valid 3D EWKB.')
+ return ewkb_w3d().write(self)
+ else:
+ return ewkb_w().write(self)
@property
def kml(self):
@@ -454,7 +494,7 @@
g = gdal.OGRGeometry(self.wkb, srid)
g.transform(ct)
# Getting a new GEOS pointer
- ptr = wkb_r.read(g.wkb)
+ ptr = wkb_r().read(g.wkb)
if clone:
# User wants a cloned transformed geometry returned.
return GEOSGeometry(ptr, srid=g.srid)
@@ -616,9 +656,6 @@
7 : GeometryCollection,
}
-# Similarly, import the GEOS I/O instances here to avoid conflicts.
-from django.contrib.gis.geos.io import wkt_r, wkt_w, wkb_r, wkb_w
-
# If supported, import the PreparedGeometry class.
if GEOS_PREPARE:
from django.contrib.gis.geos.prepared import PreparedGeometry