Explorar o código

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

Sergey Fedoseev %!s(int64=8) %!d(string=hai) anos
pai
achega
65a1f32319

+ 9 - 1
django/contrib/gis/gdal/geometries.py

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

+ 4 - 6
django/contrib/gis/geos/geometry.py

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

+ 4 - 0
django/contrib/gis/geos/point.py

@@ -1,6 +1,7 @@
 import warnings
 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.error import GEOSException
 from django.contrib.gis.geos.geometry import GEOSGeometry
@@ -43,6 +44,9 @@ class Point(GEOSGeometry):
         #  createPoint factory.
         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):
         """
         Create a coordinate sequence, set X, Y, [Z], and create point

+ 4 - 0
tests/gis_tests/geos_tests/test_geos.py

@@ -1355,6 +1355,10 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
         self.assertIsNone(g.normalize())
         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)
     def test_deprecated_srid_getters_setters(self):
         p = Point(1, 2, srid=123)