aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2020-04-16 00:44:49 +0200
committerGitHub <noreply@github.com>2020-04-16 00:44:49 +0200
commitaf85cdb2b72d720a102cb8f823daa815a595ba2d (patch)
treee4d412b6be0995e94c7d04db4909adfdf6fcf496 /src
parent70aebec863f63fdec7f86961dfa9b7924b9ab2dc (diff)
parent953ff68cbd444046f2aa2f8b305c1d7cb258cc8a (diff)
downloadPROJ-af85cdb2b72d720a102cb8f823daa815a595ba2d.tar.gz
PROJ-af85cdb2b72d720a102cb8f823daa815a595ba2d.zip
Merge pull request #2156 from rouault/backport_7_0_pr2143
[Backport 7.0] 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/iso19111/coordinateoperation.cpp55
-rw-r--r--src/iso19111/factory.cpp3
2 files changed, 43 insertions, 15 deletions
diff --git a/src/iso19111/coordinateoperation.cpp b/src/iso19111/coordinateoperation.cpp
index 24e82f7c..d038b5f9 100644
--- a/src/iso19111/coordinateoperation.cpp
+++ b/src/iso19111/coordinateoperation.cpp
@@ -10462,6 +10462,7 @@ struct CoordinateOperationContext::Private {
std::vector<std::pair<std::string, std::string>>
intermediateCRSAuthCodes_{};
bool discardSuperseded_ = true;
+ bool allowBallpark_ = true;
};
//! @endcond
@@ -10516,6 +10517,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).
@@ -11185,7 +11200,7 @@ struct FilterResults {
const CoordinateOperationContext::SourceTargetCRSExtentUse
sourceAndTargetCRSExtentUse;
- bool hasOpThatContainsAreaOfInterest = false;
+ bool hasOpThatContainsAreaOfInterestAndNoGrid = false;
std::vector<CoordinateOperationNNPtr> res{};
// ----------------------------------------------------------------------
@@ -11231,6 +11246,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);
@@ -11238,6 +11254,9 @@ struct FilterResults {
continue;
}
}
+ if (!allowBallpark && op->hasBallparkTransformation()) {
+ continue;
+ }
if (areaOfInterest) {
bool emptyIntersection = false;
auto extent = getExtent(op, true, emptyIntersection);
@@ -11246,9 +11265,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 ==
@@ -11275,9 +11296,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 ==
@@ -11311,6 +11334,9 @@ struct FilterResults {
continue;
}
}
+ if (!allowBallpark && op->hasBallparkTransformation()) {
+ continue;
+ }
res.emplace_back(op);
}
}
@@ -11444,12 +11470,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 ||
@@ -14770,7 +14797,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 b60ce9f9..f6650055 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;