From ffc865a41aa540673eaedb2552565cf9f8d18679 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Tue, 29 Oct 2019 22:20:24 +0100 Subject: Vertical transformations: improve situations similar to transforming from 'NAVD88 (ftUS)' to X, where we now consider the available transformations from 'NAVD88' to X that might exist in the database --- src/iso19111/factory.cpp | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) (limited to 'src/iso19111/factory.cpp') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 993b4eeb..d3ea8f26 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -4602,6 +4602,30 @@ std::list AuthorityFactory::createGeodeticCRSFromDatum( // --------------------------------------------------------------------------- +//! @cond Doxygen_Suppress +std::list AuthorityFactory::createVerticalCRSFromDatum( + const std::string &datum_auth_name, const std::string &datum_code) const { + std::string sql( + "SELECT auth_name, code FROM vertical_crs WHERE " + "datum_auth_name = ? AND datum_code = ? AND deprecated = 0"); + ListOfParams params{datum_auth_name, datum_code}; + if (d->hasAuthorityRestriction()) { + sql += " AND auth_name = ?"; + params.emplace_back(d->authority()); + } + auto sqlRes = d->run(sql, params); + std::list res; + for (const auto &row : sqlRes) { + const auto &auth_name = row[0]; + const auto &code = row[1]; + res.emplace_back(d->createFactory(auth_name)->createVerticalCRS(code)); + } + return res; +} +//! @endcond + +// --------------------------------------------------------------------------- + //! @cond Doxygen_Suppress std::list AuthorityFactory::createGeodeticCRSFromEllipsoid( -- cgit v1.2.3 From 05a7bcfa56a03437b2ba73616a6bc21c9347d2a7 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Wed, 30 Oct 2019 11:28:43 +0100 Subject: Rework importing of Vertical unit change from EPSG db, add support for Height Depth Reversal and use it in createOperations() --- src/iso19111/factory.cpp | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'src/iso19111/factory.cpp') diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index d3ea8f26..44e44dbe 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -2295,6 +2295,20 @@ AuthorityFactory::createConversion(const std::string &code) const { auto res = d->runWithCodeParam(sql, code); if (res.empty()) { + try { + // Conversions using methods Change of Vertical Unit or + // Height Depth Reveral are stored in other_transformation + auto op = createCoordinateOperation( + code, false /* allowConcatenated */, + false /* usePROJAlternativeGridNames */, + "other_transformation"); + auto conv = + util::nn_dynamic_pointer_cast(op); + if (conv) { + return NN_NO_CHECK(conv); + } + } catch (const std::exception &) { + } throw NoSuchAuthorityCodeException("conversion not found", d->authority(), code); } @@ -3118,13 +3132,16 @@ operation::CoordinateOperationNNPtr AuthorityFactory::createCoordinateOperation( .set(metadata::Identifier::CODE_KEY, method_code) .set(common::IdentifiedObject::NAME_KEY, method_name); - if (method_auth_name == metadata::Identifier::EPSG && - operation::isAxisOrderReversal( - std::atoi(method_code.c_str()))) { - auto op = operation::Conversion::create(props, propsMethod, - parameters, values); - op->setCRSs(sourceCRS, targetCRS, nullptr); - return op; + if (method_auth_name == metadata::Identifier::EPSG) { + int method_code_int = std::atoi(method_code.c_str()); + if (operation::isAxisOrderReversal(method_code_int) || + method_code_int == EPSG_CODE_METHOD_CHANGE_VERTICAL_UNIT || + method_code_int == EPSG_CODE_METHOD_HEIGHT_DEPTH_REVERSAL) { + auto op = operation::Conversion::create(props, propsMethod, + parameters, values); + op->setCRSs(sourceCRS, targetCRS, nullptr); + return op; + } } return operation::Transformation::create( props, sourceCRS, targetCRS, nullptr, propsMethod, parameters, -- cgit v1.2.3