aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-11-17 20:03:29 +0100
committerEven Rouault <even.rouault@spatialys.com>2019-11-17 20:03:29 +0100
commit940bb7447647631676b90b03431aa88cb88fdd2d (patch)
tree51fa2bbbcf219c289fc8f8991d0bec35d7e67a5d /src
parent650fb0fd911cba631d9202fe718fd7b705cb3f8e (diff)
downloadPROJ-940bb7447647631676b90b03431aa88cb88fdd2d.tar.gz
PROJ-940bb7447647631676b90b03431aa88cb88fdd2d.zip
findsOpsInRegistryWithIntermediate(): tune it to be able to research operations that belong to different authorities. Should make the concept of geodetic_datum_preferred_hub introduced some time ago obsolete
Diffstat (limited to 'src')
-rw-r--r--src/iso19111/coordinateoperation.cpp77
-rw-r--r--src/iso19111/factory.cpp27
2 files changed, 68 insertions, 36 deletions
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp
index 11c10e74..872ef047 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -11587,46 +11587,51 @@ CoordinateOperationFactory::Private::findsOpsInRegistryWithIntermediate(
const auto authorities(getCandidateAuthorities(
authFactory, srcAuthName, targetAuthName));
- for (const auto &authority : authorities) {
- const auto tmpAuthFactory = io::AuthorityFactory::create(
- authFactory->databaseContext(),
- authority == "any" ? std::string() : authority);
+ assert(!authorities.empty());
- io::AuthorityFactory::ObjectType intermediateObjectType =
- io::AuthorityFactory::ObjectType::CRS;
-
- // If doing GeogCRS --> GeogCRS, only use GeogCRS as
- // intermediate CRS
- // Avoid weird behaviour when doing NAD83 -> NAD83(2011)
- // that would go through NAVD88 otherwise.
- if (context.context->getIntermediateCRS().empty() &&
- dynamic_cast<const crs::GeographicCRS *>(sourceCRS.get()) &&
- dynamic_cast<const crs::GeographicCRS *>(targetCRS.get())) {
- intermediateObjectType =
- io::AuthorityFactory::ObjectType::GEOGRAPHIC_CRS;
- }
- auto res = tmpAuthFactory->createFromCRSCodesWithIntermediates(
- srcAuthName, srcCode, targetAuthName, targetCode,
- context.context->getUsePROJAlternativeGridNames(),
- context.context->getGridAvailabilityUse() ==
- CoordinateOperationContext::GridAvailabilityUse::
- DISCARD_OPERATION_IF_MISSING_GRID,
- context.context->getDiscardSuperseded(),
- context.context->getIntermediateCRS(),
- intermediateObjectType, context.extent1, context.extent2);
- if (!res.empty()) {
+ const auto tmpAuthFactory = io::AuthorityFactory::create(
+ authFactory->databaseContext(),
+ (authFactory->getAuthority() == "any" || authorities.size() > 1)
+ ? std::string()
+ : authorities.front());
+
+ io::AuthorityFactory::ObjectType intermediateObjectType =
+ io::AuthorityFactory::ObjectType::CRS;
+
+ // If doing GeogCRS --> GeogCRS, only use GeogCRS as
+ // intermediate CRS
+ // Avoid weird behaviour when doing NAD83 -> NAD83(2011)
+ // that would go through NAVD88 otherwise.
+ if (context.context->getIntermediateCRS().empty() &&
+ dynamic_cast<const crs::GeographicCRS *>(sourceCRS.get()) &&
+ dynamic_cast<const crs::GeographicCRS *>(targetCRS.get())) {
+ intermediateObjectType =
+ io::AuthorityFactory::ObjectType::GEOGRAPHIC_CRS;
+ }
+ auto res = tmpAuthFactory->createFromCRSCodesWithIntermediates(
+ srcAuthName, srcCode, targetAuthName, targetCode,
+ context.context->getUsePROJAlternativeGridNames(),
+ context.context->getGridAvailabilityUse() ==
+ CoordinateOperationContext::GridAvailabilityUse::
+ DISCARD_OPERATION_IF_MISSING_GRID,
+ context.context->getDiscardSuperseded(),
+ context.context->getIntermediateCRS(), intermediateObjectType,
+ authFactory->getAuthority() != "any" && authorities.size() > 1
+ ? authorities
+ : std::vector<std::string>(),
+ context.extent1, context.extent2);
+ if (!res.empty()) {
- auto resFiltered =
- FilterResults(res, context.context, context.extent1,
- context.extent2, false)
- .getRes();
+ auto resFiltered =
+ FilterResults(res, context.context, context.extent1,
+ context.extent2, false)
+ .getRes();
#ifdef TRACE_CREATE_OPERATIONS
- logTrace("filtering reduced from " +
- toString(static_cast<int>(res.size())) + " to " +
- toString(static_cast<int>(resFiltered.size())));
+ logTrace("filtering reduced from " +
+ toString(static_cast<int>(res.size())) + " to " +
+ toString(static_cast<int>(resFiltered.size())));
#endif
- return resFiltered;
- }
+ return resFiltered;
}
}
}
diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp
index d9917996..b55efb3c 100644
--- a/src/iso19111/factory.cpp
+++ b/src/iso19111/factory.cpp
@@ -3775,6 +3775,11 @@ static bool useIrrelevantPivot(const operation::CoordinateOperationNNPtr &op,
* @param allowedIntermediateObjectType Restrict the type of the intermediate
* object considered.
* Only ObjectType::CRS and ObjectType::GEOGRAPHIC_CRS supported currently
+ * @param allowedAuthorities One or several authority name allowed for the two
+ * coordinate operations that are going to be searched. When this vector is
+ * no empty, it overrides the authority of this object. This is useful for
+ * example when the coordinate operations to chain belong to two different
+ * allowed authorities.
* @param intersectingExtent1 Optional extent that the resulting operations
* must intersect.
* @param intersectingExtent2 Optional extent that the resulting operations
@@ -3793,6 +3798,7 @@ AuthorityFactory::createFromCRSCodesWithIntermediates(
const std::vector<std::pair<std::string, std::string>>
&intermediateCRSAuthCodes,
ObjectType allowedIntermediateObjectType,
+ const std::vector<std::string> &allowedAuthorities,
const metadata::ExtentPtr &intersectingExtent1,
const metadata::ExtentPtr &intersectingExtent2) const {
@@ -3887,6 +3893,27 @@ AuthorityFactory::createFromCRSCodesWithIntermediates(
"AND v1.deprecated = 0 AND v2.deprecated = 0 "
"AND intersects_bbox(south_lat1, west_lon1, north_lat1, east_lon1, "
"south_lat2, west_lon2, north_lat2, east_lon2) = 1 ");
+ if (!allowedAuthorities.empty()) {
+ additionalWhere += "AND v1.auth_name IN (";
+ for (size_t i = 0; i < allowedAuthorities.size(); i++) {
+ if (i > 0)
+ additionalWhere += ',';
+ additionalWhere += '?';
+ }
+ additionalWhere += ") AND v2.auth_name IN (";
+ for (size_t i = 0; i < allowedAuthorities.size(); i++) {
+ if (i > 0)
+ additionalWhere += ',';
+ additionalWhere += '?';
+ }
+ additionalWhere += ')';
+ for (const auto &allowedAuthority : allowedAuthorities) {
+ params.emplace_back(allowedAuthority);
+ }
+ for (const auto &allowedAuthority : allowedAuthorities) {
+ params.emplace_back(allowedAuthority);
+ }
+ }
if (d->hasAuthorityRestriction()) {
additionalWhere += "AND v1.auth_name = ? AND v2.auth_name = ? ";
params.emplace_back(d->authority());