diff options
| -rw-r--r-- | CMakeLists.txt | 14 | ||||
| -rw-r--r-- | src/PJ_aeqd.c | 2 | ||||
| -rw-r--r-- | src/PJ_airy.c | 2 | ||||
| -rw-r--r-- | src/PJ_cart.c | 57 | ||||
| -rw-r--r-- | src/cct.c | 9 | ||||
| -rw-r--r-- | src/gie.c | 244 | ||||
| -rw-r--r-- | src/proj.def | 4 | ||||
| -rw-r--r-- | src/proj.h | 5 | ||||
| -rw-r--r-- | src/proj_4D_api.c | 145 | ||||
| -rw-r--r-- | src/proj_internal.h | 8 | ||||
| -rw-r--r-- | src/projects.h | 2 | ||||
| -rw-r--r-- | test/gie/axisswap.gie | 3 | ||||
| -rw-r--r-- | test/gie/deformation.gie | 2 |
13 files changed, 357 insertions, 140 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index d6bbe8ea..f489f4ed 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,20 @@ cmake_minimum_required(VERSION 2.6.0 FATAL_ERROR) project(PROJ4 C) set(PROJECT_INTERN_NAME PROJ) +# Set warnings +if("${CMAKE_C_COMPILER_ID}" STREQUAL "MSVC") + set(CMAKE_C_FLAGS "/WX ${CMAKE_C_FLAGS}") +elseif("${CMAKE_C_COMPILER_ID}" STREQUAL "GNU") + set(CMAKE_C_FLAGS "-std=c89 -Wall -Wextra -Wswitch -Werror \ + -Wunused-parameter -Wmissing-prototypes -Wmissing-declarations -Wformat \ + -Werror=format-security -Wshadow ${CMAKE_C_FLAGS}") +elseif("${CMAKE_C_COMPILER_ID}" MATCHES "Clang") + set(CMAKE_C_FLAGS "-std=c89 -Wall -Wextra -Wswitch -Werror \ + -Wc99-extensions -Wc11-extensions -Wunused-parameter -Wmissing-prototypes \ + -Wmissing-declarations -Wformat -Werror=format-security -Wshadow \ + -Wfloat-conversion ${CMAKE_C_FLAGS}") +endif() + ################################################################################# # PROJ4 CMake modules ################################################################################# diff --git a/src/PJ_aeqd.c b/src/PJ_aeqd.c index aa1597e4..c089eed7 100644 --- a/src/PJ_aeqd.c +++ b/src/PJ_aeqd.c @@ -35,7 +35,7 @@ enum Mode { N_POLE = 0, S_POLE = 1, EQUIT = 2, - OBLIQ = 3, + OBLIQ = 3 }; struct pj_opaque { diff --git a/src/PJ_airy.c b/src/PJ_airy.c index 3b145475..f70e7f7a 100644 --- a/src/PJ_airy.c +++ b/src/PJ_airy.c @@ -38,7 +38,7 @@ enum Mode { N_POLE = 0, S_POLE = 1, EQUIT = 2, - OBLIQ = 3, + OBLIQ = 3 }; struct pj_opaque { diff --git a/src/PJ_cart.c b/src/PJ_cart.c index d8f4a9b9..52237f24 100644 --- a/src/PJ_cart.c +++ b/src/PJ_cart.c @@ -567,6 +567,63 @@ int pj_cart_selftest (void) { for (pm_list = proj_list_prime_meridians(); pm_list->id; ++pm_list) n++; if (n == 0) return 93; + + /* check io-predicates */ + + /* angular in on fwd, linear out */ + P = proj_create (PJ_DEFAULT_CTX, "+proj=cart +ellps=GRS80"); + if (0==P) return 0; + if (!proj_angular_input (P, PJ_FWD)) return 100; + if ( proj_angular_input (P, PJ_INV)) return 101; + if ( proj_angular_output (P, PJ_FWD)) return 102; + if (!proj_angular_output (P, PJ_INV)) return 103; + P->inverted = 1; + if ( proj_angular_input (P, PJ_FWD)) return 104; + if (!proj_angular_input (P, PJ_INV)) return 105; + if (!proj_angular_output (P, PJ_FWD)) return 106; + if ( proj_angular_output (P, PJ_INV)) return 107; + proj_destroy(P); + + /* angular in and out */ + P = proj_create(PJ_DEFAULT_CTX, + "+proj=molodensky +a=6378160 +rf=298.25 " + "+da=-23 +df=-8.120449e-8 +dx=-134 +dy=-48 +dz=149 " + "+abridged " + ); + if (0==P) return 0; + if (!proj_angular_input (P, PJ_FWD)) return 108; + if (!proj_angular_input (P, PJ_INV)) return 109; + if (!proj_angular_output (P, PJ_FWD)) return 110; + if (!proj_angular_output (P, PJ_INV)) return 111; + P->inverted = 1; + if (!proj_angular_input (P, PJ_FWD)) return 112; + if (!proj_angular_input (P, PJ_INV)) return 113; + if (!proj_angular_output (P, PJ_FWD)) return 114; + if (!proj_angular_output (P, PJ_INV)) return 115; + proj_destroy(P); + + /* linear in and out */ + P = proj_create(PJ_DEFAULT_CTX, + " +proj=helmert +ellps=GRS80" + " +x=0.0127 +y=0.0065 +z=-0.0209 +s=0.00195" + " +rx=-0.00039 +ry=0.00080 +rz=-0.00114" + " +dx=-0.0029 +dy=-0.0002 +dz=-0.0006 +ds=0.00001" + " +drx=-0.00011 +dry=-0.00019 +drz=0.00007" + " +epoch=1988.0 +transpose" + ); + if (0==P) return 0; + if (proj_angular_input (P, PJ_FWD)) return 116; + if (proj_angular_input (P, PJ_INV)) return 117; + if (proj_angular_output (P, PJ_FWD)) return 118; + if (proj_angular_output (P, PJ_INV)) return 119; + P->inverted = 1; + if (proj_angular_input (P, PJ_FWD)) return 120; + if (proj_angular_input (P, PJ_INV)) return 121; + if (proj_angular_output (P, PJ_FWD)) return 122; + if (proj_angular_output (P, PJ_INV)) return 123; + proj_destroy(P); + + return 0; } @@ -151,7 +151,7 @@ int main(int argc, char **argv) { OPTARGS *o; FILE *fout = stdout; char *buf; - int input_unit, output_unit, nfields = 4, direction = 1, verbose; + int nfields = 4, direction = 1, verbose; double fixed_z = HUGE_VAL, fixed_time = HUGE_VAL; int columns_xyzt[] = {1, 2, 3, 4}; const char *longflags[] = {"v=verbose", "h=help", "I=inverse", 0}; @@ -218,9 +218,6 @@ int main(int argc, char **argv) { P->inverted = !(P->inverted); direction = 1; - input_unit = proj_angular_left (P)? PJ_IO_UNITS_RADIANS: PJ_IO_UNITS_METERS; - output_unit = proj_angular_right (P)? PJ_IO_UNITS_RADIANS: PJ_IO_UNITS_METERS; - /* Allocate input buffer */ buf = calloc (1, 10000); if (0==buf) { @@ -258,12 +255,12 @@ int main(int argc, char **argv) { continue; } - if (PJ_IO_UNITS_RADIANS==input_unit) { + if (proj_angular_input (P, direction)) { point.lpzt.lam = proj_torad (point.lpzt.lam); point.lpzt.phi = proj_torad (point.lpzt.phi); } point = proj_trans (P, direction, point); - if (PJ_IO_UNITS_RADIANS==output_unit) { + if (proj_angular_output (P, direction)) { point.lpzt.lam = proj_todeg (point.lpzt.lam); point.lpzt.phi = proj_todeg (point.lpzt.phi); } @@ -259,8 +259,17 @@ int main (int argc, char **argv) { return T.grand_ko; } +static int another_failure (void) { + T.op_ko++; + T.total_ko++; + return 0; +} - +static int another_success (void) { + T.op_ok++; + T.total_ok++; + return 0; +} static int process_file (char *fname) { @@ -421,62 +430,73 @@ static void finish_previous_operation (char *args) { (void) args; } +/*****************************************************************************/ static int operation (char *args) { +/***************************************************************************** + Define the operation to apply to the input data (in ISO 19100 lingo, + an operation is the general term describing something that can be + either a conversion or a transformation) +******************************************************************************/ T.op_id++; strcpy (&(T.operation[0]), args); if (T.verbosity > 1) { finish_previous_operation (args); banner (args); } - /* if (0==T.op_ko) - printf ("%d\n", (int) tol_lineno); */ + T.op_ok = 0; T.op_ko = 0; direction ("forward"); - tolerance ("0.5"); + tolerance ("0.5 mm"); if (T.P) proj_destroy (T.P); T.P = proj_create (0, args); if (0==T.P) - return errmsg(3, "Invalid operation definition!\n"); + errmsg(3, "Invalid operation definition!\n %s\n", args); return 0; } -static PJ_COORD torad_if_needed (PJ *P, PJ_DIRECTION dir, PJ_COORD a) { - enum pj_io_units u = P->left; - PJ_COORD c; - if (dir==PJ_INV) - u = P->right; - if (u==PJ_IO_UNITS_CLASSIC || u==PJ_IO_UNITS_METERS) - return a; - - c.lpz.lam = proj_torad (T.a.lpz.lam); - c.lpz.phi = proj_torad (T.a.lpz.phi); - c.v[2] = T.a.v[2]; - c.v[3] = T.a.v[3]; - +static PJ_COORD torad_coord (PJ_COORD a) { + PJ_COORD c = a; + c.lpz.lam = proj_torad (a.lpz.lam); + c.lpz.phi = proj_torad (a.lpz.phi); return c; } +static PJ_COORD todeg_coord (PJ_COORD a) { + PJ_COORD c = a; + c.lpz.lam = proj_todeg (a.lpz.lam); + c.lpz.phi = proj_todeg (a.lpz.phi); + return c; +} -static int accept (char *args) { - int n, i; +/* try to parse args as a PJ_COORD */ +static PJ_COORD parse_coord (char *args) { + int i; char *endp, *prev = args; - T.a = proj_coord (0,0,0,0); - n = 4; + PJ_COORD a = proj_coord (0,0,0,0); + for (i = 0; i < 4; i++) { - T.a.v[i] = proj_strtod (prev, &endp); - if (prev==endp) { - n--; - T.a.v[i] = 0; - break; - } + double d = proj_strtod (prev, &endp); + if (prev==endp) + return i > 1? a: proj_coord_error (); + a.v[i] = d; prev = endp; } - T.a = torad_if_needed (T.P, T.dir, T.a); + + return a; +} + + +/*****************************************************************************/ +static int accept (char *args) { +/***************************************************************************** + Read ("ACCEPT") a 2, 3, or 4 dimensional input coordinate. +******************************************************************************/ + T.a = parse_coord (args); if (T.verbosity > 3) printf ("# %s", args); return 0; @@ -484,10 +504,17 @@ static int accept (char *args) { +/*****************************************************************************/ static int roundtrip (char *args) { +/***************************************************************************** + Check how far we go from the ACCEPTed point when doing successive + back/forward transformation pairs. +******************************************************************************/ int ntrips; double d, r, ans; char *endp; + if (0==T.P) + return another_failure (); ans = proj_strtod (args, &endp); ntrips = (int) (endp==args? 100: fabs(ans)); d = strtod_scaled (endp, 1); @@ -501,95 +528,106 @@ static int roundtrip (char *args) { 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); } - T.op_ko++; - T.total_ko++; - } - else { - T.op_ok++; - T.total_ok++; + another_failure (); } + else + another_success (); return 0; } -static int expect (char *args) { - double d; - enum pj_io_units unit; - char *endp, *prev = args; - int i; - - T.e = proj_coord (0,0,0,0); - T.b = proj_coord (0,0,0,0); - T.nargs = 4; - for (i = 0; i < 4; i++) { - T.e.v[i] = proj_strtod (prev, &endp); - if (prev==endp) { - T.nargs--; - T.e.v[i] = 0; - break; - } - prev = endp; - } - T.e = torad_if_needed (T.P, T.dir==PJ_FWD? PJ_INV:PJ_FWD, T.e); +static int expect_message (double d, char *args) { + another_failure (); - T.b = proj_trans (T.P, T.dir, T.a); - T.b = torad_if_needed (T.P, T.dir==PJ_FWD? PJ_INV:PJ_FWD, T.b); + if (T.verbosity < 0) + return 1; + if (d > 1e6) + d = 999999.999999; + 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, " expected: %s\n", args); + fprintf (T.fout, " got: %.9f %.9f", T.b.xy.x, T.b.xy.y); + if (T.b.xyzt.t!=0 || T.b.xyzt.z!=0) + fprintf (T.fout, " %.9f", T.b.xyz.z); + if (T.b.xyzt.t!=0) + fprintf (T.fout, " %.9f", T.b.xyzt.t); + fprintf (T.fout, "\n"); + fprintf (T.fout, " deviation: %.3f mm, expected: %.3f mm\n", 1000*d, 1000*T.tolerance); + return 1; +} - if (T.nargs < 2) { - T.op_ko++; - T.total_ko++; - 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 Too few args: %s\n", opt_strip_path (T.curr_file), (int) lineno, args); - } - return 1; +static int expect_message_cannot_parse (char *args) { + another_failure (); + 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 Too few args: %s\n", opt_strip_path (T.curr_file), (int) lineno, args); } + return 1; +} - unit = T.dir==PJ_FWD? T.P->right: T.P->left; - if (PJ_IO_UNITS_CLASSIC==unit) - unit = PJ_IO_UNITS_METERS; - if (unit==PJ_IO_UNITS_RADIANS) - d = proj_lp_dist (T.P, T.b.lp, T.e.lp); +/*****************************************************************************/ +static int expect (char *args) { +/***************************************************************************** + Tell GIE what to expect, when transforming the ACCEPTed input +******************************************************************************/ + PJ_COORD ci, co, ce; + double d; + if (0==T.P) + return another_failure (); + + 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.e): T.e; + + /* input ("accepted") values also probably in degrees */ + 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); + T.b = proj_angular_output (T.P, T.dir)? todeg_coord (co): co; + + /* 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); + /* 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); + 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) { - if (d > 1e6) - d = 999999.999999; - if (T.verbosity > -1) { - if (0==T.op_ko && T.verbosity < 2) - banner (T.operation); - fprintf (T.fout, "%s", T.op_ko? " -----\n": delim); + if (d > T.tolerance) + return expect_message (d, args); + + another_success (); - fprintf (T.fout, " FAILURE in %s(%d):\n", opt_strip_path (T.curr_file), (int) lineno); - fprintf (T.fout, " expected: %s\n", args); - fprintf (T.fout, " got: %.9f %.9f", T.b.xy.x, T.b.xy.y); - if (T.nargs > 2) - fprintf (T.fout, " %.9f", T.b.xyz.z); - if (T.nargs > 3) - fprintf (T.fout, " %.9f", T.b.xyzt.t); - fprintf (T.fout, "\n"); - fprintf (T.fout, " deviation: %.3f mm, expected: %.3f mm\n", 1000*d, 1000*T.tolerance); - } - T.op_ko++; - T.total_ko++; - } - else { - T.op_ok++; - T.total_ok++; - } return 0; } - - - +/*****************************************************************************/ static int verbose (char *args) { +/***************************************************************************** + Tell the system how noisy it should be +******************************************************************************/ int i = (int) proj_atof (args); /* if -q/--quiet flag has been given, we do nothing */ @@ -603,14 +641,22 @@ static int verbose (char *args) { return 0; } +/*****************************************************************************/ static int comment (char *args) { +/***************************************************************************** + in line comment. Equivalent to # +******************************************************************************/ (void) args; return 0; } +/*****************************************************************************/ static int echo (char *args) { - fprintf (T.fout, "%s\n", args); +/***************************************************************************** + Add user defined noise to the output stream +******************************************************************************/ +fprintf (T.fout, "%s\n", args); return 0; } diff --git a/src/proj.def b/src/proj.def index 998a260e..8b1882ee 100644 --- a/src/proj.def +++ b/src/proj.def @@ -144,5 +144,5 @@ EXPORTS proj_list_units @130 proj_list_prime_meridians @131 - proj_angular_left @132 - proj_angular_right @133 + proj_angular_input @132 + proj_angular_output @133 @@ -371,8 +371,9 @@ typedef enum PJ_DIRECTION PJ_DIRECTION; -int proj_angular_left (PJ *P); -int proj_angular_right (PJ *P); +int proj_angular_input (PJ *P, enum PJ_DIRECTION dir); +int proj_angular_output (PJ *P, enum PJ_DIRECTION dir); + PJ_COORD proj_trans (PJ *P, PJ_DIRECTION direction, PJ_COORD coord); diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c index 9ae4147f..66a272f2 100644 --- a/src/proj_4D_api.c +++ b/src/proj_4D_api.c @@ -26,12 +26,13 @@ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER * DEALINGS IN THE SOFTWARE. *****************************************************************************/ +#include <stddef.h> +#include <errno.h> +#include <ctype.h> #include <proj.h> #include "proj_internal.h" #include "projects.h" #include "geodesic.h" -#include <stddef.h> -#include <errno.h> /* Initialize PJ_COORD struct */ @@ -44,14 +45,29 @@ PJ_COORD proj_coord (double x, double y, double z, double t) { return res; } -/* We do not want to bubble enum pj_io_units up to the API level, so we provide these predicates instead */ -int proj_angular_left (PJ *P) { - return pj_left (P)==PJ_IO_UNITS_RADIANS; -} -int proj_angular_right (PJ *P) { +/*****************************************************************************/ +int proj_angular_input (PJ *P, enum PJ_DIRECTION dir) { +/****************************************************************************** + Returns 1 if the operator P expects angular input coordinates when + operating in direction dir, 0 otherwise. + dir: {PJ_FWD, PJ_INV} +******************************************************************************/ + if (PJ_FWD==dir) + return pj_left (P)==PJ_IO_UNITS_RADIANS; return pj_right (P)==PJ_IO_UNITS_RADIANS; } +/*****************************************************************************/ +int proj_angular_output (PJ *P, enum PJ_DIRECTION dir) { +/****************************************************************************** + Returns 1 if the operator P provides angular output coordinates when + operating in direction dir, 0 otherwise. + dir: {PJ_FWD, PJ_INV} +******************************************************************************/ + return proj_angular_input (P, -dir); +} + + /* Geodesic distance (in meter) between two points with angular 2D coordinates */ double proj_lp_dist (const PJ *P, LP a, LP b) { double s12, azi1, azi2; @@ -76,7 +92,6 @@ double proj_xyz_dist (XYZ a, XYZ b) { double proj_roundtrip (PJ *P, PJ_DIRECTION direction, int n, PJ_COORD coo) { int i; PJ_COORD o, u; - enum pj_io_units unit; if (0==P) return HUGE_VAL; @@ -106,9 +121,8 @@ double proj_roundtrip (PJ *P, PJ_DIRECTION direction, int n, PJ_COORD coo) { return HUGE_VAL; } - /* left when forward, because we do a roundtrip, and end where we begin */ - unit = direction==PJ_FWD? P->left: P->right; - if (unit==PJ_IO_UNITS_RADIANS) + /* 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_xyz_dist (coo.xyz, coo.xyz); @@ -281,27 +295,29 @@ size_t proj_trans_generic ( else coord = pj_inv4d (coord, P); - /* in all full length cases, we overwrite the input with the output */ + /* in all full length cases, we overwrite the input with the output, */ + /* and step on to the next element. */ + /* The casts are somewhat funky, but they compile down to no-ops and */ + /* they tell compilers and static analyzers that we know what we do */ if (nx > 1) { - *x = coord.xyzt.x; - x = (double *) ( ((char *) x) + sx); + *x = coord.xyzt.x; + x = (double *) ((void *) ( ((char *) x) + sx)); } if (ny > 1) { - *y = coord.xyzt.y; - y = (double *) ( ((char *) y) + sy); + *y = coord.xyzt.y; + y = (double *) ((void *) ( ((char *) y) + sy)); } if (nz > 1) { - *z = coord.xyzt.z; - z = (double *) ( ((char *) z) + sz); + *z = coord.xyzt.z; + z = (double *) ((void *) ( ((char *) z) + sz)); } if (nt > 1) { - *t = coord.xyzt.t; - t = (double *) ( ((char *) t) + st); + *t = coord.xyzt.t; + t = (double *) ((void *) ( ((char *) t) + st)); } } + /* Last time around, we update the length 1 cases with their transformed alter egos */ - /* ... or would we rather not? Then what about the nmin==1 case? */ - /* perhaps signalling the non-array case by setting all strides to 0? */ if (nx==1) *x = coord.xyzt.x; if (ny==1) @@ -315,20 +331,99 @@ size_t proj_trans_generic ( } - +/*************************************************************************************/ PJ *proj_create (PJ_CONTEXT *ctx, const char *definition) { +/************************************************************************************** + Create a new PJ object in the context ctx, using the given definition. If ctx==0, + the default context is used, if definition==0, or invalid, a null-pointer is + returned. The definition may use '+' as argument start indicator, as in + "+proj=utm +zone=32", or leave it out, as in "proj=utm zone=32" +**************************************************************************************/ + PJ *P; + char *args, **argv; + int argc, i, j, n; + if (0==ctx) ctx = pj_get_default_ctx (); - return pj_init_plus_ctx (ctx, definition); + + /* make a copy that we can manipulate */ + n = (int) strlen (definition); + args = (char *) malloc (n + 1); + if (0==args) + return 0; + strcpy (args, definition); + + /* all-in-one: count args, eliminate superfluous whitespace, 0-terminate substrings */ + for (i = j = argc = 0; i < n; ) { + /* skip prefix whitespace */ + while (isspace (args[i])) + i++; + + /* skip at most one prefix '+' */ + if ('+'==args[i]) + i++; + + /* whitespace after a '+' is a syntax error - but by Postel's prescription, we ignore and go on */ + if (isspace (args[i])) + continue; + + /* move a whitespace delimited text string to the left, skipping over superfluous whitespace */ + while ((0!=args[i]) && (!isspace (args[i]))) + args[j++] = args[i++]; + + /* terminate string - if that makes j pass i (often the case for first arg), let i catch up */ + args[j++] = 0; + if (i < j) + i = j; + + /* we finished another arg */ + argc++; + + /* skip postfix whitespace */ + while (isspace (args[i])) + i++; + } + + /* turn the massaged input into an array of strings */ + argv = (char **) calloc (argc, sizeof (char *)); + if (0==argv) + return pj_dealloc (args); + + argv[0] = args; + for (i = 0, j = 1; i < n; i++) { + if (0==args[i]) + argv[j++] = args + (i + 1); + if (j==argc) + break; + } + + /* ...and let pj_init_ctx do the hard work */ + P = pj_init_ctx (ctx, argc, argv); + pj_dealloc (argv); + pj_dealloc (args); + return P; } + + +/*************************************************************************************/ PJ *proj_create_argv (PJ_CONTEXT *ctx, int argc, char **argv) { +/************************************************************************************** +Create a new PJ object in the context ctx, using the given definition argument +array argv. If ctx==0, the default context is used, if definition==0, or invalid, +a null-pointer is returned. The definition arguments may use '+' as argument start +indicator, as in {"+proj=utm", "+zone=32"}, or leave it out, as in {"proj=utm", +"zone=32"}. +**************************************************************************************/ + if (0==argv) + return 0; if (0==ctx) ctx = pj_get_default_ctx (); return pj_init_ctx (ctx, argc, argv); } + /*****************************************************************************/ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *srid_from, const char *srid_to, PJ_AREA *area) { /****************************************************************************** @@ -446,7 +541,7 @@ int proj_errno_reset (PJ *P) { } -/* Create a new context - or provide a pointer to the default context */ +/* Create a new context */ PJ_CONTEXT *proj_context_create (void) { return pj_ctx_alloc (); } diff --git a/src/proj_internal.h b/src/proj_internal.h index 2d6a2406..95f34994 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -55,7 +55,13 @@ extern "C" { #define PJ_TORAD(deg) ((deg)*M_PI/180.0) #endif - +/* This enum is also conditionally defined in projects.h - but we need it here */ +/* for the pj_left/right prototypes, and enums cannot be forward declared */ +enum pj_io_units { + PJ_IO_UNITS_CLASSIC = 0, /* Scaled meters (right) */ + PJ_IO_UNITS_METERS = 1, /* Meters */ + PJ_IO_UNITS_RADIANS = 2 /* Radians */ +}; enum pj_io_units pj_left (PJ *P); enum pj_io_units pj_right (PJ *P); diff --git a/src/projects.h b/src/projects.h index 9ff24f71..a28c08d1 100644 --- a/src/projects.h +++ b/src/projects.h @@ -182,11 +182,13 @@ struct FACTORS; struct PJ_REGION_S; typedef struct PJ_REGION_S PJ_Region; typedef struct ARG_list paralist; /* parameter list */ +#ifndef PROJ_INTERNAL_H enum pj_io_units { PJ_IO_UNITS_CLASSIC = 0, /* Scaled meters (right) */ PJ_IO_UNITS_METERS = 1, /* Meters */ PJ_IO_UNITS_RADIANS = 2 /* Radians */ }; +#endif #ifndef PROJ_H typedef struct PJconsts PJ; /* the PJ object herself */ typedef union PJ_COORD PJ_COORD; diff --git a/test/gie/axisswap.gie b/test/gie/axisswap.gie index 409af742..2264a056 100644 --- a/test/gie/axisswap.gie +++ b/test/gie/axisswap.gie @@ -53,8 +53,7 @@ EXPECT 3 -2 1 4 ROUNDTRIP 100 - -OPERATION +proj=pipeline +step +proj=latlong +step +proj=axisswap +order=1,2,3,4 +angularunits +OPERATION proj=pipeline step proj=latlong step proj=axisswap order=1,2,3,4 angularunits TOLERANCE 0.00001 m ACCEPT 12 55 0 0 EXPECT 12 55 0 0 diff --git a/test/gie/deformation.gie b/test/gie/deformation.gie index 74a6b25d..4173fa31 100644 --- a/test/gie/deformation.gie +++ b/test/gie/deformation.gie @@ -64,7 +64,7 @@ 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 ------------------------------------------------------------------------------- TOLERANCE 0.000001 m ACCEPT -3004295.5882503074 -1093474.1690603832 5500477.1338251457 2000.0 |
