Coverage Report

Created: 2025-11-15 08:43

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