aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/source/development/reference/functions.rst5
-rw-r--r--src/4D_api.cpp22
-rw-r--r--test/unit/test_c_api.cpp58
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",