/* Measure numerical deviation after n roundtrips fwd-inv (or inv-fwd) */ double proj_roundtrip (PJ *P, PJ_DIRECTION direction, int n, PJ_COORD *coord) { int i; PJ_COORD t, org; if (0==P) return HUGE_VAL; if (n < 1) { proj_errno_set (P, EINVAL); return HUGE_VAL; } /* in the first half-step, we generate the output value */ org = *coord; *coord = proj_trans (P, direction, org); t = *coord; /* now we take n-1 full steps in inverse direction: We are */ /* out of phase due to the half step already taken */ for (i = 0; i < n - 1; i++) t = proj_trans (P, direction, proj_trans (P, -direction, t) ); /* finally, we take the last half-step */ t = proj_trans (P, -direction, t); /* checking for angular *input* since we do a roundtrip, and end where we begin */ if (proj_angular_input (P, direction)) return proj_lpz_dist (P, org, t); return proj_xyz_dist (org, t); }
static int expect (const char *args) { /***************************************************************************** Tell GIE what to expect, when transforming the ACCEPTed input ******************************************************************************/ PJ_COORD ci, co, ce; double d; int expect_failure = 0; int expect_failure_with_errno = 0; if (0==strncmp (args, "failure", 7)) { expect_failure = 1; /* Option: Fail with an expected errno (syntax: expect failure errno -33) */ if (0==strncmp (column (args, 2), "errno", 5)) expect_failure_with_errno = errno_from_err_const (column (args, 3)); } if (T.ignore==proj_errno(T.P)) return another_skip (); if (nullptr==T.P) { /* If we expect failure, and fail, then it's a success... */ if (expect_failure) { /* Failed to fail correctly? */ if (expect_failure_with_errno && proj_errno (T.P)!=expect_failure_with_errno) return expect_failure_with_errno_message (expect_failure_with_errno, proj_errno(T.P)); return another_succeeding_failure (); } /* Otherwise, it's a true failure */ banner (T.operation); errmsg (3, "%sInvalid operation definition in line no. %d:\n %s (errno=%s/%d)\n", delim, (int) T.operation_lineno, pj_strerrno(proj_errno(T.P)), err_const_from_errno (proj_errno(T.P)), proj_errno(T.P) ); return another_failing_failure (); } /* We may still successfully fail even if the proj_create succeeded */ if (expect_failure) { proj_errno_reset (T.P); /* Try to carry out the operation - and expect failure */ ci = proj_angular_input (T.P, T.dir)? torad_coord (T.P, T.dir, T.a): T.a; co = expect_trans_n_dim (ci); if (expect_failure_with_errno) { if (proj_errno (T.P)==expect_failure_with_errno) return another_succeeding_failure (); fprintf (T.fout, "errno=%d, expected=%d\n", proj_errno (T.P), expect_failure_with_errno); return another_failing_failure (); } /* Succeeded in failing? - that's a success */ if (co.xyz.x==HUGE_VAL) return another_succeeding_failure (); /* Failed to fail? - that's a failure */ banner (T.operation); errmsg (3, "%sFailed to fail. Operation definition in line no. %d\n", delim, (int) T.operation_lineno ); return another_failing_failure (); } if (T.verbosity > 3) { fprintf (T.fout, "%s\n", T.P->inverted? "INVERTED": "NOT INVERTED"); fprintf (T.fout, "%s\n", T.dir== 1? "forward": "reverse"); fprintf (T.fout, "%s\n", proj_angular_input (T.P, T.dir)? "angular in": "linear in"); fprintf (T.fout, "%s\n", proj_angular_output (T.P, T.dir)? "angular out": "linear out"); fprintf (T.fout, "left: %d right: %d\n", T.P->left, T.P->right); } tests++; T.e = parse_coord (args); if (HUGE_VAL==T.e.v[0]) return expect_message_cannot_parse (args); /* expected angular values, probably in degrees */ ce = proj_angular_output (T.P, T.dir)? torad_coord (T.P, T.dir, T.e): T.e; if (T.verbosity > 3) fprintf (T.fout, "EXPECTS %.12f %.12f %.12f %.12f\n", ce.v[0],ce.v[1],ce.v[2],ce.v[3]); /* input ("accepted") values, also probably in degrees */ ci = proj_angular_input (T.P, T.dir)? torad_coord (T.P, T.dir, T.a): T.a; if (T.verbosity > 3) fprintf (T.fout, "ACCEPTS %.12f %.12f %.12f %.12f\n", ci.v[0],ci.v[1],ci.v[2],ci.v[3]); /* do the transformation, but mask off dimensions not given in expect-ation */ co = expect_trans_n_dim (ci); if (T.dimensions_given < 4) co.v[3] = 0; if (T.dimensions_given < 3) co.v[2] = 0; /* angular output from proj_trans comes in radians */ T.b = proj_angular_output (T.P, T.dir)? todeg_coord (T.P, T.dir, co): co; if (T.verbosity > 3) fprintf (T.fout, "GOT %.12f %.12f %.12f %.12f\n", co.v[0],co.v[1],co.v[2],co.v[3]); #if 0 /* We need to handle unusual axis orders - that'll be an item for version 5.1 */ if (T.P->axisswap) { ce = proj_trans (T.P->axisswap, T.dir, ce); co = proj_trans (T.P->axisswap, T.dir, co); } #endif if (proj_angular_output (T.P, T.dir)) d = proj_lpz_dist (T.P, ce, co); else d = proj_xyz_dist (co, ce); if (d > T.tolerance) return expect_message (d, args); succs++; another_success (); return 0; }