Coverage Report

Created: 2025-06-09 08:44

/src/gdal/ogr/ogresrijsongeometry.cpp
Line
Count
Source (jump to first uncovered line)
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
0
{
24
0
    OGRGeometry *poGeometry = nullptr;
25
26
0
    if (OGRGeoJSONFindMemberByName(poObj, "x"))
27
0
        poGeometry = OGRESRIJSONReadPoint(poObj);
28
0
    else if (OGRGeoJSONFindMemberByName(poObj, "paths"))
29
0
        poGeometry = OGRESRIJSONReadLineString(poObj);
30
0
    else if (OGRGeoJSONFindMemberByName(poObj, "rings"))
31
0
        poGeometry = OGRESRIJSONReadPolygon(poObj);
32
0
    else if (OGRGeoJSONFindMemberByName(poObj, "points"))
33
0
        poGeometry = OGRESRIJSONReadMultiPoint(poObj);
34
35
0
    return poGeometry;
36
0
}
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
0
{
69
0
    if (nullptr == poObj)
70
0
        return wkbUnknown;
71
72
0
    json_object *poObjType = OGRGeoJSONFindMemberByName(poObj, "geometryType");
73
0
    if (nullptr == poObjType)
74
0
    {
75
0
        return wkbNone;
76
0
    }
77
78
0
    const char *name = json_object_get_string(poObjType);
79
0
    if (EQUAL(name, "esriGeometryPoint"))
80
0
        return wkbPoint;
81
0
    else if (EQUAL(name, "esriGeometryPolyline"))
82
0
        return wkbLineString;
83
0
    else if (EQUAL(name, "esriGeometryPolygon"))
84
0
        return wkbPolygon;
85
0
    else if (EQUAL(name, "esriGeometryMultiPoint"))
86
0
        return wkbMultiPoint;
87
0
    else
88
0
        return wkbUnknown;
89
0
}
90
91
/************************************************************************/
92
/*                     OGRESRIJSONGetCoordinateToDouble()               */
93
/************************************************************************/
94
95
static double OGRESRIJSONGetCoordinateToDouble(json_object *poObjCoord,
96
                                               const char *pszCoordName,
97
                                               bool &bValid)
