diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2019-08-08 20:04:20 +0200 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2019-08-09 13:22:25 +0200 |
| commit | 89f2cc7ec4178a369e73e9cd115a2552a55d870a (patch) | |
| tree | b5a96d4248a0bb866477ed3c865fdb5648dc0a06 | |
| parent | ec49c9cd0aa9de24623920b8de226daf05a0e90f (diff) | |
| download | PROJ-89f2cc7ec4178a369e73e9cd115a2552a55d870a.tar.gz PROJ-89f2cc7ec4178a369e73e9cd115a2552a55d870a.zip | |
PROJJSON export: use more compact form
| -rw-r--r-- | data/crsjson.schema.json | 45 | ||||
| -rw-r--r-- | include/proj/io.hpp | 2 | ||||
| -rw-r--r-- | src/iso19111/coordinateoperation.cpp | 11 | ||||
| -rw-r--r-- | src/iso19111/coordinatesystem.cpp | 9 | ||||
| -rw-r--r-- | src/iso19111/crs.cpp | 7 | ||||
| -rw-r--r-- | src/iso19111/datum.cpp | 30 | ||||
| -rw-r--r-- | src/iso19111/io.cpp | 10 | ||||
| -rw-r--r-- | test/cli/testprojinfo_out.dist | 37 | ||||
| -rw-r--r-- | test/unit/test_datum.cpp | 27 |
9 files changed, 109 insertions, 69 deletions
diff --git a/data/crsjson.schema.json b/data/crsjson.schema.json index 5ceeaa1e..86f1e13e 100644 --- a/data/crsjson.schema.json +++ b/data/crsjson.schema.json @@ -111,8 +111,8 @@ "properties": { "type": { "type": "string", "enum": ["Ellipsoid"] }, "name": { "type": "string" }, - "semi_major_axis": { "$ref": "#/definitions/value_and_unit" }, - "semi_minor_axis": { "$ref": "#/definitions/value_and_unit" }, + "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" } }, "required" : [ "name", "semi_major_axis", "semi_minor_axis" ], @@ -122,7 +122,7 @@ "properties": { "type": { "type": "string", "enum": ["Ellipsoid"] }, "name": { "type": "string" }, - "semi_major_axis": { "$ref": "#/definitions/value_and_unit" }, + "semi_major_axis": { "$ref": "#/definitions/value_in_metre_or_value_and_unit" }, "inverse_flattening": { "type": "number" }, "id": { "$ref": "#/definitions/id" } }, @@ -133,7 +133,7 @@ "properties": { "type": { "type": "string", "enum": ["Ellipsoid"] }, "name": { "type": "string" }, - "radius": { "$ref": "#/definitions/value_and_unit" }, + "radius": { "$ref": "#/definitions/value_in_metre_or_value_and_unit" }, "id": { "$ref": "#/definitions/id" } }, "required" : [ "name", "radius" ], @@ -255,17 +255,25 @@ }, "unit": { - "type": "object", - "properties": { - "type": { "type": "string", - "enum": ["LinearUnit", "AngularUnit", "ScaleUnit", - "TimeUnit", "ParametricUnit", "Unit"] }, - "name": { "type": "string" }, - "conversion_factor": { "type": "number" }, - "id": { "$ref": "#/definitions/id" } - }, - "required" : [ "type", "name" ], - "additionalProperties": false + "oneOf": [ + { + "type": "string", + "enum": ["metre", "degree", "unity"] + }, + { + "type": "object", + "properties": { + "type": { "type": "string", + "enum": ["LinearUnit", "AngularUnit", "ScaleUnit", + "TimeUnit", "ParametricUnit", "Unit"] }, + "name": { "type": "string" }, + "conversion_factor": { "type": "number" }, + "id": { "$ref": "#/definitions/id" } + }, + "required" : [ "type", "name" ], + "additionalProperties": false + } + ] }, "usages": { @@ -288,6 +296,13 @@ }, "required" : [ "value", "unit" ], "additionalProperties": false + }, + + "value_in_metre_or_value_and_unit": { + "oneOf": [ + { "type": "number" }, + { "$ref": "#/definitions/value_and_unit" } + ] } } diff --git a/include/proj/io.hpp b/include/proj/io.hpp index cfb4b3f7..043b4c4b 100644 --- a/include/proj/io.hpp +++ b/include/proj/io.hpp @@ -503,6 +503,8 @@ class PROJ_GCC_DLL JSONFormatter { PROJ_INTERNAL void setAllowIDInImmediateChild(); + PROJ_INTERNAL void setOmitTypeInImmediateChild(); + // cppcheck-suppress functionStatic PROJ_INTERNAL bool outputId() const; diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index a2a31edd..f4e90fe8 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -1200,7 +1200,14 @@ void OperationParameterValue::_exportToJSON( writer.AddObjKey("value"); writer.Add(l_value->value().value(), 15); writer.AddObjKey("unit"); - l_value->value().unit()._exportToJSON(formatter); + const auto &l_unit(l_value->value().unit()); + if (l_unit == common::UnitOfMeasure::METRE || + l_unit == common::UnitOfMeasure::DEGREE || + l_unit == common::UnitOfMeasure::SCALE_UNITY) { + writer.Add(l_unit.name()); + } else { + l_unit._exportToJSON(formatter); + } } else if (l_value->type() == ParameterValue::Type::FILENAME) { writer.AddObjKey("value"); writer.Add(l_value->valueFile()); @@ -5473,6 +5480,7 @@ void Conversion::_exportToJSON( } writer.AddObjKey("method"); + formatter->setOmitTypeInImmediateChild(); formatter->setAllowIDInImmediateChild(); method()->_exportToJSON(formatter); @@ -5481,6 +5489,7 @@ void Conversion::_exportToJSON( auto parametersContext(writer.MakeArrayContext(false)); for (const auto &genOpParamvalue : parameterValues()) { formatter->setAllowIDInImmediateChild(); + formatter->setOmitTypeInImmediateChild(); genOpParamvalue->_exportToJSON(formatter); } } diff --git a/src/iso19111/coordinatesystem.cpp b/src/iso19111/coordinatesystem.cpp index f96a962f..ef53dd57 100644 --- a/src/iso19111/coordinatesystem.cpp +++ b/src/iso19111/coordinatesystem.cpp @@ -410,7 +410,13 @@ void CoordinateSystemAxis::_exportToJSON( writer.Add(direction().toString()); writer.AddObjKey("unit"); - unit()._exportToJSON(formatter); + const auto &l_unit(unit()); + if (l_unit == common::UnitOfMeasure::METRE || + l_unit == common::UnitOfMeasure::DEGREE) { + writer.Add(l_unit.name()); + } else { + l_unit._exportToJSON(formatter); + } if (formatter->outputId()) { formatID(formatter); @@ -577,6 +583,7 @@ void CoordinateSystem::_exportToJSON( auto axisContext(writer.MakeArrayContext(false)); const auto &l_axisList = axisList(); for (auto &axis : l_axisList) { + formatter->setOmitTypeInImmediateChild(); axis->_exportToJSON(formatter); } diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 2ca2786d..670d0c1a 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -1366,6 +1366,7 @@ void GeodeticCRS::_exportToJSON( } writer.AddObjKey("coordinate_system"); + formatter->setOmitTypeInImmediateChild(); coordinateSystem()->_exportToJSON(formatter); ObjectUsage::baseExportToJSON(formatter); @@ -2116,6 +2117,7 @@ void GeographicCRS::_exportToJSON( } writer.AddObjKey("coordinate_system"); + formatter->setOmitTypeInImmediateChild(); coordinateSystem()->_exportToJSON(formatter); ObjectUsage::baseExportToJSON(formatter); @@ -2940,12 +2942,15 @@ void ProjectedCRS::_exportToJSON( writer.AddObjKey("base_crs"); formatter->setAllowIDInImmediateChild(); + formatter->setOmitTypeInImmediateChild(); baseCRS()->_exportToJSON(formatter); writer.AddObjKey("conversion"); + formatter->setOmitTypeInImmediateChild(); derivingConversionRef()->_exportToJSON(formatter); writer.AddObjKey("coordinate_system"); + formatter->setOmitTypeInImmediateChild(); coordinateSystem()->_exportToJSON(formatter); ObjectUsage::baseExportToJSON(formatter); @@ -4316,6 +4321,7 @@ void DerivedGeodeticCRS::_exportToJSON( derivingConversionRef()->_exportToJSON(formatter); writer.AddObjKey("coordinate_system"); + formatter->setOmitTypeInImmediateChild(); coordinateSystem()->_exportToJSON(formatter); ObjectUsage::baseExportToJSON(formatter); @@ -4485,6 +4491,7 @@ void DerivedGeographicCRS::_exportToJSON( derivingConversionRef()->_exportToJSON(formatter); writer.AddObjKey("coordinate_system"); + formatter->setOmitTypeInImmediateChild(); coordinateSystem()->_exportToJSON(formatter); ObjectUsage::baseExportToJSON(formatter); diff --git a/src/iso19111/datum.cpp b/src/iso19111/datum.cpp index 89ecc755..2944da1e 100644 --- a/src/iso19111/datum.cpp +++ b/src/iso19111/datum.cpp @@ -376,12 +376,13 @@ void PrimeMeridian::_exportToJSON( const auto &l_long = longitude(); writer.AddObjKey("longitude"); - { + const auto &unit = l_long.unit(); + if (unit == common::UnitOfMeasure::DEGREE) { + writer.Add(l_long.value(), 15); + } else { auto longitudeContext(formatter->MakeObjectContext(nullptr, false)); writer.AddObjKey("value"); writer.Add(l_long.value(), 15); - - const auto &unit = l_long.unit(); writer.AddObjKey("unit"); unit._exportToJSON(formatter); } @@ -834,7 +835,9 @@ void Ellipsoid::_exportToJSON( const auto &semiMajor = semiMajorAxis(); const auto &semiMajorUnit = semiMajor.unit(); writer.AddObjKey(isSphere() ? "radius" : "semi_major_axis"); - { + if (semiMajorUnit == common::UnitOfMeasure::METRE) { + writer.Add(semiMajor.value(), 15); + } else { auto objContext(formatter->MakeObjectContext(nullptr, false)); writer.AddObjKey("value"); writer.Add(semiMajor.value(), 15); @@ -850,13 +853,17 @@ void Ellipsoid::_exportToJSON( writer.Add(l_inverseFlattening->getSIValue(), 15); } else { writer.AddObjKey("semi_minor_axis"); - { + const auto &l_semiMinorAxis(semiMinorAxis()); + const auto &semiMinorAxisUnit(l_semiMinorAxis->unit()); + if (semiMinorAxisUnit == common::UnitOfMeasure::METRE) { + writer.Add(l_semiMinorAxis->value(), 15); + } else { auto objContext(formatter->MakeObjectContext(nullptr, false)); writer.AddObjKey("value"); - writer.Add(semiMinorAxis()->value(), 15); + writer.Add(l_semiMinorAxis->value(), 15); writer.AddObjKey("unit"); - semiMinorAxis()->unit()._exportToJSON(formatter); + semiMinorAxisUnit._exportToJSON(formatter); } } } @@ -1272,10 +1279,15 @@ void GeodeticReferenceFrame::_exportToJSON( Datum::getPrivate()->exportAnchorDefinition(formatter); writer.AddObjKey("ellipsoid"); + formatter->setOmitTypeInImmediateChild(); ellipsoid()->_exportToJSON(formatter); - writer.AddObjKey("prime_meridian"); - primeMeridian()->_exportToJSON(formatter); + const auto &l_primeMeridian(primeMeridian()); + if (l_primeMeridian->nameStr() != "Greenwich") { + writer.AddObjKey("prime_meridian"); + formatter->setOmitTypeInImmediateChild(); + primeMeridian()->_exportToJSON(formatter); + } ObjectUsage::baseExportToJSON(formatter); } diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp index 35798d9d..bb15c80a 100644 --- a/src/iso19111/io.cpp +++ b/src/iso19111/io.cpp @@ -8027,6 +8027,7 @@ struct JSONFormatter::Private { std::vector<bool> stackHasId_{false}; std::vector<bool> outputIdStack_{true}; bool allowIDInImmediateChild_ = false; + bool omitTypeInImmediateChild_ = false; std::string result_{}; @@ -8102,14 +8103,21 @@ void JSONFormatter::setAllowIDInImmediateChild() { // --------------------------------------------------------------------------- +void JSONFormatter::setOmitTypeInImmediateChild() { + d->omitTypeInImmediateChild_ = true; +} + +// --------------------------------------------------------------------------- + JSONFormatter::ObjectContext::ObjectContext(JSONFormatter &formatter, const char *objectType, bool hasId) : m_formatter(formatter) { m_formatter.d->writer_.StartObj(); - if (objectType) { + if (objectType && !m_formatter.d->omitTypeInImmediateChild_) { m_formatter.d->writer_.AddObjKey("type"); m_formatter.d->writer_.Add(objectType); } + m_formatter.d->omitTypeInImmediateChild_ = false; // All intermediate nodes shouldn't have ID if a parent has an ID // unless explicitly enabled. if (m_formatter.d->allowIDInImmediateChild_) { diff --git a/test/cli/testprojinfo_out.dist b/test/cli/testprojinfo_out.dist index 530a0426..73751b99 100644 --- a/test/cli/testprojinfo_out.dist +++ b/test/cli/testprojinfo_out.dist @@ -143,56 +143,25 @@ PROJJSON: "type": "GeodeticReferenceFrame", "name": "World Geodetic System 1984", "ellipsoid": { - "type": "Ellipsoid", "name": "WGS 84", - "semi_major_axis": { - "value": 6378137, - "unit": { - "type": "LinearUnit", - "name": "metre", - "conversion_factor": 1 - } - }, + "semi_major_axis": 6378137, "inverse_flattening": 298.257223563 - }, - "prime_meridian": { - "type": "PrimeMeridian", - "name": "Greenwich", - "longitude": { - "value": 0, - "unit": { - "type": "AngularUnit", - "name": "degree", - "conversion_factor": 0.0174532925199433 - } - } } }, "coordinate_system": { - "type": "CoordinateSystem", "subtype": "ellipsoidal", "axis": [ { - "type": "Axis", "name": "Geodetic latitude", "abbreviation": "Lat", "direction": "north", - "unit": { - "type": "AngularUnit", - "name": "degree", - "conversion_factor": 0.0174532925199433 - } + "unit": "degree" }, { - "type": "Axis", "name": "Geodetic longitude", "abbreviation": "Lon", "direction": "east", - "unit": { - "type": "AngularUnit", - "name": "degree", - "conversion_factor": 0.0174532925199433 - } + "unit": "degree" } ] }, diff --git a/test/unit/test_datum.cpp b/test/unit/test_datum.cpp index cf2e2f3a..d8fab1f0 100644 --- a/test/unit/test_datum.cpp +++ b/test/unit/test_datum.cpp @@ -212,19 +212,30 @@ TEST(datum, prime_meridian_to_JSON) { "{\n" " \"type\": \"PrimeMeridian\",\n" " \"name\": \"Greenwich\",\n" - " \"longitude\": {\n" - " \"value\": 0,\n" - " \"unit\": {\n" - " \"type\": \"AngularUnit\",\n" - " \"name\": \"degree\",\n" - " \"conversion_factor\": 0.0174532925199433\n" - " }\n" - " },\n" + " \"longitude\": 0,\n" " \"id\": {\n" " \"authority\": \"EPSG\",\n" " \"code\": 8901\n" " }\n" "}"); + + EXPECT_EQ(PrimeMeridian::PARIS->exportToJSON(JSONFormatter::create().get()), + "{\n" + " \"type\": \"PrimeMeridian\",\n" + " \"name\": \"Paris\",\n" + " \"longitude\": {\n" + " \"value\": 2.5969213,\n" + " \"unit\": {\n" + " \"type\": \"AngularUnit\",\n" + " \"name\": \"grad\",\n" + " \"conversion_factor\": 0.015707963267949\n" + " }\n" + " },\n" + " \"id\": {\n" + " \"authority\": \"EPSG\",\n" + " \"code\": 8903\n" + " }\n" + "}"); } // --------------------------------------------------------------------------- |
