mirror of
				https://github.com/django/django.git
				synced 2025-10-31 09:41:08 +00:00 
			
		
		
		
	Refs #27472 -- Fixed OGRGeometry('POINT EMPTY').geos crash.
This commit is contained in:
		
				
					committed by
					
						 Tim Graham
						Tim Graham
					
				
			
			
				
	
			
			
			
						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) | ||||
|   | ||||
		Reference in New Issue
	
	Block a user