summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Fedoseev <fedoseev.sergey@gmail.com>2016-12-02 13:18:41 +0500
committerTim Graham <timograham@gmail.com>2016-12-08 10:24:05 -0500
commita413ef2155c4f3e5bf6954608d65a96631feb7e6 (patch)
tree8999ad3227042a4863ed5b5db6f9fa083184f93e
parent65a1f32319a0a58f8458060a61c7bab0fa12292e (diff)
Refs #27472 -- Fixed OGRGeometry('POINT EMPTY').geos crash.
-rw-r--r--django/contrib/gis/gdal/geometries.py14
-rw-r--r--django/contrib/gis/gdal/prototypes/generation.py4
-rw-r--r--django/contrib/gis/gdal/prototypes/geom.py1
-rw-r--r--django/contrib/gis/geos/geometry.py4
-rw-r--r--django/contrib/gis/geos/point.py7
-rw-r--r--tests/gis_tests/gdal_tests/test_geom.py8
6 files changed, 35 insertions, 3 deletions
diff --git a/django/contrib/gis/gdal/geometries.py b/django/contrib/gis/gdal/geometries.py
index 5a9fc2796d..ef3dbb10d2 100644
--- a/django/contrib/gis/gdal/geometries.py
+++ b/django/contrib/gis/gdal/geometries.py
@@ -255,6 +255,10 @@ class OGRGeometry(GDALBase):
return Envelope(capi.get_envelope(self.ptr, byref(OGREnvelope())))
@property
+ def empty(self):
+ return capi.is_empty(self.ptr)
+
+ @property
def extent(self):
"Returns the envelope as a 4-tuple, instead of as an Envelope object."
return self.envelope.tuple
@@ -305,11 +309,15 @@ class OGRGeometry(GDALBase):
srid = property(_get_srid, _set_srid)
# #### Output Methods ####
+ def _geos_ptr(self):
+ from django.contrib.gis.geos import GEOSGeometry
+ return GEOSGeometry._from_wkb(self.wkb)
+
@property
def geos(self):
"Returns a GEOSGeometry object from this OGRGeometry."
from django.contrib.gis.geos import GEOSGeometry
- return GEOSGeometry(self.wkb, self.srid)
+ return GEOSGeometry(self._geos_ptr(), self.srid)
@property
def gml(self):
@@ -504,6 +512,10 @@ class OGRGeometry(GDALBase):
# The subclasses for OGR Geometry.
class Point(OGRGeometry):
+ def _geos_ptr(self):
+ from django.contrib.gis import geos
+ return geos.Point._create_empty() if self.empty else super(Point, self)._geos_ptr()
+
@classmethod
def _create_empty(cls):
return capi.create_geom(OGRGeomType('point').num)
diff --git a/django/contrib/gis/gdal/prototypes/generation.py b/django/contrib/gis/gdal/prototypes/generation.py
index 04b89be6a6..18246cfc63 100644
--- a/django/contrib/gis/gdal/prototypes/generation.py
+++ b/django/contrib/gis/gdal/prototypes/generation.py
@@ -49,10 +49,12 @@ def geom_output(func, argtypes, offset=None):
return func
-def int_output(func, argtypes):
+def int_output(func, argtypes, errcheck=None):
"Generates a ctypes function that returns an integer value."
func.argtypes = argtypes
func.restype = c_int
+ if errcheck:
+ func.errcheck = errcheck
return func
diff --git a/django/contrib/gis/gdal/prototypes/geom.py b/django/contrib/gis/gdal/prototypes/geom.py
index a66b18842d..f7745f552f 100644
--- a/django/contrib/gis/gdal/prototypes/geom.py
+++ b/django/contrib/gis/gdal/prototypes/geom.py
@@ -79,6 +79,7 @@ get_centroid = void_output(lgdal.OGR_G_Centroid, [c_void_p, c_void_p])
get_dims = int_output(lgdal.OGR_G_GetDimension, [c_void_p])
get_coord_dim = int_output(lgdal.OGR_G_GetCoordinateDimension, [c_void_p])
set_coord_dim = void_output(lgdal.OGR_G_SetCoordinateDimension, [c_void_p, c_int], errcheck=False)
+is_empty = int_output(lgdal.OGR_G_IsEmpty, [c_void_p], errcheck=lambda result, func, cargs: bool(result))
get_geom_count = int_output(lgdal.OGR_G_GetGeometryCount, [c_void_p])
get_geom_name = const_string_output(lgdal.OGR_G_GetGeometryName, [c_void_p], decoding='ascii')
diff --git a/django/contrib/gis/geos/geometry.py b/django/contrib/gis/geos/geometry.py
index ac16184469..29589855d0 100644
--- a/django/contrib/gis/geos/geometry.py
+++ b/django/contrib/gis/geos/geometry.py
@@ -169,6 +169,10 @@ class GEOSGeometry(GEOSBase, ListMixin):
self._post_init(srid)
@classmethod
+ def _from_wkb(cls, wkb):
+ return wkb_r().read(wkb)
+
+ @classmethod
def from_gml(cls, gml_string):
return gdal.OGRGeometry.from_gml(gml_string).geos
diff --git a/django/contrib/gis/geos/point.py b/django/contrib/gis/geos/point.py
index ccb292cecc..c7b91f9bb5 100644
--- a/django/contrib/gis/geos/point.py
+++ b/django/contrib/gis/geos/point.py
@@ -47,7 +47,12 @@ class Point(GEOSGeometry):
def _ogr_ptr(self):
return gdal.geometries.Point._create_empty() if self.empty else super(Point, self)._ogr_ptr()
- def _create_point(self, ndim, coords):
+ @classmethod
+ def _create_empty(cls):
+ return cls._create_point(None, None)
+
+ @classmethod
+ def _create_point(cls, ndim, coords):
"""
Create a coordinate sequence, set X, Y, [Z], and create point
"""
diff --git a/tests/gis_tests/gdal_tests/test_geom.py b/tests/gis_tests/gdal_tests/test_geom.py
index c205a31092..bc8219772c 100644
--- a/tests/gis_tests/gdal_tests/test_geom.py
+++ b/tests/gis_tests/gdal_tests/test_geom.py
@@ -549,3 +549,11 @@ class OGRGeomTest(unittest.TestCase, TestDataMixin):
'</gml:Point>'
),
)
+
+ def test_empty(self):
+ self.assertIs(OGRGeometry('POINT (0 0)').empty, False)
+ self.assertIs(OGRGeometry('POINT EMPTY').empty, True)
+
+ def test_empty_point_to_geos(self):
+ p = OGRGeometry('POINT EMPTY', srs=4326)
+ self.assertEqual(p.geos.ewkt, p.ewkt)