diff -r 6d3bd7133374 django/contrib/gis/geos/geometry.py
a
|
b
|
|
275 | 275 | "This property tests the validity of this Geometry." |
276 | 276 | return capi.geos_isvalid(self.ptr) |
277 | 277 | |
| 278 | @property |
| 279 | def invalid_reason(self): |
| 280 | """ |
| 281 | Returns a string containing the reason for any invalidity. |
| 282 | """ |
| 283 | if not GEOS_PREPARE: |
| 284 | raise GEOSException('Upgrade GEOS to 3.1 to get validity reason.') |
| 285 | return capi.geos_isvalidreason(self.ptr) |
| 286 | |
278 | 287 | #### Binary predicates. #### |
279 | 288 | def contains(self, other): |
280 | 289 | "Returns true if other.within(this) returns true." |
diff -r 6d3bd7133374 django/contrib/gis/geos/prototypes/__init__.py
a
|
b
|
|
18 | 18 | to_hex, to_wkb, to_wkt |
19 | 19 | |
20 | 20 | # Miscellaneous routines. |
21 | | from django.contrib.gis.geos.prototypes.misc import geos_area, geos_distance, geos_length |
| 21 | from django.contrib.gis.geos.prototypes.misc import * |
22 | 22 | |
23 | 23 | # Predicates |
24 | 24 | from django.contrib.gis.geos.prototypes.predicates import geos_hasz, geos_isempty, \ |
diff -r 6d3bd7133374 django/contrib/gis/geos/prototypes/misc.py
a
|
b
|
|
3 | 3 | ones that return the area, distance, and length. |
4 | 4 | """ |
5 | 5 | from ctypes import c_int, c_double, POINTER |
6 | | from django.contrib.gis.geos.libgeos import GEOM_PTR |
7 | | from django.contrib.gis.geos.prototypes.errcheck import check_dbl |
| 6 | from django.contrib.gis.geos.libgeos import GEOM_PTR, GEOS_PREPARE |
| 7 | from django.contrib.gis.geos.prototypes.errcheck import check_dbl, check_string |
| 8 | from django.contrib.gis.geos.prototypes.geom import geos_char_p |
8 | 9 | from django.contrib.gis.geos.prototypes.threadsafe import GEOSFunc |
9 | 10 | |
| 11 | __all__ = ['geos_area', 'geos_distance', 'geos_length'] |
| 12 | |
10 | 13 | ### ctypes generator function ### |
11 | 14 | def dbl_from_geom(func, num_geom=1): |
12 | 15 | """ |
… |
… |
|
26 | 29 | geos_area = dbl_from_geom(GEOSFunc('GEOSArea')) |
27 | 30 | geos_distance = dbl_from_geom(GEOSFunc('GEOSDistance'), num_geom=2) |
28 | 31 | geos_length = dbl_from_geom(GEOSFunc('GEOSLength')) |
| 32 | |
| 33 | # Validity reason; only in GEOS 3.1+ |
| 34 | if GEOS_PREPARE: |
| 35 | geos_isvalidreason = GEOSFunc('GEOSisValidReason') |
| 36 | geos_isvalidreason.argtypes = [GEOM_PTR] |
| 37 | geos_isvalidreason.restype = geos_char_p |
| 38 | geos_isvalidreason.errcheck = check_string |
| 39 | __all__.append('geos_isvalidreason') |
diff -r 6d3bd7133374 django/contrib/gis/geos/tests/test_geos.py
a
|
b
|
|
1 | 1 | import ctypes, random, unittest, sys |
2 | 2 | from django.contrib.gis.geos import * |
3 | 3 | from django.contrib.gis.geos.base import gdal, numpy, GEOSBase |
| 4 | from django.contrib.gis.geos.libgeos import GEOS_PREPARE |
4 | 5 | from django.contrib.gis.geometry.test_data import TestDataMixin |
5 | 6 | |
6 | 7 | class GEOSTest(unittest.TestCase, TestDataMixin): |
… |
… |
|
917 | 918 | for geom, merged in zip(ref_geoms, ref_merged): |
918 | 919 | self.assertEqual(merged, geom.merged) |
919 | 920 | |
| 921 | def test27_valid_reason(self): |
| 922 | "Testing IsValidReason support" |
| 923 | # Skipping tests if GEOS < v3.1. |
| 924 | if not GEOS_PREPARE: return |
| 925 | |
| 926 | g = GEOSGeometry("POINT(0 0)") |
| 927 | self.assert_(g.valid) |
| 928 | self.assert_(isinstance(g.invalid_reason, basestring)) |
| 929 | self.assertEqual(g.invalid_reason, "Valid Geometry") |
| 930 | |
| 931 | print "\nBEGIN - expecting GEOS_NOTICE; safe to ignore.\n" |
| 932 | |
| 933 | g = GEOSGeometry("LINESTRING(0 0, 0 0)") |
| 934 | |
| 935 | self.assert_(not g.valid) |
| 936 | self.assert_(isinstance(g.invalid_reason, basestring)) |
| 937 | self.assertEqual(g.invalid_reason, "Too few points in geometry component[0 0]") |
| 938 | |
| 939 | print "\nEND - expecting GEOS_NOTICE; safe to ignore.\n" |
| 940 | |
920 | 941 | def suite(): |
921 | 942 | s = unittest.TestSuite() |
922 | 943 | s.addTest(unittest.makeSuite(GEOSTest)) |
diff -r 6d3bd7133374 docs/ref/contrib/gis/geos.txt
a
|
b
|
|
219 | 219 | |
220 | 220 | Returns a boolean indicating whether the geometry is valid. |
221 | 221 | |
| 222 | .. attribute:: GEOSGeometry.invalid_reason |
| 223 | |
| 224 | .. versionadded:: 1.3 |
| 225 | |
| 226 | Returns a string describing the reason why a geometry is invalid. |
| 227 | |
222 | 228 | .. attribute:: GEOSGeometry.srid |
223 | 229 | |
224 | 230 | Property that may be used to retrieve or set the SRID associated with the |