diff options
| author | Kristian Evers <kristianevers@gmail.com> | 2018-06-22 10:46:26 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2018-06-22 10:46:26 +0200 |
| commit | 722f22dc585b37766153a4da37b9a829ab5b8ff7 (patch) | |
| tree | 1073c02abb4040011903d66f88b7eabdf57a2b0f /src/PJ_unitconvert.c | |
| parent | 8ee389a6f44fb9ac0380ddbd3706b9354269d62f (diff) | |
| parent | 5411bd30010b709a1482fa6a7073168f021dc627 (diff) | |
| download | PROJ-722f22dc585b37766153a4da37b9a829ab5b8ff7.tar.gz PROJ-722f22dc585b37766153a4da37b9a829ab5b8ff7.zip | |
Merge pull request #1054 from rouault/add_angular_units_to_unitconvert
Add support for deg, rad and grad in unitconvert (fixes #1052), and document that it supports numeric factors (refs #1053)
Diffstat (limited to 'src/PJ_unitconvert.c')
| -rw-r--r-- | src/PJ_unitconvert.c | 104 |
1 files changed, 84 insertions, 20 deletions
diff --git a/src/PJ_unitconvert.c b/src/PJ_unitconvert.c index 25bdc2e7..6e53f6df 100644 --- a/src/PJ_unitconvert.c +++ b/src/PJ_unitconvert.c @@ -382,6 +382,59 @@ static PJ_COORD reverse_4d(PJ_COORD obs, PJ *P) { return out; } +/* M_PI / 200 */ +#define GRAD_TO_RAD 0.015707963267948967 + +static const struct PJ_UNITS +pj_angular_units[] = { + {"rad", "1.0", "Radian", 1.0}, + {"deg", "0.017453292519943296", "Degree", DEG_TO_RAD}, + {"grad", "0.015707963267948967", "Grad", GRAD_TO_RAD}, + {NULL, NULL, NULL, 0.0} +}; + + +/***********************************************************************/ +static double get_unit_conversion_factor(const char* name, + int* p_is_linear, + const char** p_normalized_name) { +/***********************************************************************/ + int i; + const char* s; + + /* Try first with linear units */ + for (i = 0; (s = pj_units[i].id) ; ++i) { + if ( strcmp(s, name) == 0 ) { + if( p_normalized_name ) { + *p_normalized_name = pj_units[i].name; + } + if( p_is_linear ) { + *p_is_linear = 1; + } + return pj_units[i].factor; + } + } + + /* And then angular units */ + for (i = 0; (s = pj_angular_units[i].id) ; ++i) { + if ( strcmp(s, name) == 0 ) { + 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; +} /***********************************************************************/ PJ *CONVERSION(unitconvert,0) { @@ -390,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); @@ -413,11 +470,10 @@ PJ *CONVERSION(unitconvert,0) { Q->z_factor = 1.0; if ((name = pj_param (P->ctx, P->params, "sxy_in").s) != NULL) { - for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i); - - if (s) { - f = pj_units[i].factor; - proj_log_debug(P, "xy_in unit: %s", pj_units[i].name); + const char* normalized_name = NULL; + 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 { if ( (f = pj_param (P->ctx, P->params, "dxy_in").f) == 0.0) return pj_default_destructor(P, PJD_ERR_UNKNOWN_UNIT_ID); @@ -427,11 +483,10 @@ PJ *CONVERSION(unitconvert,0) { } if ((name = pj_param (P->ctx, P->params, "sxy_out").s) != NULL) { - for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i); - - if (s) { - f = pj_units[i].factor; - proj_log_debug(P, "xy_out unit: %s", pj_units[i].name); + const char* normalized_name = NULL; + 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 { if ( (f = pj_param (P->ctx, P->params, "dxy_out").f) == 0.0) return pj_default_destructor(P, PJD_ERR_UNKNOWN_UNIT_ID); @@ -440,12 +495,17 @@ PJ *CONVERSION(unitconvert,0) { Q->xy_factor /= f; } - if ((name = pj_param (P->ctx, P->params, "sz_in").s) != NULL) { - for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i); + 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 (s) { - f = pj_units[i].factor; - proj_log_debug(P, "z_in unit: %s", pj_units[i].name); + if ((name = pj_param (P->ctx, P->params, "sz_in").s) != NULL) { + const char* normalized_name = NULL; + 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 { if ( (f = pj_param (P->ctx, P->params, "dz_in").f) == 0.0) return pj_default_destructor(P, PJD_ERR_UNKNOWN_UNIT_ID); @@ -455,11 +515,10 @@ PJ *CONVERSION(unitconvert,0) { } if ((name = pj_param (P->ctx, P->params, "sz_out").s) != NULL) { - for (i = 0; (s = pj_units[i].id) && strcmp(name, s) ; ++i); - - if (s) { - f = pj_units[i].factor; - proj_log_debug(P, "z_out unit: %s", pj_units[i].name); + const char* normalized_name = NULL; + 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 { if ( (f = pj_param (P->ctx, P->params, "dz_out").f) == 0.0) return pj_default_destructor(P, PJD_ERR_UNKNOWN_UNIT_ID); @@ -468,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); |
