Fixed #25874 -- Made GEOSGeometry read SRID from GeoJSON input.
This commit is contained in:
parent
ede4f6d48c
commit
24023c6a8f
|
@ -48,6 +48,7 @@ from django.contrib.gis.gdal.error import (
|
||||||
GDALException, OGRIndexError, SRSException,
|
GDALException, OGRIndexError, SRSException,
|
||||||
)
|
)
|
||||||
from django.contrib.gis.gdal.geomtype import OGRGeomType
|
from django.contrib.gis.gdal.geomtype import OGRGeomType
|
||||||
|
from django.contrib.gis.gdal.libgdal import GDAL_VERSION
|
||||||
from django.contrib.gis.gdal.prototypes import geom as capi, srs as srs_api
|
from django.contrib.gis.gdal.prototypes import geom as capi, srs as srs_api
|
||||||
from django.contrib.gis.gdal.srs import CoordTransform, SpatialReference
|
from django.contrib.gis.gdal.srs import CoordTransform, SpatialReference
|
||||||
from django.contrib.gis.geometry.regex import hex_regex, json_regex, wkt_regex
|
from django.contrib.gis.geometry.regex import hex_regex, json_regex, wkt_regex
|
||||||
|
@ -87,7 +88,7 @@ class OGRGeometry(GDALBase):
|
||||||
else:
|
else:
|
||||||
g = capi.from_wkt(byref(c_char_p(wkt_m.group('wkt').encode())), None, byref(c_void_p()))
|
g = capi.from_wkt(byref(c_char_p(wkt_m.group('wkt').encode())), None, byref(c_void_p()))
|
||||||
elif json_m:
|
elif json_m:
|
||||||
g = capi.from_json(geom_input.encode())
|
g = self._from_json(geom_input.encode())
|
||||||
else:
|
else:
|
||||||
# Seeing if the input is a valid short-hand string
|
# Seeing if the input is a valid short-hand string
|
||||||
# (e.g., 'Point', 'POLYGON').
|
# (e.g., 'Point', 'POLYGON').
|
||||||
|
@ -139,6 +140,20 @@ class OGRGeometry(GDALBase):
|
||||||
def _from_wkb(cls, geom_input):
|
def _from_wkb(cls, geom_input):
|
||||||
return capi.from_wkb(bytes(geom_input), None, byref(c_void_p()), len(geom_input))
|
return capi.from_wkb(bytes(geom_input), None, byref(c_void_p()), len(geom_input))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _from_json(geom_input):
|
||||||
|
ptr = capi.from_json(geom_input)
|
||||||
|
if GDAL_VERSION < (2, 0):
|
||||||
|
has_srs = True
|
||||||
|
try:
|
||||||
|
capi.get_geom_srs(ptr)
|
||||||
|
except SRSException:
|
||||||
|
has_srs = False
|
||||||
|
if not has_srs:
|
||||||
|
srs = SpatialReference(4326)
|
||||||
|
capi.assign_srs(ptr, srs.ptr)
|
||||||
|
return ptr
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_bbox(cls, bbox):
|
def from_bbox(cls, bbox):
|
||||||
"Construct a Polygon from a bounding box (4-tuple)."
|
"Construct a Polygon from a bounding box (4-tuple)."
|
||||||
|
@ -146,6 +161,10 @@ class OGRGeometry(GDALBase):
|
||||||
return OGRGeometry('POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))' % (
|
return OGRGeometry('POLYGON((%s %s, %s %s, %s %s, %s %s, %s %s))' % (
|
||||||
x0, y0, x0, y1, x1, y1, x1, y0, x0, y0))
|
x0, y0, x0, y1, x1, y1, x1, y0, x0, y0))
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def from_json(geom_input):
|
||||||
|
return OGRGeometry(OGRGeometry._from_json(force_bytes(geom_input)))
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_gml(cls, gml_string):
|
def from_gml(cls, gml_string):
|
||||||
return cls(capi.from_gml(force_bytes(gml_string)))
|
return cls(capi.from_gml(force_bytes(gml_string)))
|
||||||
|
|
|
@ -61,7 +61,9 @@ class GEOSGeometry(GEOSBase, ListMixin):
|
||||||
g = wkb_r().read(force_bytes(geo_input))
|
g = wkb_r().read(force_bytes(geo_input))
|
||||||
elif json_regex.match(geo_input):
|
elif json_regex.match(geo_input):
|
||||||
# Handling GeoJSON input.
|
# Handling GeoJSON input.
|
||||||
g = wkb_r().read(gdal.OGRGeometry(geo_input).wkb)
|
ogr = gdal.OGRGeometry.from_json(geo_input)
|
||||||
|
g = ogr._geos_ptr()
|
||||||
|
input_srid = ogr.srid
|
||||||
else:
|
else:
|
||||||
raise ValueError('String input unrecognized as WKT EWKT, and HEXEWKB.')
|
raise ValueError('String input unrecognized as WKT EWKT, and HEXEWKB.')
|
||||||
elif isinstance(geo_input, GEOM_PTR):
|
elif isinstance(geo_input, GEOM_PTR):
|
||||||
|
|
|
@ -224,9 +224,18 @@ Format Input Type
|
||||||
WKT / EWKT ``str``
|
WKT / EWKT ``str``
|
||||||
HEX / HEXEWKB ``str``
|
HEX / HEXEWKB ``str``
|
||||||
WKB / EWKB ``buffer``
|
WKB / EWKB ``buffer``
|
||||||
GeoJSON ``str``
|
GeoJSON_ ``str``
|
||||||
======================= ==========
|
======================= ==========
|
||||||
|
|
||||||
|
For the GeoJSON format, the SRID is set based on the ``crs`` member. If ``crs``
|
||||||
|
isn't provided, the SRID defaults to 4326.
|
||||||
|
|
||||||
|
.. versionchanged:: 2.0
|
||||||
|
|
||||||
|
In older versions, SRID isn't set for geometries initialized from GeoJSON.
|
||||||
|
|
||||||
|
.. _GeoJSON: https://tools.ietf.org/html/rfc7946
|
||||||
|
|
||||||
.. classmethod:: GEOSGeometry.from_gml(gml_string)
|
.. classmethod:: GEOSGeometry.from_gml(gml_string)
|
||||||
|
|
||||||
.. versionadded:: 1.11
|
.. versionadded:: 1.11
|
||||||
|
|
|
@ -71,6 +71,9 @@ Minor features
|
||||||
* Added the :class:`~django.contrib.gis.db.models.functions.LineLocatePoint`
|
* Added the :class:`~django.contrib.gis.db.models.functions.LineLocatePoint`
|
||||||
function, supported on PostGIS and SpatiaLite.
|
function, supported on PostGIS and SpatiaLite.
|
||||||
|
|
||||||
|
* Any :class:`~django.contrib.gis.geos.GEOSGeometry` imported from GeoJSON now
|
||||||
|
has its SRID set.
|
||||||
|
|
||||||
:mod:`django.contrib.messages`
|
:mod:`django.contrib.messages`
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -143,7 +143,21 @@ class GEOSTest(SimpleTestCase, TestDataMixin):
|
||||||
# Loading jsons to prevent decimal differences
|
# Loading jsons to prevent decimal differences
|
||||||
self.assertEqual(json.loads(g.json), json.loads(geom.json))
|
self.assertEqual(json.loads(g.json), json.loads(geom.json))
|
||||||
self.assertEqual(json.loads(g.json), json.loads(geom.geojson))
|
self.assertEqual(json.loads(g.json), json.loads(geom.geojson))
|
||||||
self.assertEqual(GEOSGeometry(g.wkt), GEOSGeometry(geom.json))
|
self.assertEqual(GEOSGeometry(g.wkt, 4326), GEOSGeometry(geom.json))
|
||||||
|
|
||||||
|
@skipUnless(HAS_GDAL, "GDAL is required.")
|
||||||
|
def test_json_srid(self):
|
||||||
|
geojson_data = {
|
||||||
|
"type": "Point",
|
||||||
|
"coordinates": [2, 49],
|
||||||
|
"crs": {
|
||||||
|
"type": "name",
|
||||||
|
"properties": {
|
||||||
|
"name": "urn:ogc:def:crs:EPSG::4322"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.assertEqual(GEOSGeometry(json.dumps(geojson_data)), Point(2, 49, srid=4322))
|
||||||
|
|
||||||
def test_fromfile(self):
|
def test_fromfile(self):
|
||||||
"Testing the fromfile() factory."
|
"Testing the fromfile() factory."
|
||||||
|
|
Loading…
Reference in New Issue