diff options
| -rw-r--r-- | docs/source/development/reference/functions.rst | 5 | ||||
| -rw-r--r-- | src/4D_api.cpp | 22 | ||||
| -rw-r--r-- | test/unit/test_c_api.cpp | 58 |
3 files changed, 85 insertions, 0 deletions
diff --git a/docs/source/development/reference/functions.rst b/docs/source/development/reference/functions.rst index 08b3e669..34fe59ed 100644 --- a/docs/source/development/reference/functions.rst +++ b/docs/source/development/reference/functions.rst @@ -195,6 +195,11 @@ paragraph for more details. If authority is a non-empty string different of ``any``, then coordinate operations will be searched only in that authority namespace (e.g ``EPSG``). + - ACCURACY=value: to set the minimum desired accuracy (in metres) of the + candidate coordinate operations. + + - ALLOW_BALLPARK=YES/NO: can be set to NO to disallow the use of + :term:`Ballpark transformation` in the candidate coordinate operations. .. doxygenfunction:: proj_normalize_for_visualization :project: doxygen_api diff --git a/src/4D_api.cpp b/src/4D_api.cpp index 7423240f..909c3c32 100644 --- a/src/4D_api.cpp +++ b/src/4D_api.cpp @@ -1302,10 +1302,24 @@ PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, cons } const char* authority = nullptr; + double accuracy = -1; + bool allowBallparkTransformations = true; for (auto iter = options; iter && iter[0]; ++iter) { const char *value; if ((value = getOptionValue(*iter, "AUTHORITY="))) { authority = value; + } else if ((value = getOptionValue(*iter, "ACCURACY="))) { + accuracy = pj_atof(value); + } else if ((value = getOptionValue(*iter, "ALLOW_BALLPARK="))) { + if( ci_equal(value, "yes") ) + allowBallparkTransformations = true; + else if( ci_equal(value, "no") ) + allowBallparkTransformations = false; + else { + ctx->logger(ctx->logger_app_data, PJ_LOG_ERROR, + "Invalid value for ALLOW_BALLPARK option."); + return nullptr; + } } else { std::string msg("Unknown option :"); msg += *iter; @@ -1319,6 +1333,14 @@ PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, const PJ *source_crs, cons return nullptr; } + proj_operation_factory_context_set_allow_ballpark_transformations( + ctx, operation_ctx, allowBallparkTransformations); + + if( accuracy >= 0 ) { + proj_operation_factory_context_set_desired_accuracy(ctx, operation_ctx, + accuracy); + } + if( area && area->bbox_set ) { proj_operation_factory_context_set_area_of_interest( ctx, diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp index c417371d..e54c6fa7 100644 --- a/test/unit/test_c_api.cpp +++ b/test/unit/test_c_api.cpp @@ -4196,6 +4196,64 @@ TEST_F(CApi, proj_create_crs_to_crs_from_pj) { // --------------------------------------------------------------------------- +TEST_F(CApi, proj_create_crs_to_crs_from_pj_accuracy_filter) { + + auto src = proj_create(m_ctxt, "EPSG:4326"); // WGS 84 + ObjectKeeper keeper_src(src); + ASSERT_NE(src, nullptr); + + auto dst = proj_create(m_ctxt, "EPSG:4258"); // ETRS89 + ObjectKeeper keeper_dst(dst); + ASSERT_NE(dst, nullptr); + + // No options + { + auto P = + proj_create_crs_to_crs_from_pj(m_ctxt, src, dst, nullptr, nullptr); + ObjectKeeper keeper_P(P); + ASSERT_NE(P, nullptr); + } + + { + const char *const options[] = {"ACCURACY=0.05", nullptr}; + auto P = + proj_create_crs_to_crs_from_pj(m_ctxt, src, dst, nullptr, options); + ObjectKeeper keeper_P(P); + ASSERT_EQ(P, nullptr); + } +} + +// --------------------------------------------------------------------------- + +TEST_F(CApi, proj_create_crs_to_crs_from_pj_ballpark_filter) { + + auto src = proj_create(m_ctxt, "EPSG:4267"); // NAD 27 + ObjectKeeper keeper_src(src); + ASSERT_NE(src, nullptr); + + auto dst = proj_create(m_ctxt, "EPSG:4258"); // ETRS89 + ObjectKeeper keeper_dst(dst); + ASSERT_NE(dst, nullptr); + + // No options + { + auto P = + proj_create_crs_to_crs_from_pj(m_ctxt, src, dst, nullptr, nullptr); + ObjectKeeper keeper_P(P); + ASSERT_NE(P, nullptr); + } + + { + const char *const options[] = {"ALLOW_BALLPARK=NO", nullptr}; + auto P = + proj_create_crs_to_crs_from_pj(m_ctxt, src, dst, nullptr, options); + ObjectKeeper keeper_P(P); + ASSERT_EQ(P, nullptr); + } +} + +// --------------------------------------------------------------------------- + static void check_axis_is_latitude(PJ_CONTEXT *ctx, PJ *cs, int axis_number, const char *unit_name = "degree", |
