aboutsummaryrefslogtreecommitdiff
path: root/src/iso19111
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2019-02-17 19:40:38 +0100
committerEven Rouault <even.rouault@spatialys.com>2019-02-17 19:42:35 +0100
commite8b2e2a36324006146406fb1fc89ce6ed863807f (patch)
tree5c2c0c9229958d63e77171f64f909864855afb5d /src/iso19111
parenta8cbe0c66974871f5a7bd7ef94001ebf461ac7ea (diff)
downloadPROJ-e8b2e2a36324006146406fb1fc89ce6ed863807f.tar.gz
PROJ-e8b2e2a36324006146406fb1fc89ce6ed863807f.zip
Modify the default strategy of researching intermediate CRS to do it only if there is no direct transformation
Diffstat (limited to 'src/iso19111')
-rw-r--r--src/iso19111/c_api.cpp44
-rw-r--r--src/iso19111/coordinateoperation.cpp36
-rw-r--r--src/iso19111/crs.cpp9
3 files changed, 58 insertions, 31 deletions
diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp
index 79732bab..b3f200fe 100644
--- a/src/iso19111/c_api.cpp
+++ b/src/iso19111/c_api.cpp
@@ -1475,7 +1475,8 @@ PJ *proj_crs_create_bound_crs(PJ_CONTEXT *ctx, const PJ *base_crs,
* @param options null-terminated list of options, or NULL. Currently
* supported options are:
* <ul>
- * <li>ALLOW_INTERMEDIATE_CRS=YES/NO. Defaults to NO. When set to YES,
+ * <li>ALLOW_INTERMEDIATE_CRS=ALWAYS/IF_NO_DIRECT_TRANSFORMATION/NEVER. Defaults
+ * to NEVER. When set to ALWAYS/IF_NO_DIRECT_TRANSFORMATION,
* intermediate CRS may be considered when computing the possible
* transformations. Slower.</li>
* </ul>
@@ -1493,11 +1494,18 @@ PJ *proj_crs_create_bound_crs_to_WGS84(PJ_CONTEXT *ctx, const PJ *crs,
}
auto dbContext = getDBcontextNoException(ctx, __FUNCTION__);
try {
- bool allowIntermediateCRS = false;
+ CoordinateOperationContext::IntermediateCRSUse allowIntermediateCRS =
+ CoordinateOperationContext::IntermediateCRSUse::NEVER;
for (auto iter = options; iter && iter[0]; ++iter) {
const char *value;
if ((value = getOptionValue(*iter, "ALLOW_INTERMEDIATE_CRS="))) {
- allowIntermediateCRS = ci_equal(value, "YES");
+ if (ci_equal(value, "YES") || ci_equal(value, "ALWAYS")) {
+ allowIntermediateCRS =
+ CoordinateOperationContext::IntermediateCRSUse::ALWAYS;
+ } else if (ci_equal(value, "IF_NO_DIRECT_TRANSFORMATION")) {
+ allowIntermediateCRS = CoordinateOperationContext::
+ IntermediateCRSUse::IF_NO_DIRECT_TRANSFORMATION;
+ }
} else {
std::string msg("Unknown option :");
msg += *iter;
@@ -6378,22 +6386,36 @@ void proj_operation_factory_context_set_use_proj_alternative_grid_names(
* The current implementation is limited to researching one intermediate
* step.
*
- * By default, all potential C candidates will be used.
- * proj_operation_factory_context_set_allowed_intermediate_crs()
- * can be used to restrict them.
- *
- * The default is true.
+ * By default, with the IF_NO_DIRECT_TRANSFORMATION stratgey, all potential
+ * C candidates will be used if there is no direct tranformation.
*
* @param ctx PROJ context, or NULL for default context
* @param factory_ctx Operation factory context. must not be NULL
- * @param allow whether intermediate CRS may be used.
+ * @param use whether and how intermediate CRS may be used.
*/
void proj_operation_factory_context_set_allow_use_intermediate_crs(
- PJ_CONTEXT *ctx, PJ_OPERATION_FACTORY_CONTEXT *factory_ctx, int allow) {
+ PJ_CONTEXT *ctx, PJ_OPERATION_FACTORY_CONTEXT *factory_ctx,
+ PROJ_INTERMEDIATE_CRS_USE use) {
SANITIZE_CTX(ctx);
assert(factory_ctx);
try {
- factory_ctx->operationContext->setAllowUseIntermediateCRS(allow != 0);
+ switch (use) {
+ case PROJ_INTERMEDIATE_CRS_USE_ALWAYS:
+ factory_ctx->operationContext->setAllowUseIntermediateCRS(
+ CoordinateOperationContext::IntermediateCRSUse::ALWAYS);
+ break;
+
+ case PROJ_INTERMEDIATE_CRS_USE_IF_NO_DIRECT_TRANSFORMATION:
+ factory_ctx->operationContext->setAllowUseIntermediateCRS(
+ CoordinateOperationContext::IntermediateCRSUse::
+ IF_NO_DIRECT_TRANSFORMATION);
+ break;
+
+ case PROJ_INTERMEDIATE_CRS_USE_NEVER:
+ factory_ctx->operationContext->setAllowUseIntermediateCRS(
+ CoordinateOperationContext::IntermediateCRSUse::NEVER);
+ break;
+ }
} catch (const std::exception &e) {
proj_log_error(ctx, __FUNCTION__, e.what());
}
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp
index d964cdc1..2128124b 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -9242,7 +9242,8 @@ struct CoordinateOperationContext::Private {
bool usePROJNames_ = true;
GridAvailabilityUse gridAvailabilityUse_ =
GridAvailabilityUse::USE_FOR_SORTING;
- bool allowUseIntermediateCRS_ = true;
+ IntermediateCRSUse allowUseIntermediateCRS_ = CoordinateOperationContext::
+ IntermediateCRSUse::IF_NO_DIRECT_TRANSFORMATION;
std::vector<std::pair<std::string, std::string>>
intermediateCRSAuthCodes_{};
bool discardSuperseded_ = true;
@@ -9436,18 +9437,17 @@ CoordinateOperationContext::getGridAvailabilityUse() const {
*
* Concretely if in the database there is an operation from A to C
* (or C to A), and another one from C to B (or B to C), but no direct
- * operation between A and B, setting this parameter to true, allow
- * chaining both operations.
+ * operation between A and B, setting this parameter to
+ * ALWAYS/IF_NO_DIRECT_TRANSFORMATION, allow chaining both operations.
*
* The current implementation is limited to researching one intermediate
* step.
*
- * By default, all potential C candidates will be used. setIntermediateCRS()
- * can be used to restrict them.
- *
- * The default is true.
+ * By default, with the IF_NO_DIRECT_TRANSFORMATION stratgey, all potential
+ * C candidates will be used if there is no direct tranformation.
*/
-void CoordinateOperationContext::setAllowUseIntermediateCRS(bool use) {
+void CoordinateOperationContext::setAllowUseIntermediateCRS(
+ IntermediateCRSUse use) {
d->allowUseIntermediateCRS_ = use;
}
@@ -9458,12 +9458,13 @@ void CoordinateOperationContext::setAllowUseIntermediateCRS(bool use) {
*
* Concretely if in the database there is an operation from A to C
* (or C to A), and another one from C to B (or B to C), but no direct
- * operation between A and B, setting this parameter to true, allow
- * chaining both operations.
+ * operation between A and B, setting this parameter to
+ * ALWAYS/IF_NO_DIRECT_TRANSFORMATION, allow chaining both operations.
*
- * The default is true.
+ * The default is IF_NO_DIRECT_TRANSFORMATION.
*/
-bool CoordinateOperationContext::getAllowUseIntermediateCRS() const {
+CoordinateOperationContext::IntermediateCRSUse
+CoordinateOperationContext::getAllowUseIntermediateCRS() const {
return d->allowUseIntermediateCRS_;
}
@@ -10401,9 +10402,6 @@ findOpsInRegistryDirect(const crs::CRSNNPtr &sourceCRS,
static std::vector<CoordinateOperationNNPtr> findsOpsInRegistryWithIntermediate(
const crs::CRSNNPtr &sourceCRS, const crs::CRSNNPtr &targetCRS,
const CoordinateOperationContextNNPtr &context) {
- if (!context->getAllowUseIntermediateCRS()) {
- return std::vector<CoordinateOperationNNPtr>();
- }
const auto &authFactory = context->getAuthorityFactory();
assert(authFactory);
@@ -11215,7 +11213,13 @@ CoordinateOperationFactory::Private::createOperations(
// NAD27 to NAD83 has tens of results already. No need to look
// for a pivot
- if (res.size() < 5 || getenv("PROJ_FORCE_SEARCH_PIVOT")) {
+ if ((res.empty() &&
+ context.context->getAllowUseIntermediateCRS() ==
+ CoordinateOperationContext::IntermediateCRSUse::
+ IF_NO_DIRECT_TRANSFORMATION) ||
+ context.context->getAllowUseIntermediateCRS() ==
+ CoordinateOperationContext::IntermediateCRSUse::ALWAYS ||
+ getenv("PROJ_FORCE_SEARCH_PIVOT")) {
auto resWithIntermediate = findsOpsInRegistryWithIntermediate(
sourceCRS, targetCRS, context.context);
res.insert(res.end(), resWithIntermediate.begin(),
diff --git a/src/iso19111/crs.cpp b/src/iso19111/crs.cpp
index ebbed7a1..01a588e3 100644
--- a/src/iso19111/crs.cpp
+++ b/src/iso19111/crs.cpp
@@ -375,9 +375,10 @@ VerticalCRSPtr CRS::extractVerticalCRS() const {
*
* @return a CRS.
*/
-CRSNNPtr
-CRS::createBoundCRSToWGS84IfPossible(const io::DatabaseContextPtr &dbContext,
- bool allowIntermediateCRS) const {
+CRSNNPtr CRS::createBoundCRSToWGS84IfPossible(
+ const io::DatabaseContextPtr &dbContext,
+ operation::CoordinateOperationContext::IntermediateCRSUse
+ allowIntermediateCRSUse) const {
auto thisAsCRS = NN_NO_CHECK(
std::static_pointer_cast<CRS>(shared_from_this().as_nullable()));
auto boundCRS = util::nn_dynamic_pointer_cast<BoundCRS>(thisAsCRS);
@@ -442,7 +443,7 @@ CRS::createBoundCRSToWGS84IfPossible(const io::DatabaseContextPtr &dbContext,
authority == "any" ? std::string() : authority);
auto ctxt = operation::CoordinateOperationContext::create(
authFactory, extent, 0.0);
- ctxt->setAllowUseIntermediateCRS(allowIntermediateCRS);
+ ctxt->setAllowUseIntermediateCRS(allowIntermediateCRSUse);
// ctxt->setSpatialCriterion(
// operation::CoordinateOperationContext::SpatialCriterion::PARTIAL_INTERSECTION);
auto list =