1
0
mirror of https://github.com/django/django.git synced 2025-07-04 01:39:20 +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:
Justin Bronn 2007-04-19 12:49:40 +00:00
parent 522400d8ef
commit e30720a2dc
3 changed files with 47 additions and 29 deletions

View File

@ -82,6 +82,9 @@ elif os.name == 'posix':
else:
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
# both *NIX and Windows.
# 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)
def error_h(fmt, list):
# TODO: Figure out why improper format code given w/some GEOS errors
if not list:
sys.stderr.write(fmt)
if list:
err_msg = fmt % list
else:
sys.stderr.write('ERROR: %s' % str(list))
err_msg = fmt
sys.stderr.write(err_msg)
error_h = ERRORFUNC(error_h)
# 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);"
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:
"A class that, generally, encapsulates a GEOS geometry."
#### Python 'magic' routines ####
def __init__(self, input, geom_type='wkt'):
"Takes an input and the type of the input for initialization."
if geom_type == 'wkt':
# 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':
# If the geometry is in EWHEX form.
# If the geometry is in HEX form.
sz = c_size_t(len(input))
buf = create_string_buffer(input)
self._g = lgeos.GEOSGeomFromHEX_buf(buf, sz)
g = lgeos.GEOSGeomFromHEX_buf(buf, sz)
elif geom_type == 'geos':
# When the input is a C pointer (Python integer)
self._g = input
g = input
else:
# Invalid geometry 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.)
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):
"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):
"WKT is used for the string representation."
@ -412,7 +413,7 @@ class GEOSCoordSeq:
self._z = z
def __del__(self):
lgeos.GEOSCoordSeq_destroy(self._cs)
if self._cs: lgeos.GEOSCoordSeq_destroy(self._cs)
def __iter__(self):
for i in xrange(self.size):
@ -487,7 +488,7 @@ class GEOSCoordSeq:
dim = c_uint(dimension)
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()
status = lgeos.GEOSCoordSeq_getOrdinate(self._cs, idx, dim, byref(d))
if status == 0:

File diff suppressed because one or more lines are too long

View File

@ -5,18 +5,26 @@ from geometries import *
class GeosTest2(unittest.TestCase):
def test010_wkt(self):
def test0100_wkt(self):
"Testing WKT output."
for g in wkt_out:
geom = GEOSGeometry(g.wkt)
self.assertEqual(g.ewkt, geom.wkt)
def test011_hex(self):
def test0101_hex(self):
"Testing HEX output."
for g in hex_wkt:
geom = GEOSGeometry(g.wkt)
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):
"Testing Point objects."
prev = GEOSGeometry('POINT(0 0)')