diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2020-04-16 00:44:39 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-04-16 00:44:39 +0200 |
| commit | 000fa21d070e64200bc877b9d14444262e1a14b5 (patch) | |
| tree | 6d5dd2c3841bb87ec0816e6c9e9593b5091731a3 /src | |
| parent | c91966953d9ad327cbb3b9d80842cc0d3957df42 (diff) | |
| parent | 4be093e9d23b53915ed88a1c0da06f6833456a69 (diff) | |
| download | PROJ-000fa21d070e64200bc877b9d14444262e1a14b5.tar.gz PROJ-000fa21d070e64200bc877b9d14444262e1a14b5.zip | |
Merge pull request #2155 from rouault/fix_2143
createOperations(): do not remove ballpark transformation if there are only grid based operations, even if they cover the whole area of use (fixes #2143)
Diffstat (limited to 'src')
| -rw-r--r-- | src/apps/projinfo.cpp | 10 | ||||
| -rw-r--r-- | src/iso19111/c_api.cpp | 21 | ||||
| -rw-r--r-- | src/iso19111/coordinateoperation.cpp | 55 | ||||
| -rw-r--r-- | src/iso19111/factory.cpp | 3 | ||||
| -rw-r--r-- | src/proj.h | 5 |
5 files changed, 70 insertions, 24 deletions
diff --git a/src/apps/projinfo.cpp b/src/apps/projinfo.cpp index 10ce346f..85db14e2 100644 --- a/src/apps/projinfo.cpp +++ b/src/apps/projinfo.cpp @@ -705,6 +705,7 @@ static void outputOperations( ctxt->setIntermediateCRS(pivots); ctxt->setUsePROJAlternativeGridNames(usePROJGridAlternatives); ctxt->setDiscardSuperseded(!showSuperseded); + ctxt->setAllowBallparkTransformations(outputOpt.ballparkAllowed); list = CoordinateOperationFactory::create()->createOperations( nnSourceCRS, nnTargetCRS, ctxt); if (!spatialCriterionExplicitlySpecified && @@ -726,15 +727,6 @@ static void outputOperations( << std::endl; std::exit(1); } - if (!outputOpt.ballparkAllowed) { - std::vector<CoordinateOperationNNPtr> listNew; - for (const auto &op : list) { - if (!op->hasBallparkTransformation()) { - listNew.emplace_back(op); - } - } - list = std::move(listNew); - } if (outputOpt.quiet && !list.empty()) { outputObject(dbContext, list[0], allowUseIntermediateCRS, outputOpt); return; diff --git a/src/iso19111/c_api.cpp b/src/iso19111/c_api.cpp index 5a3f0374..6b726f34 100644 --- a/src/iso19111/c_api.cpp +++ b/src/iso19111/c_api.cpp @@ -7518,6 +7518,27 @@ void PROJ_DLL proj_operation_factory_context_set_discard_superseded( // --------------------------------------------------------------------------- +/** \brief Set whether ballpark transformations are allowed. + * + * @param ctx PROJ context, or NULL for default context + * @param factory_ctx Operation factory context. must not be NULL + * @param allow set to TRUE to allow ballpark transformations. + * @since 7.1 + */ +void PROJ_DLL proj_operation_factory_context_set_allow_ballpark_transformations( + PJ_CONTEXT *ctx, PJ_OPERATION_FACTORY_CONTEXT *factory_ctx, int allow) { + SANITIZE_CTX(ctx); + assert(factory_ctx); + try { + factory_ctx->operationContext->setAllowBallparkTransformations(allow != + 0); + } catch (const std::exception &e) { + proj_log_error(ctx, __FUNCTION__, e.what()); + } +} + +// --------------------------------------------------------------------------- + //! @cond Doxygen_Suppress /** \brief Opaque object representing a set of operation results. */ struct PJ_OPERATION_LIST : PJ_OBJ_LIST { diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp index 822d09ac..8c47050d 100644 --- a/src/iso19111/coordinateoperation.cpp +++ b/src/iso19111/coordinateoperation.cpp @@ -10464,6 +10464,7 @@ struct CoordinateOperationContext::Private { std::vector<std::pair<std::string, std::string>> intermediateCRSAuthCodes_{}; bool discardSuperseded_ = true; + bool allowBallpark_ = true; }; //! @endcond @@ -10518,6 +10519,20 @@ void CoordinateOperationContext::setDesiredAccuracy(double accuracy) { // --------------------------------------------------------------------------- +/** \brief Return whether ballpark transformations are allowed */ +bool CoordinateOperationContext::getAllowBallparkTransformations() const { + return d->allowBallpark_; +} + +// --------------------------------------------------------------------------- + +/** \brief Set whether ballpark transformations are allowed */ +void CoordinateOperationContext::setAllowBallparkTransformations(bool allow) { + d->allowBallpark_ = allow; +} + +// --------------------------------------------------------------------------- + /** \brief Set how source and target CRS extent should be used * when considering if a transformation can be used (only takes effect if * no area of interest is explicitly defined). @@ -11187,7 +11202,7 @@ struct FilterResults { const CoordinateOperationContext::SourceTargetCRSExtentUse sourceAndTargetCRSExtentUse; - bool hasOpThatContainsAreaOfInterest = false; + bool hasOpThatContainsAreaOfInterestAndNoGrid = false; std::vector<CoordinateOperationNNPtr> res{}; // ---------------------------------------------------------------------- @@ -11233,6 +11248,7 @@ struct FilterResults { STRICT_CONTAINMENT : context->getSpatialCriterion(); bool hasFoundOpWithExtent = false; + const bool allowBallpark = context->getAllowBallparkTransformations(); for (const auto &op : sourceList) { if (desiredAccuracy != 0) { const double accuracy = getAccuracy(op); @@ -11240,6 +11256,9 @@ struct FilterResults { continue; } } + if (!allowBallpark && op->hasBallparkTransformation()) { + continue; + } if (areaOfInterest) { bool emptyIntersection = false; auto extent = getExtent(op, true, emptyIntersection); @@ -11248,9 +11267,11 @@ struct FilterResults { hasFoundOpWithExtent = true; bool extentContains = extent->contains(NN_NO_CHECK(areaOfInterest)); - if (extentContains) { - if (!op->hasBallparkTransformation()) { - hasOpThatContainsAreaOfInterest = true; + if (!hasOpThatContainsAreaOfInterestAndNoGrid && + extentContains) { + if (!op->hasBallparkTransformation() && + op->gridsNeeded(nullptr, true).empty()) { + hasOpThatContainsAreaOfInterestAndNoGrid = true; } } if (spatialCriterion == @@ -11277,9 +11298,11 @@ struct FilterResults { !extent1 || extent->contains(NN_NO_CHECK(extent1)); bool extentContainsExtent2 = !extent2 || extent->contains(NN_NO_CHECK(extent2)); - if (extentContainsExtent1 && extentContainsExtent2) { - if (!op->hasBallparkTransformation()) { - hasOpThatContainsAreaOfInterest = true; + if (!hasOpThatContainsAreaOfInterestAndNoGrid && + extentContainsExtent1 && extentContainsExtent2) { + if (!op->hasBallparkTransformation() && + op->gridsNeeded(nullptr, true).empty()) { + hasOpThatContainsAreaOfInterestAndNoGrid = true; } } if (spatialCriterion == @@ -11313,6 +11336,9 @@ struct FilterResults { continue; } } + if (!allowBallpark && op->hasBallparkTransformation()) { + continue; + } res.emplace_back(op); } } @@ -11446,12 +11472,13 @@ struct FilterResults { // If we have more than one result, and than the last result is the // default "Ballpark geographic offset" or "Ballpark geocentric - // translation" - // operations we have synthetized, and that at least one operation - // has the desired area of interest, remove it as - // all previous results are necessarily better - if (hasOpThatContainsAreaOfInterest && res.size() > 1) { - const std::string &name = res.back()->nameStr(); + // translation" operations we have synthetized, and that at least one + // operation has the desired area of interest and does not require the + // use of grids, remove it as all previous results are necessarily + // better + if (hasOpThatContainsAreaOfInterestAndNoGrid && res.size() > 1) { + const auto &opLast = res.back(); + const std::string &name = opLast->nameStr(); if (name.find(BALLPARK_GEOGRAPHIC_OFFSET) != std::string::npos || name.find(NULL_GEOGRAPHIC_OFFSET) != std::string::npos || name.find(NULL_GEOCENTRIC_TRANSLATION) != std::string::npos || @@ -14772,7 +14799,7 @@ void CoordinateOperationFactory::Private::createOperationsCompoundToCompound( } } - // If we didn't find a non-ballbark transformation between + // If we didn't find a non-ballpark transformation between // the 2 vertical CRS, then try through intermediate geographic CRS // For example // WGS 84 + EGM96 --> ETRS89 + Belfast height where diff --git a/src/iso19111/factory.cpp b/src/iso19111/factory.cpp index 32ed6abb..aa3cd6cf 100644 --- a/src/iso19111/factory.cpp +++ b/src/iso19111/factory.cpp @@ -926,7 +926,8 @@ bool DatabaseContext::lookForGridAlternative(const std::string &officialName, bool &inverse) const { auto res = d->run( "SELECT proj_grid_name, proj_grid_format, inverse_direction FROM " - "grid_alternatives WHERE original_grid_name = ?", + "grid_alternatives WHERE original_grid_name = ? AND " + "proj_grid_name <> ''", {officialName}); if (res.empty()) { return false; @@ -1202,6 +1202,11 @@ void PROJ_DLL proj_operation_factory_context_set_discard_superseded( PJ_OPERATION_FACTORY_CONTEXT *factory_ctx, int discard); +void PROJ_DLL proj_operation_factory_context_set_allow_ballpark_transformations( + PJ_CONTEXT *ctx, + PJ_OPERATION_FACTORY_CONTEXT *factory_ctx, + int allow); + /* ------------------------------------------------------------------------- */ |
