Refs #27472 -- Fixed GEOSGeometry('POINT EMPTY').ogr crash.

This commit is contained in:
Sergey Fedoseev 2016-12-02 08:22:04 +05:00 committed by Tim Graham
parent 47ef8f31f3
commit 65a1f32319
4 changed files with 21 additions and 7 deletions

View File

@ -97,7 +97,7 @@ class OGRGeometry(GDALBase):
g = capi.create_geom(OGRGeomType(geom_input).num) g = capi.create_geom(OGRGeomType(geom_input).num)
elif isinstance(geom_input, six.memoryview): elif isinstance(geom_input, six.memoryview):
# WKB was passed in # WKB was passed in
g = capi.from_wkb(bytes(geom_input), None, byref(c_void_p()), len(geom_input)) g = self._from_wkb(geom_input)
elif isinstance(geom_input, OGRGeomType): elif isinstance(geom_input, OGRGeomType):
# OGRGeomType was passed in, an empty geometry will be created. # OGRGeomType was passed in, an empty geometry will be created.
g = capi.create_geom(geom_input.num) g = capi.create_geom(geom_input.num)
@ -144,6 +144,10 @@ class OGRGeometry(GDALBase):
self.ptr = ptr self.ptr = ptr
self.srs = srs self.srs = srs
@classmethod
def _from_wkb(cls, geom_input):
return capi.from_wkb(bytes(geom_input), None, byref(c_void_p()), len(geom_input))
@classmethod @classmethod
def from_bbox(cls, bbox): def from_bbox(cls, bbox):
"Constructs a Polygon from a bounding box (4-tuple)." "Constructs a Polygon from a bounding box (4-tuple)."
@ -500,6 +504,10 @@ class OGRGeometry(GDALBase):
# The subclasses for OGR Geometry. # The subclasses for OGR Geometry.
class Point(OGRGeometry): class Point(OGRGeometry):
@classmethod
def _create_empty(cls):
return capi.create_geom(OGRGeomType('point').num)
@property @property
def x(self): def x(self):
"Returns the X coordinate for this Point." "Returns the X coordinate for this Point."

View File

@ -479,15 +479,13 @@ class GEOSGeometry(GEOSBase, ListMixin):
return PreparedGeometry(self) return PreparedGeometry(self)
# #### GDAL-specific output routines #### # #### GDAL-specific output routines ####
def _ogr_ptr(self):
return gdal.OGRGeometry._from_wkb(self.wkb)
@property @property
def ogr(self): def ogr(self):
"Returns the OGR Geometry for this Geometry." "Returns the OGR Geometry for this Geometry."
if self.srid: return gdal.OGRGeometry(self._ogr_ptr(), self.srs)
try:
return gdal.OGRGeometry(self.wkb, self.srid)
except gdal.SRSException:
pass
return gdal.OGRGeometry(self.wkb)
@property @property
def srs(self): def srs(self):

View File

@ -1,6 +1,7 @@
import warnings import warnings
from ctypes import c_uint from ctypes import c_uint
from django.contrib.gis import gdal
from django.contrib.gis.geos import prototypes as capi from django.contrib.gis.geos import prototypes as capi
from django.contrib.gis.geos.error import GEOSException from django.contrib.gis.geos.error import GEOSException
from django.contrib.gis.geos.geometry import GEOSGeometry from django.contrib.gis.geos.geometry import GEOSGeometry
@ -43,6 +44,9 @@ class Point(GEOSGeometry):
# createPoint factory. # createPoint factory.
super(Point, self).__init__(point, srid=srid) super(Point, self).__init__(point, srid=srid)
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): def _create_point(self, ndim, coords):
""" """
Create a coordinate sequence, set X, Y, [Z], and create point Create a coordinate sequence, set X, Y, [Z], and create point

View File

@ -1355,6 +1355,10 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
self.assertIsNone(g.normalize()) self.assertIsNone(g.normalize())
self.assertTrue(g.equals_exact(MultiPoint(Point(2, 2), Point(1, 1), Point(0, 0)))) self.assertTrue(g.equals_exact(MultiPoint(Point(2, 2), Point(1, 1), Point(0, 0))))
def test_empty_point(self):
p = Point(srid=4326)
self.assertEqual(p.ogr.ewkt, p.ewkt)
@ignore_warnings(category=RemovedInDjango20Warning) @ignore_warnings(category=RemovedInDjango20Warning)
def test_deprecated_srid_getters_setters(self): def test_deprecated_srid_getters_setters(self):
p = Point(1, 2, srid=123) p = Point(1, 2, srid=123)