aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/operation/coordinateoperationfactory.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2021-09-08 14:34:50 +0200
committerEven Rouault <even.rouault@spatialys.com>2021-09-08 17:05:45 +0200
commit078952e7f078e029d66ab6ca1ed594dfecadd1fc (patch)
treefe4d22d37c1ba5343a5f5b17382ba6a8a1cb154e /src/iso19111/operation/coordinateoperationfactory.cpp
parentbc568fcc99257731a939d93cd0caa4725e6803e4 (diff)
downloadPROJ-078952e7f078e029d66ab6ca1ed594dfecadd1fc.tar.gz
PROJ-078952e7f078e029d66ab6ca1ed594dfecadd1fc.zip
createOperations(): use an explicit conversion operation for geodetic <--> geocentric latitude
Diffstat (limited to 'src/iso19111/operation/coordinateoperationfactory.cpp')
-rw-r--r--src/iso19111/operation/coordinateoperationfactory.cpp38
1 files changed, 29 insertions, 9 deletions
diff --git a/src/iso19111/operation/coordinateoperationfactory.cpp b/src/iso19111/operation/coordinateoperationfactory.cpp
index 60365713..1b1cae9b 100644
--- a/src/iso19111/operation/coordinateoperationfactory.cpp
+++ b/src/iso19111/operation/coordinateoperationfactory.cpp
@@ -2993,13 +2993,6 @@ CoordinateOperationFactory::Private::createOperations(
}
}
- // Special case if both CRS are geodetic
- if (geodSrc && geodDst && !derivedSrc && !derivedDst) {
- createOperationsGeodToGeod(sourceCRS, targetCRS, context, geodSrc,
- geodDst, res);
- return res;
- }
-
if (geodSrc && geodSrc->isSphericalPlanetocentric()) {
createOperationsFromSphericalPlanetocentric(sourceCRS, targetCRS,
context, geodSrc, res);
@@ -3008,6 +3001,13 @@ CoordinateOperationFactory::Private::createOperations(
return applyInverse(createOperations(targetCRS, sourceCRS, context));
}
+ // Special case if both CRS are geodetic
+ if (geodSrc && geodDst && !derivedSrc && !derivedDst) {
+ createOperationsGeodToGeod(sourceCRS, targetCRS, context, geodSrc,
+ geodDst, res);
+ return res;
+ }
+
if (boundSrc) {
auto geodSrcBase = util::nn_dynamic_pointer_cast<crs::GeodeticCRS>(
boundSrc->baseCRS());
@@ -3940,6 +3940,24 @@ void CoordinateOperationFactory::Private::
ENTER_FUNCTION();
+ const auto IsSameDatum = [&context,
+ &geodSrc](const crs::GeodeticCRS *geodDst) {
+ const auto &authFactory = context.context->getAuthorityFactory();
+ const auto dbContext =
+ authFactory ? authFactory->databaseContext().as_nullable()
+ : nullptr;
+
+ return geodSrc->datumNonNull(dbContext)->_isEquivalentTo(
+ geodDst->datumNonNull(dbContext).get(),
+ util::IComparable::Criterion::EQUIVALENT);
+ };
+ auto geogDst = dynamic_cast<const crs::GeographicCRS *>(targetCRS.get());
+ if (geogDst && IsSameDatum(geogDst)) {
+ res.emplace_back(Conversion::createGeographicGeocentricLatitude(
+ sourceCRS, targetCRS));
+ return;
+ }
+
// Create an intermediate geographic CRS with the same datum as the
// source spherical planetocentric one
std::string interm_crs_name(geodSrc->nameStr());
@@ -3953,7 +3971,8 @@ void CoordinateOperationFactory::Private::
cs::EllipsoidalCS::createLatitudeLongitude(
common::UnitOfMeasure::DEGREE)));
- auto opFirst = createGeodToGeodPROJBased(sourceCRS, interm_crs);
+ auto opFirst =
+ Conversion::createGeographicGeocentricLatitude(sourceCRS, interm_crs);
auto opsSecond = createOperations(interm_crs, targetCRS, context);
for (const auto &opSecond : opsSecond) {
try {
@@ -3999,7 +4018,8 @@ void CoordinateOperationFactory::Private::
auto intermBoundCRS =
crs::BoundCRS::create(intermGeog, boundSrc->hubCRS(), transf);
- auto opFirst = createGeodToGeodPROJBased(geodSrcBase, intermGeog);
+ auto opFirst =
+ Conversion::createGeographicGeocentricLatitude(geodSrcBase, intermGeog);
setCRSs(opFirst.get(), sourceCRS, intermBoundCRS);
auto opsSecond = createOperations(intermBoundCRS, targetCRS, context);
for (const auto &opSecond : opsSecond) {