From cb27f7d2bf76baa66f01a63194eaf13c49619909 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 1 Aug 2017 13:54:05 +0000 Subject: [PATCH] GeoJSON: fix 2.2 regression regarding lack of setting the FeatureCollection CRS on feature geometries (fixes https://github.com/r-spatial/sf/issues/449#issuecomment-319369945) git-svn-id: https://svn.osgeo.org/gdal/branches/2.2@39706 f0d54148-0727-0410-94bb-9a71ac55c965 --- autotest/ogr/ogr_geojson.py | 27 +++++++++++++++++++ .../ogrsf_frmts/geojson/ogrgeojsonreader.cpp | 27 ++++++++++++++++--- .../ogrsf_frmts/geojson/ogrgeojsonreader.h | 2 +- 3 files changed, 51 insertions(+), 5 deletions(-) diff --git a/autotest/ogr/ogr_geojson.py b/autotest/ogr/ogr_geojson.py index f13529d6e4fc..7a026a4b10ec 100755 --- a/autotest/ogr/ogr_geojson.py +++ b/autotest/ogr/ogr_geojson.py @@ -3595,6 +3595,32 @@ def ogr_geojson_64(): return 'success' +############################################################################### +# Test feature geometry CRS when CRS set on the FeatureCollection +# See https://github.com/r-spatial/sf/issues/449#issuecomment-319369945 + +def ogr_geojson_65(): + + ds = ogr.Open("""{ +"type": "FeatureCollection", +"crs": { "type": "name", "properties": { "name": "urn:ogc:def:crs:EPSG::32631" } }, +"features": [{ +"type": "Feature", +"geometry": { +"type": "Point", +"coordinates": [500000,4500000]}, +"properties": { +}}]}""") + lyr = ds.GetLayer(0) + f = lyr.GetNextFeature() + srs = f.GetGeometryRef().GetSpatialReference() + pcs = int(srs.GetAuthorityCode('PROJCS')) + if pcs != 32631: + gdaltest.post_reason('Spatial reference for individual geometry was not valid') + return 'fail' + + return 'success' + gdaltest_list = [ ogr_geojson_1, ogr_geojson_2, @@ -3660,6 +3686,7 @@ def ogr_geojson_64(): ogr_geojson_62, ogr_geojson_63, ogr_geojson_64, + ogr_geojson_65, ogr_geojson_cleanup ] if __name__ == '__main__': diff --git a/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp b/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp index 02905580a04e..1ff8faa5dd98 100644 --- a/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp +++ b/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.cpp @@ -35,6 +35,10 @@ CPL_CVSID("$Id$"); +static +OGRGeometry* OGRGeoJSONReadGeometry( json_object* poObj, + OGRSpatialReference* poLayerSRS ); + /************************************************************************/ /* OGRGeoJSONReader */ /************************************************************************/ @@ -219,7 +223,7 @@ void OGRGeoJSONReader::ReadLayer( OGRGeoJSONDataSource* poDS, || GeoJSONObject::eMultiPolygon == objType || GeoJSONObject::eGeometryCollection == objType ) { - OGRGeometry* poGeometry = ReadGeometry( poObj ); + OGRGeometry* poGeometry = ReadGeometry( poObj, poLayer->GetSpatialRef() ); if( !AddFeature( poLayer, poGeometry ) ) { CPLDebug( "GeoJSON", "Translation of single geometry failed." ); @@ -1005,9 +1009,10 @@ bool OGRGeoJSONReader::AddFeature( OGRGeoJSONLayer* poLayer, /* ReadGeometry */ /************************************************************************/ -OGRGeometry* OGRGeoJSONReader::ReadGeometry( json_object* poObj ) +OGRGeometry* OGRGeoJSONReader::ReadGeometry( json_object* poObj, + OGRSpatialReference* poLayerSRS ) { - OGRGeometry* poGeometry = OGRGeoJSONReadGeometry( poObj ); + OGRGeometry* poGeometry = OGRGeoJSONReadGeometry( poObj, poLayerSRS ); /* -------------------------------------------------------------------- */ /* Wrap geometry with GeometryCollection as a common denominator. */ @@ -1344,7 +1349,8 @@ OGRFeature* OGRGeoJSONReader::ReadFeature( OGRGeoJSONLayer* poLayer, // NOTE: If geometry can not be parsed or read correctly // then NULL geometry is assigned to a feature and // geometry type for layer is classified as wkbUnknown. - OGRGeometry* poGeometry = ReadGeometry( poObjGeom ); + OGRGeometry* poGeometry = ReadGeometry( poObjGeom, + poLayer->GetSpatialRef() ); if( NULL != poGeometry ) { poFeature->SetGeometryDirectly( poGeometry ); @@ -1521,6 +1527,13 @@ GeoJSONObject::Type OGRGeoJSONGetType( json_object* poObj ) OGRGeometry* OGRGeoJSONReadGeometry( json_object* poObj ) { + return OGRGeoJSONReadGeometry(poObj, NULL); +} + +OGRGeometry* OGRGeoJSONReadGeometry( json_object* poObj, + OGRSpatialReference* poLayerSRS ) +{ + OGRGeometry* poGeometry = NULL; GeoJSONObject::Type objType = OGRGeoJSONGetType( poObj ); @@ -1560,9 +1573,15 @@ OGRGeometry* OGRGeoJSONReadGeometry( json_object* poObj ) } } } + else if( poLayerSRS ) + { + poGeometry->assignSpatialReference(poLayerSRS); + } else + { // Assign WGS84 if no CRS defined on geometry. poGeometry->assignSpatialReference(OGRSpatialReference::GetWGS84SRS()); + } } return poGeometry; } diff --git a/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.h b/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.h index 20fe348b9541..97f9df7ebe38 100644 --- a/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.h +++ b/gdal/ogr/ogrsf_frmts/geojson/ogrgeojsonreader.h @@ -143,7 +143,7 @@ class OGRGeoJSONReader static bool AddFeature( OGRGeoJSONLayer* poLayer, OGRGeometry* poGeometry ); static bool AddFeature( OGRGeoJSONLayer* poLayer, OGRFeature* poFeature ); - OGRGeometry* ReadGeometry( json_object* poObj ); + OGRGeometry* ReadGeometry( json_object* poObj, OGRSpatialReference* poLayerSRS ); OGRFeature* ReadFeature( OGRGeoJSONLayer* poLayer, json_object* poObj ); void ReadFeatureCollection( OGRGeoJSONLayer* poLayer, json_object* poObj ); };