Skip to content

Commit fbc8211

Browse files
authored
Merge pull request OSGeo#13102 from rouault/fix_13093
ESRIJSON: recognize esriFieldTypeDateOnly, esriFieldTypeTimeOnly, esriFieldTypeBigInteger, esriFieldTypeGUID and esriFieldTypeGlobalID data types
2 parents 8640268 + 934dfb4 commit fbc8211

File tree

4 files changed

+110
-40
lines changed

4 files changed

+110
-40
lines changed

autotest/ogr/data/esrijson/esripoint.json

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,31 @@
4444
"alias": "fooDate",
4545
"type": "esriFieldTypeDate",
4646
"length": 8
47+
},
48+
{
49+
"name": "fooDateOnly",
50+
"alias": "fooDateOnly",
51+
"type": "esriFieldTypeDateOnly",
52+
},
53+
{
54+
"name": "fooTimeOnly",
55+
"alias": "fooTimeOnly",
56+
"type": "esriFieldTypeTimeOnly",
57+
},
58+
{
59+
"name": "fooBigInteger",
60+
"alias": "fooBigInteger",
61+
"type": "esriFieldTypeBigInteger",
62+
},
63+
{
64+
"name": "fooGUID",
65+
"alias": "fooGUID",
66+
"type": "esriFieldTypeGUID",
67+
},
68+
{
69+
"name": "fooGlobalID",
70+
"alias": "fooGlobalID",
71+
"type": "esriFieldTypeGlobalID",
4772
}
4873
],
4974
"features" : [
@@ -59,7 +84,12 @@
5984
"fooSingle" : 1.5,
6085
"fooDouble" : 3.4,
6186
"fooString" : "56",
62-
"fooDate": 1640908800000
87+
"fooDate": 1640908800000,
88+
"fooDateOnly": "2025-09-20",
89+
"fooTimeOnly": "12:34:56",
90+
"fooBigInteger": 1234567890123456,
91+
"fooGlobalID": "{FD04C39C-69C6-4DCC-88D6-7E3E673DD0CB}",
92+
"fooGUID": "{3BFE6840-A9E6-432A-AD34-B2067C8A276F}"
6393
}
6494
}
6595
]

autotest/ogr/ogr_esrijson.py

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ def test_ogr_esrijson_read_point():
8181

8282
extent = (2, 2, 49, 49)
8383

84-
rc = validate_layer(lyr, "esripoint", 1, ogr.wkbPoint, 7, extent)
84+
rc = validate_layer(lyr, "esripoint", 1, ogr.wkbPoint, 12, extent)
8585
assert rc
8686

8787
layer_defn = lyr.GetLayerDefn()
@@ -102,12 +102,47 @@ def test_ogr_esrijson_read_point():
102102
ogrtest.check_feature_geometry(feature, "POINT(2 49)")
103103

104104
assert feature.GetFID() == 1
105+
assert (
106+
lyr.GetLayerDefn()
107+
.GetFieldDefn(lyr.GetLayerDefn().GetFieldIndex("fooSmallInt"))
108+
.GetSubType()
109+
== ogr.OFSTInt16
110+
)
105111
assert feature["fooSmallInt"] == 2
106112
assert feature["fooInt"] == 1234567890
113+
assert (
114+
lyr.GetLayerDefn()
115+
.GetFieldDefn(lyr.GetLayerDefn().GetFieldIndex("fooSingle"))
116+
.GetSubType()
117+
== ogr.OFSTFloat32
118+
)
107119
assert feature["fooSingle"] == 1.5
108120
assert feature["fooDouble"] == 3.4
109121
assert feature["fooString"] == "56"
110122
assert feature["fooDate"] == "2021/12/31 00:00:00+00"
123+
assert feature["fooDateOnly"] == "2025/09/20"
124+
assert (
125+
lyr.GetLayerDefn()
126+
.GetFieldDefn(lyr.GetLayerDefn().GetFieldIndex("fooTimeOnly"))
127+
.GetType()
128+
== ogr.OFTTime
129+
)
130+
assert feature["fooTimeOnly"] == "12:34:56"
131+
assert feature["fooBigInteger"] == 1234567890123456
132+
assert (
133+
lyr.GetLayerDefn()
134+
.GetFieldDefn(lyr.GetLayerDefn().GetFieldIndex("fooGlobalID"))
135+
.GetSubType()
136+
== ogr.OFSTUUID
137+
)
138+
assert feature["fooGlobalID"] == "{FD04C39C-69C6-4DCC-88D6-7E3E673DD0CB}"
139+
assert (
140+
lyr.GetLayerDefn()
141+
.GetFieldDefn(lyr.GetLayerDefn().GetFieldIndex("fooGUID"))
142+
.GetSubType()
143+
== ogr.OFSTUUID
144+
)
145+
assert feature["fooGUID"] == "{3BFE6840-A9E6-432A-AD34-B2067C8A276F}"
111146

