diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2019-05-13 09:33:38 -0500 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2019-05-13 09:42:38 -0500 |
| commit | 97d6060e596d1b044f84e7d140b26200ef56f65e (patch) | |
| tree | bc959ee31e7f73e9ccbd5004340b3ee0548df7e5 /src/iso19111/crs.cpp | |
| parent | 32703ddba9081682b4c39ae7bcedeabeb8c6143d (diff) | |
| download | PROJ-97d6060e596d1b044f84e7d140b26200ef56f65e.tar.gz PROJ-97d6060e596d1b044f84e7d140b26200ef56f65e.zip | |
identify(): take into account the authority passed in (fixes #1465)
When identifying an object that has already a code with authority A
but the authority of interest passed was B, then it was not checking
that A != B, and did not try to search in the objects of B.
Diffstat (limited to 'src/iso19111/crs.cpp')
| -rw-r--r-- | src/iso19111/crs.cpp | 134 |
1 files changed, 88 insertions, 46 deletions
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp index 1ef7dcda..476bc72b 100644 --- a/src/iso19111/crs.cpp +++ b/src/iso19111/crs.cpp @@ -1387,6 +1387,36 @@ GeodeticCRSNNPtr GeodeticCRS::createEPSG_4978() { // --------------------------------------------------------------------------- +//! @cond Doxygen_Suppress + +static bool hasCodeCompatibleOfAuthorityFactory( + const common::IdentifiedObject *obj, + const io::AuthorityFactoryPtr &authorityFactory) { + const auto &ids = obj->identifiers(); + if (!ids.empty() && authorityFactory->getAuthority().empty()) { + return true; + } + for (const auto &id : ids) { + if (*(id->codeSpace()) == authorityFactory->getAuthority()) { + return true; + } + } + return false; +} + +static bool hasCodeCompatibleOfAuthorityFactory( + const metadata::IdentifierNNPtr &id, + const io::AuthorityFactoryPtr &authorityFactory) { + if (authorityFactory->getAuthority().empty()) { + return true; + } + return *(id->codeSpace()) == authorityFactory->getAuthority(); +} + +//! @endcond + +// --------------------------------------------------------------------------- + /** \brief Identify the CRS with reference CRSs. * * The candidate CRSs are either hard-coded, or looked in the database when @@ -1530,19 +1560,22 @@ GeodeticCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { searchByEllipsoid(); } } - } else if (!identifiers().empty()) { + } else if (hasCodeCompatibleOfAuthorityFactory(this, + authorityFactory)) { // If the CRS has already an id, check in the database for the // official object, and verify that they are equivalent. for (const auto &id : identifiers()) { - try { - auto crs = io::AuthorityFactory::create( - authorityFactory->databaseContext(), - *id->codeSpace()) - ->createGeodeticCRS(id->code()); - bool match = _isEquivalentTo(crs.get(), crsCriterion); - res.emplace_back(crs, match ? 100 : 25); - return res; - } catch (const std::exception &) { + if (hasCodeCompatibleOfAuthorityFactory(id, authorityFactory)) { + try { + auto crs = io::AuthorityFactory::create( + authorityFactory->databaseContext(), + *id->codeSpace()) + ->createGeodeticCRS(id->code()); + bool match = _isEquivalentTo(crs.get(), crsCriterion); + res.emplace_back(crs, match ? 100 : 25); + return res; + } catch (const std::exception &) { + } } } } else { @@ -2299,20 +2332,23 @@ VerticalCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { const bool unsignificantName = thisName.empty() || ci_equal(thisName, "unknown") || ci_equal(thisName, "unnamed"); - if (!identifiers().empty()) { + if (hasCodeCompatibleOfAuthorityFactory(this, authorityFactory)) { // If the CRS has already an id, check in the database for the // official object, and verify that they are equivalent. for (const auto &id : identifiers()) { - try { - auto crs = io::AuthorityFactory::create( - authorityFactory->databaseContext(), - *id->codeSpace()) - ->createVerticalCRS(id->code()); - bool match = _isEquivalentTo( - crs.get(), util::IComparable::Criterion::EQUIVALENT); - res.emplace_back(crs, match ? 100 : 25); - return res; - } catch (const std::exception &) { + if (hasCodeCompatibleOfAuthorityFactory(id, authorityFactory)) { + try { + auto crs = io::AuthorityFactory::create( + authorityFactory->databaseContext(), + *id->codeSpace()) + ->createVerticalCRS(id->code()); + bool match = _isEquivalentTo( + crs.get(), + util::IComparable::Criterion::EQUIVALENT); + res.emplace_back(crs, match ? 100 : 25); + return res; + } catch (const std::exception &) { + } } } } else if (!unsignificantName) { @@ -3100,21 +3136,24 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { ci_equal(thisName, "unnamed"); bool foundEquivalentName = false; - if (!identifiers().empty()) { + if (hasCodeCompatibleOfAuthorityFactory(this, authorityFactory)) { // If the CRS has already an id, check in the database for the // official object, and verify that they are equivalent. for (const auto &id : identifiers()) { - try { - auto crs = io::AuthorityFactory::create( - authorityFactory->databaseContext(), - *id->codeSpace()) - ->createProjectedCRS(id->code()); - bool match = _isEquivalentTo( - crs.get(), util::IComparable::Criterion:: - EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS); - res.emplace_back(crs, match ? 100 : 25); - return res; - } catch (const std::exception &) { + if (hasCodeCompatibleOfAuthorityFactory(id, authorityFactory)) { + try { + auto crs = io::AuthorityFactory::create( + authorityFactory->databaseContext(), + *id->codeSpace()) + ->createProjectedCRS(id->code()); + bool match = _isEquivalentTo( + crs.get(), + util::IComparable::Criterion:: + EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS); + res.emplace_back(crs, match ? 100 : 25); + return res; + } catch (const std::exception &) { + } } } } else if (!unsignificantName) { @@ -3189,8 +3228,8 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { // Sort results res.sort(lambdaSort); - if (identifiers().empty() && !foundEquivalentName && - (res.empty() || res.front().second < 50)) { + if (!hasCodeCompatibleOfAuthorityFactory(this, authorityFactory) && + !foundEquivalentName && (res.empty() || res.front().second < 50)) { std::set<std::pair<std::string, std::string>> alreadyKnown; for (const auto &pair : res) { const auto &ids = pair.first->identifiers(); @@ -3448,20 +3487,23 @@ CompoundCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const { ci_equal(thisName, "unnamed"); bool foundEquivalentName = false; - if (!identifiers().empty()) { + if (hasCodeCompatibleOfAuthorityFactory(this, authorityFactory)) { // If the CRS has already an id, check in the database for the // official object, and verify that they are equivalent. for (const auto &id : identifiers()) { - try { - auto crs = io::AuthorityFactory::create( - authorityFactory->databaseContext(), - *id->codeSpace()) - ->createCompoundCRS(id->code()); - bool match = _isEquivalentTo( - crs.get(), util::IComparable::Criterion::EQUIVALENT); - res.emplace_back(crs, match ? 100 : 25); - return res; - } catch (const std::exception &) { + if (hasCodeCompatibleOfAuthorityFactory(id, authorityFactory)) { + try { + auto crs = io::AuthorityFactory::create( + authorityFactory->databaseContext(), + *id->codeSpace()) + ->createCompoundCRS(id->code()); + bool match = _isEquivalentTo( + crs.get(), + util::IComparable::Criterion::EQUIVALENT); + res.emplace_back(crs, match ? 100 : 25); + return res; + } catch (const std::exception &) { + } } } } else if (!unsignificantName) { |
