diff options
| -rw-r--r-- | src/iso19111/factory.cpp | 73 | ||||
| -rw-r--r-- | test/unit/test_operationfactory.cpp | 16 |
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( |