112147
lyr = None
113148
ds = None

ogr/ogrsf_frmts/geojson/ogresrijsonreader.cpp

Lines changed: 32 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@
3535
#include "ogrgeojsonutils.h"
3636
#include "ogresrijsongeometry.h"
3737

38+
#include <map>
39+
#include <utility>
40+
3841
// #include "symbol_renames.h"
3942

4043
/************************************************************************/
@@ -295,6 +298,21 @@ bool OGRESRIJSONReader::GenerateLayerDefn()
295298
/* ParseField() */
296299
/************************************************************************/
297300

301+
static const std::map<std::string, std::pair<OGRFieldType, OGRFieldSubType>>
302+
goMapEsriTypeToOGR = {
303+
{"esriFieldTypeString", {OFTString, OFSTNone}},
304+
{"esriFieldTypeSingle", {OFTReal, OFSTFloat32}},
305+
{"esriFieldTypeDouble", {OFTReal, OFSTNone}},
306+
{"esriFieldTypeSmallInteger", {OFTInteger, OFSTInt16}},
307+
{"esriFieldTypeInteger", {OFTInteger, OFSTNone}},
308+
{"esriFieldTypeDate", {OFTDateTime, OFSTNone}},
309+
{"esriFieldTypeDateOnly", {OFTDate, OFSTNone}},
310+
{"esriFieldTypeTimeOnly", {OFTTime, OFSTNone}},
311+
{"esriFieldTypeBigInteger", {OFTInteger64, OFSTNone}},
312+
{"esriFieldTypeGUID", {OFTString, OFSTUUID}},
313+
{"esriFieldTypeGlobalID", {OFTString, OFSTUUID}},
314+
};
315+
298316
bool OGRESRIJSONReader::ParseField(json_object *poObj)
299317
{
300318
OGRFeatureDefn *poDefn = poLayer_->GetLayerDefn();
@@ -313,43 +331,26 @@ bool OGRESRIJSONReader::ParseField(json_object *poObj)
313331
OGRFieldSubType eFieldSubType = OFSTNone;
314332
const char *pszObjName = json_object_get_string(poObjName);
315333
const char *pszObjType = json_object_get_string(poObjType);
316-
if (EQUAL(pszObjType, "esriFieldTypeString"))
317-
{
318-
// do nothing
319-
}
320-
else if (EQUAL(pszObjType, "esriFieldTypeOID"))
334+
if (strcmp(pszObjType, "esriFieldTypeOID") == 0)
321335
{
322336
eFieldType = OFTInteger;
323337
poLayer_->SetFIDColumn(pszObjName);
324338
}
325-
else if (EQUAL(pszObjType, "esriFieldTypeSingle"))
326-
{
327-
eFieldType = OFTReal;
328-
eFieldSubType = OFSTFloat32;
329-
}
330-
else if (EQUAL(pszObjType, "esriFieldTypeDouble"))
331-
{
332-
eFieldType = OFTReal;
333-
}
334-
else if (EQUAL(pszObjType, "esriFieldTypeSmallInteger"))
335-
{
336-
eFieldType = OFTInteger;
337-
eFieldSubType = OFSTInt16;
338-
}
339-
else if (EQUAL(pszObjType, "esriFieldTypeInteger"))
340-
{
341-
eFieldType = OFTInteger;
342-
}
343-
else if (EQUAL(pszObjType, "esriFieldTypeDate"))
344-
{
345-
eFieldType = OFTDateTime;
346-
}
347339
else
348340
{
349-
CPLDebug("ESRIJSON",
350-
"Unhandled fields[\"%s\"].type = %s. "
351-
"Processing it as a String",
352-
pszObjName, pszObjType);
341+
const auto it = goMapEsriTypeToOGR.find(pszObjType);
342+
if (it != goMapEsriTypeToOGR.end())
343+
{
344+
eFieldType = it->second.first;
345+
eFieldSubType = it->second.second;
346+
}
347+
else
348+
{
349+
CPLDebug("ESRIJSON",
350+
"Unhandled fields[\"%s\"].type = %s. "
351+
"Processing it as a String",
352+
pszObjName, pszObjType);
353+
}
353354
}
354355
OGRFieldDefn fldDefn(pszObjName, eFieldType);
355356
fldDefn.SetSubType(eFieldSubType);

ogr/ogrsf_frmts/geojson/ogrgeojsonutils.cpp

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -22,11 +22,12 @@
2222
#include <algorithm>
2323
#include <memory>
2424

25-
const char szESRIJSonFeaturesGeometryRings[] =
26-
"{\"features\":[{\"geometry\":{\"rings\":[";
25+
constexpr const char szESRIJSonFeaturesGeometryRings[] =
26+
"\"features\":[{\"geometry\":{\"rings\":[";
2727

2828
// Cf https://github.com/OSGeo/gdal/issues/9996#issuecomment-2129845692
29-
const char szESRIJSonFeaturesAttributes[] = "{\"features\":[{\"attributes\":{";
29+
constexpr const char szESRIJSonFeaturesAttributes[] =
30+
"\"features\":[{\"attributes\":{";
3031

3132
/************************************************************************/
3233
/* SkipUTF8BOM() */
@@ -227,8 +228,9 @@ static bool IsGeoJSONLikeObject(const char *pszText, bool &bMightBeSequence,
227228

228229
const std::string osWithoutSpace = GetCompactJSon(pszText, strlen(pszText));
229230
if (osWithoutSpace.find("{\"features\":[") == 0 &&
230-
osWithoutSpace.find(szESRIJSonFeaturesGeometryRings) != 0 &&
231-
osWithoutSpace.find(szESRIJSonFeaturesAttributes) != 0)
231+
osWithoutSpace.find(szESRIJSonFeaturesGeometryRings) ==
232+
std::string::npos &&
233+
osWithoutSpace.find(szESRIJSonFeaturesAttributes) == std::string::npos)
232234
{
233235
return true;
234236
}
@@ -329,8 +331,10 @@ bool ESRIJSONIsObject(const char *pszText, GDALOpenInfo *poOpenInfo)
329331
}
330332

331333
const std::string osWithoutSpace = GetCompactJSon(pszText, strlen(pszText));
332-
if (osWithoutSpace.find(szESRIJSonFeaturesGeometryRings) == 0 ||
333-
osWithoutSpace.find(szESRIJSonFeaturesAttributes) == 0 ||
334+
if (osWithoutSpace.find(szESRIJSonFeaturesGeometryRings) !=
335+
std::string::npos ||
336+
osWithoutSpace.find(szESRIJSonFeaturesAttributes) !=
337+
std::string::npos ||
334338
osWithoutSpace.find("\"spatialReference\":{\"wkid\":") !=
335339
std::string::npos)
336340
{

0 commit comments

Comments
 (0)