aboutsummaryrefslogtreecommitdiff
path: root/src/crs.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/crs.cpp')
-rw-r--r--src/crs.cpp135
1 files changed, 79 insertions, 56 deletions
diff --git a/src/crs.cpp b/src/crs.cpp
index 546cfb0a..6212f561 100644
--- a/src/crs.cpp
+++ b/src/crs.cpp
@@ -409,74 +409,97 @@ CRSNNPtr CRS::createBoundCRSToWGS84IfPossible(
} else {
geodCRS = geogCRS;
}
- auto l_domains = domains();
+
+ if (!dbContext) {
+ return thisAsCRS;
+ }
+
+ const auto &l_domains = domains();
metadata::ExtentPtr extent;
if (!l_domains.empty()) {
extent = l_domains[0]->domainOfValidity();
}
- try {
- auto authFactory = dbContext
- ? io::AuthorityFactory::create(
- NN_NO_CHECK(dbContext), std::string())
- .as_nullable()
- : nullptr;
- auto ctxt = operation::CoordinateOperationContext::create(authFactory,
- extent, 0.0);
- // ctxt->setSpatialCriterion(
- // operation::CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION);
- auto list =
- operation::CoordinateOperationFactory::create()->createOperations(
- NN_NO_CHECK(geodCRS), hubCRS, ctxt);
- for (const auto &op : list) {
- auto transf =
- util::nn_dynamic_pointer_cast<operation::Transformation>(op);
- if (transf) {
- try {
- transf->getTOWGS84Parameters();
- } catch (const std::exception &) {
- continue;
- }
- return util::nn_static_pointer_cast<CRS>(
- BoundCRS::create(thisAsCRS, hubCRS, NN_NO_CHECK(transf)));
- } else {
- auto concatenated =
- dynamic_cast<const operation::ConcatenatedOperation *>(
- op.get());
- if (concatenated) {
- // Case for EPSG:4807 / "NTF (Paris)" that is made of a
- // longitude rotation followed by a Helmert
- // The prime meridian shift will be accounted elsewhere
- const auto &subops = concatenated->operations();
- if (subops.size() == 2) {
- auto firstOpIsTransformation =
- dynamic_cast<const operation::Transformation *>(
- subops[0].get());
- auto firstOpIsConversion =
- dynamic_cast<const operation::Conversion *>(
- subops[0].get());
- if ((firstOpIsTransformation &&
- firstOpIsTransformation->isLongitudeRotation()) ||
- (dynamic_cast<DerivedCRS *>(thisAsCRS.get()) &&
- firstOpIsConversion)) {
- transf = util::nn_dynamic_pointer_cast<
- operation::Transformation>(subops[1]);
- if (transf) {
- try {
- transf->getTOWGS84Parameters();
- } catch (const std::exception &) {
- continue;
+ std::string crs_authority;
+ const auto &l_identifiers = identifiers();
+ // If the object has an authority, restrict the transformations to
+ // come from that codespace too. This avoids for example EPSG:4269
+ // (NAD83) to use a (dubious) ESRI transformation.
+ if (!l_identifiers.empty()) {
+ crs_authority = *(l_identifiers[0]->codeSpace());
+ }
+
+ auto authorities = dbContext->getAllowedAuthorities(crs_authority, "EPSG");
+ if (authorities.empty()) {
+ authorities.emplace_back();
+ }
+ for (const auto &authority : authorities) {
+ try {
+
+ auto authFactory = io::AuthorityFactory::create(
+ NN_NO_CHECK(dbContext),
+ authority == "any" ? std::string() : authority);
+ auto ctxt = operation::CoordinateOperationContext::create(
+ authFactory, extent, 0.0);
+ // ctxt->setSpatialCriterion(
+ // operation::CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION);
+ auto list =
+ operation::CoordinateOperationFactory::create()
+ ->createOperations(NN_NO_CHECK(geodCRS), hubCRS, ctxt);
+ for (const auto &op : list) {
+ auto transf =
+ util::nn_dynamic_pointer_cast<operation::Transformation>(
+ op);
+ if (transf && !starts_with(transf->nameStr(), "Null geo")) {
+ try {
+ transf->getTOWGS84Parameters();
+ } catch (const std::exception &) {
+ continue;
+ }
+ return util::nn_static_pointer_cast<CRS>(BoundCRS::create(
+ thisAsCRS, hubCRS, NN_NO_CHECK(transf)));
+ } else {
+ auto concatenated =
+ dynamic_cast<const operation::ConcatenatedOperation *>(
+ op.get());
+ if (concatenated) {
+ // Case for EPSG:4807 / "NTF (Paris)" that is made of a
+ // longitude rotation followed by a Helmert
+ // The prime meridian shift will be accounted elsewhere
+ const auto &subops = concatenated->operations();
+ if (subops.size() == 2) {
+ auto firstOpIsTransformation =
+ dynamic_cast<const operation::Transformation *>(
+ subops[0].get());
+ auto firstOpIsConversion =
+ dynamic_cast<const operation::Conversion *>(
+ subops[0].get());
+ if ((firstOpIsTransformation &&
+ firstOpIsTransformation
+ ->isLongitudeRotation()) ||
+ (dynamic_cast<DerivedCRS *>(thisAsCRS.get()) &&
+ firstOpIsConversion)) {
+ transf = util::nn_dynamic_pointer_cast<
+ operation::Transformation>(subops[1]);
+ if (transf &&
+ !starts_with(transf->nameStr(),
+ "Null geo")) {
+ try {
+ transf->getTOWGS84Parameters();
+ } catch (const std::exception &) {
+ continue;
+ }
+ return util::nn_static_pointer_cast<CRS>(
+ BoundCRS::create(thisAsCRS, hubCRS,
+ NN_NO_CHECK(transf)));
}
- return util::nn_static_pointer_cast<CRS>(
- BoundCRS::create(thisAsCRS, hubCRS,
- NN_NO_CHECK(transf)));
}
}
}
}
}
+ } catch (const std::exception &) {
}
- } catch (const std::exception &) {
}
return thisAsCRS;
}