mirror of
https://github.com/django/django.git
synced 2025-07-04 09:49:12 +00:00
gis: Fixed segfault on invalid WKT (added test for both invalid HEX and WKT). GEOSException now a proper exception. Updated error handler.
git-svn-id: http://code.djangoproject.com/svn/django/branches/gis@5030 bcc190cf-cafb-0310-a4f2-bffc1f526a37
This commit is contained in:
parent
522400d8ef
commit
e30720a2dc
@ -82,6 +82,9 @@ elif os.name == 'posix':
|
|||||||
else:
|
else:
|
||||||
raise GEOSException, 'Unsupported OS "%s"' % os.name
|
raise GEOSException, 'Unsupported OS "%s"' % os.name
|
||||||
|
|
||||||
|
# The GEOSException class
|
||||||
|
class GEOSException(Exception): pass
|
||||||
|
|
||||||
# Getting the GEOS C library. The C interface (CDLL) is used for
|
# Getting the GEOS C library. The C interface (CDLL) is used for
|
||||||
# both *NIX and Windows.
|
# both *NIX and Windows.
|
||||||
# See the GEOS C API source code for more details on the library function calls:
|
# See the GEOS C API source code for more details on the library function calls:
|
||||||
@ -98,11 +101,11 @@ notice_h = NOTICEFUNC(notice_h)
|
|||||||
|
|
||||||
ERRORFUNC = CFUNCTYPE(None, c_char_p, c_char_p)
|
ERRORFUNC = CFUNCTYPE(None, c_char_p, c_char_p)
|
||||||
def error_h(fmt, list):
|
def error_h(fmt, list):
|
||||||
# TODO: Figure out why improper format code given w/some GEOS errors
|
if list:
|
||||||
if not list:
|
err_msg = fmt % list
|
||||||
sys.stderr.write(fmt)
|
|
||||||
else:
|
else:
|
||||||
sys.stderr.write('ERROR: %s' % str(list))
|
err_msg = fmt
|
||||||
|
sys.stderr.write(err_msg)
|
||||||
error_h = ERRORFUNC(error_h)
|
error_h = ERRORFUNC(error_h)
|
||||||
|
|
||||||
# The initGEOS routine should be called first, however, that routine takes
|
# The initGEOS routine should be called first, however, that routine takes
|
||||||
@ -111,44 +114,42 @@ error_h = ERRORFUNC(error_h)
|
|||||||
# "extern void GEOS_DLL initGEOS(GEOSMessageHandler notice_function, GEOSMessageHandler error_function);"
|
# "extern void GEOS_DLL initGEOS(GEOSMessageHandler notice_function, GEOSMessageHandler error_function);"
|
||||||
lgeos.initGEOS(notice_h, error_h)
|
lgeos.initGEOS(notice_h, error_h)
|
||||||
|
|
||||||
class GEOSException:
|
|
||||||
"Exception class for any GEOS-related errors."
|
|
||||||
def __init__(self, msg):
|
|
||||||
self.msg = msg
|
|
||||||
def __str__(self):
|
|
||||||
return repr(self.msg)
|
|
||||||
|
|
||||||
class GEOSGeometry:
|
class GEOSGeometry:
|
||||||
"A class that, generally, encapsulates a GEOS geometry."
|
"A class that, generally, encapsulates a GEOS geometry."
|
||||||
|
|
||||||
#### Python 'magic' routines ####
|
#### Python 'magic' routines ####
|
||||||
def __init__(self, input, geom_type='wkt'):
|
def __init__(self, input, geom_type='wkt'):
|
||||||
"Takes an input and the type of the input for initialization."
|
"Takes an input and the type of the input for initialization."
|
||||||
|
|
||||||
if geom_type == 'wkt':
|
if geom_type == 'wkt':
|
||||||
# If the geometry is in WKT form
|
# If the geometry is in WKT form
|
||||||
self._g = lgeos.GEOSGeomFromWKT(c_char_p(input))
|
buf = create_string_buffer(input)
|
||||||
|
g = lgeos.GEOSGeomFromWKT(buf)
|
||||||
elif geom_type == 'hex':
|
elif geom_type == 'hex':
|
||||||
# If the geometry is in EWHEX form.
|
# If the geometry is in HEX form.
|
||||||
sz = c_size_t(len(input))
|
sz = c_size_t(len(input))
|
||||||
buf = create_string_buffer(input)
|
buf = create_string_buffer(input)
|
||||||
self._g = lgeos.GEOSGeomFromHEX_buf(buf, sz)
|
g = lgeos.GEOSGeomFromHEX_buf(buf, sz)
|
||||||
elif geom_type == 'geos':
|
elif geom_type == 'geos':
|
||||||
# When the input is a C pointer (Python integer)
|
# When the input is a C pointer (Python integer)
|
||||||
self._g = input
|
g = input
|
||||||
else:
|
else:
|
||||||
# Invalid geometry type.
|
# Invalid geometry type.
|
||||||
raise GEOSException, 'Improper geometry input type!'
|
raise GEOSException, 'Improper geometry input type!'
|
||||||
|
|
||||||
|
# If the geometry pointer is NULL (0), then raise an exception.
|
||||||
|
if not g:
|
||||||
|
self._g = False # Setting this before raising the exception
|
||||||
|
raise GEOSException, 'Invalid %s given!' % geom_type.upper()
|
||||||
|
else:
|
||||||
|
self._g = g
|
||||||
|
|
||||||
# Setting the class type (e.g. 'Point', 'Polygon', etc.)
|
# Setting the class type (e.g. 'Point', 'Polygon', etc.)
|
||||||
self.__class__ = GEO_CLASSES[self.geom_type]
|
self.__class__ = GEO_CLASSES[self.geom_type]
|
||||||
|
|
||||||
# If the geometry pointer is NULL (0), then raise an exception.
|
|
||||||
if not self._g:
|
|
||||||
raise GEOSException, 'Could not initialize on input!'
|
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
"This cleans up the memory allocated for the geometry."
|
"This cleans up the memory allocated for the geometry."
|
||||||
lgeos.GEOSGeom_destroy(self._g)
|
if self._g: lgeos.GEOSGeom_destroy(self._g)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
"WKT is used for the string representation."
|
"WKT is used for the string representation."
|
||||||
@ -412,7 +413,7 @@ class GEOSCoordSeq:
|
|||||||
self._z = z
|
self._z = z
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
lgeos.GEOSCoordSeq_destroy(self._cs)
|
if self._cs: lgeos.GEOSCoordSeq_destroy(self._cs)
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
for i in xrange(self.size):
|
for i in xrange(self.size):
|
||||||
@ -487,7 +488,7 @@ class GEOSCoordSeq:
|
|||||||
dim = c_uint(dimension)
|
dim = c_uint(dimension)
|
||||||
idx = c_uint(index)
|
idx = c_uint(index)
|
||||||
|
|
||||||
# 'd' is the value of the point
|
# 'd' is the value of the point, passed in by reference
|
||||||
d = c_double()
|
d = c_double()
|
||||||
status = lgeos.GEOSCoordSeq_getOrdinate(self._cs, idx, dim, byref(d))
|
status = lgeos.GEOSCoordSeq_getOrdinate(self._cs, idx, dim, byref(d))
|
||||||
if status == 0:
|
if status == 0:
|
||||||
|
File diff suppressed because one or more lines are too long
@ -5,18 +5,26 @@ from geometries import *
|
|||||||
|
|
||||||
class GeosTest2(unittest.TestCase):
|
class GeosTest2(unittest.TestCase):
|
||||||
|
|
||||||
def test010_wkt(self):
|
def test0100_wkt(self):
|
||||||
"Testing WKT output."
|
"Testing WKT output."
|
||||||
for g in wkt_out:
|
for g in wkt_out:
|
||||||
geom = GEOSGeometry(g.wkt)
|
geom = GEOSGeometry(g.wkt)
|
||||||
self.assertEqual(g.ewkt, geom.wkt)
|
self.assertEqual(g.ewkt, geom.wkt)
|
||||||
|
|
||||||
def test011_hex(self):
|
def test0101_hex(self):
|
||||||
"Testing HEX output."
|
"Testing HEX output."
|
||||||
for g in hex_wkt:
|
for g in hex_wkt:
|
||||||
geom = GEOSGeometry(g.wkt)
|
geom = GEOSGeometry(g.wkt)
|
||||||
self.assertEqual(g.hex, geom.hex)
|
self.assertEqual(g.hex, geom.hex)
|
||||||
|
|
||||||
|
def test0102_errors(self):
|
||||||
|
"Testing the Error handlers."
|
||||||
|
for err in errors:
|
||||||
|
if err.hex:
|
||||||
|
self.assertRaises(GEOSException, GEOSGeometry, err.wkt, 'hex')
|
||||||
|
else:
|
||||||
|
self.assertRaises(GEOSException, GEOSGeometry, err.wkt)
|
||||||
|
|
||||||
def test02_points(self):
|
def test02_points(self):
|
||||||
"Testing Point objects."
|
"Testing Point objects."
|
||||||
prev = GEOSGeometry('POINT(0 0)')
|
prev = GEOSGeometry('POINT(0 0)')
|
||||||
|
Loading…
x
Reference in New Issue
Block a user