LCOV - code coverage report
Current view: top level - ogr - ogresrijsongeometry.cpp (source / functions) Hit Total Coverage
Test: gdal_filtered.info Lines: 241 307 78.5 %
Date: 2024-11-21 22:18:42 Functions: 12 12 100.0 %

          Line data    Source code
       1             : // SPDX-License-Identifier: MIT
       2             : // Copyright 2024, Even Rouault <even.rouault at spatialys.com>
       3             : 
       4             : /*! @cond Doxygen_Suppress */
       5             : 
       6             : #include "ogresrijsongeometry.h"
       7             : 
       8             : #include "ogrlibjsonutils.h"
       9             : 
      10             : #include "ogr_geometry.h"
      11             : #include "ogr_spatialref.h"
      12             : 
      13             : static OGRPoint *OGRESRIJSONReadPoint(json_object *poObj);
      14             : static OGRGeometry *OGRESRIJSONReadLineString(json_object *poObj);
      15             : static OGRGeometry *OGRESRIJSONReadPolygon(json_object *poObj);
      16             : static OGRMultiPoint *OGRESRIJSONReadMultiPoint(json_object *poObj);
      17             : 
      18             : /************************************************************************/
      19             : /*                       OGRESRIJSONReadGeometry()                      */
      20             : /************************************************************************/
      21             : 
      22          19 : OGRGeometry *OGRESRIJSONReadGeometry(json_object *poObj)
      23             : {
      24          19 :     OGRGeometry *poGeometry = nullptr;
      25             : 
      26          19 :     if (OGRGeoJSONFindMemberByName(poObj, "x"))
      27           6 :         poGeometry = OGRESRIJSONReadPoint(poObj);
      28          13 :     else if (OGRGeoJSONFindMemberByName(poObj, "paths"))
      29           3 :         poGeometry = OGRESRIJSONReadLineString(poObj);
      30          10 :     else if (OGRGeoJSONFindMemberByName(poObj, "rings"))
      31           5 :         poGeometry = OGRESRIJSONReadPolygon(poObj);
      32           5 :     else if (OGRGeoJSONFindMemberByName(poObj, "points"))
      33           5 :         poGeometry = OGRESRIJSONReadMultiPoint(poObj);
      34             : 
      35          19 :     return poGeometry;
      36             : }
      37             : 
      38             : /************************************************************************/
      39             : /*                     OGR_G_CreateGeometryFromEsriJson()               */
      40             : /************************************************************************/
      41             : 
      42             : /** Create a OGR geometry from a ESRIJson geometry object */
      43           2 : OGRGeometryH OGR_G_CreateGeometryFromEsriJson(const char *pszJson)
      44             : {
      45           2 :     if (nullptr == pszJson)
      46             :     {
      47             :         // Translation failed.
      48           0 :         return nullptr;
      49             :     }
      50             : 
      51           2 :     json_object *poObj = nullptr;
      52           2 :     if (!OGRJSonParse(pszJson, &poObj))
      53           1 :         return nullptr;
      54             : 
      55           1 :     OGRGeometry *poGeometry = OGRESRIJSONReadGeometry(poObj);
      56             : 
      57             :     // Release JSON tree.
      58           1 :     json_object_put(poObj);
      59             : 
      60           1 :     return OGRGeometry::ToHandle(poGeometry);
      61             : }
      62             : 
      63             : /************************************************************************/
      64             : /*                        OGRESRIJSONGetType()                          */
      65             : /************************************************************************/
      66             : 
      67          21 : OGRwkbGeometryType OGRESRIJSONGetGeometryType(json_object *poObj)
      68             : {
      69          21 :     if (nullptr == poObj)
      70           0 :         return wkbUnknown;
      71             : 
      72          21 :     json_object *poObjType = OGRGeoJSONFindMemberByName(poObj, "geometryType");
      73          21 :     if (nullptr == poObjType)
      74             :     {
      75           1 :         return wkbNone;
      76             :     }
      77             : 
      78          20 :     const char *name = json_object_get_string(poObjType);
      79          20 :     if (EQUAL(name, "esriGeometryPoint"))
      80           8 :         return wkbPoint;
      81          12 :     else if (EQUAL(name, "esriGeometryPolyline"))
      82           3 :         return wkbLineString;
      83           9 :     else if (EQUAL(name, "esriGeometryPolygon"))
      84           4 :         return wkbPolygon;
      85           5 :     else if (EQUAL(name, "esriGeometryMultiPoint"))
      86           5 :         return wkbMultiPoint;
      87             :     else
      88           0 :         return wkbUnknown;
      89             : }
      90             : 
      91             : /************************************************************************/
      92             : /*                     OGRESRIJSONGetCoordinateToDouble()               */
      93             : /************************************************************************/
      94             : 
      95         175 : static double OGRESRIJSONGetCoordinateToDouble(json_object *poObjCoord,
      96             :                                                const char *pszCoordName,
      97             :                                                bool &bValid)
      98             : {
      99         175 :     const int iType = json_object_get_type(poObjCoord);
     100         175 :     if (json_type_double != iType && json_type_int != iType)
     101             :     {
     102           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     103             :                  "Invalid '%s' coordinate. "
     104             :                  "Type is not double or integer for \'%s\'.",
     105             :                  pszCoordName, json_object_to_json_string(poObjCoord));
     106           0 :         bValid = false;
     107           0 :         return 0.0;
     108             :     }
     109             : 
     110         175 :     return json_object_get_double(poObjCoord);
     111             : }
     112             : 
     113             : /************************************************************************/
     114             : /*                       OGRESRIJSONGetCoordinate()                     */
     115             : /************************************************************************/
     116             : 
     117          12 : static double OGRESRIJSONGetCoordinate(json_object *poObj,
     118             :                                        const char *pszCoordName, bool &bValid)
     119             : {
     120          12 :     json_object *poObjCoord = OGRGeoJSONFindMemberByName(poObj, pszCoordName);
     121          12 :     if (nullptr == poObjCoord)
     122             :     {
     123           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     124             :                  "Invalid Point object. "
     125             :                  "Missing '%s' member.",
     126             :                  pszCoordName);
     127           0 :         bValid = false;
     128           0 :         return 0.0;
     129             :     }
     130             : 
     131          12 :     return OGRESRIJSONGetCoordinateToDouble(poObjCoord, pszCoordName, bValid);
     132             : }
     133             : 
     134             : /************************************************************************/
     135             : /*                          OGRESRIJSONReadPoint()                      */
     136             : /************************************************************************/
     137             : 
     138           6 : OGRPoint *OGRESRIJSONReadPoint(json_object *poObj)
     139             : {
     140           6 :     CPLAssert(nullptr != poObj);
     141             : 
     142           6 :     bool bValid = true;
     143           6 :     const double dfX = OGRESRIJSONGetCoordinate(poObj, "x", bValid);
     144           6 :     const double dfY = OGRESRIJSONGetCoordinate(poObj, "y", bValid);
     145           6 :     if (!bValid)
     146           0 :         return nullptr;
     147             : 
     148           6 :     json_object *poObjZ = OGRGeoJSONFindMemberByName(poObj, "z");
     149           6 :     if (nullptr == poObjZ)
     150           3 :         return new OGRPoint(dfX, dfY);
     151             : 
     152           3 :     const double dfZ = OGRESRIJSONGetCoordinateToDouble(poObjZ, "z", bValid);
     153           3 :     if (!bValid)
     154           0 :         return nullptr;
     155           3 :     return new OGRPoint(dfX, dfY, dfZ);
     156             : }
     157             : 
     158             : /************************************************************************/
     159             : /*                     OGRESRIJSONReaderParseZM()                      */
     160             : /************************************************************************/
     161             : 
     162          13 : static void OGRESRIJSONReaderParseZM(json_object *poObj, bool *bHasZ,
     163             :                                      bool *bHasM)
     164             : {
     165          13 :     CPLAssert(nullptr != poObj);
     166             :     // The ESRI geojson spec states that geometries other than point can
     167             :     // have the attributes hasZ and hasM.  A geometry that has a z value
     168             :     // implies the 3rd number in the tuple is z.  if hasM is true, but hasZ
     169             :     // is not, it is the M value.
     170          13 :     bool bZ = false;
     171          13 :     json_object *poObjHasZ = OGRGeoJSONFindMemberByName(poObj, "hasZ");
     172          13 :     if (poObjHasZ != nullptr)
     173             :     {
     174           2 :         if (json_object_get_type(poObjHasZ) == json_type_boolean)
     175             :         {
     176           2 :             bZ = CPL_TO_BOOL(json_object_get_boolean(poObjHasZ));
     177             :         }
     178             :     }
     179             : 
     180          13 :     bool bM = false;
     181          13 :     json_object *poObjHasM = OGRGeoJSONFindMemberByName(poObj, "hasM");
     182          13 :     if (poObjHasM != nullptr)
     183             :     {
     184           2 :         if (json_object_get_type(poObjHasM) == json_type_boolean)
     185             :         {
     186           2 :             bM = CPL_TO_BOOL(json_object_get_boolean(poObjHasM));
     187             :         }
     188             :     }
     189          13 :     if (bHasZ != nullptr)
     190          13 :         *bHasZ = bZ;
     191          13 :     if (bHasM != nullptr)
     192          13 :         *bHasM = bM;
     193          13 : }
     194             : 
     195             : /************************************************************************/
     196             : /*                     OGRESRIJSONReaderParseXYZMArray()                  */
     197             : /************************************************************************/
     198             : 
     199          70 : static bool OGRESRIJSONReaderParseXYZMArray(json_object *poObjCoords,
     200             :                                             bool /*bHasZ*/, bool bHasM,
     201             :                                             double *pdfX, double *pdfY,
     202             :                                             double *pdfZ, double *pdfM,
     203             :                                             int *pnNumCoords)
     204             : {
     205          70 :     if (poObjCoords == nullptr)
     206             :     {
     207           0 :         CPLDebug("ESRIJSON",
     208             :                  "OGRESRIJSONReaderParseXYZMArray: got null object.");
     209           0 :         return false;
     210             :     }
     211             : 
     212          70 :     if (json_type_array != json_object_get_type(poObjCoords))
     213             :     {
     214           0 :         CPLDebug("ESRIJSON",
     215             :                  "OGRESRIJSONReaderParseXYZMArray: got non-array object.");
     216           0 :         return false;
     217             :     }
     218             : 
     219          70 :     const auto coordDimension = json_object_array_length(poObjCoords);
     220             : 
     221             :     // Allow 4 coordinates if M is present, but it is eventually ignored.
     222          70 :     if (coordDimension < 2 || coordDimension > 4)
     223             :     {
     224           0 :         CPLDebug("ESRIJSON",
     225             :                  "OGRESRIJSONReaderParseXYZMArray: got an unexpected "
     226             :                  "array object.");
     227           0 :         return false;
     228             :     }
     229             : 
     230             :     // Read X coordinate.
     231          70 :     json_object *poObjCoord = json_object_array_get_idx(poObjCoords, 0);
     232          70 :     if (poObjCoord == nullptr)
     233             :     {
     234           0 :         CPLDebug("ESRIJSON",
     235             :                  "OGRESRIJSONReaderParseXYZMArray: got null object.");
     236           0 :         return false;
     237             :     }
     238             : 
     239          70 :     bool bValid = true;
     240             :     const double dfX =
     241          70 :         OGRESRIJSONGetCoordinateToDouble(poObjCoord, "x", bValid);
     242             : 
     243             :     // Read Y coordinate.
     244          70 :     poObjCoord = json_object_array_get_idx(poObjCoords, 1);
     245          70 :     if (poObjCoord == nullptr)
     246             :     {
     247           0 :         CPLDebug("ESRIJSON",
     248             :                  "OGRESRIJSONReaderParseXYZMArray: got null object.");
     249           0 :         return false;
     250             :     }
     251             : 
     252             :     const double dfY =
     253          70 :         OGRESRIJSONGetCoordinateToDouble(poObjCoord, "y", bValid);
     254          70 :     if (!bValid)
     255           0 :         return false;
     256             : 
     257             :     // Read Z or M or Z and M coordinates.
     258          70 :     if (coordDimension > 2)
     259             :     {
     260          18 :         poObjCoord = json_object_array_get_idx(poObjCoords, 2);
     261          18 :         if (poObjCoord == nullptr)
     262             :         {
     263           0 :             CPLDebug("ESRIJSON",
     264             :                      "OGRESRIJSONReaderParseXYZMArray: got null object.");
     265           0 :             return false;
     266             :         }
     267             : 
     268          34 :         const double dfZorM = OGRESRIJSONGetCoordinateToDouble(
     269          16 :             poObjCoord, (coordDimension > 3 || !bHasM) ? "z" : "m", bValid);
     270          18 :         if (!bValid)
     271           0 :             return false;
     272          18 :         if (pdfZ != nullptr)
     273             :         {
     274          18 :             if (coordDimension > 3 || !bHasM)
     275          16 :                 *pdfZ = dfZorM;
     276             :             else
     277           2 :                 *pdfZ = 0.0;
     278             :         }
     279          18 :         if (pdfM != nullptr && coordDimension == 3)
     280             :         {
     281          16 :             if (bHasM)
     282           2 :                 *pdfM = dfZorM;
     283             :             else
     284          14 :                 *pdfM = 0.0;
     285             :         }
     286          18 :         if (coordDimension == 4)
     287             :         {
     288           2 :             poObjCoord = json_object_array_get_idx(poObjCoords, 3);
     289           2 :             if (poObjCoord == nullptr)
     290             :             {
     291           0 :                 CPLDebug("ESRIJSON",
     292             :                          "OGRESRIJSONReaderParseXYZMArray: got null object.");
     293           0 :                 return false;
     294             :             }
     295             : 
     296             :             const double dfM =
     297           2 :                 OGRESRIJSONGetCoordinateToDouble(poObjCoord, "m", bValid);
     298           2 :             if (!bValid)
     299           0 :                 return false;
     300           2 :             if (pdfM != nullptr)
     301           2 :                 *pdfM = dfM;
     302             :         }
     303             :     }
     304             :     else
     305             :     {
     306          52 :         if (pdfZ != nullptr)
     307          52 :             *pdfZ = 0.0;
     308          52 :         if (pdfM != nullptr)
     309          52 :             *pdfM = 0.0;
     310             :     }
     311             : 
     312          70 :     if (pnNumCoords != nullptr)
     313          70 :         *pnNumCoords = static_cast<int>(coordDimension);
     314          70 :     if (pdfX != nullptr)
     315          70 :         *pdfX = dfX;
     316          70 :     if (pdfY != nullptr)
     317          70 :         *pdfY = dfY;
     318             : 
     319          70 :     return true;
     320             : }
     321             : 
     322             : /************************************************************************/
     323             : /*                        OGRESRIJSONReadLineString()                   */
     324             : /************************************************************************/
     325             : 
     326           3 : OGRGeometry *OGRESRIJSONReadLineString(json_object *poObj)
     327             : {
     328           3 :     CPLAssert(nullptr != poObj);
     329             : 
     330           3 :     bool bHasZ = false;
     331           3 :     bool bHasM = false;
     332             : 
     333           3 :     OGRESRIJSONReaderParseZM(poObj, &bHasZ, &bHasM);
     334             : 
     335           3 :     json_object *poObjPaths = OGRGeoJSONFindMemberByName(poObj, "paths");
     336           3 :     if (nullptr == poObjPaths)
     337             :     {
     338           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     339             :                  "Invalid LineString object. "
     340             :                  "Missing \'paths\' member.");
     341           0 :         return nullptr;
     342             :     }
     343             : 
     344           3 :     if (json_type_array != json_object_get_type(poObjPaths))
     345             :     {
     346           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     347             :                  "Invalid LineString object. "
     348             :                  "Invalid \'paths\' member.");
     349           0 :         return nullptr;
     350             :     }
     351             : 
     352           3 :     OGRMultiLineString *poMLS = nullptr;
     353           3 :     OGRGeometry *poRet = nullptr;
     354           3 :     const auto nPaths = json_object_array_length(poObjPaths);
     355           7 :     for (auto iPath = decltype(nPaths){0}; iPath < nPaths; iPath++)
     356             :     {
     357           4 :         json_object *poObjPath = json_object_array_get_idx(poObjPaths, iPath);
     358           8 :         if (poObjPath == nullptr ||
     359           4 :             json_type_array != json_object_get_type(poObjPath))
     360             :         {
     361           0 :             delete poRet;
     362           0 :             CPLDebug("ESRIJSON", "LineString: got non-array object.");
     363           0 :             return nullptr;
     364             :         }
     365             : 
     366           4 :         OGRLineString *poLine = new OGRLineString();
     367           4 :         if (nPaths > 1)
     368             :         {
     369           2 :             if (iPath == 0)
     370             :             {
     371           1 :                 poMLS = new OGRMultiLineString();
     372           1 :                 poRet = poMLS;
     373             :             }
     374           2 :             poMLS->addGeometryDirectly(poLine);
     375             :         }
     376             :         else
     377             :         {
     378           2 :             poRet = poLine;
     379             :         }
     380           4 :         const auto nPoints = json_object_array_length(poObjPath);
     381          12 :         for (auto i = decltype(nPoints){0}; i < nPoints; i++)
     382             :         {
     383           8 :             int nNumCoords = 2;
     384           8 :             json_object *poObjCoords = json_object_array_get_idx(poObjPath, i);
     385           8 :             double dfX = 0.0;
     386           8 :             double dfY = 0.0;
     387           8 :             double dfZ = 0.0;
     388           8 :             double dfM = 0.0;
     389           8 :             if (!OGRESRIJSONReaderParseXYZMArray(poObjCoords, bHasZ, bHasM,
     390             :                                                  &dfX, &dfY, &dfZ, &dfM,
     391             :                                                  &nNumCoords))
     392             :             {
     393           0 :                 delete poRet;
     394           0 :                 return nullptr;
     395             :             }
     396             : 
     397           8 :             if (nNumCoords == 3 && !bHasM)
     398             :             {
     399           2 :                 poLine->addPoint(dfX, dfY, dfZ);
     400             :             }
     401           6 :             else if (nNumCoords == 3)
     402             :             {
     403           0 :                 poLine->addPointM(dfX, dfY, dfM);
     404             :             }
     405           6 :             else if (nNumCoords == 4)
     406             :             {
     407           0 :                 poLine->addPoint(dfX, dfY, dfZ, dfM);
     408             :             }
     409             :             else
     410             :             {
     411           6 :                 poLine->addPoint(dfX, dfY);
     412             :             }
     413             :         }
     414             :     }
     415             : 
     416           3 :     if (poRet == nullptr)
     417           0 :         poRet = new OGRLineString();
     418             : 
     419           3 :     return poRet;
     420             : }
     421             : 
     422             : /************************************************************************/
     423             : /*                          OGRESRIJSONReadPolygon()                    */
     424             : /************************************************************************/
     425             : 
     426           5 : OGRGeometry *OGRESRIJSONReadPolygon(json_object *poObj)
     427             : {
     428           5 :     CPLAssert(nullptr != poObj);
     429             : 
     430           5 :     bool bHasZ = false;
     431           5 :     bool bHasM = false;
     432             : 
     433           5 :     OGRESRIJSONReaderParseZM(poObj, &bHasZ, &bHasM);
     434             : 
     435           5 :     json_object *poObjRings = OGRGeoJSONFindMemberByName(poObj, "rings");
     436           5 :     if (nullptr == poObjRings)
     437             :     {
     438           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     439             :                  "Invalid Polygon object. "
     440             :                  "Missing \'rings\' member.");
     441           0 :         return nullptr;
     442             :     }
     443             : 
     444           5 :     if (json_type_array != json_object_get_type(poObjRings))
     445             :     {
     446           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     447             :                  "Invalid Polygon object. "
     448             :                  "Invalid \'rings\' member.");
     449           0 :         return nullptr;
     450             :     }
     451             : 
     452           5 :     const auto nRings = json_object_array_length(poObjRings);
     453           5 :     OGRGeometry **papoGeoms = new OGRGeometry *[nRings];
     454          11 :     for (auto iRing = decltype(nRings){0}; iRing < nRings; iRing++)
     455             :     {
     456           6 :         json_object *poObjRing = json_object_array_get_idx(poObjRings, iRing);
     457          12 :         if (poObjRing == nullptr ||
     458           6 :             json_type_array != json_object_get_type(poObjRing))
     459             :         {
     460           0 :             for (auto j = decltype(iRing){0}; j < iRing; j++)
     461           0 :                 delete papoGeoms[j];
     462           0 :             delete[] papoGeoms;
     463           0 :             CPLDebug("ESRIJSON", "Polygon: got non-array object.");
     464           0 :             return nullptr;
     465             :         }
     466             : 
     467           6 :         OGRPolygon *poPoly = new OGRPolygon();
     468           6 :         auto poLine = std::make_unique<OGRLinearRing>();
     469           6 :         papoGeoms[iRing] = poPoly;
     470             : 
     471           6 :         const auto nPoints = json_object_array_length(poObjRing);
     472          58 :         for (auto i = decltype(nPoints){0}; i < nPoints; i++)
     473             :         {
     474          52 :             int nNumCoords = 2;
     475          52 :             json_object *poObjCoords = json_object_array_get_idx(poObjRing, i);
     476          52 :             double dfX = 0.0;
     477          52 :             double dfY = 0.0;
     478          52 :             double dfZ = 0.0;
     479          52 :             double dfM = 0.0;
     480          52 :             if (!OGRESRIJSONReaderParseXYZMArray(poObjCoords, bHasZ, bHasM,
     481             :                                                  &dfX, &dfY, &dfZ, &dfM,
     482             :                                                  &nNumCoords))
     483             :             {
     484           0 :                 for (auto j = decltype(iRing){0}; j <= iRing; j++)
     485           0 :                     delete papoGeoms[j];
     486           0 :                 delete[] papoGeoms;
     487           0 :                 return nullptr;
     488             :             }
     489             : 
     490          52 :             if (nNumCoords == 3 && !bHasM)
     491             :             {
     492          10 :                 poLine->addPoint(dfX, dfY, dfZ);
     493             :             }
     494          42 :             else if (nNumCoords == 3)
     495             :             {
     496           0 :                 poLine->addPointM(dfX, dfY, dfM);
     497             :             }
     498          42 :             else if (nNumCoords == 4)
     499             :             {
     500           0 :                 poLine->addPoint(dfX, dfY, dfZ, dfM);
     501             :             }
     502             :             else
     503             :             {
     504          42 :                 poLine->addPoint(dfX, dfY);
     505             :             }
     506             :         }
     507           6 :         poPoly->addRingDirectly(poLine.release());
     508             :     }
     509             : 
     510           5 :     OGRGeometry *poRet = OGRGeometryFactory::organizePolygons(
     511             :         papoGeoms, static_cast<int>(nRings), nullptr, nullptr);
     512           5 :     delete[] papoGeoms;
     513             : 
     514           5 :     return poRet;
     515             : }
     516             : 
     517             : /************************************************************************/
     518             : /*                        OGRESRIJSONReadMultiPoint()                   */
     519             : /************************************************************************/
     520             : 
     521           5 : OGRMultiPoint *OGRESRIJSONReadMultiPoint(json_object *poObj)
     522             : {
     523           5 :     CPLAssert(nullptr != poObj);
     524             : 
     525           5 :     bool bHasZ = false;
     526           5 :     bool bHasM = false;
     527             : 
     528           5 :     OGRESRIJSONReaderParseZM(poObj, &bHasZ, &bHasM);
     529             : 
     530           5 :     json_object *poObjPoints = OGRGeoJSONFindMemberByName(poObj, "points");
     531           5 :     if (nullptr == poObjPoints)
     532             :     {
     533           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     534             :                  "Invalid MultiPoint object. "
     535             :                  "Missing \'points\' member.");
     536           0 :         return nullptr;
     537             :     }
     538             : 
     539           5 :     if (json_type_array != json_object_get_type(poObjPoints))
     540             :     {
     541           0 :         CPLError(CE_Failure, CPLE_AppDefined,
     542             :                  "Invalid MultiPoint object. "
     543             :                  "Invalid \'points\' member.");
     544           0 :         return nullptr;
     545             :     }
     546             : 
     547           5 :     OGRMultiPoint *poMulti = new OGRMultiPoint();
     548             : 
     549           5 :     const auto nPoints = json_object_array_length(poObjPoints);
     550          15 :     for (auto i = decltype(nPoints){0}; i < nPoints; i++)
     551             :     {
     552          10 :         int nNumCoords = 2;
     553          10 :         json_object *poObjCoords = json_object_array_get_idx(poObjPoints, i);
     554          10 :         double dfX = 0.0;
     555          10 :         double dfY = 0.0;
     556          10 :         double dfZ = 0.0;
     557          10 :         double dfM = 0.0;
     558          10 :         if (!OGRESRIJSONReaderParseXYZMArray(poObjCoords, bHasZ, bHasM, &dfX,
     559             :                                              &dfY, &dfZ, &dfM, &nNumCoords))
     560             :         {
     561           0 :             delete poMulti;
     562           0 :             return nullptr;
     563             :         }
     564             : 
     565          10 :         if (nNumCoords == 3 && !bHasM)
     566             :         {
     567           2 :             poMulti->addGeometryDirectly(new OGRPoint(dfX, dfY, dfZ));
     568             :         }
     569           8 :         else if (nNumCoords == 3)
     570             :         {
     571           2 :             OGRPoint *poPoint = new OGRPoint(dfX, dfY);
     572           2 :             poPoint->setM(dfM);
     573           2 :             poMulti->addGeometryDirectly(poPoint);
     574             :         }
     575           6 :         else if (nNumCoords == 4)
     576             :         {
     577           2 :             poMulti->addGeometryDirectly(new OGRPoint(dfX, dfY, dfZ, dfM));
     578             :         }
     579             :         else
     580             :         {
     581           4 :             poMulti->addGeometryDirectly(new OGRPoint(dfX, dfY));
     582             :         }
     583             :     }
     584             : 
     585           5 :     return poMulti;
     586             : }
     587             : 
     588             : /************************************************************************/
     589             : /*                    OGRESRIJSONReadSpatialReference()                 */
     590             : /************************************************************************/
     591             : 
     592          22 : OGRSpatialReference *OGRESRIJSONReadSpatialReference(json_object *poObj)
     593             : {
     594             :     /* -------------------------------------------------------------------- */
     595             :     /*      Read spatial reference definition.                              */
     596             :     /* -------------------------------------------------------------------- */
     597          22 :     OGRSpatialReference *poSRS = nullptr;
     598             : 
     599             :     json_object *poObjSrs =
     600          22 :         OGRGeoJSONFindMemberByName(poObj, "spatialReference");
     601          22 :     if (nullptr != poObjSrs)
     602             :     {
     603             :         json_object *poObjWkid =
     604          10 :             OGRGeoJSONFindMemberByName(poObjSrs, "latestWkid");
     605          10 :         if (poObjWkid == nullptr)
     606           9 :             poObjWkid = OGRGeoJSONFindMemberByName(poObjSrs, "wkid");
     607          10 :         if (poObjWkid == nullptr)
     608             :         {
     609           1 :             json_object *poObjWkt = OGRGeoJSONFindMemberByName(poObjSrs, "wkt");
     610           1 :             if (poObjWkt == nullptr)
     611           0 :                 return nullptr;
     612             : 
     613           1 :             const char *pszWKT = json_object_get_string(poObjWkt);
     614           1 :             poSRS = new OGRSpatialReference();
     615           1 :             poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
     616           1 :             if (OGRERR_NONE != poSRS->importFromWkt(pszWKT))
     617             :             {
     618           0 :                 delete poSRS;
     619           0 :                 poSRS = nullptr;
     620             :             }
     621             :             else
     622             :             {
     623           1 :                 auto poSRSMatch = poSRS->FindBestMatch(70);
     624           1 :                 if (poSRSMatch)
     625             :                 {
     626           1 :                     poSRS->Release();
     627           1 :                     poSRS = poSRSMatch;
     628           1 :                     poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
     629             :                 }
     630             :             }
     631             : 
     632           1 :             return poSRS;
     633             :         }
     634             : 
     635           9 :         const int nEPSG = json_object_get_int(poObjWkid);
     636             : 
     637           9 :         poSRS = new OGRSpatialReference();
     638           9 :         poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
     639           9 :         if (OGRERR_NONE != poSRS->importFromEPSG(nEPSG))
     640             :         {
     641           0 :             delete poSRS;
     642           0 :             poSRS = nullptr;
     643             :         }
     644             :     }
     645             : 
     646          21 :     return poSRS;
     647             : }
     648             : 
     649             : /*! @endcond */

Generated by: LCOV version 1.14