aboutsummaryrefslogtreecommitdiff
path: root/src/4D_api.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/4D_api.cpp')
-rw-r--r--src/4D_api.cpp197
1 files changed, 124 insertions, 73 deletions
diff --git a/src/4D_api.cpp b/src/4D_api.cpp
index 013a4628..37afd289 100644
--- a/src/4D_api.cpp
+++ b/src/4D_api.cpp
@@ -27,6 +27,8 @@
* DEALINGS IN THE SOFTWARE.
*****************************************************************************/
+#define FROM_PROJ_CPP
+
#include <errno.h>
#include <stddef.h>
#include <stdio.h>
@@ -44,7 +46,9 @@
#include "proj/common.hpp"
#include "proj/coordinateoperation.hpp"
+#include "proj/internal/internal.hpp"
+using namespace NS_PROJ::internal;
/* Initialize PJ_COORD struct */
PJ_COORD proj_coord (double x, double y, double z, double t) {
@@ -458,7 +462,7 @@ Returns 1 on success, 0 on failure
if (nullptr==def)
return 0;
sprintf (def, "break_cs2cs_recursion proj=axisswap axis=%s", P->axis);
- Q = proj_create (P->ctx, def);
+ Q = pj_create_internal (P->ctx, def);
free (def);
if (nullptr==Q)
return 0;
@@ -473,7 +477,7 @@ Returns 1 on success, 0 on failure
if (nullptr==def)
return 0;
sprintf (def, "break_cs2cs_recursion proj=vgridshift grids=%s", gridnames);
- Q = proj_create (P->ctx, def);
+ Q = pj_create_internal (P->ctx, def);
free (def);
if (nullptr==Q)
return 0;
@@ -488,7 +492,7 @@ Returns 1 on success, 0 on failure
if (nullptr==def)
return 0;
sprintf (def, "break_cs2cs_recursion proj=hgridshift grids=%s", gridnames);
- Q = proj_create (P->ctx, def);
+ Q = pj_create_internal (P->ctx, def);
free (def);
if (nullptr==Q)
return 0;
@@ -520,7 +524,7 @@ Returns 1 on success, 0 on failure
if (nullptr==def)
return 0;
sprintf (def, "break_cs2cs_recursion proj=helmert exact %s convention=position_vector", s);
- Q = proj_create (P->ctx, def);
+ Q = pj_create_internal (P->ctx, def);
free(def);
if (nullptr==Q)
return 0;
@@ -546,14 +550,14 @@ Returns 1 on success, 0 on failure
*next_pos = '.';
}
}
- Q = proj_create (P->ctx, def);
+ Q = pj_create_internal (P->ctx, def);
if (nullptr==Q)
return 0;
P->cart = skip_prep_fin (Q);
if (!P->is_geocent) {
sprintf (def, "break_cs2cs_recursion proj=cart ellps=WGS84");
- Q = proj_create (P->ctx, def);
+ Q = pj_create_internal (P->ctx, def);
if (nullptr==Q)
return 0;
P->cart_wgs84 = skip_prep_fin (Q);
@@ -564,9 +568,10 @@ Returns 1 on success, 0 on failure
}
-
/*************************************************************************************/
-PJ *proj_create (PJ_CONTEXT *ctx, const char *definition) {
+PJ *pj_create_internal (PJ_CONTEXT *ctx, const char *definition) {
+/*************************************************************************************/
+
/**************************************************************************************
Create a new PJ object in the context ctx, using the given definition. If ctx==0,
the default context is used, if definition==0, or invalid, a null-pointer is
@@ -624,8 +629,6 @@ PJ *proj_create (PJ_CONTEXT *ctx, const char *definition) {
return P;
}
-
-
/*************************************************************************************/
PJ *proj_create_argv (PJ_CONTEXT *ctx, int argc, char **argv) {
/**************************************************************************************
@@ -658,6 +661,34 @@ indicator, as in {"+proj=utm", "+zone=32"}, or leave it out, as in {"proj=utm",
return P;
}
+/*************************************************************************************/
+PJ *pj_create_argv_internal (PJ_CONTEXT *ctx, int argc, char **argv) {
+/**************************************************************************************
+Same as proj_create_argv() but calls pj_create_internal() instead of proj_create() internally
+**************************************************************************************/
+ PJ *P;
+ const char *c;
+
+ if (nullptr==ctx)
+ ctx = pj_get_default_ctx ();
+ if (nullptr==argv) {
+ proj_context_errno_set(ctx, PJD_ERR_NO_ARGS);
+ return nullptr;
+ }
+
+ /* We assume that free format is used, and build a full proj_create compatible string */
+ c = pj_make_args (argc, argv);
+ if (nullptr==c) {
+ proj_context_errno_set(ctx, ENOMEM);
+ return nullptr;
+ }
+
+ P = pj_create_internal (ctx, c);
+
+ pj_dealloc ((char *) c);
+ return P;
+}
+
/** Create an area of use */
PJ_AREA * proj_area_create(void) {
return static_cast<PJ_AREA*>(pj_calloc(1, sizeof(PJ_AREA)));
@@ -731,6 +762,20 @@ int proj_context_get_use_proj4_init_rules(PJ_CONTEXT *ctx, int from_legacy_code_
return from_legacy_code_path;
}
+/** Adds a " +type=crs" suffix to a PROJ string (if it is a PROJ string) */
+std::string pj_add_type_crs_if_needed(const std::string& str)
+{
+ std::string ret(str);
+ if( (starts_with(str, "proj=") ||
+ starts_with(str, "+proj=") ||
+ starts_with(str, "+init=") ||
+ starts_with(str, "+title=")) &&
+ str.find("type=crs") == std::string::npos )
+ {
+ ret += " +type=crs";
+ }
+ return ret;
+}
/*****************************************************************************/
PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *source_crs, const char *target_crs, PJ_AREA *area) {
@@ -748,7 +793,7 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *source_crs, const char
- a PROJ string, like "+proj=longlat +datum=WGS84".
When using that syntax, the axis order and unit for geographic CRS will
be longitude, latitude, and the unit degrees.
- - more generally any string accepted by proj_create_from_user_input()
+ - more generally any string accepted by proj_create()
An "area of use" can be specified in area. When it is supplied, the more
accurate transformation between two given systems can be chosen.
@@ -759,88 +804,94 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *source_crs, const char
******************************************************************************/
const char* proj_string;
- const char* const optionsProj4Mode[] = { "USE_PROJ4_INIT_RULES=YES", nullptr };
if( !ctx ) {
ctx = pj_get_default_ctx();
}
- const char* const* optionsImportCRS =
- proj_context_get_use_proj4_init_rules(ctx, FALSE) ? optionsProj4Mode : nullptr;
+ try
+ {
+ std::string source_crs_modified(pj_add_type_crs_if_needed(source_crs));
+ std::string target_crs_modified(pj_add_type_crs_if_needed(target_crs));
- auto src = proj_create_from_user_input(ctx, source_crs, optionsImportCRS);
- if( !src ) {
- proj_context_log_debug(ctx, "Cannot instantiate source_crs");
- return nullptr;
- }
+ auto src = proj_create(ctx, source_crs_modified.c_str());
+ if( !src ) {
+ proj_context_log_debug(ctx, "Cannot instantiate source_crs");
+ return nullptr;
+ }
- auto dst = proj_create_from_user_input(ctx, target_crs, optionsImportCRS);
- if( !dst ) {
- proj_context_log_debug(ctx, "Cannot instantiate target_crs");
- proj_destroy(src);
- return nullptr;
- }
+ auto dst = proj_create(ctx, target_crs_modified.c_str());
+ if( !dst ) {
+ proj_context_log_debug(ctx, "Cannot instantiate target_crs");
+ proj_destroy(src);
+ return nullptr;
+ }
- auto operation_ctx = proj_create_operation_factory_context(ctx, nullptr);
- if( !operation_ctx ) {
- proj_destroy(src);
- proj_destroy(dst);
- return nullptr;
- }
+ auto operation_ctx = proj_create_operation_factory_context(ctx, nullptr);
+ if( !operation_ctx ) {
+ proj_destroy(src);
+ proj_destroy(dst);
+ return nullptr;
+ }
- if( area && area->bbox_set ) {
- proj_operation_factory_context_set_area_of_interest(
- ctx,
- operation_ctx,
- area->west_lon_degree,
- area->south_lat_degree,
- area->east_lon_degree,
- area->north_lat_degree);
- }
+ if( area && area->bbox_set ) {
+ proj_operation_factory_context_set_area_of_interest(
+ ctx,
+ operation_ctx,
+ area->west_lon_degree,
+ area->south_lat_degree,
+ area->east_lon_degree,
+ area->north_lat_degree);
+ }
- proj_operation_factory_context_set_grid_availability_use(
- ctx, operation_ctx, PROJ_GRID_AVAILABILITY_DISCARD_OPERATION_IF_MISSING_GRID);
+ 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, src, dst, operation_ctx);
- proj_operation_factory_context_destroy(operation_ctx);
- proj_destroy(src);
- proj_destroy(dst);
+ proj_operation_factory_context_destroy(operation_ctx);
+ proj_destroy(src);
+ proj_destroy(dst);
- if( !op_list ) {
- return nullptr;
- }
+ if( !op_list ) {
+ return nullptr;
+ }
+
+ if( proj_list_get_count(op_list) == 0 ) {
+ proj_list_destroy(op_list);
+ proj_context_log_debug(ctx, "No operation found matching criteria");
+ return nullptr;
+ }
- if( proj_list_get_count(op_list) == 0 ) {
+ auto op = proj_list_get(ctx, op_list, 0);
proj_list_destroy(op_list);
- proj_context_log_debug(ctx, "No operation found matching criteria");
- return nullptr;
- }
+ if( !op ) {
+ return nullptr;
+ }
- auto op = proj_list_get(ctx, op_list, 0);
- proj_list_destroy(op_list);
- if( !op ) {
- return nullptr;
- }
+ proj_string = proj_as_proj_string(ctx, op, PJ_PROJ_5, nullptr);
+ if( !proj_string) {
+ proj_destroy(op);
+ proj_context_log_debug(ctx, "Cannot export operation as a PROJ string");
+ return nullptr;
+ }
+
+ PJ* P;
+ if( proj_string[0] == '\0' ) {
+ /* Null transform ? */
+ P = proj_create(ctx, "proj=affine");
+ } else {
+ P = proj_create(ctx, proj_string);
+ }
- proj_string = proj_as_proj_string(ctx, op, PJ_PROJ_5, nullptr);
- if( !proj_string) {
proj_destroy(op);
- proj_context_log_debug(ctx, "Cannot export operation as a PROJ string");
- return nullptr;
- }
- PJ* P;
- if( proj_string[0] == '\0' ) {
- /* Null transform ? */
- P = proj_create(ctx, "proj=affine");
- } else {
- P = proj_create(ctx, proj_string);
+ return P;
+ }
+ catch( const std::exception& )
+ {
+ return nullptr;
}
-
- proj_destroy(op);
-
- return P;
}
PJ *proj_destroy (PJ *P) {