aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2021-04-24 15:22:02 +0200
committerEven Rouault <even.rouault@spatialys.com>2021-04-24 15:51:19 +0200
commit7898eaba1160631405e8d4eccd73254f453bd3d4 (patch)
tree7d796b52ce2ca6ffa6ca3d584fecdab4d70965e0 /src
parent01a5c03c052be14f731b1e96ca3c0005f110aad8 (diff)
downloadPROJ-7898eaba1160631405e8d4eccd73254f453bd3d4.tar.gz
PROJ-7898eaba1160631405e8d4eccd73254f453bd3d4.zip
Improvements related to DerivedVerticalCRS using Change Unit and Height/Depth reversal methods
- For instantiation from urn combined references, create a better name, using conventions of EPSG vertical CRS - For exportToWKT(), allow export in WKT < WKT2 for such DerivedVerticalCRS
Diffstat (limited to 'src')
-rw-r--r--src/iso19111/crs.cpp27
-rw-r--r--src/iso19111/io.cpp69
2 files changed, 85 insertions, 11 deletions
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp
index 2d589ad1..51317c18 100644
--- a/src/iso19111/crs.cpp
+++ b/src/iso19111/crs.cpp
@@ -6506,6 +6506,33 @@ DerivedVerticalCRSNNPtr DerivedVerticalCRS::create(
void DerivedVerticalCRS::_exportToWKT(io::WKTFormatter *formatter) const {
const bool isWKT2 = formatter->version() == io::WKTFormatter::Version::WKT2;
if (!isWKT2) {
+
+ bool useBaseMethod = true;
+ const DerivedVerticalCRS *dvcrs = this;
+ while (true) {
+ // If the derived vertical CRS is obtained through simple conversion
+ // methods that just do unit change or height/depth reversal, export
+ // it as a regular VerticalCRS
+ const int methodCode =
+ dvcrs->derivingConversionRef()->method()->getEPSGCode();
+ if (methodCode == EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT ||
+ methodCode ==
+ EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT_NO_CONV_FACTOR ||
+ methodCode == EPSG_CODE_METHOD_HEIGHT_DEPTH_REVERSAL) {
+ dvcrs = dynamic_cast<DerivedVerticalCRS *>(baseCRS().get());
+ if (dvcrs == nullptr) {
+ break;
+ }
+ } else {
+ useBaseMethod = false;
+ break;
+ }
+ }
+ if (useBaseMethod) {
+ VerticalCRS::_exportToWKT(formatter);
+ return;
+ }
+
io::FormattingException::Throw(
"DerivedVerticalCRS can only be exported to WKT2");
}
diff --git a/src/iso19111/io.cpp b/src/iso19111/io.cpp
index e3da80e0..6ddeed7a 100644
--- a/src/iso19111/io.cpp
+++ b/src/iso19111/io.cpp
@@ -6491,12 +6491,13 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text,
AuthorityFactory::create(NN_NO_CHECK(dbContext), tokensOp[1]);
auto op = factoryOp->createCoordinateOperation(tokensOp[3], true);
- std::string name(baseCRS->nameStr());
+ const auto &baseName = baseCRS->nameStr();
+ std::string name(baseName);
auto geogCRS =
util::nn_dynamic_pointer_cast<GeographicCRS>(baseCRS);
if (geogCRS &&
geogCRS->coordinateSystem()->axisList().size() == 3 &&
- baseCRS->nameStr().find("3D") == std::string::npos) {
+ baseName.find("3D") == std::string::npos) {
name += " (3D)";
}
name += " / ";
@@ -6532,15 +6533,61 @@ static BaseObjectNNPtr createFromUserInput(const std::string &text,
baseCRS)) {
return DerivedProjectedCRS::create(props, NN_NO_CHECK(pcrs),
convNN, cs);
- } else if (dynamic_cast<VerticalCRS *>(baseCRS.get()) &&
- dynamic_cast<VerticalCS *>(cs.get())) {
- return DerivedVerticalCRS::create(
- props,
- NN_NO_CHECK(util::nn_dynamic_pointer_cast<VerticalCRS>(
- baseCRS)),
- convNN,
- NN_NO_CHECK(
- util::nn_dynamic_pointer_cast<VerticalCS>(cs)));
+ } else if (auto vertBaseCRS =
+ util::nn_dynamic_pointer_cast<VerticalCRS>(
+ baseCRS)) {
+ if (auto vertCS =
+ util::nn_dynamic_pointer_cast<VerticalCS>(cs)) {
+ const int methodCode = convNN->method()->getEPSGCode();
+ std::string newName(baseName);
+ std::string unitNameSuffix;
+ for (const char *suffix : {" (ft)", " (ftUS)"}) {
+ if (ends_with(newName, suffix)) {
+ unitNameSuffix = suffix;
+ newName.resize(newName.size() - strlen(suffix));
+ break;
+ }
+ }
+ bool newNameOk = false;
+ if (methodCode ==
+ EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT_NO_CONV_FACTOR ||
+ methodCode ==
+ EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT) {
+ const auto &unitName =
+ vertCS->axisList()[0]->unit().name();
+ if (unitName == UnitOfMeasure::METRE.name()) {
+ newNameOk = true;
+ } else if (unitName == UnitOfMeasure::FOOT.name()) {
+ newName += " (ft)";
+ newNameOk = true;
+ } else if (unitName ==
+ UnitOfMeasure::US_FOOT.name()) {
+ newName += " (ftUS)";
+ newNameOk = true;
+ }
+ } else if (methodCode ==
+ EPSG_CODE_METHOD_HEIGHT_DEPTH_REVERSAL) {
+ if (ends_with(newName, " height")) {
+ newName.resize(newName.size() -
+ strlen(" height"));
+ newName += " depth";
+ newName += unitNameSuffix;
+ newNameOk = true;
+ } else if (ends_with(newName, " depth")) {
+ newName.resize(newName.size() -
+ strlen(" depth"));
+ newName += " height";
+ newName += unitNameSuffix;
+ newNameOk = true;
+ }
+ }
+ if (newNameOk) {
+ props.set(IdentifiedObject::NAME_KEY, newName);
+ }
+ return DerivedVerticalCRS::create(
+ props, NN_NO_CHECK(vertBaseCRS), convNN,
+ NN_NO_CHECK(vertCS));
+ }
}
}