aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/crs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/iso19111/crs.cpp')
-rw-r--r--src/iso19111/crs.cpp85
1 files changed, 56 insertions, 29 deletions
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp
index 73c61e2c..7c58640e 100644
--- a/src/iso19111/crs.cpp
+++ b/src/iso19111/crs.cpp
@@ -39,6 +39,7 @@
#include "proj/coordinateoperation.hpp"
#include "proj/coordinatesystem.hpp"
#include "proj/io.hpp"
+#include "proj/metadata.hpp"
#include "proj/util.hpp"
#include "proj/internal/coordinatesystem_internal.hpp"
@@ -446,7 +447,8 @@ CRSNNPtr CRS::createBoundCRSToWGS84IfPossible(
crs_authority = *(l_identifiers[0]->codeSpace());
}
- auto authorities = dbContext->getAllowedAuthorities(crs_authority, "EPSG");
+ auto authorities = dbContext->getAllowedAuthorities(
+ crs_authority, metadata::Identifier::EPSG);
if (authorities.empty()) {
authorities.emplace_back();
}
@@ -1686,8 +1688,8 @@ void GeodeticCRS::_exportToWKT(io::WKTFormatter *formatter) const {
auto geogCRS2D = demoteTo2D(std::string(), dbContext);
if (dbContext) {
- const auto res = geogCRS2D->identify(
- io::AuthorityFactory::create(NN_NO_CHECK(dbContext), "EPSG"));
+ const auto res = geogCRS2D->identify(io::AuthorityFactory::create(
+ NN_NO_CHECK(dbContext), metadata::Identifier::EPSG));
if (res.size() == 1) {
const auto &front = res.front();
if (front.second == 100) {
@@ -2086,26 +2088,31 @@ GeodeticCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
? util::IComparable::Criterion::EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS
: util::IComparable::Criterion::EQUIVALENT;
- const GeographicCRSNNPtr candidatesCRS[] = {GeographicCRS::EPSG_4326,
- GeographicCRS::EPSG_4267,
- GeographicCRS::EPSG_4269};
- for (const auto &crs : candidatesCRS) {
- const bool nameEquivalent = metadata::Identifier::isEquivalentName(
- thisName.c_str(), crs->nameStr().c_str());
- const bool nameEqual = thisName == crs->nameStr();
- const bool isEq = _isEquivalentTo(crs.get(), crsCriterion, dbContext);
- if (nameEquivalent && isEq && (!authorityFactory || nameEqual)) {
- res.emplace_back(util::nn_static_pointer_cast<GeodeticCRS>(crs),
- nameEqual ? 100 : 90);
- return res;
- } else if (nameEqual && !isEq && !authorityFactory) {
- res.emplace_back(util::nn_static_pointer_cast<GeodeticCRS>(crs),
- 25);
- return res;
- } else if (isEq && !authorityFactory) {
- res.emplace_back(util::nn_static_pointer_cast<GeodeticCRS>(crs),
- 70);
- return res;
+ if (authorityFactory == nullptr ||
+ authorityFactory->getAuthority().empty() ||
+ authorityFactory->getAuthority() == metadata::Identifier::EPSG) {
+ const GeographicCRSNNPtr candidatesCRS[] = {GeographicCRS::EPSG_4326,
+ GeographicCRS::EPSG_4267,
+ GeographicCRS::EPSG_4269};
+ for (const auto &crs : candidatesCRS) {
+ const bool nameEquivalent = metadata::Identifier::isEquivalentName(
+ thisName.c_str(), crs->nameStr().c_str());
+ const bool nameEqual = thisName == crs->nameStr();
+ const bool isEq =
+ _isEquivalentTo(crs.get(), crsCriterion, dbContext);
+ if (nameEquivalent && isEq && (!authorityFactory || nameEqual)) {
+ res.emplace_back(util::nn_static_pointer_cast<GeodeticCRS>(crs),
+ nameEqual ? 100 : 90);
+ return res;
+ } else if (nameEqual && !isEq && !authorityFactory) {
+ res.emplace_back(util::nn_static_pointer_cast<GeodeticCRS>(crs),
+ 25);
+ return res;
+ } else if (isEq && !authorityFactory) {
+ res.emplace_back(util::nn_static_pointer_cast<GeodeticCRS>(crs),
+ 70);
+ return res;
+ }
}
}
@@ -3645,8 +3652,8 @@ void ProjectedCRS::_exportToWKT(io::WKTFormatter *formatter) const {
if (axisList.size() == 3 && !(isWKT2 && formatter->use2019Keywords())) {
auto projCRS2D = demoteTo2D(std::string(), dbContext);
if (dbContext) {
- const auto res = projCRS2D->identify(
- io::AuthorityFactory::create(NN_NO_CHECK(dbContext), "EPSG"));
+ const auto res = projCRS2D->identify(io::AuthorityFactory::create(
+ NN_NO_CHECK(dbContext), metadata::Identifier::EPSG));
if (res.size() == 1) {
const auto &front = res.front();
if (front.second == 100) {
@@ -4164,19 +4171,25 @@ ProjectedCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
? 90
: 70;
};
- auto computeUTMCRSName = [](const char *base, int l_zone, bool l_north) {
- return base + toString(l_zone) + (l_north ? "N" : "S");
- };
const auto &conv = derivingConversionRef();
const auto &cs = coordinateSystem();
if (baseRes.size() == 1 && baseRes.front().second >= 70 &&
+ (authorityFactory == nullptr ||
+ authorityFactory->getAuthority().empty() ||
+ authorityFactory->getAuthority() == metadata::Identifier::EPSG) &&
conv->isUTM(zone, north) &&
cs->_isEquivalentTo(
cs::CartesianCS::createEastingNorthing(common::UnitOfMeasure::METRE)
.get(),
util::IComparable::Criterion::EQUIVALENT, dbContext)) {
+
+ auto computeUTMCRSName = [](const char *base, int l_zone,
+ bool l_north) {
+ return base + toString(l_zone) + (l_north ? "N" : "S");
+ };
+
if (baseRes.front().first->_isEquivalentTo(
GeographicCRS::EPSG_4326.get(),
util::IComparable::Criterion::EQUIVALENT, dbContext)) {
@@ -4829,7 +4842,14 @@ CompoundCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
const auto &thisName(nameStr());
const auto &components = componentReferenceSystems();
- const bool l_implicitCS = components[0]->hasImplicitCS();
+ bool l_implicitCS = components[0]->hasImplicitCS();
+ if (!l_implicitCS) {
+ const auto projCRS =
+ dynamic_cast<const ProjectedCRS *>(components[0].get());
+ if (projCRS) {
+ l_implicitCS = projCRS->baseCRS()->hasImplicitCS();
+ }
+ }
const auto crsCriterion =
l_implicitCS
? util::IComparable::Criterion::EQUIVALENT_EXCEPT_AXIS_ORDER_GEOGCRS
@@ -4949,6 +4969,13 @@ CompoundCRS::identify(const io::AuthorityFactoryPtr &authorityFactory) const {
}
res.sort(lambdaSort);
+
+ // If there's a single candidate at 90% confidence with same name,
+ // then promote it to 100%
+ if (res.size() == 1 && res.front().second == 90 &&
+ thisName == res.front().first->nameStr()) {
+ res.front().second = 100;
+ }
}
// If we didn't find a match for the CompoundCRS, check if the