mirror of https://github.com/django/django.git
Refs #27472 -- Fixed OGRGeometry('POINT EMPTY').geos crash.
This commit is contained in:
parent
65a1f32319
commit
a413ef2155
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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')
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
"""
|
||||
|
|
|
@ -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)
|
||||
|
|
Loading…
Reference in New Issue