diff options
| author | Kristian Evers <kristianevers@gmail.com> | 2018-01-04 16:51:30 +0100 |
|---|---|---|
| committer | Kristian Evers <kristianevers@gmail.com> | 2018-01-05 00:29:04 +0100 |
| commit | 7449edfb10496e2e8d1633d6fe77201787ae7ad8 (patch) | |
| tree | bbbb11dc9ffe2c07b87f5183b8260466c6fa6fb4 /src/PJ_unitconvert.c | |
| parent | 81df68d8aa1ad9d9bb50f7266b231ec44cd36885 (diff) | |
| download | PROJ-7449edfb10496e2e8d1633d6fe77201787ae7ad8.tar.gz PROJ-7449edfb10496e2e8d1633d6fe77201787ae7ad8.zip | |
Custom unit factors in unitconvert.
Added the possibility to use custom unit factors. Similar to the
classic +to_meter parameter the conversion factor is related to meters,
i.e. the factor for conversion from kilometers meters is 1000. The
custom unit factors is given using the existing xy_in, xy_out, z_in and
z_out parameters, for example:
proj=unitconvert xy_in=4.5 +xy_out=mm
Diffstat (limited to 'src/PJ_unitconvert.c')
| -rw-r--r-- | src/PJ_unitconvert.c | 85 |
1 files changed, 53 insertions, 32 deletions
diff --git a/src/PJ_unitconvert.c b/src/PJ_unitconvert.c index 9cd2acf8..bf1fcd37 100644 --- a/src/PJ_unitconvert.c +++ b/src/PJ_unitconvert.c @@ -80,6 +80,13 @@ struct TIME_UNITS { char *name; /* comments */ }; +struct pj_opaque_unitconvert { + int t_in_id; /* time unit id for the time input unit */ + int t_out_id; /* time unit id for the time output unit */ + double xy_factor; /* unit conversion factor for horizontal components */ + double z_factor; /* unit conversion factor for vertical components */ +}; + /***********************************************************************/ static int is_leap_year(int year) { @@ -255,7 +262,6 @@ static double mjd_to_yyyymmdd(double mjd) { return year*10000.0 + month*100.0 + day; } - static const struct TIME_UNITS time_units[] = { {"mjd", mjd_to_mjd, mjd_to_mjd, "Modified julian date"}, {"decimalyear", decimalyear_to_mjd, mjd_to_decimalyear, "Decimal year"}, @@ -264,15 +270,6 @@ static const struct TIME_UNITS time_units[] = { {NULL, NULL, NULL, NULL} }; -struct pj_opaque_unitconvert { - int t_in_id; /* time unit id for the time input unit */ - int t_out_id; /* time unit id for the time output unit */ - int xy_in_id; /* unit id for the horizontal input unit */ - int xy_out_id; /* unit id for the horizontal output unit */ - int z_in_id; /* unit id for the vertical input unit */ - int z_out_id; /* unit id for the vertical output unit */ -}; - /***********************************************************************/ static XY forward_2d(LP lp, PJ *P) { @@ -283,8 +280,8 @@ static XY forward_2d(LP lp, PJ *P) { PJ_COORD point = {{0,0,0,0}}; point.lp = lp; - point.xy.x *= pj_units[Q->xy_in_id].factor / pj_units[Q->xy_out_id].factor; - point.xy.y *= pj_units[Q->xy_in_id].factor / pj_units[Q->xy_out_id].factor; + point.xy.x *= Q->xy_factor; + point.xy.y *= Q->xy_factor; return point.xy; } @@ -299,8 +296,8 @@ static LP reverse_2d(XY xy, PJ *P) { PJ_COORD point = {{0,0,0,0}}; point.xy = xy; - point.xy.x *= pj_units[Q->xy_out_id].factor / pj_units[Q->xy_in_id].factor; - point.xy.y *= pj_units[Q->xy_out_id].factor / pj_units[Q->xy_in_id].factor; + point.xy.x /= Q->xy_factor; + point.xy.y /= Q->xy_factor; return point.lp; } @@ -318,7 +315,7 @@ static XYZ forward_3d(LPZ lpz, PJ *P) { /* take care of the horizontal components in the 2D function */ point.xy = forward_2d(point.lp, P); - point.xyz.z *= pj_units[Q->z_in_id].factor / pj_units[Q->z_out_id].factor; + point.xyz.z *= Q->z_factor; return point.xyz; } @@ -335,7 +332,7 @@ static LPZ reverse_3d(XYZ xyz, PJ *P) { /* take care of the horizontal components in the 2D function */ point.lp = reverse_2d(point.xy, P); - point.xyz.z *= pj_units[Q->z_out_id].factor / pj_units[Q->z_in_id].factor; + point.xyz.z /= Q->z_factor; return point.lpz; } @@ -387,6 +384,7 @@ PJ *CONVERSION(unitconvert,0) { struct pj_opaque_unitconvert *Q = pj_calloc (1, sizeof (struct pj_opaque_unitconvert)); char *s, *name; int i; + double f; if (0==Q) return pj_default_destructor (P, ENOMEM); @@ -406,40 +404,63 @@ PJ *CONVERSION(unitconvert,0) { Q->t_in_id = -1; Q->t_out_id = -1; + Q->xy_factor = 1.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) return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); - - Q->xy_in_id = i; - proj_log_debug(P, "xy_in unit: %s", pj_units[i].name); + if (s) { + f = pj_units[i].factor; + proj_log_debug(P, "xy_in unit: %s", pj_units[i].name); + } else { + if ( (f = pj_param (P->ctx, P->params, "dxy_in").f) == 0.0) + return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); + } + if (f != 0.0) + Q->xy_factor *= f; } 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) return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); - - Q->xy_out_id = i; - proj_log_debug(P, "xy_out unit: %s", pj_units[i].name); + if (s) { + f = pj_units[i].factor; + proj_log_debug(P, "xy_out unit: %s", pj_units[i].name); + } else { + if ( (f = pj_param (P->ctx, P->params, "dxy_out").f) == 0.0) + return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); + } + if (f != 0.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 (!s) return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); /* unknown unit conversion id */ - - Q->z_in_id = i; - proj_log_debug(P, "z_in unit: %s", pj_units[i].name); + if (s) { + f = pj_units[i].factor; + proj_log_debug(P, "z_in unit: %s", pj_units[i].name); + } else { + if ( (f = pj_param (P->ctx, P->params, "dz_in").f) == 0.0) + return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); + } + if (f != 0.0) + Q->z_factor *= f; } 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) return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); /* unknown unit conversion id */ - - Q->z_out_id = i; - proj_log_debug(P, "z_out unit: %s", pj_units[i].name); + if (s) { + f = pj_units[i].factor; + proj_log_debug(P, "z_out unit: %s", pj_units[i].name); + } else { + if ( (f = pj_param (P->ctx, P->params, "dz_out").f) == 0.0) + return pj_default_destructor(P, PJD_ERR_UNKNOW_UNIT_ID); + } + if (f != 0.0) + Q->z_factor /= f; } |
