aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2021-07-08 13:22:01 +0200
committergithub-actions[bot] <github-actions[bot]@users.noreply.github.com>2021-07-08 11:24:30 +0000
commit18fc6a629e19bfe038fbd21bd3d4748f52203fab (patch)
tree837159111c4df2aca578c609904c5ad429933734
parent345900742cdfc30753b260fad8a240420c217491 (diff)
downloadPROJ-18fc6a629e19bfe038fbd21bd3d4748f52203fab.tar.gz
PROJ-18fc6a629e19bfe038fbd21bd3d4748f52203fab.zip
Merge pull request #2769 from rouault/fix_2768
createOperations(): make sure to associate an extent to the transform…
-rw-r--r--src/iso19111/operation/coordinateoperationfactory.cpp42
-rw-r--r--test/unit/test_c_api.cpp15
2 files changed, 51 insertions, 6 deletions
diff --git a/src/iso19111/operation/coordinateoperationfactory.cpp b/src/iso19111/operation/coordinateoperationfactory.cpp
index 183926bf..e04cdb8d 100644
--- a/src/iso19111/operation/coordinateoperationfactory.cpp
+++ b/src/iso19111/operation/coordinateoperationfactory.cpp
@@ -3476,7 +3476,7 @@ CoordinateOperationFactory::Private::createOperationsGeogToVertFromGeoid(
vertDst->datum(), vertDst->datumEnsemble(),
cs::VerticalCS::createGravityRelatedHeight(
common::UnitOfMeasure::METRE)));
- const auto properties = util::PropertyMap().set(
+ auto properties = util::PropertyMap().set(
common::IdentifiedObject::NAME_KEY,
buildOpName("Transformation", vertCRSMetre, geogSrcCRS));
@@ -3485,14 +3485,21 @@ CoordinateOperationFactory::Private::createOperationsGeogToVertFromGeoid(
std::vector<metadata::PositionalAccuracyNNPtr> accuracies;
const auto &modelAccuracies =
model->coordinateOperationAccuracies();
+ std::vector<CoordinateOperationNNPtr> transformationsForGrid;
+ double accuracy = -1;
+ size_t idx = static_cast<size_t>(-1);
if (modelAccuracies.empty()) {
if (authFactory) {
- const auto transformationsForGrid =
+ transformationsForGrid =
io::DatabaseContext::getTransformationsForGridName(
authFactory->databaseContext(), projFilename);
- double accuracy = -1;
- for (const auto &transf : transformationsForGrid) {
- accuracy = std::max(accuracy, getAccuracy(transf));
+ for (size_t i = 0; i < transformationsForGrid.size(); ++i) {
+ const auto &transf = transformationsForGrid[i];
+ const double transfAcc = getAccuracy(transf);
+ if (transfAcc - accuracy > 1e-10) {
+ accuracy = transfAcc;
+ idx = i;
+ }
}
if (accuracy >= 0) {
accuracies.emplace_back(
@@ -3502,6 +3509,31 @@ CoordinateOperationFactory::Private::createOperationsGeogToVertFromGeoid(
}
}
+ // Set extent
+ bool dummy = false;
+ // Use in priority the one of the geoid model transformation
+ auto extent = getExtent(model, true, dummy);
+ // Otherwise fallback to the extent of a transformation using
+ // the grid.
+ if (extent == nullptr && authFactory != nullptr) {
+ if (transformationsForGrid.empty()) {
+ transformationsForGrid =
+ io::DatabaseContext::getTransformationsForGridName(
+ authFactory->databaseContext(), projFilename);
+ }
+ if (idx != static_cast<size_t>(-1)) {
+ const auto &transf = transformationsForGrid[idx];
+ extent = getExtent(transf, true, dummy);
+ } else if (!transformationsForGrid.empty()) {
+ const auto &transf = transformationsForGrid.front();
+ extent = getExtent(transf, true, dummy);
+ }
+ }
+ if (extent) {
+ properties.set(common::ObjectUsage::DOMAIN_OF_VALIDITY_KEY,
+ NN_NO_CHECK(extent));
+ }
+
return Transformation::createGravityRelatedHeightToGeographic3D(
properties, vertCRSMetre, geogSrcCRS, nullptr, projFilename,
!modelAccuracies.empty() ? modelAccuracies : accuracies);
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp
index 90641bd1..34f32c19 100644
--- a/test/unit/test_c_api.cpp
+++ b/test/unit/test_c_api.cpp
@@ -5082,7 +5082,20 @@ TEST_F(CApi, proj_create_vertical_crs_ex_implied_accuracy) {
ObjectKeeper keeper_transform(transform);
// This is the accuracy of operations EPSG:5656 / 5657
- ASSERT_EQ(proj_coordoperation_get_accuracy(m_ctxt, transform), 0.15);
+ const double acc = proj_coordoperation_get_accuracy(m_ctxt, transform);
+ EXPECT_NEAR(acc, 0.15, 1e-10);
+
+ // Check there's an asssociated area of use
+ double west_lon_degree = 0;
+ double south_lat_degree = 0;
+ double east_lon_degree = 0;
+ double north_lat_degree = 0;
+ ASSERT_EQ(proj_get_area_of_use(m_ctxt, transform, &west_lon_degree,
+ &south_lat_degree, &east_lon_degree,
+ &north_lat_degree, nullptr),
+ true);
+ EXPECT_LE(north_lat_degree, -10);
+ EXPECT_GE(west_lon_degree, 110);
}
// ---------------------------------------------------------------------------