summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--django/contrib/gis/geos/base.py24
-rw-r--r--django/contrib/gis/geos/libgeos.py8
-rw-r--r--django/contrib/gis/tests/geometries.py1
-rw-r--r--django/contrib/gis/tests/test_geos.py42
4 files changed, 65 insertions, 10 deletions
diff --git a/django/contrib/gis/geos/base.py b/django/contrib/gis/geos/base.py
index e36db67ae0..b431ef15bf 100644
--- a/django/contrib/gis/geos/base.py
+++ b/django/contrib/gis/geos/base.py
@@ -6,7 +6,7 @@
from ctypes import \
byref, string_at, create_string_buffer, pointer, \
c_char_p, c_double, c_int, c_size_t
-from types import StringType, UnicodeType, IntType, FloatType
+from types import StringType, UnicodeType, IntType, FloatType, BufferType
# Python and GEOS-related dependencies.
import re
@@ -30,9 +30,13 @@ class GEOSGeometry(object):
#### Python 'magic' routines ####
def __init__(self, geo_input, srid=None):
"""
- The base constructor for GEOS geometry objects, and may take the following
- string inputs: WKT and HEXEWKB (a PostGIS-specific canonical form).
-
+ The base constructor for GEOS geometry objects, and may take the
+ following inputs:
+
+ * string: WKT
+ * string: HEXEWKB (a PostGIS-specific canonical form)
+ * buffer: WKB
+
The `srid` keyword is used to specify the Source Reference Identifier
(SRID) number for this Geometry. If not set, the SRID will be None.
"""
@@ -55,6 +59,11 @@ class GEOSGeometry(object):
# When the input is either a memory address (an integer), or a
# GEOSPointer object.
g = geo_input
+ elif isinstance(geo_input, BufferType):
+ # When the input is a buffer (WKB).
+ wkb_input = str(geo_input)
+ sz = c_size_t(len(wkb_input))
+ g = lgeos.GEOSGeomFromWKB_buf(c_char_p(wkb_input), sz)
else:
# Invalid geometry type.
raise TypeError, 'Improper geometry input type: %s' % str(type(geo_input))
@@ -414,6 +423,13 @@ class GEOSGeometry(object):
return string_at(h, sz.value)
@property
+ def wkb(self):
+ "Returns the WKB of the Geometry as a buffer."
+ sz = c_size_t()
+ h = lgeos.GEOSGeomToWKB_buf(self._ptr(), byref(sz))
+ return buffer(string_at(h, sz.value))
+
+ @property
def kml(self):
"Returns the KML representation of this Geometry."
gtype = self.geom_type
diff --git a/django/contrib/gis/geos/libgeos.py b/django/contrib/gis/geos/libgeos.py
index 65e80b40de..4dcdb16d66 100644
--- a/django/contrib/gis/geos/libgeos.py
+++ b/django/contrib/gis/geos/libgeos.py
@@ -52,8 +52,12 @@ lgeos = CDLL(lib_name)
# Supposed to mimic the GEOS message handler (C below):
# "typedef void (*GEOSMessageHandler)(const char *fmt, ...);"
NOTICEFUNC = CFUNCTYPE(None, c_char_p, c_char_p)
-def notice_h(fmt, list, output_h=sys.stdout):
- output_h.write('GEOS_NOTICE: %s\n' % (fmt % list))
+def notice_h(fmt, lst, output_h=sys.stdout):
+ try:
+ warn_msg = fmt % lst
+ except:
+ warn_msg = fmt
+ output_h.write('GEOS_NOTICE: %s\n' % warn_msg)
notice_h = NOTICEFUNC(notice_h)
ERRORFUNC = CFUNCTYPE(None, c_char_p, c_char_p)
diff --git a/django/contrib/gis/tests/geometries.py b/django/contrib/gis/tests/geometries.py
index b2602c1b24..564630d161 100644
--- a/django/contrib/gis/tests/geometries.py
+++ b/django/contrib/gis/tests/geometries.py
@@ -49,6 +49,7 @@ errors = (TestGeom('GEOMETR##!@#%#............a32515', bad=True, hex=False),
TestGeom('POINT (5, 23)', bad=True, hex=False),
TestGeom('AAABBBDDDAAD##@#1113511111-098111111111111111533333333333333', bad=True, hex=True),
TestGeom('FFFFFFFFFFFFFFFFF1355555555555555555565111', bad=True, hex=True),
+ TestGeom('', bad=True, hex=False),
)
# Polygons
diff --git a/django/contrib/gis/tests/test_geos.py b/django/contrib/gis/tests/test_geos.py
index be0da42e5a..062da04098 100644
--- a/django/contrib/gis/tests/test_geos.py
+++ b/django/contrib/gis/tests/test_geos.py
@@ -31,14 +31,48 @@ class GEOSTest(unittest.TestCase):
def test01d_errors(self):
"Testing the Error handlers."
+ # string-based
print "\nBEGIN - expecting GEOS_ERROR; safe to ignore.\n"
for err in errors:
- if err.hex:
- self.assertRaises(GEOSException, fromstr, err.wkt)
- else:
- self.assertRaises(GEOSException, fromstr, err.wkt)
+ self.assertRaises(GEOSException, fromstr, err.wkt)
print "\nEND - expecting GEOS_ERROR; safe to ignore.\n"
+
+ class NotAGeometry(object):
+ pass
+
+ # Some other object
+ self.assertRaises(TypeError, GEOSGeometry, NotAGeometry())
+ # None
+ self.assertRaises(TypeError, GEOSGeometry, None)
+ # Bad WKB
+ self.assertRaises(GEOSException, GEOSGeometry, buffer('0'))
+ def test01e_wkb(self):
+ "Testing WKB output."
+ from binascii import b2a_hex
+ for g in hex_wkt:
+ geom = fromstr(g.wkt)
+ wkb = geom.wkb
+ self.assertEqual(b2a_hex(wkb).upper(), g.hex)
+
+ def test01f_create_hex(self):
+ "Testing creation from HEX."
+ for g in hex_wkt:
+ geom_h = GEOSGeometry(g.hex)
+ # we need to do this so decimal places get normalised
+ geom_t = fromstr(g.wkt)
+ self.assertEqual(geom_t.wkt, geom_h.wkt)
+
+ def test01g_create_wkb(self):
+ "Testing creation from WKB."
+ from binascii import a2b_hex
+ for g in hex_wkt:
+ wkb = buffer(a2b_hex(g.hex))
+ geom_h = GEOSGeometry(wkb)
+ # we need to do this so decimal places get normalised
+ geom_t = fromstr(g.wkt)
+ self.assertEqual(geom_t.wkt, geom_h.wkt)
+
def test02a_points(self):
"Testing Point objects."
prev = fromstr('POINT(0 0)')