diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2021-04-24 15:22:02 +0200 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2021-04-24 15:51:19 +0200 |
| commit | 7898eaba1160631405e8d4eccd73254f453bd3d4 (patch) | |
| tree | 7d796b52ce2ca6ffa6ca3d584fecdab4d70965e0 /src | |
| parent | 01a5c03c052be14f731b1e96ca3c0005f110aad8 (diff) | |
| download | PROJ-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.cpp | 27 | ||||
| -rw-r--r-- | src/iso19111/io.cpp | 69 |
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)); + } } } |
