aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--data/projjson.schema.json11
-rw-r--r--include/proj/internal/io_internal.hpp1
-rw-r--r--src/iso19111/crs.cpp31
-rw-r--r--src/iso19111/io.cpp35
-rw-r--r--src/iso19111/static.cpp1
-rw-r--r--test/cli/testprojinfo_out.dist2
-rw-r--r--test/unit/test_c_api.cpp2
-rw-r--r--test/unit/test_io.cpp56
8 files changed, 125 insertions, 14 deletions
diff --git a/data/projjson.schema.json b/data/projjson.schema.json
index 60fca6df..e71e5031 100644
--- a/data/projjson.schema.json
+++ b/data/projjson.schema.json
@@ -1,5 +1,5 @@
{
- "$id": "https://proj.org/schemas/v0.1/projjson.schema.json",
+ "$id": "https://proj.org/schemas/v0.2/projjson.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"description": "Schema for PROJJSON",
"$comment": "This file exists both in data/ and in schemas/vXXX/. Keep both in sync. And if changing the value of $id, change PROJJSON_CURRENT_VERSION accordingly in io.cpp",
@@ -932,6 +932,15 @@
},
"datum_ensemble": { "$ref": "#/definitions/datum_ensemble" },
"coordinate_system": { "$ref": "#/definitions/coordinate_system" },
+ "geoid_model": {
+ "type": "object",
+ "properties": {
+ "name": { "type": "string" },
+ "id": { "$ref": "#/definitions/id" }
+ },
+ "required" : [ "name" ],
+ "additionalProperties": false
+ },
"$schema" : {},
"scope": {},
"area": {},
diff --git a/include/proj/internal/io_internal.hpp b/include/proj/internal/io_internal.hpp
index 781dfa6c..1e2508cc 100644
--- a/include/proj/internal/io_internal.hpp
+++ b/include/proj/internal/io_internal.hpp
@@ -134,6 +134,7 @@ class WKTConstants {
static const std::string BASEPARAMCRS;
static const std::string BASETIMECRS;
static const std::string VERSION;
+ static const std::string GEOIDMODEL; // WKT2-2019
// WKT2 alternate (longer or shorter)
static const std::string GEODETICCRS;
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp
index 26725e24..b9b38c80 100644
--- a/src/iso19111/crs.cpp
+++ b/src/iso19111/crs.cpp
@@ -2478,6 +2478,14 @@ void VerticalCRS::_exportToWKT(io::WKTFormatter *formatter) const {
cs->_exportToWKT(formatter);
formatter->setOutputAxis(oldAxisOutputRule);
+ if (isWKT2 && formatter->use2019Keywords() && !d->geoidModel.empty()) {
+ const auto &model = d->geoidModel[0];
+ formatter->startNode(io::WKTConstants::GEOIDMODEL, false);
+ formatter->addQuotedString(model->nameStr());
+ model->formatID(formatter);
+ formatter->endNode();
+ }
+
ObjectUsage::baseExportToWKT(formatter);
formatter->endNode();
}
@@ -2539,6 +2547,15 @@ void VerticalCRS::_exportToJSON(
formatter->setOmitTypeInImmediateChild();
coordinateSystem()->_exportToJSON(formatter);
+ if (!d->geoidModel.empty()) {
+ const auto &model = d->geoidModel[0];
+ writer.AddObjKey("geoid_model");
+ auto objectContext2(formatter->MakeObjectContext(nullptr, false));
+ writer.AddObjKey("name");
+ writer.Add(model->nameStr());
+ model->formatID(formatter);
+ }
+
ObjectUsage::baseExportToJSON(formatter);
}
//! @endcond
@@ -2572,7 +2589,8 @@ void VerticalCRS::addLinearUnitConvert(
* cs::VerticalCS.
*
* @param properties See \ref general_properties.
- * At minimum the name should be defined.
+ * At minimum the name should be defined. The GEOID_MODEL property can be set
+ * to a TransformationNNPtr object.
* @param datumIn The datum of the CRS.
* @param csIn a VerticalCS.
* @return new VerticalCRS.
@@ -2592,7 +2610,8 @@ VerticalCRS::create(const util::PropertyMap &properties,
* One and only one of datum or datumEnsemble should be set to a non-null value.
*
* @param properties See \ref general_properties.
- * At minimum the name should be defined.
+ * At minimum the name should be defined. The GEOID_MODEL property can be set
+ * to a TransformationNNPtr object.
* @param datumIn The datum of the CRS, or nullptr
* @param datumEnsembleIn The datum ensemble of the CRS, or nullptr.
* @param csIn a VerticalCS.
@@ -2607,6 +2626,14 @@ VerticalCRS::create(const util::PropertyMap &properties,
csIn));
crs->assignSelf(crs);
crs->setProperties(properties);
+ const auto geoidModelPtr = properties.get("GEOID_MODEL");
+ if (geoidModelPtr) {
+ auto transf = util::nn_dynamic_pointer_cast<operation::Transformation>(
+ *geoidModelPtr);
+ if (transf) {
+ crs->d->geoidModel.emplace_back(NN_NO_CHECK(transf));
+ }
+ }
return crs;
}
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index fc66b6c9..116a8b78 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -89,7 +89,7 @@ static const std::string emptyString{};
// If changing that value, change it in data/projjson.schema.json as well
#define PROJJSON_CURRENT_VERSION \
- "https://proj.org/schemas/v0.1/projjson.schema.json"
+ "https://proj.org/schemas/v0.2/projjson.schema.json"
//! @endcond
#if 0
@@ -3820,8 +3820,22 @@ CRSNNPtr WKTParser::Private::buildVerticalCRS(const WKTNodeNNPtr &node) {
ThrowNotExpectedCSType("vertical");
}
+ auto &props = buildProperties(node);
+ auto &geoidModelNode = nodeP->lookForChild(WKTConstants::GEOIDMODEL);
+ if (!isNull(geoidModelNode)) {
+ auto &propsModel = buildProperties(geoidModelNode);
+ const auto dummyCRS = VerticalCRS::create(
+ PropertyMap(), datum, datumEnsemble, NN_NO_CHECK(verticalCS));
+ const auto model(Transformation::create(
+ propsModel, dummyCRS, dummyCRS, nullptr,
+ OperationMethod::create(PropertyMap(),
+ std::vector<OperationParameterNNPtr>()),
+ {}, {}));
+ props.set("GEOID_MODEL", model);
+ }
+
auto crs = nn_static_pointer_cast<CRS>(VerticalCRS::create(
- buildProperties(node), datum, datumEnsemble, NN_NO_CHECK(verticalCS)));
+ props, datum, datumEnsemble, NN_NO_CHECK(verticalCS)));
if (!isNull(datumNode)) {
auto &extensionNode = datumNode->lookForChild(WKTConstants::EXTENSION);
@@ -4987,7 +5001,22 @@ VerticalCRSNNPtr JSONParser::buildVerticalCRS(const json &j) {
if (!verticalCS) {
throw ParsingException("expected a vertical CS");
}
- return VerticalCRS::create(buildProperties(j), datum, datumEnsemble,
+
+ auto props = buildProperties(j);
+ if (j.contains("geoid_model")) {
+ auto geoidModelJ = getObject(j, "geoid_model");
+ auto propsModel = buildProperties(geoidModelJ);
+ const auto dummyCRS = VerticalCRS::create(
+ PropertyMap(), datum, datumEnsemble, NN_NO_CHECK(verticalCS));
+ const auto model(Transformation::create(
+ propsModel, dummyCRS, dummyCRS, nullptr,
+ OperationMethod::create(PropertyMap(),
+ std::vector<OperationParameterNNPtr>()),
+ {}, {}));
+ props.set("GEOID_MODEL", model);
+ }
+
+ return VerticalCRS::create(props, datum, datumEnsemble,
NN_NO_CHECK(verticalCS));
}
diff --git a/src/iso19111/static.cpp b/src/iso19111/static.cpp
index 824047f0..0ed08c95 100644
--- a/src/iso19111/static.cpp
+++ b/src/iso19111/static.cpp
@@ -274,6 +274,7 @@ DEFINE_WKT_CONSTANT(BASEENGCRS);
DEFINE_WKT_CONSTANT(BASEPARAMCRS);
DEFINE_WKT_CONSTANT(BASETIMECRS);
DEFINE_WKT_CONSTANT(VERSION);
+DEFINE_WKT_CONSTANT(GEOIDMODEL);
DEFINE_WKT_CONSTANT(GEODETICCRS);
DEFINE_WKT_CONSTANT(GEODETICDATUM);
diff --git a/test/cli/testprojinfo_out.dist b/test/cli/testprojinfo_out.dist
index c1d9f3e0..40b8330a 100644
--- a/test/cli/testprojinfo_out.dist
+++ b/test/cli/testprojinfo_out.dist
@@ -137,7 +137,7 @@ GEOGCS["GCS_WGS_1984",DATUM["D_WGS_1984",SPHEROID["WGS_1984",6378137.0,298.25722
PROJJSON:
{
- "$schema": "https://proj.org/schemas/v0.1/projjson.schema.json",
+ "$schema": "https://proj.org/schemas/v0.2/projjson.schema.json",
"type": "GeographicCRS",
"name": "WGS 84",
"datum": {
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp
index 8ac5a511..5e6d1924 100644
--- a/test/unit/test_c_api.cpp
+++ b/test/unit/test_c_api.cpp
@@ -3600,7 +3600,7 @@ TEST_F(CApi, proj_as_projjson) {
EXPECT_EQ(std::string(projjson),
"{\n"
" \"$schema\": "
- "\"https://proj.org/schemas/v0.1/projjson.schema.json\",\n"
+ "\"https://proj.org/schemas/v0.2/projjson.schema.json\",\n"
" \"type\": \"Ellipsoid\",\n"
" \"name\": \"WGS 84\",\n"
" \"semi_major_axis\": 6378137,\n"
diff --git a/test/unit/test_io.cpp b/test/unit/test_io.cpp
index 074a59b9..6bb93e97 100644
--- a/test/unit/test_io.cpp
+++ b/test/unit/test_io.cpp
@@ -1960,16 +1960,21 @@ TEST(wkt_parse, vertcrs_VRF_WKT2) {
// ---------------------------------------------------------------------------
TEST(wkt_parse, vertcrs_with_GEOIDMODEL) {
- auto wkt = "VERTCRS[\"CGVD2013\","
- " VRF[\"Canadian Geodetic Vertical Datum of 2013\"],"
- " CS[vertical,1],"
- " AXIS[\"gravity-related height (H)\",up],"
- " LENGTHUNIT[\"metre\",1.0],"
- " GEOIDMODEL[\"CGG2013\",ID[\"EPSG\",6648]]]";
+ auto wkt = "VERTCRS[\"CGVD2013\",\n"
+ " VDATUM[\"Canadian Geodetic Vertical Datum of 2013\"],\n"
+ " CS[vertical,1],\n"
+ " AXIS[\"gravity-related height (H)\",up,\n"
+ " LENGTHUNIT[\"metre\",1]],\n"
+ " GEOIDMODEL[\"CGG2013\",\n"
+ " ID[\"EPSG\",6648]]]";
auto obj = WKTParser().createFromWKT(wkt);
auto crs = nn_dynamic_pointer_cast<VerticalCRS>(obj);
ASSERT_TRUE(crs != nullptr);
+ EXPECT_EQ(
+ crs->exportToWKT(
+ WKTFormatter::create(WKTFormatter::Convention::WKT2_2019).get()),
+ wkt);
}
// ---------------------------------------------------------------------------
@@ -10808,6 +10813,45 @@ TEST(json_import, vertical_crs_with_datum_ensemble) {
// ---------------------------------------------------------------------------
+TEST(json_import, vertical_crs_with_geoid_model) {
+ auto json = "{\n"
+ " \"$schema\": \"foo\",\n"
+ " \"type\": \"VerticalCRS\",\n"
+ " \"name\": \"CGVD2013\",\n"
+ " \"datum\": {\n"
+ " \"type\": \"VerticalReferenceFrame\",\n"
+ " \"name\": \"Canadian Geodetic Vertical Datum of 2013\"\n"
+ " },\n"
+ " \"coordinate_system\": {\n"
+ " \"subtype\": \"vertical\",\n"
+ " \"axis\": [\n"
+ " {\n"
+ " \"name\": \"Gravity-related height\",\n"
+ " \"abbreviation\": \"H\",\n"
+ " \"direction\": \"up\",\n"
+ " \"unit\": \"metre\"\n"
+ " }\n"
+ " ]\n"
+ " },\n"
+ " \"geoid_model\": {\n"
+ " \"name\": \"CGG2013\",\n"
+ " \"id\": {\n"
+ " \"authority\": \"EPSG\",\n"
+ " \"code\": 6648\n"
+ " }\n"
+ " }\n"
+ "}";
+
+ // No database
+ auto obj = createFromUserInput(json, nullptr);
+ auto vcrs = nn_dynamic_pointer_cast<VerticalCRS>(obj);
+ ASSERT_TRUE(vcrs != nullptr);
+ EXPECT_EQ(vcrs->exportToJSON(&(JSONFormatter::create()->setSchema("foo"))),
+ json);
+}
+
+// ---------------------------------------------------------------------------
+
TEST(json_import, parametric_crs) {
auto json = "{\n"
" \"$schema\": \"foo\",\n"