aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/source/development/reference/functions.rst12
-rw-r--r--scripts/reference_exported_symbols.txt1
-rw-r--r--src/4D_api.cpp46
-rw-r--r--src/proj.h5
-rw-r--r--test/unit/test_c_api.cpp26
5 files changed, 69 insertions, 21 deletions
diff --git a/docs/source/development/reference/functions.rst b/docs/source/development/reference/functions.rst
index 64a4e8ca..e5f48439 100644
--- a/docs/source/development/reference/functions.rst
+++ b/docs/source/development/reference/functions.rst
@@ -153,6 +153,18 @@ paragraph for more details.
:type `area`: PJ_AREA
:returns: :c:type:`PJ*`
+.. c:function:: PJ* proj_create_crs_to_crs_from_pj(PJ_CONTEXT *ctx, PJ *source_crs, PJ *target_crs, PJ_AREA *area, const char* const *options)
+
+ .. versionadded:: 6.2.0
+
+ Create a transformation object that is a pipeline between two known
+ coordinate reference systems.
+
+ This is the same as :c:func:`proj_create_crs_to_crs` except that the source and
+ target CRS are passed as PJ* objects which must of the CRS variety.
+
+ :param `options`: should be set to NULL currently.
+
.. c:function:: PJ *proj_normalize_for_visualization(PJ_CONTEXT *ctx, const PJ* obj)
.. versionadded:: 6.1.0
diff --git a/scripts/reference_exported_symbols.txt b/scripts/reference_exported_symbols.txt
index fa6b16a4..6df84099 100644
--- a/scripts/reference_exported_symbols.txt
+++ b/scripts/reference_exported_symbols.txt
@@ -874,6 +874,7 @@ proj_create_conversion_wagner_v
proj_create_conversion_wagner_vi
proj_create_conversion_wagner_vii
proj_create_crs_to_crs
+proj_create_crs_to_crs_from_pj
proj_create_cs
proj_create_ellipsoidal_2D_cs
proj_create_engineering_crs
diff --git a/src/4D_api.cpp b/src/4D_api.cpp
index 07ccfd91..3a9582e6 100644
--- a/src/4D_api.cpp
+++ b/src/4D_api.cpp
@@ -1045,10 +1045,27 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *source_crs, const char
return nullptr;
}
+ auto ret = proj_create_crs_to_crs_from_pj(ctx, src, dst, area, nullptr);
+ proj_destroy(src);
+ proj_destroy(dst);
+ return ret;
+}
+
+/*****************************************************************************/
+PJ *proj_create_crs_to_crs_from_pj (PJ_CONTEXT *ctx, PJ *source_crs, PJ *target_crs, PJ_AREA *area, const char* const *) {
+/******************************************************************************
+ Create a transformation pipeline between two known coordinate reference
+ systems.
+
+ See docs/source/development/reference/functions.rst
+
+******************************************************************************/
+ if( !ctx ) {
+ ctx = pj_get_default_ctx();
+ }
+
auto operation_ctx = proj_create_operation_factory_context(ctx, nullptr);
if( !operation_ctx ) {
- proj_destroy(src);
- proj_destroy(dst);
return nullptr;
}
@@ -1067,12 +1084,10 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *source_crs, const char
proj_operation_factory_context_set_grid_availability_use(
ctx, operation_ctx, PROJ_GRID_AVAILABILITY_DISCARD_OPERATION_IF_MISSING_GRID);
- auto op_list = proj_create_operations(ctx, src, dst, operation_ctx);
+ auto op_list = proj_create_operations(ctx, source_crs, target_crs, operation_ctx);
if( !op_list ) {
proj_operation_factory_context_destroy(operation_ctx);
- proj_destroy(src);
- proj_destroy(dst);
return nullptr;
}
@@ -1080,8 +1095,7 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *source_crs, const char
if( op_count == 0 ) {
proj_list_destroy(op_list);
proj_operation_factory_context_destroy(operation_ctx);
- proj_destroy(src);
- proj_destroy(dst);
+
proj_context_log_debug(ctx, "No operation found matching criteria");
return nullptr;
}
@@ -1090,35 +1104,29 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *source_crs, const char
assert(P);
if( P == nullptr || op_count == 1 || (area && area->bbox_set) ||
- proj_get_type(src) == PJ_TYPE_GEOCENTRIC_CRS ||
- proj_get_type(dst) == PJ_TYPE_GEOCENTRIC_CRS ) {
+ proj_get_type(source_crs) == PJ_TYPE_GEOCENTRIC_CRS ||
+ proj_get_type(target_crs) == PJ_TYPE_GEOCENTRIC_CRS ) {
proj_list_destroy(op_list);
proj_operation_factory_context_destroy(operation_ctx);
- proj_destroy(src);
- proj_destroy(dst);
return P;
}
- auto pjGeogToSrc = create_operation_to_base_geog_crs(ctx, src);
+ auto pjGeogToSrc = create_operation_to_base_geog_crs(ctx, source_crs);
if( !pjGeogToSrc )
{
proj_list_destroy(op_list);
proj_operation_factory_context_destroy(operation_ctx);
- proj_destroy(src);
- proj_destroy(dst);
proj_context_log_debug(ctx,
"Cannot create transformation from geographic CRS of source CRS to source CRS");
proj_destroy(P);
return nullptr;
}
- auto pjGeogToDst = create_operation_to_base_geog_crs(ctx, dst);
+ auto pjGeogToDst = create_operation_to_base_geog_crs(ctx, target_crs);
if( !pjGeogToDst )
{
proj_list_destroy(op_list);
proj_operation_factory_context_destroy(operation_ctx);
- proj_destroy(src);
- proj_destroy(dst);
proj_context_log_debug(ctx,
"Cannot create transformation from geographic CRS of target CRS to target CRS");
proj_destroy(P);
@@ -1177,8 +1185,6 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *source_crs, const char
proj_list_destroy(op_list);
proj_operation_factory_context_destroy(operation_ctx);
- proj_destroy(src);
- proj_destroy(dst);
proj_destroy(pjGeogToSrc);
proj_destroy(pjGeogToDst);
@@ -1205,8 +1211,6 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *source_crs, const char
{
proj_list_destroy(op_list);
proj_operation_factory_context_destroy(operation_ctx);
- proj_destroy(src);
- proj_destroy(dst);
proj_destroy(pjGeogToSrc);
proj_destroy(pjGeogToDst);
proj_destroy(P);
diff --git a/src/proj.h b/src/proj.h
index 4a3e4c59..9cf83df7 100644
--- a/src/proj.h
+++ b/src/proj.h
@@ -357,6 +357,11 @@ int PROJ_DLL proj_context_get_use_proj4_init_rules(PJ_CONTEXT *ctx, int from_leg
PJ PROJ_DLL *proj_create (PJ_CONTEXT *ctx, const char *definition);
PJ PROJ_DLL *proj_create_argv (PJ_CONTEXT *ctx, int argc, char **argv);
PJ PROJ_DLL *proj_create_crs_to_crs(PJ_CONTEXT *ctx, const char *source_crs, const char *target_crs, PJ_AREA *area);
+PJ PROJ_DLL *proj_create_crs_to_crs_from_pj(PJ_CONTEXT *ctx,
+ PJ *source_crs,
+ PJ *target_crs,
+ PJ_AREA *area,
+ const char* const *options);
PJ PROJ_DLL *proj_normalize_for_visualization(PJ_CONTEXT *ctx, const PJ* obj);
PJ PROJ_DLL *proj_destroy (PJ *P);
diff --git a/test/unit/test_c_api.cpp b/test/unit/test_c_api.cpp
index 74377738..2a1c8577 100644
--- a/test/unit/test_c_api.cpp
+++ b/test/unit/test_c_api.cpp
@@ -3711,4 +3711,30 @@ TEST_F(Fixture_proj_context_set_autoclose_database,
proj_context_set_autoclose_database_false) {
test(false);
}
+
+// ---------------------------------------------------------------------------
+
+TEST_F(CApi, proj_create_crs_to_crs_from_pj) {
+
+ auto src = proj_create(m_ctxt, "EPSG:4326");
+ ObjectKeeper keeper_src(src);
+ ASSERT_NE(src, nullptr);
+
+ auto dst = proj_create(m_ctxt, "EPSG:32631");
+ ObjectKeeper keeper_dst(dst);
+ ASSERT_NE(dst, nullptr);
+
+ auto P = proj_create_crs_to_crs_from_pj(m_ctxt, src, dst, nullptr, nullptr);
+ ObjectKeeper keeper_P(P);
+ ASSERT_NE(P, nullptr);
+ auto Pnormalized = proj_normalize_for_visualization(m_ctxt, P);
+ ObjectKeeper keeper_Pnormalized(Pnormalized);
+ ASSERT_NE(Pnormalized, nullptr);
+ auto projstr = proj_as_proj_string(m_ctxt, Pnormalized, PJ_PROJ_5, nullptr);
+ ASSERT_NE(projstr, nullptr);
+ EXPECT_EQ(std::string(projstr),
+ "+proj=pipeline +step +proj=unitconvert +xy_in=deg +xy_out=rad "
+ "+step +proj=utm +zone=31 +ellps=WGS84");
+}
+
} // namespace