aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111/factory.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-09-12 15:55:04 +0200
committerEven Rouault <even.rouault@spatialys.com>2019-09-12 22:57:25 +0200
commiteed28e5183579d09e102d1ad72e91fc82005dfe8 (patch)
tree7986041f092cb4dcf53f61bdbe5f95f9e4705a08 /src/iso19111/factory.cpp
parent63857c92b271bbcd10df0a032304982011acb2a9 (diff)
downloadPROJ-eed28e5183579d09e102d1ad72e91fc82005dfe8.tar.gz
PROJ-eed28e5183579d09e102d1ad72e91fc82005dfe8.zip
createOperations(): use more candidates when transforming between a geographic and vertical CRS
For example when transforming from NAD83+NAVD88 height to WGS84, there is no transformation between NAVD88 height to WGS84. In that case, use all potential transformations from NAVD88 height to another geographic CRS for the vertical part.
Diffstat (limited to 'src/iso19111/factory.cpp')
-rw-r--r--src/iso19111/factory.cpp69
1 files changed, 39 insertions, 30 deletions
diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp
index 4bf5427d..3ed69ae9 100644
--- a/src/iso19111/factory.cpp
+++ b/src/iso19111/factory.cpp
@@ -3312,9 +3312,9 @@ AuthorityFactory::createFromCoordinateReferenceSystemCodes(
bool discardSuperseded) const {
auto cacheKey(d->authority());
- cacheKey += sourceCRSAuthName;
+ cacheKey += sourceCRSAuthName.empty() ? "{empty}" : sourceCRSAuthName;
cacheKey += sourceCRSCode;
- cacheKey += targetCRSAuthName;
+ cacheKey += targetCRSAuthName.empty() ? "{empty}" : targetCRSAuthName;
cacheKey += targetCRSCode;
cacheKey += (usePROJAlternativeGridNames ? '1' : '0');
cacheKey += (discardIfMissingGrid ? '1' : '0');
@@ -3326,27 +3326,30 @@ AuthorityFactory::createFromCoordinateReferenceSystemCodes(
return list;
}
- // Look-up first for conversion which is the most precise.
- std::string sql("SELECT conversion_auth_name, "
- "geodetic_crs_auth_name, geodetic_crs_code FROM "
- "projected_crs WHERE auth_name = ? AND code = ?");
- auto params = ListOfParams{targetCRSAuthName, targetCRSCode};
- auto res = d->run(sql, params);
- if (!res.empty()) {
- const auto &row = res.front();
- bool ok = row[1] == sourceCRSAuthName && row[2] == sourceCRSCode;
- if (ok && d->hasAuthorityRestriction()) {
- ok = row[0] == d->authority();
- }
- if (ok) {
- auto targetCRS = d->createFactory(targetCRSAuthName)
- ->createProjectedCRS(targetCRSCode);
- auto conv = targetCRS->derivingConversion();
- list.emplace_back(conv);
- d->context()->d->cache(cacheKey, list);
- return list;
+ if (!targetCRSAuthName.empty()) {
+ // Look-up first for conversion which is the most precise.
+ std::string sql("SELECT conversion_auth_name, "
+ "geodetic_crs_auth_name, geodetic_crs_code FROM "
+ "projected_crs WHERE auth_name = ? AND code = ?");
+ auto params = ListOfParams{targetCRSAuthName, targetCRSCode};
+ auto res = d->run(sql, params);
+ if (!res.empty()) {
+ const auto &row = res.front();
+ bool ok = row[1] == sourceCRSAuthName && row[2] == sourceCRSCode;
+ if (ok && d->hasAuthorityRestriction()) {
+ ok = row[0] == d->authority();
+ }
+ if (ok) {
+ auto targetCRS = d->createFactory(targetCRSAuthName)
+ ->createProjectedCRS(targetCRSCode);
+ auto conv = targetCRS->derivingConversion();
+ list.emplace_back(conv);
+ d->context()->d->cache(cacheKey, list);
+ return list;
+ }
}
}
+ std::string sql;
if (discardSuperseded) {
sql = "SELECT cov.auth_name, cov.code, cov.table_name, "
"ss.replacement_auth_name, ss.replacement_code FROM "
@@ -3358,20 +3361,26 @@ AuthorityFactory::createFromCoordinateReferenceSystemCodes(
"ss.superseded_auth_name = cov.auth_name AND "
"ss.superseded_code = cov.code AND "
"ss.superseded_table_name = ss.replacement_table_name "
- "WHERE source_crs_auth_name = ? AND source_crs_code = ? AND "
- "target_crs_auth_name = ? AND target_crs_code = ? AND "
- "cov.deprecated = 0";
+ "WHERE ";
} else {
sql = "SELECT cov.auth_name, cov.code, cov.table_name FROM "
"coordinate_operation_view cov JOIN area "
"ON cov.area_of_use_auth_name = area.auth_name AND "
"cov.area_of_use_code = area.code "
- "WHERE source_crs_auth_name = ? AND source_crs_code = ? AND "
- "target_crs_auth_name = ? AND target_crs_code = ? AND "
- "cov.deprecated = 0";
+ "WHERE ";
+ }
+ ListOfParams params;
+ if (!sourceCRSAuthName.empty()) {
+ sql += "source_crs_auth_name = ? AND source_crs_code = ? AND ";
+ params.emplace_back(sourceCRSAuthName);
+ params.emplace_back(sourceCRSCode);
+ }
+ if (!targetCRSAuthName.empty()) {
+ sql += "target_crs_auth_name = ? AND target_crs_code = ? AND ";
+ params.emplace_back(targetCRSAuthName);
+ params.emplace_back(targetCRSCode);
}
- params = {sourceCRSAuthName, sourceCRSCode, targetCRSAuthName,
- targetCRSCode};
+ sql += "cov.deprecated = 0";
if (d->hasAuthorityRestriction()) {
sql += " AND cov.auth_name = ?";
params.emplace_back(d->authority());
@@ -3379,7 +3388,7 @@ AuthorityFactory::createFromCoordinateReferenceSystemCodes(
sql += " ORDER BY pseudo_area_from_swne(south_lat, west_lon, north_lat, "
"east_lon) DESC, "
"(CASE WHEN accuracy is NULL THEN 1 ELSE 0 END), accuracy";
- res = d->run(sql, params);
+ auto res = d->run(sql, params);
std::set<std::pair<std::string, std::string>> setTransf;
if (discardSuperseded) {
for (const auto &row : res) {