aboutsummaryrefslogtreecommitdiff
path: root/src/PJ_unitconvert.c
diff options
context:
space:
mode:
authorKristian Evers <kristianevers@gmail.com>2018-01-04 16:51:30 +0100
committerKristian Evers <kristianevers@gmail.com>2018-01-05 00:29:04 +0100
commit7449edfb10496e2e8d1633d6fe77201787ae7ad8 (patch)
treebbbb11dc9ffe2c07b87f5183b8260466c6fa6fb4 /src/PJ_unitconvert.c
parent81df68d8aa1ad9d9bb50f7266b231ec44cd36885 (diff)
downloadPROJ-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.c85
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;
}