diff --git a/src/PJ_unitconvert.c b/src/PJ_unitconvert.c index 59af201f95..6e53f6df1a 100644 --- a/src/PJ_unitconvert.c +++ b/src/PJ_unitconvert.c @@ -396,6 +396,7 @@ pj_angular_units[] = { /***********************************************************************/ static double get_unit_conversion_factor(const char* name, + int* p_is_linear, const char** p_normalized_name) { /***********************************************************************/ int i; @@ -407,6 +408,9 @@ static double get_unit_conversion_factor(const char* name, if( p_normalized_name ) { *p_normalized_name = pj_units[i].name; } + if( p_is_linear ) { + *p_is_linear = 1; + } return pj_units[i].factor; } } @@ -417,12 +421,18 @@ static double get_unit_conversion_factor(const char* name, if( p_normalized_name ) { *p_normalized_name = pj_angular_units[i].name; } + if( p_is_linear ) { + *p_is_linear = 0; + } return pj_angular_units[i].factor; } } if( p_normalized_name ) { *p_normalized_name = NULL; } + if( p_is_linear ) { + *p_is_linear = -1; + } return 0.0; } @@ -433,6 +443,10 @@ PJ *CONVERSION(unitconvert,0) { char *s, *name; int i; double f; + int xy_in_is_linear = -1; /* unknown */ + int xy_out_is_linear = -1; /* unknown */ + int z_in_is_linear = -1; /* unknown */ + int z_out_is_linear = -1; /* unknown */ if (0==Q) return pj_default_destructor (P, ENOMEM); @@ -457,7 +471,7 @@ PJ *CONVERSION(unitconvert,0) { if ((name = pj_param (P->ctx, P->params, "sxy_in").s) != NULL) { const char* normalized_name = NULL; - f = get_unit_conversion_factor(name, &normalized_name); + f = get_unit_conversion_factor(name, &xy_in_is_linear, &normalized_name); if (f != 0.0) { proj_log_debug(P, "xy_in unit: %s", normalized_name); } else { @@ -470,7 +484,7 @@ PJ *CONVERSION(unitconvert,0) { if ((name = pj_param (P->ctx, P->params, "sxy_out").s) != NULL) { const char* normalized_name = NULL; - f = get_unit_conversion_factor(name, &normalized_name); + f = get_unit_conversion_factor(name, &xy_out_is_linear, &normalized_name); if (f != 0.0) { proj_log_debug(P, "xy_out unit: %s", normalized_name); } else { @@ -481,9 +495,15 @@ PJ *CONVERSION(unitconvert,0) { Q->xy_factor /= f; } + if( xy_in_is_linear >= 0 && xy_out_is_linear >= 0 && + xy_in_is_linear != xy_out_is_linear ) { + proj_log_debug(P, "inconsistent unit type between xy_in and xy_out"); + return pj_default_destructor(P, PJD_ERR_INCONSISTENT_UNIT); + } + if ((name = pj_param (P->ctx, P->params, "sz_in").s) != NULL) { const char* normalized_name = NULL; - f = get_unit_conversion_factor(name, &normalized_name); + f = get_unit_conversion_factor(name, &z_in_is_linear, &normalized_name); if (f != 0.0) { proj_log_debug(P, "z_in unit: %s", normalized_name); } else { @@ -496,7 +516,7 @@ PJ *CONVERSION(unitconvert,0) { if ((name = pj_param (P->ctx, P->params, "sz_out").s) != NULL) { const char* normalized_name = NULL; - f = get_unit_conversion_factor(name, &normalized_name); + f = get_unit_conversion_factor(name, &z_out_is_linear, &normalized_name); if (f != 0.0) { proj_log_debug(P, "z_out unit: %s", normalized_name); } else { @@ -507,6 +527,11 @@ PJ *CONVERSION(unitconvert,0) { Q->z_factor /= f; } + if( z_in_is_linear >= 0 && z_out_is_linear >= 0 && + z_in_is_linear != z_out_is_linear ) { + proj_log_debug(P, "inconsistent unit type between z_in and z_out"); + return pj_default_destructor(P, PJD_ERR_INCONSISTENT_UNIT); + } if ((name = pj_param (P->ctx, P->params, "st_in").s) != NULL) { for (i = 0; (s = time_units[i].id) && strcmp(name, s) ; ++i); diff --git a/src/projects.h b/src/projects.h index 5b9238132d..45edeb659a 100644 --- a/src/projects.h +++ b/src/projects.h @@ -583,6 +583,7 @@ enum deprecated_constants_for_now_dropped_analytical_factors { #define PJD_ERR_ELLIPSOIDAL_UNSUPPORTED -56 #define PJD_ERR_TOO_MANY_INITS -57 #define PJD_ERR_INVALID_ARG -58 +#define PJD_ERR_INCONSISTENT_UNIT -59 struct projFileAPI_t; diff --git a/test/gie/unitconvert.gie b/test/gie/unitconvert.gie index ff6dc96f5d..7bbea49da1 100644 --- a/test/gie/unitconvert.gie +++ b/test/gie/unitconvert.gie @@ -35,5 +35,12 @@ tolerance 0.000000000001 accept 50 50 1 1 expect 45 45 1 1 +operation proj=unitconvert xy_in=m xy_out=rad +accept 1 1 1 1 +expect failure + +operation proj=unitconvert z_in=rad z_out=m +accept 1 1 1 1 +expect failure