aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2021-04-18 16:29:57 +0200
committerGitHub <noreply@github.com>2021-04-18 16:29:57 +0200
commitc70a7447c1f7ca71534b0b711150784aff5b8dbd (patch)
tree6b59da476222a0e0ecacc056f811d3f06f07deb6
parente4e2991b174ea48b67e9b41c8f356a9cf1bba081 (diff)
parentdd79ca70edcee3dc4f5485a87e11e52cfa2ea041 (diff)
downloadPROJ-c70a7447c1f7ca71534b0b711150784aff5b8dbd.tar.gz
PROJ-c70a7447c1f7ca71534b0b711150784aff5b8dbd.zip
Merge pull request #2676 from rouault/fix_geog_to_geog_deprecated
createOperations(): fix Geog to Geog when one is deprecated (fix master regression)
-rw-r--r--src/iso19111/factory.cpp73
-rw-r--r--test/unit/test_operationfactory.cpp16
2 files changed, 59 insertions, 30 deletions
diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp
index 088289c5..8f2bd24a 100644
--- a/src/iso19111/factory.cpp
+++ b/src/iso19111/factory.cpp
@@ -6752,42 +6752,55 @@ AuthorityFactory::createBetweenGeodeticCRSWithDatumBasedIntermediates(
return listTmp;
}
- // Find all geodetic CRS that share the same datum as the source CRS
- SQLResultSet listSourceCRS;
- {
- const auto res = d->run("SELECT datum_auth_name, datum_code FROM "
- "geodetic_crs WHERE auth_name = ? AND code = ?",
- {sourceCRSAuthName, sourceCRSCode});
- if (res.size() != 1) {
- return listTmp;
+ const auto GetListCRSWithSameDatum = [this](const crs::GeodeticCRS *crs,
+ const std::string &crsAuthName,
+ const std::string &crsCode) {
+ // Find all geodetic CRS that share the same datum as the CRS
+ SQLResultSet listCRS;
+
+ const common::IdentifiedObject *obj = crs->datum().get();
+ if (obj == nullptr)
+ obj = crs->datumEnsemble().get();
+ assert(obj != nullptr);
+ const auto &ids = obj->identifiers();
+ std::string datumAuthName;
+ std::string datumCode;
+ if (!ids.empty()) {
+ const auto &id = ids.front();
+ datumAuthName = *(id->codeSpace());
+ datumCode = id->code();
+ } else {
+ const auto res =
+ d->run("SELECT datum_auth_name, datum_code FROM "
+ "geodetic_crs WHERE auth_name = ? AND code = ?",
+ {crsAuthName, crsCode});
+ if (res.size() != 1) {
+ return listCRS;
+ }
+ const auto &row = res.front();
+ datumAuthName = row[0];
+ datumCode = row[1];
}
- const auto &row = res.front();
- const auto sourceDatumAuthName = row[0];
- const auto sourceDatumCode = row[1];
- listSourceCRS =
+ listCRS =
d->run("SELECT auth_name, code FROM geodetic_crs WHERE "
"datum_auth_name = ? AND datum_code = ? AND deprecated = 0",
- {sourceDatumAuthName, sourceDatumCode});
- }
-
- // Find all geodetic CRS that share the same datum as the target CRS
- SQLResultSet listTargetCRS;
- {
- const auto res = d->run("SELECT datum_auth_name, datum_code FROM "
- "geodetic_crs WHERE auth_name = ? AND code = ?",
- {targetCRSAuthName, targetCRSCode});
- if (res.size() != 1) {
- return listTmp;
+ {datumAuthName, datumCode});
+ if (listCRS.empty()) {
+ // Can happen if the CRS is deprecated
+ listCRS.emplace_back(SQLRow{crsAuthName, crsCode});
}
- const auto &row = res.front();
- const auto targetDatumAuthName = row[0];
- const auto targetDatumCode = row[1];
+ return listCRS;
+ };
- listTargetCRS =
- d->run("SELECT auth_name, code FROM geodetic_crs WHERE "
- "datum_auth_name = ? AND datum_code = ? AND deprecated = 0",
- {targetDatumAuthName, targetDatumCode});
+ const SQLResultSet listSourceCRS = GetListCRSWithSameDatum(
+ sourceGeodCRS, sourceCRSAuthName, sourceCRSCode);
+ const SQLResultSet listTargetCRS = GetListCRSWithSameDatum(
+ targetGeodCRS, targetCRSAuthName, targetCRSCode);
+ if (listSourceCRS.empty() || listTargetCRS.empty()) {
+ // would happen only if we had CRS objects in the database without a
+ // link to a datum.
+ return listTmp;
}
ListOfParams params;
diff --git a/test/unit/test_operationfactory.cpp b/test/unit/test_operationfactory.cpp
index 7e33ca72..4c204c21 100644
--- a/test/unit/test_operationfactory.cpp
+++ b/test/unit/test_operationfactory.cpp
@@ -1033,6 +1033,22 @@ TEST(operation, geogCRS_to_geogCRS_init_IGNF_to_init_IGNF_context) {
// ---------------------------------------------------------------------------
+TEST(operation, geogCRS_to_geogCRS_context_deprecated) {
+ auto authFactory =
+ AuthorityFactory::create(DatabaseContext::create(), "EPSG");
+ auto ctxt = CoordinateOperationContext::create(authFactory, nullptr, 0.0);
+ auto list = CoordinateOperationFactory::create()->createOperations(
+ authFactory->createCoordinateReferenceSystem(
+ "4226"), // Cote d'Ivoire (deprecated)
+ authFactory->createCoordinateReferenceSystem("4258"), // ETRS89
+ ctxt);
+ ASSERT_TRUE(!list.empty());
+ EXPECT_EQ(list[0]->nameStr(),
+ "Ballpark geographic offset from Cote d'Ivoire to ETRS89");
+}
+
+// ---------------------------------------------------------------------------
+
TEST(operation, geogCRS_to_geogCRS_3D) {
auto geogcrs_m_obj = PROJStringParser().createFromPROJString(