diff --git a/autotest/ogr/ogr_jsonfg.py b/autotest/ogr/ogr_jsonfg.py index a94636f7af96..e95a7e5b92db 100755 --- a/autotest/ogr/ogr_jsonfg.py +++ b/autotest/ogr/ogr_jsonfg.py @@ -950,7 +950,7 @@ def test_jsonfg_write_several_layers(): [["GEOMETRYCOLLECTION (POINT (1 2))"], ogr.wkbGeometryCollection], [["GEOMETRYCOLLECTION Z (POINT Z (1 2 3))"], ogr.wkbGeometryCollection25D], [["POINT (1 2)", "LINESTRING (1 2,3 4)"], ogr.wkbUnknown], - [["POLYHEDRALSURFACE EMPTY"], ogr.wkbPolyhedralSurface], + [["POLYHEDRALSURFACE Z EMPTY"], ogr.wkbPolyhedralSurfaceZ], [ [ "POLYHEDRALSURFACE Z (((0 0 0,0 1 0,1 1 0,0 0 0)),((0 0 0,1 0 0,0 0 1,0 0 0)),((0 0 0,0 1 0,0 0 1,0 0 0)),((0 1 0,1 0 0,0 0 1,0 1 0)))" diff --git a/ogr/ogrsf_frmts/jsonfg/ogrjsonfgreader.cpp b/ogr/ogrsf_frmts/jsonfg/ogrjsonfgreader.cpp index a14ee55c9d6e..b6d95ae424cf 100644 --- a/ogr/ogrsf_frmts/jsonfg/ogrjsonfgreader.cpp +++ b/ogr/ogrsf_frmts/jsonfg/ogrjsonfgreader.cpp @@ -663,6 +663,50 @@ const char *OGRJSONFGReader::GetLayerNameForFeature(json_object *poObj) const return pszName; } +/************************************************************************/ +/* OGRJSONFGGetOGRGeometryType() */ +/************************************************************************/ + +static OGRwkbGeometryType OGRJSONFGGetOGRGeometryType(json_object *poObj) +{ + const auto eType = OGRGeoJSONGetOGRGeometryType(poObj); + if (eType != wkbUnknown) + return eType; + + json_object *poObjType = CPL_json_object_object_get(poObj, "type"); + const char *pszType = json_object_get_string(poObjType); + if (!pszType) + return wkbNone; + + if (strcmp(pszType, "Polyhedron") == 0) + { + return wkbPolyhedralSurfaceZ; + } + else if (strcmp(pszType, "Prism") == 0) + { + auto poBase = CPL_json_object_object_get(poObj, "base"); + if (!poBase || json_object_get_type(poBase) != json_type_object) + { + return wkbNone; + } + + const auto eBaseGeomType = OGRGeoJSONGetOGRGeometryType(poBase); + if (eBaseGeomType == wkbPoint) + { + return wkbLineString25D; + } + else if (eBaseGeomType == wkbLineString) + { + return wkbMultiPolygon25D; + } + else if (eBaseGeomType == wkbPolygon) + { + return wkbPolyhedralSurfaceZ; + } + } + return wkbNone; +} + /************************************************************************/ /* OGRJSONFGCreateNonGeoJSONGeometry() */ /************************************************************************/ @@ -708,6 +752,8 @@ OGRJSONFGCreateNonGeoJSONGeometry(json_object *poObj, bool bWarn) if (poGeom->addGeometryDirectly(poPoly) != OGRERR_NONE) return nullptr; } + if (nPolys == 0) + poGeom->set3D(true); return poGeom; } @@ -904,22 +950,8 @@ bool OGRJSONFGReader::GenerateLayerDefnFromFeature(json_object *poObj) (eGeometryElement_ != GeometryElement::PLACE); if (poPlace && json_object_get_type(poPlace) == json_type_object) { - const auto eType = OGRGeoJSONGetOGRGeometryType(poPlace); - if (eType == wkbUnknown) - { - auto poGeom = - OGRJSONFGCreateNonGeoJSONGeometry(poPlace, /*bWarn=*/true); - if (poGeom) - { - bFallbackToGeometry = false; - poContext->bDetectLayerGeomType = - OGRGeoJSONUpdateLayerGeomType( - poContext->bFirstGeometry, - poGeom->getGeometryType(), - poContext->eLayerGeomType); - } - } - else + const auto eType = OGRJSONFGGetOGRGeometryType(poPlace); + if (eType != wkbNone) { bFallbackToGeometry = false; poContext->bDetectLayerGeomType = OGRGeoJSONUpdateLayerGeomType(