Fixed #25873 -- Made GEOSGeometry handle the srid parameter more predictably.
This commit is contained in:
parent
068d75688f
commit
6ecccad711
|
@ -35,7 +35,7 @@ class BaseGeometryWidget(Widget):
|
|||
|
||||
def deserialize(self, value):
|
||||
try:
|
||||
return GEOSGeometry(value, self.map_srid)
|
||||
return GEOSGeometry(value)
|
||||
except (GEOSException, ValueError) as err:
|
||||
logger.error("Error creating geometry from value '%s' (%s)", value, err)
|
||||
return None
|
||||
|
@ -48,7 +48,7 @@ class BaseGeometryWidget(Widget):
|
|||
|
||||
if value:
|
||||
# Check that srid of value and map match
|
||||
if value.srid != self.map_srid:
|
||||
if value.srid and value.srid != self.map_srid:
|
||||
try:
|
||||
ogr = value.ogr
|
||||
ogr.transform(self.map_srid)
|
||||
|
|
|
@ -46,6 +46,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
|||
The `srid` keyword is used to specify the Source Reference Identifier
|
||||
(SRID) number for this Geometry. If not set, the SRID will be None.
|
||||
"""
|
||||
input_srid = None
|
||||
if isinstance(geo_input, bytes):
|
||||
geo_input = force_text(geo_input)
|
||||
if isinstance(geo_input, str):
|
||||
|
@ -53,7 +54,7 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
|||
if wkt_m:
|
||||
# Handling WKT input.
|
||||
if wkt_m.group('srid'):
|
||||
srid = int(wkt_m.group('srid'))
|
||||
input_srid = int(wkt_m.group('srid'))
|
||||
g = wkt_r().read(force_bytes(wkt_m.group('wkt')))
|
||||
elif hex_regex.match(geo_input):
|
||||
# Handling HEXEWKB input.
|
||||
|
@ -75,14 +76,17 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
|||
# Invalid geometry type.
|
||||
raise TypeError('Improper geometry input type: %s' % type(geo_input))
|
||||
|
||||
if g:
|
||||
# Setting the pointer object with a valid pointer.
|
||||
self.ptr = g
|
||||
else:
|
||||
if not g:
|
||||
raise GEOSException('Could not initialize GEOS Geometry with given input.')
|
||||
|
||||
input_srid = input_srid or capi.geos_get_srid(g) or None
|
||||
if input_srid and srid and input_srid != srid:
|
||||
raise ValueError('Input geometry already has SRID: %d.' % input_srid)
|
||||
|
||||
# Setting the pointer object with a valid pointer.
|
||||
self.ptr = g
|
||||
# Post-initialization setup.
|
||||
self._post_init(srid)
|
||||
self._post_init(input_srid or srid)
|
||||
|
||||
def _post_init(self, srid):
|
||||
"Perform post-initialization setup."
|
||||
|
|
|
@ -194,6 +194,27 @@ This is the base class for all GEOS geometry objects. It initializes on the
|
|||
given ``geo_input`` argument, and then assumes the proper geometry subclass
|
||||
(e.g., ``GEOSGeometry('POINT(1 1)')`` will create a :class:`Point` object).
|
||||
|
||||
The ``srid`` parameter, if given, is set as the SRID of the created geometry if
|
||||
``geo_input`` doesn't have an SRID. If different SRIDs are provided through the
|
||||
``geo_input`` and ``srid`` parameters, ``ValueError`` is raised::
|
||||
|
||||
>>> from django.contrib.gis.geos import GEOSGeometry
|
||||
>>> GEOSGeometry('POINT EMPTY', srid=4326).ewkt
|
||||
'SRID=4326;POINT EMPTY'
|
||||
>>> GEOSGeometry('SRID=4326;POINT EMPTY', srid=4326).ewkt
|
||||
'SRID=4326;POINT EMPTY'
|
||||
>>> GEOSGeometry('SRID=1;POINT EMPTY', srid=4326)
|
||||
Traceback (most recent call last):
|
||||
...
|
||||
ValueError: Input geometry already has SRID: 1.
|
||||
|
||||
.. versionchanged:: 2.0
|
||||
|
||||
In older versions, the ``srid`` parameter is handled differently for WKT
|
||||
and WKB input. For WKT, ``srid`` is used only if the input geometry doesn't
|
||||
have an SRID. For WKB, ``srid`` (if given) replaces the SRID of the input
|
||||
geometry.
|
||||
|
||||
The following input formats, along with their corresponding Python types,
|
||||
are accepted:
|
||||
|
||||
|
|
|
@ -708,6 +708,14 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
|
|||
pnt_wo_srid = Point(1, 1)
|
||||
pnt_wo_srid.srid = pnt_wo_srid.srid
|
||||
|
||||
# Input geometries that have an SRID.
|
||||
self.assertEqual(GEOSGeometry(pnt.ewkt, srid=pnt.srid).srid, pnt.srid)
|
||||
self.assertEqual(GEOSGeometry(pnt.ewkb, srid=pnt.srid).srid, pnt.srid)
|
||||
with self.assertRaisesMessage(ValueError, 'Input geometry already has SRID: %d.' % pnt.srid):
|
||||
GEOSGeometry(pnt.ewkt, srid=1)
|
||||
with self.assertRaisesMessage(ValueError, 'Input geometry already has SRID: %d.' % pnt.srid):
|
||||
GEOSGeometry(pnt.ewkb, srid=1)
|
||||
|
||||
@skipUnless(HAS_GDAL, "GDAL is required.")
|
||||
def test_custom_srid(self):
|
||||
"""Test with a null srid and a srid unknown to GDAL."""
|
||||
|
|
Loading…
Reference in New Issue