aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/PJ_cart.c10
-rw-r--r--src/PJ_hgridshift.c3
-rw-r--r--src/PJ_horner.c5
-rw-r--r--src/PJ_molodensky.c8
-rw-r--r--src/PJ_vgridshift.c7
-rw-r--r--src/gie.c53
-rw-r--r--src/proj.def47
-rw-r--r--src/proj.h5
-rw-r--r--src/proj_4D_api.c46
-rw-r--r--test/gie/axisswap.gie8
-rw-r--r--test/gie/deformation.gie30
11 files changed, 130 insertions, 92 deletions
diff --git a/src/PJ_cart.c b/src/PJ_cart.c
index 52237f24..e2768c55 100644
--- a/src/PJ_cart.c
+++ b/src/PJ_cart.c
@@ -318,8 +318,8 @@ int pj_cart_selftest (void) {
b = proj_trans (P, PJ_FWD, a);
/* Check roundtrip precision for 10000 iterations each way */
- dist = proj_roundtrip (P, PJ_FWD, 10000, a);
- dist = proj_roundtrip (P, PJ_INV, 10000, b);
+ dist = proj_roundtrip (P, PJ_FWD, 10000, &a);
+ dist = proj_roundtrip (P, PJ_INV, 10000, &b);
if (dist > 2e-9)
return 7;
@@ -331,7 +331,7 @@ int pj_cart_selftest (void) {
a.lpz.z = 100;
/* Forward projection: Ellipsoidal-to-3D-Cartesian */
- dist = proj_roundtrip (P, PJ_FWD, 1, a);
+ dist = proj_roundtrip (P, PJ_FWD, 1, &a);
if (dist > 1e-12)
return 8;
@@ -340,12 +340,14 @@ int pj_cart_selftest (void) {
a.lpz.lam = PJ_TORAD(0);
a.lpz.phi = PJ_TORAD(-90);
a.lpz.z = 100;
+ b = a;
/* Forward projection: Ellipsoidal-to-3D-Cartesian */
- dist = proj_roundtrip (P, PJ_FWD, 1, a);
+ dist = proj_roundtrip (P, PJ_FWD, 1, &a);
if (dist > 1e-12)
return 9;
+
/* Inverse projection: 3D-Cartesian-to-Ellipsoidal */
b = proj_trans (P, PJ_INV, b);
diff --git a/src/PJ_hgridshift.c b/src/PJ_hgridshift.c
index 26a2f471..d57af697 100644
--- a/src/PJ_hgridshift.c
+++ b/src/PJ_hgridshift.c
@@ -105,8 +105,9 @@ int pj_hgridshift_selftest (void) {
a = proj_coord (0,0,0,0);
a.lpz.lam = PJ_TORAD(173);
a.lpz.phi = PJ_TORAD(-45);
+ b = a;
- dist = proj_roundtrip (P, PJ_FWD, 1, a);
+ dist = proj_roundtrip (P, PJ_FWD, 1, &b);
if (dist > 0.00000001) {
printf("dist: %f\n",dist);
return 1;
diff --git a/src/PJ_horner.c b/src/PJ_horner.c
index c28e3907..51c271ae 100644
--- a/src/PJ_horner.c
+++ b/src/PJ_horner.c
@@ -529,9 +529,10 @@ int pj_horner_selftest (void) {
a = b = proj_coord (0,0,0,0);
a.uv.v = 6125305.4245;
a.uv.u = 878354.8539;
+ c = a;
/* Check roundtrip precision for 1 iteration each way, starting in forward direction */
- dist = proj_roundtrip (P, PJ_FWD, 1, a);
+ dist = proj_roundtrip (P, PJ_FWD, 1, &c);
if (dist > 0.01)
return 1;
@@ -560,7 +561,7 @@ int pj_horner_selftest (void) {
return 3;
/* Check roundtrip precision for 1 iteration each way */
- dist = proj_roundtrip (P, PJ_FWD, 1, a);
+ dist = proj_roundtrip (P, PJ_FWD, 1, &a);
if (dist > 0.01)
return 4;
diff --git a/src/PJ_molodensky.c b/src/PJ_molodensky.c
index a35cabe4..73d0e5c2 100644
--- a/src/PJ_molodensky.c
+++ b/src/PJ_molodensky.c
@@ -318,7 +318,7 @@ int pj_molodensky_selftest (void) {return 0;}
#else
int pj_molodensky_selftest (void) {
- PJ_COORD in, res, exp;
+ PJ_COORD in, ni, res, exp;
PJ *P;
/* Test the abridged Molodensky first. Example from appendix 3 of Deakin (2004). */
@@ -346,7 +346,8 @@ int pj_molodensky_selftest (void) {
}
/* let's try a roundtrip */
- if (proj_roundtrip(P, PJ_FWD, 100, in) > 1) {
+ ni = in;
+ if (proj_roundtrip(P, PJ_FWD, 100, &ni) > 1) {
proj_destroy(P);
return 12;
}
@@ -375,7 +376,8 @@ int pj_molodensky_selftest (void) {
}
/* let's try a roundtrip */
- if (proj_roundtrip(P, PJ_FWD, 100, in) > 1) {
+ ni = in;
+ if (proj_roundtrip(P, PJ_FWD, 100, &ni) > 1) {
proj_destroy(P);
return 22;
}
diff --git a/src/PJ_vgridshift.c b/src/PJ_vgridshift.c
index e3f3cbd3..5ab4a162 100644
--- a/src/PJ_vgridshift.c
+++ b/src/PJ_vgridshift.c
@@ -108,8 +108,8 @@ int pj_vgridshift_selftest (void) {
a = proj_coord(0,0,0,0);
a.lpz.lam = PJ_TORAD(12.5);
a.lpz.phi = PJ_TORAD(55.5);
-
- dist = proj_roundtrip (P, PJ_FWD, 1, a);
+ b = a;
+ dist = proj_roundtrip (P, PJ_FWD, 1, &b);
if (dist > 0.00000001)
return 1;
@@ -125,6 +125,9 @@ int pj_vgridshift_selftest (void) {
if (proj_xyz_dist(expect.xyz, b.xyz) > 1e-4) failures++;
expect.lpz.z = -35.880001068115234000;
if (proj_xyz_dist(expect.xyz, b.xyz) > 1e-4) failures++;
+ /* manual roundtrip a->b, b<-b, b==a */
+ b = proj_trans(P, PJ_INV, b);
+ if (proj_xyz_dist(a.xyz, b.xyz) > 1e-9) failures++;
if (failures > 1)
return 2;
diff --git a/src/gie.c b/src/gie.c
index 7bee8b67..09a33069 100644
--- a/src/gie.c
+++ b/src/gie.c
@@ -377,8 +377,6 @@ static double strtod_scaled (char *args, double default_scale) {
static int banner (char *args) {
char dots[] = {"..."}, nodots[] = {""}, *thedots = nodots;
- if (T.total_ko > 0 && T.op_ko==0)
- printf ("\n\n");
if (strlen(args) > 70)
thedots = dots;
fprintf (T.fout, "%s%-70.70s%s\n", delim, args, thedots);
@@ -513,29 +511,36 @@ static int roundtrip (char *args) {
int ntrips;
double d, r, ans;
char *endp;
+ PJ_COORD coo;
+
if (0==T.P)
return another_failure ();
+
ans = proj_strtod (args, &endp);
ntrips = (int) (endp==args? 100: fabs(ans));
d = strtod_scaled (endp, 1);
d = d==HUGE_VAL? T.tolerance: d;
- r = proj_roundtrip (T.P, PJ_FWD, ntrips, T.a);
- if (r > d) {
- if (T.verbosity > -1) {
- if (0==T.op_ko && T.verbosity < 2)
- banner (T.operation);
- fprintf (T.fout, "%s", T.op_ko? " -----\n": delim);
- fprintf (T.fout, " FAILURE in %s(%d):\n", opt_strip_path (T.curr_file), (int) lineno);
- fprintf (T.fout, " roundtrip deviation: %.3f mm, expected: %.3f mm\n", 1000*r, 1000*d);
- }
- another_failure ();
- }
- else
- another_success ();
+ coo = T.a;
- return 0;
+ /* input ("accepted") values - probably in degrees */
+ coo = proj_angular_input (T.P, T.dir)? torad_coord (T.a): T.a;
+
+ r = proj_roundtrip (T.P, T.dir, ntrips, &coo);
+ if (r <= d)
+ return another_success ();
+
+ if (T.verbosity > -1) {
+ if (0==T.op_ko && T.verbosity < 2)
+ banner (T.operation);
+ fprintf (T.fout, "%s", T.op_ko? " -----\n": delim);
+ fprintf (T.fout, " FAILURE in %s(%d):\n", opt_strip_path (T.curr_file), (int) lineno);
+ fprintf (T.fout, " roundtrip deviation: %.3f mm, expected: %.3f mm\n", 1000*r, 1000*d);
+ }
+ return another_failure ();
}
+
+
static int expect_message (double d, char *args) {
another_failure ();
@@ -589,7 +594,7 @@ static int expect (char *args) {
ce = proj_angular_output (T.P, T.dir)? torad_coord (T.e): T.e;
/* input ("accepted") values also probably in degrees */
- ci = proj_angular_input (T.P, T.dir)? torad_coord (T.a): T.a;
+ ci = proj_angular_input (T.P, T.dir)? torad_coord (T.a): T.a;
/* angular output from proj_trans comes in radians */
co = proj_trans (T.P, T.dir, ci);
@@ -598,21 +603,22 @@ static int expect (char *args) {
/* but there are a few more possible input conventions... */
if (proj_angular_output (T.P, T.dir)) {
double e = HUGE_VAL;
- d = hypot (proj_lp_dist (T.P, ce.lp, co.lp), ce.lpz.z - co.lpz.z);
+ d = proj_lpz_dist (T.P, ce.lpz, co.lpz);
/* check whether input was already in radians */
if (d > T.tolerance)
- e = hypot (proj_lp_dist (T.P, T.e.lp, co.lp), T.e.lpz.z - co.lpz.z);
+ e = proj_lpz_dist (T.P, T.e.lpz, co.lpz);
if (e < d)
d = e;
+
/* or the tolerance may be based on euclidean distance */
if (d > T.tolerance)
e = proj_xyz_dist (T.b.xyz, T.e.xyz);
if (e < d)
d = e;
+
}
else
d = proj_xyz_dist (T.b.xyz, T.e.xyz);
-
if (d > T.tolerance)
return expect_message (d, args);
@@ -663,11 +669,14 @@ fprintf (T.fout, "%s\n", args);
static int dispatch (char *cmnd, char *args) {
+ int last_errno = proj_errno_reset (T.P);
+
if (0==level%2) {
if (0==strcmp (cmnd, "BEGIN"))
level++;
return 0;
}
+
if (0==strcmp (cmnd, "OPERATION")) return operation (args);
if (0==strcmp (cmnd, "operation")) return operation (args);
if (0==strcmp (cmnd, "ACCEPT")) return accept (args);
@@ -688,6 +697,10 @@ static int dispatch (char *cmnd, char *args) {
if (0==strcmp (cmnd, "echo")) return echo (args);
if (0==strcmp (cmnd, "END")) return finish_previous_operation (args), level++, 0;
if ('#'==cmnd[0]) return comment (args);
+
+ if (proj_errno(T.P))
+ printf ("#####***** ERRNO=%d\n", proj_errno(T.P));
+ proj_errno_restore (T.P, last_errno);
return 0;
}
diff --git a/src/proj.def b/src/proj.def
index 8b1882ee..cc1793e1 100644
--- a/src/proj.def
+++ b/src/proj.def
@@ -117,32 +117,33 @@ EXPORTS
proj_context_destroy @109
proj_lp_dist @110
- proj_xy_dist @111
- proj_xyz_dist @112
+ proj_lpz_dist @111
+ proj_xy_dist @112
+ proj_xyz_dist @113
- proj_log_level @113
- proj_log_func @114
- proj_log_error @115
- proj_log_debug @116
- proj_log_trace @117
+ proj_log_level @114
+ proj_log_func @115
+ proj_log_error @116
+ proj_log_debug @117
+ proj_log_trace @118
- proj_info @118
- proj_pj_info @119
- proj_grid_info @120
- proj_init_info @121
+ proj_info @119
+ proj_pj_info @120
+ proj_grid_info @121
+ proj_init_info @122
- proj_torad @122
- proj_todeg @123
- proj_rtodms @124
- proj_dmstor @125
+ proj_torad @123
+ proj_todeg @124
+ proj_rtodms @125
+ proj_dmstor @126
- proj_derivatives @126
- proj_factors @127
+ proj_derivatives @127
+ proj_factors @128
- proj_list_operations @128
- proj_list_ellps @129
- proj_list_units @130
- proj_list_prime_meridians @131
+ proj_list_operations @129
+ proj_list_ellps @130
+ proj_list_units @131
+ proj_list_prime_meridians @132
- proj_angular_input @132
- proj_angular_output @133
+ proj_angular_input @133
+ proj_angular_output @134
diff --git a/src/proj.h b/src/proj.h
index bc0e1e06..19bb2192 100644
--- a/src/proj.h
+++ b/src/proj.h
@@ -393,11 +393,14 @@ int proj_trans_array (PJ *P, PJ_DIRECTION direction, size_t n, PJ_COORD *coord);
PJ_COORD proj_coord (double x, double y, double z, double t);
/* Measure internal consistency - in forward or inverse direction */
-double proj_roundtrip (PJ *P, PJ_DIRECTION direction, int n, PJ_COORD coo);
+double proj_roundtrip (PJ *P, PJ_DIRECTION direction, int n, PJ_COORD *coo);
/* Geodesic distance between two points with angular 2D coordinates */
double proj_lp_dist (const PJ *P, LP a, LP b);
+/* The geodesic distance AND the vertical offset */
+double proj_lpz_dist (const PJ *P, LPZ a, LPZ b);
+
/* Euclidean distance between two points with linear 2D coordinates */
double proj_xy_dist (XY a, XY b);
diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c
index 66a272f2..ee4cb20f 100644
--- a/src/proj_4D_api.c
+++ b/src/proj_4D_api.c
@@ -76,6 +76,14 @@ double proj_lp_dist (const PJ *P, LP a, LP b) {
return s12;
}
+/* The geodesic distance AND the vertical offset */
+double proj_lpz_dist (const PJ *P, LPZ a, LPZ b) {
+ PJ_COORD aa, bb;
+ aa.lpz = a;
+ bb.lpz = b;
+ return hypot (proj_lp_dist (P, aa.lp, bb.lp), a.z - b.z);
+}
+
/* Euclidean distance between two points with linear 2D coordinates */
double proj_xy_dist (XY a, XY b) {
return hypot (a.x - b.x, a.y - b.y);
@@ -89,9 +97,9 @@ double proj_xyz_dist (XYZ a, XYZ b) {
/* Measure numerical deviation after n roundtrips fwd-inv (or inv-fwd) */
-double proj_roundtrip (PJ *P, PJ_DIRECTION direction, int n, PJ_COORD coo) {
+double proj_roundtrip (PJ *P, PJ_DIRECTION direction, int n, PJ_COORD *coo) {
int i;
- PJ_COORD o, u;
+ PJ_COORD o, u, org;
if (0==P)
return HUGE_VAL;
@@ -101,34 +109,28 @@ double proj_roundtrip (PJ *P, PJ_DIRECTION direction, int n, PJ_COORD coo) {
return HUGE_VAL;
}
- o = coo;
+ /* in the first half-step, we generate the output value */
+ u = org = *coo;
+ o = *coo = proj_trans (P, direction, u);
- switch (direction) {
- case PJ_FWD:
- for (i = 0; i < n; i++) {
- u = pj_fwd4d (o, P);
- o = pj_inv4d (u, P);
- }
- break;
- case PJ_INV:
- for (i = 0; i < n; i++) {
- u = pj_inv4d (o, P);
- o = pj_fwd4d (u, P);
- }
- break;
- default:
- proj_errno_set (P, EINVAL);
- return HUGE_VAL;
+ /* now we take n-1 full steps */
+ for (i = 0; i < n - 1; i++) {
+ u = proj_trans (P, -direction, o);
+ o = proj_trans (P, direction, u);
}
- /* checking for angular input since we do a roundtrip, and end where we begin */
+ /* finally, we take the last half-step */
+ u = proj_trans (P, -direction, o);
+
+ /* checking for angular *input* since we do a roundtrip, and end where we begin */
if (proj_angular_input (P, direction))
- return hypot (proj_lp_dist (P, coo.lp, o.lp), coo.lpz.z - o.lpz.z);
+ return proj_lpz_dist (P, org.lpz, u.lpz);
- return proj_xyz_dist (coo.xyz, coo.xyz);
+ return proj_xyz_dist (org.xyz, u.xyz);
}
+
/* Apply the transformation P to the coordinate coo */
PJ_COORD proj_trans (PJ *P, PJ_DIRECTION direction, PJ_COORD coo) {
if (0==P)
diff --git a/test/gie/axisswap.gie b/test/gie/axisswap.gie
index 2264a056..b9281ef7 100644
--- a/test/gie/axisswap.gie
+++ b/test/gie/axisswap.gie
@@ -63,4 +63,12 @@ TOLERANCE 0.00001 m
ACCEPT 12 55 0 0
EXPECT -55 -12 0 0
+-------------------------------------------------------------------------------
+operation +proj=aea +ellps=GRS80 +lat_1=0 +lat_2=2
+-------------------------------------------------------------------------------
+tolerance 0.00010 mm
+accept 2 1
+expect 222571.608757106 110653.326743030
+ROUNDTRIP 100
+
END
diff --git a/test/gie/deformation.gie b/test/gie/deformation.gie
index 4173fa31..ce9aca75 100644
--- a/test/gie/deformation.gie
+++ b/test/gie/deformation.gie
@@ -1,4 +1,3 @@
-BEGIN
===============================================================================
Test for the deformation operation - Kinematic Gridshifting
@@ -10,26 +9,27 @@ The input coordinate is located at lon=60, lam=-160 - somewhere in Alaska.
===============================================================================
+BEGIN
-------------------------------------------------------------------------------
Test using only horizontal grid and +tobs parameter
-------------------------------------------------------------------------------
OPERATION +proj=deformation +xy_grids=alaska +t_epoch=2016.0 +t_obs=2000.0
-------------------------------------------------------------------------------
-TOLERANCE 0.000001 m
+TOLERANCE 1 um
ACCEPT -3004295.5882503074 -1093474.1690603832 5500477.1338251457
-EXPECT -3004295.5888766116 -1093474.1688513425 5500477.1338251457
-ROUNDTRIP 1000
+EXPECT -3004295.5888766116 -1093474.1688513425 5500477.1338251457
+# ROUNDTRIP 1000
-------------------------------------------------------------------------------
Test using only vertical grid and +tobs parameter
-------------------------------------------------------------------------------
OPERATION +proj=deformation +z_grids=egm96_15.gtx +t_epoch=2016.0 +t_obs=2000.0
-------------------------------------------------------------------------------
-TOLERANCE 0.000001 m
+TOLERANCE 1 um
ACCEPT -3004295.5882503074 -1093474.1690603832 5500477.1338251457
EXPECT -3004295.5882503074 -1093474.1690603832 5500234.008855661
-ROUNDTRIP 1000
+# ROUNDTRIP 1000
-------------------------------------------------------------------------------
Test using both horizontal and vertical grids as well as the +tobs parameter
@@ -39,35 +39,37 @@ OPERATION +proj=deformation +xy_grids=alaska +z_grids=egm96_15.gtx +t_epoch=20
TOLERANCE 0.000001 m
ACCEPT -3004295.5882503074 -1093474.1690603832 5500477.1338251457
EXPECT -3004295.5888766116 -1093474.1688513425 5500234.008855661
-ROUNDTRIP 1000
+# ROUNDTRIP 1000
-------------------------------------------------------------------------------
Test using only horizontal grid
-------------------------------------------------------------------------------
OPERATION +proj=deformation +xy_grids=alaska +t_epoch=2016.0
-------------------------------------------------------------------------------
-TOLERANCE 0.000001 m
+TOLERANCE 1 um
ACCEPT -3004295.5882503074 -1093474.1690603832 5500477.1338251457 2000.0
EXPECT -3004295.5888766116 -1093474.1688513425 5500477.1338251457 2000.0
-ROUNDTRIP 1000
+# ROUNDTRIP 1000
-------------------------------------------------------------------------------
Test using only vertical grid
-------------------------------------------------------------------------------
OPERATION +proj=deformation +z_grids=egm96_15.gtx +t_epoch=2016.0
-------------------------------------------------------------------------------
-TOLERANCE 0.000001 m
+TOLERANCE 1 um
ACCEPT -3004295.5882503074 -1093474.1690603832 5500477.1338251457 2000.0
EXPECT -3004295.5882503074 -1093474.1690603832 5500234.008855661 2000.0
-ROUNDTRIP 1000
+# ROUNDTRIP 1000
-------------------------------------------------------------------------------
Test using both horizontal and vertical grids
-------------------------------------------------------------------------------
-OPERATION proj=deformation xy_grids=alaska z_grids=egm96_15.gtx t_epoch=2016.0
+OPERATION +proj=deformation +xy_grids=alaska +z_grids=egm96_15.gtx +t_epoch=2016.0 +ellps=GRS80
-------------------------------------------------------------------------------
-TOLERANCE 0.000001 m
+TOLERANCE 1 um
ACCEPT -3004295.5882503074 -1093474.1690603832 5500477.1338251457 2000.0
EXPECT -3004295.5888766116 -1093474.1688513425 5500234.008855661 2000.0
-ROUNDTRIP 1000
+# ROUNDTRIP 1000
+
+
END