diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2019-08-22 22:52:48 +0200 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2019-08-23 21:49:40 +0200 |
| commit | 11869e2c4d29f0e607a0f78fb289d253fccd9a16 (patch) | |
| tree | 5b8be1637f9272b8b3ddb4a6280b6207389fbf4f | |
| parent | b7f829ce8f7c9fce2934b3981493a5d3338143b9 (diff) | |
| download | PROJ-11869e2c4d29f0e607a0f78fb289d253fccd9a16.tar.gz PROJ-11869e2c4d29f0e607a0f78fb289d253fccd9a16.zip | |
Add proj_create_crs_to_crs_from_pj()
I've been frustrated a number of times with proj_create_crs_to_crs()
not accepting a PJ* object for the source and target CRS.
And thus constraining to go back to WKT2 in a artificial way.
| -rw-r--r-- | docs/source/development/reference/functions.rst | 12 | ||||
| -rw-r--r-- | scripts/reference_exported_symbols.txt | 1 | ||||
| -rw-r--r-- | src/4D_api.cpp | 46 | ||||
| -rw-r--r-- | src/proj.h | 5 | ||||
| -rw-r--r-- | test/unit/test_c_api.cpp | 26 |
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); @@ -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 |
