Refs #27472 -- Fixed OGRGeometry('POINT EMPTY').geos crash.

This commit is contained in:
Sergey Fedoseev 2016-12-02 13:18:41 +05:00 committed by Tim Graham
parent 65a1f32319
commit a413ef2155
6 changed files with 35 additions and 3 deletions

View File

@ -254,6 +254,10 @@ class OGRGeometry(GDALBase):
# TODO: Fix Envelope() for Point geometries.
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."
@ -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)

View File

@ -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

View File

@ -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')

View File

@ -168,6 +168,10 @@ class GEOSGeometry(GEOSBase, ListMixin):
self.ptr = ptr
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

View File

@ -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
"""

View File

@ -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)