aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-08-12 13:45:17 +0200
committerEven Rouault <even.rouault@spatialys.com>2019-08-12 13:45:17 +0200
commit8d0500b325d12b047797a60e3c13d4b473fae987 (patch)
tree3537d416efd354bdfb7248034d912675d344ca9f
parent0a1261781de96d2bb8c76fbd905ebf8b0121d3a6 (diff)
downloadPROJ-8d0500b325d12b047797a60e3c13d4b473fae987.tar.gz
PROJ-8d0500b325d12b047797a60e3c13d4b473fae987.zip
PROJJSON: add support for importing 'ids'
-rw-r--r--data/crsjson.schema.json144
-rw-r--r--src/iso19111/io.cpp63
-rw-r--r--test/unit/test_io.cpp25
3 files changed, 174 insertions, 58 deletions
diff --git a/data/crsjson.schema.json b/data/crsjson.schema.json
index 10b17caa..726d8ece 100644
--- a/data/crsjson.schema.json
+++ b/data/crsjson.schema.json
@@ -25,9 +25,13 @@
"type": "array",
"items": { "$ref": "#/definitions/parameter_value" }
},
- "id": { "$ref": "#/definitions/id" }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
},
"required" : [ "name", "method", "parameters" ],
+ "allOf": [
+ { "$ref": "#/definitions/id_ids_mutually_exclusive" }
+ ],
"additionalProperties": false
},
@@ -79,9 +83,13 @@
"past",
"unspecified" ] },
"unit": { "$ref": "#/definitions/unit" },
- "id": { "$ref": "#/definitions/id" }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
},
"required" : [ "name", "abbreviation", "direction" ],
+ "allOf": [
+ { "$ref": "#/definitions/id_ids_mutually_exclusive" }
+ ],
"additionalProperties": false
},
@@ -125,7 +133,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "components" ],
"additionalProperties": false
@@ -148,7 +156,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "source_crs", "target_crs", "steps" ],
"additionalProperties": false
@@ -164,9 +172,13 @@
"type": "array",
"items": { "$ref": "#/definitions/parameter_value" }
},
- "id": { "$ref": "#/definitions/id" }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
},
"required" : [ "name", "method" ],
+ "allOf": [
+ { "$ref": "#/definitions/id_ids_mutually_exclusive" }
+ ],
"additionalProperties": false
},
@@ -189,9 +201,13 @@
"type": "array",
"items": { "$ref": "#/definitions/axis" }
},
- "id": { "$ref": "#/definitions/id" }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
},
"required" : [ "subtype", "axis" ],
+ "allOf": [
+ { "$ref": "#/definitions/id_ids_mutually_exclusive" }
+ ],
"additionalProperties": false
},
@@ -237,17 +253,25 @@
"type": "object",
"properties": {
"name": { "type": "string" },
- "id": { "$ref": "#/definitions/id" }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
},
"required" : [ "name" ],
+ "allOf": [
+ { "$ref": "#/definitions/id_ids_mutually_exclusive" }
+ ],
"additionalProperties": false
}
},
"ellipsoid": { "$ref": "#/definitions/ellipsoid" },
"accuracy": { "type": "string" },
- "id": { "$ref": "#/definitions/id" }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
},
"required" : [ "name", "members", "accuracy" ],
+ "allOf": [
+ { "$ref": "#/definitions/id_ids_mutually_exclusive" }
+ ],
"additionalProperties": false
},
@@ -266,7 +290,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "base_crs", "conversion", "coordinate_system" ],
"additionalProperties": false
@@ -288,7 +312,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "base_crs", "conversion", "coordinate_system" ],
"additionalProperties": false
@@ -309,7 +333,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "base_crs", "conversion", "coordinate_system" ],
"additionalProperties": false
@@ -330,7 +354,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "base_crs", "conversion", "coordinate_system" ],
"additionalProperties": false
@@ -351,7 +375,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "base_crs", "conversion", "coordinate_system" ],
"additionalProperties": false
@@ -372,7 +396,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "base_crs", "conversion", "coordinate_system" ],
"additionalProperties": false
@@ -394,7 +418,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "ellipsoid", "frame_reference_epoch" ],
"additionalProperties": false
@@ -414,7 +438,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "frame_reference_epoch" ],
"additionalProperties": false
@@ -429,7 +453,8 @@
"name": { "type": "string" },
"semi_major_axis": { "$ref": "#/definitions/value_in_metre_or_value_and_unit" },
"semi_minor_axis": { "$ref": "#/definitions/value_in_metre_or_value_and_unit" },
- "id": { "$ref": "#/definitions/id" }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
},
"required" : [ "name", "semi_major_axis", "semi_minor_axis" ],
"additionalProperties": false
@@ -440,7 +465,8 @@
"name": { "type": "string" },
"semi_major_axis": { "$ref": "#/definitions/value_in_metre_or_value_and_unit" },
"inverse_flattening": { "type": "number" },
- "id": { "$ref": "#/definitions/id" }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
},
"required" : [ "name", "semi_major_axis", "inverse_flattening" ],
"additionalProperties": false
@@ -450,11 +476,15 @@
"type": { "type": "string", "enum": ["Ellipsoid"] },
"name": { "type": "string" },
"radius": { "$ref": "#/definitions/value_in_metre_or_value_and_unit" },
- "id": { "$ref": "#/definitions/id" }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
},
"required" : [ "name", "radius" ],
"additionalProperties": false
}
+ ],
+ "allOf": [
+ { "$ref": "#/definitions/id_ids_mutually_exclusive" }
]
},
@@ -471,7 +501,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "datum" ],
"additionalProperties": false
@@ -489,7 +519,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name" ],
"additionalProperties": false
@@ -513,7 +543,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name" ],
"description": "One and only one of datum and datum_ensemble must be provided",
@@ -538,7 +568,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "ellipsoid" ],
"additionalProperties": false
@@ -556,17 +586,33 @@
"additionalProperties": false
},
+ "ids": {
+ "type": "array",
+ "items": { "$ref": "#/definitions/id" }
+ },
+
"method": {
"type": "object",
"properties": {
"type": { "type": "string", "enum": ["OperationMethod"]},
"name": { "type": "string" },
- "id": { "$ref": "#/definitions/id" }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
},
"required" : [ "name" ],
+ "allOf": [
+ { "$ref": "#/definitions/id_ids_mutually_exclusive" }
+ ],
"additionalProperties": false
},
+ "id_ids_mutually_exclusive": {
+ "not": {
+ "type": "object",
+ "required": [ "id", "ids" ]
+ }
+ },
+
"one_and_only_one_of_datum_or_datum_ensemble": {
"allOf": [
{
@@ -593,16 +639,24 @@
"area": { "type": "string" },
"bbox": { "$ref": "#/definitions/bbox" },
"remarks": { "type": "string" },
- "id": { "$ref": "#/definitions/id" }
- }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
+ },
+ "allOf": [
+ { "$ref": "#/definitions/id_ids_mutually_exclusive" }
+ ]
},
{
"type": "object",
"properties": {
"usages": { "$ref": "#/definitions/usages" },
"remarks": { "type": "string" },
- "id": { "$ref": "#/definitions/id" }
- }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
+ },
+ "allOf": [
+ { "$ref": "#/definitions/id_ids_mutually_exclusive" }
+ ]
}
]
},
@@ -619,9 +673,13 @@
]
},
"unit": { "$ref": "#/definitions/unit" },
- "id": { "$ref": "#/definitions/id" }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
},
"required" : [ "name", "value" ],
+ "allOf": [
+ { "$ref": "#/definitions/id_ids_mutually_exclusive" }
+ ],
"additionalProperties": false
},
@@ -638,7 +696,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "datum" ],
"additionalProperties": false
@@ -656,7 +714,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name" ],
"additionalProperties": false
@@ -668,9 +726,13 @@
"type": { "type": "string", "enum": ["PrimeMeridian"] },
"name": { "type": "string" },
"longitude": { "$ref": "#/definitions/value_and_unit" },
- "id": { "$ref": "#/definitions/id" }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
},
"required" : [ "name" ],
+ "allOf": [
+ { "$ref": "#/definitions/id_ids_mutually_exclusive" }
+ ],
"additionalProperties": false
},
@@ -696,7 +758,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "base_crs", "conversion", "coordinate_system" ],
"additionalProperties": false
@@ -715,7 +777,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "datum" ],
"additionalProperties": false
@@ -734,7 +796,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "calendar" ],
"additionalProperties": false
@@ -760,7 +822,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name", "source_crs", "target_crs", "method", "parameters" ],
"additionalProperties": false
@@ -780,9 +842,13 @@
"TimeUnit", "ParametricUnit", "Unit"] },
"name": { "type": "string" },
"conversion_factor": { "type": "number" },
- "id": { "$ref": "#/definitions/id" }
+ "id": { "$ref": "#/definitions/id" },
+ "ids": { "$ref": "#/definitions/ids" }
},
"required" : [ "type", "name" ],
+ "allOf": [
+ { "$ref": "#/definitions/id_ids_mutually_exclusive" }
+ ],
"additionalProperties": false
}
]
@@ -836,7 +902,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name"],
"description": "One and only one of datum and datum_ensemble must be provided",
@@ -859,7 +925,7 @@
"bbox": {},
"usages": {},
"remarks": {},
- "id": {}
+ "id": {}, "ids": {}
},
"required" : [ "name" ],
"additionalProperties": false
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index cd54f4ea..9f4f6061 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -4389,6 +4389,7 @@ class JSONParser {
static Length getLength(const json &j, const char *key);
static Measure getMeasure(const json &j);
+ IdentifierNNPtr buildId(const json &j, bool removeInverseOf);
ObjectDomainPtr buildObjectDomain(const json &j);
PropertyMap buildProperties(const json &j, bool removeInverseOf = false);
@@ -4659,6 +4660,34 @@ ObjectDomainPtr JSONParser::buildObjectDomain(const json &j) {
// ---------------------------------------------------------------------------
+IdentifierNNPtr JSONParser::buildId(const json &j, bool removeInverseOf) {
+
+ PropertyMap propertiesId;
+ auto codeSpace(getString(j, "authority"));
+ if (removeInverseOf && starts_with(codeSpace, "INVERSE(") &&
+ codeSpace.back() == ')') {
+ codeSpace = codeSpace.substr(strlen("INVERSE("));
+ codeSpace.resize(codeSpace.size() - 1);
+ }
+ propertiesId.set(metadata::Identifier::CODESPACE_KEY, codeSpace);
+ propertiesId.set(metadata::Identifier::AUTHORITY_KEY, codeSpace);
+ if (!j.contains("code")) {
+ throw ParsingException("Missing \"code\" key");
+ }
+ std::string code;
+ auto codeJ = j["code"];
+ if (codeJ.is_string()) {
+ code = codeJ.get<std::string>();
+ } else if (codeJ.is_number_integer()) {
+ code = internal::toString(codeJ.get<int>());
+ } else {
+ throw ParsingException("Unexpected type for value of \"code\"");
+ }
+ return Identifier::create(code, propertiesId);
+}
+
+// ---------------------------------------------------------------------------
+
PropertyMap JSONParser::buildProperties(const json &j, bool removeInverseOf) {
PropertyMap map;
std::string name(getName(j));
@@ -4667,26 +4696,22 @@ PropertyMap JSONParser::buildProperties(const json &j, bool removeInverseOf) {
}
map.set(IdentifiedObject::NAME_KEY, name);
- if (j.contains("id")) {
- auto id = getObject(j, "id");
- auto codeSpace(getString(id, "authority"));
- if (removeInverseOf && starts_with(codeSpace, "INVERSE(") &&
- codeSpace.back() == ')') {
- codeSpace = codeSpace.substr(strlen("INVERSE("));
- codeSpace.resize(codeSpace.size() - 1);
- }
- map.set(metadata::Identifier::CODESPACE_KEY, codeSpace);
- if (!id.contains("code")) {
- throw ParsingException("Missing \"code\" key");
- }
- auto code = id["code"];
- if (code.is_string()) {
- map.set(metadata::Identifier::CODE_KEY, code.get<std::string>());
- } else if (code.is_number_integer()) {
- map.set(metadata::Identifier::CODE_KEY, code.get<int>());
- } else {
- throw ParsingException("Unexpected type for value of \"code\"");
+ if (j.contains("ids")) {
+ auto idsJ = getArray(j, "ids");
+ auto identifiers = ArrayOfBaseObject::create();
+ for (const auto &idJ : idsJ) {
+ if (!idJ.is_object()) {
+ throw ParsingException(
+ "Unexpected type for value of \"ids\" child");
+ }
+ identifiers->add(buildId(idJ, removeInverseOf));
}
+ map.set(IdentifiedObject::IDENTIFIERS_KEY, identifiers);
+ } else if (j.contains("id")) {
+ auto idJ = getObject(j, "id");
+ auto identifiers = ArrayOfBaseObject::create();
+ identifiers->add(buildId(idJ, removeInverseOf));
+ map.set(IdentifiedObject::IDENTIFIERS_KEY, identifiers);
}
if (j.contains("remarks")) {
diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp
index 74ef82f3..e1d424e9 100644
--- a/test/unit/test_io.cpp
+++ b/test/unit/test_io.cpp
@@ -11323,3 +11323,28 @@ TEST(json_import, derived_temporal_crs) {
ASSERT_TRUE(crs != nullptr);
EXPECT_EQ(crs->exportToJSON((JSONFormatter::create().get())), json);
}
+
+// ---------------------------------------------------------------------------
+
+TEST(json_import, multiple_ids) {
+ auto json = "{\n"
+ " \"type\": \"Ellipsoid\",\n"
+ " \"name\": \"WGS 84\",\n"
+ " \"semi_major_axis\": 6378137,\n"
+ " \"inverse_flattening\": 298.257223563,\n"
+ " \"ids\": [\n"
+ " {\n"
+ " \"authority\": \"EPSG\",\n"
+ " \"code\": 4326\n"
+ " },\n"
+ " {\n"
+ " \"authority\": \"FOO\",\n"
+ " \"code\": \"BAR\"\n"
+ " }\n"
+ " ]\n"
+ "}";
+ auto obj = createFromUserInput(json, nullptr);
+ auto ellps = nn_dynamic_pointer_cast<Ellipsoid>(obj);
+ ASSERT_TRUE(ellps != nullptr);
+ EXPECT_EQ(ellps->exportToJSON((JSONFormatter::create().get())), json);
+}