98
0
{
99
0
    const int iType = json_object_get_type(poObjCoord);
100
0
    if (json_type_double != iType && json_type_int != iType)
101
0
    {
102
0
        CPLError(CE_Failure, CPLE_AppDefined,
103
0
                 "Invalid '%s' coordinate. "
104
0
                 "Type is not double or integer for \'%s\'.",
105
0
                 pszCoordName, json_object_to_json_string(poObjCoord));
106
0
        bValid = false;
107
0
        return 0.0;
108
0
    }
109
110
0
    return json_object_get_double(poObjCoord);
111
0
}
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
0
{
165
0
    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
0
    bool bZ = false;
171
0
    json_object *poObjHasZ = OGRGeoJSONFindMemberByName(poObj, "hasZ");
172
0
    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
0
    bool bM = false;
181
0
    json_object *poObjHasM = OGRGeoJSONFindMemberByName(poObj, "hasM");
182
0
    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
0
    if (bHasZ != nullptr)
190
0
        *bHasZ = bZ;
191
0
    if (bHasM != nullptr)
192
0
        *bHasM = bM;
193
0
}
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
0
{
205
0
    if (poObjCoords == nullptr)
206
0
    {
207
0
        CPLDebug("ESRIJSON",
208
0
                 "OGRESRIJSONReaderParseXYZMArray: got null object.");
209
0
        return false;
210
0
    }
211
212
0
    if (json_type_array != json_object_get_type(poObjCoords))
213
0
    {
214
0
        CPLDebug("ESRIJSON",
215
0
                 "OGRESRIJSONReaderParseXYZMArray: got non-array object.");
216
0
        return false;
217
0
    }
218
219
0
    const auto coordDimension = json_object_array_length(poObjCoords);
220
221
    // Allow 4 coordinates if M is present, but it is eventually ignored.
222
0
    if (coordDimension < 2 || coordDimension > 4)
223
0
    {
224
0
        CPLDebug("ESRIJSON",
225
0
                 "OGRESRIJSONReaderParseXYZMArray: got an unexpected "
226
0
                 "array object.");
227
0
        return false;
228
0
    }
229
230
    // Read X coordinate.
231
0
    json_object *poObjCoord = json_object_array_get_idx(poObjCoords, 0);
232
0
    if (poObjCoord == nullptr)
233
0
    {
234
0
        CPLDebug("ESRIJSON",
235
0
                 "OGRESRIJSONReaderParseXYZMArray: got null object.");
236
0
        return false;
237
0
    }
238
239
0
    bool bValid = true;
240
0
    const double dfX =
241
0
        OGRESRIJSONGetCoordinateToDouble(poObjCoord, "x", bValid);
242
243
    // Read Y coordinate.
244
0
    poObjCoord = json_object_array_get_idx(poObjCoords, 1);
245
0
    if (poObjCoord == nullptr)
246
0
    {
247
0
        CPLDebug("ESRIJSON",
248
0
                 "OGRESRIJSONReaderParseXYZMArray: got null object.");
249
0
        return false;
250
0
    }
251
252
0
    const double dfY =
253
0
        OGRESRIJSONGetCoordinateToDouble(poObjCoord, "y", bValid);
254
0
    if (!bValid)
255
0
        return false;
256
257
    // Read Z or M or Z and M coordinates.
258
0
    if (coordDimension > 2)
259
0
    {
260
0
        poObjCoord = json_object_array_get_idx(poObjCoords, 2);
261
0
        if (poObjCoord == nullptr)
262
0
        {
263
0
            CPLDebug("ESRIJSON",
264
0
                     "OGRESRIJSONReaderParseXYZMArray: got null object.");
265
0
            return false;
266
0
        }
267
268
0
        const double dfZorM = OGRESRIJSONGetCoordinateToDouble(
269
0
            poObjCoord, (coordDimension > 3 || !bHasM) ? "z" : "m", bValid);
270
0
        if (!bValid)
271
0
            return false;
272
0
        if (pdfZ != nullptr)
273
0
        {
274
0
            if (coordDimension > 3 || !bHasM)
275
0
                *pdfZ = dfZorM;
276
0
            else
277
0
                *pdfZ = 0.0;
278
0
        }
279
0
        if (pdfM != nullptr && coordDimension == 3)
280
0
        {
281
0
            if (bHasM)
282
0
                *pdfM = dfZorM;
283
0
            else
284
0
                *pdfM = 0.0;
285
0
        }
286
0
        if (coordDimension == 4)
287
0
        {
288
0
            poObjCoord = json_object_array_get_idx(poObjCoords, 3);
289
0
            if (poObjCoord == nullptr)
290
0
            {
291
0
                CPLDebug("ESRIJSON",
292
0
                         "OGRESRIJSONReaderParseXYZMArray: got null object.");
293
0
                return false;
294
0
            }
295
296
0
            const double dfM =
297
0
                OGRESRIJSONGetCoordinateToDouble(poObjCoord, "m", bValid);
298
0
            if (!bValid)
299
0
                return false;
300
0
            if (pdfM != nullptr)
301
0
                *pdfM = dfM;
302
0
        }
303
0
    }
304
0
    else
305
0
    {
306
0
        if (pdfZ != nullptr)
307
0
            *pdfZ = 0.0;
308
0
        if (pdfM != nullptr)
309
0
            *pdfM = 0.0;
310
0
    }
311
312
0
    if (pnNumCoords != nullptr)
313
0
        *pnNumCoords = static_cast<int>(coordDimension);
314
0
    if (pdfX != nullptr)
315
0
        *pdfX = dfX;
316
0
    if (pdfY != nullptr)
317
0
        *pdfY = dfY;
318
319
0
    return true;
320
0
}
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
0
{
428
0
    CPLAssert(nullptr != poObj);
429
430
0
    bool bHasZ = false;
431
0
    bool bHasM = false;
432
433
0
    OGRESRIJSONReaderParseZM(poObj, &bHasZ, &bHasM);
434
435
0
    json_object *poObjRings = OGRGeoJSONFindMemberByName(poObj, "rings");
436
0
    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
0
    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
0
    const auto nRings = json_object_array_length(poObjRings);
453
0
    OGRGeometry **papoGeoms = new OGRGeometry *[nRings];
454
0
    for (auto iRing = decltype(nRings){0}; iRing < nRings; iRing++)
455
0
    {
456
0
        json_object *poObjRing = json_object_array_get_idx(poObjRings, iRing);
457
0
        if (poObjRing == nullptr ||
458
0
            json_type_array != json_object_get_type(poObjRing))
459
0
        {
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
0
        }
466
467
0
        OGRPolygon *poPoly = new OGRPolygon();
468
0
        auto poLine = std::make_unique<OGRLinearRing>();
469
0
        papoGeoms[iRing] = poPoly;
470
471
0
        const auto nPoints = json_object_array_length(poObjRing);
472
0
        for (auto i = decltype(nPoints){0}; i < nPoints; i++)
473
0
        {
474
0
            int nNumCoords = 2;
475
0
            json_object *poObjCoords = json_object_array_get_idx(poObjRing, i);
476
0
            double dfX = 0.0;
477
0
            double dfY = 0.0;
478
0
            double dfZ = 0.0;
479
0
            double dfM = 0.0;
480
0
            if (!OGRESRIJSONReaderParseXYZMArray(poObjCoords, bHasZ, bHasM,
481
0
                                                 &dfX, &dfY, &dfZ, &dfM,
482
0
                                                 &nNumCoords))
483
0
            {
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
0
            }
489
490
0
            if (nNumCoords == 3 && !bHasM)
491
0
            {
492
0
                poLine->addPoint(dfX, dfY, dfZ);
493
0
            }
494
0
            else if (nNumCoords == 3)
495
0
            {
496
0
                poLine->addPointM(dfX, dfY, dfM);
497
0
            }
498
0
            else if (nNumCoords == 4)
499
0
            {
500
0
                poLine->addPoint(dfX, dfY, dfZ, dfM);
501
0
            }
502
0
            else
503
0
            {
504
0
                poLine->addPoint(dfX, dfY);
505
0
            }
506
0
        }
507
0
        poPoly->addRingDirectly(poLine.release());
508
0
    }
509
510
0
    OGRGeometry *poRet = OGRGeometryFactory::organizePolygons(
511
0
        papoGeoms, static_cast<int>(nRings), nullptr, nullptr);
512
0
    delete[] papoGeoms;
513
514
0
    return poRet;
515
0
}
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
0
{
594
    /* -------------------------------------------------------------------- */
595
    /*      Read spatial reference definition.                              */
596
    /* -------------------------------------------------------------------- */
597
0
    OGRSpatialReference *poSRS = nullptr;
598
599
0
    json_object *poObjSrs =
600
0
        OGRGeoJSONFindMemberByName(poObj, "spatialReference");
601
0
    if (nullptr != poObjSrs)
602
0
    {
603
0
        json_object *poObjWkid =
604
0
            OGRGeoJSONFindMemberByName(poObjSrs, "latestWkid");
605
0
        if (poObjWkid == nullptr)
606
0
            poObjWkid = OGRGeoJSONFindMemberByName(poObjSrs, "wkid");
607
0
        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
0
        const int nEPSG = json_object_get_int(poObjWkid);
636
637
0
        poSRS = new OGRSpatialReference();
638
0
        poSRS->SetAxisMappingStrategy(OAMS_TRADITIONAL_GIS_ORDER);
639
0
        if (OGRERR_NONE != poSRS->importFromEPSG(nEPSG))
640
0
        {
641
0
            delete poSRS;
642
0
            poSRS = nullptr;
643
0
        }
644
0
    }
645
646
0
    return poSRS;
647
0
}
648
649
/*! @endcond */