aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-08-08 20:04:20 +0200
committerEven Rouault <even.rouault@spatialys.com>2019-08-09 13:22:25 +0200
commit89f2cc7ec4178a369e73e9cd115a2552a55d870a (patch)
treeb5a96d4248a0bb866477ed3c865fdb5648dc0a06
parentec49c9cd0aa9de24623920b8de226daf05a0e90f (diff)
downloadPROJ-89f2cc7ec4178a369e73e9cd115a2552a55d870a.tar.gz
PROJ-89f2cc7ec4178a369e73e9cd115a2552a55d870a.zip
PROJJSON export: use more compact form
-rw-r--r--data/crsjson.schema.json45
-rw-r--r--include/proj/io.hpp2
-rw-r--r--src/iso19111/coordinateoperation.cpp11
-rw-r--r--src/iso19111/coordinatesystem.cpp9
-rw-r--r--src/iso19111/crs.cpp7
-rw-r--r--src/iso19111/datum.cpp30
-rw-r--r--src/iso19111/io.cpp10
-rw-r--r--test/cli/testprojinfo_out.dist37
-rw-r--r--test/unit/test_datum.cpp27
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"
+ "}");
}
// ---------------------------------------------------------------------------