Skip to content

Commit

Permalink
Add proj_create_crs_to_crs_from_pj() (#1567)
Browse files Browse the repository at this point in the history
Add proj_create_crs_to_crs_from_pj()
  • Loading branch information
kbevers committed Aug 23, 2019
2 parents b7f829c + 11869e2 commit a0b45b5
Show file tree
Hide file tree
Showing 5 changed files with 69 additions and 21 deletions.
12 changes: 12 additions & 0 deletions docs/source/development/reference/functions.rst
Expand Up @@ -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
Expand Down
1 change: 1 addition & 0 deletions scripts/reference_exported_symbols.txt
Expand Up @@ -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
Expand Down
46 changes: 25 additions & 21 deletions src/4D_api.cpp
Expand Up @@ -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;
}

Expand All @@ -1067,21 +1084,18 @@ 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;
}

auto op_count = proj_list_get_count(op_list);
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;
}
Expand All @@ -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);
Expand Down Expand Up @@ -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);

Expand All @@ -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);
Expand Down
5 changes: 5 additions & 0 deletions src/proj.h
Expand Up @@ -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);

Expand Down
26 changes: 26 additions & 0 deletions test/unit/test_c_api.cpp
Expand Up @@ -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

0 comments on commit a0b45b5

Please sign in to comment.