summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin Bronn <jbronn@gmail.com>2010-11-04 01:29:37 +0000
committerJustin Bronn <jbronn@gmail.com>2010-11-04 01:29:37 +0000
commitcabc21ca60758626ef8a5a8ff8c7f551a7e53db7 (patch)
tree822152946512d1c2da54b8cca69f66927cc89294
parent877033b479ed4252ed4d40714a70fcb4a85c641f (diff)
Fixed #14318 -- Added `GEOSGeometry.valid_reason` property. Thanks, Rob Coup.
git-svn-id: http://code.djangoproject.com/svn/django/trunk@14447 bcc190cf-cafb-0310-a4f2-bffc1f526a37
-rw-r--r--django/contrib/gis/geos/geometry.py17
-rw-r--r--django/contrib/gis/geos/prototypes/__init__.py2
-rw-r--r--django/contrib/gis/geos/prototypes/misc.py15
-rw-r--r--django/contrib/gis/geos/tests/test_geos.py21
-rw-r--r--docs/ref/contrib/gis/geos.txt6
5 files changed, 54 insertions, 7 deletions
diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py
index 51666bc4d4..34b126d777 100644
--- a/django/contrib/gis/geos/geometry.py
+++ b/django/contrib/gis/geos/geometry.py
@@ -275,6 +275,15 @@ class GEOSGeometry(GEOSBase, ListMixin):
"This property tests the validity of this Geometry."
return capi.geos_isvalid(self.ptr)
+ @property
+ def valid_reason(self):
+ """
+ Returns a string containing the reason for any invalidity.
+ """
+ if not GEOS_PREPARE:
+ raise GEOSException('Upgrade GEOS to 3.1 to get validity reason.')
+ return capi.geos_isvalidreason(self.ptr)
+
#### Binary predicates. ####
def contains(self, other):
"Returns true if other.within(this) returns true."
@@ -376,7 +385,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
"""
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`
+ because it is not a part of the OGC specification (use the `hexewkb`
property instead).
"""
# A possible faster, all-python, implementation:
@@ -386,14 +395,14 @@ class GEOSGeometry(GEOSBase, ListMixin):
@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
+ 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.')
+ 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)
diff --git a/django/contrib/gis/geos/prototypes/__init__.py b/django/contrib/gis/geos/prototypes/__init__.py
index 2355928774..23735f5e9b 100644
--- a/django/contrib/gis/geos/prototypes/__init__.py
+++ b/django/contrib/gis/geos/prototypes/__init__.py
@@ -18,7 +18,7 @@ from django.contrib.gis.geos.prototypes.geom import from_hex, from_wkb, from_wkt
to_hex, to_wkb, to_wkt
# Miscellaneous routines.
-from django.contrib.gis.geos.prototypes.misc import geos_area, geos_distance, geos_length
+from django.contrib.gis.geos.prototypes.misc import *
# Predicates
from django.contrib.gis.geos.prototypes.predicates import geos_hasz, geos_isempty, \
diff --git a/django/contrib/gis/geos/prototypes/misc.py b/django/contrib/gis/geos/prototypes/misc.py
index 5b3b658fc0..fd4f78a011 100644
--- a/django/contrib/gis/geos/prototypes/misc.py
+++ b/django/contrib/gis/geos/prototypes/misc.py
@@ -3,10 +3,13 @@
ones that return the area, distance, and length.
"""
from ctypes import c_int, c_double, POINTER
-from django.contrib.gis.geos.libgeos import GEOM_PTR
-from django.contrib.gis.geos.prototypes.errcheck import check_dbl
+from django.contrib.gis.geos.libgeos import GEOM_PTR, GEOS_PREPARE
+from django.contrib.gis.geos.prototypes.errcheck import check_dbl, check_string
+from django.contrib.gis.geos.prototypes.geom import geos_char_p
from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc
+__all__ = ['geos_area', 'geos_distance', 'geos_length']
+
### ctypes generator function ###
def dbl_from_geom(func, num_geom=1):
"""
@@ -26,3 +29,11 @@ def dbl_from_geom(func, num_geom=1):
geos_area = dbl_from_geom(GEOSFunc('GEOSArea'))
geos_distance = dbl_from_geom(GEOSFunc('GEOSDistance'), num_geom=2)
geos_length = dbl_from_geom(GEOSFunc('GEOSLength'))
+
+# Validity reason; only in GEOS 3.1+
+if GEOS_PREPARE:
+ geos_isvalidreason = GEOSFunc('GEOSisValidReason')
+ geos_isvalidreason.argtypes = [GEOM_PTR]
+ geos_isvalidreason.restype = geos_char_p
+ geos_isvalidreason.errcheck = check_string
+ __all__.append('geos_isvalidreason')
diff --git a/django/contrib/gis/geos/tests/test_geos.py b/django/contrib/gis/geos/tests/test_geos.py
index 3cd021e8b8..421e8c5f5e 100644
--- a/django/contrib/gis/geos/tests/test_geos.py
+++ b/django/contrib/gis/geos/tests/test_geos.py
@@ -1,6 +1,7 @@
import ctypes, random, unittest, sys
from django.contrib.gis.geos import *
from django.contrib.gis.geos.base import gdal, numpy, GEOSBase
+from django.contrib.gis.geos.libgeos import GEOS_PREPARE
from django.contrib.gis.geometry.test_data import TestDataMixin
class GEOSTest(unittest.TestCase, TestDataMixin):
@@ -917,6 +918,26 @@ class GEOSTest(unittest.TestCase, TestDataMixin):
for geom, merged in zip(ref_geoms, ref_merged):
self.assertEqual(merged, geom.merged)
+ def test27_valid_reason(self):
+ "Testing IsValidReason support"
+ # Skipping tests if GEOS < v3.1.
+ if not GEOS_PREPARE: return
+
+ g = GEOSGeometry("POINT(0 0)")
+ self.assert_(g.valid)
+ self.assert_(isinstance(g.valid_reason, basestring))
+ self.assertEqual(g.valid_reason, "Valid Geometry")
+
+ print "\nBEGIN - expecting GEOS_NOTICE; safe to ignore.\n"
+
+ g = GEOSGeometry("LINESTRING(0 0, 0 0)")
+
+ self.assert_(not g.valid)
+ self.assert_(isinstance(g.valid_reason, basestring))
+ self.assertEqual(g.valid_reason, "Too few points in geometry component[0 0]")
+
+ print "\nEND - expecting GEOS_NOTICE; safe to ignore.\n"
+
def suite():
s = unittest.TestSuite()
s.addTest(unittest.makeSuite(GEOSTest))
diff --git a/docs/ref/contrib/gis/geos.txt b/docs/ref/contrib/gis/geos.txt
index 06a88a88ec..088ea6cdbe 100644
--- a/docs/ref/contrib/gis/geos.txt
+++ b/docs/ref/contrib/gis/geos.txt
@@ -219,6 +219,12 @@ definition.
Returns a boolean indicating whether the geometry is valid.
+.. attribute:: GEOSGeometry.valid_reason
+
+.. versionadded:: 1.3
+
+Returns a string describing the reason why a geometry is invalid.
+
.. attribute:: GEOSGeometry.srid
Property that may be used to retrieve or set the SRID associated with the