diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2021-07-08 13:22:01 +0200 |
|---|---|---|
| committer | github-actions[bot] <github-actions[bot]@users.noreply.github.com> | 2021-07-08 11:24:30 +0000 |
| commit | 18fc6a629e19bfe038fbd21bd3d4748f52203fab (patch) | |
| tree | 837159111c4df2aca578c609904c5ad429933734 | |
| parent | 345900742cdfc30753b260fad8a240420c217491 (diff) | |
| download | PROJ-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.cpp | 42 | ||||
| -rw-r--r-- | test/unit/test_c_api.cpp | 15 |
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); } // --------------------------------------------------------------------------- |
