aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt14
-rw-r--r--src/PJ_aeqd.c2
-rw-r--r--src/PJ_airy.c2
-rw-r--r--src/PJ_cart.c57
-rw-r--r--src/cct.c9
-rw-r--r--src/gie.c244
-rw-r--r--src/proj.def4
-rw-r--r--src/proj.h5
-rw-r--r--src/proj_4D_api.c145
-rw-r--r--src/proj_internal.h8
-rw-r--r--src/projects.h2
-rw-r--r--test/gie/axisswap.gie3
-rw-r--r--test/gie/deformation.gie2
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;
}
diff --git a/src/cct.c b/src/cct.c
index de97f728..1bd25f1d 100644
--- a/src/cct.c
+++ b/src/cct.c
@@ -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);
}
diff --git a/src/gie.c b/src/gie.c
index 2bca2f66..7bee8b67 100644
--- a/src/gie.c
+++ b/src/gie.c
@@ -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
diff --git a/src/proj.h b/src/proj.h
index 7607c3d8..bc0e1e06 100644
--- a/src/proj.h
+++ b/src/proj.h
@@ -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