diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2018-12-28 17:56:25 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2018-12-28 17:56:25 +0100 |
| commit | d43a09983fd0c115a175613c7d77a648b0500791 (patch) | |
| tree | 0f44003997d3dbfef4ed0e47778084352ba4dd33 /src | |
| parent | f49a5b744a28fe2a51cdcb7b4bc86f5d834f1e54 (diff) | |
| download | PROJ-d43a09983fd0c115a175613c7d77a648b0500791.tar.gz PROJ-d43a09983fd0c115a175613c7d77a648b0500791.zip | |
createOperations(): allow looking for geographic CRS by name (helps with WKT 2 definitions of PROJCRS that lack it)
Diffstat (limited to 'src')
| -rw-r--r-- | src/iso19111/coordinateoperation.cpp | 237 |
1 files changed, 152 insertions, 85 deletions
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index ad174fc5..7e478822 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -10045,6 +10045,77 @@ applyInverse(const std::vector<CoordinateOperationNNPtr> &list) { // --------------------------------------------------------------------------- //! @cond Doxygen_Suppress + +static void buildSourceAndTargetCRSIds( + const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS, + const CoordinateOperationContextNNPtr &context, + std::list<std::pair<std::string, std::string>> &sourceIds, + std::list<std::pair<std::string, std::string>> &targetIds) { + const auto &authFactory = context->getAuthorityFactory(); + assert(authFactory); + const auto &authFactoryName = authFactory->getAuthority(); + + const auto findObjectInDB = [&authFactory, &authFactoryName]( + const crs::CRSNNPtr &crs, + std::list<std::pair<std::string, std::string>> &idList) { + try { + const auto tmpAuthFactory = io::AuthorityFactory::create( + authFactory->databaseContext(), + (authFactoryName.empty() || authFactoryName == "any") + ? std::string() + : authFactoryName); + std::vector<io::AuthorityFactory::ObjectType> allowedObjects; + auto geogCRS = dynamic_cast<const crs::GeographicCRS *>(crs.get()); + if (geogCRS) { + allowedObjects.push_back( + geogCRS->coordinateSystem()->axisList().size() == 2 + ? io::AuthorityFactory::ObjectType::GEOGRAPHIC_2D_CRS + : io::AuthorityFactory::ObjectType::GEOGRAPHIC_3D_CRS); + } else if (dynamic_cast<crs::ProjectedCRS *>(crs.get())) { + allowedObjects.push_back( + io::AuthorityFactory::ObjectType::PROJECTED_CRS); + } + if (!allowedObjects.empty()) { + auto matches = tmpAuthFactory->createObjectsFromName( + crs->nameStr(), allowedObjects, false, 2); + if (matches.size() == 1 && + crs->_isEquivalentTo( + matches.front().get(), + util::IComparable::Criterion::EQUIVALENT) && + !matches.front()->identifiers().empty()) { + const auto &ids = matches.front()->identifiers(); + idList.emplace_back(*(ids[0]->codeSpace()), ids[0]->code()); + } + } + } catch (const std::exception &) { + } + }; + + for (const auto &id : sourceCRS->identifiers()) { + const auto &authName = *(id->codeSpace()); + const auto &code = id->code(); + if (!authName.empty()) { + sourceIds.emplace_back(authName, code); + } + } + if (sourceIds.empty()) { + findObjectInDB(sourceCRS, sourceIds); + } + + for (const auto &id : targetCRS->identifiers()) { + const auto &authName = *(id->codeSpace()); + const auto &code = id->code(); + if (!authName.empty()) { + targetIds.emplace_back(authName, code); + } + } + if (targetIds.empty()) { + findObjectInDB(targetCRS, targetIds); + } +} + +// --------------------------------------------------------------------------- + // Look in the authority registry for operations from sourceCRS to targetCRS static std::vector<CoordinateOperationNNPtr> findOpsInRegistryDirect(const crs::CRSNNPtr &sourceCRS, @@ -10054,48 +10125,46 @@ findOpsInRegistryDirect(const crs::CRSNNPtr &sourceCRS, assert(authFactory); const auto &authFactoryName = authFactory->getAuthority(); - for (const auto &idSrc : sourceCRS->identifiers()) { - const auto &srcAuthName = *(idSrc->codeSpace()); - const auto &srcCode = idSrc->code(); - if (!srcAuthName.empty()) { - for (const auto &idTarget : targetCRS->identifiers()) { - const auto &targetAuthName = *(idTarget->codeSpace()); - const auto &targetCode = idTarget->code(); - if (!targetAuthName.empty()) { - std::vector<std::string> authorities; - if (authFactoryName == "any") { - authorities.emplace_back(); - } - if (authFactoryName.empty()) { - authorities = authFactory->databaseContext() - ->getAllowedAuthorities( - srcAuthName, targetAuthName); - if (authorities.empty()) { - authorities.emplace_back(); - } - } else { - authorities.emplace_back(authFactoryName); - } - for (const auto &authority : authorities) { - const auto tmpAuthFactory = - io::AuthorityFactory::create( - authFactory->databaseContext(), - authority == "any" ? std::string() : authority); - auto res = - tmpAuthFactory - ->createFromCoordinateReferenceSystemCodes( - srcAuthName, srcCode, targetAuthName, - targetCode, - context->getUsePROJAlternativeGridNames(), - context->getGridAvailabilityUse() == - CoordinateOperationContext:: - GridAvailabilityUse:: - DISCARD_OPERATION_IF_MISSING_GRID, - context->getDiscardSuperseded()); - if (!res.empty()) { - return res; - } - } + std::list<std::pair<std::string, std::string>> sourceIds; + std::list<std::pair<std::string, std::string>> targetIds; + buildSourceAndTargetCRSIds(sourceCRS, targetCRS, context, sourceIds, + targetIds); + + for (const auto &idSrc : sourceIds) { + const auto &srcAuthName = idSrc.first; + const auto &srcCode = idSrc.second; + for (const auto &idTarget : targetIds) { + const auto &targetAuthName = idTarget.first; + const auto &targetCode = idTarget.second; + + std::vector<std::string> authorities; + if (authFactoryName == "any") { + authorities.emplace_back(); + } + if (authFactoryName.empty()) { + authorities = + authFactory->databaseContext()->getAllowedAuthorities( + srcAuthName, targetAuthName); + if (authorities.empty()) { + authorities.emplace_back(); + } + } else { + authorities.emplace_back(authFactoryName); + } + for (const auto &authority : authorities) { + const auto tmpAuthFactory = io::AuthorityFactory::create( + authFactory->databaseContext(), + authority == "any" ? std::string() : authority); + auto res = + tmpAuthFactory->createFromCoordinateReferenceSystemCodes( + srcAuthName, srcCode, targetAuthName, targetCode, + context->getUsePROJAlternativeGridNames(), + context->getGridAvailabilityUse() == + CoordinateOperationContext::GridAvailabilityUse:: + DISCARD_OPERATION_IF_MISSING_GRID, + context->getDiscardSuperseded()); + if (!res.empty()) { + return res; } } } @@ -10121,49 +10190,47 @@ static std::vector<CoordinateOperationNNPtr> findsOpsInRegistryWithIntermediate( assert(authFactory); const auto &authFactoryName = authFactory->getAuthority(); - for (const auto &idSrc : sourceCRS->identifiers()) { - const auto &srcAuthName = *(idSrc->codeSpace()); - const auto &srcCode = idSrc->code(); - if (!srcAuthName.empty()) { - for (const auto &idTarget : targetCRS->identifiers()) { - const auto &targetAuthName = *(idTarget->codeSpace()); - const auto &targetCode = idTarget->code(); - if (!targetAuthName.empty()) { - std::vector<std::string> authorities; - if (authFactoryName == "any") { - authorities.emplace_back(); - } - if (authFactoryName.empty()) { - authorities = authFactory->databaseContext() - ->getAllowedAuthorities( - srcAuthName, targetAuthName); - if (authorities.empty()) { - authorities.emplace_back(); - } - } else { - authorities.emplace_back(authFactoryName); - } - for (const auto &authority : authorities) { - const auto tmpAuthFactory = - io::AuthorityFactory::create( - authFactory->databaseContext(), - authority == "any" ? std::string() : authority); - - auto res = - tmpAuthFactory->createFromCRSCodesWithIntermediates( - srcAuthName, srcCode, targetAuthName, - targetCode, - context->getUsePROJAlternativeGridNames(), - context->getGridAvailabilityUse() == - CoordinateOperationContext:: - GridAvailabilityUse:: - DISCARD_OPERATION_IF_MISSING_GRID, - context->getDiscardSuperseded(), - context->getIntermediateCRS()); - if (!res.empty()) { - return res; - } - } + std::list<std::pair<std::string, std::string>> sourceIds; + std::list<std::pair<std::string, std::string>> targetIds; + buildSourceAndTargetCRSIds(sourceCRS, targetCRS, context, sourceIds, + targetIds); + + for (const auto &idSrc : sourceIds) { + const auto &srcAuthName = idSrc.first; + const auto &srcCode = idSrc.second; + for (const auto &idTarget : targetIds) { + const auto &targetAuthName = idTarget.first; + const auto &targetCode = idTarget.second; + + std::vector<std::string> authorities; + if (authFactoryName == "any") { + authorities.emplace_back(); + } + if (authFactoryName.empty()) { + authorities = + authFactory->databaseContext()->getAllowedAuthorities( + srcAuthName, targetAuthName); + if (authorities.empty()) { + authorities.emplace_back(); + } + } else { + authorities.emplace_back(authFactoryName); + } + for (const auto &authority : authorities) { + const auto tmpAuthFactory = io::AuthorityFactory::create( + authFactory->databaseContext(), + authority == "any" ? std::string() : authority); + + auto res = tmpAuthFactory->createFromCRSCodesWithIntermediates( + srcAuthName, srcCode, targetAuthName, targetCode, + context->getUsePROJAlternativeGridNames(), + context->getGridAvailabilityUse() == + CoordinateOperationContext::GridAvailabilityUse:: + DISCARD_OPERATION_IF_MISSING_GRID, + context->getDiscardSuperseded(), + context->getIntermediateCRS()); + if (!res.empty()) { + return res; } } } |
