From d4e6ed566b7de7ab8999b8c21616951a72482c95 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Mon, 9 Oct 2017 22:58:00 +0200 Subject: Remove PJ_DATUMS which was introduced to proj.h by mistake --- src/proj.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'src') diff --git a/src/proj.h b/src/proj.h index 049daf19..3af1584c 100644 --- a/src/proj.h +++ b/src/proj.h @@ -212,9 +212,6 @@ typedef struct PJ_LIST PJ_OPERATIONS; struct PJ_ELLPS; typedef struct PJ_ELLPS PJ_ELLPS; -struct PJ_DATUMS; -typedef struct PJ_DATUMS PJ_DATUMS; - struct PJ_UNITS; typedef struct PJ_UNITS PJ_UNITS; -- cgit v1.2.3 From 0333785b7d89b3af154793b4f4bb939e1bdaf731 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Tue, 10 Oct 2017 00:35:55 +0200 Subject: Resolve OSS Fuzz issue 3595 division by zero by replacing atan(y/x) with atan2(y,x) --- src/geocent.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/geocent.c b/src/geocent.c index e340e73d..a8cec043 100644 --- a/src/geocent.c +++ b/src/geocent.c @@ -430,7 +430,7 @@ void pj_Convert_Geocentric_To_Geodetic (GeocentricInfo *gi, while (SDPHI*SDPHI > genau2 && iter < maxiter); /* ellipsoidal (geodetic) latitude */ - *Latitude=atan(SPHI/fabs(CPHI)); + *Latitude=atan2(SPHI, fabs(CPHI)); return; #endif /* defined(USE_ITERATIVE_METHOD) */ -- cgit v1.2.3 From 4dc807e127f9c6f1eb4b85bc7a7e001ca14e2e88 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Wed, 11 Oct 2017 23:19:24 +0200 Subject: repair a simple dealloc bug in PJ_pipeline, which caused a landslide of OSS Fuzz issue reports --- src/PJ_pipeline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index 9352b4fd..d1ddf65f 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -270,7 +270,7 @@ static void *destructor (PJ *P, int errlev) { return pj_default_destructor (P, errlev); for (i = 0; i < P->opaque->steps; i++) - pj_default_destructor (P->opaque->pipeline[i+1], errlev); + P->opaque->pipeline[i+1]->destructor (P->opaque->pipeline[i+1], errlev); pj_dealloc (P->opaque->reverse_step); pj_dealloc (P->opaque->omit_forward); -- cgit v1.2.3 From 973c87c5115e34c60d65f702815edee169fcdd1e Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Sat, 7 Oct 2017 17:48:25 +0200 Subject: gie.c and builtins.gie now able to reproduce internal test results improved docs, improved strtod - avoid precision loss for very long fractions Switch gie.c to use same framework as cct.c numerous improvements in proj_strtod.c and gie.c Add gie to the build system --- src/CMakeLists.txt | 26 +- src/Makefile.am | 12 +- src/bin_gie.cmake | 9 + src/gie.c | 722 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/makefile.vc | 9 +- src/optargpm.h | 21 +- src/proj_strtod.c | 54 +++- 7 files changed, 823 insertions(+), 30 deletions(-) create mode 100644 src/bin_gie.cmake create mode 100644 src/gie.c (limited to 'src') diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 788273a9..494eef9b 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -3,11 +3,12 @@ include(lib_proj.cmake) # configure executable build -option(BUILD_CCT "Build cct (coordinate conversion and transformation tool)" ON) -option(BUILD_CS2CS "Build cs2cs (coordinate systems to coordinate systems translation tool)" ON) -option(BUILD_PROJ "Build proj (cartographic projection tool : latlong <-> projected coordinates" ON) -option(BUILD_GEOD "Build geod (computation of geodesic lines)" ON) -option(BUILD_NAD2BIN "Build nad2bin (format conversion tool) " ON) +option(BUILD_CCT "Build cct (coordinate conversion and transformation tool)" ON) +option(BUILD_CS2CS "Build cs2cs (coordinate systems to coordinate systems translation tool)" ON) +option(BUILD_GEOD "Build geod (computation of geodesic lines)" ON) +option(BUILD_GIE "Build gie (geospatial integrity investigation environment - a PROJ.4 test tool)" ON) +option(BUILD_NAD2BIN "Build nad2bin (format conversion tool)" ON) +option(BUILD_PROJ "Build proj (cartographic projection tool : latlong <-> projected coordinates)" ON) if(NOT MSVC) if (NOT APPLE) @@ -33,11 +34,6 @@ if(BUILD_CS2CS) set(BIN_TARGETS ${BIN_TARGETS} cs2cs) endif(BUILD_CS2CS) -if(BUILD_PROJ) - include(bin_proj.cmake) - set(BIN_TARGETS ${BIN_TARGETS} binproj) -endif(BUILD_PROJ) - if(BUILD_GEOD) include(bin_geod.cmake) include(bin_geodtest.cmake) @@ -49,6 +45,16 @@ if(BUILD_NAD2BIN) set(BIN_TARGETS ${BIN_TARGETS} nad2bin) endif(BUILD_NAD2BIN) +if(BUILD_PROJ) + include(bin_proj.cmake) + set(BIN_TARGETS ${BIN_TARGETS} binproj) +endif(BUILD_PROJ) + +if(BUILD_GIE) + include(bin_gie.cmake) + set(BIN_TARGETS ${BIN_TARGETS} gie) +endif(BUILD_GIE) + if (MSVC OR CMAKE_CONFIGURATION_TYPES) if(BIN_TARGETS) # Add _d suffix for your debug versions of the tools diff --git a/src/Makefile.am b/src/Makefile.am index 25b7456c..1a1f3270 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -12,7 +12,7 @@ AM_CPPFLAGS = -DPROJ_LIB=\"$(pkgdatadir)\" \ include_HEADERS = proj.h proj_api.h projects.h geodesic.h \ org_proj4_Projections.h org_proj4_PJ.h -EXTRA_DIST = makefile.vc proj.def bin_cct.cmake bin_cs2cs.cmake \ +EXTRA_DIST = makefile.vc proj.def bin_cct.cmake bin_gie.cmake bin_cs2cs.cmake \ bin_geod.cmake bin_nad2bin.cmake bin_proj.cmake \ lib_proj.cmake CMakeLists.txt bin_geodtest.cmake geodtest.c @@ -21,15 +21,19 @@ cs2cs_SOURCES = cs2cs.c gen_cheb.c p_series.c cct_SOURCES = cct.c proj_strtod.c optargpm.h nad2bin_SOURCES = nad2bin.c geod_SOURCES = geod.c geod_set.c geod_interface.c geod_interface.h + +gie_SOURCES = gie.c proj_strtod.c optargpm.h multistresstest_SOURCES = multistresstest.c test228_SOURCES = test228.c geodtest_SOURCES = geodtest.c -proj_LDADD = libproj.la -cs2cs_LDADD = libproj.la cct_LDADD = libproj.la -nad2bin_LDADD = libproj.la +cs2cs_LDADD = libproj.la geod_LDADD = libproj.la +proj_LDADD = libproj.la +nad2bin_LDADD = libproj.la + +gie_LDADD = libproj.la multistresstest_LDADD = libproj.la @THREAD_LIB@ test228_LDADD = libproj.la @THREAD_LIB@ geodtest_LDADD = libproj.la diff --git a/src/bin_gie.cmake b/src/bin_gie.cmake new file mode 100644 index 00000000..ca6dde0e --- /dev/null +++ b/src/bin_gie.cmake @@ -0,0 +1,9 @@ +set(GIE_SRC gie.c proj_strtod.c) +set(GIE_INCLUDE optargpm.h) + +source_group("Source Files\\Bin" FILES ${GIE_SRC}) + +add_executable(gie ${GIE_SRC} ${GIE_INCLUDE}) +target_link_libraries(gie ${PROJ_LIBRARIES}) +install(TARGETS gie + RUNTIME DESTINATION ${BINDIR}) diff --git a/src/gie.c b/src/gie.c new file mode 100644 index 00000000..adfc4e0f --- /dev/null +++ b/src/gie.c @@ -0,0 +1,722 @@ +/*********************************************************************** + + gie - The Geospatial Integrity Investigation Environment + +************************************************************************ + +The Geospatial Integrity Investigation Environment "gie" is a modest +regression testing environment for the PROJ.4 transformation library. + +Its primary design goal was to be able to replace those thousands of +lines of regression testing code that are (at time of writing) part +of PROJ.4, while not requiring any other kind of tooling than the same +C compiler already employed for compiling the library. + +The basic functionality of the gie command language is implemented +through just 3 command verbs: + +OPERATION, which defines the PROJ.4 operation to test, +ACCEPT, which defines the input coordinate to read, and +EXPECT, which defines the result to expect. + +E.g: + +operation +proj=utm +zone=32 +ellps=GRS80 +accept 12 55 +expect 691_875.632_14 6_098_907.825_05 + +Note that gie accepts the underscore ("_") as a thousands separator. +It is not required (in fact, it is entirely ignored by the input +routine), but it significantly improves the readability of the very +long strings of numbers typically required in projected coordinates. + +By default, gie considers the EXPECTation met, if the result comes to +within 0.5 mm of the expected. This default can be changed using the +TOLERANCE command verb (and yes, I know, linguistically speaking, both +"operation" and "tolerance" are nouns, not verbs). See the first +few hundred lines of the "builtins.gie" test file for more details of +the command verbs available (verbs of both the VERBal and NOUNistic +persuation). + +-- + +But more importantly than being an acronym for "Geospatial Integrity +Investigation Environment", gie were also the initials, user id, and +USGS email address of Gerald Ian Evenden (1935--2016), the geospatial +visionary, who, already in the 1980s, started what was to become the +PROJ.4 of today. + +Gerald's clear vision was that map projections are *just special +functions*. Some of them rather complex, most of them of two variables, +but all of them *just special functions*, and not particularly more +special than the sin(), cos(), tan(), and hypot() already available in +the C standard library. + +And hence, *they should not be particularly much harder to use*, for a +programmer, than the sin()s, tan()s and hypot()s so readily available. + +Gerald's ingenuity also showed in the implementation of the vision, +where he devised a highly comprehensible, yet simple, system of key-value +pairs for parameterising a map projection, and the highly flexible +PJ struct, storing run-time compiled versions of those key-value pairs, +hence making a map projection function call, pj_fwd(PJ, point), as easy +as a traditional function call like hypot(x,y). + +While today, we may have more formally well defined metadata systems +(most prominent the OGC WKT representation), nothing comes close being +as easily readable ("human compatible") as Gerald's key-value system. +This system in particular, and the PROJ.4 system in general, was +Gerald's great gift to anyone using and/or communicating about geodata. + +It is only reasonable to name a program keeping an eye on the integrity +of the PROJ.4 system in honour of Gerald. So in honour, and hopefully +also in the spirit, of Gerald Ian Evenden (1935--2016), this is the +Geospatial Integrity Investigation Environment. + +************************************************************************ + +Thomas Knudsen, thokn@sdfe.dk, 2017-10-01/2017-10-08 + +************************************************************************ + +* Copyright (c) 2017 Thomas Knudsen +* Copyright (c) 2017, SDFE +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. + +***********************************************************************/ + +#include "optargpm.h" + +#include +#include "proj_internal.h" +#include "projects.h" + +#include +#include +#include + +#include +#include + +#include +#include + + + +/* from proj_strtod.c */ +double proj_strtod(const char *str, char **endptr); +double proj_atof(const char *str); + +static char *column (char *buf, int n); +int main(int argc, char **argv); + +static int process_file (char *fname); +static int errmsg (int errlev, char *msg, ...); +static int get_inp (FILE *f, char *inp, int size); +static int get_cmnd (char *inp, char *cmnd, int len); +static char *get_args (char *inp); +static int dispatch (char *cmnd, char *args); + + + +#define SKIP -1 + +typedef struct { + char operation[10000]; + PJ *P; + PJ_COORD a, b, c, e; + PJ_DIRECTION dir; + int verbosity; + int nargs; + int op_id; + int op_ok, op_ko; + int total_ok, total_ko; + int grand_ok, grand_ko; + double tolerance; + char *curr_file; + FILE *fout; +} gie_ctx; + +gie_ctx T = {{""}, 0, {{0,0,0,0}}, {{0,0,0,0}}, {{0,0,0,0}}, {{0,0,0,0}}, PJ_FWD, 1, 0, 0,0,0,0,0,0,0, 0.0005, 0, 0}; + +OPTARGS *o; + + + +size_t tol_lineno = 0; +size_t lineno = 0; +size_t level = 0; +char delim[] = {"-------------------------------------------------------------------------------\n"}; +char DELIM[] = {"===============================================================================\n"}; + + +#define CMDLEN 25000 + +int nfiles = 0; + + +static const char usage[] = { + "--------------------------------------------------------------------------------\n" + "Usage: %s [-options]... infile...\n" + "--------------------------------------------------------------------------------\n" + "Options:\n" + "--------------------------------------------------------------------------------\n" + " -h Help: print this usage information\n" + " -o /path/to/file Specify output file name\n" + " -v Verbose: Provide non-essential informational output.\n" + " Repeat -v for more verbosity (e.g. -vv)\n" + " -q Quiet: Opposite of verbose. In quiet mode not even errors\n" + " are reported. Only interaction is through the return code\n" + " (0 on success, non-zero indicates number of FAILED tests)\n" + "--------------------------------------------------------------------------------\n" + "Long Options:\n" + "--------------------------------------------------------------------------------\n" + " --output Alias for -o\n" + " --verbose Alias for -v\n" + " --help Alias for -h\n" + "--------------------------------------------------------------------------------\n" + "Examples:\n" + "--------------------------------------------------------------------------------\n" + "1. Run all tests in file \"corner-cases.gie\", providing much extra information\n" + " gie -vvvv corner-cases.gie\n" + "2. Run all tests in files \"foo\" and \"bar\", providing info on failures only\n" + " gie foo bar\n" + "--------------------------------------------------------------------------------\n" +}; + +int main (int argc, char **argv) { + int i; + const char *longflags[] = {"v=verbose", "q=quiet", "h=help", 0}; + const char *longkeys[] = {"o=output", 0}; + + o = opt_parse (argc, argv, "hvq", "o", longflags, longkeys); + if (0==o) + return 0; + + if (opt_given (o, "h")) { + printf (usage, o->progname); + return 0; + } + + + + T.verbosity = opt_given (o, "q"); + if (T.verbosity) + T.verbosity = -1; + if (T.verbosity != -1) + T.verbosity = opt_given (o, "v") + 1; + + T.fout = stdout; + if (opt_given (o, "o")) + T.fout = fopen (opt_arg (o, "output"), "rt"); + if (0==T.fout) { + fprintf (stderr, "%s: Cannot open '%s' for output\n", o->progname, opt_arg (o, "output")); + free (o); + return 1; + } + + if (0==o->fargc) { + if (T.verbosity==-1) + return -1; + fprintf (T.fout, "Nothing to do\n"); + return 0; + } + + for (i = 0; i < o->fargc; i++) + process_file (o->fargv[i]); + + if (T.verbosity > 0) { + if (o->fargc > 1) + fprintf (T.fout, "%sGrand total: %d. Success: %d, Failure: %d\n", delim, T.grand_ok+T.grand_ko, T.grand_ok, T.grand_ko); + printf (delim); + } + else + if (T.grand_ko) + fprintf (T.fout, "Failures: %d", T.grand_ko); + + if (stdout != T.fout) + fclose (T.fout); + + free (o); + return T.grand_ko; +} + + + + + +static int process_file (char *fname) { + FILE *f; + char inp[CMDLEN]; + char cmnd[1000]; + char *args; + + lineno = level = 0; + T.op_ok = T.total_ok = 0; + T.op_ko = T.total_ko = 0; + + f = fopen (fname, "rt"); + if (0==f) { + if (T.verbosity > 0) { + fprintf (T.fout, "%sCannot open spec'd input file '%s' - bye!\n", delim, fname); + return 2; + } + errmsg (2, "Cannot open spec'd input file '%s' - bye!\n", fname); + } + if (T.verbosity > 0) + fprintf (T.fout, "%sReading file '%s'\n", delim, fname); + T.curr_file = fname; + while (get_inp(f, inp, CMDLEN)) { + int len; + + if (feof(f)) + break; + len = get_cmnd (inp, cmnd, 1000); + if (len>=999) { + errmsg (2, "Command verb too long: '%s' - bye!\n", cmnd); + proj_destroy (T.P); + T.P = 0; + return 0; + + } + args = get_args (inp); + if (SKIP==dispatch (cmnd, args)) + return proj_destroy (T.P), T.P = 0, 0; + } + fclose (f); + + T.grand_ok += T.total_ok; + T.grand_ko += T.total_ko; + if (T.verbosity > 0) + fprintf (T.fout, "%stotal: %2d tests succeeded, %2d tests %s\n", delim, T.total_ok, T.total_ko, T.total_ko? "FAILED!": "failed."); + + if (level==0) + return errmsg (-3, "File '%s':Missing 'BEGIN' cmnd - bye!\n", fname); + if (level && level%2) + return errmsg (-4, "File '%s':Missing 'END' cmnd - bye!\n", fname); + return 0; +} + + + + + + +/* return a pointer to the n'th column of buf or a pointer to the terminating 0 if less than n */ +static char *column (char *buf, int n) { + int i; + if (n <= 0) + return buf; + for (i = 0; i < n; i++) { + while (isspace(*buf)) + buf++; + if (i == n - 1) + break; + while ((0 != *buf) && !isspace(*buf)) + buf++; + } + return buf; +} + + + + +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); + return 0; +} + + + + + + +static int tolerance (char *args) { + char *endp = args; + T.tolerance = proj_strtod (endp, &endp); + if (HUGE_VAL==T.tolerance) { + T.tolerance = 0.0005; + return 1; + } + while (isspace (*endp)) + endp++; + + if (0==strcmp(endp, "km")) + T.tolerance *= 1000; + else if (0==strcmp(endp, "m")) + T.tolerance *= 1; + else if (0==strcmp(endp, "dm")) + T.tolerance /= 10; + else if (0==strcmp(endp, "cm")) + T.tolerance /= 100; + else if (0==strcmp(endp, "mm")) + T.tolerance /= 1000; + else if (0==strcmp(endp, "um")) + T.tolerance /= 1e6; + else if (0==strcmp(endp, "nm")) + T.tolerance /= 1e9; + else + T.tolerance /= 1000; /* If no unit, assume mm */ + return 0; +} + + +static int direction (char *args) { + char *endp = args; + while (isspace (*endp)) + endp++; + switch (*endp) { + case 'F': + case 'f': + T.dir = PJ_FWD; + break; + case 'I': + case 'i': + case 'R': + case 'r': + T.dir = PJ_INV; + break; + default: + return 1; + } + return 0; +} + + + + +static void finish_previous_operation () { + if (T.verbosity > 1 && T.op_id > 1 && T.op_ok+T.op_ko) + fprintf (T.fout, "%s %d tests succeeded, %d tests %s\n", delim, T.op_ok, T.op_ko, T.op_ko? "FAILED!": "failed."); +} + +static int operation (char *args) { + 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"); + + if (T.P) + proj_destroy (T.P); + T.P = proj_create (0, args); + if (0==T.P) + return errmsg(3, "Invalid operation definition!\n"); + 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; + + if (u==PJ_IO_UNITS_RADIANS) { + c.lpz.lam = proj_torad (T.a.lpz.lam); + c.lpz.phi = proj_torad (T.a.lpz.phi); + } + + return c; +} + + +static int accept (char *args) { + int n, i; + char *endp = args; + T.a = proj_coord (0,0,0,0); + n = 4; + for (i = 0; i < 4; i++) { + T.a.v[i] = proj_strtod (endp, &endp); + if (HUGE_VAL==T.a.v[i]) { + n--; + T.a.v[i] = 0; + } + } + T.a = torad_if_needed (T.P, T.dir, T.a); + if (T.verbosity > 3) + printf ("# %s", args); + return 0; +} + + + +static int roundtrip (char *args) { + int ntrips; + double d, r, ans; + char *endp; + ans = proj_strtod (args, &endp); + ntrips = ans==HUGE_VAL? 100: fabs(ans); + d = proj_strtod (endp, &endp); + d = d==HUGE_VAL? T.tolerance: d / 1000; + 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, 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 deivation: %.3f mm, expected: %.3f mm\n", 1000*r, 1000*d); + } + T.op_ko++; + T.total_ko++; + } + return 0; +} + +static int expect (char *args) { + double d; + enum pj_io_units unit; + char *endp = 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 (endp, &endp); + if (HUGE_VAL==T.e.v[i]) { + T.nargs--; + T.e.v[i] = 0; + } + } + T.e = torad_if_needed (T.P, T.dir==PJ_FWD? PJ_INV:PJ_FWD, T.e); + + T.b = proj_trans_coord (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.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, 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); + else + d = proj_xyz_dist (T.b.xyz, T.e.xyz); + + if (d > T.tolerance) { + if (d > 10) + d = 9.999999; + if (T.verbosity > -1) { + if (0==T.op_ko && T.verbosity < 2) + banner (T.operation); + fprintf (T.fout, 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.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) { + int i = proj_atof (args); + + /* if -q/--quiet flag has been given, we do nothing */ + if (T.verbosity < 0) + return 0; + + if (strlen (args)) + T.verbosity = i; + else + T.verbosity++; + return 0; +} + +static int comment (char *args) { + (void) args; + return 0; +} + + +static int echo (char *args) { + fprintf (T.fout, "%s\n", args); + return 0; +} + + + +static int dispatch (char *cmnd, char *args) { + if (0==level%2) { + if (0==strcmp (cmnd, "BEGIN")) + level++; + return 0; + } + if (0==stricmp (cmnd, "OPERATION")) return operation (args); + if (0==stricmp (cmnd, "ACCEPT")) return accept (args); + if (0==stricmp (cmnd, "EXPECT")) return expect (args); + if (0==stricmp (cmnd, "ROUNDTRIP")) return roundtrip (args); + if (0==stricmp (cmnd, "BANNER")) return banner (args); + if (0==stricmp (cmnd, "VERBOSE")) return verbose (args); + if (0==stricmp (cmnd, "DIRECTION")) return direction (args); + if (0==stricmp (cmnd, "TOLERANCE")) return tolerance (args); + if (0==stricmp (cmnd, "ECHO")) return echo (args); + if (0==strcmp (cmnd, "END")) return finish_previous_operation (args), level++, 0; + if ('#'==cmnd[0]) return comment (args); + return 0; +} + + + + + + + + +static int errmsg (int errlev, char *msg, ...) { + va_list args; + va_start(args, msg); + vfprintf(stdout, msg, args); + va_end(args); + if (errlev) + errno = errlev; + return errlev; +} + +#define skipspace(f, c) \ + do { \ + while (isspace (c=fgetc(f)) && !feof(f)){ \ + if ('\n'==c) lineno++; \ + } \ + if (feof(f)) \ + break; \ + } while (ungetc(c, f), 0) + +#define skipline(f, c) \ + do { \ + while ((c=fgetc(f)) && !feof(f)) { \ + if ((c=='\r') || (c=='\n')) \ + break; \ + } \ + skipspace (f, c); \ + } while (0) + + +/* skip whitespace at continuation line */ +#define continuation(f, buf, c) \ + if ((c=='\r')||(c=='\n')) { \ + if (c=='\n') lineno++; \ + next--; \ + while (isspace (c=fgetc(f)) && !feof(f)); \ + } + +static int get_inp (FILE *f, char *inp, int size) { + char *next; + int c, esc; + char *endp = inp + size - 2; + + skipspace (f, c); + + for (c = esc = 0, next = inp; !feof(f); ) { + c = fgetc(f); + if (esc) { + continuation (f, next, c); + esc = 0; + /* handle escape sequences here */ + switch (c) { + case '\\': c = '\\'; break; + default: (void) c; + } + } + if (c=='\r') + break; + if (c=='\n') { + lineno++; + break; + } + + *next++ = c; + if ('\\'==c) + esc = 1; + if (feof(f) || (next==endp)) + break; + } + *(next) = 0; + return strlen(inp); +} + +static int get_cmnd (char *inp, char *cmnd, int len) { + cmnd[0] = 0; + while (isspace(*inp++)); + inp--; + while (len-- && !isspace(*inp) && *inp) + *cmnd++ = *inp++; + *cmnd = 0; + return len; +} + +static char *get_args (char *inp) { + char *args = inp; + while (isspace(*args++)) + if (0==*args) + return args; + while (!isspace(*++args)) + if (0==*args) + return args; + while (isspace(*args++)) + if (0==*args) + return args; + return --args; +} diff --git a/src/makefile.vc b/src/makefile.vc index ac5acf15..fdf03bd3 100644 --- a/src/makefile.vc +++ b/src/makefile.vc @@ -71,12 +71,15 @@ PROJEXE_OBJ = proj.obj gen_cheb.obj p_series.obj emess.obj CS2CSEXE_OBJ = cs2cs.obj gen_cheb.obj p_series.obj emess.obj GEODEXE_OBJ = geod.obj geod_set.obj geod_interface.obj emess.obj CCTEXE_OBJ = cct.obj proj_strtod.obj +GIEEXE_OBJ = gie.obj proj_strtod.obj + MULTISTRESSTEST_OBJ = multistresstest.obj PROJ_DLL = proj$(VERSION).dll PROJ_EXE = proj.exe CS2CS_EXE = cs2cs.exe GEOD_EXE = geod.exe CCT_EXE = cct.exe +GIE_EXE = gie.exe NAD2BIN_EXE = nad2bin.exe MULTISTRESSTEST_EXE = multistresstest.exe @@ -85,7 +88,7 @@ CFLAGS = /nologo -I. -DPROJ_LIB=\"$(PROJ_LIB_DIR)\" \ default: all -all: proj.lib $(PROJ_EXE) $(CS2CS_EXE) $(GEOD_EXE) $(CCT_EXE) $(NAD2BIN_EXE) +all: proj.lib $(PROJ_EXE) $(CS2CS_EXE) $(GEOD_EXE) $(CCT_EXE) $(GIE_EXE) $(NAD2BIN_EXE) proj.lib: $(LIBOBJ) if exist proj.lib del proj.lib @@ -114,6 +117,10 @@ $(CCT_EXE): $(CCTEXE_OBJ) $(EXE_PROJ) cl $(CCTEXE_OBJ) $(EXE_PROJ) if exist $(CCT_EXE).manifest mt -manifest $(CCT_EXE).manifest -outputresource:$(CCT_EXE);1 +$(GIE_EXE): $(GIEEXE_OBJ) $(EXE_PROJ) + cl $(GIEEXE_OBJ) $(EXE_PROJ) + if exist $(GIE_EXE).manifest mt -manifest $(GIE_EXE).manifest -outputresource:$(GIE_EXE);1 + $(NAD2BIN_EXE): nad2bin.obj emess.obj $(EXE_PROJ) cl nad2bin.obj emess.obj $(EXE_PROJ) diff --git a/src/optargpm.h b/src/optargpm.h index 6be2c9ef..4933cd2d 100644 --- a/src/optargpm.h +++ b/src/optargpm.h @@ -372,7 +372,8 @@ static int opt_ordinal (OPTARGS *opt, char *option) { } } - + /* kill some potential compiler warnings about unused functions */ + (void) opt_eof (0); return 0; } @@ -397,12 +398,23 @@ char *opt_arg (OPTARGS *opt, char *option) { return opt->optarg[ordinal]; } +char *opt_strip_path (char *full_name) { + char *last_path_delim, *stripped_name = full_name; + + last_path_delim = strrchr (stripped_name, '\\'); + if (last_path_delim > stripped_name) + stripped_name = last_path_delim + 1; + + last_path_delim = strrchr (stripped_name, '/'); + if (last_path_delim > stripped_name) + stripped_name = last_path_delim + 1; + return stripped_name; +} /* split command line options into options/flags ("-" style), projdefs ("+" style) and input file args */ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, const char **longflags, const char **longkeys) { int i, j; OPTARGS *o; - char *last_path_delim; o = (OPTARGS *) calloc (1, sizeof(OPTARGS)); if (0==o) @@ -410,14 +422,15 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, o->argc = argc; o->argv = argv; - o->progname = argv[0]; + o->progname = opt_strip_path (argv[0]); +/* o->progname = argv[0]; last_path_delim = strrchr (argv[0], '\\'); if (last_path_delim > o->progname) o->progname = last_path_delim; last_path_delim = strrchr (argv[0], '/'); if (last_path_delim > o->progname) o->progname = last_path_delim; - +*/ /* Reset all flags */ for (i = 0; i < (int) strlen (flags); i++) diff --git a/src/proj_strtod.c b/src/proj_strtod.c index e9942e5c..c771f2a6 100644 --- a/src/proj_strtod.c +++ b/src/proj_strtod.c @@ -86,6 +86,7 @@ Thomas Knudsen, thokn@sdfe.dk, 2017-01-17/2017-09-18 ***********************************************************************/ +#include /* for strchr */ #include #include #include /* for HUGE_VAL */ @@ -96,14 +97,16 @@ double proj_atof(const char *str); double proj_strtod(const char *str, char **endptr) { - double number = 0; + double number = 0, integral_part = 0; int exponent = 0; + int fraction_is_nonzero = 0; int sign = 0; char *p = (char *) str; int n = 0; - int num_digits_total = 0; - int num_digits_after_comma = 0; - + int num_digits_total = 0; + int num_digits_after_comma = 0; + int num_prefixed_zeros = 0; + if (0==str) { errno = EFAULT; if (endptr) @@ -123,10 +126,10 @@ double proj_strtod(const char *str, char **endptr) { return HUGE_VAL; } - /* Then handle optional prefixed sign */ + /* Then handle optional prefixed sign and skip prefix zeros */ switch (*p) { case '-': - sign = -1, p++; break; + sign = -1, p++; break; case '+': sign = 1, p++; break; default: @@ -137,7 +140,11 @@ double proj_strtod(const char *str, char **endptr) { errno = EINVAL; return HUGE_VAL; } - + + /* skip prefixed zeros */ + while ('0'==*p || '_'==*p) + p++; + /* Now expect a (potentially zero-length) string of digits */ while (isdigit(*p) || ('_'==*p)) { if ('_'==*p) { @@ -148,23 +155,45 @@ double proj_strtod(const char *str, char **endptr) { p++; num_digits_total++; } - + integral_part = number; + /* Do we have a fractional part? */ if ('.'==*p) { p++; + + /* keep on skipping prefixed zeros (i.e. allow writing 1e-20 */ + /* as 0.00000000000000000001 without losing precision) */ + if (0==integral_part) + while ('0'==*p || '_'==*p) { + if ('0'==*p) + num_prefixed_zeros++; + p++; + } + /* if the next character is nonnumeric, we have reached the end */ + if (0==strchr ("0123456789eE+-", *p)) + return integral_part; + while (isdigit(*p) || '_'==*p) { - if ('_'==*p) { + /* Don't let pathologically long fractions destroy precision */ + if ('_'==*p || num_digits_total > 17) { p++; continue; } + number = number * 10. + (*p - '0'); + if (*p!='0') + fraction_is_nonzero = 1; p++; num_digits_total++; num_digits_after_comma++; } - exponent = -num_digits_after_comma; + /* Avoid having long zero-tails (4321.000...000) destroy precision */ + if (fraction_is_nonzero) + exponent = -(num_digits_after_comma + num_prefixed_zeros); + else + number = integral_part; } /* non-digit */ @@ -221,8 +250,11 @@ double proj_strtod(const char *str, char **endptr) { return HUGE_VAL; } - number *= pow (10, exponent); + /* on some platforms pow() is very slow - so don't call it if exponent==0 */ + if (exponent) + number *= pow (10, exponent); + /* Did we run into an infinity? */ if (fabs(number) > DBL_MAX) errno = ERANGE; -- cgit v1.2.3 From f1e12f6bd6c12f08caee2cca15f34aec14f4615b Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Tue, 10 Oct 2017 15:56:42 +0200 Subject: remove trailing whitespace Add missing prototype for opt_strip_path() A bunch of minor oops cleanups Remove unused functiion cloumn() Fighting the good fight trying to be *both* POSIX *and* Windows compatible A few more improvements: 2 missing casts and a potentially uninitialized variable --- src/gie.c | 118 +++++++++++++++++++++++++----------------------------- src/optargpm.h | 33 +++++++-------- src/proj_strtod.c | 14 +++---- 3 files changed, 78 insertions(+), 87 deletions(-) (limited to 'src') diff --git a/src/gie.c b/src/gie.c index adfc4e0f..91af00b9 100644 --- a/src/gie.c +++ b/src/gie.c @@ -124,15 +124,14 @@ Thomas Knudsen, thokn@sdfe.dk, 2017-10-01/2017-10-08 double proj_strtod(const char *str, char **endptr); double proj_atof(const char *str); -static char *column (char *buf, int n); int main(int argc, char **argv); -static int process_file (char *fname); +static int process_file (char *fname); static int errmsg (int errlev, char *msg, ...); static int get_inp (FILE *f, char *inp, int size); static int get_cmnd (char *inp, char *cmnd, int len); static char *get_args (char *inp); -static int dispatch (char *cmnd, char *args); +static int dispatch (char *cmnd, char *args); @@ -198,14 +197,14 @@ static const char usage[] = { " gie -vvvv corner-cases.gie\n" "2. Run all tests in files \"foo\" and \"bar\", providing info on failures only\n" " gie foo bar\n" - "--------------------------------------------------------------------------------\n" + "--------------------------------------------------------------------------------\n" }; int main (int argc, char **argv) { int i; const char *longflags[] = {"v=verbose", "q=quiet", "h=help", 0}; const char *longkeys[] = {"o=output", 0}; - + o = opt_parse (argc, argv, "hvq", "o", longflags, longkeys); if (0==o) return 0; @@ -215,7 +214,7 @@ int main (int argc, char **argv) { return 0; } - + T.verbosity = opt_given (o, "q"); if (T.verbosity) @@ -245,7 +244,7 @@ int main (int argc, char **argv) { if (T.verbosity > 0) { if (o->fargc > 1) fprintf (T.fout, "%sGrand total: %d. Success: %d, Failure: %d\n", delim, T.grand_ok+T.grand_ko, T.grand_ok, T.grand_ko); - printf (delim); + fprintf (T.fout, "%s", delim); } else if (T.grand_ko) @@ -261,7 +260,7 @@ int main (int argc, char **argv) { - + static int process_file (char *fname) { FILE *f; char inp[CMDLEN]; @@ -294,7 +293,7 @@ static int process_file (char *fname) { proj_destroy (T.P); T.P = 0; return 0; - + } args = get_args (inp); if (SKIP==dispatch (cmnd, args)) @@ -306,7 +305,7 @@ static int process_file (char *fname) { T.grand_ko += T.total_ko; if (T.verbosity > 0) fprintf (T.fout, "%stotal: %2d tests succeeded, %2d tests %s\n", delim, T.total_ok, T.total_ko, T.total_ko? "FAILED!": "failed."); - + if (level==0) return errmsg (-3, "File '%s':Missing 'BEGIN' cmnd - bye!\n", fname); if (level && level%2) @@ -319,25 +318,6 @@ static int process_file (char *fname) { -/* return a pointer to the n'th column of buf or a pointer to the terminating 0 if less than n */ -static char *column (char *buf, int n) { - int i; - if (n <= 0) - return buf; - for (i = 0; i < n; i++) { - while (isspace(*buf)) - buf++; - if (i == n - 1) - break; - while ((0 != *buf) && !isspace(*buf)) - buf++; - } - return buf; -} - - - - static int banner (char *args) { char dots[] = {"..."}, nodots[] = {""}, *thedots = nodots; if (T.total_ko > 0 && T.op_ko==0) @@ -399,7 +379,7 @@ static int direction (char *args) { T.dir = PJ_INV; break; default: - return 1; + return 1; } return 0; } @@ -407,9 +387,10 @@ static int direction (char *args) { -static void finish_previous_operation () { +static void finish_previous_operation (char *args) { if (T.verbosity > 1 && T.op_id > 1 && T.op_ok+T.op_ko) fprintf (T.fout, "%s %d tests succeeded, %d tests %s\n", delim, T.op_ok, T.op_ko, T.op_ko? "FAILED!": "failed."); + (void) args; } static int operation (char *args) { @@ -423,10 +404,10 @@ static int operation (char *args) { printf ("%d\n", (int) tol_lineno); */ T.op_ok = 0; T.op_ko = 0; - + direction ("forward"); tolerance ("0.5"); - + if (T.P) proj_destroy (T.P); T.P = proj_create (0, args); @@ -443,11 +424,11 @@ static PJ_COORD torad_if_needed (PJ *P, PJ_DIRECTION dir, PJ_COORD a) { u = P->right; if (u==PJ_IO_UNITS_CLASSIC || u==PJ_IO_UNITS_METERS) return a; - - if (u==PJ_IO_UNITS_RADIANS) { - c.lpz.lam = proj_torad (T.a.lpz.lam); - c.lpz.phi = proj_torad (T.a.lpz.phi); - } + + 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]; return c; } @@ -478,15 +459,15 @@ static int roundtrip (char *args) { double d, r, ans; char *endp; ans = proj_strtod (args, &endp); - ntrips = ans==HUGE_VAL? 100: fabs(ans); + ntrips = (int) (ans==HUGE_VAL? 100: fabs(ans)); d = proj_strtod (endp, &endp); d = d==HUGE_VAL? T.tolerance: d / 1000; 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, T.op_ko? " -----\n": delim); + 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 deivation: %.3f mm, expected: %.3f mm\n", 1000*r, 1000*d); } @@ -513,17 +494,17 @@ static int expect (char *args) { } } T.e = torad_if_needed (T.P, T.dir==PJ_FWD? PJ_INV:PJ_FWD, T.e); - + T.b = proj_trans_coord (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.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, T.op_ko? " -----\n": delim); + 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; @@ -544,8 +525,8 @@ static int expect (char *args) { if (T.verbosity > -1) { if (0==T.op_ko && T.verbosity < 2) banner (T.operation); - fprintf (T.fout, T.op_ko? " -----\n": delim); - + 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); @@ -572,7 +553,7 @@ static int expect (char *args) { static int verbose (char *args) { - int i = proj_atof (args); + int i = (int) proj_atof (args); /* if -q/--quiet flag has been given, we do nothing */ if (T.verbosity < 0) @@ -604,17 +585,26 @@ static int dispatch (char *cmnd, char *args) { level++; return 0; } - if (0==stricmp (cmnd, "OPERATION")) return operation (args); - if (0==stricmp (cmnd, "ACCEPT")) return accept (args); - if (0==stricmp (cmnd, "EXPECT")) return expect (args); - if (0==stricmp (cmnd, "ROUNDTRIP")) return roundtrip (args); - if (0==stricmp (cmnd, "BANNER")) return banner (args); - if (0==stricmp (cmnd, "VERBOSE")) return verbose (args); - if (0==stricmp (cmnd, "DIRECTION")) return direction (args); - if (0==stricmp (cmnd, "TOLERANCE")) return tolerance (args); - if (0==stricmp (cmnd, "ECHO")) return echo (args); - if (0==strcmp (cmnd, "END")) return finish_previous_operation (args), level++, 0; - if ('#'==cmnd[0]) return comment (args); + if (0==strcmp (cmnd, "OPERATION")) return operation (args); + if (0==strcmp (cmnd, "operation")) return operation (args); + if (0==strcmp (cmnd, "ACCEPT")) return accept (args); + if (0==strcmp (cmnd, "accept")) return accept (args); + if (0==strcmp (cmnd, "EXPECT")) return expect (args); + if (0==strcmp (cmnd, "expect")) return expect (args); + if (0==strcmp (cmnd, "ROUNDTRIP")) return roundtrip (args); + if (0==strcmp (cmnd, "roundtrip")) return roundtrip (args); + if (0==strcmp (cmnd, "BANNER")) return banner (args); + if (0==strcmp (cmnd, "banner")) return banner (args); + if (0==strcmp (cmnd, "VERBOSE")) return verbose (args); + if (0==strcmp (cmnd, "verbose")) return verbose (args); + if (0==strcmp (cmnd, "DIRECTION")) return direction (args); + if (0==strcmp (cmnd, "direction")) return direction (args); + if (0==strcmp (cmnd, "TOLERANCE")) return tolerance (args); + if (0==strcmp (cmnd, "tolerance")) return tolerance (args); + if (0==strcmp (cmnd, "ECHO")) return echo (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); return 0; } @@ -661,10 +651,10 @@ static int errmsg (int errlev, char *msg, ...) { next--; \ while (isspace (c=fgetc(f)) && !feof(f)); \ } - + static int get_inp (FILE *f, char *inp, int size) { char *next; - int c, esc; + int c = 0, esc; char *endp = inp + size - 2; skipspace (f, c); @@ -686,15 +676,15 @@ static int get_inp (FILE *f, char *inp, int size) { lineno++; break; } - - *next++ = c; + + *next++ = (char) c; if ('\\'==c) esc = 1; if (feof(f) || (next==endp)) break; } *(next) = 0; - return strlen(inp); + return (int) strlen(inp); } static int get_cmnd (char *inp, char *cmnd, int len) { diff --git a/src/optargpm.h b/src/optargpm.h index 4933cd2d..c47dfec1 100644 --- a/src/optargpm.h +++ b/src/optargpm.h @@ -1,6 +1,6 @@ /*********************************************************************** - OPTARGPM - a header-only library for decoding + OPTARGPM - a header-only library for decoding PROJ.4 style command line options Thomas Knudsen, 2017-09-10 @@ -18,7 +18,7 @@ this is an attempt to catch up and chop the ketchup. Since optargpm (for "optarg plus minus") does not belong, in any obvious way, in any systems development library, it is provided as -a "header only" library. +a "header only" library. While this is conventional in C++, it is frowned at in plain C. But frown away - "header only" has its places, and this is one of @@ -56,7 +56,7 @@ Supporting a wide range of option syntax, the getoptpm API is somewhat quirky, but also compact, consisting of one data type, 3(+2) functions, and one enumeration: -OPTARGS +OPTARGS Housekeeping data type. An instance of OPTARGS is conventionally called o or opt opt_parse (opt, argc, argv ...): @@ -105,7 +105,7 @@ int main(int argc, char **argv) { FILE *out = stdout; char *longflags[] = {"v=verbose", "h=help", 0}; char *longkeys[] = {"o=output", "hello", 0}; - + o = opt_parse (argc, argv, "hv", "o", longflags, longkeys); if (0==o) return 0; @@ -116,7 +116,7 @@ int main(int argc, char **argv) { exit (0); } - if (opt_given (o, "v")) + if (opt_given (o, "v")) puts ("Feeling chatty today?"); if (opt_given (o, "hello")) { @@ -126,8 +126,8 @@ int main(int argc, char **argv) { if (opt_given (o, "o")) out = fopen (opt_arg (o, "output"), "rt"); // Note: "output" translates to "o" internally - - // Setup transformation + + // Setup transformation P = proj_create_argv (0, o->pargc, o->pargv); // Loop over all lines of all input files @@ -207,6 +207,7 @@ static int opt_raise_flag (OPTARGS *opt, int ordinal); static int opt_ordinal (OPTARGS *opt, char *option); int opt_given (OPTARGS *opt, char *option); char *opt_arg (OPTARGS *opt, char *option); +char *opt_strip_path (char *full_name); OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, const char **longflags, const char **longkeys); #define opt_eof_handler(opt) if (opt_eof (opt)) {continue;} else {;} @@ -223,7 +224,7 @@ struct OPTARGS { char *optarg[256]; /* optarg[(int) 'f'] holds a pointer to the argument of option "-f" */ char *flags; /* a list of flag style options supported, e.g. "hv" (help and verbose) */ char *keys; /* a list of key/value style options supported, e.g. "o" (output) */ - const char **longflags; /* long flags, {"help", "verbose"}, or {"h=help", "v=verbose"}, to indicate homologous short options */ + const char **longflags; /* long flags, {"help", "verbose"}, or {"h=help", "v=verbose"}, to indicate homologous short options */ const char **longkeys; /* e.g. {"output"} or {o=output"} to support --output=/path/to/output-file. In the latter case, */ /* all operations on "--output" gets redirected to "-o", so user code need handle arguments to "-o" only */ }; @@ -264,7 +265,7 @@ int opt_input_loop (OPTARGS *opt, int binary) { } opt->record_index = 0; - + /* no input files specified - read from stdin */ if ((0==opt->fargc) && (0==opt->input)) { opt->input = stdin; @@ -415,7 +416,7 @@ char *opt_strip_path (char *full_name) { OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, const char **longflags, const char **longkeys) { int i, j; OPTARGS *o; - + o = (OPTARGS *) calloc (1, sizeof(OPTARGS)); if (0==o) return 0; @@ -430,7 +431,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, last_path_delim = strrchr (argv[0], '/'); if (last_path_delim > o->progname) o->progname = last_path_delim; -*/ +*/ /* Reset all flags */ for (i = 0; i < (int) strlen (flags); i++) @@ -439,7 +440,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, /* Flag args for all argument taking options as "unset" */ for (i = 0; i < (int) strlen (keys); i++) o->optarg[(int) keys[i]] = argv[0]; - + /* Hence, undefined/illegal options have an argument of 0 */ /* long opts are handled similarly, but are mapped to the high bit character range (above 128) */ @@ -457,7 +458,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, if (0==strchr (flags, longflags[i][0])) { fprintf (stderr, "%s: Invalid alias - '%s'. Valid short flags are '%s'\n", o->progname, longflags[i], flags); free (o); - return 0; + return 0; } } for (i = 0; longkeys && longkeys[i]; i++) { @@ -469,7 +470,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, if (0==strchr (keys, longkeys[i][0])) { fprintf (stderr, "%s: Invalid alias - '%s'. Valid short flags are '%s'\n", o->progname, longkeys[i], keys); free (o); - return 0; + return 0; } } @@ -514,7 +515,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, char cstring[2], *crepr = cstring; cstring[0] = (char) c; cstring[1] = 0; - + /* Long style flags and options (--long_opt_name, --long_opt_namr arg, --long_opt_name=arg) */ if (c== (int)'-') { @@ -537,7 +538,7 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, o->optarg[c] = equals + 1; break; } - + /* "outline" --foo bar style arg */ if (!opt_is_flag (o, c)) { if ((argc==i + 1) || ('+'==argv[i+1][0]) || ('-'==argv[i+1][0])) diff --git a/src/proj_strtod.c b/src/proj_strtod.c index c771f2a6..aa2211f5 100644 --- a/src/proj_strtod.c +++ b/src/proj_strtod.c @@ -94,7 +94,7 @@ Thomas Knudsen, thokn@sdfe.dk, 2017-01-17/2017-09-18 double proj_strtod(const char *str, char **endptr); double proj_atof(const char *str); - + double proj_strtod(const char *str, char **endptr) { double number = 0, integral_part = 0; @@ -106,7 +106,7 @@ double proj_strtod(const char *str, char **endptr) { int num_digits_total = 0; int num_digits_after_comma = 0; int num_prefixed_zeros = 0; - + if (0==str) { errno = EFAULT; if (endptr) @@ -140,11 +140,11 @@ double proj_strtod(const char *str, char **endptr) { errno = EINVAL; return HUGE_VAL; } - + /* skip prefixed zeros */ while ('0'==*p || '_'==*p) p++; - + /* Now expect a (potentially zero-length) string of digits */ while (isdigit(*p) || ('_'==*p)) { if ('_'==*p) { @@ -156,11 +156,11 @@ double proj_strtod(const char *str, char **endptr) { num_digits_total++; } integral_part = number; - + /* Do we have a fractional part? */ if ('.'==*p) { p++; - + /* keep on skipping prefixed zeros (i.e. allow writing 1e-20 */ /* as 0.00000000000000000001 without losing precision) */ if (0==integral_part) @@ -173,7 +173,7 @@ double proj_strtod(const char *str, char **endptr) { /* if the next character is nonnumeric, we have reached the end */ if (0==strchr ("0123456789eE+-", *p)) return integral_part; - + while (isdigit(*p) || '_'==*p) { /* Don't let pathologically long fractions destroy precision */ if ('_'==*p || num_digits_total > 17) { -- cgit v1.2.3 From 48bfa6121fd19718b93d9ed9e09ddaed0739fadf Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Wed, 11 Oct 2017 18:13:35 +0200 Subject: Run 'gie builtins.gie' as part of Travis CI jobs Touch up configuration files to support gie --- src/Makefile.am | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 1a1f3270..a039151d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,6 +1,6 @@ AM_CFLAGS = @C_WFLAGS@ -bin_PROGRAMS = proj nad2bin geod cs2cs cct +bin_PROGRAMS = proj nad2bin geod cs2cs gie cct EXTRA_PROGRAMS = multistresstest test228 TESTS = geodtest -- cgit v1.2.3 From 5f0e700b01a15d523b34fb278c41236f5dc84f66 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Thu, 12 Oct 2017 20:07:03 +0200 Subject: Resolve OSS-Fuzz issue 3619, https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3619 credit to OSS-Fuzz --- src/PJ_eqdc.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/PJ_eqdc.c b/src/PJ_eqdc.c index 6b3449f7..cb7e7f10 100644 --- a/src/PJ_eqdc.c +++ b/src/PJ_eqdc.c @@ -93,7 +93,7 @@ PJ *PROJECTION(eqdc) { Q->phi2 = pj_param(P->ctx, P->params, "rlat_2").f; if (fabs(Q->phi1 + Q->phi2) < EPS10) - pj_default_destructor (P, PJD_ERR_CONIC_LAT_EQUAL); + return pj_default_destructor (P, PJD_ERR_CONIC_LAT_EQUAL); if (!(Q->en = pj_enfn(P->es))) return pj_default_destructor(P, ENOMEM); -- cgit v1.2.3 From f6966b8d5ecef5474ceadd099975467ada140c57 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Thu, 12 Oct 2017 20:39:41 +0200 Subject: Resolve OSS-Fuzz issue 3620 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3620 Credit to OSS-Fuzz --- src/PJ_pipeline.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index d1ddf65f..137fdec8 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -269,15 +269,18 @@ static void *destructor (PJ *P, int errlev) { if (0==P->opaque) return pj_default_destructor (P, errlev); - for (i = 0; i < P->opaque->steps; i++) - P->opaque->pipeline[i+1]->destructor (P->opaque->pipeline[i+1], errlev); + /* Deallocate each pipeine step, then pipeline array */ + if (0!=P->opaque->pipeline) + for (i = 0; i < P->opaque->steps; i++) + if (0!=P->opaque->pipeline[i+1]) + P->opaque->pipeline[i+1]->destructor (P->opaque->pipeline[i+1], errlev); + pj_dealloc (P->opaque->pipeline); pj_dealloc (P->opaque->reverse_step); pj_dealloc (P->opaque->omit_forward); pj_dealloc (P->opaque->omit_inverse); pj_dealloc (P->opaque->argv); pj_dealloc (P->opaque->current_argv); - pj_dealloc (P->opaque->pipeline); return pj_default_destructor(P, errlev); } -- cgit v1.2.3 From b6e37b99b1f7d07de691f428e8d04dbd5f8b3caa Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Thu, 12 Oct 2017 20:58:47 +0200 Subject: Remove first batch of internal self tests, now moved to builtins.gie: All projections starting with "a". Replace with stubs returning 10000. The two PJ_apply_?gridhift.c files have not been touched --- src/PJ_aea.c | 116 +------------------------------------------------------- src/PJ_aeqd.c | 59 +--------------------------- src/PJ_airy.c | 29 +------------- src/PJ_aitoff.c | 93 +-------------------------------------------- src/PJ_august.c | 28 -------------- 5 files changed, 5 insertions(+), 320 deletions(-) (limited to 'src') diff --git a/src/PJ_aea.c b/src/PJ_aea.c index 228d3afd..5e8e3333 100644 --- a/src/PJ_aea.c +++ b/src/PJ_aea.c @@ -218,119 +218,5 @@ PJ *PROJECTION(leac) { } -#ifndef PJ_SELFTEST -int pj_aea_selftest (void) {return 10000;} -#else - -int pj_aea_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=aea +ellps=GRS80 +lat_1=0 +lat_2=2"}; - char s_args[] = {"+proj=aea +R=6400000 +lat_1=0 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {222571.60875710563, 110653.32674302977}, - {222706.30650839131, -110484.26714439997}, - {-222571.60875710563, 110653.32674302977}, - {-222706.30650839131, -110484.26714439997}, - }; - - XY s_fwd_expect[] = { - {223334.08517088494, 111780.43188447191}, - {223470.15499168713, -111610.33943099028}, - {-223334.08517088494, 111780.43188447191}, - {-223470.15499168713, -111610.33943099028}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0017966310597749514, 0.00090436885862202158}, - {0.0017966300767030448, -0.00090437009538581453}, - {-0.0017966310597749514, 0.00090436885862202158}, - {-0.0017966300767030448, -0.00090437009538581453}, - }; - - LP s_inv_expect[] = { - {0.0017904935979658752, 0.00089524594491375306}, - {0.0017904926216016812, -0.00089524716502493225}, - {-0.0017904935979658752, 0.00089524594491375306}, - {-0.0017904926216016812, -0.00089524716502493225}, - }; - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif - - - -#ifndef PJ_SELFTEST +int pj_aea_selftest (void) {return 10000;} int pj_leac_selftest (void) {return 10000;} -#else - -int pj_leac_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=leac +ellps=GRS80 +lat_1=0 +lat_2=2"}; - char s_args[] = {"+proj=leac +R=6400000 +lat_1=0 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {220685.14054297868, 112983.50088939646}, - {224553.31227982609, -108128.63674487274}, - {-220685.14054297868, 112983.50088939646}, - {-224553.31227982609, -108128.63674487274}, - }; - - XY s_fwd_expect[] = { - {221432.86859285168, 114119.45452653214}, - {225331.72412711097, -109245.82943505641}, - {-221432.86859285168, 114119.45452653214}, - {-225331.72412711097, -109245.82943505641}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0017966446840328458, 0.00090435171340223211}, - {0.0017966164523713021, -0.00090438724081843625}, - {-0.0017966446840328458, 0.00090435171340223211}, - {-0.0017966164523713021, -0.00090438724081843625}, - }; - - LP s_inv_expect[] = { - {0.0017905070979748127, 0.00089522906964877795}, - {0.001790479121519977, -0.00089526404022281043}, - {-0.0017905070979748127, 0.00089522906964877795}, - {-0.001790479121519977, -0.00089526404022281043}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} -#endif diff --git a/src/PJ_aeqd.c b/src/PJ_aeqd.c index c6fa9e06..f0c813f5 100644 --- a/src/PJ_aeqd.c +++ b/src/PJ_aeqd.c @@ -318,61 +318,4 @@ PJ *PROJECTION(aeqd) { } -#ifndef PJ_SELFTEST -int pj_aeqd_selftest (void) {return 0;} -#else - -int pj_aeqd_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=aeqd +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=aeqd +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222616.522190051648, 110596.996549550197}, - { 222616.522190051648, -110596.996549550211}, - {-222616.522190051648, 110596.996549550197}, - {-222616.522190051648, -110596.996549550211}, - }; - - XY s_fwd_expect[] = { - { 223379.456047271, 111723.757570854126}, - { 223379.456047271, -111723.757570854126}, - {-223379.456047271, 111723.757570854126}, - {-223379.456047271, -111723.757570854126}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.00179663056838724787, 0.000904369476930248902}, - { 0.00179663056838724787, -0.000904369476930248469}, - {-0.00179663056838724787, 0.000904369476930248902}, - {-0.00179663056838724787, -0.000904369476930248469}, - }; - - LP s_inv_expect[] = { - { 0.00179049310992953335, 0.000895246554746200623}, - { 0.00179049310992953335, -0.000895246554746200623}, - {-0.00179049310992953335, 0.000895246554746200623}, - {-0.00179049310992953335, -0.000895246554746200623}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_aeqd_selftest (void) {return 10000;} diff --git a/src/PJ_airy.c b/src/PJ_airy.c index d832b9b7..a5ee1f24 100644 --- a/src/PJ_airy.c +++ b/src/PJ_airy.c @@ -147,31 +147,4 @@ PJ *PROJECTION(airy) { } -#ifndef PJ_SELFTEST -int pj_airy_selftest (void) {return 0;} -#else - -int pj_airy_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=airy +a=6400000 +lat_1=0 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 189109.88690862127, 94583.752387504152}, - { 189109.88690862127, -94583.752387504152}, - {-189109.88690862127, 94583.752387504152}, - {-189109.88690862127, -94583.752387504152}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 0, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - -#endif +int pj_airy_selftest (void) {return 10000;} diff --git a/src/PJ_aitoff.c b/src/PJ_aitoff.c index 3455fa71..8e9201d0 100644 --- a/src/PJ_aitoff.c +++ b/src/PJ_aitoff.c @@ -189,94 +189,5 @@ PJ *PROJECTION(wintri) { } -#ifndef PJ_SELFTEST -int pj_aitoff_selftest (void) {return 0;} -#else - -int pj_aitoff_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=aitoff +R=6400000 +lat_1=0 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - - XY s_fwd_expect[] = { - {223379.45881169615, 111706.74288385305}, - {223379.45881169615, -111706.74288385305}, - {-223379.45881169615, 111706.74288385305}, - {-223379.45881169615, -111706.74288385305}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - - LP s_inv_expect[] = { - {0.0017904931100388164, 0.00089524655491012516}, - {0.0017904931100388164, -0.00089524655491012516}, - {-0.0017904931100388164, 0.00089524655491012516}, - {-0.0017904931100388164, -0.00089524655491012516}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif - - - -#ifndef PJ_SELFTEST -int pj_wintri_selftest (void) {return 0;} -#else - -int pj_wintri_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=wintri +a=6400000 +lat_1=0 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {223390.80153348515, 111703.90750574505}, - {223390.80153348515, -111703.90750574505}, - {-223390.80153348515, 111703.90750574505}, - {-223390.80153348515, -111703.90750574505}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {0.0017904931099113196, 0.00089524655490101819}, - {0.0017904931099113196, -0.00089524655490101819}, - {-0.0017904931099113196, 0.00089524655490101819}, - {-0.0017904931099113196, -0.00089524655490101819}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_aitoff_selftest (void) {return 10000;} +int pj_wintri_selftest (void) {return 10000;} diff --git a/src/PJ_august.c b/src/PJ_august.c index d81644bf..c437ca2f 100644 --- a/src/PJ_august.c +++ b/src/PJ_august.c @@ -31,32 +31,4 @@ PJ *PROJECTION(august) { return P; } -#ifndef PJ_SELFTEST int pj_august_selftest (void) {return 0;} -#else - -int pj_august_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=august +a=6400000 +lat_1=0 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {223404.97818097242, 111722.34028976287}, - {223404.97818097242, -111722.34028976287}, - {-223404.97818097242, 111722.34028976287}, - {-223404.97818097242, -111722.34028976287}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif -- cgit v1.2.3 From 1b1d3bd77237ac574e3d5c8f4c3cc50bdadac76a Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Fri, 13 Oct 2017 11:40:56 +0200 Subject: OSS-Fuzz issue 3630: Missing return in PJ_lsat.c Resolves https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3630 Credit to OSS-Fuzz --- src/PJ_lsat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/PJ_lsat.c b/src/PJ_lsat.c index 1b3778d6..7319bee7 100644 --- a/src/PJ_lsat.c +++ b/src/PJ_lsat.c @@ -163,7 +163,7 @@ PJ *PROJECTION(lsat) { path = pj_param(P->ctx, P->params, "ipath").i; if (path <= 0 || path > (land <= 3 ? 251 : 233)) - pj_default_destructor(P, PJD_ERR_PATH_NOT_IN_RANGE); + return pj_default_destructor(P, PJD_ERR_PATH_NOT_IN_RANGE); if (land <= 3) { P->lam0 = DEG_TO_RAD * 128.87 - M_TWOPI / 251. * path; -- cgit v1.2.3 From 3ef083767eaf975399243246605fddc40cc097f9 Mon Sep 17 00:00:00 2001 From: Aaron Puchert Date: Thu, 19 Oct 2017 14:04:35 +0200 Subject: Prevent crashes and leaks on allocation failure (#606) * Prevent crashes and leaks on allocation failure Memory allocation can fail. We need to gracefully handle this case and prevent dereferencing null pointers. * Make NULL checks consistent within a file * Properly report allocation errors * Improve cleanup in pj_gc_reader.c * Implement pj_strdup and use instead of strdup The function strdup is not part of ANSI C 89, but a POSIX extension. Therefore we can not rely on it being available on all platforms. --- src/PJ_bonne.c | 2 ++ src/PJ_healpix.c | 4 ++++ src/PJ_laea.c | 2 ++ src/bch2bps.c | 20 ++++++++++++++++---- src/geod_set.c | 4 ++++ src/mk_cheby.c | 34 +++++++++++++++++++++------------- src/pj_datum_set.c | 7 ++++++- src/pj_fileapi.c | 8 ++++++++ src/pj_gc_reader.c | 31 ++++++++++++++++++++++++++++--- src/pj_gridinfo.c | 8 ++++---- src/pj_init.c | 6 ++++++ src/pj_malloc.c | 10 ++++++++++ src/pj_pr_list.c | 14 +++++++++++--- src/pj_strtod.c | 4 ++-- src/proj_api.h | 1 + src/projects.h | 1 - 16 files changed, 125 insertions(+), 31 deletions(-) (limited to 'src') diff --git a/src/PJ_bonne.c b/src/PJ_bonne.c index 368829c5..711e234f 100644 --- a/src/PJ_bonne.c +++ b/src/PJ_bonne.c @@ -111,6 +111,8 @@ PJ *PROJECTION(bonne) { if (P->es != 0.0) { Q->en = pj_enfn(P->es); + if (0==Q->en) + return destructor(P, ENOMEM); Q->m1 = pj_mlfn(Q->phi1, Q->am1 = sin(Q->phi1), c = cos(Q->phi1), Q->en); Q->am1 = c / (sqrt(1. - P->es * Q->am1 * Q->am1) * Q->am1); diff --git a/src/PJ_healpix.c b/src/PJ_healpix.c index 241d7ef4..438cb595 100644 --- a/src/PJ_healpix.c +++ b/src/PJ_healpix.c @@ -620,6 +620,8 @@ PJ *PROJECTION(healpix) { if (P->es != 0.0) { Q->apa = pj_authset(P->es); /* For auth_lat(). */ + if (0==Q->apa) + return destructor(P, ENOMEM); Q->qp = pj_qsfn(1.0, P->e, P->one_es); /* For auth_lat(). */ P->a = P->a*sqrt(0.5*Q->qp); /* Set P->a to authalic radius. */ P->ra = 1.0/P->a; @@ -651,6 +653,8 @@ PJ *PROJECTION(rhealpix) { return destructor (P, PJD_ERR_AXIS); if (P->es != 0.0) { Q->apa = pj_authset(P->es); /* For auth_lat(). */ + if (0==Q->apa) + return destructor(P, ENOMEM); Q->qp = pj_qsfn(1.0, P->e, P->one_es); /* For auth_lat(). */ P->a = P->a*sqrt(0.5*Q->qp); /* Set P->a to authalic radius. */ P->ra = 1.0/P->a; diff --git a/src/PJ_laea.c b/src/PJ_laea.c index ddca63d9..270b8dc8 100644 --- a/src/PJ_laea.c +++ b/src/PJ_laea.c @@ -255,6 +255,8 @@ PJ *PROJECTION(laea) { Q->qp = pj_qsfn(1., P->e, P->one_es); Q->mmf = .5 / (1. - P->es); Q->apa = pj_authset(P->es); + if (0==Q->apa) + return destructor(P, ENOMEM); switch (Q->mode) { case N_POLE: case S_POLE: diff --git a/src/bch2bps.c b/src/bch2bps.c index 68a4737d..c0a357c1 100644 --- a/src/bch2bps.c +++ b/src/bch2bps.c @@ -30,12 +30,14 @@ dadd(projUV *a, projUV *b, double m, int n) { a++->v -= m * b++->v; } } - static void /* convert row to pover series */ + static int /* convert row to power series */ rows(projUV *c, projUV *d, int n) { projUV sv, *dd; int j, k; dd = (projUV *)vector1(n-1, sizeof(projUV)); + if (!dd) + return 0; sv.u = sv.v = 0.; for (j = 0; j < n; ++j) d[j] = dd[j] = sv; d[0] = c[n-1]; @@ -58,14 +60,21 @@ rows(projUV *c, projUV *d, int n) { d[0].u = -dd[0].u + .5 * c[0].u; d[0].v = -dd[0].v + .5 * c[0].v; pj_dalloc(dd); + return 1; } - static void /* convert columns to power series */ + static int /* convert columns to power series */ cols(projUV **c, projUV **d, int nu, int nv) { projUV *sv, **dd; int j, k; dd = (projUV **)vector2(nu, nv, sizeof(projUV)); + if (!dd) + return 0; sv = (projUV *)vector1(nv, sizeof(projUV)); + if (!sv) { + freev2((void **)dd, nu); + return 0; + } bclear(d, nu, nv); bclear(dd, nu, nv); bmove(d[0], c[nu-1], nv); @@ -84,6 +93,7 @@ cols(projUV **c, projUV **d, int nu, int nv) { submop(d[0], .5, c[0], dd[0], nv); freev2((void **) dd, nu); pj_dalloc(sv); + return 1; } static void /* row adjust for range -1 to 1 to a to b */ rowshft(double a, double b, projUV *d, int n) { @@ -129,11 +139,13 @@ bch2bps(projUV a, projUV b, projUV **c, int nu, int nv) { return 0; /* do rows to power series */ for (i = 0; i < nu; ++i) { - rows(c[i], d[i], nv); + if (!rows(c[i], d[i], nv)) + return 0; rowshft(a.v, b.v, d[i], nv); } /* do columns to power series */ - cols(d, c, nu, nv); + if (!cols(d, c, nu, nv)) + return 0; colshft(a.u, b.u, c, nu, nv); freev2((void **) d, nu); return 1; diff --git a/src/geod_set.c b/src/geod_set.c index 60f19990..16396a90 100644 --- a/src/geod_set.c +++ b/src/geod_set.c @@ -16,8 +16,12 @@ geod_set(int argc, char **argv) { if (argc <= 0) emess(1, "no arguments in initialization list"); start = curr = pj_mkparam(argv[0]); + if (!curr) + emess(1, "memory allocation failed"); for (i = 1; i < argc; ++i) { curr->next = pj_mkparam(argv[i]); + if (!curr->next) + emess(1, "memory allocation failed"); curr = curr->next; } /* set elliptical parameters */ diff --git a/src/mk_cheby.c b/src/mk_cheby.c index a7cd75c5..b074650a 100644 --- a/src/mk_cheby.c +++ b/src/mk_cheby.c @@ -19,18 +19,23 @@ makeT(int nru, int nrv) { Tseries *T; int i; - if ((T = (Tseries *)pj_malloc(sizeof(Tseries))) && - (T->cu = (struct PW_COEF *)pj_malloc( - sizeof(struct PW_COEF) * nru)) && - (T->cv = (struct PW_COEF *)pj_malloc( - sizeof(struct PW_COEF) * nrv))) { - for (i = 0; i < nru; ++i) - T->cu[i].c = 0; - for (i = 0; i < nrv; ++i) - T->cv[i].c = 0; - return T; - } else + if (!(T = (Tseries *)pj_malloc(sizeof(Tseries)))) return 0; + if (!(T->cu = (struct PW_COEF *)pj_malloc(sizeof(struct PW_COEF) * nru))) { + pj_dalloc(T); + return 0; + } + if (!(T->cv = (struct PW_COEF *)pj_malloc(sizeof(struct PW_COEF) * nrv))) { + pj_dalloc(T->cu); + pj_dalloc(T); + return 0; + } + + for (i = 0; i < nru; ++i) + T->cu[i].c = 0; + for (i = 0; i < nrv; ++i) + T->cv[i].c = 0; + return T; } Tseries * mk_cheby(projUV a, projUV b, double res, projUV *resid, projUV (*func)(projUV), @@ -40,9 +45,12 @@ mk_cheby(projUV a, projUV b, double res, projUV *resid, projUV (*func)(projUV), projUV **w; double cutres; - if (!(w = (projUV **)vector2(nu, nv, sizeof(projUV))) || - !(ncu = (int *)vector1(nu + nv, sizeof(int)))) + if (!(w = (projUV **)vector2(nu, nv, sizeof(projUV)))) return 0; + if (!(ncu = (int *)vector1(nu + nv, sizeof(int)))) { + freev2((void **)w, nu); + return 0; + } ncv = ncu + nu; if (!bchgen(a, b, nu, nv, w, func)) { projUV *s; diff --git a/src/pj_datum_set.c b/src/pj_datum_set.c index 3fba68f4..c2fb1608 100644 --- a/src/pj_datum_set.c +++ b/src/pj_datum_set.c @@ -25,6 +25,7 @@ * DEALINGS IN THE SOFTWARE. *****************************************************************************/ +#include #include #include @@ -101,7 +102,11 @@ int pj_datum_set(projCtx ctx, paralist *pl, PJ *projdef) const char *date; projdef->datum_type = PJD_GRIDSHIFT; - projdef->catalog_name = strdup(catalog); + projdef->catalog_name = pj_strdup(catalog); + if (!projdef->catalog_name) { + pj_ctx_set_errno(ctx, ENOMEM); + return 1; + } date = pj_param(ctx, pl, "sdate").s; if( date != NULL) diff --git a/src/pj_fileapi.c b/src/pj_fileapi.c index 1e5bfa51..e223993e 100644 --- a/src/pj_fileapi.c +++ b/src/pj_fileapi.c @@ -26,6 +26,7 @@ * DEALINGS IN THE SOFTWARE. *****************************************************************************/ +#include #include #include @@ -76,6 +77,13 @@ static PAFile pj_stdio_fopen(projCtx ctx, const char *filename, } pafile = (stdio_pafile *) malloc(sizeof(stdio_pafile)); + if (!pafile) + { + pj_ctx_set_errno(ctx, ENOMEM); + fclose(fp); + return NULL; + } + pafile->fp = fp; pafile->ctx = ctx; return (PAFile) pafile; diff --git a/src/pj_gc_reader.c b/src/pj_gc_reader.c index dc528b52..e49e56a4 100644 --- a/src/pj_gc_reader.c +++ b/src/pj_gc_reader.c @@ -27,6 +27,7 @@ #define PJ_LIB__ +#include #include #include #include @@ -56,15 +57,29 @@ PJ_GridCatalog *pj_gc_readcatalog( projCtx ctx, const char *catalog_name ) catalog = (PJ_GridCatalog *) calloc(1,sizeof(PJ_GridCatalog)); if( !catalog ) { + pj_ctx_set_errno(ctx, ENOMEM); pj_ctx_fclose(ctx, fid); return NULL; } - catalog->catalog_name = strdup(catalog_name); + catalog->catalog_name = pj_strdup(catalog_name); + if (!catalog->catalog_name) { + pj_ctx_set_errno(ctx, ENOMEM); + free(catalog); + pj_ctx_fclose(ctx, fid); + return NULL; + } entry_max = 10; catalog->entries = (PJ_GridCatalogEntry *) malloc(entry_max * sizeof(PJ_GridCatalogEntry)); + if (!catalog->entries) { + pj_ctx_set_errno(ctx, ENOMEM); + free(catalog->catalog_name); + free(catalog); + pj_ctx_fclose(ctx, fid); + return NULL; + } while( pj_gc_readentry( ctx, fid, catalog->entries+catalog->entry_count) == 0) @@ -83,6 +98,7 @@ PJ_GridCatalog *pj_gc_readcatalog( projCtx ctx, const char *catalog_name ) int i; for( i = 0; i < catalog->entry_count; i++ ) free( catalog->entries[i].definition ); + free( catalog->entries ); free( catalog->catalog_name ); free( catalog ); pj_ctx_fclose(ctx, fid); @@ -124,6 +140,7 @@ static int pj_gc_read_csv_line( projCtx ctx, PAFile fid, while( token_count < max_tokens && *next != '\0' ) { const char *start = next; + char* token; while( *next != '\0' && *next != ',' ) next++; @@ -134,7 +151,14 @@ static int pj_gc_read_csv_line( projCtx ctx, PAFile fid, next++; } - tokens[token_count++] = strdup(start); + token = pj_strdup(start); + if (!token) { + while (token_count > 0) + free(tokens[--token_count]); + pj_ctx_set_errno(ctx, ENOMEM); + return 0; + } + tokens[token_count++] = token; } return token_count; @@ -199,7 +223,8 @@ static int pj_gc_readentry(projCtx ctx, PAFile fid, PJ_GridCatalogEntry *entry) } else { - entry->definition = strdup( tokens[0] ); + entry->definition = tokens[0]; + tokens[0] = NULL; /* We take ownership of tokens[0] */ entry->region.ll_long = dmstor_ctx( ctx, tokens[1], NULL ); entry->region.ll_lat = dmstor_ctx( ctx, tokens[2], NULL ); entry->region.ur_long = dmstor_ctx( ctx, tokens[3], NULL ); diff --git a/src/pj_gridinfo.c b/src/pj_gridinfo.c index 458f0f2b..332a0ffb 100644 --- a/src/pj_gridinfo.c +++ b/src/pj_gridinfo.c @@ -570,8 +570,8 @@ static int pj_gridinfo_init_ntv2( projCtx ctx, PAFile fid, PJ_GRIDINFO *gilist ) gi = (PJ_GRIDINFO *) pj_malloc(sizeof(PJ_GRIDINFO)); memset( gi, 0, sizeof(PJ_GRIDINFO) ); - gi->gridname = strdup( gilist->gridname ); - gi->filename = strdup( gilist->filename ); + gi->gridname = pj_strdup( gilist->gridname ); + gi->filename = pj_strdup( gilist->filename ); gi->next = NULL; } @@ -866,7 +866,7 @@ PJ_GRIDINFO *pj_gridinfo_init( projCtx ctx, const char *gridname ) gilist = (PJ_GRIDINFO *) pj_malloc(sizeof(PJ_GRIDINFO)); memset( gilist, 0, sizeof(PJ_GRIDINFO) ); - gilist->gridname = strdup( gridname ); + gilist->gridname = pj_strdup( gridname ); gilist->filename = NULL; gilist->format = "missing"; gilist->grid_offset = 0; @@ -882,7 +882,7 @@ PJ_GRIDINFO *pj_gridinfo_init( projCtx ctx, const char *gridname ) return gilist; } - gilist->filename = strdup(fname); + gilist->filename = pj_strdup(fname); /* -------------------------------------------------------------------- */ /* Load a header, to determine the file type. */ diff --git a/src/pj_init.c b/src/pj_init.c index 951f1cfb..704a8b55 100644 --- a/src/pj_init.c +++ b/src/pj_init.c @@ -359,6 +359,8 @@ pj_init_plus_ctx( projCtx ctx, const char *definition ) /* make a copy that we can manipulate */ defn_copy = (char *) pj_malloc( strlen(definition)+1 ); + if (!defn_copy) + return NULL; strcpy( defn_copy, definition ); /* split into arguments based on '+' and trim white space */ @@ -453,10 +455,14 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { /* put arguments into internal linked list */ start = curr = pj_mkparam(argv[0]); + if (!curr) + return pj_dealloc_params (ctx, start, ENOMEM); /* build parameter list and expand +init's. Does not take care of a single +init. */ for (i = 1; i < argc; ++i) { curr->next = pj_mkparam(argv[i]); + if (!curr->next) + return pj_dealloc_params (ctx, start, ENOMEM); /* check if +init present */ if (pj_param(ctx, curr, "tinit").i) { diff --git a/src/pj_malloc.c b/src/pj_malloc.c index 4e465c46..c003c717 100644 --- a/src/pj_malloc.c +++ b/src/pj_malloc.c @@ -130,6 +130,16 @@ pointer" to signal an error in a multi level allocation: return 0; } +/**********************************************************************/ +char *pj_strdup(const char *str) +/**********************************************************************/ +{ + size_t len = strlen(str) + 1; + char *dup = pj_malloc(len); + if (dup) + memcpy(dup, str, len); + return dup; +} /*****************************************************************************/ diff --git a/src/pj_pr_list.c b/src/pj_pr_list.c index 5ccfbe5b..00cd4bc3 100644 --- a/src/pj_pr_list.c +++ b/src/pj_pr_list.c @@ -62,6 +62,8 @@ char *pj_get_def( PJ *P, int options ) (void) options; definition = (char *) pj_malloc(def_max); + if (!definition) + return NULL; definition[0] = '\0'; for (t = P->params; t; t = t->next) @@ -78,9 +80,15 @@ char *pj_get_def( PJ *P, int options ) def_max = def_max * 2 + l + 5; def2 = (char *) pj_malloc(def_max); - strcpy( def2, definition ); - pj_dalloc( definition ); - definition = def2; + if (def2) { + strcpy( def2, definition ); + pj_dalloc( definition ); + definition = def2; + } + else { + pj_dalloc( definition ); + return NULL; + } } /* append this parameter */ diff --git a/src/pj_strtod.c b/src/pj_strtod.c index 7c2da9a7..9a66f70f 100644 --- a/src/pj_strtod.c +++ b/src/pj_strtod.c @@ -102,7 +102,7 @@ static char* pj_replace_point_by_locale_point(const char* pszNumber, char point, pszNew = pszWorkBuffer; } else - pszNew = strdup(pszNumber); + pszNew = pj_strdup(pszNumber); pszNew[pszPoint - pszNumber] = byPoint; return pszNew; } @@ -128,7 +128,7 @@ static char* pj_replace_point_by_locale_point(const char* pszNumber, char point, pszNew = pszWorkBuffer; } else - pszNew = strdup(pszNumber); + pszNew = pj_strdup(pszNumber); if( pszLocalePoint ) pszNew[pszLocalePoint - pszNumber] = ' '; if( pszPoint ) diff --git a/src/proj_api.h b/src/proj_api.h index 2add2946..151a824d 100644 --- a/src/proj_api.h +++ b/src/proj_api.h @@ -167,6 +167,7 @@ void *pj_malloc(size_t); void pj_dalloc(void *); void *pj_calloc (size_t n, size_t size); void *pj_dealloc (void *ptr); +char *pj_strdup(const char *str); char *pj_strerrno(int); int *pj_get_errno_ref(void); const char *pj_get_release(void); diff --git a/src/projects.h b/src/projects.h index 9391835d..2af382e5 100644 --- a/src/projects.h +++ b/src/projects.h @@ -93,7 +93,6 @@ extern double hypot(double, double); # include # define rewind wceex_rewind # define getenv wceex_getenv -# define strdup _strdup # define hypot _hypot #endif -- cgit v1.2.3 From 6b1880383695096a7e8e92983b6f916ad00b2d42 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Thu, 19 Oct 2017 16:50:38 +0200 Subject: Parse -I / --inverse properly in cct. Fixes #607. --- src/cct.c | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/src/cct.c b/src/cct.c index 83a0b0a3..35d4ec3f 100644 --- a/src/cct.c +++ b/src/cct.c @@ -87,7 +87,7 @@ char *column (char *buf, int n); PJ_COORD parse_input_line (char *buf, int *columns, double fixed_height, double fixed_time); int print_output_line (FILE *fout, char *buf, PJ_COORD point); int main(int argc, char **argv); - + static const char usage[] = { @@ -101,6 +101,7 @@ static const char usage[] = { " Defaults to 1,2,3,4\n" " -z value Provide a fixed z value for all input data (e.g. -z 0)\n" " -t value Provide a fixed t value for all input data (e.g. -t 0)\n" + " -I Do the inverse transformation\n" " -v Verbose: Provide non-essential informational output.\n" " Repeat -v for more verbosity (e.g. -vv)\n" "--------------------------------------------------------------------------------\n" @@ -111,6 +112,7 @@ static const char usage[] = { " --height Alias for -z\n" " --time Alias for -t\n" " --verbose Alias for -v\n" + " --inverse Alias for -I\n" " --help Alias for -h\n" "--------------------------------------------------------------------------------\n" "Operator Specs:\n" @@ -140,7 +142,7 @@ static const char usage[] = { " cct -c 5,2,1,4 +proj=utm +ellps=GRS80 +zone=32\n" "4. as (1) but specify fixed height and time, hence needing only 2 cols in input:\n" " cct -t 0 -z 0 +proj=utm +ellps=GRS80 +zone=32\n" - "--------------------------------------------------------------------------------\n" + "--------------------------------------------------------------------------------\n" }; int main(int argc, char **argv) { @@ -152,10 +154,10 @@ int main(int argc, char **argv) { int input_unit, output_unit, 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", 0}; + const char *longflags[] = {"v=verbose", "h=help", "I=inverse", 0}; const char *longkeys[] = {"o=output", "c=columns", "z=height", "t=time", 0}; - - o = opt_parse (argc, argv, "hv", "cozt", longflags, longkeys); + + o = opt_parse (argc, argv, "hvI", "cozt", longflags, longkeys); if (0==o) return 0; @@ -177,14 +179,14 @@ int main(int argc, char **argv) { } if (verbose > 3) fprintf (fout, "%s: Running in very verbose mode\n", o->progname); - - + + if (opt_given (o, "z")) { fixed_z = proj_atof (opt_arg (o, "z")); nfields--; } - + if (opt_given (o, "t")) { fixed_time = proj_atof (opt_arg (o, "t")); nfields--; @@ -200,7 +202,7 @@ int main(int argc, char **argv) { return 1; } } - + /* Setup transformation */ P = proj_create_argv (0, o->pargc, o->pargv); if ((0==P) || (0==o->pargc)) { -- cgit v1.2.3 From 666c17ac7a9d3b958e5c74ed2649487cb0c9eb3f Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Thu, 19 Oct 2017 18:33:08 +0200 Subject: Teach proj_strtod to understand corner cases 0 and 0. (#611) --- src/proj_strtod.c | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/proj_strtod.c b/src/proj_strtod.c index aa2211f5..42b7691d 100644 --- a/src/proj_strtod.c +++ b/src/proj_strtod.c @@ -86,6 +86,7 @@ Thomas Knudsen, thokn@sdfe.dk, 2017-01-17/2017-09-18 ***********************************************************************/ +#include /* for strchr */ #include /* for strchr */ #include #include @@ -141,10 +142,14 @@ double proj_strtod(const char *str, char **endptr) { return HUGE_VAL; } - /* skip prefixed zeros */ + /* skip prefixed zeros before '.' */ while ('0'==*p || '_'==*p) p++; + /* zero? */ + if (0==*p || 0==strchr ("0123456789eE.", *p)) + return 0; + /* Now expect a (potentially zero-length) string of digits */ while (isdigit(*p) || ('_'==*p)) { if ('_'==*p) { @@ -171,8 +176,11 @@ double proj_strtod(const char *str, char **endptr) { } /* if the next character is nonnumeric, we have reached the end */ - if (0==strchr ("0123456789eE+-", *p)) + if (0==*p || 0==strchr ("0123456789eE+-", *p)) { + if (endptr) + *endptr = p; return integral_part; + } while (isdigit(*p) || '_'==*p) { /* Don't let pathologically long fractions destroy precision */ @@ -244,10 +252,10 @@ double proj_strtod(const char *str, char **endptr) { } if ((exponent < DBL_MIN_EXP) || (exponent > DBL_MAX_EXP)) { - errno = ERANGE; - if (endptr) - *endptr = p; - return HUGE_VAL; + errno = ERANGE; + if (endptr) + *endptr = p; + return HUGE_VAL; } /* on some platforms pow() is very slow - so don't call it if exponent==0 */ @@ -260,15 +268,15 @@ double proj_strtod(const char *str, char **endptr) { if (endptr) *endptr = p; - return number; } double proj_atof(const char *str) { - return proj_strtod(str, (void *) 0); + return proj_strtod(str, (void *) 0); } #ifdef TEST +#include #include int main (int argc, char **argv) { -- cgit v1.2.3 From 3cbef771c6f2012e82ce9c8640264e6a1f86cc77 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Thu, 19 Oct 2017 19:01:17 +0200 Subject: remove internal seftests from projections starting with a 'b' --- src/PJ_bacon.c | 83 ---------------------------------------------------------- src/PJ_bipc.c | 57 ---------------------------------------- src/PJ_boggs.c | 26 +----------------- src/PJ_bonne.c | 56 --------------------------------------- 4 files changed, 1 insertion(+), 221 deletions(-) (limited to 'src') diff --git a/src/PJ_bacon.c b/src/PJ_bacon.c index cb7286be..13fb0044 100644 --- a/src/PJ_bacon.c +++ b/src/PJ_bacon.c @@ -77,89 +77,6 @@ PJ *PROJECTION(ortel) { } -#ifndef PJ_SELFTEST int pj_bacon_selftest (void) {return 0;} -#else -int pj_bacon_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=bacon +a=6400000 +lat_1=0 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {223334.13255596498, 175450.72592266591}, - {223334.13255596498, -175450.72592266591}, - {-223334.13255596498, 175450.72592266591}, - {-223334.13255596498, -175450.72592266591}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 0, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} -#endif - - - - -#ifndef PJ_SELFTEST int pj_apian_selftest (void) {return 0;} -#else -int pj_apian_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=apian +a=6400000 +lat_1=0 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223374.57735525275, 111701.07212763709}, - { 223374.57735525275, -111701.07212763709}, - {-223374.57735525275, 111701.07212763709}, - {-223374.57735525275, -111701.07212763709}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 0, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} -#endif - - - - -#ifndef PJ_SELFTEST int pj_ortel_selftest (void) {return 0;} -#else -int pj_ortel_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=ortel +a=6400000 +lat_1=0 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223374.57735525275, 111701.07212763709}, - { 223374.57735525275, -111701.07212763709}, - {-223374.57735525275, 111701.07212763709}, - {-223374.57735525275, -111701.07212763709}, - }; - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 0, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} -#endif - diff --git a/src/PJ_bipc.c b/src/PJ_bipc.c index 0019d614..ce726c06 100644 --- a/src/PJ_bipc.c +++ b/src/PJ_bipc.c @@ -171,61 +171,4 @@ PJ *PROJECTION(bipc) { } -#ifndef PJ_SELFTEST int pj_bipc_selftest (void) {return 0;} -#else - -int pj_bipc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=bipc +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=bipc +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {2452160.2177257561, -14548450.759654747}, - {2447915.213725341, -14763427.21279873}, - {2021695.5229349085, -14540413.695283702}, - {2018090.5030046992, -14755620.651414108}, - }; - - XY s_fwd_expect[] = { - {2460565.7409749646, -14598319.9893308}, - {2456306.1859352002, -14814033.339502094}, - {2028625.4978190989, -14590255.375482792}, - {2025008.1205891429, -14806200.018759441}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {-73.038700284978702, 17.248118466239116}, - {-73.03730373933017, 17.249414978178777}, - {-73.03589317304332, 17.245536403008771}, - {-73.034496627213585, 17.246832895573739}, - }; - - LP s_inv_expect[] = { - {-73.038693104942126, 17.248116270440242}, - {-73.037301330021322, 17.24940835333777}, - {-73.035895582251086, 17.245543027866539}, - {-73.034503807150301, 17.246835091521532}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif diff --git a/src/PJ_boggs.c b/src/PJ_boggs.c index e6efd7d3..5e95e7f8 100644 --- a/src/PJ_boggs.c +++ b/src/PJ_boggs.c @@ -41,29 +41,5 @@ PJ *PROJECTION(boggs) { return P; } -#ifndef PJ_SELFTEST -int pj_boggs_selftest (void) {return 0;} -#else -int pj_boggs_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=boggs +a=6400000 +lat_1=0 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - XY s_fwd_expect[] = { - { 211949.70080818201, 117720.99830541089}, - { 211949.70080818201, -117720.99830541089}, - {-211949.70080818201, 117720.99830541089}, - {-211949.70080818201, -117720.99830541089}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 0, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} -#endif +int pj_boggs_selftest (void) {return 0;} diff --git a/src/PJ_bonne.c b/src/PJ_bonne.c index 711e234f..736ab68f 100644 --- a/src/PJ_bonne.c +++ b/src/PJ_bonne.c @@ -130,60 +130,4 @@ PJ *PROJECTION(bonne) { } -#ifndef PJ_SELFTEST int pj_bonne_selftest (void) {return 0;} -#else -int pj_bonne_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=bonne +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=bonne +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222605.29609715697, 55321.139565494814}, - { 222605.29609923941, -165827.64779905154}, - {-222605.29609715697, 55321.139565494814}, - {-222605.29609923941, -165827.64779905154}, - }; - - XY s_fwd_expect[] = { - { 223368.11557252839, 55884.555246393575}, - { 223368.11557463196, -167517.59936969393}, - {-223368.11557252839, 55884.555246393575}, - {-223368.11557463196, -167517.59936969393}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017966987691132891, 0.50090436853737497}, - { 0.0017966982774478867, 0.4990956309655612}, - {-0.0017966987691132891, 0.50090436853737497}, - {-0.0017966982774478867, 0.4990956309655612}, - }; - - LP s_inv_expect[] = { - { 0.0017905615332457991, 0.50089524631087834}, - { 0.0017905610449335603, 0.49910475320072978}, - {-0.0017905615332457991, 0.50089524631087834}, - {-0.0017905610449335603, 0.49910475320072978}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif -- cgit v1.2.3 From 2ef55da22cfb5eca21431ca5fdacb85b359dbb32 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Thu, 19 Oct 2017 19:04:06 +0200 Subject: make selftest stubs return stub signal --- src/PJ_bacon.c | 6 +++--- src/PJ_bipc.c | 2 +- src/PJ_boggs.c | 2 +- src/PJ_bonne.c | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/PJ_bacon.c b/src/PJ_bacon.c index 13fb0044..930e9c07 100644 --- a/src/PJ_bacon.c +++ b/src/PJ_bacon.c @@ -77,6 +77,6 @@ PJ *PROJECTION(ortel) { } -int pj_bacon_selftest (void) {return 0;} -int pj_apian_selftest (void) {return 0;} -int pj_ortel_selftest (void) {return 0;} +int pj_bacon_selftest (void) {return 10000;} +int pj_apian_selftest (void) {return 10000;} +int pj_ortel_selftest (void) {return 10000;} diff --git a/src/PJ_bipc.c b/src/PJ_bipc.c index ce726c06..7dd8a30f 100644 --- a/src/PJ_bipc.c +++ b/src/PJ_bipc.c @@ -171,4 +171,4 @@ PJ *PROJECTION(bipc) { } -int pj_bipc_selftest (void) {return 0;} +int pj_bipc_selftest (void) {return 10000;} diff --git a/src/PJ_boggs.c b/src/PJ_boggs.c index 5e95e7f8..8c35fcb3 100644 --- a/src/PJ_boggs.c +++ b/src/PJ_boggs.c @@ -42,4 +42,4 @@ PJ *PROJECTION(boggs) { } -int pj_boggs_selftest (void) {return 0;} +int pj_boggs_selftest (void) {return 10000;} diff --git a/src/PJ_bonne.c b/src/PJ_bonne.c index 736ab68f..596610bb 100644 --- a/src/PJ_bonne.c +++ b/src/PJ_bonne.c @@ -130,4 +130,4 @@ PJ *PROJECTION(bonne) { } -int pj_bonne_selftest (void) {return 0;} +int pj_bonne_selftest (void) {return 10000;} -- cgit v1.2.3 From 60d1592843f894d4967bccc9a22b8521b5ade86d Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Thu, 19 Oct 2017 19:31:32 +0200 Subject: remove internal seftests from projections starting with a 'c' (excluding PJ_cart) --- src/PJ_calcofi.c | 59 +------------------------------------------------------- src/PJ_cass.c | 57 +----------------------------------------------------- src/PJ_cc.c | 44 +----------------------------------------- src/PJ_cea.c | 58 +------------------------------------------------------ src/PJ_chamb.c | 30 +--------------------------- src/PJ_collg.c | 44 +----------------------------------------- src/PJ_comill.c | 44 +----------------------------------------- src/PJ_crast.c | 45 +----------------------------------------- 8 files changed, 8 insertions(+), 373 deletions(-) (limited to 'src') diff --git a/src/PJ_calcofi.c b/src/PJ_calcofi.c index b188f7e9..2782b152 100644 --- a/src/PJ_calcofi.c +++ b/src/PJ_calcofi.c @@ -163,61 +163,4 @@ PJ *PROJECTION(calcofi) { } -#ifndef PJ_SELFTEST -int pj_calcofi_selftest (void) {return 0;} -#else - -int pj_calcofi_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=calcofi +ellps=GRS80 +lat_1=0.5 +lat_2=2 +no_defs"}; - char s_args[] = {"+proj=calcofi +R=6400000 +lat_1=0.5 +lat_2=2 +no_defs"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {508.44487214981905, -1171.7648604175156}, - {514.99916815188112, -1145.8219814677668}, - {500.68538412539851, -1131.4453779204598}, - {507.36971913666355, -1106.1782014834275}, - }; - - XY s_fwd_expect[] = { - {507.09050748781806, -1164.7273751978314}, - {513.68613637462886, -1138.9992682173072}, - {499.33626147591531, -1124.4351309968195}, - {506.0605703929898, -1099.3756650673038}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {-110.36330792469906, 12.032056975840137}, - {-98.455008863288782, 18.698723642506803}, - {-207.4470245036909, 81.314089278595247}, - {-62.486322854481287, 87.980755945261919}, - }; - - LP s_inv_expect[] = { - {-110.30519040955151, 12.032056975840137}, - {-98.322360950234085, 18.698723642506803}, - {-207.54490681381429, 81.314089278595247}, - {-62.576950371885275, 87.980755945261919}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_calcofi_selftest (void) {return 10000;} diff --git a/src/PJ_cass.c b/src/PJ_cass.c index 6955146e..603ce013 100644 --- a/src/PJ_cass.c +++ b/src/PJ_cass.c @@ -118,59 +118,4 @@ PJ *PROJECTION(cass) { } -#ifndef PJ_SELFTEST -int pj_cass_selftest (void) {return 0;} -#else - -int pj_cass_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=cass +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=cass +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222605.28577699114, 110642.22925399939}, - { 222605.28577699114, -110642.22925399939}, - {-222605.28577699114, 110642.22925399939}, - {-222605.28577699114, -110642.22925399939}, - }; - - XY s_fwd_expect[] = { - { 223368.10520348375, 111769.14504058579}, - { 223368.10520348375, -111769.14504058579}, - {-223368.10520348375, 111769.14504058579}, - {-223368.10520348375, -111769.14504058579}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017966305684613522, 0.00090436947663183841}, - { 0.0017966305684613522, -0.00090436947663183841}, - {-0.0017966305684613522, 0.00090436947663183841}, - {-0.0017966305684613522, -0.00090436947663183841}, - }; - - LP s_inv_expect[] = { - { 0.0017904931100023887, 0.00089524655445477922}, - { 0.0017904931100023887, -0.00089524655445477922}, - {-0.0017904931100023887, 0.00089524655445477922}, - {-0.0017904931100023887, -0.00089524655445477922}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} -#endif +int pj_cass_selftest (void) {return 10000;} diff --git a/src/PJ_cc.c b/src/PJ_cc.c index 9ba51386..a45eaf83 100644 --- a/src/PJ_cc.c +++ b/src/PJ_cc.c @@ -38,46 +38,4 @@ PJ *PROJECTION(cc) { } -#ifndef PJ_SELFTEST -int pj_cc_selftest (void) {return 0;} -#else - -int pj_cc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=cc +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {223402.14425527418, 111712.41554059254}, - {223402.14425527418, -111712.41554059254}, - {-223402.14425527418, 111712.41554059254}, - {-223402.14425527418, -111712.41554059254}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {0.0017904931097838226, 0.00089524655481905597}, - {0.0017904931097838226, -0.00089524655481905597}, - {-0.0017904931097838226, 0.00089524655481905597}, - {-0.0017904931097838226, -0.00089524655481905597}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_cc_selftest (void) {return 10000;} diff --git a/src/PJ_cea.c b/src/PJ_cea.c index 0ec7376c..0ffc2f4c 100644 --- a/src/PJ_cea.c +++ b/src/PJ_cea.c @@ -98,60 +98,4 @@ PJ *PROJECTION(cea) { } -#ifndef PJ_SELFTEST -int pj_cea_selftest (void) {return 0;} -#else - -int pj_cea_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=cea +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=cea +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222638.981586547132, 110568.812396267356}, - { 222638.981586547132, -110568.812396265886}, - {-222638.981586547132, 110568.812396267356}, - {-222638.981586547132, -110568.812396265886}, - }; - - XY s_fwd_expect[] = { - { 223402.144255274179, 111695.401198614476}, - { 223402.144255274179, -111695.401198614476}, - {-223402.144255274179, 111695.401198614476}, - {-223402.144255274179, -111695.401198614476}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.00179663056823904264, 0.000904369476105564289}, - { 0.00179663056823904264, -0.000904369476105564289}, - {-0.00179663056823904264, 0.000904369476105564289}, - {-0.00179663056823904264, -0.000904369476105564289}, - }; - - LP s_inv_expect[] = { - { 0.00179049310978382265, 0.000895246554928338998}, - { 0.00179049310978382265, -0.000895246554928338998}, - {-0.00179049310978382265, 0.000895246554928338998}, - {-0.00179049310978382265, -0.000895246554928338998}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - -#endif +int pj_cea_selftest (void) {return 10000;} diff --git a/src/PJ_chamb.c b/src/PJ_chamb.c index 9edb699f..de47c2d9 100644 --- a/src/PJ_chamb.c +++ b/src/PJ_chamb.c @@ -136,32 +136,4 @@ PJ *PROJECTION(chamb) { } -#ifndef PJ_SELFTEST -int pj_chamb_selftest (void) {return 0;} -#else - -int pj_chamb_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=chamb +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {-27864.7795868005815, -223364.324593274243}, - {-251312.283053493476, -223402.145526208304}, - {-27864.7856491046077, 223364.327328827145}, - {-251312.289116443484, 223402.142197287147}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif +int pj_chamb_selftest (void) {return 10000;} diff --git a/src/PJ_collg.c b/src/PJ_collg.c index 01c65cd0..15e8354c 100644 --- a/src/PJ_collg.c +++ b/src/PJ_collg.c @@ -49,46 +49,4 @@ PJ *PROJECTION(collg) { return P; } -#ifndef PJ_SELFTEST -int pj_collg_selftest (void) {return 0;} -#else - -int pj_collg_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=collg +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {249872.921577929839, 99423.1747884602082}, - {254272.532301245432, -98559.3077607425657}, - {-249872.921577929839, 99423.1747884602082}, - {-254272.532301245432, -98559.3077607425657}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {0.00158679719207879865, 0.00101017310941749921}, - {0.001586769215623956, -0.00101018201458258111}, - {-0.00158679719207879865, 0.00101017310941749921}, - {-0.001586769215623956, -0.00101018201458258111}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_collg_selftest (void) {return 10000;} diff --git a/src/PJ_comill.c b/src/PJ_comill.c index a329c0ac..e1994478 100644 --- a/src/PJ_comill.c +++ b/src/PJ_comill.c @@ -81,46 +81,4 @@ PJ *PROJECTION(comill) { } -#ifndef PJ_SELFTEST -int pj_comill_selftest (void) {return 0;} -#else - -int pj_comill_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=comill +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {223402.144255274179, 110611.859089458536}, - {223402.144255274179, -110611.859089458536}, - {-223402.144255274179, 110611.859089458536}, - {-223402.144255274179, -110611.859089458536}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {0.00179049310978382265, 0.000904106801510605831}, - {0.00179049310978382265, -0.000904106801510605831}, - {-0.00179049310978382265, 0.000904106801510605831}, - {-0.00179049310978382265, -0.000904106801510605831}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_comill_selftest (void) {return 10000;} diff --git a/src/PJ_crast.c b/src/PJ_crast.c index b47b0e55..30f2e304 100644 --- a/src/PJ_crast.c +++ b/src/PJ_crast.c @@ -37,47 +37,4 @@ PJ *PROJECTION(crast) { return P; } -#ifndef PJ_SELFTEST -int pj_crast_selftest (void) {return 0;} -#else - -int pj_crast_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=crast +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - - XY s_fwd_expect[] = { - {218280.142056780722, 114306.045604279774}, - {218280.142056780722, -114306.045604279774}, - {-218280.142056780722, 114306.045604279774}, - {-218280.142056780722, -114306.045604279774}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {0.00183225941982580187, 0.00087483943098902331}, - {0.00183225941982580187, -0.00087483943098902331}, - {-0.00183225941982580187, 0.00087483943098902331}, - {-0.00183225941982580187, -0.00087483943098902331}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_crast_selftest (void) {return 10000;} -- cgit v1.2.3 From 4d7e3c59dfe7d66233352fd75d89f439713a604d Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Fri, 20 Oct 2017 07:11:23 +0200 Subject: Improve proj_strtod test cases (#614) * Improve proj_strtod test cases * Add missing stdlib.h include --- src/proj_strtod.c | 137 ++++++++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 123 insertions(+), 14 deletions(-) (limited to 'src') diff --git a/src/proj_strtod.c b/src/proj_strtod.c index 42b7691d..f0ac96f5 100644 --- a/src/proj_strtod.c +++ b/src/proj_strtod.c @@ -86,7 +86,7 @@ Thomas Knudsen, thokn@sdfe.dk, 2017-01-17/2017-09-18 ***********************************************************************/ -#include /* for strchr */ +#include /* for abs */ #include /* for strchr */ #include #include @@ -162,6 +162,15 @@ double proj_strtod(const char *str, char **endptr) { } integral_part = number; + /* Done? */ + if (0==*p) { + if (endptr) + *endptr = p; + if (sign==-1) + return -number; + return number; + } + /* Do we have a fractional part? */ if ('.'==*p) { p++; @@ -176,10 +185,12 @@ double proj_strtod(const char *str, char **endptr) { } /* if the next character is nonnumeric, we have reached the end */ - if (0==*p || 0==strchr ("0123456789eE+-", *p)) { + if (0==*p || 0==strchr ("_0123456789eE+-", *p)) { if (endptr) *endptr = p; - return integral_part; + if (sign==-1) + return -number; + return number; } while (isdigit(*p) || '_'==*p) { @@ -202,7 +213,8 @@ double proj_strtod(const char *str, char **endptr) { exponent = -(num_digits_after_comma + num_prefixed_zeros); else number = integral_part; - } + } /* end of fractional part */ + /* non-digit */ if (0==num_digits_total) { @@ -218,6 +230,8 @@ double proj_strtod(const char *str, char **endptr) { /* Do we have an exponent part? */ if (*p == 'e' || *p == 'E') { p++; + while ('_'==*p) + p++; /* Does it have a sign? */ sign = 0; if ('-'==*p) @@ -251,23 +265,27 @@ double proj_strtod(const char *str, char **endptr) { exponent += n; } + if (endptr) + *endptr = p; + if ((exponent < DBL_MIN_EXP) || (exponent > DBL_MAX_EXP)) { errno = ERANGE; - if (endptr) - *endptr = p; return HUGE_VAL; } - /* on some platforms pow() is very slow - so don't call it if exponent==0 */ - if (exponent) + /* on some platforms pow() is very slow - so don't call it if exponent is close to 0 */ + if (0==exponent) + return number; + if (abs (exponent) < 20) { + double ex = 1; + int absexp = exponent < 0? -exponent: exponent; + while (absexp--) + ex *= 10; + number = exponent < 0? number / ex: number * ex; + } + else number *= pow (10, exponent); - /* Did we run into an infinity? */ - if (fabs(number) > DBL_MAX) - errno = ERANGE; - - if (endptr) - *endptr = p; return number; } @@ -276,12 +294,103 @@ double proj_atof(const char *str) { } #ifdef TEST + +/* compile/run: gcc -DTEST -o proj_strtod_test proj_strtod.c && proj_strtod_test */ + #include +#include #include +char *un_underscore (char *s) { + static char u[1024]; + int i, m, n; + for (i = m = 0, n = strlen (s); i < n; i++) { + if (s[i]=='_') { + m++; + continue; + } + u[i - m] = s[i]; + } + u[n-m] = 0; + return u; +} + +int thetest (char *s, int line) { + char *endp, *endq, *u; + double p, q; + int errnop, errnoq, prev_errno; + + prev_errno = errno; + + u = un_underscore (s); + + errno = 0; + p = proj_strtod (s, &endp); + errnop = errno; + errno = 0; + q = strtod (u, &endq); + errnoq = errno; + + errno = prev_errno; + + if (q==p && 0==strcmp (endp, endq) && errnop==errnoq && 0) + return 0; + + errno = line; + printf ("Line: %3.3d - [%s] [%s]\n", line, s, u); + printf ("proj_strtod: %2d %.17g [%s]\n", errnop, p, endp); + printf ("libc_strtod: %2d %.17g [%s]\n", errnoq, q, endq); + return 1; +} + +#define test(s) thetest(s, __LINE__) + int main (int argc, char **argv) { double res; char *endptr; + + errno = 0; + + test ("1"); + test ("0"); + test ("1."); + test ("0."); + test ("1.0"); + test ("0.0"); + test ("1.0"); + test ("0.0"); + test ("_1.0"); + test ("_0.0"); + test ("1_.0"); + test ("0_.0"); + test ("1__.0"); + test ("0__.0"); + test ("1.__0"); + test ("0.__0"); + test ("1.0___"); + test ("0.0___"); + test ("1e2"); + test ("__123_456_789_._10_11_12"); + test ("1______"); + test ("1___e__2__"); + test ("-1"); + test ("-1.0"); + test ("-0"); + test ("-1e__-_2__rest"); + test ("0.00002"); + test ("0.00001"); + test ("-0.00002"); + test ("-0.00001"); + test ("-0.00001e-2"); + test ("-0.00001e2"); + test ("1e9999"); + + /* We expect this one to differ */ + test ("0.000000000000000000000000000000000000000000000000000000000000000000000000002"); + + if (errno) + printf ("First discrepancy in line %d\n", errno); + if (argc < 2) return 0; res = proj_strtod (argv[1], &endptr); -- cgit v1.2.3 From 33c3549fa7a26d86388520c91b7f0fa38d51bfa1 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Fri, 20 Oct 2017 07:22:32 +0200 Subject: Silence proj_strtod Avoid printing output for succeeding tests --- src/proj_strtod.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/proj_strtod.c b/src/proj_strtod.c index f0ac96f5..d4063b0b 100644 --- a/src/proj_strtod.c +++ b/src/proj_strtod.c @@ -333,7 +333,7 @@ int thetest (char *s, int line) { errno = prev_errno; - if (q==p && 0==strcmp (endp, endq) && errnop==errnoq && 0) + if (q==p && 0==strcmp (endp, endq) && errnop==errnoq) return 0; errno = line; -- cgit v1.2.3 From 81bf085dce5ce6eac59835cd45dba6aecdb1a8e6 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Fri, 20 Oct 2017 13:10:28 +0200 Subject: Remove superfluous internal selftests from projection files matching patterns PJ_d....c and PJ_e....c (#615) --- src/PJ_denoy.c | 29 +--------- src/PJ_eck1.c | 43 +------------- src/PJ_eck2.c | 44 +------------- src/PJ_eck3.c | 180 ++------------------------------------------------------- src/PJ_eck4.c | 44 +------------- src/PJ_eck5.c | 44 +------------- src/PJ_eqc.c | 44 +------------- src/PJ_eqdc.c | 59 +------------------ 8 files changed, 11 insertions(+), 476 deletions(-) (limited to 'src') diff --git a/src/PJ_denoy.c b/src/PJ_denoy.c index 3964c7da..aec78b40 100644 --- a/src/PJ_denoy.c +++ b/src/PJ_denoy.c @@ -29,31 +29,4 @@ PJ *PROJECTION(denoy) { return P; } -#ifndef PJ_SELFTEST -int pj_denoy_selftest (void) {return 0;} -#else - -int pj_denoy_selftest (void) { - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=denoy +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223377.422876954137, 111701.07212763709}, - { 223377.422876954137, -111701.07212763709}, - {-223377.422876954137, 111701.07212763709}, - {-223377.422876954137, -111701.07212763709}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, 0, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif +int pj_denoy_selftest (void) {return 10000;} diff --git a/src/PJ_eck1.c b/src/PJ_eck1.c index bd5c1916..10fef421 100644 --- a/src/PJ_eck1.c +++ b/src/PJ_eck1.c @@ -39,45 +39,4 @@ PJ *PROJECTION(eck1) { } -#ifndef PJ_SELFTEST -int pj_eck1_selftest (void) {return 0;} -#else - -int pj_eck1_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=eck1 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - XY s_fwd_expect[] = { - { 204680.88820295094, 102912.17842606473}, - { 204680.88820295094, -102912.17842606473}, - {-204680.88820295094, 102912.17842606473}, - {-204680.88820295094, -102912.17842606473}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0019434150820034624, 0.00097170229538813102}, - { 0.0019434150820034624, -0.00097170229538813102}, - {-0.0019434150820034624, 0.00097170229538813102}, - {-0.0019434150820034624, -0.00097170229538813102}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_eck1_selftest (void) {return 10000;} diff --git a/src/PJ_eck2.c b/src/PJ_eck2.c index 3b2e4e49..f8adcc7a 100644 --- a/src/PJ_eck2.c +++ b/src/PJ_eck2.c @@ -53,46 +53,4 @@ PJ *PROJECTION(eck2) { } -#ifndef PJ_SELFTEST -int pj_eck2_selftest (void) {return 0;} -#else - -int pj_eck2_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=eck2 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 204472.87090796008, 121633.73497524235}, - { 204472.87090796008, -121633.73497524235}, - {-204472.87090796008, 121633.73497524235}, - {-204472.87090796008, -121633.73497524235}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0019434150820034624, 0.00082480429919795412}, - { 0.0019434150820034624, -0.00082480429919795412}, - {-0.0019434150820034624, 0.00082480429919795412}, - {-0.0019434150820034624, -0.00082480429919795412}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_eck2_selftest (void) {return 10000;} diff --git a/src/PJ_eck3.c b/src/PJ_eck3.c index 8dc72c7c..3e64e050 100644 --- a/src/PJ_eck3.c +++ b/src/PJ_eck3.c @@ -107,179 +107,7 @@ PJ *PROJECTION(putp1) { } -#ifndef PJ_SELFTEST -int pj_eck3_selftest (void) {return 0;} -#else - -int pj_eck3_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=eck3 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 188652.01572153764, 94328.919337031271}, - { 188652.01572153764, -94328.919337031271}, - {-188652.01572153764, 94328.919337031271}, - {-188652.01572153764, -94328.919337031271}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0021202405520236059, 0.0010601202759750307}, - { 0.0021202405520236059, -0.0010601202759750307}, - {-0.0021202405520236059, 0.0010601202759750307}, - {-0.0021202405520236059, -0.0010601202759750307}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif - -#ifndef PJ_SELFTEST -int pj_kav7_selftest (void) {return 0;} -#else - -int pj_kav7_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=kav7 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 193462.9749437288, 111701.07212763709}, - { 193462.9749437288, -111701.07212763709}, - {-193462.9749437288, 111701.07212763709}, - {-193462.9749437288, -111701.07212763709} - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0020674833579085268, 0.00089524655489191132}, - { 0.0020674833579085268, -0.00089524655489191132}, - {-0.0020674833579085268, 0.00089524655489191132}, - {-0.0020674833579085268, -0.00089524655489191132} - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif - -#ifndef PJ_SELFTEST -int pj_wag6_selftest (void) {return 0;} -#else - -int pj_wag6_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=wag6 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 211652.56216440981, 105831.18078732977}, - { 211652.56216440981, -105831.18078732977}, - {-211652.56216440981, 105831.18078732977}, - {-211652.56216440981, -105831.18078732977} - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0018898022163257513, 0.000944901108123818}, - { 0.0018898022163257513, -0.000944901108123818}, - {-0.0018898022163257513, 0.000944901108123818}, - {-0.0018898022163257513, -0.000944901108123818} - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif - - -#ifndef PJ_SELFTEST -int pj_putp1_selftest (void) {return 0;} -#else - -int pj_putp1_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=putp1 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 211642.76275416015, 105831.18078732977}, - { 211642.76275416015, -105831.18078732977}, - {-211642.76275416015, 105831.18078732977}, - {-211642.76275416015, -105831.18078732977} - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0018898022164038663, 0.000944901108123818}, - { 0.0018898022164038663, -0.000944901108123818}, - {-0.0018898022164038663, 0.000944901108123818}, - {-0.0018898022164038663, -0.000944901108123818} - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_eck3_selftest (void) {return 10000;} +int pj_kav7_selftest (void) {return 10000;} +int pj_wag6_selftest (void) {return 10000;} +int pj_putp1_selftest (void) {return 10000;} diff --git a/src/PJ_eck4.c b/src/PJ_eck4.c index 0ad9ec43..8c323656 100644 --- a/src/PJ_eck4.c +++ b/src/PJ_eck4.c @@ -60,46 +60,4 @@ PJ *PROJECTION(eck4) { } -#ifndef PJ_SELFTEST -int pj_eck4_selftest (void) {return 0;} -#else - -int pj_eck4_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=eck4 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 188646.38935641639, 132268.54017406539}, - { 188646.38935641639, -132268.54017406539}, - {-188646.38935641639, 132268.54017406539}, - {-188646.38935641639, -132268.54017406539}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0021202405520236059, 0.00075601458836610643}, - { 0.0021202405520236059, -0.00075601458836610643}, - {-0.0021202405520236059, 0.00075601458836610643}, - {-0.0021202405520236059, -0.00075601458836610643}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_eck4_selftest (void) {return 10000;} diff --git a/src/PJ_eck5.c b/src/PJ_eck5.c index 13617c1d..69e83eda 100644 --- a/src/PJ_eck5.c +++ b/src/PJ_eck5.c @@ -36,46 +36,4 @@ PJ *PROJECTION(eck5) { return P; } -#ifndef PJ_SELFTEST -int pj_eck5_selftest (void) {return 0;} -#else - -int pj_eck5_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=eck5 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 197031.39213406085, 98523.198847226551}, - { 197031.39213406085, -98523.198847226551}, - {-197031.39213406085, 98523.198847226551}, - {-197031.39213406085, -98523.198847226551}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {0.002029978749734037, 0.001014989374787388}, - {0.002029978749734037, -0.001014989374787388}, - {-0.002029978749734037, 0.001014989374787388}, - {-0.002029978749734037, -0.001014989374787388}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_eck5_selftest (void) {return 10000;} diff --git a/src/PJ_eqc.c b/src/PJ_eqc.c index 4f471df1..2b69788f 100644 --- a/src/PJ_eqc.c +++ b/src/PJ_eqc.c @@ -49,46 +49,4 @@ PJ *PROJECTION(eqc) { } -#ifndef PJ_SELFTEST -int pj_eqc_selftest (void) {return 0;} -#else - -int pj_eqc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=eqc +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223402.144255274179, 111701.07212763709}, - { 223402.144255274179, -111701.07212763709}, - {-223402.144255274179, 111701.07212763709}, - {-223402.144255274179, -111701.07212763709}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00179049310978382265, 0.000895246554891911323}, - { 0.00179049310978382265, -0.000895246554891911323}, - {-0.00179049310978382265, 0.000895246554891911323}, - {-0.00179049310978382265, -0.000895246554891911323}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_eqc_selftest (void) {return 10000;} diff --git a/src/PJ_eqdc.c b/src/PJ_eqdc.c index cb7e7f10..6e9d2c75 100644 --- a/src/PJ_eqdc.c +++ b/src/PJ_eqdc.c @@ -130,61 +130,4 @@ PJ *PROJECTION(eqdc) { } -#ifndef PJ_SELFTEST -int pj_eqdc_selftest (void) {return 0;} -#else - -int pj_eqdc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=eqdc +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=eqdc +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222588.440269285755, 110659.134907347048}, - { 222756.836702042434, -110489.578087220681}, - {-222588.440269285755, 110659.134907347048}, - {-222756.836702042434, -110489.578087220681}, - }; - - XY s_fwd_expect[] = { - { 223351.088175113517, 111786.108747173785}, - { 223521.200266735133, -111615.970741240744}, - {-223351.088175113517, 111786.108747173785}, - {-223521.200266735133, -111615.970741240744}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.00179635944879094839, 0.000904368858588402644}, - { 0.00179635822020772734, -0.000904370095529954975}, - {-0.00179635944879094839, 0.000904368858588402644}, - {-0.00179635822020772734, -0.000904370095529954975}, - }; - - LP s_inv_expect[] = { - { 0.0017902210900486641, 0.000895245944814909169}, - { 0.00179021986984890255, -0.000895247165333684842}, - {-0.0017902210900486641, 0.000895245944814909169}, - {-0.00179021986984890255, -0.000895247165333684842}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_eqdc_selftest (void) {return 10000;} -- cgit v1.2.3 From 080e1a5ab59e36c316c3590b74feb07638276a99 Mon Sep 17 00:00:00 2001 From: Aaron Puchert Date: Fri, 20 Oct 2017 14:35:35 +0200 Subject: Handle allocation failure when loading grid files (#616) * Handle allocation failure when loading grid files Continuing #606, we tackle the same issues in the loading and processing of grid files. This should fix potential crashes and memory leaks, and makes sure the global lock is always released. * Use pj_calloc when zero-initialized memory is wanted --- src/nad_init.c | 3 ++- src/pj_gridinfo.c | 59 ++++++++++++++++++++++++++++++++++++++++++++++++------- src/pj_gridlist.c | 7 +++++-- src/pj_strtod.c | 10 ++++++++-- 4 files changed, 67 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/nad_init.c b/src/nad_init.c index 0a28e200..a9082f8f 100644 --- a/src/nad_init.c +++ b/src/nad_init.c @@ -224,7 +224,7 @@ struct CTABLE *nad_ctable2_init( projCtx ctx, PAFile fid ) ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE)); if( ct == NULL ) { - pj_ctx_set_errno( ctx, -38 ); + pj_ctx_set_errno( ctx, ENOMEM ); return NULL; } @@ -241,6 +241,7 @@ struct CTABLE *nad_ctable2_init( projCtx ctx, PAFile fid ) || ct->lim.phi < 1 || ct->lim.phi > 100000 ) { pj_ctx_set_errno( ctx, -38 ); + pj_dalloc( ct ); return NULL; } diff --git a/src/pj_gridinfo.c b/src/pj_gridinfo.c index 332a0ffb..ad4695ca 100644 --- a/src/pj_gridinfo.c +++ b/src/pj_gridinfo.c @@ -212,7 +212,9 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) ct_tmp.cvs = (FLP *) pj_malloc(gi->ct->lim.lam*gi->ct->lim.phi*sizeof(FLP)); if( row_buf == NULL || ct_tmp.cvs == NULL ) { - pj_ctx_set_errno( ctx, -38 ); + pj_dalloc( row_buf ); + pj_dalloc( ct_tmp.cvs ); + pj_ctx_set_errno( ctx, ENOMEM ); pj_release_lock(); return 0; } @@ -230,6 +232,7 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) pj_dalloc( row_buf ); pj_dalloc( ct_tmp.cvs ); pj_ctx_set_errno( ctx, -38 ); + pj_release_lock(); return 0; } @@ -290,7 +293,9 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) ct_tmp.cvs = (FLP *) pj_malloc(gi->ct->lim.lam*gi->ct->lim.phi*sizeof(FLP)); if( row_buf == NULL || ct_tmp.cvs == NULL ) { - pj_ctx_set_errno( ctx, -38 ); + pj_dalloc( row_buf ); + pj_dalloc( ct_tmp.cvs ); + pj_ctx_set_errno( ctx, ENOMEM ); pj_release_lock(); return 0; } @@ -362,7 +367,7 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) ct_tmp.cvs = (FLP *) pj_malloc(words*sizeof(float)); if( ct_tmp.cvs == NULL ) { - pj_ctx_set_errno( ctx, -38 ); + pj_ctx_set_errno( ctx, ENOMEM ); pj_release_lock(); return 0; } @@ -371,6 +376,7 @@ int pj_gridinfo_load( projCtx ctx, PJ_GRIDINFO *gi ) != (size_t)words ) { pj_dalloc( ct_tmp.cvs ); + pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); pj_release_lock(); return 0; } @@ -519,6 +525,10 @@ static int pj_gridinfo_init_ntv2( projCtx ctx, PAFile fid, PJ_GRIDINFO *gilist ) /* Initialize a corresponding "ct" structure. */ /* -------------------------------------------------------------------- */ ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE)); + if (!ct) { + pj_ctx_set_errno(ctx, ENOMEM); + return 0; + } strncpy( ct->id, (const char *) header + 8, 8 ); ct->id[8] = '\0'; @@ -553,6 +563,7 @@ static int pj_gridinfo_init_ntv2( projCtx ctx, PAFile fid, PJ_GRIDINFO *gilist ) "GS_COUNT(%d) does not match expected cells (%dx%d=%d)\n", gs_count, ct->lim.lam, ct->lim.phi, ct->lim.lam * ct->lim.phi ); + pj_dalloc(ct); pj_ctx_set_errno( ctx, -38 ); return 0; } @@ -567,11 +578,23 @@ static int pj_gridinfo_init_ntv2( projCtx ctx, PAFile fid, PJ_GRIDINFO *gilist ) gi = gilist; else { - gi = (PJ_GRIDINFO *) pj_malloc(sizeof(PJ_GRIDINFO)); - memset( gi, 0, sizeof(PJ_GRIDINFO) ); + gi = (PJ_GRIDINFO *) pj_calloc(1, sizeof(PJ_GRIDINFO)); + if (!gi) { + pj_dalloc(ct); + pj_gridinfo_free(ctx, gilist); + pj_ctx_set_errno(ctx, ENOMEM); + return 0; + } gi->gridname = pj_strdup( gilist->gridname ); gi->filename = pj_strdup( gilist->filename ); + if (!gi->gridname || gi->filename) { + pj_gridinfo_free(ctx, gi); + pj_dalloc(ct); + pj_gridinfo_free(ctx, gilist); + pj_ctx_set_errno(ctx, ENOMEM); + return 0; + } gi->next = NULL; } @@ -699,6 +722,10 @@ static int pj_gridinfo_init_ntv1( projCtx ctx, PAFile fid, PJ_GRIDINFO *gi ) /* Fill in CTABLE structure. */ /* -------------------------------------------------------------------- */ ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE)); + if (!ct) { + pj_ctx_set_errno(ctx, ENOMEM); + return 0; + } strcpy( ct->id, "NTv1 Grid Shift File" ); ct->ll.lam = - *((double *) (header+72)); @@ -799,6 +826,10 @@ static int pj_gridinfo_init_gtx( projCtx ctx, PAFile fid, PJ_GRIDINFO *gi ) /* Fill in CTABLE structure. */ /* -------------------------------------------------------------------- */ ct = (struct CTABLE *) pj_malloc(sizeof(struct CTABLE)); + if (!ct) { + pj_ctx_set_errno(ctx, ENOMEM); + return 0; + } strcpy( ct->id, "GTX Vertical Grid Shift File" ); ct->ll.lam = xorigin; @@ -863,10 +894,18 @@ PJ_GRIDINFO *pj_gridinfo_init( projCtx ctx, const char *gridname ) /* Initialize a GRIDINFO with stub info we would use if it */ /* cannot be loaded. */ /* -------------------------------------------------------------------- */ - gilist = (PJ_GRIDINFO *) pj_malloc(sizeof(PJ_GRIDINFO)); - memset( gilist, 0, sizeof(PJ_GRIDINFO) ); + gilist = (PJ_GRIDINFO *) pj_calloc(1, sizeof(PJ_GRIDINFO)); + if (!gilist) { + pj_ctx_set_errno(ctx, ENOMEM); + return NULL; + } gilist->gridname = pj_strdup( gridname ); + if (!gilist->gridname) { + pj_dalloc(gilist); + pj_ctx_set_errno(ctx, ENOMEM); + return NULL; + } gilist->filename = NULL; gilist->format = "missing"; gilist->grid_offset = 0; @@ -883,6 +922,12 @@ PJ_GRIDINFO *pj_gridinfo_init( projCtx ctx, const char *gridname ) } gilist->filename = pj_strdup(fname); + if (!gilist->filename) { + pj_dalloc(gilist->gridname); + pj_dalloc(gilist); + pj_ctx_set_errno(ctx, ENOMEM); + return NULL; + } /* -------------------------------------------------------------------- */ /* Load a header, to determine the file type. */ diff --git a/src/pj_gridlist.c b/src/pj_gridlist.c index 1123274e..4617591c 100644 --- a/src/pj_gridlist.c +++ b/src/pj_gridlist.c @@ -28,6 +28,7 @@ #define PJ_LIB__ +#include #include #include #include @@ -103,6 +104,10 @@ static int pj_gridlist_merge_gridfile( projCtx ctx, int new_max = *p_gridmax + 20; new_list = (PJ_GRIDINFO **) pj_calloc(new_max, sizeof(void *)); + if (!new_list) { + pj_ctx_set_errno( ctx, ENOMEM ); + return 0; + } if( *p_gridlist != NULL ) { memcpy( new_list, *p_gridlist, @@ -132,8 +137,6 @@ static int pj_gridlist_merge_gridfile( projCtx ctx, if( this_grid == NULL ) { - /* we should get at least a stub grid with a missing "ct" member */ - assert( FALSE ); return 0; } diff --git a/src/pj_strtod.c b/src/pj_strtod.c index 9a66f70f..4c03a661 100644 --- a/src/pj_strtod.c +++ b/src/pj_strtod.c @@ -101,8 +101,11 @@ static char* pj_replace_point_by_locale_point(const char* pszNumber, char point, strcpy(pszWorkBuffer, pszNumber); pszNew = pszWorkBuffer; } - else + else { pszNew = pj_strdup(pszNumber); + if (!pszNew) + return NULL; + } pszNew[pszPoint - pszNumber] = byPoint; return pszNew; } @@ -127,8 +130,11 @@ static char* pj_replace_point_by_locale_point(const char* pszNumber, char point, strcpy(pszWorkBuffer, pszNumber); pszNew = pszWorkBuffer; } - else + else { pszNew = pj_strdup(pszNumber); + if (!pszNew) + return NULL; + } if( pszLocalePoint ) pszNew[pszLocalePoint - pszNumber] = ' '; if( pszPoint ) -- cgit v1.2.3 From 95d51f1df697d0ab3367ee92af40c1494878ca92 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Fri, 20 Oct 2017 14:47:14 +0200 Subject: Repair statistics for ROUNDTRIP tests --- src/gie.c | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'src') diff --git a/src/gie.c b/src/gie.c index 91af00b9..6ff157ac 100644 --- a/src/gie.c +++ b/src/gie.c @@ -474,6 +474,11 @@ static int roundtrip (char *args) { T.op_ko++; T.total_ko++; } + else { + T.op_ok++; + T.total_ok++; + } + return 0; } -- cgit v1.2.3 From 9311b85611ad78158dfc62098e96e45930b5d825 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Fri, 20 Oct 2017 22:11:18 +0200 Subject: Addition of an "area of use" argument to proj_transform_crs_to_crs (#565) In anticipation of a late-binding implementation of the proj_transform_crs_to_crs function an area argument is added to the function prototype. The PJ_AREA struct is not in use yet, but will be when the function is more tightly coupled to the EPSG database in the future. --- src/PJ_cart.c | 4 ++-- src/pj_obs_api.c | 15 ++++++++++++--- src/proj.h | 12 +++++++++++- src/projects.h | 6 ++++++ 4 files changed, 31 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/PJ_cart.c b/src/PJ_cart.c index 914fa94b..37aa3b97 100644 --- a/src/PJ_cart.c +++ b/src/PJ_cart.c @@ -457,7 +457,7 @@ int pj_cart_selftest (void) { proj_destroy (P); /* test proj_create_crs_to_crs() */ - P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "epsg:25832", "epsg:25833"); + P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "epsg:25832", "epsg:25833", NULL); if (P==0) return 50; @@ -472,7 +472,7 @@ int pj_cart_selftest (void) { proj_destroy(P); /* let's make sure that only entries in init-files results in a usable PJ */ - P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "proj=utm +zone=32 +datum=WGS84", "proj=utm +zone=33 +datum=WGS84"); + P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "proj=utm +zone=32 +datum=WGS84", "proj=utm +zone=33 +datum=WGS84", NULL); if (P != 0) { proj_destroy(P); return 52; diff --git a/src/pj_obs_api.c b/src/pj_obs_api.c index 9f699fcf..55da9fa2 100644 --- a/src/pj_obs_api.c +++ b/src/pj_obs_api.c @@ -388,13 +388,13 @@ PJ *proj_create_argv (PJ_CONTEXT *ctx, int argc, char **argv) { } /*****************************************************************************/ -PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *srid_from, const char *srid_to) { +PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *srid_from, const char *srid_to, PJ_AREA *area) { /****************************************************************************** Create a transformation pipeline between two known coordinate reference systems. srid_from and srid_to should be the value part of a +init=... parameter - set, i.e. "epsg:25833" or "IGNF:AMST63". Any projection definition that is + set, i.e. "epsg:25833" or "IGNF:AMST63". Any projection definition that can be found in a init-file in PROJ_LIB is a valid input to this function. For now the function mimics the cs2cs app: An input and an output CRS is @@ -403,14 +403,23 @@ PJ *proj_create_crs_to_crs (PJ_CONTEXT *ctx, const char *srid_from, const char function can be extended to support "late-binding" transformations in the future without affecting users of the function. + An "area of use" can be specified in area. In the current version of this + function is has no function, but is added in anticipation of a + "late-binding" implementation in the future. The idea being, that if a user + supplies an area of use, the more accurate transformation between two given + systems can be chosen. + Example call: - PJ *P = proj_create_crs_to_crs(0, "epsg:25832", "epsg:25833"); + PJ *P = proj_create_crs_to_crs(0, "epsg:25832", "epsg:25833", NULL); ******************************************************************************/ PJ *P; char buffer[512]; + /* area not in use yet, suppressing warning */ + (void)area; + strcpy(buffer, "+proj=pipeline +step +init="); strncat(buffer, srid_from, 512-strlen(buffer)); strncat(buffer, " +inv +step +init=", 512-strlen(buffer)); diff --git a/src/proj.h b/src/proj.h index 3af1584c..aa9f3b17 100644 --- a/src/proj.h +++ b/src/proj.h @@ -182,6 +182,9 @@ typedef union PJ_TRIPLET PJ_TRIPLET; union PJ_COORD; typedef union PJ_COORD PJ_COORD; +struct PJ_AREA; +typedef struct PJ_AREA PJ_AREA; + struct DERIVS; typedef struct DERIVS PJ_DERIVS; @@ -295,6 +298,7 @@ union PJ_PAIR { double v[2]; /* Yes - It's really just a vector! */ }; + struct PJ_OBS { PJ_COORD coo; /* coordinate data */ PJ_TRIPLET anc; /* ancillary data */ @@ -302,6 +306,7 @@ struct PJ_OBS { unsigned int flags; /* additional data, intended for flags */ }; + #define PJ_IS_ANAL_XL_YL 01 /* derivatives of lon analytic */ #define PJ_IS_ANAL_XP_YP 02 /* derivatives of lat analytic */ #define PJ_IS_ANAL_HK 04 /* h and k analytic */ @@ -363,9 +368,14 @@ PJ_CONTEXT *proj_context_destroy (PJ_CONTEXT *ctx); /* Manage the transformation definition object PJ */ PJ *proj_create (PJ_CONTEXT *ctx, const char *definition); PJ *proj_create_argv (PJ_CONTEXT *ctx, int argc, char **argv); -PJ *proj_create_crs_to_crs(PJ_CONTEXT *ctx, const char *srid_from, const char *srid_to); +PJ *proj_create_crs_to_crs(PJ_CONTEXT *ctx, const char *srid_from, const char *srid_to, PJ_AREA *area); PJ *proj_destroy (PJ *P); +/* Setter-functions for the opaque PJ_AREA struct */ +/* Uncomment these when implementing support for area-based transformations. +void proj_area_bbox(PJ_AREA *area, LP ll, LP ur); +void proj_area_description(PJ_AREA *area, const char *descr); +*/ /* Apply transformation to observation - in forward or inverse direction */ enum PJ_DIRECTION { diff --git a/src/projects.h b/src/projects.h index 2af382e5..cbb980ca 100644 --- a/src/projects.h +++ b/src/projects.h @@ -200,6 +200,12 @@ struct PJ_REGION_S { double ur_lat; }; +struct PJ_AREA { + int id; /* Area ID in the EPSG database */ + LP ll; /* Lower left corner of bounding box */ + LP ur; /* Upper right corner of bounding box */ + char descr[64]; /* text representation of area */ +}; struct projCtx_t; typedef struct projCtx_t projCtx_t; -- cgit v1.2.3 From 05eed057d109f650b41c6abf3dd3574a346aec10 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Sat, 21 Oct 2017 02:34:10 +0200 Subject: Make sure units of latlong operations are treated correctly (#620) Added 4D fwd/inv functions and unit descriptors to the latlong PJ object to work properly in pipelines. --- src/PJ_latlong.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/PJ_latlong.c b/src/PJ_latlong.c index dec69b70..1677142a 100644 --- a/src/PJ_latlong.c +++ b/src/PJ_latlong.c @@ -29,7 +29,8 @@ /* very loosely based upon DMA code by Bradford W. Drew */ #define PJ_LIB__ -#include +#include +#include "projects.h" PROJ_HEAD(lonlat, "Lat/long (Geodetic)") "\n\t"; PROJ_HEAD(latlon, "Lat/long (Geodetic alias)") "\n\t"; @@ -52,6 +53,15 @@ static LP inverse(XY xy, PJ *P) { return lp; } +static PJ_OBS forward_obs(PJ_OBS obs, PJ *P) { + (void) P; + return obs; +} + +static PJ_OBS inverse_obs(PJ_OBS obs, PJ *P) { + (void) P; + return obs; +} PJ *PROJECTION(latlong) { P->is_latlong = 1; @@ -59,6 +69,10 @@ PJ *PROJECTION(latlong) { P->y0 = 0.0; P->inv = inverse; P->fwd = forward; + P->invobs = inverse_obs; + P->fwdobs = forward_obs; + P->left = PJ_IO_UNITS_RADIANS; + P->right = PJ_IO_UNITS_RADIANS; return P; } @@ -70,6 +84,10 @@ PJ *PROJECTION(longlat) { P->y0 = 0.0; P->inv = inverse; P->fwd = forward; + P->invobs = inverse_obs; + P->fwdobs = forward_obs; + P->left = PJ_IO_UNITS_RADIANS; + P->right = PJ_IO_UNITS_RADIANS; return P; } @@ -81,6 +99,10 @@ PJ *PROJECTION(latlon) { P->y0 = 0.0; P->inv = inverse; P->fwd = forward; + P->invobs = inverse_obs; + P->fwdobs = forward_obs; + P->left = PJ_IO_UNITS_RADIANS; + P->right = PJ_IO_UNITS_RADIANS; return P; } @@ -90,7 +112,12 @@ PJ *PROJECTION(lonlat) { P->is_latlong = 1; P->x0 = 0.0; P->y0 = 0.0; - P->inv = inverse; P->fwd = forward; + P->inv = inverse; + P->fwd = forward; + P->invobs = inverse_obs; + P->fwdobs = forward_obs; + P->left = PJ_IO_UNITS_RADIANS; + P->right = PJ_IO_UNITS_RADIANS; return P; } -- cgit v1.2.3 From 11e5226a96f2e77dac210d38b8afc11e34a2c196 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Tue, 24 Oct 2017 18:34:40 +0200 Subject: Extend proj_strtod test case collection and improve its strtod-replication --- src/proj_strtod.c | 66 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/proj_strtod.c b/src/proj_strtod.c index d4063b0b..757dfaf6 100644 --- a/src/proj_strtod.c +++ b/src/proj_strtod.c @@ -121,10 +121,16 @@ double proj_strtod(const char *str, char **endptr) { /* Empty string? */ if (0==*p) { - errno = EINVAL; if (endptr) - *endptr = p; - return HUGE_VAL; + *endptr = (char *) str; + return 0; + } + + /* non-numeric? */ + if (0==strchr("0123456789+-._", *p)) { + if (endptr) + *endptr = (char *) str; + return 0; } /* Then handle optional prefixed sign and skip prefix zeros */ @@ -137,9 +143,15 @@ double proj_strtod(const char *str, char **endptr) { if (isdigit(*p) || '_'==*p || '.'==*p) break; if (endptr) - *endptr = p; - errno = EINVAL; - return HUGE_VAL; + *endptr = (char *) str; + return 0; + } + + /* stray sign, as in "+/-"? */ + if (0!=sign && (0==strchr ("0123456789._", *p) || 0==*p)) { + if (endptr) + *endptr = (char *) str; + return 0; } /* skip prefixed zeros before '.' */ @@ -147,8 +159,11 @@ double proj_strtod(const char *str, char **endptr) { p++; /* zero? */ - if (0==*p || 0==strchr ("0123456789eE.", *p)) - return 0; + if ((0==*p) || 0==strchr ("0123456789eE.", *p) || isspace(*p)) { + if (endptr) + *endptr = p; + return sign==-1? -0: 0; + } /* Now expect a (potentially zero-length) string of digits */ while (isdigit(*p) || ('_'==*p)) { @@ -228,8 +243,15 @@ double proj_strtod(const char *str, char **endptr) { number = -number; /* Do we have an exponent part? */ - if (*p == 'e' || *p == 'E') { + while (*p == 'e' || *p == 'E') { p++; + + /* Just a stray "e", as in 100elephants? */ + if (0==*p || 0==strchr ("0123456789+-_", *p)) { + p--; + break; + } + while ('_'==*p) p++; /* Does it have a sign? */ @@ -263,6 +285,7 @@ double proj_strtod(const char *str, char **endptr) { if (-1==sign) n = -n; exponent += n; + break; } if (endptr) @@ -351,14 +374,31 @@ int main (int argc, char **argv) { errno = 0; - test ("1"); - test ("0"); + test (""); + test (" "); + test (" abcde"); + test (" edcba"); + test ("abcde"); + test ("edcba"); + test ("+"); + test ("-"); + test ("+ "); + test ("- "); + test (" + "); + test (" - "); + test ("e 1"); + test ("e1"); + test ("0 66"); test ("1."); test ("0."); test ("1.0"); test ("0.0"); - test ("1.0"); - test ("0.0"); + test ("1 "); + test ("0 "); + test ("-0 "); + test ("0_ "); + test ("0_"); + test ("1e"); test ("_1.0"); test ("_0.0"); test ("1_.0"); -- cgit v1.2.3 From 2ad201bdb0f3408eed0aab07fe255c6ff1cd3249 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Tue, 24 Oct 2017 23:36:13 +0200 Subject: Make gie roundtrips compatible with updated proj_strtod In order to mimic strtod, proj_strtod now returns 0 and not HUGE_VAL on nonnumeric input. Hence, we must check the return pointers to identify an error. --- src/gie.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gie.c b/src/gie.c index 6ff157ac..33fc4d82 100644 --- a/src/gie.c +++ b/src/gie.c @@ -457,11 +457,11 @@ static int accept (char *args) { static int roundtrip (char *args) { int ntrips; double d, r, ans; - char *endp; + char *endp, *endq; ans = proj_strtod (args, &endp); ntrips = (int) (ans==HUGE_VAL? 100: fabs(ans)); - d = proj_strtod (endp, &endp); - d = d==HUGE_VAL? T.tolerance: d / 1000; + d = proj_strtod (endp, &endq); + d = (endp==endq)? T.tolerance: d / 1000; r = proj_roundtrip (T.P, PJ_FWD, ntrips, T.a); if (r > d) { if (T.verbosity > -1) { -- cgit v1.2.3 From a3fa749bc4f378d005c9e3fd809c0be25de5ffb2 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Wed, 25 Oct 2017 10:39:56 +0200 Subject: Remove PJ_OBS from the API surface, rename pj_obs_api.c to pj_4D_api.c (#625) * Remove PJ_OBS from the API surface, rename pj_obs_api.c to pj_4D_api.c * Repair proj.def --- src/Makefile.am | 2 +- src/PJ_cart.c | 10 +- src/PJ_helmert.c | 4 +- src/PJ_latlong.c | 3 +- src/lib_proj.cmake | 2 +- src/makefile.vc | 2 +- src/pj_internal.c | 55 +++- src/pj_obs_api.c | 818 ---------------------------------------------------- src/proj.def | 75 +++-- src/proj.h | 19 +- src/proj_4D_api.c | 752 +++++++++++++++++++++++++++++++++++++++++++++++ src/proj_internal.h | 9 + src/projects.h | 6 +- 13 files changed, 863 insertions(+), 894 deletions(-) delete mode 100644 src/pj_obs_api.c create mode 100644 src/proj_4D_api.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index a039151d..363f2cce 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -85,7 +85,7 @@ libproj_la_SOURCES = \ jniproj.c pj_mutex.c pj_initcache.c pj_apply_vgridshift.c geodesic.c \ pj_strtod.c \ \ - pj_obs_api.c PJ_cart.c PJ_pipeline.c PJ_horner.c PJ_helmert.c \ + proj_4D_api.c PJ_cart.c PJ_pipeline.c PJ_horner.c PJ_helmert.c \ PJ_vgridshift.c PJ_hgridshift.c PJ_unitconvert.c PJ_molodensky.c \ pj_internal.c diff --git a/src/PJ_cart.c b/src/PJ_cart.c index 37aa3b97..99e1af7d 100644 --- a/src/PJ_cart.c +++ b/src/PJ_cart.c @@ -387,10 +387,10 @@ int pj_cart_selftest (void) { b = proj_trans_obs (P, PJ_FWD, obs[1]); n = proj_transform ( - P, PJ_FWD, + P, PJ_FWD, &(obs[0].coo.lpz.lam), sz, 2, &(obs[0].coo.lpz.phi), sz, 2, - &(obs[0].coo.lpz.z), sz, 2, + &(obs[0].coo.lpz.z), sz, 2, 0, sz, 0 ); if (2!=n) @@ -408,10 +408,10 @@ int pj_cart_selftest (void) { h = 27; t = 33; n = proj_transform ( - P, PJ_FWD, + P, PJ_FWD, &(obs[0].coo.lpz.lam), sz, 2, &(obs[0].coo.lpz.phi), sz, 2, - &h, 0, 1, + &h, 0, 1, &t, 0, 1 ); if (2!=n) @@ -429,7 +429,7 @@ int pj_cart_selftest (void) { obs[0].coo = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); obs[1].coo = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); - if (proj_transform_obs(P, PJ_FWD, 2, obs)) + if (proj_transform_coord(P, PJ_FWD, 2, (PJ_COORD *) obs)) return 30; if (a.coo.lpz.lam != obs[0].coo.lpz.lam) return 31; diff --git a/src/PJ_helmert.c b/src/PJ_helmert.c index ffbdd01a..503dc392 100644 --- a/src/PJ_helmert.c +++ b/src/PJ_helmert.c @@ -668,11 +668,11 @@ int pj_helmert_selftest (void) { matrix is updated when necessary. Test coordinates from GNSStrans. */ XYZ expect4a = {3370658.18890, 711877.42370, 5349787.12430}; XYZ expect4b = {3370658.18087, 711877.42750, 5349787.12648}; - PJ_OBS in4 = {{{3370658.378, 711877.314, 5349787.086, 2017.0}}, {{ 0, 0, 0}}, 0, 0}; + PJ_OBS in4 = {{{3370658.378, 711877.314, 5349787.086, 2017.0}}}; PJ_OBS out; PJ *helmert = proj_create( - 0, + 0, " +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" diff --git a/src/PJ_latlong.c b/src/PJ_latlong.c index 1677142a..7ee41e2a 100644 --- a/src/PJ_latlong.c +++ b/src/PJ_latlong.c @@ -1,6 +1,6 @@ /****************************************************************************** * Project: PROJ.4 - * Purpose: Stub projection implementation for lat/long coordinates. We + * Purpose: Stub projection implementation for lat/long coordinates. We * don't actually change the coordinates, but we want proj=latlong * to act sort of like a projection. * Author: Frank Warmerdam, warmerdam@pobox.com @@ -29,6 +29,7 @@ /* very loosely based upon DMA code by Bradford W. Drew */ #define PJ_LIB__ +#include "proj_internal.h" #include #include "projects.h" diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 1be10362..053e9ef6 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -201,7 +201,7 @@ SET(SRC_LIBPROJ_CORE pj_mlfn.c pj_msfn.c pj_mutex.c - pj_obs_api.c + proj_4D_api.c pj_internal.c proj_internal.h pj_open_lib.c diff --git a/src/makefile.vc b/src/makefile.vc index fdf03bd3..1330e9bb 100644 --- a/src/makefile.vc +++ b/src/makefile.vc @@ -60,7 +60,7 @@ support = \ pj_internal.obj pipeline = \ - pj_obs_api.obj PJ_cart.obj PJ_pipeline.obj PJ_horner.obj PJ_helmert.obj \ + proj_4D_api.obj PJ_cart.obj PJ_pipeline.obj PJ_horner.obj PJ_helmert.obj \ PJ_vgridshift.obj PJ_hgridshift.obj PJ_unitconvert.obj PJ_molodensky.obj geodesic = geodesic.obj diff --git a/src/pj_internal.c b/src/pj_internal.c index 31c299ac..5eb98afb 100644 --- a/src/pj_internal.c +++ b/src/pj_internal.c @@ -1,8 +1,9 @@ /****************************************************************************** * Project: PROJ.4 - * Purpose: This is primarily material originating from pj_obs_api.c, - * that does not fit into the API category. Hence this pile of - * tubings and fittings for PROJ.4 internal plumbing. + * Purpose: This is primarily material originating from pj_obs_api.c + * (now proj_4D_api.c), that does not fit into the API + * category. Hence this pile of tubings and fittings for + * PROJ.4 internal plumbing. * * Author: Thomas Knudsen, thokn@sdfe.dk, 2017-07-05 * @@ -42,12 +43,52 @@ /* Used for zero-initializing new objects */ const PJ_COORD proj_coord_null = {{0, 0, 0, 0}}; const PJ_OBS proj_obs_null = { - {{0, 0, 0, 0}}, - {{0, 0, 0}}, - 0, 0 + {{0, 0, 0, 0}} }; + +/* Initialize PJ_OBS struct */ +PJ_OBS proj_obs (double x, double y, double z, double t) { + PJ_OBS res; + res.coo = proj_coord (x, y, z, t); + return res; +} + + + + + + + + + + + + + + +/* Apply the transformation P to the coordinate coo */ +PJ_OBS proj_trans_obs (PJ *P, PJ_DIRECTION direction, PJ_OBS obs) { + if (0==P) + return obs; + + switch (direction) { + case PJ_FWD: + return pj_fwdobs (obs, P); + case PJ_INV: + return pj_invobs (obs, P); + case PJ_IDENT: + return obs; + default: + break; + } + + proj_errno_set (P, EINVAL); + return proj_obs_error (); +} + + /* Work around non-constness of MSVC HUGE_VAL by providing functions rather than constants */ PJ_COORD proj_coord_error (void) { PJ_COORD c; @@ -58,8 +99,6 @@ PJ_COORD proj_coord_error (void) { PJ_OBS proj_obs_error (void) { PJ_OBS obs; obs.coo = proj_coord_error (); - obs.anc.v[0] = obs.anc.v[1] = obs.anc.v[2] = HUGE_VAL; - obs.id = obs.flags = 0; return obs; } diff --git a/src/pj_obs_api.c b/src/pj_obs_api.c deleted file mode 100644 index 55da9fa2..00000000 --- a/src/pj_obs_api.c +++ /dev/null @@ -1,818 +0,0 @@ -/****************************************************************************** - * Project: PROJ.4 - * Purpose: Implement a (currently minimalistic) proj API based primarily - * on the PJ_OBS generic geodetic data type. - * - * proj thread contexts have not seen widespread use, so one of the - * intentions with this new API is to make them less visible on the - * API surface: Contexts do not have a life by themselves, they are - * visible only through their associated PJs, and the number of - * functions supporting them is limited. - * - * Author: Thomas Knudsen, thokn@sdfe.dk, 2016-06-09/2016-11-06 - * - ****************************************************************************** - * Copyright (c) 2016, 2017 Thomas Knudsen/SDFE - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - *****************************************************************************/ -#define PJ_OBS_API_C -#include -#include "proj_internal.h" -#include "projects.h" -#include "geodesic.h" -#include -#include - - -/* Initialize PJ_COORD struct */ -PJ_COORD proj_coord (double x, double y, double z, double t) { - PJ_COORD res; - res.v[0] = x; - res.v[1] = y; - res.v[2] = z; - res.v[3] = t; - return res; -} - -/* Initialize PJ_OBS struct */ -PJ_OBS proj_obs (double x, double y, double z, double t, double o, double p, double k, int id, unsigned int flags) { - PJ_OBS res; - res.coo.v[0] = x; - res.coo.v[1] = y; - res.coo.v[2] = z; - res.coo.v[3] = t; - res.anc.v[0] = o; - res.anc.v[1] = p; - res.anc.v[2] = k; - res.id = id; - res.flags = flags; - - return res; -} - - - -/* 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; - /* Note: the geodesic code takes arguments in degrees */ - geod_inverse (P->geod, PJ_TODEG(a.phi), PJ_TODEG(a.lam), PJ_TODEG(b.phi), PJ_TODEG(b.lam), &s12, &azi1, &azi2); - return s12; -} - -/* 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); -} - -/* Euclidean distance between two points with linear 3D coordinates */ -double proj_xyz_dist (XYZ a, XYZ b) { - return hypot (hypot (a.x - b.x, a.y - b.y), a.z - b.z); -} - - - -/* Measure numerical deviation after n roundtrips fwd-inv (or inv-fwd) */ -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; - - if (n < 1) { - proj_errno_set (P, EINVAL); - return HUGE_VAL; - } - - o = coo; - - switch (direction) { - case PJ_FWD: - for (i = 0; i < n; i++) { - u = pj_fwdcoord (o, P); - o = pj_invcoord (u, P); - } - break; - case PJ_INV: - for (i = 0; i < n; i++) { - u = pj_invcoord (o, P); - o = pj_fwdcoord (u, P); - } - break; - default: - proj_errno_set (P, EINVAL); - 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) - return hypot (proj_lp_dist (P, coo.lp, o.lp), coo.lpz.z - o.lpz.z); - - return proj_xyz_dist (coo.xyz, coo.xyz); -} - - - - - - - - - - - - - -/* Apply the transformation P to the coordinate coo */ -PJ_OBS proj_trans_obs (PJ *P, PJ_DIRECTION direction, PJ_OBS obs) { - if (0==P) - return obs; - - switch (direction) { - case PJ_FWD: - return pj_fwdobs (obs, P); - case PJ_INV: - return pj_invobs (obs, P); - case PJ_IDENT: - return obs; - default: - break; - } - - proj_errno_set (P, EINVAL); - return proj_obs_error (); -} - - - -/* Apply the transformation P to the coordinate coo */ -PJ_COORD proj_trans_coord (PJ *P, PJ_DIRECTION direction, PJ_COORD coo) { - if (0==P) - return coo; - - switch (direction) { - case PJ_FWD: - return pj_fwdcoord (coo, P); - case PJ_INV: - return pj_invcoord (coo, P); - case PJ_IDENT: - return coo; - default: - break; - } - - proj_errno_set (P, EINVAL); - return proj_coord_error (); -} - - - -/*************************************************************************************/ -size_t proj_transform ( - PJ *P, - PJ_DIRECTION direction, - double *x, size_t sx, size_t nx, - double *y, size_t sy, size_t ny, - double *z, size_t sz, size_t nz, - double *t, size_t st, size_t nt -) { -/************************************************************************************** - - Transform a series of coordinates, where the individual coordinate dimension - may be represented by an array that is either - - 1. fully populated - 2. a null pointer and/or a length of zero, which will be treated as a - fully populated array of zeroes - 3. of length one, i.e. a constant, which will be treated as a fully - populated array of that constant value - - The strides, sx, sy, sz, st, represent the step length, in bytes, between - consecutive elements of the corresponding array. This makes it possible for - proj_transform to handle transformation of a large class of application - specific data structures, without necessarily understanding the data structure - format, as in: - - typedef struct {double x, y; int quality_level; char surveyor_name[134];} XYQS; - XYQS survey[345]; - double height = 23.45; - PJ *P = {...}; - size_t stride = sizeof (XYQS); - ... - proj_transform ( - P, PJ_INV, sizeof(XYQS), - &(survey[0].x), stride, 345, (* We have 345 eastings *) - &(survey[0].y), stride, 345, (* ...and 345 northings. *) - &height, 1, (* The height is the constant 23.45 m *) - 0, 0 (* and the time is the constant 0.00 s *) - ); - - This is similar to the inner workings of the pj_transform function, but the - stride functionality has been generalized to work for any size of basic unit, - not just a fixed number of doubles. - - In most cases, the stride will be identical for x, y,z, and t, since they will - typically be either individual arrays (stride = sizeof(double)), or strided - views into an array of application specific data structures (stride = sizeof (...)). - - But in order to support cases where x, y, z, and t come from heterogeneous - sources, individual strides, sx, sy, sz, st, are used. - - Caveat: Since proj_transform does its work *in place*, this means that even the - supposedly constants (i.e. length 1 arrays) will return from the call in altered - state. Hence, remember to reinitialize between repeated calls. - - Return value: Number of transformations completed. - -**************************************************************************************/ - PJ_COORD coord = proj_coord_null; - size_t i, nmin; - double null_broadcast = 0; - if (0==P) - return 0; - - /* ignore lengths of null arrays */ - if (0==x) nx = 0; - if (0==y) ny = 0; - if (0==z) nz = 0; - if (0==t) nt = 0; - - /* and make the nullities point to some real world memory for broadcasting nulls */ - if (0==nx) x = &null_broadcast; - if (0==ny) y = &null_broadcast; - if (0==nz) z = &null_broadcast; - if (0==nt) t = &null_broadcast; - - /* nothing to do? */ - if (0==nx+ny+nz+nt) - return 0; - - /* arrays of length 1 are constants, which we broadcast along the longer arrays */ - /* so we need to find the length of the shortest non-unity array to figure out */ - /* how many coordinate pairs we must transform */ - nmin = (nx > 1)? nx: (ny > 1)? ny: (nz > 1)? nz: (nt > 1)? nt: 1; - if ((nx > 1) && (nx < nmin)) nmin = nx; - if ((ny > 1) && (ny < nmin)) nmin = ny; - if ((nz > 1) && (nz < nmin)) nmin = nz; - if ((nt > 1) && (nt < nmin)) nmin = nt; - - /* Check validity of direction flag */ - switch (direction) { - case PJ_FWD: - case PJ_INV: - break; - case PJ_IDENT: - return nmin; - default: - proj_errno_set (P, EINVAL); - return 0; - } - - /* Arrays of length==0 are broadcast as the constant 0 */ - /* Arrays of length==1 are broadcast as their single value */ - /* Arrays of length >1 are iterated over (for the first nmin values) */ - /* The slightly convolved incremental indexing is used due */ - /* to the stride, which may be any size supported by the platform */ - for (i = 0; i < nmin; i++) { - coord.xyzt.x = *x; - coord.xyzt.y = *y; - coord.xyzt.z = *z; - coord.xyzt.t = *t; - - if (PJ_FWD==direction) - coord = pj_fwdcoord (coord, P); - else - coord = pj_invcoord (coord, P); - - /* in all full length cases, we overwrite the input with the output */ - if (nx > 1) { - *x = coord.xyzt.x; - x = (double *) ( ((char *) x) + sx); - } - if (ny > 1) { - *y = coord.xyzt.y; - y = (double *) ( ((char *) y) + sy); - } - if (nz > 1) { - *z = coord.xyzt.z; - z = (double *) ( ((char *) z) + sz); - } - if (nt > 1) { - *t = coord.xyzt.t; - t = (double *) ( ((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) - *y = coord.xyzt.y; - if (nz==1) - *z = coord.xyzt.z; - if (nt==1) - *t = coord.xyzt.t; - - return i; -} - -/*****************************************************************************/ -int proj_transform_obs (PJ *P, PJ_DIRECTION direction, size_t n, PJ_OBS *obs) { -/****************************************************************************** - Batch transform an array of PJ_OBS. - - Returns 0 if all observations are transformed without error, otherwise - returns error number. -******************************************************************************/ - size_t i; - for (i=0; i= 511) - continue; - - if (strlen(info.searchpath) != 0) { - strcat(info.searchpath, ";"); - len = strlen(paths[i]); - strncat(info.searchpath, paths[i], sizeof(info.searchpath)-len-1); - } else { - pj_strlcpy(info.searchpath, paths[i], sizeof(info.searchpath)); - } - } - - return info; -} - - -/*****************************************************************************/ -PJ_PROJ_INFO proj_pj_info(PJ *P) { -/****************************************************************************** - Basic info about a particular instance of a projection object. - - Returns PJ_PROJ_INFO struct. - -******************************************************************************/ - PJ_PROJ_INFO info; - char *def; - - memset(&info, 0, sizeof(PJ_PROJ_INFO)); - - /* Expected accuracy of the transformation. Hardcoded for now, will be improved */ - /* later. Most likely to be used when a transformation is set up with */ - /* proj_create_crs_to_crs in a future version that leverages the EPSG database. */ - info.accuracy = -1.0; - - if (!P) { - return info; - } - - /* projection id */ - if (pj_param(P->ctx, P->params, "tproj").i) - pj_strlcpy(info.id, pj_param(P->ctx, P->params, "sproj").s, sizeof(info.id)); - - /* projection description */ - pj_strlcpy(info.description, P->descr, sizeof(info.description)); - - /* projection definition */ - def = pj_get_def(P, 0); /* pj_get_def takes a non-const PJ pointer */ - pj_strlcpy(info.definition, &def[1], sizeof(info.definition)); /* def includes a leading space */ - pj_dealloc(def); - - /* this does not take into account that a pipeline potentially does not */ - /* have an inverse. */ - info.has_inverse = (P->inv != 0 || P->inv3d != 0 || P->invobs != 0); - - return info; -} - - -/*****************************************************************************/ -PJ_GRID_INFO proj_grid_info(const char *gridname) { -/****************************************************************************** - Information about a named datum grid. - - Returns PJ_GRID_INFO struct. - -******************************************************************************/ - PJ_GRID_INFO info; - - /*PJ_CONTEXT *ctx = proj_context_create(); */ - PJ_CONTEXT *ctx = pj_get_default_ctx(); - PJ_GRIDINFO *gridinfo = pj_gridinfo_init(ctx, gridname); - memset(&info, 0, sizeof(PJ_GRID_INFO)); - - /* in case the grid wasn't found */ - if (gridinfo->filename == NULL) { - pj_gridinfo_free(ctx, gridinfo); - strcpy(info.format, "missing"); - return info; - } - - /* name of grid */ - pj_strlcpy(info.gridname, gridname, sizeof(info.gridname)); - - /* full path of grid */ - pj_find_file(ctx, gridname, info.filename, sizeof(info.filename)); - - /* grid format */ - pj_strlcpy(info.format, gridinfo->format, sizeof(info.format)); - - /* grid size */ - info.n_lon = gridinfo->ct->lim.lam; - info.n_lat = gridinfo->ct->lim.phi; - - /* cell size */ - info.cs_lon = gridinfo->ct->del.lam; - info.cs_lat = gridinfo->ct->del.phi; - - /* bounds of grid */ - info.lowerleft = gridinfo->ct->ll; - info.upperright.lam = info.lowerleft.lam + info.n_lon*info.cs_lon; - info.upperright.phi = info.lowerleft.phi + info.n_lat*info.cs_lat; - - pj_gridinfo_free(ctx, gridinfo); - - return info; -} - -/*****************************************************************************/ -PJ_INIT_INFO proj_init_info(const char *initname){ -/****************************************************************************** - Information about a named init file. - - Maximum length of initname is 64. - - Returns PJ_INIT_INFO struct. - - If the init file is not found all members of - the return struct are set to 0. If the init file is found, but it the - metadata is missing, the value is set to "Unknown". - -******************************************************************************/ - int file_found, def_found=0; - char param[80], key[74]; - paralist *start, *next; - PJ_INIT_INFO info; - PJ_CONTEXT *ctx = pj_get_default_ctx(); - - memset(&info, 0, sizeof(PJ_INIT_INFO)); - - file_found = pj_find_file(ctx, initname, info.filename, sizeof(info.filename)); - if (!file_found || strlen(initname) > 64) { - return info; - } - - pj_strlcpy(info.name, initname, sizeof(info.name)); - strcpy(info.origin, "Unknown"); - strcpy(info.version, "Unknown"); - strcpy(info.lastupdate, "Unknown"); - - pj_strlcpy(key, initname, 64); /* make room for ":metadata\0" at the end */ - strncat(key, ":metadata", 9); - strcpy(param, "+init="); - strncat(param, key, 73); - - start = pj_mkparam(param); - next = pj_get_init(ctx, &start, start, key, &def_found); - - if (pj_param(ctx, start, "tversion").i) { - pj_strlcpy(info.version, pj_param(ctx, start, "sversion").s, sizeof(info.version)); - } - - if (pj_param(ctx, start, "torigin").i) { - pj_strlcpy(info.origin, pj_param(ctx, start, "sorigin").s, sizeof(info.origin)); - } - - if (pj_param(ctx, start, "tlastupdate").i) { - pj_strlcpy(info.lastupdate, pj_param(ctx, start, "slastupdate").s, sizeof(info.lastupdate)); - } - - for ( ; start; start = next) { - next = start->next; - pj_dalloc(start); - } - - return info; -} - - -/*****************************************************************************/ -PJ_DERIVS proj_derivatives(PJ *P, const LP lp) { -/****************************************************************************** - Derivatives of coordinates. - - returns PJ_DERIVS. If unsuccessfull error number is set and the returned - struct contains NULL data. - -******************************************************************************/ - PJ_DERIVS derivs; - - if (pj_deriv(lp, 1e-5, P, &derivs)) { - /* errno set in pj_derivs */ - memset(&derivs, 0, sizeof(PJ_DERIVS)); - } - - return derivs; -} - - -/*****************************************************************************/ -PJ_FACTORS proj_factors(PJ *P, const LP lp) { -/****************************************************************************** - Cartographic characteristics at point lp. - - Characteristics include meridian, parallel and areal scales, angular - distortion, meridian/parallel, meridian convergence and scale error. - - returns PJ_FACTORS. If unsuccessfull error number is set and the returned - struct contains NULL data. - -******************************************************************************/ - PJ_FACTORS factors; - - /* pj_factors rely code being zero */ - factors.code = 0; - - if (pj_factors(lp, P, 0.0, &factors)) { - /* errno set in pj_factors */ - memset(&factors, 0, sizeof(PJ_FACTORS)); - } - - return factors; -} - - -const PJ_ELLPS *proj_list_ellps(void) { - return pj_get_ellps_ref(); -} - -const PJ_UNITS *proj_list_units(void) { - return pj_get_units_ref(); -} - -const PJ_OPERATIONS *proj_list_operations(void) { - return pj_get_list_ref(); -} - -const PJ_PRIME_MERIDIANS *proj_list_prime_meridians(void) { - return pj_get_prime_meridians_ref(); -} - -double proj_torad (double angle_in_degrees) { return PJ_TORAD (angle_in_degrees);} -double proj_todeg (double angle_in_radians) { return PJ_TODEG (angle_in_radians);} - - -double proj_dmstor(const char *is, char **rs) { - return dmstor(is, rs); -} - -char* proj_rtodms(char *s, double r, int pos, int neg) { - return rtodms(s, r, pos, neg); -} diff --git a/src/proj.def b/src/proj.def index 598f2824..86deb24d 100644 --- a/src/proj.def +++ b/src/proj.def @@ -100,50 +100,49 @@ EXPORTS proj_trans_obs @95 proj_trans_coord @96 proj_transform @97 - proj_transform_obs @98 - proj_transform_coord @99 - proj_roundtrip @100 + proj_transform_coord @98 + proj_roundtrip @99 - proj_coord @101 - proj_obs @102 - proj_coord_error @103 - proj_obs_error @104 + proj_coord @100 + proj_obs @101 + proj_coord_error @102 + proj_obs_error @103 - proj_errno @105 - proj_errno_set @106 - proj_errno_reset @107 - proj_errno_restore @108 - proj_context_errno_set @109 + proj_errno @104 + proj_errno_set @105 + proj_errno_reset @106 + proj_errno_restore @107 + proj_context_errno_set @108 - proj_context_create @110 - proj_context_set @111 - proj_context_inherit @112 - proj_context_destroy @113 + proj_context_create @109 + proj_context_set @110 + proj_context_inherit @111 + proj_context_destroy @112 - proj_lp_dist @114 - proj_xy_dist @115 - proj_xyz_dist @116 + proj_lp_dist @113 + proj_xy_dist @114 + proj_xyz_dist @115 - proj_log_level @117 - proj_log_func @118 - proj_log_error @119 - proj_log_debug @120 - proj_log_trace @121 + proj_log_level @116 + proj_log_func @117 + proj_log_error @118 + proj_log_debug @119 + proj_log_trace @120 - proj_info @122 - proj_pj_info @123 - proj_grid_info @124 - proj_init_info @125 + proj_info @121 + proj_pj_info @122 + proj_grid_info @123 + proj_init_info @124 - proj_torad @126 - proj_todeg @127 - proj_rtodms @128 - proj_dmstor @129 + proj_torad @125 + proj_todeg @126 + proj_rtodms @127 + proj_dmstor @128 - proj_derivatives @130 - proj_factors @131 + proj_derivatives @129 + proj_factors @130 - proj_list_operations @132 - proj_list_ellps @133 - proj_list_units @134 - proj_list_prime_meridians @135 + proj_list_operations @131 + proj_list_ellps @132 + proj_list_units @133 + proj_list_prime_meridians @134 diff --git a/src/proj.h b/src/proj.h index aa9f3b17..ed885091 100644 --- a/src/proj.h +++ b/src/proj.h @@ -90,7 +90,7 @@ * compatible call proj_context_create(0), which will not create * a new context, but simply provide a pointer to the default one. * - * See pj_obs_api_test.c for an example of how to use the API. + * See proj_4D_api_test.c for examples of how to use the API. * * Author: Thomas Knudsen, * Benefitting from a large number of comments and suggestions @@ -170,10 +170,6 @@ extern char const pj_release[]; /* global release id string */ /* first forward declare everything needed */ -/* Data type for generic geodetic observations */ -struct PJ_OBS; -typedef struct PJ_OBS PJ_OBS; - /* Data type for generic geodetic 3D data */ union PJ_TRIPLET; typedef union PJ_TRIPLET PJ_TRIPLET; @@ -299,14 +295,6 @@ union PJ_PAIR { }; -struct PJ_OBS { - PJ_COORD coo; /* coordinate data */ - PJ_TRIPLET anc; /* ancillary data */ - int id; /* integer ancillary data - e.g. observation number, EPSG code... */ - unsigned int flags; /* additional data, intended for flags */ -}; - - #define PJ_IS_ANAL_XL_YL 01 /* derivatives of lon analytic */ #define PJ_IS_ANAL_XP_YP 02 /* derivatives of lat analytic */ #define PJ_IS_ANAL_HK 04 /* h and k analytic */ @@ -385,7 +373,6 @@ enum PJ_DIRECTION { }; typedef enum PJ_DIRECTION PJ_DIRECTION; -PJ_OBS proj_trans_obs (PJ *P, PJ_DIRECTION direction, PJ_OBS obs); PJ_COORD proj_trans_coord (PJ *P, PJ_DIRECTION direction, PJ_COORD coord); @@ -398,16 +385,14 @@ size_t proj_transform ( double *t, size_t st, size_t nt ); -int proj_transform_obs (PJ *P, PJ_DIRECTION direction, size_t n, PJ_OBS *obs); int proj_transform_coord (PJ *P, PJ_DIRECTION direction, size_t n, PJ_COORD *coord); /* Initializers */ PJ_COORD proj_coord (double x, double y, double z, double t); -PJ_OBS proj_obs (double x, double y, double z, double t, double o, double p, double k, int id, unsigned int flags); /* Measure internal consistency - in forward or inverse direction */ 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); diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c new file mode 100644 index 00000000..b1aa3883 --- /dev/null +++ b/src/proj_4D_api.c @@ -0,0 +1,752 @@ +/****************************************************************************** + * Project: PROJ.4 + * Purpose: Implement a (currently minimalistic) proj API based primarily + * on the PJ_COORD 4D geodetic spatiotemporal data type. + * + * proj thread contexts have not seen widespread use, so one of the + * intentions with this new API is to make them less visible on the + * API surface: Contexts do not have a life by themselves, they are + * visible only through their associated PJs, and the number of + * functions supporting them is limited. + * + * Author: Thomas Knudsen, thokn@sdfe.dk, 2016-06-09/2016-11-06 + * + ****************************************************************************** + * Copyright (c) 2016, 2017 Thomas Knudsen/SDFE + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + *****************************************************************************/ +#include +#include "proj_internal.h" +#include "projects.h" +#include "geodesic.h" +#include +#include + + +/* Initialize PJ_COORD struct */ +PJ_COORD proj_coord (double x, double y, double z, double t) { + PJ_COORD res; + res.v[0] = x; + res.v[1] = y; + res.v[2] = z; + res.v[3] = t; + return res; +} + + + +/* 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; + /* Note: the geodesic code takes arguments in degrees */ + geod_inverse (P->geod, PJ_TODEG(a.phi), PJ_TODEG(a.lam), PJ_TODEG(b.phi), PJ_TODEG(b.lam), &s12, &azi1, &azi2); + return s12; +} + +/* 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); +} + +/* Euclidean distance between two points with linear 3D coordinates */ +double proj_xyz_dist (XYZ a, XYZ b) { + return hypot (hypot (a.x - b.x, a.y - b.y), a.z - b.z); +} + + + +/* Measure numerical deviation after n roundtrips fwd-inv (or inv-fwd) */ +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; + + if (n < 1) { + proj_errno_set (P, EINVAL); + return HUGE_VAL; + } + + o = coo; + + switch (direction) { + case PJ_FWD: + for (i = 0; i < n; i++) { + u = pj_fwdcoord (o, P); + o = pj_invcoord (u, P); + } + break; + case PJ_INV: + for (i = 0; i < n; i++) { + u = pj_invcoord (o, P); + o = pj_fwdcoord (u, P); + } + break; + default: + proj_errno_set (P, EINVAL); + 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) + return hypot (proj_lp_dist (P, coo.lp, o.lp), coo.lpz.z - o.lpz.z); + + return proj_xyz_dist (coo.xyz, coo.xyz); +} + + + +/* Apply the transformation P to the coordinate coo */ +PJ_COORD proj_trans_coord (PJ *P, PJ_DIRECTION direction, PJ_COORD coo) { + if (0==P) + return coo; + + switch (direction) { + case PJ_FWD: + return pj_fwdcoord (coo, P); + case PJ_INV: + return pj_invcoord (coo, P); + case PJ_IDENT: + return coo; + default: + break; + } + + proj_errno_set (P, EINVAL); + return proj_coord_error (); +} + + + +/*************************************************************************************/ +size_t proj_transform ( + PJ *P, + PJ_DIRECTION direction, + double *x, size_t sx, size_t nx, + double *y, size_t sy, size_t ny, + double *z, size_t sz, size_t nz, + double *t, size_t st, size_t nt +) { +/************************************************************************************** + + Transform a series of coordinates, where the individual coordinate dimension + may be represented by an array that is either + + 1. fully populated + 2. a null pointer and/or a length of zero, which will be treated as a + fully populated array of zeroes + 3. of length one, i.e. a constant, which will be treated as a fully + populated array of that constant value + + The strides, sx, sy, sz, st, represent the step length, in bytes, between + consecutive elements of the corresponding array. This makes it possible for + proj_transform to handle transformation of a large class of application + specific data structures, without necessarily understanding the data structure + format, as in: + + typedef struct {double x, y; int quality_level; char surveyor_name[134];} XYQS; + XYQS survey[345]; + double height = 23.45; + PJ *P = {...}; + size_t stride = sizeof (XYQS); + ... + proj_transform ( + P, PJ_INV, sizeof(XYQS), + &(survey[0].x), stride, 345, (* We have 345 eastings *) + &(survey[0].y), stride, 345, (* ...and 345 northings. *) + &height, 1, (* The height is the constant 23.45 m *) + 0, 0 (* and the time is the constant 0.00 s *) + ); + + This is similar to the inner workings of the pj_transform function, but the + stride functionality has been generalized to work for any size of basic unit, + not just a fixed number of doubles. + + In most cases, the stride will be identical for x, y,z, and t, since they will + typically be either individual arrays (stride = sizeof(double)), or strided + views into an array of application specific data structures (stride = sizeof (...)). + + But in order to support cases where x, y, z, and t come from heterogeneous + sources, individual strides, sx, sy, sz, st, are used. + + Caveat: Since proj_transform does its work *in place*, this means that even the + supposedly constants (i.e. length 1 arrays) will return from the call in altered + state. Hence, remember to reinitialize between repeated calls. + + Return value: Number of transformations completed. + +**************************************************************************************/ + PJ_COORD coord = proj_coord_null; + size_t i, nmin; + double null_broadcast = 0; + if (0==P) + return 0; + + /* ignore lengths of null arrays */ + if (0==x) nx = 0; + if (0==y) ny = 0; + if (0==z) nz = 0; + if (0==t) nt = 0; + + /* and make the nullities point to some real world memory for broadcasting nulls */ + if (0==nx) x = &null_broadcast; + if (0==ny) y = &null_broadcast; + if (0==nz) z = &null_broadcast; + if (0==nt) t = &null_broadcast; + + /* nothing to do? */ + if (0==nx+ny+nz+nt) + return 0; + + /* arrays of length 1 are constants, which we broadcast along the longer arrays */ + /* so we need to find the length of the shortest non-unity array to figure out */ + /* how many coordinate pairs we must transform */ + nmin = (nx > 1)? nx: (ny > 1)? ny: (nz > 1)? nz: (nt > 1)? nt: 1; + if ((nx > 1) && (nx < nmin)) nmin = nx; + if ((ny > 1) && (ny < nmin)) nmin = ny; + if ((nz > 1) && (nz < nmin)) nmin = nz; + if ((nt > 1) && (nt < nmin)) nmin = nt; + + /* Check validity of direction flag */ + switch (direction) { + case PJ_FWD: + case PJ_INV: + break; + case PJ_IDENT: + return nmin; + default: + proj_errno_set (P, EINVAL); + return 0; + } + + /* Arrays of length==0 are broadcast as the constant 0 */ + /* Arrays of length==1 are broadcast as their single value */ + /* Arrays of length >1 are iterated over (for the first nmin values) */ + /* The slightly convolved incremental indexing is used due */ + /* to the stride, which may be any size supported by the platform */ + for (i = 0; i < nmin; i++) { + coord.xyzt.x = *x; + coord.xyzt.y = *y; + coord.xyzt.z = *z; + coord.xyzt.t = *t; + + if (PJ_FWD==direction) + coord = pj_fwdcoord (coord, P); + else + coord = pj_invcoord (coord, P); + + /* in all full length cases, we overwrite the input with the output */ + if (nx > 1) { + *x = coord.xyzt.x; + x = (double *) ( ((char *) x) + sx); + } + if (ny > 1) { + *y = coord.xyzt.y; + y = (double *) ( ((char *) y) + sy); + } + if (nz > 1) { + *z = coord.xyzt.z; + z = (double *) ( ((char *) z) + sz); + } + if (nt > 1) { + *t = coord.xyzt.t; + t = (double *) ( ((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) + *y = coord.xyzt.y; + if (nz==1) + *z = coord.xyzt.z; + if (nt==1) + *t = coord.xyzt.t; + + return i; +} + +/*****************************************************************************/ +int proj_transform_coord (PJ *P, PJ_DIRECTION direction, size_t n, PJ_COORD *coord) { +/****************************************************************************** + Batch transform an array of PJ_COORD. + + Returns 0 if all coordinates are transformed without error, otherwise + returns error number. +******************************************************************************/ + size_t i; + for (i=0; i= 511) + continue; + + if (strlen(info.searchpath) != 0) { + strcat(info.searchpath, ";"); + len = strlen(paths[i]); + strncat(info.searchpath, paths[i], sizeof(info.searchpath)-len-1); + } else { + pj_strlcpy(info.searchpath, paths[i], sizeof(info.searchpath)); + } + } + + return info; +} + + +/*****************************************************************************/ +PJ_PROJ_INFO proj_pj_info(PJ *P) { +/****************************************************************************** + Basic info about a particular instance of a projection object. + + Returns PJ_PROJ_INFO struct. + +******************************************************************************/ + PJ_PROJ_INFO info; + char *def; + + memset(&info, 0, sizeof(PJ_PROJ_INFO)); + + /* Expected accuracy of the transformation. Hardcoded for now, will be improved */ + /* later. Most likely to be used when a transformation is set up with */ + /* proj_create_crs_to_crs in a future version that leverages the EPSG database. */ + info.accuracy = -1.0; + + if (!P) { + return info; + } + + /* projection id */ + if (pj_param(P->ctx, P->params, "tproj").i) + pj_strlcpy(info.id, pj_param(P->ctx, P->params, "sproj").s, sizeof(info.id)); + + /* projection description */ + pj_strlcpy(info.description, P->descr, sizeof(info.description)); + + /* projection definition */ + def = pj_get_def(P, 0); /* pj_get_def takes a non-const PJ pointer */ + pj_strlcpy(info.definition, &def[1], sizeof(info.definition)); /* def includes a leading space */ + pj_dealloc(def); + + /* this does not take into account that a pipeline potentially does not */ + /* have an inverse. */ + info.has_inverse = (P->inv != 0 || P->inv3d != 0 || P->invobs != 0); + + return info; +} + + +/*****************************************************************************/ +PJ_GRID_INFO proj_grid_info(const char *gridname) { +/****************************************************************************** + Information about a named datum grid. + + Returns PJ_GRID_INFO struct. + +******************************************************************************/ + PJ_GRID_INFO info; + + /*PJ_CONTEXT *ctx = proj_context_create(); */ + PJ_CONTEXT *ctx = pj_get_default_ctx(); + PJ_GRIDINFO *gridinfo = pj_gridinfo_init(ctx, gridname); + memset(&info, 0, sizeof(PJ_GRID_INFO)); + + /* in case the grid wasn't found */ + if (gridinfo->filename == NULL) { + pj_gridinfo_free(ctx, gridinfo); + strcpy(info.format, "missing"); + return info; + } + + /* name of grid */ + pj_strlcpy(info.gridname, gridname, sizeof(info.gridname)); + + /* full path of grid */ + pj_find_file(ctx, gridname, info.filename, sizeof(info.filename)); + + /* grid format */ + pj_strlcpy(info.format, gridinfo->format, sizeof(info.format)); + + /* grid size */ + info.n_lon = gridinfo->ct->lim.lam; + info.n_lat = gridinfo->ct->lim.phi; + + /* cell size */ + info.cs_lon = gridinfo->ct->del.lam; + info.cs_lat = gridinfo->ct->del.phi; + + /* bounds of grid */ + info.lowerleft = gridinfo->ct->ll; + info.upperright.lam = info.lowerleft.lam + info.n_lon*info.cs_lon; + info.upperright.phi = info.lowerleft.phi + info.n_lat*info.cs_lat; + + pj_gridinfo_free(ctx, gridinfo); + + return info; +} + +/*****************************************************************************/ +PJ_INIT_INFO proj_init_info(const char *initname){ +/****************************************************************************** + Information about a named init file. + + Maximum length of initname is 64. + + Returns PJ_INIT_INFO struct. + + If the init file is not found all members of + the return struct are set to 0. If the init file is found, but it the + metadata is missing, the value is set to "Unknown". + +******************************************************************************/ + int file_found, def_found=0; + char param[80], key[74]; + paralist *start, *next; + PJ_INIT_INFO info; + PJ_CONTEXT *ctx = pj_get_default_ctx(); + + memset(&info, 0, sizeof(PJ_INIT_INFO)); + + file_found = pj_find_file(ctx, initname, info.filename, sizeof(info.filename)); + if (!file_found || strlen(initname) > 64) { + return info; + } + + pj_strlcpy(info.name, initname, sizeof(info.name)); + strcpy(info.origin, "Unknown"); + strcpy(info.version, "Unknown"); + strcpy(info.lastupdate, "Unknown"); + + pj_strlcpy(key, initname, 64); /* make room for ":metadata\0" at the end */ + strncat(key, ":metadata", 9); + strcpy(param, "+init="); + strncat(param, key, 73); + + start = pj_mkparam(param); + next = pj_get_init(ctx, &start, start, key, &def_found); + + if (pj_param(ctx, start, "tversion").i) { + pj_strlcpy(info.version, pj_param(ctx, start, "sversion").s, sizeof(info.version)); + } + + if (pj_param(ctx, start, "torigin").i) { + pj_strlcpy(info.origin, pj_param(ctx, start, "sorigin").s, sizeof(info.origin)); + } + + if (pj_param(ctx, start, "tlastupdate").i) { + pj_strlcpy(info.lastupdate, pj_param(ctx, start, "slastupdate").s, sizeof(info.lastupdate)); + } + + for ( ; start; start = next) { + next = start->next; + pj_dalloc(start); + } + + return info; +} + + +/*****************************************************************************/ +PJ_DERIVS proj_derivatives(PJ *P, const LP lp) { +/****************************************************************************** + Derivatives of coordinates. + + returns PJ_DERIVS. If unsuccessfull error number is set and the returned + struct contains NULL data. + +******************************************************************************/ + PJ_DERIVS derivs; + + if (pj_deriv(lp, 1e-5, P, &derivs)) { + /* errno set in pj_derivs */ + memset(&derivs, 0, sizeof(PJ_DERIVS)); + } + + return derivs; +} + + +/*****************************************************************************/ +PJ_FACTORS proj_factors(PJ *P, const LP lp) { +/****************************************************************************** + Cartographic characteristics at point lp. + + Characteristics include meridian, parallel and areal scales, angular + distortion, meridian/parallel, meridian convergence and scale error. + + returns PJ_FACTORS. If unsuccessfull error number is set and the returned + struct contains NULL data. + +******************************************************************************/ + PJ_FACTORS factors; + + /* pj_factors rely code being zero */ + factors.code = 0; + + if (pj_factors(lp, P, 0.0, &factors)) { + /* errno set in pj_factors */ + memset(&factors, 0, sizeof(PJ_FACTORS)); + } + + return factors; +} + + +const PJ_ELLPS *proj_list_ellps(void) { + return pj_get_ellps_ref(); +} + +const PJ_UNITS *proj_list_units(void) { + return pj_get_units_ref(); +} + +const PJ_OPERATIONS *proj_list_operations(void) { + return pj_get_list_ref(); +} + +const PJ_PRIME_MERIDIANS *proj_list_prime_meridians(void) { + return pj_get_prime_meridians_ref(); +} + +double proj_torad (double angle_in_degrees) { return PJ_TORAD (angle_in_degrees);} +double proj_todeg (double angle_in_radians) { return PJ_TODEG (angle_in_radians);} + + +double proj_dmstor(const char *is, char **rs) { + return dmstor(is, rs); +} + +char* proj_rtodms(char *s, double r, int pos, int neg) { + return rtodms(s, r, pos, neg); +} diff --git a/src/proj_internal.h b/src/proj_internal.h index 0b74b563..5773637c 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -50,6 +50,12 @@ extern "C" { +struct PJ_OBS { + PJ_COORD coo; /* coordinate data */ +}; +typedef struct PJ_OBS PJ_OBS; + + #ifndef PJ_TODEG #define PJ_TODEG(rad) ((rad)*180.0/M_PI) #endif @@ -59,6 +65,9 @@ extern "C" { +PJ_OBS proj_obs (double x, double y, double z, double t); +PJ_OBS proj_trans_obs (PJ *P, PJ_DIRECTION direction, PJ_OBS obs); + PJ_COORD proj_coord_error (void); PJ_OBS proj_obs_error (void); #ifndef PJ_INTERNAL_C diff --git a/src/projects.h b/src/projects.h index cbb980ca..b9d88cf3 100644 --- a/src/projects.h +++ b/src/projects.h @@ -174,6 +174,9 @@ typedef struct { double u, v, w; } UVW; /* Forward declarations and typedefs for stuff needed inside the PJ object */ struct PJconsts; struct PJ_OBS; +#ifndef PROJ_INTERNAL_H +typedef struct PJ_OBS PJ_OBS; +#endif union PJ_COORD; struct geod_geodesic; struct pj_opaque; @@ -189,7 +192,6 @@ enum pj_io_units { }; #ifndef PROJ_H typedef struct PJconsts PJ; /* the PJ object herself */ -typedef struct PJ_OBS PJ_OBS; typedef union PJ_COORD PJ_COORD; #endif @@ -259,7 +261,7 @@ struct PJconsts { void (*spc)(LP, PJ *, struct FACTORS *); void *(*destructor)(PJ *, int); - + /************************************************************************************* -- cgit v1.2.3 From a15c64a4f82a9996ee2d6a21de902f6bc80dc4ac Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Wed, 25 Oct 2017 13:11:48 +0200 Subject: Repair gie and cct after breakage due to proj_strtod update (#628) * Repair gie and cct after breakage due to proj_strtod update * Remove unused variables --- src/cct.c | 20 +++++++++---- src/gie.c | 99 +++++++++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 80 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/cct.c b/src/cct.c index 35d4ec3f..72d8c6cc 100644 --- a/src/cct.c +++ b/src/cct.c @@ -289,22 +289,32 @@ char *column (char *buf, int n) { return buf; } +/* column to double */ +static double cold (char *args, int col) { + char *endp; + char *target; + double d; + target = column (args, col); + d = proj_strtod (target, &endp); + if (endp==target) + return HUGE_VAL; + return d; +} PJ_COORD parse_input_line (char *buf, int *columns, double fixed_height, double fixed_time) { PJ_COORD err = proj_coord (HUGE_VAL, HUGE_VAL, HUGE_VAL, HUGE_VAL); PJ_COORD result = err; int prev_errno = errno; - char *endptr = 0; errno = 0; result.xyzt.z = fixed_height; result.xyzt.t = fixed_time; - result.xyzt.x = proj_strtod (column (buf, columns[0]), &endptr); - result.xyzt.y = proj_strtod (column (buf, columns[1]), &endptr); + result.xyzt.x = cold (buf, columns[0]); + result.xyzt.y = cold (buf, columns[1]); if (result.xyzt.z==HUGE_VAL) - result.xyzt.z = proj_strtod (column (buf, columns[2]), &endptr); + result.xyzt.z = cold (buf, columns[2]); if (result.xyzt.t==HUGE_VAL) - result.xyzt.t = proj_strtod (column (buf, columns[3]), &endptr); + result.xyzt.t = cold (buf, columns[3]); if (0!=errno) return err; diff --git a/src/gie.c b/src/gie.c index 33fc4d82..f0850b61 100644 --- a/src/gie.c +++ b/src/gie.c @@ -132,6 +132,7 @@ static int get_inp (FILE *f, char *inp, int size); static int get_cmnd (char *inp, char *cmnd, int len); static char *get_args (char *inp); static int dispatch (char *cmnd, char *args); +static char *column (char *buf, int n); @@ -314,6 +315,52 @@ static int process_file (char *fname) { } +/* return a pointer to the n'th column of buf */ +char *column (char *buf, int n) { + int i; + if (n <= 0) + return buf; + for (i = 0; i < n; i++) { + while (isspace(*buf)) + buf++; + if (i == n - 1) + break; + while ((0 != *buf) && !isspace(*buf)) + buf++; + } + return buf; +} + + + +static double strtod_scaled (char *args, double default_scale) { + double s; + char *endp = args; + s = proj_strtod (args, &endp); + if (args==endp) + return HUGE_VAL; + + endp = column (args, 2); + + if (0==strcmp(endp, "km")) + s *= 1000; + else if (0==strcmp(endp, "m")) + s *= 1; + else if (0==strcmp(endp, "dm")) + s /= 10; + else if (0==strcmp(endp, "cm")) + s /= 100; + else if (0==strcmp(endp, "mm")) + s /= 1000; + else if (0==strcmp(endp, "um")) + s /= 1e6; + else if (0==strcmp(endp, "nm")) + s /= 1e9; + else + s *= default_scale; + return s; +} + @@ -334,31 +381,11 @@ static int banner (char *args) { static int tolerance (char *args) { - char *endp = args; - T.tolerance = proj_strtod (endp, &endp); + T.tolerance = strtod_scaled (args, 1); if (HUGE_VAL==T.tolerance) { T.tolerance = 0.0005; return 1; } - while (isspace (*endp)) - endp++; - - if (0==strcmp(endp, "km")) - T.tolerance *= 1000; - else if (0==strcmp(endp, "m")) - T.tolerance *= 1; - else if (0==strcmp(endp, "dm")) - T.tolerance /= 10; - else if (0==strcmp(endp, "cm")) - T.tolerance /= 100; - else if (0==strcmp(endp, "mm")) - T.tolerance /= 1000; - else if (0==strcmp(endp, "um")) - T.tolerance /= 1e6; - else if (0==strcmp(endp, "nm")) - T.tolerance /= 1e9; - else - T.tolerance /= 1000; /* If no unit, assume mm */ return 0; } @@ -436,15 +463,17 @@ static PJ_COORD torad_if_needed (PJ *P, PJ_DIRECTION dir, PJ_COORD a) { static int accept (char *args) { int n, i; - char *endp = args; + char *endp, *prev = args; T.a = proj_coord (0,0,0,0); n = 4; for (i = 0; i < 4; i++) { - T.a.v[i] = proj_strtod (endp, &endp); - if (HUGE_VAL==T.a.v[i]) { + T.a.v[i] = proj_strtod (prev, &endp); + if (prev==endp) { n--; T.a.v[i] = 0; + break; } + prev = endp; } T.a = torad_if_needed (T.P, T.dir, T.a); if (T.verbosity > 3) @@ -457,11 +486,11 @@ static int accept (char *args) { static int roundtrip (char *args) { int ntrips; double d, r, ans; - char *endp, *endq; + char *endp; ans = proj_strtod (args, &endp); - ntrips = (int) (ans==HUGE_VAL? 100: fabs(ans)); - d = proj_strtod (endp, &endq); - d = (endp==endq)? T.tolerance: d / 1000; + 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) { @@ -469,7 +498,7 @@ static int roundtrip (char *args) { 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 deivation: %.3f mm, expected: %.3f mm\n", 1000*r, 1000*d); + fprintf (T.fout, " roundtrip deviation: %.3f mm, expected: %.3f mm\n", 1000*r, 1000*d); } T.op_ko++; T.total_ko++; @@ -485,18 +514,20 @@ static int roundtrip (char *args) { static int expect (char *args) { double d; enum pj_io_units unit; - char *endp = args; + 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 (endp, &endp); - if (HUGE_VAL==T.e.v[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); @@ -525,8 +556,8 @@ static int expect (char *args) { d = proj_xyz_dist (T.b.xyz, T.e.xyz); if (d > T.tolerance) { - if (d > 10) - d = 9.999999; + if (d > 1e6) + d = 999999.999999; if (T.verbosity > -1) { if (0==T.op_ko && T.verbosity < 2) banner (T.operation); -- cgit v1.2.3 From 076247ec39e8ad1ce9554744b8c65b26f43b2017 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Wed, 25 Oct 2017 20:46:56 +0200 Subject: Remove superfluous internal selftests from projection files matching patterns PJ_f....c and PJ_e....c --- src/PJ_fahey.c | 44 +------------ src/PJ_fouc_s.c | 44 +------------ src/PJ_gall.c | 44 +------------ src/PJ_geos.c | 59 +---------------- src/PJ_gins8.c | 30 +-------- src/PJ_gn_sinu.c | 197 ++----------------------------------------------------- src/PJ_gnom.c | 44 +------------ src/PJ_goode.c | 46 +------------ src/PJ_gstmerc.c | 45 +------------ 9 files changed, 14 insertions(+), 539 deletions(-) (limited to 'src') diff --git a/src/PJ_fahey.c b/src/PJ_fahey.c index 42318f8f..4fcb7849 100644 --- a/src/PJ_fahey.c +++ b/src/PJ_fahey.c @@ -37,46 +37,4 @@ PJ *PROJECTION(fahey) { return P; } -#ifndef PJ_SELFTEST -int pj_fahey_selftest (void) {return 0;} -#else - -int pj_fahey_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=fahey +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 182993.34464912376, 101603.19356988439}, - { 182993.34464912376, -101603.19356988439}, - {-182993.34464912376, 101603.19356988439}, - {-182993.34464912376, -101603.19356988439}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {0.0021857886080359551, 0.00098424601668238403}, - {0.0021857886080359551, -0.00098424601668238403}, - {-0.0021857886080359551, 0.00098424601668238403}, - {-0.0021857886080359551, -0.00098424601668238403}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_fahey_selftest (void) {return 10000;} diff --git a/src/PJ_fouc_s.c b/src/PJ_fouc_s.c index 343e5878..c581e690 100644 --- a/src/PJ_fouc_s.c +++ b/src/PJ_fouc_s.c @@ -67,46 +67,4 @@ PJ *PROJECTION(fouc_s) { } -#ifndef PJ_SELFTEST -int pj_fouc_s_selftest (void) {return 0;} -#else - -int pj_fouc_s_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=fouc_s +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223402.14425527424, 111695.40119861449}, - { 223402.14425527424, -111695.40119861449}, - {-223402.14425527424, 111695.40119861449}, - {-223402.14425527424, -111695.40119861449}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017904931097838226, 0.000895246554928339}, - { 0.0017904931097838226, -0.000895246554928339}, - {-0.0017904931097838226, 0.000895246554928339}, - {-0.0017904931097838226, -0.000895246554928339}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_fouc_s_selftest (void) {return 10000;} diff --git a/src/PJ_gall.c b/src/PJ_gall.c index 01a56e33..8a003073 100644 --- a/src/PJ_gall.c +++ b/src/PJ_gall.c @@ -41,46 +41,4 @@ PJ *PROJECTION(gall) { } -#ifndef PJ_SELFTEST -int pj_gall_selftest (void) {return 0;} -#else - -int pj_gall_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=gall +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 157969.17113451968, 95345.249178385886}, - { 157969.17113451968, -95345.249178385886}, - {-157969.17113451968, 95345.249178385886}, - {-157969.17113451968, -95345.249178385886}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0025321396391918614, 0.001048846580346495}, - { 0.0025321396391918614, -0.001048846580346495}, - {-0.0025321396391918614, 0.001048846580346495}, - {-0.0025321396391918614, -0.001048846580346495}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_gall_selftest (void) {return 10000;} diff --git a/src/PJ_geos.c b/src/PJ_geos.c index 5fd3e56b..7d527409 100644 --- a/src/PJ_geos.c +++ b/src/PJ_geos.c @@ -234,61 +234,4 @@ PJ *PROJECTION(geos) { } -#ifndef PJ_SELFTEST -int pj_geos_selftest (void) {return 0;} -#else - -int pj_geos_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=geos +ellps=GRS80 +lat_1=0.5 +lat_2=2 +h=35785831"}; - char s_args[] = {"+proj=geos +R=6400000 +lat_1=0.5 +lat_2=2 +h=35785831"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222527.07036580026, 110551.30341332949}, - { 222527.07036580026, -110551.30341332949}, - {-222527.07036580026, 110551.30341332949}, - {-222527.07036580026, -110551.30341332949}, - }; - - XY s_fwd_expect[] = { - { 223289.45763579503, 111677.65745653701}, - { 223289.45763579503, -111677.65745653701}, - {-223289.45763579503, 111677.65745653701}, - {-223289.45763579503, -111677.65745653701}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017966305689715385, 0.00090436947723267452}, - { 0.0017966305689715385, -0.00090436947723267452}, - {-0.0017966305689715385, 0.00090436947723267452}, - {-0.0017966305689715385, -0.00090436947723267452}, - }; - - LP s_inv_expect[] = { - { 0.0017904931105078943, 0.00089524655504237148}, - { 0.0017904931105078943, -0.00089524655504237148}, - {-0.0017904931105078943, 0.00089524655504237148}, - {-0.0017904931105078943, -0.00089524655504237148}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_geos_selftest (void) {return 10000;} diff --git a/src/PJ_gins8.c b/src/PJ_gins8.c index b27ec092..26db4f31 100644 --- a/src/PJ_gins8.c +++ b/src/PJ_gins8.c @@ -31,32 +31,4 @@ PJ *PROJECTION(gins8) { } -#ifndef PJ_SELFTEST -int pj_gins8_selftest (void) {return 0;} -#else - -int pj_gins8_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=gins8 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 194350.25093959007, 111703.90763533533}, - { 194350.25093959007, -111703.90763533533}, - {-194350.25093959007, 111703.90763533533}, - {-194350.25093959007, -111703.90763533533}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif +int pj_gins8_selftest (void) {return 10000;} diff --git a/src/PJ_gn_sinu.c b/src/PJ_gn_sinu.c index d13f2834..bfe26b53 100644 --- a/src/PJ_gn_sinu.c +++ b/src/PJ_gn_sinu.c @@ -120,7 +120,7 @@ PJ *PROJECTION(sinu) { if (!(Q->en = pj_enfn(P->es))) return pj_default_destructor (P, ENOMEM); - + if (P->es != 0.0) { P->inv = e_inverse; P->fwd = e_forward; @@ -184,194 +184,7 @@ PJ *PROJECTION(gn_sinu) { } -#ifndef PJ_SELFTEST -int pj_sinu_selftest (void) {return 0;} -#else - -int pj_sinu_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=sinu +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=sinu +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222605.29953946592, 110574.38855415257}, - { 222605.29953946592, -110574.38855415257}, - {-222605.29953946592, 110574.38855415257}, - {-222605.29953946592, -110574.38855415257}, - }; - - XY s_fwd_expect[] = { - { 223368.11902663155, 111701.07212763709}, - { 223368.11902663155, -111701.07212763709}, - {-223368.11902663155, 111701.07212763709}, - {-223368.11902663155, -111701.07212763709}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017966305684613522, 0.00090436947707945409}, - { 0.0017966305684613522, -0.00090436947707945409}, - {-0.0017966305684613522, 0.00090436947707945409}, - {-0.0017966305684613522, -0.00090436947707945409}, - }; - - LP s_inv_expect[] = { - { 0.0017904931100023887, 0.00089524655489191132}, - { 0.0017904931100023887, -0.00089524655489191132}, - {-0.0017904931100023887, 0.00089524655489191132}, - {-0.0017904931100023887, -0.00089524655489191132}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif - -#ifndef PJ_SELFTEST -int pj_eck6_selftest (void) {return 0;} -#else - -int pj_eck6_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=eck6 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 197021.60562899226, 126640.42073317352}, - { 197021.60562899226, -126640.42073317352}, - {-197021.60562899226, 126640.42073317352}, - {-197021.60562899226, -126640.42073317352}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.002029978749734037, 0.00078963032910382171}, - { 0.002029978749734037, -0.00078963032910382171}, - {-0.002029978749734037, 0.00078963032910382171}, - {-0.002029978749734037, -0.00078963032910382171}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif - -#ifndef PJ_SELFTEST -int pj_mbtfps_selftest (void) {return 0;} -#else - -int pj_mbtfps_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=mbtfps +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 204740.11747857218, 121864.72971934026}, - { 204740.11747857218, -121864.72971934026}, - {-204740.11747857218, 121864.72971934026}, - {-204740.11747857218, -121864.72971934026}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0019534152166442065, 0.00082057965689633387}, - { 0.0019534152166442065, -0.00082057965689633387}, - {-0.0019534152166442065, 0.00082057965689633387}, - {-0.0019534152166442065, -0.00082057965689633387}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif - - -#ifndef PJ_SELFTEST -int pj_gn_sinu_selftest (void) {return 0;} -#else - -int pj_gn_sinu_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=gn_sinu +a=6400000 +lat_1=0.5 +lat_2=2 +m=1 +n=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223385.13250469571, 111698.23644718733}, - { 223385.13250469571, -111698.23644718733}, - {-223385.13250469571, 111698.23644718733}, - {-223385.13250469571, -111698.23644718733}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017904931098931057, 0.00089524655491012516}, - { 0.0017904931098931057, -0.00089524655491012516}, - {-0.0017904931098931057, 0.00089524655491012516}, - {-0.0017904931098931057, -0.00089524655491012516}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_sinu_selftest (void) {return 10000;} +int pj_eck6_selftest (void) {return 10000;} +int pj_mbtfps_selftest (void) {return 10000;} +int pj_gn_sinu_selftest (void) {return 10000;} diff --git a/src/PJ_gnom.c b/src/PJ_gnom.c index 1d3f3386..2aedefec 100644 --- a/src/PJ_gnom.c +++ b/src/PJ_gnom.c @@ -136,46 +136,4 @@ PJ *PROJECTION(gnom) { } -#ifndef PJ_SELFTEST -int pj_gnom_selftest (void) {return 0;} -#else - -int pj_gnom_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=gnom +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223492.92474718543, 111780.50920659291}, - { 223492.92474718543, -111780.50920659291}, - {-223492.92474718543, 111780.50920659291}, - {-223492.92474718543, -111780.50920659291}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017904931092009798, 0.00089524655438192376}, - { 0.0017904931092009798, -0.00089524655438192376}, - {-0.0017904931092009798, 0.00089524655438192376}, - {-0.0017904931092009798, -0.00089524655438192376}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_gnom_selftest (void) {return 10000;} diff --git a/src/PJ_goode.c b/src/PJ_goode.c index 3bfeb21f..3c5d172d 100644 --- a/src/PJ_goode.c +++ b/src/PJ_goode.c @@ -71,7 +71,7 @@ PJ *PROJECTION(goode) { Q->moll->ctx = P->ctx; if (!(Q->sinu = pj_sinu(Q->sinu)) || !(Q->moll = pj_moll(Q->moll))) return destructor (P, ENOMEM); - + P->fwd = s_forward; P->inv = s_inverse; @@ -79,46 +79,4 @@ PJ *PROJECTION(goode) { } -#ifndef PJ_SELFTEST -int pj_goode_selftest (void) {return 0;} -#else - -int pj_goode_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=goode +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223368.11902663155, 111701.07212763709}, - { 223368.11902663155, -111701.07212763709}, - {-223368.11902663155, 111701.07212763709}, - {-223368.11902663155, -111701.07212763709}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017904931100023887, 0.00089524655489191132}, - { 0.0017904931100023887, -0.00089524655489191132}, - {-0.0017904931100023887, 0.00089524655489191132}, - {-0.0017904931100023887, -0.00089524655489191132}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_goode_selftest (void) {return 10000;} diff --git a/src/PJ_gstmerc.c b/src/PJ_gstmerc.c index c2846761..efb44b88 100644 --- a/src/PJ_gstmerc.c +++ b/src/PJ_gstmerc.c @@ -69,47 +69,4 @@ PJ *PROJECTION(gstmerc) { } -#ifndef PJ_SELFTEST -int pj_gstmerc_selftest (void) {return 0;} -#else - -int pj_gstmerc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=gstmerc +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - - XY s_fwd_expect[] = { - { 223413.46640632182, 111769.14504058557}, - { 223413.46640632182, -111769.14504058668}, - {-223413.46640632302, 111769.14504058557}, - {-223413.46640632302, -111769.14504058668}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017904931097109673, 0.0008952465544509083}, - { 0.0017904931097109673, -0.0008952465544509083}, - {-0.0017904931097109673, 0.0008952465544509083}, - {-0.0017904931097109673, -0.0008952465544509083}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_gstmerc_selftest (void) {return 10000;} -- cgit v1.2.3 From 9649cc099728162c4c8862b7d5a69d0dfee92c1d Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Thu, 26 Oct 2017 23:10:42 +0200 Subject: Repair and improve broken cct output routine (#631) Repair and improve broken cct output routine and do a few minor cleanups --- src/cct.c | 51 ++++++++++++++++++++++++++++----------------------- 1 file changed, 28 insertions(+), 23 deletions(-) (limited to 'src') diff --git a/src/cct.c b/src/cct.c index 72d8c6cc..90b84159 100644 --- a/src/cct.c +++ b/src/cct.c @@ -44,7 +44,7 @@ Hence, in honour of cct (the geodesist) this is cct (the program). ************************************************************************ -Thomas Knudsen, thokn@sdfe.dk, 2016-05-25/2017-09-19 +Thomas Knudsen, thokn@sdfe.dk, 2016-05-25/2017-10-26 ************************************************************************ @@ -73,7 +73,7 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-25/2017-09-19 #include "optargpm.h" #include -#include +#include "projects.h" #include #include #include @@ -85,8 +85,6 @@ double proj_atof(const char *str); char *column (char *buf, int n); PJ_COORD parse_input_line (char *buf, int *columns, double fixed_height, double fixed_time); -int print_output_line (FILE *fout, char *buf, PJ_COORD point); -int main(int argc, char **argv); @@ -237,16 +235,31 @@ int main(int argc, char **argv) { } - /* Loop over all lines of all input files */ + /* Loop over all records of all input files */ while (opt_input_loop (o, optargs_file_format_text)) { void *ret = fgets (buf, 10000, o->input); - int res; opt_eof_handler (o); if (0==ret) { fprintf (stderr, "Read error in record %d\n", (int) o->record_index); continue; } point = parse_input_line (buf, columns_xyzt, fixed_z, fixed_time); + if (HUGE_VAL==point.xyzt.x) { + char *c = column (buf, 1); + + /* if it's a comment or blank line, we reflect it */ + if (c && ((*c=='\0') || (*c=='#'))) { + fprintf (fout, "%s\n", buf); + continue; + } + + /* otherwise, it must be a syntax error */ + fprintf (fout, "# Record %d UNREADABLE: %s", (int) o->record_index, buf); + if (verbose) + fprintf (stderr, "%s: Could not parse file '%s' line %d\n", o->progname, opt_filename (o), opt_record (o)); + continue; + } + if (PJ_IO_UNITS_RADIANS==input_unit) { point.lpzt.lam = proj_torad (point.lpzt.lam); point.lpzt.phi = proj_torad (point.lpzt.phi); @@ -256,13 +269,17 @@ int main(int argc, char **argv) { point.lpzt.lam = proj_todeg (point.lpzt.lam); point.lpzt.phi = proj_todeg (point.lpzt.phi); } - res = print_output_line (fout, buf, point); - if (0==res) { - fprintf (fout, "# UNREADABLE: %s", buf); - if (verbose) - fprintf (stderr, "%s: Could not parse file '%s' line %d\n", o->progname, opt_filename (o), opt_record (o)); + + if (HUGE_VAL==point.xyzt.x) { + /* transformation error (TODO provide existing internal errmsg here) */ + fprintf (fout, "# Record %d TRANSFORMATION ERROR: %s", (int) o->record_index, buf); + continue; } + + /* Time to print the result */ + fprintf (fout, "%20.15f %20.15f %20.15f %20.15f\n", point.xyzt.x, point.xyzt.y, point.xyzt.z, point.xyzt.t); } + if (stdout != fout) fclose (fout); free (o); @@ -322,15 +339,3 @@ PJ_COORD parse_input_line (char *buf, int *columns, double fixed_height, double errno = prev_errno; return result; } - - -int print_output_line (FILE *fout, char *buf, PJ_COORD point) { - char *c; - if (HUGE_VAL!=point.xyzt.x) - return fprintf (fout, "%20.15f %20.15f %20.15f %20.15f\n", point.xyzt.x, point.xyzt.y, point.xyzt.z, point.xyzt.t); - c = column (buf, 1); - /* reflect comments and blanks */ - if (c && ((*c=='\0') || (*c=='#'))) - return fprintf (fout, "%s\n", buf); - return 0; -} -- cgit v1.2.3 From 5646ff12f32adf78e2bc187e6557ce64e4e04b39 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Fri, 27 Oct 2017 22:50:40 +0200 Subject: Linguistics: Clarify this and that, here and there (#632) * Linguistics: Clarify this and that, here and there * Revert nullification of PJ_cart->fwd, inv --- src/PJ_cart.c | 32 +++++++++++++++----------------- src/PJ_helmert.c | 11 +++++++---- src/PJ_horner.c | 32 +++++++++++++++----------------- src/PJ_molodensky.c | 7 +++++++ src/PJ_pipeline.c | 21 ++++++++++++--------- src/gie.c | 9 +++++---- src/optargpm.h | 16 ++++------------ src/proj.h | 27 +++++++++++---------------- src/proj_4D_api.c | 6 ------ src/proj_strtod.c | 2 +- src/projects.h | 2 +- 11 files changed, 78 insertions(+), 87 deletions(-) (limited to 'src') diff --git a/src/PJ_cart.c b/src/PJ_cart.c index 99e1af7d..67154ab3 100644 --- a/src/PJ_cart.c +++ b/src/PJ_cart.c @@ -120,8 +120,13 @@ static double normal_radius_of_curvature (double a, double es, double phi) { /*********************************************************************/ static double geocentric_radius (double a, double b, double phi) { -/*********************************************************************/ - /* This is from WP2, but uses hypot() for potentially better numerical robustness */ +/********************************************************************* + Return the geocentric radius at latitude phi, of an ellipsoid + with semimajor axis a and semiminor axis b. + + This is from WP2, but uses hypot() for potentially better + numerical robustness +***********************************************************************/ return hypot (a*a*cos (phi), b*b*sin(phi)) / hypot (a*cos(phi), b*sin(phi)); } @@ -129,18 +134,15 @@ static double geocentric_radius (double a, double b, double phi) { /*********************************************************************/ static XYZ cartesian (LPZ geodetic, PJ *P) { /*********************************************************************/ - double N, h, lam, phi, cosphi = cos(geodetic.phi); + double N, cosphi = cos(geodetic.phi); XYZ xyz; N = normal_radius_of_curvature(P->a, P->es, geodetic.phi); - phi = geodetic.phi; - lam = geodetic.lam; - h = geodetic.z; /* HM formula 5-27 (z formula follows WP) */ - xyz.x = (N + h) * cosphi * cos(lam); - xyz.y = (N + h) * cosphi * sin(lam); - xyz.z = (N * (1 - P->es) + h) * sin(phi); + xyz.x = (N + geodetic.z) * cosphi * cos(geodetic.lam); + xyz.y = (N + geodetic.z) * cosphi * sin(geodetic.lam); + xyz.z = (N * (1 - P->es) + geodetic.z) * sin(geodetic.phi); return xyz; } @@ -149,23 +151,19 @@ static XYZ cartesian (LPZ geodetic, PJ *P) { /*********************************************************************/ static LPZ geodetic (XYZ cartesian, PJ *P) { /*********************************************************************/ - double N, b, p, theta, c, s, e2s; + double N, p, theta, c, s; LPZ lpz; /* Perpendicular distance from point to Z-axis (HM eq. 5-28) */ p = hypot (cartesian.x, cartesian.y); - /* Ancillary ellipsoidal parameters */ - b = P->b; - e2s = P->e2s; - /* HM eq. (5-37) */ - theta = atan2 (cartesian.z * P->a, p * b); + theta = atan2 (cartesian.z * P->a, p * P->b); /* HM eq. (5-36) (from BB, 1976) */ c = cos(theta); s = sin(theta); - lpz.phi = atan2 (cartesian.z + e2s*b*s*s*s, p - P->es*P->a*c*c*c); + lpz.phi = atan2 (cartesian.z + P->e2s*P->b*s*s*s, p - P->es*P->a*c*c*c); lpz.lam = atan2 (cartesian.y, cartesian.x); N = normal_radius_of_curvature (P->a, P->es, lpz.phi); @@ -176,7 +174,7 @@ static LPZ geodetic (XYZ cartesian, PJ *P) { /* by computing the height as the cartesian z value */ /* minus the geocentric radius of the Earth at the given */ /* latitude */ - double r = geocentric_radius (P->a, b, lpz.phi); + double r = geocentric_radius (P->a, P->b, lpz.phi); lpz.z = fabs (cartesian.z) - r; } else diff --git a/src/PJ_helmert.c b/src/PJ_helmert.c index 503dc392..c9c30401 100644 --- a/src/PJ_helmert.c +++ b/src/PJ_helmert.c @@ -92,8 +92,9 @@ struct pj_opaque_helmert { #define R21 (Q->R[2][1]) #define R22 (Q->R[2][2]) +/**************************************************************************/ static void update_parameters(PJ *P) { - /************************************************************************** +/*************************************************************************** Update transformation parameters. --------------------------------- @@ -114,7 +115,8 @@ static void update_parameters(PJ *P) { of that parameter. [0] http://itrf.ign.fr/doc_ITRF/Transfo-ITRF2008_ITRFs.txt - **************************************************************************/ + +*******************************************************************************/ struct pj_opaque_helmert *Q = (struct pj_opaque_helmert *) P->opaque; double dt = Q->t_obs - Q->epoch; @@ -146,8 +148,9 @@ static void update_parameters(PJ *P) { return; } +/**************************************************************************/ static void build_rot_matrix(PJ *P) { - /************************************************************************** +/*************************************************************************** Build rotation matrix. ---------------------- @@ -208,7 +211,7 @@ static void build_rot_matrix(PJ *P) { as published, the "transpose" option provides the ability to switch between the conventions. - ***************************************************************************/ +***************************************************************************/ struct pj_opaque_helmert *Q = (struct pj_opaque_helmert *) P->opaque; double f, t, p; /* phi/fi , theta, psi */ diff --git a/src/PJ_horner.c b/src/PJ_horner.c index d6d2c51c..a9a2c922 100644 --- a/src/PJ_horner.c +++ b/src/PJ_horner.c @@ -1,19 +1,3 @@ -#define PJ_LIB__ -#include "proj_internal.h" -#include "projects.h" -#include -#include -#include -#include - -PROJ_HEAD(horner, "Horner polynomial evaluation"); - -/* make horner.h interface with proj's memory management */ -#define horner_dealloc(x) pj_dealloc(x) -#define horner_calloc(n,x) pj_calloc(n,x) - -/* The next few hundred lines is mostly cut-and-paste from the horner.h header library */ - /*********************************************************************** Interfacing to a classic piece of geodetic software @@ -91,6 +75,20 @@ PROJ_HEAD(horner, "Horner polynomial evaluation"); * *****************************************************************************/ +#define PJ_LIB__ +#include "proj_internal.h" +#include "projects.h" +#include +#include +#include +#include + +PROJ_HEAD(horner, "Horner polynomial evaluation"); + +/* make horner.h interface with proj's memory management */ +#define horner_dealloc(x) pj_dealloc(x) +#define horner_calloc(n,x) pj_calloc(n,x) + struct horner; typedef struct horner HORNER; @@ -399,7 +397,7 @@ static int parse_coefs (PJ *P, double *coefs, char *param, int ncoefs) { buf = pj_calloc (strlen (param) + 2, sizeof(char)); if (0==buf) { - proj_log_error (P, "Horner: Out of core"); + proj_log_error (P, "Horner: No memory left"); return 0; } diff --git a/src/PJ_molodensky.c b/src/PJ_molodensky.c index f09f07cd..50423fd8 100644 --- a/src/PJ_molodensky.c +++ b/src/PJ_molodensky.c @@ -90,6 +90,13 @@ static double RM (double a, double es, double phi) { E.J Krakiwsky & D.B. Thomson, 1974, GEODETIC POSITION COMPUTATIONS, + + Fredericton NB, Canada: + University of New Brunswick, + Department of Geodesy and Geomatics Engineering, + Lecture Notes No. 39, + 99 pp. + http://www2.unb.ca/gge/Pubs/LN39.pdf **********************************************************/ diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index 137fdec8..ab2d3420 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -45,9 +45,10 @@ It is a very powerful concept, that increases the range of relevance of the proj.4 system substantially. It is, however, not a particularly intrusive - addition to the code base: The implementation is by and large completed by - adding an extra projection called "pipeline" (i.e. this file), which - handles all business. + addition to the PROJ.4 code base: The implementation is by and large completed + by adding an extra projection called "pipeline" (i.e. this file), which + handles all business, and a small amount of added functionality in the + pj_init code, implementing support for multilevel, embedded pipelines. Syntactically, the pipeline system introduces the "+step" keyword (which indicates the start of each transformation step), the "+omit_fwd" and @@ -63,10 +64,11 @@ Where indicate the Helmert arguments: 3 translations (+x=..., +y=..., +z=...), 3 rotations (+rx=..., +ry=..., +rz=...) and a scale factor (+s=...). - Following geodetic conventions, the rotations are given in Milliarcseconds, + Following geodetic conventions, the rotations are given in arcseconds, and the scale factor is given as parts-per-million. - [1] B. W. Kernighan & P. J. Plauger: Software tools. Addison-Wesley, 1976, 338 pp. + [1] B. W. Kernighan & P. J. Plauger: Software tools. + Reading, Massachusetts, Addison-Wesley, 1976, 338 pp. ******************************************************************************** @@ -156,10 +158,11 @@ static LP pipeline_reverse (XY xyz, PJ *P); The P->left and P->right elements indicate isomorphism. - For classic proj style projections, they both have the - value PJ_IO_UNITS_CLASSIC (default initialization), indicating - that the forward driver expects angular input coordinates, and - provides linear output coordinates. + For classic proj style projections, P->left has the value + PJ_IO_UNITS_RADIANS, while P->right has the value + PJ_IO_UNITS_CLASSIC, indicating that the forward driver expects + angular input coordinates, and provides linear output coordinates, + scaled by the P->a semimajor axis length. Newer projections may set P->left and P->right to either PJ_IO_UNITS_METERS, PJ_IO_UNITS_RADIANS or PJ_IO_UNITS_ANY, diff --git a/src/gie.c b/src/gie.c index f0850b61..269a7239 100644 --- a/src/gie.c +++ b/src/gie.c @@ -52,11 +52,12 @@ but all of them *just special functions*, and not particularly more special than the sin(), cos(), tan(), and hypot() already available in the C standard library. -And hence, *they should not be particularly much harder to use*, for a -programmer, than the sin()s, tan()s and hypot()s so readily available. +And hence, according to Gerald, *they should not be particularly much +harder to use*, for a programmer, than the sin()s, tan()s and hypot()s +so readily available. Gerald's ingenuity also showed in the implementation of the vision, -where he devised a highly comprehensible, yet simple, system of key-value +where he devised a comprehensive, yet simple, system of key-value pairs for parameterising a map projection, and the highly flexible PJ struct, storing run-time compiled versions of those key-value pairs, hence making a map projection function call, pj_fwd(PJ, point), as easy @@ -332,7 +333,7 @@ char *column (char *buf, int n) { } - +/* interpret as a numeric followed by a linear decadal prefix - return the properly scaled numeric */ static double strtod_scaled (char *args, double default_scale) { double s; char *endp = args; diff --git a/src/optargpm.h b/src/optargpm.h index c47dfec1..23e375f8 100644 --- a/src/optargpm.h +++ b/src/optargpm.h @@ -10,8 +10,8 @@ For PROJ.4 command line programs, we have a somewhat complex option decoding situation, since we have to navigate in a cocktail of classic single letter style options, prefixed by "-", GNU style long options -prefixwd by "--", transformation specification elements prefixed by "+", -and input file names prefixed by "" nothing. +prefixed by "--", transformation specification elements prefixed by "+", +and input file names prefixed by "" (i.e. nothing). Hence, classic getopt.h style decoding does not cut the mustard, so this is an attempt to catch up and chop the ketchup. @@ -48,8 +48,8 @@ Operator specs are +proj=utm +zone=32 +ellps=GRS80 Operands are bar baz -While claiming neither to save the world, nor to hint at the "shape of -jazz to come", at least optargpm has shown useful in constructing cs2cs +While neither claiming to save the world, nor to hint at the "shape of +jazz to come", at least optargpm has shown useful in constructing cs2cs style transformation filters. Supporting a wide range of option syntax, the getoptpm API is somewhat @@ -424,14 +424,6 @@ OPTARGS *opt_parse (int argc, char **argv, const char *flags, const char *keys, o->argc = argc; o->argv = argv; o->progname = opt_strip_path (argv[0]); -/* o->progname = argv[0]; - last_path_delim = strrchr (argv[0], '\\'); - if (last_path_delim > o->progname) - o->progname = last_path_delim; - last_path_delim = strrchr (argv[0], '/'); - if (last_path_delim > o->progname) - o->progname = last_path_delim; -*/ /* Reset all flags */ for (i = 0; i < (int) strlen (flags); i++) diff --git a/src/proj.h b/src/proj.h index ed885091..dd0672f9 100644 --- a/src/proj.h +++ b/src/proj.h @@ -53,26 +53,21 @@ * it remains as-is for now). * * THIRD, I try to eliminate implicit type punning. Hence this API - * introduces the PJ_OBS ("observation") data type, for generic - * coordinate and handling of ancillary data. + * introduces the PJ_COORD union data type, for generic 4D coordinate + * handling. * - * It includes the PJ_COORD and PJ_TRIPLET unions making it possible - * to make explicit the previously used "implicit type punning", where - * a XY is turned into a LP by re#defining both as UV, behind the back - * of the user. + * PJ_COORD makes it possible to make explicit the previously used + * "implicit type punning", where a XY is turned into a LP by + * re#defining both as UV, behind the back of the user. * * The PJ_COORD union is used for storing 1D, 2D, 3D and 4D coordinates. - * The PJ_TRIPLET union is used for storing any set of up to 3 related - * observations. At the application code level, the names of these - * unions will usually not be used - they will only be accessed via - * their tag names in the PJ_OBS data type. * * The bare essentials API presented here follows the PROJ.4 * convention of sailing the coordinate to be reprojected, up on * the stack ("call by value"), and symmetrically returning the - * result on the stack. Although the PJ_OBS object is 4 times - * as large as the traditional XY and LP objects, timing results - * have shown the overhead to be very reasonable. + * result on the stack. Although the PJ_COORD object is twice as large + * as the traditional XY and LP objects, timing results have shown the + * overhead to be very reasonable. * * Contexts and thread safety * -------------------------- @@ -82,8 +77,8 @@ * context subsystem is unavoidable in a multi-threaded world. * Hence, instead of hiding it away, we move it into the limelight, * highly recommending (but not formally requiring) the bracketing - * with calls to proj_context_create(...)/proj_context_destroy() of - * any code block calling PROJ.4 functions. + * of any code block calling PROJ.4 functions with calls to + * proj_context_create(...)/proj_context_destroy() * * Legacy single threaded code need not do anything, but *may* * implement a bit of future compatibility by using the backward @@ -426,7 +421,7 @@ const PJ_ELLPS *proj_list_ellps(void); const PJ_UNITS *proj_list_units(void); const PJ_PRIME_MERIDIANS *proj_list_prime_meridians(void); -/* These are trivial, and while occasionaly useful in real code, primarily here to */ +/* These are trivial, and while occasionally useful in real code, primarily here to */ /* simplify demo code, and in acknowledgement of the proj-internal discrepancy between */ /* angular units expected by classical proj, and by Charles Karney's geodesics subsystem */ double proj_torad (double angle_in_degrees); diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c index b1aa3883..5484b650 100644 --- a/src/proj_4D_api.c +++ b/src/proj_4D_api.c @@ -3,12 +3,6 @@ * Purpose: Implement a (currently minimalistic) proj API based primarily * on the PJ_COORD 4D geodetic spatiotemporal data type. * - * proj thread contexts have not seen widespread use, so one of the - * intentions with this new API is to make them less visible on the - * API surface: Contexts do not have a life by themselves, they are - * visible only through their associated PJs, and the number of - * functions supporting them is limited. - * * Author: Thomas Knudsen, thokn@sdfe.dk, 2016-06-09/2016-11-06 * ****************************************************************************** diff --git a/src/proj_strtod.c b/src/proj_strtod.c index 757dfaf6..fa683465 100644 --- a/src/proj_strtod.c +++ b/src/proj_strtod.c @@ -17,7 +17,7 @@ In the early versions of proj, iirc, a gnu version of strtod was used, mostly to work around cases where the same system library was used for C and Fortran linking, hence making strtod accept "D" and "d" as exponentiation indicators, following Fortran Double Precision constant -syntax. This broke the proj angular syntax accepting a "d" to mean +syntax. This broke the proj angular syntax, accepting a "d" to mean "degree": 12d34'56", meaning 12 degrees 34 minutes and 56 seconds. With an explicit MIT licence, PROJ.4 could not include GPL code any diff --git a/src/projects.h b/src/projects.h index b9d88cf3..1fe595bc 100644 --- a/src/projects.h +++ b/src/projects.h @@ -186,7 +186,7 @@ struct PJ_REGION_S; typedef struct PJ_REGION_S PJ_Region; typedef struct ARG_list paralist; /* parameter list */ enum pj_io_units { - PJ_IO_UNITS_CLASSIC = 0, /* LEFT: Radians RIGHT: Scaled meters */ + PJ_IO_UNITS_CLASSIC = 0, /* Scaled meters (right) */ PJ_IO_UNITS_METERS = 1, /* Meters */ PJ_IO_UNITS_RADIANS = 2 /* Radians */ }; -- cgit v1.2.3 From 234d712d2cf1145ba84c48f51511f92b461e9707 Mon Sep 17 00:00:00 2001 From: Ilya Oshchepkov Date: Sat, 28 Oct 2017 14:13:05 +0300 Subject: Add ellipsoids for the Russian coordinate systems PZ-90 and GSK-2011 --- src/pj_ellps.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src') diff --git a/src/pj_ellps.c b/src/pj_ellps.c index 32fbbd42..2a2c5d3b 100644 --- a/src/pj_ellps.c +++ b/src/pj_ellps.c @@ -15,6 +15,7 @@ pj_ellps[] = { {"andrae", "a=6377104.43", "rf=300.0", "Andrae 1876 (Den., Iclnd.)"}, {"aust_SA", "a=6378160.0", "rf=298.25", "Australian Natl & S. Amer. 1969"}, {"GRS67", "a=6378160.0", "rf=298.2471674270", "GRS 67(IUGG 1967)"}, +{"GSK2011", "a=6378136.5", "rf=298.2564151", "GSK-2011"}, {"bessel", "a=6377397.155", "rf=299.1528128", "Bessel 1841"}, {"bess_nam", "a=6377483.865", "rf=299.1528128", "Bessel 1841 (Namibia)"}, {"clrk66", "a=6378206.4", "b=6356583.8", "Clarke 1866"}, @@ -40,6 +41,7 @@ pj_ellps[] = { {"mprts", "a=6397300.", "rf=191.", "Maupertius 1738"}, {"new_intl", "a=6378157.5", "b=6356772.2", "New International 1967"}, {"plessis", "a=6376523.", "b=6355863.", "Plessis 1817 (France)"}, +{"PZ90", "a=6378136.0", "rf=298.25784", "PZ-90"}, {"SEasia", "a=6378155.0", "b=6356773.3205", "Southeast Asia"}, {"walbeck", "a=6376896.0", "b=6355834.8467", "Walbeck"}, {"WGS60", "a=6378165.0", "rf=298.3", "WGS 60"}, -- cgit v1.2.3 From 0d0beff91ddfc2cc4d195a141524a139f3afb756 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Sat, 28 Oct 2017 15:42:00 +0200 Subject: Allow nested pipelines. (#629) Allow nested pipelines when wrapped in +init's. The previous behaviour was to quit pipeline initialization when encountering a nested pipeline definition. With this commit that behaviour is changed so that it is possible to nest pipelines as long as they are defined elsewhere in a init-file. This is useful in init-files where steps in complicated transformations can be grouped in "sub-pipelines". These "sub-pipelines" can then be used as individual steps in a larger and more complicated pipeline. Nested pipelines are governed by the following rules: 1. You can't have more than one literal +proj=pipeline in a proj-string 2. Pipelines can be nested if they are wrapped up in a +init 3. More than one +init is disallowed in non-pipeline proj-strings 4. +inits are expanded as late as possible, that is they will only be expanded in single operations (that can be a part of a pipeline) --- src/PJ_pipeline.c | 2 +- src/pj_init.c | 96 +++++++++++++++++++++++++++++++++---------------------- src/pj_strerrno.c | 3 +- src/projects.h | 1 + 4 files changed, 62 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index ab2d3420..f1411cb4 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -380,7 +380,7 @@ PJ *PROJECTION(pipeline) { if (0==strcmp ("proj=pipeline", argv[i])) { if (-1 != i_pipeline) { - proj_log_error (P, "Pipeline: Nesting invalid"); + proj_log_error (P, "Pipeline: Nesting only allowed when child pipelines are wrapped in +init's"); return destructor (P, PJD_ERR_MALFORMED_PIPELINE); /* ERROR: nested pipelines */ } i_pipeline = i; diff --git a/src/pj_init.c b/src/pj_init.c index 704a8b55..2a945397 100644 --- a/src/pj_init.c +++ b/src/pj_init.c @@ -381,8 +381,9 @@ pj_init_plus_ctx( projCtx ctx, const char *definition ) if( argc+1 == MAX_ARG ) { - pj_ctx_set_errno( ctx, -44 ); - goto bum_call; + pj_dalloc( defn_copy ); + pj_ctx_set_errno( ctx, PJD_ERR_UNPARSEABLE_CS_DEF ); + return 0; } argv[argc++] = defn_copy + i + 1; @@ -410,9 +411,7 @@ pj_init_plus_ctx( projCtx ctx, const char *definition ) /* perform actual initialization */ result = pj_init_ctx( ctx, argc, argv ); -bum_call: pj_dalloc( defn_copy ); - return result; } @@ -441,6 +440,8 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { int i; int found_def = 0; PJ *PIN = 0; + int n_pipelines = 0; + int n_inits = 0; if (0==ctx) ctx = pj_get_default_ctx (); @@ -452,36 +453,45 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { pj_ctx_set_errno (ctx, PJD_ERR_NO_ARGS); return 0; } - + + /* count occurrences of pipelines and inits */ + for (i = 0; i < argc; ++i) { + if (!strcmp (argv[i], "+proj=pipeline") || !strcmp(argv[i], "proj=pipeline") ) + n_pipelines++; + if (!strncmp (argv[i], "+init=", 6) || !strncmp(argv[i], "init=", 5)) + n_inits++; + } + + /* can't have nested pipeline directly */ + if (n_pipelines > 1) { + pj_ctx_set_errno (ctx, PJD_ERR_MALFORMED_PIPELINE); + return 0; + } + + /* don't allow more than one +init in non-pipeline operations */ + if (n_pipelines == 0 && n_inits > 1) { + pj_ctx_set_errno (ctx, PJD_ERR_TOO_MANY_INITS); + return 0; + } + /* put arguments into internal linked list */ start = curr = pj_mkparam(argv[0]); if (!curr) return pj_dealloc_params (ctx, start, ENOMEM); - /* build parameter list and expand +init's. Does not take care of a single +init. */ for (i = 1; i < argc; ++i) { curr->next = pj_mkparam(argv[i]); if (!curr->next) return pj_dealloc_params (ctx, start, ENOMEM); - - /* check if +init present */ - if (pj_param(ctx, curr, "tinit").i) { - found_def = 0; - curr = get_init(ctx, &curr, curr->next, pj_param(ctx, curr, "sinit").s, &found_def); - if (!curr) - return pj_dealloc_params (ctx, start, PJD_ERR_NO_ARGS); - - if (!found_def) - return pj_dealloc_params (ctx, start, PJD_ERR_NO_OPTION_IN_INIT_FILE); - - } else { - curr = curr->next; - } + curr = curr->next; } - /* in case the parameter list only consist of a +init parameter - it is expanded here (will not be handled in the above loop). */ - if (pj_param(ctx, start, "tinit").i && argc == 1) { + + /* Only expand +init's in non-pipeline operations. +init's in pipelines are */ + /* expanded in the individual pipeline steps during pipeline initialization. */ + /* Potentially this leads to many nested pipelines, which shouldn't be a */ + /* problem when +inits are expanded as late as possible. */ + if (pj_param(ctx, start, "tinit").i && n_pipelines == 0) { found_def = 0; curr = get_init(ctx, &start, curr, pj_param(ctx, start, "sinit").s, &found_def); if (!curr) @@ -489,10 +499,10 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { if (!found_def) return pj_dealloc_params (ctx, start, PJD_ERR_NO_OPTION_IN_INIT_FILE); } - + if (ctx->last_errno) return pj_dealloc_params (ctx, start, ctx->last_errno); - + /* find projection selection */ if (!(name = pj_param(ctx, start, "sproj").s)) return pj_default_destructor (PIN, PJD_ERR_PROJ_NOT_NAMED); @@ -500,10 +510,11 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { if (!s) return pj_dealloc_params (ctx, start, PJD_ERR_UNKNOWN_PROJECTION_ID); - - /* set defaults, unless inhibited */ - if (!(pj_param(ctx, start, "bno_defs").i)) - curr = get_defaults(ctx,&start, curr, name); + + /* set defaults, unless inhibited or we are initializing a pipeline */ + if (!(pj_param(ctx, start, "bno_defs").i) && n_pipelines == 0) + curr = get_defaults(ctx,&start, curr, name); + proj = (PJ *(*)(PJ *)) pj_list[i].proj; /* allocate projection structure */ @@ -511,6 +522,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { if (0==PIN) return pj_dealloc_params (ctx, start, ENOMEM); + PIN->ctx = ctx; PIN->params = start; PIN->is_latlong = 0; @@ -526,13 +538,21 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { PIN->vgridlist_geoid_count = 0; /* set datum parameters */ - if (pj_datum_set(ctx, start, PIN)) + if (pj_datum_set(ctx, start, PIN)) return pj_default_destructor (PIN, PJD_ERR_MISSING_ARGS); - /* set ellipsoid/sphere parameters */ - if (pj_ell_set(ctx, start, &PIN->a, &PIN->es)) { - pj_log (ctx, PJ_LOG_DEBUG_MINOR, "pj_init_ctx: Must specify ellipsoid or sphere"); - return pj_default_destructor (PIN, PJD_ERR_MISSING_ARGS); + /* set ellipsoid/sphere parameters. If we are initializing a pipeline we */ + /* override ellipsoid-setter, since it also adds a "+ellps=WGS84" to the */ + /* parameter list which creates problems when the pipeline driver passes */ + /* the global parameters on the it's children. */ + if (n_pipelines > 0) { + PIN->a = 6378137.0; + PIN->es = .00669438002290341575; + } else { + if (pj_ell_set(ctx, start, &PIN->a, &PIN->es)) { + pj_log (ctx, PJ_LOG_DEBUG_MINOR, "pj_init_ctx: Must specify ellipsoid or sphere"); + return pj_default_destructor (PIN, PJD_ERR_MISSING_ARGS); + } } PIN->a_orig = PIN->a; @@ -606,7 +626,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { if( !(fabs(PIN->long_wrap_center) < 10 * M_TWOPI) ) return pj_default_destructor (PIN, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT); } - + /* axis orientation */ if( (pj_param(ctx, start,"saxis").s) != NULL ) { @@ -619,7 +639,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { || strchr( axis_legal, axis_arg[1] ) == NULL || strchr( axis_legal, axis_arg[2] ) == NULL) return pj_default_destructor (PIN, PJD_ERR_AXIS); - + /* it would be nice to validate we don't have on axis repeated */ strcpy( PIN->axis, axis_arg ); } @@ -643,7 +663,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { PIN->k0 = pj_param(ctx, start, "dk").f; else PIN->k0 = 1.; - if (PIN->k0 <= 0.) + if (PIN->k0 <= 0.) return pj_default_destructor (PIN, PJD_ERR_K_LESS_THAN_ZERO); /* set units */ @@ -704,7 +724,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { && *next_str == '\0' ) value = name; - if (!value) + if (!value) return pj_default_destructor (PIN, PJD_ERR_UNKNOWN_PRIME_MERIDIAN); PIN->from_greenwich = dmstor_ctx(ctx,value,NULL); } diff --git a/src/pj_strerrno.c b/src/pj_strerrno.c index 89a5a025..fe137b87 100644 --- a/src/pj_strerrno.c +++ b/src/pj_strerrno.c @@ -62,7 +62,8 @@ pj_err_list[] = { "missing required arguments", /* -54 */ "lat_0 = 0", /* -55 */ "ellipsoidal usage unsupported", /* -56 */ - + "only one +init allowed for non-pipeline operations", /* -57 */ + /* When adding error messages, remember to update ID defines in projects.h, and transient_error array in pj_transform */ }; diff --git a/src/projects.h b/src/projects.h index 1fe595bc..6ea0c914 100644 --- a/src/projects.h +++ b/src/projects.h @@ -532,6 +532,7 @@ struct FACTORS { #define PJD_ERR_MISSING_ARGS -54 #define PJD_ERR_LAT_0_IS_ZERO -55 #define PJD_ERR_ELLIPSOIDAL_UNSUPPORTED -56 +#define PJD_ERR_TOO_MANY_INITS -57 struct projFileAPI_t; -- cgit v1.2.3 From b8f765def1c54ddd0e8c61fd4619f58aa35165ff Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Tue, 24 Oct 2017 18:34:40 +0200 Subject: Extend proj_strtod test case collection and improve its strtod-replication --- src/proj_strtod.c | 66 ++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 53 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/proj_strtod.c b/src/proj_strtod.c index d4063b0b..757dfaf6 100644 --- a/src/proj_strtod.c +++ b/src/proj_strtod.c @@ -121,10 +121,16 @@ double proj_strtod(const char *str, char **endptr) { /* Empty string? */ if (0==*p) { - errno = EINVAL; if (endptr) - *endptr = p; - return HUGE_VAL; + *endptr = (char *) str; + return 0; + } + + /* non-numeric? */ + if (0==strchr("0123456789+-._", *p)) { + if (endptr) + *endptr = (char *) str; + return 0; } /* Then handle optional prefixed sign and skip prefix zeros */ @@ -137,9 +143,15 @@ double proj_strtod(const char *str, char **endptr) { if (isdigit(*p) || '_'==*p || '.'==*p) break; if (endptr) - *endptr = p; - errno = EINVAL; - return HUGE_VAL; + *endptr = (char *) str; + return 0; + } + + /* stray sign, as in "+/-"? */ + if (0!=sign && (0==strchr ("0123456789._", *p) || 0==*p)) { + if (endptr) + *endptr = (char *) str; + return 0; } /* skip prefixed zeros before '.' */ @@ -147,8 +159,11 @@ double proj_strtod(const char *str, char **endptr) { p++; /* zero? */ - if (0==*p || 0==strchr ("0123456789eE.", *p)) - return 0; + if ((0==*p) || 0==strchr ("0123456789eE.", *p) || isspace(*p)) { + if (endptr) + *endptr = p; + return sign==-1? -0: 0; + } /* Now expect a (potentially zero-length) string of digits */ while (isdigit(*p) || ('_'==*p)) { @@ -228,8 +243,15 @@ double proj_strtod(const char *str, char **endptr) { number = -number; /* Do we have an exponent part? */ - if (*p == 'e' || *p == 'E') { + while (*p == 'e' || *p == 'E') { p++; + + /* Just a stray "e", as in 100elephants? */ + if (0==*p || 0==strchr ("0123456789+-_", *p)) { + p--; + break; + } + while ('_'==*p) p++; /* Does it have a sign? */ @@ -263,6 +285,7 @@ double proj_strtod(const char *str, char **endptr) { if (-1==sign) n = -n; exponent += n; + break; } if (endptr) @@ -351,14 +374,31 @@ int main (int argc, char **argv) { errno = 0; - test ("1"); - test ("0"); + test (""); + test (" "); + test (" abcde"); + test (" edcba"); + test ("abcde"); + test ("edcba"); + test ("+"); + test ("-"); + test ("+ "); + test ("- "); + test (" + "); + test (" - "); + test ("e 1"); + test ("e1"); + test ("0 66"); test ("1."); test ("0."); test ("1.0"); test ("0.0"); - test ("1.0"); - test ("0.0"); + test ("1 "); + test ("0 "); + test ("-0 "); + test ("0_ "); + test ("0_"); + test ("1e"); test ("_1.0"); test ("_0.0"); test ("1_.0"); -- cgit v1.2.3 From 395ec20b5a661e77d048212182841e5684dd6757 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Tue, 24 Oct 2017 23:36:13 +0200 Subject: Make gie roundtrips compatible with updated proj_strtod In order to mimic strtod, proj_strtod now returns 0 and not HUGE_VAL on nonnumeric input. Hence, we must check the return pointers to identify an error. --- src/gie.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'src') diff --git a/src/gie.c b/src/gie.c index 6ff157ac..33fc4d82 100644 --- a/src/gie.c +++ b/src/gie.c @@ -457,11 +457,11 @@ static int accept (char *args) { static int roundtrip (char *args) { int ntrips; double d, r, ans; - char *endp; + char *endp, *endq; ans = proj_strtod (args, &endp); ntrips = (int) (ans==HUGE_VAL? 100: fabs(ans)); - d = proj_strtod (endp, &endp); - d = d==HUGE_VAL? T.tolerance: d / 1000; + d = proj_strtod (endp, &endq); + d = (endp==endq)? T.tolerance: d / 1000; r = proj_roundtrip (T.P, PJ_FWD, ntrips, T.a); if (r > d) { if (T.verbosity > -1) { -- cgit v1.2.3 From fd95842b9fafb0e140bc867af71f358c92258ff8 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Wed, 25 Oct 2017 10:39:56 +0200 Subject: Remove PJ_OBS from the API surface, rename pj_obs_api.c to pj_4D_api.c (#625) * Remove PJ_OBS from the API surface, rename pj_obs_api.c to pj_4D_api.c * Repair proj.def --- src/Makefile.am | 2 +- src/PJ_cart.c | 10 +- src/PJ_helmert.c | 4 +- src/PJ_latlong.c | 3 +- src/lib_proj.cmake | 2 +- src/makefile.vc | 2 +- src/pj_internal.c | 55 +++- src/pj_obs_api.c | 818 ---------------------------------------------------- src/proj.def | 75 +++-- src/proj.h | 19 +- src/proj_4D_api.c | 752 +++++++++++++++++++++++++++++++++++++++++++++++ src/proj_internal.h | 9 + src/projects.h | 6 +- 13 files changed, 863 insertions(+), 894 deletions(-) delete mode 100644 src/pj_obs_api.c create mode 100644 src/proj_4D_api.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index a039151d..363f2cce 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -85,7 +85,7 @@ libproj_la_SOURCES = \ jniproj.c pj_mutex.c pj_initcache.c pj_apply_vgridshift.c geodesic.c \ pj_strtod.c \ \ - pj_obs_api.c PJ_cart.c PJ_pipeline.c PJ_horner.c PJ_helmert.c \ + proj_4D_api.c PJ_cart.c PJ_pipeline.c PJ_horner.c PJ_helmert.c \ PJ_vgridshift.c PJ_hgridshift.c PJ_unitconvert.c PJ_molodensky.c \ pj_internal.c diff --git a/src/PJ_cart.c b/src/PJ_cart.c index 37aa3b97..99e1af7d 100644 --- a/src/PJ_cart.c +++ b/src/PJ_cart.c @@ -387,10 +387,10 @@ int pj_cart_selftest (void) { b = proj_trans_obs (P, PJ_FWD, obs[1]); n = proj_transform ( - P, PJ_FWD, + P, PJ_FWD, &(obs[0].coo.lpz.lam), sz, 2, &(obs[0].coo.lpz.phi), sz, 2, - &(obs[0].coo.lpz.z), sz, 2, + &(obs[0].coo.lpz.z), sz, 2, 0, sz, 0 ); if (2!=n) @@ -408,10 +408,10 @@ int pj_cart_selftest (void) { h = 27; t = 33; n = proj_transform ( - P, PJ_FWD, + P, PJ_FWD, &(obs[0].coo.lpz.lam), sz, 2, &(obs[0].coo.lpz.phi), sz, 2, - &h, 0, 1, + &h, 0, 1, &t, 0, 1 ); if (2!=n) @@ -429,7 +429,7 @@ int pj_cart_selftest (void) { obs[0].coo = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); obs[1].coo = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); - if (proj_transform_obs(P, PJ_FWD, 2, obs)) + if (proj_transform_coord(P, PJ_FWD, 2, (PJ_COORD *) obs)) return 30; if (a.coo.lpz.lam != obs[0].coo.lpz.lam) return 31; diff --git a/src/PJ_helmert.c b/src/PJ_helmert.c index ffbdd01a..503dc392 100644 --- a/src/PJ_helmert.c +++ b/src/PJ_helmert.c @@ -668,11 +668,11 @@ int pj_helmert_selftest (void) { matrix is updated when necessary. Test coordinates from GNSStrans. */ XYZ expect4a = {3370658.18890, 711877.42370, 5349787.12430}; XYZ expect4b = {3370658.18087, 711877.42750, 5349787.12648}; - PJ_OBS in4 = {{{3370658.378, 711877.314, 5349787.086, 2017.0}}, {{ 0, 0, 0}}, 0, 0}; + PJ_OBS in4 = {{{3370658.378, 711877.314, 5349787.086, 2017.0}}}; PJ_OBS out; PJ *helmert = proj_create( - 0, + 0, " +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" diff --git a/src/PJ_latlong.c b/src/PJ_latlong.c index 1677142a..7ee41e2a 100644 --- a/src/PJ_latlong.c +++ b/src/PJ_latlong.c @@ -1,6 +1,6 @@ /****************************************************************************** * Project: PROJ.4 - * Purpose: Stub projection implementation for lat/long coordinates. We + * Purpose: Stub projection implementation for lat/long coordinates. We * don't actually change the coordinates, but we want proj=latlong * to act sort of like a projection. * Author: Frank Warmerdam, warmerdam@pobox.com @@ -29,6 +29,7 @@ /* very loosely based upon DMA code by Bradford W. Drew */ #define PJ_LIB__ +#include "proj_internal.h" #include #include "projects.h" diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 1be10362..053e9ef6 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -201,7 +201,7 @@ SET(SRC_LIBPROJ_CORE pj_mlfn.c pj_msfn.c pj_mutex.c - pj_obs_api.c + proj_4D_api.c pj_internal.c proj_internal.h pj_open_lib.c diff --git a/src/makefile.vc b/src/makefile.vc index fdf03bd3..1330e9bb 100644 --- a/src/makefile.vc +++ b/src/makefile.vc @@ -60,7 +60,7 @@ support = \ pj_internal.obj pipeline = \ - pj_obs_api.obj PJ_cart.obj PJ_pipeline.obj PJ_horner.obj PJ_helmert.obj \ + proj_4D_api.obj PJ_cart.obj PJ_pipeline.obj PJ_horner.obj PJ_helmert.obj \ PJ_vgridshift.obj PJ_hgridshift.obj PJ_unitconvert.obj PJ_molodensky.obj geodesic = geodesic.obj diff --git a/src/pj_internal.c b/src/pj_internal.c index 31c299ac..5eb98afb 100644 --- a/src/pj_internal.c +++ b/src/pj_internal.c @@ -1,8 +1,9 @@ /****************************************************************************** * Project: PROJ.4 - * Purpose: This is primarily material originating from pj_obs_api.c, - * that does not fit into the API category. Hence this pile of - * tubings and fittings for PROJ.4 internal plumbing. + * Purpose: This is primarily material originating from pj_obs_api.c + * (now proj_4D_api.c), that does not fit into the API + * category. Hence this pile of tubings and fittings for + * PROJ.4 internal plumbing. * * Author: Thomas Knudsen, thokn@sdfe.dk, 2017-07-05 * @@ -42,12 +43,52 @@ /* Used for zero-initializing new objects */ const PJ_COORD proj_coord_null = {{0, 0, 0, 0}}; const PJ_OBS proj_obs_null = { - {{0, 0, 0, 0}}, - {{0, 0, 0}}, - 0, 0 + {{0, 0, 0, 0}} }; + +/* Initialize PJ_OBS struct */ +PJ_OBS proj_obs (double x, double y, double z, double t) { + PJ_OBS res; + res.coo = proj_coord (x, y, z, t); + return res; +} + + + + + + + + + + + + + + +/* Apply the transformation P to the coordinate coo */ +PJ_OBS proj_trans_obs (PJ *P, PJ_DIRECTION direction, PJ_OBS obs) { + if (0==P) + return obs; + + switch (direction) { + case PJ_FWD: + return pj_fwdobs (obs, P); + case PJ_INV: + return pj_invobs (obs, P); + case PJ_IDENT: + return obs; + default: + break; + } + + proj_errno_set (P, EINVAL); + return proj_obs_error (); +} + + /* Work around non-constness of MSVC HUGE_VAL by providing functions rather than constants */ PJ_COORD proj_coord_error (void) { PJ_COORD c; @@ -58,8 +99,6 @@ PJ_COORD proj_coord_error (void) { PJ_OBS proj_obs_error (void) { PJ_OBS obs; obs.coo = proj_coord_error (); - obs.anc.v[0] = obs.anc.v[1] = obs.anc.v[2] = HUGE_VAL; - obs.id = obs.flags = 0; return obs; } diff --git a/src/pj_obs_api.c b/src/pj_obs_api.c deleted file mode 100644 index 55da9fa2..00000000 --- a/src/pj_obs_api.c +++ /dev/null @@ -1,818 +0,0 @@ -/****************************************************************************** - * Project: PROJ.4 - * Purpose: Implement a (currently minimalistic) proj API based primarily - * on the PJ_OBS generic geodetic data type. - * - * proj thread contexts have not seen widespread use, so one of the - * intentions with this new API is to make them less visible on the - * API surface: Contexts do not have a life by themselves, they are - * visible only through their associated PJs, and the number of - * functions supporting them is limited. - * - * Author: Thomas Knudsen, thokn@sdfe.dk, 2016-06-09/2016-11-06 - * - ****************************************************************************** - * Copyright (c) 2016, 2017 Thomas Knudsen/SDFE - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - *****************************************************************************/ -#define PJ_OBS_API_C -#include -#include "proj_internal.h" -#include "projects.h" -#include "geodesic.h" -#include -#include - - -/* Initialize PJ_COORD struct */ -PJ_COORD proj_coord (double x, double y, double z, double t) { - PJ_COORD res; - res.v[0] = x; - res.v[1] = y; - res.v[2] = z; - res.v[3] = t; - return res; -} - -/* Initialize PJ_OBS struct */ -PJ_OBS proj_obs (double x, double y, double z, double t, double o, double p, double k, int id, unsigned int flags) { - PJ_OBS res; - res.coo.v[0] = x; - res.coo.v[1] = y; - res.coo.v[2] = z; - res.coo.v[3] = t; - res.anc.v[0] = o; - res.anc.v[1] = p; - res.anc.v[2] = k; - res.id = id; - res.flags = flags; - - return res; -} - - - -/* 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; - /* Note: the geodesic code takes arguments in degrees */ - geod_inverse (P->geod, PJ_TODEG(a.phi), PJ_TODEG(a.lam), PJ_TODEG(b.phi), PJ_TODEG(b.lam), &s12, &azi1, &azi2); - return s12; -} - -/* 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); -} - -/* Euclidean distance between two points with linear 3D coordinates */ -double proj_xyz_dist (XYZ a, XYZ b) { - return hypot (hypot (a.x - b.x, a.y - b.y), a.z - b.z); -} - - - -/* Measure numerical deviation after n roundtrips fwd-inv (or inv-fwd) */ -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; - - if (n < 1) { - proj_errno_set (P, EINVAL); - return HUGE_VAL; - } - - o = coo; - - switch (direction) { - case PJ_FWD: - for (i = 0; i < n; i++) { - u = pj_fwdcoord (o, P); - o = pj_invcoord (u, P); - } - break; - case PJ_INV: - for (i = 0; i < n; i++) { - u = pj_invcoord (o, P); - o = pj_fwdcoord (u, P); - } - break; - default: - proj_errno_set (P, EINVAL); - 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) - return hypot (proj_lp_dist (P, coo.lp, o.lp), coo.lpz.z - o.lpz.z); - - return proj_xyz_dist (coo.xyz, coo.xyz); -} - - - - - - - - - - - - - -/* Apply the transformation P to the coordinate coo */ -PJ_OBS proj_trans_obs (PJ *P, PJ_DIRECTION direction, PJ_OBS obs) { - if (0==P) - return obs; - - switch (direction) { - case PJ_FWD: - return pj_fwdobs (obs, P); - case PJ_INV: - return pj_invobs (obs, P); - case PJ_IDENT: - return obs; - default: - break; - } - - proj_errno_set (P, EINVAL); - return proj_obs_error (); -} - - - -/* Apply the transformation P to the coordinate coo */ -PJ_COORD proj_trans_coord (PJ *P, PJ_DIRECTION direction, PJ_COORD coo) { - if (0==P) - return coo; - - switch (direction) { - case PJ_FWD: - return pj_fwdcoord (coo, P); - case PJ_INV: - return pj_invcoord (coo, P); - case PJ_IDENT: - return coo; - default: - break; - } - - proj_errno_set (P, EINVAL); - return proj_coord_error (); -} - - - -/*************************************************************************************/ -size_t proj_transform ( - PJ *P, - PJ_DIRECTION direction, - double *x, size_t sx, size_t nx, - double *y, size_t sy, size_t ny, - double *z, size_t sz, size_t nz, - double *t, size_t st, size_t nt -) { -/************************************************************************************** - - Transform a series of coordinates, where the individual coordinate dimension - may be represented by an array that is either - - 1. fully populated - 2. a null pointer and/or a length of zero, which will be treated as a - fully populated array of zeroes - 3. of length one, i.e. a constant, which will be treated as a fully - populated array of that constant value - - The strides, sx, sy, sz, st, represent the step length, in bytes, between - consecutive elements of the corresponding array. This makes it possible for - proj_transform to handle transformation of a large class of application - specific data structures, without necessarily understanding the data structure - format, as in: - - typedef struct {double x, y; int quality_level; char surveyor_name[134];} XYQS; - XYQS survey[345]; - double height = 23.45; - PJ *P = {...}; - size_t stride = sizeof (XYQS); - ... - proj_transform ( - P, PJ_INV, sizeof(XYQS), - &(survey[0].x), stride, 345, (* We have 345 eastings *) - &(survey[0].y), stride, 345, (* ...and 345 northings. *) - &height, 1, (* The height is the constant 23.45 m *) - 0, 0 (* and the time is the constant 0.00 s *) - ); - - This is similar to the inner workings of the pj_transform function, but the - stride functionality has been generalized to work for any size of basic unit, - not just a fixed number of doubles. - - In most cases, the stride will be identical for x, y,z, and t, since they will - typically be either individual arrays (stride = sizeof(double)), or strided - views into an array of application specific data structures (stride = sizeof (...)). - - But in order to support cases where x, y, z, and t come from heterogeneous - sources, individual strides, sx, sy, sz, st, are used. - - Caveat: Since proj_transform does its work *in place*, this means that even the - supposedly constants (i.e. length 1 arrays) will return from the call in altered - state. Hence, remember to reinitialize between repeated calls. - - Return value: Number of transformations completed. - -**************************************************************************************/ - PJ_COORD coord = proj_coord_null; - size_t i, nmin; - double null_broadcast = 0; - if (0==P) - return 0; - - /* ignore lengths of null arrays */ - if (0==x) nx = 0; - if (0==y) ny = 0; - if (0==z) nz = 0; - if (0==t) nt = 0; - - /* and make the nullities point to some real world memory for broadcasting nulls */ - if (0==nx) x = &null_broadcast; - if (0==ny) y = &null_broadcast; - if (0==nz) z = &null_broadcast; - if (0==nt) t = &null_broadcast; - - /* nothing to do? */ - if (0==nx+ny+nz+nt) - return 0; - - /* arrays of length 1 are constants, which we broadcast along the longer arrays */ - /* so we need to find the length of the shortest non-unity array to figure out */ - /* how many coordinate pairs we must transform */ - nmin = (nx > 1)? nx: (ny > 1)? ny: (nz > 1)? nz: (nt > 1)? nt: 1; - if ((nx > 1) && (nx < nmin)) nmin = nx; - if ((ny > 1) && (ny < nmin)) nmin = ny; - if ((nz > 1) && (nz < nmin)) nmin = nz; - if ((nt > 1) && (nt < nmin)) nmin = nt; - - /* Check validity of direction flag */ - switch (direction) { - case PJ_FWD: - case PJ_INV: - break; - case PJ_IDENT: - return nmin; - default: - proj_errno_set (P, EINVAL); - return 0; - } - - /* Arrays of length==0 are broadcast as the constant 0 */ - /* Arrays of length==1 are broadcast as their single value */ - /* Arrays of length >1 are iterated over (for the first nmin values) */ - /* The slightly convolved incremental indexing is used due */ - /* to the stride, which may be any size supported by the platform */ - for (i = 0; i < nmin; i++) { - coord.xyzt.x = *x; - coord.xyzt.y = *y; - coord.xyzt.z = *z; - coord.xyzt.t = *t; - - if (PJ_FWD==direction) - coord = pj_fwdcoord (coord, P); - else - coord = pj_invcoord (coord, P); - - /* in all full length cases, we overwrite the input with the output */ - if (nx > 1) { - *x = coord.xyzt.x; - x = (double *) ( ((char *) x) + sx); - } - if (ny > 1) { - *y = coord.xyzt.y; - y = (double *) ( ((char *) y) + sy); - } - if (nz > 1) { - *z = coord.xyzt.z; - z = (double *) ( ((char *) z) + sz); - } - if (nt > 1) { - *t = coord.xyzt.t; - t = (double *) ( ((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) - *y = coord.xyzt.y; - if (nz==1) - *z = coord.xyzt.z; - if (nt==1) - *t = coord.xyzt.t; - - return i; -} - -/*****************************************************************************/ -int proj_transform_obs (PJ *P, PJ_DIRECTION direction, size_t n, PJ_OBS *obs) { -/****************************************************************************** - Batch transform an array of PJ_OBS. - - Returns 0 if all observations are transformed without error, otherwise - returns error number. -******************************************************************************/ - size_t i; - for (i=0; i= 511) - continue; - - if (strlen(info.searchpath) != 0) { - strcat(info.searchpath, ";"); - len = strlen(paths[i]); - strncat(info.searchpath, paths[i], sizeof(info.searchpath)-len-1); - } else { - pj_strlcpy(info.searchpath, paths[i], sizeof(info.searchpath)); - } - } - - return info; -} - - -/*****************************************************************************/ -PJ_PROJ_INFO proj_pj_info(PJ *P) { -/****************************************************************************** - Basic info about a particular instance of a projection object. - - Returns PJ_PROJ_INFO struct. - -******************************************************************************/ - PJ_PROJ_INFO info; - char *def; - - memset(&info, 0, sizeof(PJ_PROJ_INFO)); - - /* Expected accuracy of the transformation. Hardcoded for now, will be improved */ - /* later. Most likely to be used when a transformation is set up with */ - /* proj_create_crs_to_crs in a future version that leverages the EPSG database. */ - info.accuracy = -1.0; - - if (!P) { - return info; - } - - /* projection id */ - if (pj_param(P->ctx, P->params, "tproj").i) - pj_strlcpy(info.id, pj_param(P->ctx, P->params, "sproj").s, sizeof(info.id)); - - /* projection description */ - pj_strlcpy(info.description, P->descr, sizeof(info.description)); - - /* projection definition */ - def = pj_get_def(P, 0); /* pj_get_def takes a non-const PJ pointer */ - pj_strlcpy(info.definition, &def[1], sizeof(info.definition)); /* def includes a leading space */ - pj_dealloc(def); - - /* this does not take into account that a pipeline potentially does not */ - /* have an inverse. */ - info.has_inverse = (P->inv != 0 || P->inv3d != 0 || P->invobs != 0); - - return info; -} - - -/*****************************************************************************/ -PJ_GRID_INFO proj_grid_info(const char *gridname) { -/****************************************************************************** - Information about a named datum grid. - - Returns PJ_GRID_INFO struct. - -******************************************************************************/ - PJ_GRID_INFO info; - - /*PJ_CONTEXT *ctx = proj_context_create(); */ - PJ_CONTEXT *ctx = pj_get_default_ctx(); - PJ_GRIDINFO *gridinfo = pj_gridinfo_init(ctx, gridname); - memset(&info, 0, sizeof(PJ_GRID_INFO)); - - /* in case the grid wasn't found */ - if (gridinfo->filename == NULL) { - pj_gridinfo_free(ctx, gridinfo); - strcpy(info.format, "missing"); - return info; - } - - /* name of grid */ - pj_strlcpy(info.gridname, gridname, sizeof(info.gridname)); - - /* full path of grid */ - pj_find_file(ctx, gridname, info.filename, sizeof(info.filename)); - - /* grid format */ - pj_strlcpy(info.format, gridinfo->format, sizeof(info.format)); - - /* grid size */ - info.n_lon = gridinfo->ct->lim.lam; - info.n_lat = gridinfo->ct->lim.phi; - - /* cell size */ - info.cs_lon = gridinfo->ct->del.lam; - info.cs_lat = gridinfo->ct->del.phi; - - /* bounds of grid */ - info.lowerleft = gridinfo->ct->ll; - info.upperright.lam = info.lowerleft.lam + info.n_lon*info.cs_lon; - info.upperright.phi = info.lowerleft.phi + info.n_lat*info.cs_lat; - - pj_gridinfo_free(ctx, gridinfo); - - return info; -} - -/*****************************************************************************/ -PJ_INIT_INFO proj_init_info(const char *initname){ -/****************************************************************************** - Information about a named init file. - - Maximum length of initname is 64. - - Returns PJ_INIT_INFO struct. - - If the init file is not found all members of - the return struct are set to 0. If the init file is found, but it the - metadata is missing, the value is set to "Unknown". - -******************************************************************************/ - int file_found, def_found=0; - char param[80], key[74]; - paralist *start, *next; - PJ_INIT_INFO info; - PJ_CONTEXT *ctx = pj_get_default_ctx(); - - memset(&info, 0, sizeof(PJ_INIT_INFO)); - - file_found = pj_find_file(ctx, initname, info.filename, sizeof(info.filename)); - if (!file_found || strlen(initname) > 64) { - return info; - } - - pj_strlcpy(info.name, initname, sizeof(info.name)); - strcpy(info.origin, "Unknown"); - strcpy(info.version, "Unknown"); - strcpy(info.lastupdate, "Unknown"); - - pj_strlcpy(key, initname, 64); /* make room for ":metadata\0" at the end */ - strncat(key, ":metadata", 9); - strcpy(param, "+init="); - strncat(param, key, 73); - - start = pj_mkparam(param); - next = pj_get_init(ctx, &start, start, key, &def_found); - - if (pj_param(ctx, start, "tversion").i) { - pj_strlcpy(info.version, pj_param(ctx, start, "sversion").s, sizeof(info.version)); - } - - if (pj_param(ctx, start, "torigin").i) { - pj_strlcpy(info.origin, pj_param(ctx, start, "sorigin").s, sizeof(info.origin)); - } - - if (pj_param(ctx, start, "tlastupdate").i) { - pj_strlcpy(info.lastupdate, pj_param(ctx, start, "slastupdate").s, sizeof(info.lastupdate)); - } - - for ( ; start; start = next) { - next = start->next; - pj_dalloc(start); - } - - return info; -} - - -/*****************************************************************************/ -PJ_DERIVS proj_derivatives(PJ *P, const LP lp) { -/****************************************************************************** - Derivatives of coordinates. - - returns PJ_DERIVS. If unsuccessfull error number is set and the returned - struct contains NULL data. - -******************************************************************************/ - PJ_DERIVS derivs; - - if (pj_deriv(lp, 1e-5, P, &derivs)) { - /* errno set in pj_derivs */ - memset(&derivs, 0, sizeof(PJ_DERIVS)); - } - - return derivs; -} - - -/*****************************************************************************/ -PJ_FACTORS proj_factors(PJ *P, const LP lp) { -/****************************************************************************** - Cartographic characteristics at point lp. - - Characteristics include meridian, parallel and areal scales, angular - distortion, meridian/parallel, meridian convergence and scale error. - - returns PJ_FACTORS. If unsuccessfull error number is set and the returned - struct contains NULL data. - -******************************************************************************/ - PJ_FACTORS factors; - - /* pj_factors rely code being zero */ - factors.code = 0; - - if (pj_factors(lp, P, 0.0, &factors)) { - /* errno set in pj_factors */ - memset(&factors, 0, sizeof(PJ_FACTORS)); - } - - return factors; -} - - -const PJ_ELLPS *proj_list_ellps(void) { - return pj_get_ellps_ref(); -} - -const PJ_UNITS *proj_list_units(void) { - return pj_get_units_ref(); -} - -const PJ_OPERATIONS *proj_list_operations(void) { - return pj_get_list_ref(); -} - -const PJ_PRIME_MERIDIANS *proj_list_prime_meridians(void) { - return pj_get_prime_meridians_ref(); -} - -double proj_torad (double angle_in_degrees) { return PJ_TORAD (angle_in_degrees);} -double proj_todeg (double angle_in_radians) { return PJ_TODEG (angle_in_radians);} - - -double proj_dmstor(const char *is, char **rs) { - return dmstor(is, rs); -} - -char* proj_rtodms(char *s, double r, int pos, int neg) { - return rtodms(s, r, pos, neg); -} diff --git a/src/proj.def b/src/proj.def index 598f2824..86deb24d 100644 --- a/src/proj.def +++ b/src/proj.def @@ -100,50 +100,49 @@ EXPORTS proj_trans_obs @95 proj_trans_coord @96 proj_transform @97 - proj_transform_obs @98 - proj_transform_coord @99 - proj_roundtrip @100 + proj_transform_coord @98 + proj_roundtrip @99 - proj_coord @101 - proj_obs @102 - proj_coord_error @103 - proj_obs_error @104 + proj_coord @100 + proj_obs @101 + proj_coord_error @102 + proj_obs_error @103 - proj_errno @105 - proj_errno_set @106 - proj_errno_reset @107 - proj_errno_restore @108 - proj_context_errno_set @109 + proj_errno @104 + proj_errno_set @105 + proj_errno_reset @106 + proj_errno_restore @107 + proj_context_errno_set @108 - proj_context_create @110 - proj_context_set @111 - proj_context_inherit @112 - proj_context_destroy @113 + proj_context_create @109 + proj_context_set @110 + proj_context_inherit @111 + proj_context_destroy @112 - proj_lp_dist @114 - proj_xy_dist @115 - proj_xyz_dist @116 + proj_lp_dist @113 + proj_xy_dist @114 + proj_xyz_dist @115 - proj_log_level @117 - proj_log_func @118 - proj_log_error @119 - proj_log_debug @120 - proj_log_trace @121 + proj_log_level @116 + proj_log_func @117 + proj_log_error @118 + proj_log_debug @119 + proj_log_trace @120 - proj_info @122 - proj_pj_info @123 - proj_grid_info @124 - proj_init_info @125 + proj_info @121 + proj_pj_info @122 + proj_grid_info @123 + proj_init_info @124 - proj_torad @126 - proj_todeg @127 - proj_rtodms @128 - proj_dmstor @129 + proj_torad @125 + proj_todeg @126 + proj_rtodms @127 + proj_dmstor @128 - proj_derivatives @130 - proj_factors @131 + proj_derivatives @129 + proj_factors @130 - proj_list_operations @132 - proj_list_ellps @133 - proj_list_units @134 - proj_list_prime_meridians @135 + proj_list_operations @131 + proj_list_ellps @132 + proj_list_units @133 + proj_list_prime_meridians @134 diff --git a/src/proj.h b/src/proj.h index aa9f3b17..ed885091 100644 --- a/src/proj.h +++ b/src/proj.h @@ -90,7 +90,7 @@ * compatible call proj_context_create(0), which will not create * a new context, but simply provide a pointer to the default one. * - * See pj_obs_api_test.c for an example of how to use the API. + * See proj_4D_api_test.c for examples of how to use the API. * * Author: Thomas Knudsen, * Benefitting from a large number of comments and suggestions @@ -170,10 +170,6 @@ extern char const pj_release[]; /* global release id string */ /* first forward declare everything needed */ -/* Data type for generic geodetic observations */ -struct PJ_OBS; -typedef struct PJ_OBS PJ_OBS; - /* Data type for generic geodetic 3D data */ union PJ_TRIPLET; typedef union PJ_TRIPLET PJ_TRIPLET; @@ -299,14 +295,6 @@ union PJ_PAIR { }; -struct PJ_OBS { - PJ_COORD coo; /* coordinate data */ - PJ_TRIPLET anc; /* ancillary data */ - int id; /* integer ancillary data - e.g. observation number, EPSG code... */ - unsigned int flags; /* additional data, intended for flags */ -}; - - #define PJ_IS_ANAL_XL_YL 01 /* derivatives of lon analytic */ #define PJ_IS_ANAL_XP_YP 02 /* derivatives of lat analytic */ #define PJ_IS_ANAL_HK 04 /* h and k analytic */ @@ -385,7 +373,6 @@ enum PJ_DIRECTION { }; typedef enum PJ_DIRECTION PJ_DIRECTION; -PJ_OBS proj_trans_obs (PJ *P, PJ_DIRECTION direction, PJ_OBS obs); PJ_COORD proj_trans_coord (PJ *P, PJ_DIRECTION direction, PJ_COORD coord); @@ -398,16 +385,14 @@ size_t proj_transform ( double *t, size_t st, size_t nt ); -int proj_transform_obs (PJ *P, PJ_DIRECTION direction, size_t n, PJ_OBS *obs); int proj_transform_coord (PJ *P, PJ_DIRECTION direction, size_t n, PJ_COORD *coord); /* Initializers */ PJ_COORD proj_coord (double x, double y, double z, double t); -PJ_OBS proj_obs (double x, double y, double z, double t, double o, double p, double k, int id, unsigned int flags); /* Measure internal consistency - in forward or inverse direction */ 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); diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c new file mode 100644 index 00000000..b1aa3883 --- /dev/null +++ b/src/proj_4D_api.c @@ -0,0 +1,752 @@ +/****************************************************************************** + * Project: PROJ.4 + * Purpose: Implement a (currently minimalistic) proj API based primarily + * on the PJ_COORD 4D geodetic spatiotemporal data type. + * + * proj thread contexts have not seen widespread use, so one of the + * intentions with this new API is to make them less visible on the + * API surface: Contexts do not have a life by themselves, they are + * visible only through their associated PJs, and the number of + * functions supporting them is limited. + * + * Author: Thomas Knudsen, thokn@sdfe.dk, 2016-06-09/2016-11-06 + * + ****************************************************************************** + * Copyright (c) 2016, 2017 Thomas Knudsen/SDFE + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sublicense, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS + * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + *****************************************************************************/ +#include +#include "proj_internal.h" +#include "projects.h" +#include "geodesic.h" +#include +#include + + +/* Initialize PJ_COORD struct */ +PJ_COORD proj_coord (double x, double y, double z, double t) { + PJ_COORD res; + res.v[0] = x; + res.v[1] = y; + res.v[2] = z; + res.v[3] = t; + return res; +} + + + +/* 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; + /* Note: the geodesic code takes arguments in degrees */ + geod_inverse (P->geod, PJ_TODEG(a.phi), PJ_TODEG(a.lam), PJ_TODEG(b.phi), PJ_TODEG(b.lam), &s12, &azi1, &azi2); + return s12; +} + +/* 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); +} + +/* Euclidean distance between two points with linear 3D coordinates */ +double proj_xyz_dist (XYZ a, XYZ b) { + return hypot (hypot (a.x - b.x, a.y - b.y), a.z - b.z); +} + + + +/* Measure numerical deviation after n roundtrips fwd-inv (or inv-fwd) */ +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; + + if (n < 1) { + proj_errno_set (P, EINVAL); + return HUGE_VAL; + } + + o = coo; + + switch (direction) { + case PJ_FWD: + for (i = 0; i < n; i++) { + u = pj_fwdcoord (o, P); + o = pj_invcoord (u, P); + } + break; + case PJ_INV: + for (i = 0; i < n; i++) { + u = pj_invcoord (o, P); + o = pj_fwdcoord (u, P); + } + break; + default: + proj_errno_set (P, EINVAL); + 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) + return hypot (proj_lp_dist (P, coo.lp, o.lp), coo.lpz.z - o.lpz.z); + + return proj_xyz_dist (coo.xyz, coo.xyz); +} + + + +/* Apply the transformation P to the coordinate coo */ +PJ_COORD proj_trans_coord (PJ *P, PJ_DIRECTION direction, PJ_COORD coo) { + if (0==P) + return coo; + + switch (direction) { + case PJ_FWD: + return pj_fwdcoord (coo, P); + case PJ_INV: + return pj_invcoord (coo, P); + case PJ_IDENT: + return coo; + default: + break; + } + + proj_errno_set (P, EINVAL); + return proj_coord_error (); +} + + + +/*************************************************************************************/ +size_t proj_transform ( + PJ *P, + PJ_DIRECTION direction, + double *x, size_t sx, size_t nx, + double *y, size_t sy, size_t ny, + double *z, size_t sz, size_t nz, + double *t, size_t st, size_t nt +) { +/************************************************************************************** + + Transform a series of coordinates, where the individual coordinate dimension + may be represented by an array that is either + + 1. fully populated + 2. a null pointer and/or a length of zero, which will be treated as a + fully populated array of zeroes + 3. of length one, i.e. a constant, which will be treated as a fully + populated array of that constant value + + The strides, sx, sy, sz, st, represent the step length, in bytes, between + consecutive elements of the corresponding array. This makes it possible for + proj_transform to handle transformation of a large class of application + specific data structures, without necessarily understanding the data structure + format, as in: + + typedef struct {double x, y; int quality_level; char surveyor_name[134];} XYQS; + XYQS survey[345]; + double height = 23.45; + PJ *P = {...}; + size_t stride = sizeof (XYQS); + ... + proj_transform ( + P, PJ_INV, sizeof(XYQS), + &(survey[0].x), stride, 345, (* We have 345 eastings *) + &(survey[0].y), stride, 345, (* ...and 345 northings. *) + &height, 1, (* The height is the constant 23.45 m *) + 0, 0 (* and the time is the constant 0.00 s *) + ); + + This is similar to the inner workings of the pj_transform function, but the + stride functionality has been generalized to work for any size of basic unit, + not just a fixed number of doubles. + + In most cases, the stride will be identical for x, y,z, and t, since they will + typically be either individual arrays (stride = sizeof(double)), or strided + views into an array of application specific data structures (stride = sizeof (...)). + + But in order to support cases where x, y, z, and t come from heterogeneous + sources, individual strides, sx, sy, sz, st, are used. + + Caveat: Since proj_transform does its work *in place*, this means that even the + supposedly constants (i.e. length 1 arrays) will return from the call in altered + state. Hence, remember to reinitialize between repeated calls. + + Return value: Number of transformations completed. + +**************************************************************************************/ + PJ_COORD coord = proj_coord_null; + size_t i, nmin; + double null_broadcast = 0; + if (0==P) + return 0; + + /* ignore lengths of null arrays */ + if (0==x) nx = 0; + if (0==y) ny = 0; + if (0==z) nz = 0; + if (0==t) nt = 0; + + /* and make the nullities point to some real world memory for broadcasting nulls */ + if (0==nx) x = &null_broadcast; + if (0==ny) y = &null_broadcast; + if (0==nz) z = &null_broadcast; + if (0==nt) t = &null_broadcast; + + /* nothing to do? */ + if (0==nx+ny+nz+nt) + return 0; + + /* arrays of length 1 are constants, which we broadcast along the longer arrays */ + /* so we need to find the length of the shortest non-unity array to figure out */ + /* how many coordinate pairs we must transform */ + nmin = (nx > 1)? nx: (ny > 1)? ny: (nz > 1)? nz: (nt > 1)? nt: 1; + if ((nx > 1) && (nx < nmin)) nmin = nx; + if ((ny > 1) && (ny < nmin)) nmin = ny; + if ((nz > 1) && (nz < nmin)) nmin = nz; + if ((nt > 1) && (nt < nmin)) nmin = nt; + + /* Check validity of direction flag */ + switch (direction) { + case PJ_FWD: + case PJ_INV: + break; + case PJ_IDENT: + return nmin; + default: + proj_errno_set (P, EINVAL); + return 0; + } + + /* Arrays of length==0 are broadcast as the constant 0 */ + /* Arrays of length==1 are broadcast as their single value */ + /* Arrays of length >1 are iterated over (for the first nmin values) */ + /* The slightly convolved incremental indexing is used due */ + /* to the stride, which may be any size supported by the platform */ + for (i = 0; i < nmin; i++) { + coord.xyzt.x = *x; + coord.xyzt.y = *y; + coord.xyzt.z = *z; + coord.xyzt.t = *t; + + if (PJ_FWD==direction) + coord = pj_fwdcoord (coord, P); + else + coord = pj_invcoord (coord, P); + + /* in all full length cases, we overwrite the input with the output */ + if (nx > 1) { + *x = coord.xyzt.x; + x = (double *) ( ((char *) x) + sx); + } + if (ny > 1) { + *y = coord.xyzt.y; + y = (double *) ( ((char *) y) + sy); + } + if (nz > 1) { + *z = coord.xyzt.z; + z = (double *) ( ((char *) z) + sz); + } + if (nt > 1) { + *t = coord.xyzt.t; + t = (double *) ( ((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) + *y = coord.xyzt.y; + if (nz==1) + *z = coord.xyzt.z; + if (nt==1) + *t = coord.xyzt.t; + + return i; +} + +/*****************************************************************************/ +int proj_transform_coord (PJ *P, PJ_DIRECTION direction, size_t n, PJ_COORD *coord) { +/****************************************************************************** + Batch transform an array of PJ_COORD. + + Returns 0 if all coordinates are transformed without error, otherwise + returns error number. +******************************************************************************/ + size_t i; + for (i=0; i= 511) + continue; + + if (strlen(info.searchpath) != 0) { + strcat(info.searchpath, ";"); + len = strlen(paths[i]); + strncat(info.searchpath, paths[i], sizeof(info.searchpath)-len-1); + } else { + pj_strlcpy(info.searchpath, paths[i], sizeof(info.searchpath)); + } + } + + return info; +} + + +/*****************************************************************************/ +PJ_PROJ_INFO proj_pj_info(PJ *P) { +/****************************************************************************** + Basic info about a particular instance of a projection object. + + Returns PJ_PROJ_INFO struct. + +******************************************************************************/ + PJ_PROJ_INFO info; + char *def; + + memset(&info, 0, sizeof(PJ_PROJ_INFO)); + + /* Expected accuracy of the transformation. Hardcoded for now, will be improved */ + /* later. Most likely to be used when a transformation is set up with */ + /* proj_create_crs_to_crs in a future version that leverages the EPSG database. */ + info.accuracy = -1.0; + + if (!P) { + return info; + } + + /* projection id */ + if (pj_param(P->ctx, P->params, "tproj").i) + pj_strlcpy(info.id, pj_param(P->ctx, P->params, "sproj").s, sizeof(info.id)); + + /* projection description */ + pj_strlcpy(info.description, P->descr, sizeof(info.description)); + + /* projection definition */ + def = pj_get_def(P, 0); /* pj_get_def takes a non-const PJ pointer */ + pj_strlcpy(info.definition, &def[1], sizeof(info.definition)); /* def includes a leading space */ + pj_dealloc(def); + + /* this does not take into account that a pipeline potentially does not */ + /* have an inverse. */ + info.has_inverse = (P->inv != 0 || P->inv3d != 0 || P->invobs != 0); + + return info; +} + + +/*****************************************************************************/ +PJ_GRID_INFO proj_grid_info(const char *gridname) { +/****************************************************************************** + Information about a named datum grid. + + Returns PJ_GRID_INFO struct. + +******************************************************************************/ + PJ_GRID_INFO info; + + /*PJ_CONTEXT *ctx = proj_context_create(); */ + PJ_CONTEXT *ctx = pj_get_default_ctx(); + PJ_GRIDINFO *gridinfo = pj_gridinfo_init(ctx, gridname); + memset(&info, 0, sizeof(PJ_GRID_INFO)); + + /* in case the grid wasn't found */ + if (gridinfo->filename == NULL) { + pj_gridinfo_free(ctx, gridinfo); + strcpy(info.format, "missing"); + return info; + } + + /* name of grid */ + pj_strlcpy(info.gridname, gridname, sizeof(info.gridname)); + + /* full path of grid */ + pj_find_file(ctx, gridname, info.filename, sizeof(info.filename)); + + /* grid format */ + pj_strlcpy(info.format, gridinfo->format, sizeof(info.format)); + + /* grid size */ + info.n_lon = gridinfo->ct->lim.lam; + info.n_lat = gridinfo->ct->lim.phi; + + /* cell size */ + info.cs_lon = gridinfo->ct->del.lam; + info.cs_lat = gridinfo->ct->del.phi; + + /* bounds of grid */ + info.lowerleft = gridinfo->ct->ll; + info.upperright.lam = info.lowerleft.lam + info.n_lon*info.cs_lon; + info.upperright.phi = info.lowerleft.phi + info.n_lat*info.cs_lat; + + pj_gridinfo_free(ctx, gridinfo); + + return info; +} + +/*****************************************************************************/ +PJ_INIT_INFO proj_init_info(const char *initname){ +/****************************************************************************** + Information about a named init file. + + Maximum length of initname is 64. + + Returns PJ_INIT_INFO struct. + + If the init file is not found all members of + the return struct are set to 0. If the init file is found, but it the + metadata is missing, the value is set to "Unknown". + +******************************************************************************/ + int file_found, def_found=0; + char param[80], key[74]; + paralist *start, *next; + PJ_INIT_INFO info; + PJ_CONTEXT *ctx = pj_get_default_ctx(); + + memset(&info, 0, sizeof(PJ_INIT_INFO)); + + file_found = pj_find_file(ctx, initname, info.filename, sizeof(info.filename)); + if (!file_found || strlen(initname) > 64) { + return info; + } + + pj_strlcpy(info.name, initname, sizeof(info.name)); + strcpy(info.origin, "Unknown"); + strcpy(info.version, "Unknown"); + strcpy(info.lastupdate, "Unknown"); + + pj_strlcpy(key, initname, 64); /* make room for ":metadata\0" at the end */ + strncat(key, ":metadata", 9); + strcpy(param, "+init="); + strncat(param, key, 73); + + start = pj_mkparam(param); + next = pj_get_init(ctx, &start, start, key, &def_found); + + if (pj_param(ctx, start, "tversion").i) { + pj_strlcpy(info.version, pj_param(ctx, start, "sversion").s, sizeof(info.version)); + } + + if (pj_param(ctx, start, "torigin").i) { + pj_strlcpy(info.origin, pj_param(ctx, start, "sorigin").s, sizeof(info.origin)); + } + + if (pj_param(ctx, start, "tlastupdate").i) { + pj_strlcpy(info.lastupdate, pj_param(ctx, start, "slastupdate").s, sizeof(info.lastupdate)); + } + + for ( ; start; start = next) { + next = start->next; + pj_dalloc(start); + } + + return info; +} + + +/*****************************************************************************/ +PJ_DERIVS proj_derivatives(PJ *P, const LP lp) { +/****************************************************************************** + Derivatives of coordinates. + + returns PJ_DERIVS. If unsuccessfull error number is set and the returned + struct contains NULL data. + +******************************************************************************/ + PJ_DERIVS derivs; + + if (pj_deriv(lp, 1e-5, P, &derivs)) { + /* errno set in pj_derivs */ + memset(&derivs, 0, sizeof(PJ_DERIVS)); + } + + return derivs; +} + + +/*****************************************************************************/ +PJ_FACTORS proj_factors(PJ *P, const LP lp) { +/****************************************************************************** + Cartographic characteristics at point lp. + + Characteristics include meridian, parallel and areal scales, angular + distortion, meridian/parallel, meridian convergence and scale error. + + returns PJ_FACTORS. If unsuccessfull error number is set and the returned + struct contains NULL data. + +******************************************************************************/ + PJ_FACTORS factors; + + /* pj_factors rely code being zero */ + factors.code = 0; + + if (pj_factors(lp, P, 0.0, &factors)) { + /* errno set in pj_factors */ + memset(&factors, 0, sizeof(PJ_FACTORS)); + } + + return factors; +} + + +const PJ_ELLPS *proj_list_ellps(void) { + return pj_get_ellps_ref(); +} + +const PJ_UNITS *proj_list_units(void) { + return pj_get_units_ref(); +} + +const PJ_OPERATIONS *proj_list_operations(void) { + return pj_get_list_ref(); +} + +const PJ_PRIME_MERIDIANS *proj_list_prime_meridians(void) { + return pj_get_prime_meridians_ref(); +} + +double proj_torad (double angle_in_degrees) { return PJ_TORAD (angle_in_degrees);} +double proj_todeg (double angle_in_radians) { return PJ_TODEG (angle_in_radians);} + + +double proj_dmstor(const char *is, char **rs) { + return dmstor(is, rs); +} + +char* proj_rtodms(char *s, double r, int pos, int neg) { + return rtodms(s, r, pos, neg); +} diff --git a/src/proj_internal.h b/src/proj_internal.h index 0b74b563..5773637c 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -50,6 +50,12 @@ extern "C" { +struct PJ_OBS { + PJ_COORD coo; /* coordinate data */ +}; +typedef struct PJ_OBS PJ_OBS; + + #ifndef PJ_TODEG #define PJ_TODEG(rad) ((rad)*180.0/M_PI) #endif @@ -59,6 +65,9 @@ extern "C" { +PJ_OBS proj_obs (double x, double y, double z, double t); +PJ_OBS proj_trans_obs (PJ *P, PJ_DIRECTION direction, PJ_OBS obs); + PJ_COORD proj_coord_error (void); PJ_OBS proj_obs_error (void); #ifndef PJ_INTERNAL_C diff --git a/src/projects.h b/src/projects.h index cbb980ca..b9d88cf3 100644 --- a/src/projects.h +++ b/src/projects.h @@ -174,6 +174,9 @@ typedef struct { double u, v, w; } UVW; /* Forward declarations and typedefs for stuff needed inside the PJ object */ struct PJconsts; struct PJ_OBS; +#ifndef PROJ_INTERNAL_H +typedef struct PJ_OBS PJ_OBS; +#endif union PJ_COORD; struct geod_geodesic; struct pj_opaque; @@ -189,7 +192,6 @@ enum pj_io_units { }; #ifndef PROJ_H typedef struct PJconsts PJ; /* the PJ object herself */ -typedef struct PJ_OBS PJ_OBS; typedef union PJ_COORD PJ_COORD; #endif @@ -259,7 +261,7 @@ struct PJconsts { void (*spc)(LP, PJ *, struct FACTORS *); void *(*destructor)(PJ *, int); - + /************************************************************************************* -- cgit v1.2.3 From 064efb77179850a552c56831047e8e739aed4067 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Wed, 25 Oct 2017 13:11:48 +0200 Subject: Repair gie and cct after breakage due to proj_strtod update (#628) * Repair gie and cct after breakage due to proj_strtod update * Remove unused variables --- src/cct.c | 20 +++++++++---- src/gie.c | 99 +++++++++++++++++++++++++++++++++++++++++---------------------- 2 files changed, 80 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/cct.c b/src/cct.c index 35d4ec3f..72d8c6cc 100644 --- a/src/cct.c +++ b/src/cct.c @@ -289,22 +289,32 @@ char *column (char *buf, int n) { return buf; } +/* column to double */ +static double cold (char *args, int col) { + char *endp; + char *target; + double d; + target = column (args, col); + d = proj_strtod (target, &endp); + if (endp==target) + return HUGE_VAL; + return d; +} PJ_COORD parse_input_line (char *buf, int *columns, double fixed_height, double fixed_time) { PJ_COORD err = proj_coord (HUGE_VAL, HUGE_VAL, HUGE_VAL, HUGE_VAL); PJ_COORD result = err; int prev_errno = errno; - char *endptr = 0; errno = 0; result.xyzt.z = fixed_height; result.xyzt.t = fixed_time; - result.xyzt.x = proj_strtod (column (buf, columns[0]), &endptr); - result.xyzt.y = proj_strtod (column (buf, columns[1]), &endptr); + result.xyzt.x = cold (buf, columns[0]); + result.xyzt.y = cold (buf, columns[1]); if (result.xyzt.z==HUGE_VAL) - result.xyzt.z = proj_strtod (column (buf, columns[2]), &endptr); + result.xyzt.z = cold (buf, columns[2]); if (result.xyzt.t==HUGE_VAL) - result.xyzt.t = proj_strtod (column (buf, columns[3]), &endptr); + result.xyzt.t = cold (buf, columns[3]); if (0!=errno) return err; diff --git a/src/gie.c b/src/gie.c index 33fc4d82..f0850b61 100644 --- a/src/gie.c +++ b/src/gie.c @@ -132,6 +132,7 @@ static int get_inp (FILE *f, char *inp, int size); static int get_cmnd (char *inp, char *cmnd, int len); static char *get_args (char *inp); static int dispatch (char *cmnd, char *args); +static char *column (char *buf, int n); @@ -314,6 +315,52 @@ static int process_file (char *fname) { } +/* return a pointer to the n'th column of buf */ +char *column (char *buf, int n) { + int i; + if (n <= 0) + return buf; + for (i = 0; i < n; i++) { + while (isspace(*buf)) + buf++; + if (i == n - 1) + break; + while ((0 != *buf) && !isspace(*buf)) + buf++; + } + return buf; +} + + + +static double strtod_scaled (char *args, double default_scale) { + double s; + char *endp = args; + s = proj_strtod (args, &endp); + if (args==endp) + return HUGE_VAL; + + endp = column (args, 2); + + if (0==strcmp(endp, "km")) + s *= 1000; + else if (0==strcmp(endp, "m")) + s *= 1; + else if (0==strcmp(endp, "dm")) + s /= 10; + else if (0==strcmp(endp, "cm")) + s /= 100; + else if (0==strcmp(endp, "mm")) + s /= 1000; + else if (0==strcmp(endp, "um")) + s /= 1e6; + else if (0==strcmp(endp, "nm")) + s /= 1e9; + else + s *= default_scale; + return s; +} + @@ -334,31 +381,11 @@ static int banner (char *args) { static int tolerance (char *args) { - char *endp = args; - T.tolerance = proj_strtod (endp, &endp); + T.tolerance = strtod_scaled (args, 1); if (HUGE_VAL==T.tolerance) { T.tolerance = 0.0005; return 1; } - while (isspace (*endp)) - endp++; - - if (0==strcmp(endp, "km")) - T.tolerance *= 1000; - else if (0==strcmp(endp, "m")) - T.tolerance *= 1; - else if (0==strcmp(endp, "dm")) - T.tolerance /= 10; - else if (0==strcmp(endp, "cm")) - T.tolerance /= 100; - else if (0==strcmp(endp, "mm")) - T.tolerance /= 1000; - else if (0==strcmp(endp, "um")) - T.tolerance /= 1e6; - else if (0==strcmp(endp, "nm")) - T.tolerance /= 1e9; - else - T.tolerance /= 1000; /* If no unit, assume mm */ return 0; } @@ -436,15 +463,17 @@ static PJ_COORD torad_if_needed (PJ *P, PJ_DIRECTION dir, PJ_COORD a) { static int accept (char *args) { int n, i; - char *endp = args; + char *endp, *prev = args; T.a = proj_coord (0,0,0,0); n = 4; for (i = 0; i < 4; i++) { - T.a.v[i] = proj_strtod (endp, &endp); - if (HUGE_VAL==T.a.v[i]) { + T.a.v[i] = proj_strtod (prev, &endp); + if (prev==endp) { n--; T.a.v[i] = 0; + break; } + prev = endp; } T.a = torad_if_needed (T.P, T.dir, T.a); if (T.verbosity > 3) @@ -457,11 +486,11 @@ static int accept (char *args) { static int roundtrip (char *args) { int ntrips; double d, r, ans; - char *endp, *endq; + char *endp; ans = proj_strtod (args, &endp); - ntrips = (int) (ans==HUGE_VAL? 100: fabs(ans)); - d = proj_strtod (endp, &endq); - d = (endp==endq)? T.tolerance: d / 1000; + 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) { @@ -469,7 +498,7 @@ static int roundtrip (char *args) { 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 deivation: %.3f mm, expected: %.3f mm\n", 1000*r, 1000*d); + fprintf (T.fout, " roundtrip deviation: %.3f mm, expected: %.3f mm\n", 1000*r, 1000*d); } T.op_ko++; T.total_ko++; @@ -485,18 +514,20 @@ static int roundtrip (char *args) { static int expect (char *args) { double d; enum pj_io_units unit; - char *endp = args; + 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 (endp, &endp); - if (HUGE_VAL==T.e.v[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); @@ -525,8 +556,8 @@ static int expect (char *args) { d = proj_xyz_dist (T.b.xyz, T.e.xyz); if (d > T.tolerance) { - if (d > 10) - d = 9.999999; + if (d > 1e6) + d = 999999.999999; if (T.verbosity > -1) { if (0==T.op_ko && T.verbosity < 2) banner (T.operation); -- cgit v1.2.3 From 47dd489e1def98f583a3288e4e3f101ae741b4e2 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Wed, 25 Oct 2017 20:46:56 +0200 Subject: Remove superfluous internal selftests from projection files matching patterns PJ_f....c and PJ_e....c --- src/PJ_fahey.c | 44 +------------ src/PJ_fouc_s.c | 44 +------------ src/PJ_gall.c | 44 +------------ src/PJ_geos.c | 59 +---------------- src/PJ_gins8.c | 30 +-------- src/PJ_gn_sinu.c | 197 ++----------------------------------------------------- src/PJ_gnom.c | 44 +------------ src/PJ_goode.c | 46 +------------ src/PJ_gstmerc.c | 45 +------------ 9 files changed, 14 insertions(+), 539 deletions(-) (limited to 'src') diff --git a/src/PJ_fahey.c b/src/PJ_fahey.c index 42318f8f..4fcb7849 100644 --- a/src/PJ_fahey.c +++ b/src/PJ_fahey.c @@ -37,46 +37,4 @@ PJ *PROJECTION(fahey) { return P; } -#ifndef PJ_SELFTEST -int pj_fahey_selftest (void) {return 0;} -#else - -int pj_fahey_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=fahey +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 182993.34464912376, 101603.19356988439}, - { 182993.34464912376, -101603.19356988439}, - {-182993.34464912376, 101603.19356988439}, - {-182993.34464912376, -101603.19356988439}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {0.0021857886080359551, 0.00098424601668238403}, - {0.0021857886080359551, -0.00098424601668238403}, - {-0.0021857886080359551, 0.00098424601668238403}, - {-0.0021857886080359551, -0.00098424601668238403}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_fahey_selftest (void) {return 10000;} diff --git a/src/PJ_fouc_s.c b/src/PJ_fouc_s.c index 343e5878..c581e690 100644 --- a/src/PJ_fouc_s.c +++ b/src/PJ_fouc_s.c @@ -67,46 +67,4 @@ PJ *PROJECTION(fouc_s) { } -#ifndef PJ_SELFTEST -int pj_fouc_s_selftest (void) {return 0;} -#else - -int pj_fouc_s_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=fouc_s +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223402.14425527424, 111695.40119861449}, - { 223402.14425527424, -111695.40119861449}, - {-223402.14425527424, 111695.40119861449}, - {-223402.14425527424, -111695.40119861449}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017904931097838226, 0.000895246554928339}, - { 0.0017904931097838226, -0.000895246554928339}, - {-0.0017904931097838226, 0.000895246554928339}, - {-0.0017904931097838226, -0.000895246554928339}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_fouc_s_selftest (void) {return 10000;} diff --git a/src/PJ_gall.c b/src/PJ_gall.c index 01a56e33..8a003073 100644 --- a/src/PJ_gall.c +++ b/src/PJ_gall.c @@ -41,46 +41,4 @@ PJ *PROJECTION(gall) { } -#ifndef PJ_SELFTEST -int pj_gall_selftest (void) {return 0;} -#else - -int pj_gall_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=gall +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 157969.17113451968, 95345.249178385886}, - { 157969.17113451968, -95345.249178385886}, - {-157969.17113451968, 95345.249178385886}, - {-157969.17113451968, -95345.249178385886}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0025321396391918614, 0.001048846580346495}, - { 0.0025321396391918614, -0.001048846580346495}, - {-0.0025321396391918614, 0.001048846580346495}, - {-0.0025321396391918614, -0.001048846580346495}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_gall_selftest (void) {return 10000;} diff --git a/src/PJ_geos.c b/src/PJ_geos.c index 5fd3e56b..7d527409 100644 --- a/src/PJ_geos.c +++ b/src/PJ_geos.c @@ -234,61 +234,4 @@ PJ *PROJECTION(geos) { } -#ifndef PJ_SELFTEST -int pj_geos_selftest (void) {return 0;} -#else - -int pj_geos_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=geos +ellps=GRS80 +lat_1=0.5 +lat_2=2 +h=35785831"}; - char s_args[] = {"+proj=geos +R=6400000 +lat_1=0.5 +lat_2=2 +h=35785831"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222527.07036580026, 110551.30341332949}, - { 222527.07036580026, -110551.30341332949}, - {-222527.07036580026, 110551.30341332949}, - {-222527.07036580026, -110551.30341332949}, - }; - - XY s_fwd_expect[] = { - { 223289.45763579503, 111677.65745653701}, - { 223289.45763579503, -111677.65745653701}, - {-223289.45763579503, 111677.65745653701}, - {-223289.45763579503, -111677.65745653701}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017966305689715385, 0.00090436947723267452}, - { 0.0017966305689715385, -0.00090436947723267452}, - {-0.0017966305689715385, 0.00090436947723267452}, - {-0.0017966305689715385, -0.00090436947723267452}, - }; - - LP s_inv_expect[] = { - { 0.0017904931105078943, 0.00089524655504237148}, - { 0.0017904931105078943, -0.00089524655504237148}, - {-0.0017904931105078943, 0.00089524655504237148}, - {-0.0017904931105078943, -0.00089524655504237148}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_geos_selftest (void) {return 10000;} diff --git a/src/PJ_gins8.c b/src/PJ_gins8.c index b27ec092..26db4f31 100644 --- a/src/PJ_gins8.c +++ b/src/PJ_gins8.c @@ -31,32 +31,4 @@ PJ *PROJECTION(gins8) { } -#ifndef PJ_SELFTEST -int pj_gins8_selftest (void) {return 0;} -#else - -int pj_gins8_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=gins8 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 194350.25093959007, 111703.90763533533}, - { 194350.25093959007, -111703.90763533533}, - {-194350.25093959007, 111703.90763533533}, - {-194350.25093959007, -111703.90763533533}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif +int pj_gins8_selftest (void) {return 10000;} diff --git a/src/PJ_gn_sinu.c b/src/PJ_gn_sinu.c index d13f2834..bfe26b53 100644 --- a/src/PJ_gn_sinu.c +++ b/src/PJ_gn_sinu.c @@ -120,7 +120,7 @@ PJ *PROJECTION(sinu) { if (!(Q->en = pj_enfn(P->es))) return pj_default_destructor (P, ENOMEM); - + if (P->es != 0.0) { P->inv = e_inverse; P->fwd = e_forward; @@ -184,194 +184,7 @@ PJ *PROJECTION(gn_sinu) { } -#ifndef PJ_SELFTEST -int pj_sinu_selftest (void) {return 0;} -#else - -int pj_sinu_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=sinu +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=sinu +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222605.29953946592, 110574.38855415257}, - { 222605.29953946592, -110574.38855415257}, - {-222605.29953946592, 110574.38855415257}, - {-222605.29953946592, -110574.38855415257}, - }; - - XY s_fwd_expect[] = { - { 223368.11902663155, 111701.07212763709}, - { 223368.11902663155, -111701.07212763709}, - {-223368.11902663155, 111701.07212763709}, - {-223368.11902663155, -111701.07212763709}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017966305684613522, 0.00090436947707945409}, - { 0.0017966305684613522, -0.00090436947707945409}, - {-0.0017966305684613522, 0.00090436947707945409}, - {-0.0017966305684613522, -0.00090436947707945409}, - }; - - LP s_inv_expect[] = { - { 0.0017904931100023887, 0.00089524655489191132}, - { 0.0017904931100023887, -0.00089524655489191132}, - {-0.0017904931100023887, 0.00089524655489191132}, - {-0.0017904931100023887, -0.00089524655489191132}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif - -#ifndef PJ_SELFTEST -int pj_eck6_selftest (void) {return 0;} -#else - -int pj_eck6_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=eck6 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 197021.60562899226, 126640.42073317352}, - { 197021.60562899226, -126640.42073317352}, - {-197021.60562899226, 126640.42073317352}, - {-197021.60562899226, -126640.42073317352}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.002029978749734037, 0.00078963032910382171}, - { 0.002029978749734037, -0.00078963032910382171}, - {-0.002029978749734037, 0.00078963032910382171}, - {-0.002029978749734037, -0.00078963032910382171}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif - -#ifndef PJ_SELFTEST -int pj_mbtfps_selftest (void) {return 0;} -#else - -int pj_mbtfps_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=mbtfps +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 204740.11747857218, 121864.72971934026}, - { 204740.11747857218, -121864.72971934026}, - {-204740.11747857218, 121864.72971934026}, - {-204740.11747857218, -121864.72971934026}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0019534152166442065, 0.00082057965689633387}, - { 0.0019534152166442065, -0.00082057965689633387}, - {-0.0019534152166442065, 0.00082057965689633387}, - {-0.0019534152166442065, -0.00082057965689633387}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif - - -#ifndef PJ_SELFTEST -int pj_gn_sinu_selftest (void) {return 0;} -#else - -int pj_gn_sinu_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=gn_sinu +a=6400000 +lat_1=0.5 +lat_2=2 +m=1 +n=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223385.13250469571, 111698.23644718733}, - { 223385.13250469571, -111698.23644718733}, - {-223385.13250469571, 111698.23644718733}, - {-223385.13250469571, -111698.23644718733}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017904931098931057, 0.00089524655491012516}, - { 0.0017904931098931057, -0.00089524655491012516}, - {-0.0017904931098931057, 0.00089524655491012516}, - {-0.0017904931098931057, -0.00089524655491012516}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_sinu_selftest (void) {return 10000;} +int pj_eck6_selftest (void) {return 10000;} +int pj_mbtfps_selftest (void) {return 10000;} +int pj_gn_sinu_selftest (void) {return 10000;} diff --git a/src/PJ_gnom.c b/src/PJ_gnom.c index 1d3f3386..2aedefec 100644 --- a/src/PJ_gnom.c +++ b/src/PJ_gnom.c @@ -136,46 +136,4 @@ PJ *PROJECTION(gnom) { } -#ifndef PJ_SELFTEST -int pj_gnom_selftest (void) {return 0;} -#else - -int pj_gnom_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=gnom +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223492.92474718543, 111780.50920659291}, - { 223492.92474718543, -111780.50920659291}, - {-223492.92474718543, 111780.50920659291}, - {-223492.92474718543, -111780.50920659291}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017904931092009798, 0.00089524655438192376}, - { 0.0017904931092009798, -0.00089524655438192376}, - {-0.0017904931092009798, 0.00089524655438192376}, - {-0.0017904931092009798, -0.00089524655438192376}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_gnom_selftest (void) {return 10000;} diff --git a/src/PJ_goode.c b/src/PJ_goode.c index 3bfeb21f..3c5d172d 100644 --- a/src/PJ_goode.c +++ b/src/PJ_goode.c @@ -71,7 +71,7 @@ PJ *PROJECTION(goode) { Q->moll->ctx = P->ctx; if (!(Q->sinu = pj_sinu(Q->sinu)) || !(Q->moll = pj_moll(Q->moll))) return destructor (P, ENOMEM); - + P->fwd = s_forward; P->inv = s_inverse; @@ -79,46 +79,4 @@ PJ *PROJECTION(goode) { } -#ifndef PJ_SELFTEST -int pj_goode_selftest (void) {return 0;} -#else - -int pj_goode_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=goode +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223368.11902663155, 111701.07212763709}, - { 223368.11902663155, -111701.07212763709}, - {-223368.11902663155, 111701.07212763709}, - {-223368.11902663155, -111701.07212763709}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017904931100023887, 0.00089524655489191132}, - { 0.0017904931100023887, -0.00089524655489191132}, - {-0.0017904931100023887, 0.00089524655489191132}, - {-0.0017904931100023887, -0.00089524655489191132}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_goode_selftest (void) {return 10000;} diff --git a/src/PJ_gstmerc.c b/src/PJ_gstmerc.c index c2846761..efb44b88 100644 --- a/src/PJ_gstmerc.c +++ b/src/PJ_gstmerc.c @@ -69,47 +69,4 @@ PJ *PROJECTION(gstmerc) { } -#ifndef PJ_SELFTEST -int pj_gstmerc_selftest (void) {return 0;} -#else - -int pj_gstmerc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=gstmerc +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - - XY s_fwd_expect[] = { - { 223413.46640632182, 111769.14504058557}, - { 223413.46640632182, -111769.14504058668}, - {-223413.46640632302, 111769.14504058557}, - {-223413.46640632302, -111769.14504058668}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017904931097109673, 0.0008952465544509083}, - { 0.0017904931097109673, -0.0008952465544509083}, - {-0.0017904931097109673, 0.0008952465544509083}, - {-0.0017904931097109673, -0.0008952465544509083}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_gstmerc_selftest (void) {return 10000;} -- cgit v1.2.3 From 3a2bd267a67d41a461946a6f7b0a99262f47d8a7 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Mon, 23 Oct 2017 11:38:56 +0200 Subject: Refactor grid shift functions. This refactoring of the grid shift functions allows for easier access to the actual grid values, as well as making it possible to perform horizontal grid shift on a single coordinate without using the pj_apply_gridshift* functions. The latter simplifies the execution path of the forward and inverse functions in PJ_hgridshift.c. This commit introduces proj_*grid_init, proj_*grid_value and proj_hgrid_apply. The init functions initialises horizontal and vertical grids respectivelive (wrappers for pj_gridlist_from_nadgrids with simpler parameters). The proj_*grid_value functions returns the specific grid value at coordinate lp. The proj_hgrid_apply function applies the grid offset to the input coordinate and outputs the adjusted coordinate. --- src/PJ_hgridshift.c | 52 ++------ src/PJ_vgridshift.c | 25 ++-- src/pj_apply_gridshift.c | 275 +++++++++++++++++++++++++++-------------- src/pj_apply_vgridshift.c | 305 ++++++++++++++++++++++++++++------------------ src/proj_internal.h | 7 +- 5 files changed, 398 insertions(+), 266 deletions(-) (limited to 'src') diff --git a/src/PJ_hgridshift.c b/src/PJ_hgridshift.c index 0adc9e00..659039ab 100644 --- a/src/PJ_hgridshift.c +++ b/src/PJ_hgridshift.c @@ -4,7 +4,6 @@ PROJ_HEAD(hgridshift, "Horizontal grid shift"); - static XYZ forward_3d(LPZ lpz, PJ *P) { PJ_TRIPLET point; point.lpz = lpz; @@ -12,9 +11,7 @@ static XYZ forward_3d(LPZ lpz, PJ *P) { if (P->gridlist != NULL) { /* Only try the gridshift if at least one grid is loaded, * otherwise just pass the coordinate through unchanged. */ - pj_apply_gridshift_3( P->ctx, P->gridlist, - P->gridlist_count, 1, 1, 0, - &point.xyz.x, &point.xyz.y, &point.xyz.z ); + point.lp = proj_hgrid_apply(P, point.lp, PJ_FWD); } return point.xyz; @@ -28,9 +25,7 @@ static LPZ reverse_3d(XYZ xyz, PJ *P) { if (P->gridlist != NULL) { /* Only try the gridshift if at least one grid is loaded, * otherwise just pass the coordinate through unchanged. */ - pj_apply_gridshift_3( P->ctx, P->gridlist, - P->gridlist_count, 0, 1, 0, - &point.xyz.x, &point.xyz.y, &point.xyz.z ); + point.lp = proj_hgrid_apply(P, point.lp, PJ_INV); } return point.lpz; @@ -52,29 +47,8 @@ static PJ_OBS reverse_obs(PJ_OBS obs, PJ *P) { -#if 0 -static XY forward_xy(LP lp, PJ *P) { - PJ_TRIPLET point; - point.lp = lp; - point.lpz.z = 0; - point.xyz = forward_3d (point.lpz, P); - return point.xy; -} - - -static LP reverse_lp(XY xy, PJ *P) { - PJ_TRIPLET point; - point.xy = xy; - point.xyz.z = 0; - point.lpz = reverse_3d (point.xyz, P); - return point.lp; -} -#endif - - - PJ *PROJECTION(hgridshift) { - + P->fwdobs = forward_obs; P->invobs = reverse_obs; P->fwd3d = forward_3d; @@ -90,14 +64,12 @@ PJ *PROJECTION(hgridshift) { return pj_default_destructor (P, PJD_ERR_NO_ARGS); } - /* Build gridlist. P->gridlist can be empty if +grids only ask for optional grids. */ - P->gridlist = pj_gridlist_from_nadgrids( P->ctx, pj_param(P->ctx, P->params, "sgrids").s, - &(P->gridlist_count) ); + proj_hgrid_init(P, "grids"); /* Was gridlist compiled properly? */ - if ( pj_ctx_get_errno(pj_get_ctx(P)) ) { + if ( proj_errno(P) ) { proj_log_error(P, "hgridshift: could not find required grid(s)."); - return pj_default_destructor (P, PJD_ERR_FAILED_TO_LOAD_GRID); + return pj_default_destructor(P, PJD_ERR_FAILED_TO_LOAD_GRID); } return P; @@ -119,26 +91,28 @@ int pj_hgridshift_selftest (void) { proj_destroy (P); return 99; } - + /* fail on purpose: open non-existing grid */ P = proj_create(PJ_DEFAULT_CTX, "+proj=hgridshift +grids=@nonexistinggrid.gsb,anothernonexistinggrid.gsb"); if (0!=P) { proj_destroy (P); return 999; } - + /* Failure most likely means the grid is missing */ P = proj_create(PJ_DEFAULT_CTX, "+proj=hgridshift +grids=nzgd2kgrid0005.gsb +ellps=GRS80"); if (0==P) return 10; - + a = proj_obs_null; a.coo.lpz.lam = PJ_TORAD(173); a.coo.lpz.phi = PJ_TORAD(-45); - + dist = proj_roundtrip (P, PJ_FWD, 1, a.coo); - if (dist > 0.00000001) + if (dist > 0.00000001) { + printf("dist: %f\n",dist); return 1; + } expect.coo.lpz.lam = PJ_TORAD(172.999892181021551); expect.coo.lpz.phi = PJ_TORAD(-45.001620431954613); diff --git a/src/PJ_vgridshift.c b/src/PJ_vgridshift.c index ededd544..691f791b 100644 --- a/src/PJ_vgridshift.c +++ b/src/PJ_vgridshift.c @@ -9,14 +9,10 @@ static XYZ forward_3d(LPZ lpz, PJ *P) { PJ_TRIPLET point; point.lpz = lpz; - if (P->gridlist != NULL) { + if (P->vgridlist_geoid != NULL) { /* Only try the gridshift if at least one grid is loaded, * otherwise just pass the coordinate through unchanged. */ - pj_apply_vgridshift( P, "sgrids", - &(P->gridlist), - &(P->gridlist_count), - 1, 1, 0, - &point.xyz.x, &point.xyz.y, &point.xyz.z ); + point.xyz.z -= proj_vgrid_value(P, point.lp); } return point.xyz; @@ -27,14 +23,10 @@ static LPZ reverse_3d(XYZ xyz, PJ *P) { PJ_TRIPLET point; point.xyz = xyz; - if (P->gridlist != NULL) { + if (P->vgridlist_geoid != NULL) { /* Only try the gridshift if at least one grid is loaded, * otherwise just pass the coordinate through unchanged. */ - pj_apply_vgridshift( P, "sgrids", - &(P->gridlist), - &(P->gridlist_count), - 0, 1, 0, - &point.xyz.x, &point.xyz.y, &point.xyz.z ); + point.xyz.z += proj_vgrid_value(P, point.lp); } return point.lpz; @@ -61,14 +53,13 @@ PJ *PROJECTION(vgridshift) { return pj_default_destructor(P, PJD_ERR_NO_ARGS); } - /* Build gridlist. P->gridlist can be empty if +grids only ask for optional grids. */ - P->gridlist = pj_gridlist_from_nadgrids( P->ctx, pj_param(P->ctx, P->params, "sgrids").s, - &(P->gridlist_count) ); + /* Build gridlist. P->vgridlist_geoid can be empty if +grids only ask for optional grids. */ + proj_vgrid_init(P, "grids"); /* Was gridlist compiled properly? */ - if ( pj_ctx_get_errno(P->ctx) ) { + if ( proj_errno(P) ) { proj_log_error(P, "vgridshift: could not find required grid(s)."); - return pj_default_destructor(P, -38); + return pj_default_destructor(P, PJD_ERR_FAILED_TO_LOAD_GRID); } P->fwdobs = forward_obs; diff --git a/src/pj_apply_gridshift.c b/src/pj_apply_gridshift.c index 91e2de26..45887abd 100644 --- a/src/pj_apply_gridshift.c +++ b/src/pj_apply_gridshift.c @@ -2,7 +2,7 @@ * Project: PROJ.4 * Purpose: Apply datum shifts based on grid shift files (normally NAD27 to * NAD83 or the reverse). This module is responsible for keeping - * a list of loaded grids, and calling with each one that is + * a list of loaded grids, and calling with each one that is * allowed for a given datum (expressed as the nadgrids= parameter). * Author: Frank Warmerdam, warmerdam@pobox.com * @@ -30,9 +30,10 @@ #define PJ_LIB__ -#include #include #include +#include "proj_internal.h" +#include "projects.h" /************************************************************************/ /* pj_apply_gridshift() */ @@ -43,7 +44,7 @@ /* it to honour our public api. */ /************************************************************************/ -int pj_apply_gridshift( projCtx ctx, const char *nadgrids, int inverse, +int pj_apply_gridshift( projCtx ctx, const char *nadgrids, int inverse, long point_count, int point_offset, double *x, double *y, double *z ) @@ -51,16 +52,16 @@ int pj_apply_gridshift( projCtx ctx, const char *nadgrids, int inverse, PJ_GRIDINFO **gridlist; int grid_count; int ret; - + gridlist = pj_gridlist_from_nadgrids( ctx, nadgrids, &grid_count ); if( gridlist == NULL || grid_count == 0 ) return ctx->last_errno; - ret = pj_apply_gridshift_3( ctx, gridlist, grid_count, inverse, + ret = pj_apply_gridshift_3( ctx, gridlist, grid_count, inverse, point_count, point_offset, x, y, z ); - /* + /* ** Note this frees the array of grid list pointers, but not the grids ** which is as intended. The grids themselves live on. */ @@ -72,13 +73,13 @@ int pj_apply_gridshift( projCtx ctx, const char *nadgrids, int inverse, /************************************************************************/ /* pj_apply_gridshift_2() */ /* */ -/* This implementation takes uses the gridlist from a coordinate */ +/* This implementation uses the gridlist from a coordinate */ /* system definition. If the gridlist has not yet been */ /* populated in the coordinate system definition we set it up */ /* now. */ /************************************************************************/ -int pj_apply_gridshift_2( PJ *defn, int inverse, +int pj_apply_gridshift_2( PJ *defn, int inverse, long point_count, int point_offset, double *x, double *y, double *z ) @@ -86,10 +87,10 @@ int pj_apply_gridshift_2( PJ *defn, int inverse, if( defn->catalog_name != NULL ) return pj_gc_apply_gridshift( defn, inverse, point_count, point_offset, x, y, z ); - + if( defn->gridlist == NULL ) { - defn->gridlist = + defn->gridlist = pj_gridlist_from_nadgrids( pj_get_ctx( defn ), pj_param(defn->ctx, defn->params,"snadgrids").s, &(defn->gridlist_count) ); @@ -97,12 +98,76 @@ int pj_apply_gridshift_2( PJ *defn, int inverse, if( defn->gridlist == NULL || defn->gridlist_count == 0 ) return defn->ctx->last_errno; } - + return pj_apply_gridshift_3( pj_get_ctx( defn ), - defn->gridlist, defn->gridlist_count, inverse, + defn->gridlist, defn->gridlist_count, inverse, point_count, point_offset, x, y, z ); } +/************************************************************************/ +/* find_ctable() */ +/* */ +/* Determine which grid is the correct given an input coordinate. */ +/************************************************************************/ + +static struct CTABLE* find_ctable(projCtx ctx, LP input, int grid_count, PJ_GRIDINFO **tables) { + int itable; + double epsilon; + struct CTABLE *ct = NULL; + + /* keep trying till we find a table that works */ + for( itable = 0; itable < grid_count; itable++ ) + { + + PJ_GRIDINFO *gi = tables[itable]; + ct = gi->ct; + epsilon = (fabs(ct->del.phi)+fabs(ct->del.lam))/10000.0; + /* skip tables that don't match our point at all. */ + if ( ct->ll.phi - epsilon > input.phi + || ct->ll.lam - epsilon > input.lam + || (ct->ll.phi + (ct->lim.phi-1) * ct->del.phi + epsilon < input.phi) + || (ct->ll.lam + (ct->lim.lam-1) * ct->del.lam + epsilon < input.lam) ) { + continue; + } + + /* If we have child nodes, check to see if any of them apply. */ + while( gi->child ) + { + PJ_GRIDINFO *child; + + for( child = gi->child; child != NULL; child = child->next ) + { + struct CTABLE *ct1 = child->ct; + epsilon = (fabs(ct1->del.phi)+fabs(ct1->del.lam))/10000.0; + + if( ct1->ll.phi - epsilon > input.phi + || ct1->ll.lam - epsilon > input.lam + || (ct1->ll.phi+(ct1->lim.phi-1)*ct1->del.phi + epsilon < input.phi) + || (ct1->ll.lam+(ct1->lim.lam-1)*ct1->del.lam + epsilon < input.lam) ) { + continue; + } + break; + } + + /* If we didn't find a child then nothing more to do */ + if( child == NULL ) break; + + /* Otherwise use the child, first checking it's children */ + gi = child; + ct = child->ct; + } + /* load the grid shift info if we don't have it. */ + if( ct->cvs == NULL) { + if (!pj_gridinfo_load( ctx, gi ) ) { + pj_ctx_set_errno( ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); + return NULL; + } + } + /* if we get this far we have found a suitable grid */ + break; + } + return ct; +} /************************************************************************/ /* pj_apply_gridshift_3() */ @@ -113,16 +178,16 @@ int pj_apply_gridshift_2( PJ *defn, int inverse, int pj_apply_gridshift_3( projCtx ctx, PJ_GRIDINFO **tables, int grid_count, int inverse, long point_count, int point_offset, double *x, double *y, double *z ) - { int i; + struct CTABLE *ct; static int debug_count = 0; (void) z; if( tables == NULL || grid_count == 0 ) { - pj_ctx_set_errno( ctx, -38); - return -38; + pj_ctx_set_errno(ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + return PJD_ERR_FAILED_TO_LOAD_GRID; } ctx->last_errno = 0; @@ -138,100 +203,39 @@ int pj_apply_gridshift_3( projCtx ctx, PJ_GRIDINFO **tables, int grid_count, output.phi = HUGE_VAL; output.lam = HUGE_VAL; - /* keep trying till we find a table that works */ - for( itable = 0; itable < grid_count; itable++ ) - { - PJ_GRIDINFO *gi = tables[itable]; - struct CTABLE *ct = gi->ct; - double epsilon = (fabs(ct->del.phi)+fabs(ct->del.lam))/10000.0; - - /* skip tables that don't match our point at all. */ - if( ct->ll.phi - epsilon > input.phi - || ct->ll.lam - epsilon > input.lam - || (ct->ll.phi + (ct->lim.phi-1) * ct->del.phi + epsilon - < input.phi) - || (ct->ll.lam + (ct->lim.lam-1) * ct->del.lam + epsilon - < input.lam) ) - continue; - - /* If we have child nodes, check to see if any of them apply. */ - while( gi->child ) - { - PJ_GRIDINFO *child; - - for( child = gi->child; child != NULL; child = child->next ) - { - struct CTABLE *ct1 = child->ct; - epsilon = - (fabs(ct1->del.phi)+fabs(ct1->del.lam))/10000.0; - - if( ct1->ll.phi - epsilon > input.phi - || ct1->ll.lam - epsilon > input.lam - || (ct1->ll.phi+(ct1->lim.phi-1)*ct1->del.phi + epsilon - < input.phi) - || (ct1->ll.lam+(ct1->lim.lam-1)*ct1->del.lam + epsilon - < input.lam) ) - continue; - - break; - } - - /* If we didn't find a child then nothing more to do */ - - if( child == NULL ) break; - - /* Otherwise use the child, first checking it's children */ - - gi = child; - ct = child->ct; - } + ct = find_ctable(ctx, input, grid_count, tables); + output = nad_cvt( input, inverse, ct ); - /* load the grid shift info if we don't have it. */ - if( ct->cvs == NULL && !pj_gridinfo_load( ctx, gi ) ) - { - pj_ctx_set_errno( ctx, -38 ); - return -38; - } - - output = nad_cvt( input, inverse, ct ); - if( output.lam != HUGE_VAL ) - { - if( debug_count++ < 20 ) - pj_log( ctx, PJ_LOG_DEBUG_MINOR, - "pj_apply_gridshift(): used %s", ct->id ); - break; - } - } + if ( output.lam != HUGE_VAL && debug_count++ < 20 ) + pj_log( ctx, PJ_LOG_DEBUG_MINOR, "pj_apply_gridshift(): used %s", ct->id ); - if( output.lam == HUGE_VAL ) + if ( output.lam == HUGE_VAL ) { if( ctx->debug_level >= PJ_LOG_DEBUG_MAJOR ) { pj_log( ctx, PJ_LOG_DEBUG_MAJOR, "pj_apply_gridshift(): failed to find a grid shift table for\n" " location (%.7fdW,%.7fdN)", - x[io] * RAD_TO_DEG, + x[io] * RAD_TO_DEG, y[io] * RAD_TO_DEG ); for( itable = 0; itable < grid_count; itable++ ) { PJ_GRIDINFO *gi = tables[itable]; if( itable == 0 ) - pj_log( ctx, PJ_LOG_DEBUG_MAJOR, - " tried: %s", gi->gridname ); + pj_log( ctx, PJ_LOG_DEBUG_MAJOR, " tried: %s", gi->gridname ); else - pj_log( ctx, PJ_LOG_DEBUG_MAJOR, - ",%s", gi->gridname ); + pj_log( ctx, PJ_LOG_DEBUG_MAJOR, ",%s", gi->gridname ); } } - /* - * We don't actually have any machinery currently to set the - * following macro, so this is mostly kept here to make it clear - * how we ought to operate if we wanted to make it super clear + /* + * We don't actually have any machinery currently to set the + * following macro, so this is mostly kept here to make it clear + * how we ought to operate if we wanted to make it super clear * that an error has occurred when points are outside our available - * datum shift areas. But if this is on, we will find that "low - * value" points on the fringes of some datasets will completely - * fail causing lots of problems when it is more or less ok to + * datum shift areas. But if this is on, we will find that "low + * value" points on the fringes of some datasets will completely + * fail causing lots of problems when it is more or less ok to * just not apply a datum shift. So rather than deal with * that we just fallback to no shift. (see also bug #45). */ @@ -252,3 +256,92 @@ int pj_apply_gridshift_3( projCtx ctx, PJ_GRIDINFO **tables, int grid_count, return 0; } +/**********************************************/ +int proj_hgrid_init(PJ* P, const char *grids) { +/********************************************** + + Initizalize and populate list of horizontal + grids. + + Takes a PJ-object and the plus-parameter + name that is used in the proj-string to + specify the grids to load, e.g. "+grids". + The + should be left out here. + + Returns the number of loaded grids. + +***********************************************/ + + /* prepend "s" to the "grids" string to allow usage with pj_param */ + char *sgrids = (char *) pj_malloc( (strlen(grids)+1) *sizeof(char) ); + sprintf(sgrids, "%s%s", "s", grids); + + if (P->gridlist == NULL) { + P->gridlist = pj_gridlist_from_nadgrids( + P->ctx, + pj_param(P->ctx, P->params, sgrids).s, + &(P->gridlist_count) + ); + + if( P->gridlist == NULL || P->gridlist_count == 0 ) { + pj_dealloc(sgrids); + return 0; + } + } + + if (P->gridlist_count == 0) { + proj_errno_set(P, PJD_ERR_FAILED_TO_LOAD_GRID); + } + + pj_dealloc(sgrids); + return P->gridlist_count; +} + +/********************************************/ +/* proj_hgrid_value() */ +/* */ +/* Return coordinate offset in grid */ +/********************************************/ +LP proj_hgrid_value(PJ *P, LP lp) { + struct CTABLE *ct; + LP out; + + ct = find_ctable(P->ctx, lp, P->gridlist_count, P->gridlist); + + /* normalize input to ll origin */ + lp.lam -= ct->ll.lam; + lp.phi -= ct->ll.phi; + lp.lam = adjlon(lp.lam - M_PI) + M_PI; + + out = nad_intr(lp, ct); + + if (out.lam == HUGE_VAL || out.phi == HUGE_VAL) { + pj_ctx_set_errno(P->ctx, PJD_ERR_GRID_AREA); + } + + return out; +} + +LP proj_hgrid_apply(PJ *P, LP lp, PJ_DIRECTION direction) { + struct CTABLE *ct; + int inverse; + LP out; + + out.lam = HUGE_VAL; out.phi = HUGE_VAL; + + ct = find_ctable(P->ctx, lp, P->gridlist_count, P->gridlist); + + if (ct == NULL || ct->cvs == NULL) { + pj_ctx_set_errno( P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); + return out; + } + + inverse = direction == PJ_FWD ? 0 : 1; + out = nad_cvt(lp, inverse, ct); + + if (out.lam == HUGE_VAL || out.phi == HUGE_VAL) + pj_ctx_set_errno(P->ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + + return out; + +} diff --git a/src/pj_apply_vgridshift.c b/src/pj_apply_vgridshift.c index 35047a19..3c7cc210 100644 --- a/src/pj_apply_vgridshift.c +++ b/src/pj_apply_vgridshift.c @@ -28,23 +28,120 @@ #define PJ_LIB__ -#include #include #include +#include "proj_internal.h" +#include "projects.h" + +static double pj_read_vgrid_value( PJ *defn, LP input, int *gridlist_count_p, PJ_GRIDINFO **tables, struct CTABLE *ct) { + int itable = 0; + double value = HUGE_VAL; + double grid_x, grid_y; + int grid_ix, grid_iy; + int grid_ix2, grid_iy2; + float *cvs; + /* do not deal with NaN coordinates */ + if( input.phi != input.phi || input.lam != input.lam ) + itable = *gridlist_count_p; + + /* keep trying till we find a table that works */ + for ( ; itable < *gridlist_count_p; itable++ ) + { + PJ_GRIDINFO *gi = tables[itable]; + + ct = gi->ct; + + /* skip tables that don't match our point at all. */ + if( ct->ll.phi > input.phi || ct->ll.lam > input.lam + || ct->ll.phi + (ct->lim.phi-1) * ct->del.phi < input.phi + || ct->ll.lam + (ct->lim.lam-1) * ct->del.lam < input.lam ) + continue; + + /* If we have child nodes, check to see if any of them apply. */ + while( gi->child != NULL ) + { + PJ_GRIDINFO *child; + + for( child = gi->child; child != NULL; child = child->next ) + { + struct CTABLE *ct1 = child->ct; + + if( ct1->ll.phi > input.phi || ct1->ll.lam > input.lam + || ct1->ll.phi+(ct1->lim.phi-1)*ct1->del.phi < input.phi + || ct1->ll.lam+(ct1->lim.lam-1)*ct1->del.lam < input.lam) + continue; + + break; + } + + /* we didn't find a more refined child node to use, so go with current grid */ + if( child == NULL ) + { + break; + } + + /* Otherwise let's try for childrens children .. */ + gi = child; + ct = child->ct; + } + + /* load the grid shift info if we don't have it. */ + if( ct->cvs == NULL && !pj_gridinfo_load( pj_get_ctx(defn), gi ) ) + { + pj_ctx_set_errno( defn->ctx, PJD_ERR_FAILED_TO_LOAD_GRID ); + return PJD_ERR_FAILED_TO_LOAD_GRID; + } + + } + + /* Interpolation a location within the grid */ + grid_x = (input.lam - ct->ll.lam) / ct->del.lam; + grid_y = (input.phi - ct->ll.phi) / ct->del.phi; + grid_ix = (int) floor(grid_x); + grid_iy = (int) floor(grid_y); + grid_x -= grid_ix; + grid_y -= grid_iy; + + grid_ix2 = grid_ix + 1; + if( grid_ix2 >= ct->lim.lam ) + grid_ix2 = ct->lim.lam - 1; + grid_iy2 = grid_iy + 1; + if( grid_iy2 >= ct->lim.phi ) + grid_iy2 = ct->lim.phi - 1; + + cvs = (float *) ct->cvs; + value = cvs[grid_ix + grid_iy * ct->lim.lam] + * (1.0-grid_x) * (1.0-grid_y) + + cvs[grid_ix2 + grid_iy * ct->lim.lam] + * (grid_x) * (1.0-grid_y) + + cvs[grid_ix + grid_iy2 * ct->lim.lam] + * (1.0-grid_x) * (grid_y) + + cvs[grid_ix2 + grid_iy2 * ct->lim.lam] + * (grid_x) * (grid_y); + + /* nodata? */ + /* GTX official nodata value if -88.88880f, but some grids also */ + /* use other big values for nodata (e.g naptrans2008.gtx has */ + /* nodata values like -2147479936), so test them too */ + if( value > 1000 || value < -1000 || value == -88.88880f ) + value = HUGE_VAL; + + + return value; +} /************************************************************************/ /* pj_apply_vgridshift() */ /* */ -/* This implementation takes uses the gridlist from a coordinate */ +/* This implementation takes uses the gridlist from a coordinate */ /* system definition. If the gridlist has not yet been */ /* populated in the coordinate system definition we set it up */ /* now. */ /************************************************************************/ - int pj_apply_vgridshift( PJ *defn, const char *listname, - PJ_GRIDINFO ***gridlist_p, + PJ_GRIDINFO ***gridlist_p, int *gridlist_count_p, - int inverse, + int inverse, long point_count, int point_offset, double *x, double *y, double *z ) @@ -52,22 +149,23 @@ int pj_apply_vgridshift( PJ *defn, const char *listname, int i; static int debug_count = 0; PJ_GRIDINFO **tables; + struct CTABLE ct; if( *gridlist_p == NULL ) { - *gridlist_p = - pj_gridlist_from_nadgrids( pj_get_ctx(defn), + *gridlist_p = + pj_gridlist_from_nadgrids( pj_get_ctx(defn), pj_param(defn->ctx,defn->params,listname).s, gridlist_count_p ); if( *gridlist_p == NULL || *gridlist_count_p == 0 ) return defn->ctx->last_errno; } - + if( *gridlist_count_p == 0 ) { - pj_ctx_set_errno( defn->ctx, -38); - return -38; + pj_ctx_set_errno( defn->ctx, PJD_ERR_FAILED_TO_LOAD_GRID); + return PJD_ERR_FAILED_TO_LOAD_GRID; } tables = *gridlist_p; @@ -75,127 +173,37 @@ int pj_apply_vgridshift( PJ *defn, const char *listname, for( i = 0; i < point_count; i++ ) { + double value; long io = i * point_offset; LP input; - int itable = 0; - double value = HUGE_VAL; input.phi = y[io]; input.lam = x[io]; - /* do not deal with NaN coordinates */ - if( input.phi != input.phi || input.lam != input.lam ) - itable = *gridlist_count_p; + value = pj_read_vgrid_value(defn, input, gridlist_count_p, tables, &ct); - /* keep trying till we find a table that works */ - for( ; itable < *gridlist_count_p; itable++ ) + if( inverse ) + z[io] -= value; + else + z[io] += value; + if( value != HUGE_VAL ) { - PJ_GRIDINFO *gi = tables[itable]; - struct CTABLE *ct = gi->ct; - double grid_x, grid_y; - int grid_ix, grid_iy; - int grid_ix2, grid_iy2; - float *cvs; - - /* skip tables that don't match our point at all. */ - if( ct->ll.phi > input.phi || ct->ll.lam > input.lam - || ct->ll.phi + (ct->lim.phi-1) * ct->del.phi < input.phi - || ct->ll.lam + (ct->lim.lam-1) * ct->del.lam < input.lam ) - continue; - - /* If we have child nodes, check to see if any of them apply. */ - while( gi->child != NULL ) - { - PJ_GRIDINFO *child; - - for( child = gi->child; child != NULL; child = child->next ) - { - struct CTABLE *ct1 = child->ct; - - if( ct1->ll.phi > input.phi || ct1->ll.lam > input.lam - || ct1->ll.phi+(ct1->lim.phi-1)*ct1->del.phi < input.phi - || ct1->ll.lam+(ct1->lim.lam-1)*ct1->del.lam < input.lam) - continue; - - break; - } - - /* we didn't find a more refined child node to use, so go with current grid */ - if( child == NULL ) - { - break; - } - - /* Otherwise let's try for childrens children .. */ - gi = child; - ct = child->ct; - } - - /* load the grid shift info if we don't have it. */ - if( ct->cvs == NULL && !pj_gridinfo_load( pj_get_ctx(defn), gi ) ) - { - pj_ctx_set_errno( defn->ctx, -38 ); - return -38; - } - - /* Interpolation a location within the grid */ - grid_x = (input.lam - ct->ll.lam) / ct->del.lam; - grid_y = (input.phi - ct->ll.phi) / ct->del.phi; - grid_ix = (int) floor(grid_x); - grid_iy = (int) floor(grid_y); - grid_x -= grid_ix; - grid_y -= grid_iy; - - grid_ix2 = grid_ix + 1; - if( grid_ix2 >= ct->lim.lam ) - grid_ix2 = ct->lim.lam - 1; - grid_iy2 = grid_iy + 1; - if( grid_iy2 >= ct->lim.phi ) - grid_iy2 = ct->lim.phi - 1; - - cvs = (float *) ct->cvs; - value = cvs[grid_ix + grid_iy * ct->lim.lam] - * (1.0-grid_x) * (1.0-grid_y) - + cvs[grid_ix2 + grid_iy * ct->lim.lam] - * (grid_x) * (1.0-grid_y) - + cvs[grid_ix + grid_iy2 * ct->lim.lam] - * (1.0-grid_x) * (grid_y) - + cvs[grid_ix2 + grid_iy2 * ct->lim.lam] - * (grid_x) * (grid_y); - - /* nodata? */ - /* GTX official nodata value if -88.88880f, but some grids also */ - /* use other big values for nodata (e.g naptrans2008.gtx has */ - /* nodata values like -2147479936), so test them too */ - if( value > 1000 || value < -1000 || value == -88.88880f ) - value = HUGE_VAL; - else - { - if( inverse ) - z[io] -= value; - else - z[io] += value; - } - - if( value != HUGE_VAL ) - { - if( debug_count++ < 20 ) - pj_log( defn->ctx, PJ_LOG_DEBUG_MINOR, - "pj_apply_gridshift(): used %s", - ct->id ); + if( debug_count++ < 20 ) { + proj_log_trace(defn, "pj_apply_gridshift(): used %s", ct.id); break; } } if( value == HUGE_VAL ) { + int itable; char gridlist[3000]; - pj_log( defn->ctx, PJ_LOG_DEBUG_MAJOR, - "pj_apply_vgridshift(): failed to find a grid shift table for\n" - " location (%.7fdW,%.7fdN)", - x[io] * RAD_TO_DEG, - y[io] * RAD_TO_DEG ); + proj_log_debug(defn, + "pj_apply_vgridshift(): failed to find a grid shift table for\n" + " location (%.7fdW,%.7fdN)", + x[io] * RAD_TO_DEG, + y[io] * RAD_TO_DEG ); gridlist[0] = '\0'; for( itable = 0; itable < *gridlist_count_p; itable++ ) @@ -212,10 +220,10 @@ int pj_apply_vgridshift( PJ *defn, const char *listname, else sprintf( gridlist+strlen(gridlist), ",%s", gi->gridname ); } - pj_log( defn->ctx, PJ_LOG_DEBUG_MAJOR, - "%s", gridlist ); - + + proj_log_debug(defn, "%s", gridlist); pj_ctx_set_errno( defn->ctx, PJD_ERR_GRID_AREA ); + return PJD_ERR_GRID_AREA; } } @@ -223,3 +231,64 @@ int pj_apply_vgridshift( PJ *defn, const char *listname, return 0; } +/**********************************************/ +int proj_vgrid_init(PJ* P, const char *grids) { +/********************************************** + + Initizalize and populate gridlist. + + Takes a PJ-object and the plus-parameter + name that is used in the proj-string to + specify the grids to load, e.g. "+grids". + The + should be left out here. + + Returns the number of loaded grids. + +***********************************************/ + + /* prepend "s" to the "grids" string to allow usage with pj_param */ + char *sgrids = (char *) pj_malloc( (strlen(grids)+1+1) *sizeof(char) ); + sprintf(sgrids, "%s%s", "s", grids); + + if (P->vgridlist_geoid == NULL) { + P->vgridlist_geoid = pj_gridlist_from_nadgrids( + P->ctx, + pj_param(P->ctx, P->params, sgrids).s, + &(P->vgridlist_geoid_count) + ); + + if( P->vgridlist_geoid == NULL || P->vgridlist_geoid_count == 0 ) { + pj_dealloc(sgrids); + return 0; + } + } + + if (P->vgridlist_geoid_count == 0) { + proj_errno_set(P, PJD_ERR_FAILED_TO_LOAD_GRID); + } + + pj_dealloc(sgrids); + return P->vgridlist_geoid_count; +} + +/***********************************************/ +double proj_vgrid_value(PJ *P, LP lp){ +/*********************************************** + + Read grid value at position lp in grids loaded + with proj_grid_init. + + Returns the grid value of the given coordinate. + +************************************************/ + + struct CTABLE used_grid; + double value; + memset(&used_grid, 0, sizeof(struct CTABLE)); + + value = pj_read_vgrid_value(P, lp, &(P->vgridlist_geoid_count), P->vgridlist_geoid, &used_grid); + proj_log_trace(P, "proj_vgrid_value: (%f, %f) = %f", lp.lam*RAD_TO_DEG, lp.phi*RAD_TO_DEG, value); + + return value; +} + diff --git a/src/proj_internal.h b/src/proj_internal.h index 5773637c..29e73e70 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -89,7 +89,12 @@ PJ_OBS pj_invobs (PJ_OBS obs, PJ *P); PJ_COORD pj_fwdcoord (PJ_COORD coo, PJ *P); PJ_COORD pj_invcoord (PJ_COORD coo, PJ *P); - +/* Grid functionality */ +int proj_vgrid_init(PJ *P, const char *grids); +int proj_hgrid_init(PJ *P, const char *grids); +double proj_vgrid_value(PJ *P, LP lp); +LP proj_hgrid_value(PJ *P, LP lp); +LP proj_hgrid_apply(PJ *P, LP lp, PJ_DIRECTION direction); /* High level functionality for handling thread contexts */ enum proj_log_level { -- cgit v1.2.3 From 5877ffac2fd4c2f89deb5b9d962a1969192856c4 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Mon, 23 Oct 2017 11:52:59 +0200 Subject: Addition of 'deformation': Kinematic grid shifting. Kinematic deformation models are used in some geodetic transformations. This commit introduces the ability to do transformations involving a gridded deformation/velocity model. For practical reasons a gridded deformation model needs to be split into two seperate files, one for the horizontal components and one for the vertical component. For this we use formats already known to PROJ.4, namely the CTable/CTable2 and the GTX formats. Grids are specified in the proj-string with +xy_grids and +z_grids. Grid values are expected to be in m/year. The kinematic part of the operation is controlled by the +t_epoch parameter, which is the central epoch of the transformation. An observation epoch is also needed. It can be specified either in the PJ_OBS input as the fourth element in the coordinate, or in the proj-string with +t_obs. If +t_obs is present in the proj-string it takes presedence over the value in the PJ_OBS coordinate. --- src/Makefile.am | 2 +- src/PJ_deformation.c | 291 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib_proj.cmake | 1 + src/makefile.vc | 3 +- src/pj_ell_set.c | 39 ++++++- src/pj_list.h | 1 + src/proj_internal.h | 1 + 7 files changed, 335 insertions(+), 3 deletions(-) create mode 100644 src/PJ_deformation.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 363f2cce..0bfcfb24 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -87,7 +87,7 @@ libproj_la_SOURCES = \ \ proj_4D_api.c PJ_cart.c PJ_pipeline.c PJ_horner.c PJ_helmert.c \ PJ_vgridshift.c PJ_hgridshift.c PJ_unitconvert.c PJ_molodensky.c \ - pj_internal.c + PJ_deformation.c pj_internal.c install-exec-local: rm -f $(DESTDIR)$(bindir)/invproj$(EXEEXT) diff --git a/src/PJ_deformation.c b/src/PJ_deformation.c new file mode 100644 index 00000000..05858900 --- /dev/null +++ b/src/PJ_deformation.c @@ -0,0 +1,291 @@ +/*********************************************************************** + + Kinematic datum shifting utilizing a deformation model + + Kristian Evers, 2017-10-29 + +************************************************************************ + +Perform datum shifts by means of a deformation/velocity model. + + X_out = X_in + (T_ct - T_obs)*DX + Y_out = Y_in + (T_ct - T_obs)*DY + Z_out = Z_in + (T_ct - T_obs)*DZ + + +Corrections are done in cartesian space. Coordinates of the +gridded model are in lat/long space and the corrections in the model are +in cartesian space. Hence the input coordinates needs to be converted +to lat/long space when searching for corrections in the grid. The +corrections are then applied to the input coordinates in cartesian +space. + +A full deformation model is described by two grids, one for the horizontal +components and one for the vertical component. The horizontal grid is +stored in CTable/CTable2 and the vertical grid is stored in the GTX +format. Both grids are expected to contain grid-values in units of +m/year. + +************************************************************************ +* Copyright (c) 2017, Kristian Evers +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +***********************************************************************/ +#define PJ_LIB__ +#include +#include +#include "proj_internal.h" +#include "projects.h" + +PROJ_HEAD(deformation, "Kinematic grid shift"); + +#define TOL 1e-8 +#define MAX_ITERATIONS 10 + +struct pj_opaque { + double t_obs; + double t_epoch; + int has_xy_grids, has_z_grids; + PJ *cart; +}; + +static XYZ get_xygrid_shift(PJ* P, XYZ cartesian) { + PJ_COORD geodetic, shift; + + geodetic.lpz = pj_inv3d(cartesian, P->opaque->cart); + shift.lp = proj_hgrid_value(P, geodetic.lp); + + return shift.xyz; +} + +static double get_zgrid_shift(PJ* P, XYZ cartesian) { + PJ_COORD geodetic; + + geodetic.lpz = pj_inv3d(cartesian, P->opaque->cart); + + return proj_vgrid_value(P, geodetic.lp); +} + +static XYZ reverse_hshift(PJ *P, XYZ input, double dt) { + XYZ out, delta, dif; + int i = MAX_ITERATIONS; + + delta = get_xygrid_shift(P, input); + + out.x = input.x + dt*delta.x; + out.y = input.y - dt*delta.y; + out.z = input.z; + + do { + delta = get_xygrid_shift(P, out); + + if (delta.x == HUGE_VAL) + break; + + dif.x = out.x - dt*delta.x - input.x; + dif.y = out.y + dt*delta.y - input.y; + out.x += dif.x; + out.y += dif.y; + + } while ( --i && hypot(dif.x, dif.y) > TOL ); + + return out; +} + +static XYZ forward_3d(LPZ lpz, PJ *P) { + struct pj_opaque *Q = (struct pj_opaque *) P->opaque; + PJ_COORD out, in; + XYZ shift; + double dt = 0.0; + in.lpz = lpz; + out = in; + + if (Q->t_obs != HUGE_VAL) { + dt = Q->t_obs - Q->t_epoch; + } else { + out = proj_coord_error(); /* in the 3D case +t_obs must be specified */ + proj_log_debug(P, "deformation: +t_obs must be specified"); + return out.xyz; + } + + if (Q->has_xy_grids) { + shift = get_xygrid_shift(P, in.xyz); + + out.xyz.x += dt * shift.x; + out.xyz.y += dt * shift.y; + } + + if (Q->has_z_grids) + out.xyz.z += dt * get_zgrid_shift(P, in.xyz); + + return out.xyz; +} + + +static PJ_OBS forward_obs(PJ_OBS in, PJ *P) { + struct pj_opaque *Q = (struct pj_opaque *) P->opaque; + double dt; + XYZ shift; + PJ_OBS out = in; + + if (Q->t_obs != HUGE_VAL) { + dt = Q->t_obs - Q->t_epoch; + } else { + dt = in.coo.xyzt.t - Q->t_epoch; + } + + if (Q->has_xy_grids) { + shift = get_xygrid_shift(P, in.coo.xyz); + out.coo.xyz.x += dt * shift.x; + out.coo.xyz.y += dt * shift.y; + } + + if (Q->has_z_grids) + out.coo.xyz.z += dt * get_zgrid_shift(P, in.coo.xyz); + + return out; +} + + +static LPZ reverse_3d(XYZ in, PJ *P) { + struct pj_opaque *Q = (struct pj_opaque *) P->opaque; + PJ_COORD out; + double dt = 0.0; + out.xyz = in; + + if (Q->t_obs != HUGE_VAL) { + dt = Q->t_epoch - Q->t_obs; + } else { + out = proj_coord_error(); /* in the 3D case +t_obs must be specified */ + proj_log_debug(P, "deformation: +t_obs must be specified"); + return out.lpz; + } + + if (Q->has_xy_grids) { + out.xyz = reverse_hshift(P, in, dt); + } + + if (Q->has_z_grids) + out.xyz.z = in.z + dt * get_zgrid_shift(P, in); + + return out.lpz; +} + +static PJ_OBS reverse_obs(PJ_OBS in, PJ *P) { + struct pj_opaque *Q = (struct pj_opaque *) P->opaque; + PJ_OBS out = in; + double dt; + + if (Q->t_obs != HUGE_VAL) { + dt = Q->t_epoch - Q->t_obs; + } else { + dt = Q->t_epoch - in.coo.xyzt.t; + } + + if (Q->has_xy_grids) + out.coo.xyz = reverse_hshift(P, in.coo.xyz, dt); + + if (Q->has_z_grids) + out.coo.xyz.z = in.coo.xyz.z + dt * get_zgrid_shift(P, in.coo.xyz); + + return out; +} + +static void *destructor(PJ *P, int errlev) { + if (0==P) + return 0; + + if (0==P->opaque) + return pj_default_destructor (P, errlev); + + if (P->opaque->cart) + P->opaque->cart->destructor (P->opaque->cart, errlev); + + return pj_default_destructor(P, errlev); +} + + +PJ *PROJECTION(deformation) { + struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); + if (0==Q) + return pj_default_destructor(P, ENOMEM); + P->opaque = (void *) Q; + + Q->cart = proj_create(P->ctx, "+proj=cart"); + if (Q->cart == 0) + return destructor(P, ENOMEM); + + /* inherit ellipsoid definition from P to Q->cart (simpler than guessing */ + /* how the ellipsoid was specified in original definition) */ + pj_inherit_ellipsoid_defs(P, Q->cart); + + Q->has_xy_grids = pj_param(P->ctx, P->params, "txy_grids").i; + Q->has_z_grids = pj_param(P->ctx, P->params, "tz_grids").i; + + /* Build gridlists. P->gridlist and P->vgridlist_geoid can be empty if */ + /* +xy_grids or +z_grids only ask for optional grids */ + if (!Q->has_xy_grids && !Q->has_z_grids) { + proj_log_error(P, "deformation: At least one of either +xy_grids or +z_grids should be specified."); + return destructor(P, PJD_ERR_NO_ARGS ); + } + + if (Q->has_xy_grids) { + Q->has_xy_grids = proj_hgrid_init(P, "xy_grids"); + if (proj_errno(P)) { + proj_log_error(P, "deformation: could not find requested grid(s)."); + return destructor(P, PJD_ERR_FAILED_TO_LOAD_GRID); + } + } + + if (Q->has_z_grids) { + Q->has_z_grids = proj_vgrid_init(P, "z_grids"); + if (proj_errno(P)) { + proj_log_error(P, "deformation: could not find requested grid(s)."); + return destructor(P, PJD_ERR_FAILED_TO_LOAD_GRID); + } + } + + Q->t_obs = HUGE_VAL; + if (pj_param(P->ctx, P->params, "tt_obs").i) { + Q->t_obs = pj_param(P->ctx, P->params, "dt_obs").f; + } + + if (pj_param(P->ctx, P->params, "tt_epoch").i) { + Q->t_epoch = pj_param(P->ctx, P->params, "dt_epoch").f; + } else { + proj_log_error(P, "deformation: +t_epoch parameter missing."); + return destructor(P, PJD_ERR_MISSING_ARGS); + } + + P->fwdobs = forward_obs; + P->invobs = reverse_obs; + P->fwd3d = forward_3d; + P->inv3d = reverse_3d; + P->fwd = 0; + P->inv = 0; + + P->left = PJ_IO_UNITS_METERS; + P->right = PJ_IO_UNITS_METERS; + P->destructor = destructor; + + return P; +} + +int pj_deformation_selftest (void) {return 10000;} diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 053e9ef6..969ad64b 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -58,6 +58,7 @@ SET(SRC_LIBPROJ_PJ PJ_collg.c PJ_comill.c PJ_crast.c + PJ_deformation.c PJ_denoy.c PJ_eck1.c PJ_eck2.c diff --git a/src/makefile.vc b/src/makefile.vc index 1330e9bb..15fd6428 100644 --- a/src/makefile.vc +++ b/src/makefile.vc @@ -61,7 +61,8 @@ support = \ pipeline = \ proj_4D_api.obj PJ_cart.obj PJ_pipeline.obj PJ_horner.obj PJ_helmert.obj \ - PJ_vgridshift.obj PJ_hgridshift.obj PJ_unitconvert.obj PJ_molodensky.obj + PJ_vgridshift.obj PJ_hgridshift.obj PJ_unitconvert.obj PJ_molodensky.obj \ + PJ_deformation.obj geodesic = geodesic.obj diff --git a/src/pj_ell_set.c b/src/pj_ell_set.c index 72892ac2..d43feecb 100644 --- a/src/pj_ell_set.c +++ b/src/pj_ell_set.c @@ -1,12 +1,49 @@ /* set ellipsoid parameters a and es */ -#include #include +#include "proj_internal.h" +#include "projects.h" #define SIXTH .1666666666666666667 /* 1/6 */ #define RA4 .04722222222222222222 /* 17/360 */ #define RA6 .02215608465608465608 /* 67/3024 */ #define RV4 .06944444444444444444 /* 5/72 */ #define RV6 .04243827160493827160 /* 55/1296 */ +/* copy ellipsoidal parameters from src to dst */ +void pj_inherit_ellipsoid_defs(const PJ *src, PJ *dst) { + + /* The linear parameters */ + dst->a = src->a; + dst->b = src->b; + dst->ra = src->ra; + dst->rb = src->rb; + + /* The eccentricities */ + dst->alpha = src->alpha; + dst->e = src->e; + dst->es = src->es; + dst->e2 = src->e2; + dst->e2s = src->e2s; + dst->e3 = src->e3; + dst->e3s = src->e3s; + dst->one_es = src->one_es; + dst->rone_es = src->rone_es; + + /* The flattenings */ + dst->f = src->f; + dst->f2 = src->f2; + dst->n = src->n; + dst->rf = src->rf; + dst->rf2 = src->rf2; + dst->rn = src->rn; + + /* This one's for GRS80 */ + dst->J = src->J; + + /* es and a before any +proj related adjustment */ + dst->es_orig = src->es_orig; + dst->a_orig = src->a_orig; +} + /* initialize geographic shape parameters */ int pj_ell_set(projCtx ctx, paralist *pl, double *a, double *es) { int i; diff --git a/src/pj_list.h b/src/pj_list.h index bf287219..76c37126 100644 --- a/src/pj_list.h +++ b/src/pj_list.h @@ -25,6 +25,7 @@ PROJ_HEAD(chamb, "Chamberlin Trimetric") PROJ_HEAD(collg, "Collignon") PROJ_HEAD(comill, "Compact Miller") PROJ_HEAD(crast, "Craster Parabolic (Putnins P4)") +PROJ_HEAD(deformation, "Kinematic grid shift") PROJ_HEAD(denoy, "Denoyer Semi-Elliptical") PROJ_HEAD(eck1, "Eckert I") PROJ_HEAD(eck2, "Eckert II") diff --git a/src/proj_internal.h b/src/proj_internal.h index 29e73e70..ba542dea 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -117,6 +117,7 @@ void proj_log_trace (PJ *P, const char *fmt, ...); /*void proj_log_func (PJ *P, void *app_data, void (*log)(void *, int, const char *));*/ void proj_log_func (PJ_CONTEXT *ctx, void *app_data, PJ_LOG_FUNCTION log); +void pj_inherit_ellipsoid_defs(const PJ *src, PJ *dst); /* Lowest level: Minimum support for fileapi */ void proj_fileapi_set (PJ *P, void *fileapi); -- cgit v1.2.3 From f7f1d3e0fe966e76e8fab2048519e15bf2434c64 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Sun, 29 Oct 2017 23:04:14 +0100 Subject: Make sure to use the same context for pipeline childs as for the parent --- src/PJ_pipeline.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index f1411cb4..b60105bf 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -436,7 +436,7 @@ PJ *PROJECTION(pipeline) { for (j = 1; j < current_argc; j++) proj_log_trace (P, " %s", current_argv[j]); - next_step = pj_init (current_argc, current_argv); + next_step = pj_init_ctx (P->ctx, current_argc, current_argv); proj_log_trace (P, "Pipeline: Step %d at %p", i, next_step); if (0==next_step) { proj_log_error (P, "Pipeline: Bad step definition: %s", current_argv[0]); -- cgit v1.2.3 From 9222694f522afb0dd96a50a8263dad62efa5d54e Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Mon, 30 Oct 2017 16:08:31 +0100 Subject: change suspicious loop exit condition in nad_cvt (#634) * change suspicious loop exit condition in nad_cvt * touch up nad_cvt.c * ...and remove tabs --- src/nad_cvt.c | 122 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 62 insertions(+), 60 deletions(-) (limited to 'src') diff --git a/src/nad_cvt.c b/src/nad_cvt.c index f48f9e0d..c913511f 100644 --- a/src/nad_cvt.c +++ b/src/nad_cvt.c @@ -1,68 +1,70 @@ #define PJ_LIB__ -#include -#define MAX_TRY 9 +#include "projects.h" +#define MAX_ITERATIONS 10 #define TOL 1e-12 - LP -nad_cvt(LP in, int inverse, struct CTABLE *ct) { - LP t, tb; - if (in.lam == HUGE_VAL) - return in; - /* normalize input to ll origin */ - tb = in; - tb.lam -= ct->ll.lam; - tb.phi -= ct->ll.phi; - tb.lam = adjlon(tb.lam - M_PI) + M_PI; - t = nad_intr(tb, ct); - if (inverse) { - LP del, dif; - int i = MAX_TRY; +LP nad_cvt(LP in, int inverse, struct CTABLE *ct) { + LP t, tb,del, dif; + int i = MAX_ITERATIONS; + const double toltol = TOL*TOL; - if (t.lam == HUGE_VAL) return t; - t.lam = tb.lam + t.lam; - t.phi = tb.phi - t.phi; + if (in.lam == HUGE_VAL) + return in; - do { - del = nad_intr(t, ct); + /* normalize input to ll origin */ + tb = in; + tb.lam -= ct->ll.lam; + tb.phi -= ct->ll.phi; + tb.lam = adjlon (tb.lam - M_PI) + M_PI; - /* This case used to return failure, but I have - changed it to return the first order approximation - of the inverse shift. This avoids cases where the - grid shift *into* this grid came from another grid. - While we aren't returning optimally correct results - I feel a close result in this case is better than - no result. NFW - To demonstrate use -112.5839956 49.4914451 against - the NTv2 grid shift file from Canada. */ - if (del.lam == HUGE_VAL) - { - if( getenv( "PROJ_DEBUG" ) != NULL ) - fprintf( stderr, - "Inverse grid shift iteration failed, presumably at grid edge.\n" - "Using first approximation.\n" ); - /* return del */; - break; - } + t = nad_intr (tb, ct); + if (t.lam == HUGE_VAL) + return t; - t.lam -= dif.lam = t.lam - del.lam - tb.lam; - t.phi -= dif.phi = t.phi + del.phi - tb.phi; - } while (i-- && fabs(dif.lam) > TOL && fabs(dif.phi) > TOL); - if (i < 0) { - if( getenv( "PROJ_DEBUG" ) != NULL ) - fprintf( stderr, - "Inverse grid shift iterator failed to converge.\n" ); - t.lam = t.phi = HUGE_VAL; - return t; - } - in.lam = adjlon(t.lam + ct->ll.lam); - in.phi = t.phi + ct->ll.phi; - } else { - if (t.lam == HUGE_VAL) - in = t; - else { - in.lam -= t.lam; - in.phi += t.phi; - } - } - return in; + if (!inverse) { + in.lam -= t.lam; + in.phi += t.phi; + return in; + } + + t.lam = tb.lam + t.lam; + t.phi = tb.phi - t.phi; + + do { + del = nad_intr(t, ct); + + /* This case used to return failure, but I have + changed it to return the first order approximation + of the inverse shift. This avoids cases where the + grid shift *into* this grid came from another grid. + While we aren't returning optimally correct results + I feel a close result in this case is better than + no result. NFW + To demonstrate use -112.5839956 49.4914451 against + the NTv2 grid shift file from Canada. */ + if (del.lam == HUGE_VAL) + break; + + dif.lam = t.lam - del.lam - tb.lam; + dif.phi = t.phi + del.phi - tb.phi; + t.lam -= dif.lam; + t.phi -= dif.phi; + + } while (--i && (dif.lam*dif.lam + dif.phi*dif.phi > toltol)); /* prob. slightly faster than hypot() */ + + if (i==0) { + /* If we had access to a context, this should go through pj_log, and we should set ctx->errno */ + if (getenv ("PROJ_DEBUG")) + fprintf( stderr, "Inverse grid shift iterator failed to converge.\n" ); + t.lam = t.phi = HUGE_VAL; + return t; + } + + /* and again: pj_log and ctx->errno */ + if (del.lam==HUGE_VAL && getenv ("PROJ_DEBUG")) + fprintf (stderr, "Inverse grid shift iteration failed, presumably at grid edge.\nUsing first approximation.\n"); + + in.lam = adjlon (t.lam + ct->ll.lam); + in.phi = t.phi + ct->ll.phi; + return in; } -- cgit v1.2.3 From 0d1eeb16dd0a574d81ba0eaeea430f1be105a038 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Tue, 31 Oct 2017 13:05:15 +0100 Subject: Fix heap-buffer-overflow in proj_hgrid_init. Resolves https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3940 Credit to OSS-Fuzz. --- src/pj_apply_gridshift.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/pj_apply_gridshift.c b/src/pj_apply_gridshift.c index 45887abd..7d9ac94b 100644 --- a/src/pj_apply_gridshift.c +++ b/src/pj_apply_gridshift.c @@ -273,7 +273,7 @@ int proj_hgrid_init(PJ* P, const char *grids) { ***********************************************/ /* prepend "s" to the "grids" string to allow usage with pj_param */ - char *sgrids = (char *) pj_malloc( (strlen(grids)+1) *sizeof(char) ); + char *sgrids = (char *) pj_malloc( (strlen(grids)+1+1) *sizeof(char) ); sprintf(sgrids, "%s%s", "s", grids); if (P->gridlist == NULL) { -- cgit v1.2.3 From c8bef3173f55ec2de0d0ea452c0c9a07e0c89638 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Tue, 31 Oct 2017 22:46:40 +0100 Subject: Add 'axisswap' operation - swap axes in pipelines --- src/Makefile.am | 2 +- src/PJ_axisswap.c | 243 +++++++++++++++++++++++++++++++++++++++++++++++++++++ src/lib_proj.cmake | 1 + src/makefile.vc | 3 +- src/pj_list.h | 1 + 5 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 src/PJ_axisswap.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 0bfcfb24..7edc05b1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -87,7 +87,7 @@ libproj_la_SOURCES = \ \ proj_4D_api.c PJ_cart.c PJ_pipeline.c PJ_horner.c PJ_helmert.c \ PJ_vgridshift.c PJ_hgridshift.c PJ_unitconvert.c PJ_molodensky.c \ - PJ_deformation.c pj_internal.c + PJ_deformation.c pj_internal.c PJ_axisswap.c install-exec-local: rm -f $(DESTDIR)$(bindir)/invproj$(EXEEXT) diff --git a/src/PJ_axisswap.c b/src/PJ_axisswap.c new file mode 100644 index 00000000..42c0d779 --- /dev/null +++ b/src/PJ_axisswap.c @@ -0,0 +1,243 @@ +/*********************************************************************** + + Axis order operation for use with transformation pipelines. + + Kristian Evers, kreve@sdfe.dk, 2017-10-31 + +************************************************************************ + +Change the order and sign of 2,3 or 4 axes. Each of the possible four +axes are numbered with 1-4, such that the first input axis is 1, the +second is 2 and so on. The output ordering is controlled by a list of the +input axes re-ordered to the new mapping. Examples: + +Reversing the order of the axes: + + +proj=axisswap +order=4,3,2,1 + +Swapping the first two axes (x and y): + + +proj=axisswap +order=2,1,3,4 + +The direction, or sign, of an axis can be changed by adding a minus in +front of the axis-number: + + +proj=axisswap +order=1,-2,3,4 + +It is only necessary to specify the axes that are affected by the swap +operation: + + +proj=axisswap +order=2,1 + +************************************************************************ +* Copyright (c) 2017, Kristian Evers / SDFE +* +* Permission is hereby granted, free of charge, to any person obtaining a +* copy of this software and associated documentation files (the "Software"), +* to deal in the Software without restriction, including without limitation +* the rights to use, copy, modify, merge, publish, distribute, sublicense, +* and/or sell copies of the Software, and to permit persons to whom the +* Software is furnished to do so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included +* in all copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS +* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +* DEALINGS IN THE SOFTWARE. +* +***********************************************************************/ + +#define PJ_LIB__ +#include +#include "proj_internal.h" +#include "projects.h" + +PROJ_HEAD(axisswap, "Axis ordering"); + +struct pj_opaque { + unsigned int axis[4]; + int sign[4]; +}; + +static int sign(int x) { + return (x > 0) - (x < 0); +} + +static XY forward_2d(LP lp, PJ *P) { + struct pj_opaque *Q = (struct pj_opaque *) P->opaque; + unsigned int i; + PJ_COORD out, in; + + in.lp = lp; + out = proj_coord_error(); + + for (i=0; i<2; i++) + out.v[i] = in.v[Q->axis[i]] * Q->sign[i]; + + return out.xy; +} + + +static LP reverse_2d(XY xy, PJ *P) { + struct pj_opaque *Q = (struct pj_opaque *) P->opaque; + unsigned int i; + PJ_COORD out, in; + + in.xy = xy; + out = proj_coord_error(); + + for (i=0; i<2; i++) + out.v[Q->axis[i]] = in.v[i] * Q->sign[i]; + + return out.lp; +} + + +static XYZ forward_3d(LPZ lpz, PJ *P) { + struct pj_opaque *Q = (struct pj_opaque *) P->opaque; + unsigned int i; + PJ_COORD out, in; + + in.lpz = lpz; + out = proj_coord_error(); + + for (i=0; i<3; i++) + out.v[i] = in.v[Q->axis[i]] * Q->sign[i]; + + return out.xyz; +} + +static LPZ reverse_3d(XYZ xyz, PJ *P) { + struct pj_opaque *Q = (struct pj_opaque *) P->opaque; + unsigned int i; + PJ_COORD in, out; + + out = proj_coord_error(); + in.xyz = xyz; + + for (i=0; i<3; i++) + out.v[Q->axis[i]] = in.v[i] * Q->sign[i]; + + return out.lpz; +} + + +static PJ_OBS forward_obs(PJ_OBS obs, PJ *P) { + struct pj_opaque *Q = (struct pj_opaque *) P->opaque; + unsigned int i; + PJ_COORD in, out; + + out = proj_coord_error(); + in = obs.coo; + + for (i=0; i<4; i++) + out.v[i] = in.v[Q->axis[i]] * Q->sign[i]; + + obs.coo = out; + return obs; +} + + +static PJ_OBS reverse_obs(PJ_OBS obs, PJ *P) { + struct pj_opaque *Q = (struct pj_opaque *) P->opaque; + unsigned int i; + PJ_COORD in, out; + + out = proj_coord_error(); + in = obs.coo; + + for (i=0; i<4; i++) { + out.v[Q->axis[i]] = in.v[i] * Q->sign[i]; + } + + obs.coo = out; + return obs; +} + + +/***********************************************************************/ +PJ *PROJECTION(axisswap) { +/***********************************************************************/ + struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); + char *order, *s; + unsigned int i, j, n; + + if (0==Q) + return pj_default_destructor (P, ENOMEM); + P->opaque = (void *) Q; + + /* read axis order */ + if (pj_param (P->ctx, P->params, "torder").i) { + order = pj_param(P->ctx, P->params, "sorder").s; + } else { + return pj_default_destructor(P, PJD_ERR_MISSING_ARGS); + } + + /* fill axis list with indices from 4-7 to simplify duplicate search further down */ + for (i=0; i<4; i++) + Q->axis[i] = i+4; + + /* check that all characteds are valid */ + for (i=0; iaxis[n] = abs(atoi(s))-1; + Q->sign[n++] = sign(atoi(s)); + while( *s != '\0' && *s != ',' ) + s++; + if( *s == ',' ) + s++; + } + + /* check for duplicate axes */ + for (i=0; i<4; i++) + for (j=0; j<4; j++) { + if (i==j) + continue; + if (Q->axis[i] == Q->axis[j]) { + proj_log_error(P, "swapaxis: duplicate axes specified"); + return pj_default_destructor(P, PJD_ERR_AXIS); + } + } + + /* only map fwd/inv functions that are possible with the given axis setup */ + if (n == 4) { + P->fwdobs = forward_obs; + P->invobs = reverse_obs; + } + if (n == 3 && Q->axis[0] < 3 && Q->axis[1] < 3 && Q->axis[2] < 3) { + P->fwd3d = forward_3d; + P->inv3d = reverse_3d; + } + if (n == 2 && Q->axis[0] < 2 && Q->axis[1] < 2) { + P->fwd = forward_2d; + P->inv = reverse_2d; + } + + if (P->fwdobs == NULL && P->fwd3d == NULL && P->fwd == NULL) { + proj_log_error(P, "swapaxis: bad axis order"); + return pj_default_destructor(P, PJD_ERR_AXIS); + } + + if (pj_param(P->ctx, P->params, "tangularunits").i) { + P->left = PJ_IO_UNITS_RADIANS; + P->right = PJ_IO_UNITS_RADIANS; + } else { + P->left = PJ_IO_UNITS_METERS; + P->right = PJ_IO_UNITS_METERS; + } + + return P; +} + +int pj_axisswap_selftest (void) {return 10000;} diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 969ad64b..4b701886 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -45,6 +45,7 @@ SET(SRC_LIBPROJ_PJ PJ_airy.c PJ_aitoff.c PJ_august.c + PJ_axisswap.c PJ_bacon.c PJ_bipc.c PJ_boggs.c diff --git a/src/makefile.vc b/src/makefile.vc index edb683b0..ae2dc587 100644 --- a/src/makefile.vc +++ b/src/makefile.vc @@ -62,8 +62,7 @@ support = \ pipeline = \ proj_4D_api.obj PJ_cart.obj PJ_pipeline.obj PJ_horner.obj PJ_helmert.obj \ PJ_vgridshift.obj PJ_hgridshift.obj PJ_unitconvert.obj PJ_molodensky.obj \ - PJ_deformation.obj - + PJ_deformation.obj PJ_axisswap.obj geodesic = geodesic.obj diff --git a/src/pj_list.h b/src/pj_list.h index 76c37126..0720b456 100644 --- a/src/pj_list.h +++ b/src/pj_list.h @@ -12,6 +12,7 @@ PROJ_HEAD(aitoff, "Aitoff") PROJ_HEAD(alsk, "Mod. Stererographics of Alaska") PROJ_HEAD(apian, "Apian Globular I") PROJ_HEAD(august, "August Epicycloidal") +PROJ_HEAD(axisswap, "Axis ordering") PROJ_HEAD(bacon, "Bacon Globular") PROJ_HEAD(bipc, "Bipolar conic of western hemisphere") PROJ_HEAD(boggs, "Boggs Eumorphic") -- cgit v1.2.3 From 7503fbe7511cf9b98f9321ef27ee7d2c05401a1e Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Wed, 1 Nov 2017 10:16:08 +0100 Subject: Resolves several OSS-Fuzz issues: 3944, 3947, 3955. https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3944 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3947 https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3955 Credit to OSS-Fuzz. --- src/pj_apply_vgridshift.c | 50 +++++++++++++++++++++++------------------------ 1 file changed, 25 insertions(+), 25 deletions(-) (limited to 'src') diff --git a/src/pj_apply_vgridshift.c b/src/pj_apply_vgridshift.c index 3c7cc210..6435b954 100644 --- a/src/pj_apply_vgridshift.c +++ b/src/pj_apply_vgridshift.c @@ -92,33 +92,33 @@ static double pj_read_vgrid_value( PJ *defn, LP input, int *gridlist_count_p, PJ return PJD_ERR_FAILED_TO_LOAD_GRID; } - } - /* Interpolation a location within the grid */ - grid_x = (input.lam - ct->ll.lam) / ct->del.lam; - grid_y = (input.phi - ct->ll.phi) / ct->del.phi; - grid_ix = (int) floor(grid_x); - grid_iy = (int) floor(grid_y); - grid_x -= grid_ix; - grid_y -= grid_iy; - - grid_ix2 = grid_ix + 1; - if( grid_ix2 >= ct->lim.lam ) - grid_ix2 = ct->lim.lam - 1; - grid_iy2 = grid_iy + 1; - if( grid_iy2 >= ct->lim.phi ) - grid_iy2 = ct->lim.phi - 1; - - cvs = (float *) ct->cvs; - value = cvs[grid_ix + grid_iy * ct->lim.lam] - * (1.0-grid_x) * (1.0-grid_y) - + cvs[grid_ix2 + grid_iy * ct->lim.lam] - * (grid_x) * (1.0-grid_y) - + cvs[grid_ix + grid_iy2 * ct->lim.lam] - * (1.0-grid_x) * (grid_y) - + cvs[grid_ix2 + grid_iy2 * ct->lim.lam] - * (grid_x) * (grid_y); + /* Interpolation a location within the grid */ + grid_x = (input.lam - ct->ll.lam) / ct->del.lam; + grid_y = (input.phi - ct->ll.phi) / ct->del.phi; + grid_ix = (int) floor(grid_x); + grid_iy = (int) floor(grid_y); + grid_x -= grid_ix; + grid_y -= grid_iy; + + grid_ix2 = grid_ix + 1; + if( grid_ix2 >= ct->lim.lam ) + grid_ix2 = ct->lim.lam - 1; + grid_iy2 = grid_iy + 1; + if( grid_iy2 >= ct->lim.phi ) + grid_iy2 = ct->lim.phi - 1; + + cvs = (float *) ct->cvs; + value = cvs[grid_ix + grid_iy * ct->lim.lam] + * (1.0-grid_x) * (1.0-grid_y) + + cvs[grid_ix2 + grid_iy * ct->lim.lam] + * (grid_x) * (1.0-grid_y) + + cvs[grid_ix + grid_iy2 * ct->lim.lam] + * (1.0-grid_x) * (grid_y) + + cvs[grid_ix2 + grid_iy2 * ct->lim.lam] + * (grid_x) * (grid_y); + } /* nodata? */ /* GTX official nodata value if -88.88880f, but some grids also */ /* use other big values for nodata (e.g naptrans2008.gtx has */ -- cgit v1.2.3 From f41a5b70a928067bfa416786b319a51f025f1463 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Sat, 4 Nov 2017 15:51:16 +0100 Subject: Add Clifford J. Mugnier notes about LCCA from PROJ.4 mailing list --- src/PJ_lcca.c | 49 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/PJ_lcca.c b/src/PJ_lcca.c index 7d1355b9..cf1aa83f 100644 --- a/src/PJ_lcca.c +++ b/src/PJ_lcca.c @@ -1,5 +1,50 @@ -/* PROJ.4 Cartographic Projection System -*/ +/***************************************************************************** + + Lambert Conformal Conic Alternative + ----------------------------------- + + This is Gerald Evenden's 2003 implementation of an alternative + "almost" LCC, which has been in use historically, but which + should NOT be used for new projects - i.e: use this implementation + if you need interoperability with old data represented in this + projection, but not in any other case. + + The code was originally discussed on the PROJ.4 mailing list in + a thread archived over at + + http://lists.maptools.org/pipermail/proj/2003-March/000644.html + + It was discussed again in the thread starting at + + http://lists.maptools.org/pipermail/proj/2017-October/007828.html + and continuing at + http://lists.maptools.org/pipermail/proj/2017-November/007831.html + + which prompted Clifford J. Mugnier to add these clarifying notes: + + The French Army Truncated Cubic Lambert (partially conformal) Conic + projection is the Legal system for the projection in France between + the late 1800s and 1948 when the French Legislature changed the law + to recognize the fully conformal version. + + It was (might still be in one or two North African prior French + Colonies) used in North Africa in Algeria, Tunisia, & Morocco, as + well as in Syria during the Levant. + + Last time I have seen it used was about 30+ years ago in + Algeria when it was used to define Lease Block boundaries for + Petroleum Exploration & Production. + + (signed) + + Clifford J. Mugnier, c.p., c.m.s. + Chief of Geodesy + LSU Center for GeoInformatics + Dept. of Civil Engineering + LOUISIANA STATE UNIVERSITY + +*****************************************************************************/ + #define PJ_LIB__ #include #include -- cgit v1.2.3 From 98078be18bcb0d515362ecc8f122eeca0c3a4b26 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Sun, 5 Nov 2017 16:48:49 +0100 Subject: Pipeline cleanup (WIP) (#637) * Remove a number of debugging calls and memory management from the inner loop of the pipeline drivers * An attempt at handling inverted steps in a more straightforward way --- src/PJ_pipeline.c | 135 ++++++++-------------------------------------------- src/pj_internal.c | 15 ++++++ src/proj_4D_api.c | 1 - src/proj_internal.h | 2 + src/projects.h | 1 + 5 files changed, 38 insertions(+), 116 deletions(-) (limited to 'src') diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index b60105bf..73e15174 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -107,22 +107,17 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-20 PROJ_HEAD(pipeline, "Transformation pipeline manager"); /* Projection specific elements for the PJ object */ -#define PIPELINE_STACK_SIZE 100 struct pj_opaque { int reversible; int steps; - int depth; int verbose; - int *reverse_step; - int *omit_forward; - int *omit_inverse; char **argv; char **current_argv; - PJ_OBS stack[PIPELINE_STACK_SIZE]; PJ **pipeline; }; + static PJ_OBS pipeline_forward_obs (PJ_OBS, PJ *P); static PJ_OBS pipeline_reverse_obs (PJ_OBS, PJ *P); static XYZ pipeline_forward_3d (LPZ lpz, PJ *P); @@ -185,50 +180,23 @@ static PJ_OBS pipeline_forward_obs (PJ_OBS point, PJ *P) { first_step = 1; last_step = P->opaque->steps + 1; - for (i = first_step; i != last_step; i++) { - proj_log_trace (P, "In[%2.2d]: %20.15g %20.15g %20.15g - %20.20s", - i-first_step, point.coo.xyz.x, point.coo.xyz.y, point.coo.xyz.z, - P->opaque->pipeline[i]->descr - ); + for (i = first_step; i != last_step; i++) + point = proj_trans_obs (P->opaque->pipeline[i], 1, point); - if (P->opaque->omit_forward[i]) - continue; - if (P->opaque->reverse_step[i]) - point = proj_trans_obs (P->opaque->pipeline[i], PJ_INV, point); - else - point = proj_trans_obs (P->opaque->pipeline[i], PJ_FWD, point); - if (P->opaque->depth < PIPELINE_STACK_SIZE) - P->opaque->stack[P->opaque->depth++] = point; - } - proj_log_trace (P, "Out[ ]: %20.15g %20.15g %20.15g", point.coo.xyz.x, point.coo.xyz.y, point.coo.xyz.z); - - P->opaque->depth = 0; /* Clear the stack */ return point; } + static PJ_OBS pipeline_reverse_obs (PJ_OBS point, PJ *P) { int i, first_step, last_step; first_step = P->opaque->steps; last_step = 0; - for (i = first_step; i != last_step; i--) { - proj_log_trace (P, "In[%2.2d]: %20.15g %20.15g %20.15g - %.4f %.4f", - i - 1, point.coo.xyz.x, point.coo.xyz.y, point.coo.xyz.z, - P->opaque->pipeline[i]->a, P->opaque->pipeline[i]->rf - ); - if (P->opaque->omit_inverse[i]) - continue; - if (P->opaque->reverse_step[i]) - point = proj_trans_obs (P->opaque->pipeline[i], PJ_FWD, point); - else - point = proj_trans_obs (P->opaque->pipeline[i], PJ_INV, point); - if (P->opaque->depth < PIPELINE_STACK_SIZE) - P->opaque->stack[P->opaque->depth++] = point; - } - proj_log_trace (P, "Out[ ]: %20.15g %20.15g %20.15g", point.coo.xyz.x, point.coo.xyz.y, point.coo.xyz.z); - P->opaque->depth = 0; /* Clear the stack */ + for (i = first_step; i != last_step; i--) + point = proj_trans_obs (P->opaque->pipeline[i], -1, point); + return point; } @@ -279,9 +247,6 @@ static void *destructor (PJ *P, int errlev) { P->opaque->pipeline[i+1]->destructor (P->opaque->pipeline[i+1], errlev); pj_dealloc (P->opaque->pipeline); - pj_dealloc (P->opaque->reverse_step); - pj_dealloc (P->opaque->omit_forward); - pj_dealloc (P->opaque->omit_inverse); pj_dealloc (P->opaque->argv); pj_dealloc (P->opaque->current_argv); @@ -298,18 +263,6 @@ static PJ *pj_create_pipeline (PJ *P, size_t steps) { P->opaque->steps = (int)steps; - P->opaque->reverse_step = pj_calloc (steps + 2, sizeof(int)); - if (0==P->opaque->reverse_step) - return 0; - - P->opaque->omit_forward = pj_calloc (steps + 2, sizeof(int)); - if (0==P->opaque->omit_forward) - return 0; - - P->opaque->omit_inverse = pj_calloc (steps + 2, sizeof(int)); - if (0==P->opaque->omit_inverse) - return 0; - return P; } @@ -339,6 +292,7 @@ static char **argv_params (paralist *params, size_t argc) { } + PJ *PROJECTION(pipeline) { int i, nsteps = 0, argc; int i_pipeline = -1, i_first_step = -1, i_current_step; @@ -418,84 +372,35 @@ PJ *PROJECTION(pipeline) { for (j = i_pipeline + 1; 0 != strcmp ("step", argv[j]); j++) current_argv[current_argc++] = argv[j]; - /* Finally handle non-symmetric steps and inverted steps */ - for (j = 0; j < current_argc; j++) { - if (0==strcmp("omit_inv", current_argv[j])) { - P->opaque->omit_inverse[i+1] = 1; - P->opaque->omit_forward[i+1] = 0; - } - if (0==strcmp("omit_fwd", current_argv[j])) { - P->opaque->omit_inverse[i+1] = 0; - P->opaque->omit_forward[i+1] = 1; - } - if (0==strcmp("inv", current_argv[j])) - P->opaque->reverse_step[i+1] = 1; - } - proj_log_trace (P, "Pipeline: init - %s, %d", current_argv[0], current_argc); for (j = 1; j < current_argc; j++) proj_log_trace (P, " %s", current_argv[j]); next_step = pj_init_ctx (P->ctx, current_argc, current_argv); + proj_log_trace (P, "Pipeline: Step %d at %p", i, next_step); if (0==next_step) { proj_log_error (P, "Pipeline: Bad step definition: %s", current_argv[0]); return destructor (P, PJD_ERR_MALFORMED_PIPELINE); /* ERROR: bad pipeline def */ } + + /* Is this step inverted? */ + for (j = 0; j < current_argc; j++) + if (0==strcmp("inv", current_argv[j])) + next_step->inverted = 1; + P->opaque->pipeline[i+1] = next_step; + proj_log_trace (P, "Pipeline: step done"); } proj_log_trace (P, "Pipeline: %d steps built. Determining i/o characteristics", nsteps); /* Determine forward input (= reverse output) data type */ - - /* First locate the first forward-active pipeline step */ - for (i = 0; i < nsteps; i++) - if (0==P->opaque->omit_forward[i+1]) - break; - if (i==nsteps) { - proj_log_error (P, "Pipeline: No forward steps"); - return destructor (P, PJD_ERR_MALFORMED_PIPELINE); - } - - if (P->opaque->reverse_step[i + 1]) - P->left = P->opaque->pipeline[i + 1]->right; - else - P->left = P->opaque->pipeline[i + 1]->left; - - if (P->left==PJ_IO_UNITS_CLASSIC) { - if (P->opaque->reverse_step[i + 1]) - P->left = PJ_IO_UNITS_METERS; - else - P->left = PJ_IO_UNITS_RADIANS; - } + P->left = pj_left (P->opaque->pipeline[1]); /* Now, correspondingly determine forward output (= reverse input) data type */ - - /* First locate the last reverse-active pipeline step */ - for (i = nsteps - 1; i >= 0; i--) - if (0==P->opaque->omit_inverse[i+1]) - break; - if (i==-1) { - proj_log_error (P, "Pipeline: No reverse steps"); - return destructor (P, PJD_ERR_MALFORMED_PIPELINE); - } - - if (P->opaque->reverse_step[i + 1]) - P->right = P->opaque->pipeline[i + 1]->left; - else - P->right = P->opaque->pipeline[i + 1]->right; - - if (P->right==PJ_IO_UNITS_CLASSIC) { - if (P->opaque->reverse_step[i + 1]) - P->right = PJ_IO_UNITS_RADIANS; - else - P->right = PJ_IO_UNITS_METERS; - } - proj_log_trace (P, "Pipeline: Units - left: [%s], right: [%s]\n", - P->left ==PJ_IO_UNITS_RADIANS? "angular": "linear", - P->right==PJ_IO_UNITS_RADIANS? "angular": "linear"); + P->right = pj_right (P->opaque->pipeline[nsteps]); return P; } @@ -512,14 +417,14 @@ int pj_pipeline_selftest (void) { double dist; /* forward-reverse geo->utm->geo */ - P = proj_create (PJ_DEFAULT_CTX, "+proj=pipeline +zone=32 +step +proj=utm +ellps=GRS80 +step +proj=utm +ellps=GRS80 +inv"); + P = proj_create (PJ_DEFAULT_CTX, "+proj=pipeline +zone=32 +step +proj=utm +ellps=GRS80 +step +proj=utm +ellps=GRS80 +inv"); if (0==P) return 1000; /* zero initialize everything, then set (longitude, latitude, height) to (12, 55, 0) */ a = b = proj_obs_null; a.coo.lpz.lam = PJ_TORAD(12); a.coo.lpz.phi = PJ_TORAD(55); - a.coo.lpz.z = 0; + a.coo.lpz.z = 10; /* Forward projection */ b = proj_trans_obs (P, PJ_FWD, a); diff --git a/src/pj_internal.c b/src/pj_internal.c index 5eb98afb..19dd6409 100644 --- a/src/pj_internal.c +++ b/src/pj_internal.c @@ -66,13 +66,28 @@ PJ_OBS proj_obs (double x, double y, double z, double t) { +enum pj_io_units pj_left (PJ *P) { + enum pj_io_units u = P->inverted? P->right: P->left; + if (u==PJ_IO_UNITS_RADIANS) + return PJ_IO_UNITS_RADIANS; + return PJ_IO_UNITS_METERS; +} +enum pj_io_units pj_right (PJ *P) { + enum pj_io_units u = P->inverted? P->left: P->right; + if (u==PJ_IO_UNITS_RADIANS) + return PJ_IO_UNITS_RADIANS; + return PJ_IO_UNITS_METERS; +} /* Apply the transformation P to the coordinate coo */ PJ_OBS proj_trans_obs (PJ *P, PJ_DIRECTION direction, PJ_OBS obs) { if (0==P) return obs; + if (P->inverted) + direction = -direction; + switch (direction) { case PJ_FWD: return pj_fwdobs (obs, P); diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c index 5484b650..4b8fd854 100644 --- a/src/proj_4D_api.c +++ b/src/proj_4D_api.c @@ -45,7 +45,6 @@ PJ_COORD proj_coord (double x, double y, double z, double t) { } - /* 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; diff --git a/src/proj_internal.h b/src/proj_internal.h index ba542dea..36ff5767 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -64,6 +64,8 @@ typedef struct PJ_OBS PJ_OBS; #endif +enum pj_io_units pj_left (PJ *P); +enum pj_io_units pj_right (PJ *P); PJ_OBS proj_obs (double x, double y, double z, double t); PJ_OBS proj_trans_obs (PJ *P, PJ_DIRECTION direction, PJ_OBS obs); diff --git a/src/projects.h b/src/projects.h index 6ea0c914..a7763dd1 100644 --- a/src/projects.h +++ b/src/projects.h @@ -231,6 +231,7 @@ struct PJconsts { paralist *params; /* Parameter list */ struct geod_geodesic *geod; /* For geodesic computations */ struct pj_opaque *opaque; /* Projection specific parameters, Defined in PJ_*.c */ + int inverted; /* Tell high level API functions to swap inv/fwd */ /************************************************************************************* -- cgit v1.2.3 From 4446aa8fbce9d31ab1bf1f9a4138b3d76cf55e84 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Sun, 5 Nov 2017 16:51:04 +0100 Subject: Improve ISO 19000 alignment (#639) * Discern between conversions and transformations --- src/PJ_helmert.c | 2 +- src/projects.h | 22 +++++++++++++++++++--- 2 files changed, 20 insertions(+), 4 deletions(-) (limited to 'src') diff --git a/src/PJ_helmert.c b/src/PJ_helmert.c index c9c30401..f49bbe97 100644 --- a/src/PJ_helmert.c +++ b/src/PJ_helmert.c @@ -461,7 +461,7 @@ static PJ_OBS helmert_reverse_obs (PJ_OBS point, PJ *P) { #define ARCSEC_TO_RAD (DEG_TO_RAD / 3600.0) /***********************************************************************/ -PJ *PROJECTION(helmert) { +PJ *TRANSFORMATION(helmert, 0) { /***********************************************************************/ struct pj_opaque_helmert *Q = pj_calloc (1, sizeof (struct pj_opaque_helmert)); if (0==Q) diff --git a/src/projects.h b/src/projects.h index a7763dd1..0631924c 100644 --- a/src/projects.h +++ b/src/projects.h @@ -328,6 +328,7 @@ struct PJconsts { int geoc; /* Geocentric latitude flag */ int is_latlong; /* proj=latlong ... not really a projection at all */ int is_geocent; /* proj=geocent ... not really a projection at all */ + int need_ellps; /* 0 for operations that are purely cartesian */ enum pj_io_units left; /* Flags for input/output coordinate types */ enum pj_io_units right; @@ -584,12 +585,14 @@ extern struct PJ_PRIME_MERIDIANS pj_prime_meridians[]; #ifdef PJ_LIB__ #define PROJ_HEAD(id, name) static const char des_##id [] = name - -#define PROJECTION(name) \ +#define OPERATION(name, NEED_ELLPS) \ + \ pj_projection_specific_setup_##name (PJ *P); \ -C_NAMESPACE_VAR const char * const pj_s_##name = des_##name; \ C_NAMESPACE PJ *pj_##name (PJ *P); \ int pj_ ## name ## _selftest (void); \ + \ +C_NAMESPACE_VAR const char * const pj_s_##name = des_##name; \ + \ C_NAMESPACE PJ *pj_##name (PJ *P) { \ if (P) \ return pj_projection_specific_setup_##name (P); \ @@ -598,14 +601,27 @@ C_NAMESPACE PJ *pj_##name (PJ *P) { \ return 0; \ P->destructor = pj_default_destructor; \ P->descr = des_##name; \ + P->need_ellps = NEED_ELLPS; \ P->left = PJ_IO_UNITS_RADIANS; \ P->right = PJ_IO_UNITS_CLASSIC; \ return P; \ } \ + \ PJ *pj_projection_specific_setup_##name (PJ *P) + +/* In ISO19000 lingo, an operation is either a conversion or a transformation */ +#define CONVERSION(name, need_ellps) OPERATION (name, need_ellps) +#define TRANSFORMATION(name, need_ellps) OPERATION (name, need_ellps) + +/* In PROJ.4 a projection is a conversion taking angular input and giving scaled linear output */ +#define PROJECTION(name) CONVERSION (name, 1) + #endif /* def PJ_LIB__ */ + + + int pj_generic_selftest ( char *e_args, char *s_args, -- cgit v1.2.3 From 9877a5f096fb15e5cae1f28334c826a7fa16eee7 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Mon, 6 Nov 2017 08:13:06 +0100 Subject: Remove CVS echo in PJ_sch.c --- src/PJ_sch.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src') diff --git a/src/PJ_sch.c b/src/PJ_sch.c index dc8cc770..cd4aa95e 100644 --- a/src/PJ_sch.c +++ b/src/PJ_sch.c @@ -1,6 +1,4 @@ /****************************************************************************** - * $Id$ - * * Project: SCH Coordinate system * Purpose: Implementation of SCH Coordinate system * References : -- cgit v1.2.3 From 4a4a349689c80e8e608b158a209c88267764f92d Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Mon, 6 Nov 2017 10:02:05 +0100 Subject: Eliminate the last traces of PJ_OBS (#643) PJ_OBS eliminated, API adjusted to reflect that we now have only one 4D data type. 2 new API functions added to determine output types of a PJ. --- src/PJ_axisswap.c | 37 +++++------ src/PJ_cart.c | 171 +++++++++++++++++++++++---------------------------- src/PJ_deformation.c | 28 ++++----- src/PJ_helmert.c | 42 ++++++------- src/PJ_hgridshift.c | 36 +++++------ src/PJ_horner.c | 64 +++++++++---------- src/PJ_latlong.c | 20 +++--- src/PJ_molodensky.c | 48 +++++++-------- src/PJ_ob_tran.c | 10 +-- src/PJ_pipeline.c | 126 ++++++++++++++++++------------------- src/PJ_unitconvert.c | 58 ++++++++--------- src/PJ_vgridshift.c | 42 ++++++------- src/cct.c | 22 +++---- src/gie.c | 2 +- src/pj_internal.c | 121 +++--------------------------------- src/proj.def | 80 ++++++++++++------------ src/proj.h | 12 +++- src/proj_4D_api.c | 77 +++++++++++++---------- src/proj_internal.h | 27 +------- src/projects.h | 13 ++-- 20 files changed, 450 insertions(+), 586 deletions(-) (limited to 'src') diff --git a/src/PJ_axisswap.c b/src/PJ_axisswap.c index 42c0d779..84b48afe 100644 --- a/src/PJ_axisswap.c +++ b/src/PJ_axisswap.c @@ -127,36 +127,31 @@ static LPZ reverse_3d(XYZ xyz, PJ *P) { } -static PJ_OBS forward_obs(PJ_OBS obs, PJ *P) { +static PJ_COORD forward_4d(PJ_COORD coo, PJ *P) { struct pj_opaque *Q = (struct pj_opaque *) P->opaque; unsigned int i; - PJ_COORD in, out; + PJ_COORD out; out = proj_coord_error(); - in = obs.coo; for (i=0; i<4; i++) - out.v[i] = in.v[Q->axis[i]] * Q->sign[i]; + out.v[i] = coo.v[Q->axis[i]] * Q->sign[i]; - obs.coo = out; - return obs; + return out; } -static PJ_OBS reverse_obs(PJ_OBS obs, PJ *P) { +static PJ_COORD reverse_4d(PJ_COORD coo, PJ *P) { struct pj_opaque *Q = (struct pj_opaque *) P->opaque; unsigned int i; - PJ_COORD in, out; + PJ_COORD out; out = proj_coord_error(); - in = obs.coo; - for (i=0; i<4; i++) { - out.v[Q->axis[i]] = in.v[i] * Q->sign[i]; - } + for (i=0; i<4; i++) + out.v[Q->axis[i]] = coo.v[i] * Q->sign[i]; - obs.coo = out; - return obs; + return out; } @@ -182,7 +177,7 @@ PJ *PROJECTION(axisswap) { for (i=0; i<4; i++) Q->axis[i] = i+4; - /* check that all characteds are valid */ + /* check that all characters are valid */ for (i=0; iaxis[n] = abs(atoi(s))-1; Q->sign[n++] = sign(atoi(s)); - while( *s != '\0' && *s != ',' ) + while ( *s != '\0' && *s != ',' ) s++; - if( *s == ',' ) + if ( *s == ',' ) s++; } @@ -212,8 +207,8 @@ PJ *PROJECTION(axisswap) { /* only map fwd/inv functions that are possible with the given axis setup */ if (n == 4) { - P->fwdobs = forward_obs; - P->invobs = reverse_obs; + P->fwd4d = forward_4d; + P->inv4d = reverse_4d; } if (n == 3 && Q->axis[0] < 3 && Q->axis[1] < 3 && Q->axis[2] < 3) { P->fwd3d = forward_3d; @@ -224,7 +219,7 @@ PJ *PROJECTION(axisswap) { P->inv = reverse_2d; } - if (P->fwdobs == NULL && P->fwd3d == NULL && P->fwd == NULL) { + if (P->fwd4d == NULL && P->fwd3d == NULL && P->fwd == NULL) { proj_log_error(P, "swapaxis: bad axis order"); return pj_default_destructor(P, PJD_ERR_AXIS); } diff --git a/src/PJ_cart.c b/src/PJ_cart.c index 67154ab3..f5d5a062 100644 --- a/src/PJ_cart.c +++ b/src/PJ_cart.c @@ -227,7 +227,7 @@ int pj_cart_selftest (void) {return 0;} int pj_cart_selftest (void) { PJ_CONTEXT *ctx; PJ *P; - PJ_OBS a, b, obs[2]; + PJ_COORD a, b, obs[2]; PJ_COORD coord[2]; PJ_INFO info; @@ -265,24 +265,24 @@ int pj_cart_selftest (void) { return 2; /* zero initialize everything, then set (longitude, latitude) to (12, 55) */ - a = proj_obs_null; - /* a.coo.lp: The coordinate part of a, interpreted as a classic LP pair */ - a.coo.lp.lam = PJ_TORAD(12); - a.coo.lp.phi = PJ_TORAD(55); + a = proj_coord (0,0,0,0); + /* a.lp: The coordinate part of a, interpreted as a classic LP pair */ + a.lp.lam = PJ_TORAD(12); + a.lp.phi = PJ_TORAD(55); /* Forward projection */ - b = proj_trans_obs (P, PJ_FWD, a); + b = proj_trans (P, PJ_FWD, a); /* Inverse projection */ - a = proj_trans_obs (P, PJ_INV, b); + a = proj_trans (P, PJ_INV, b); /* Null projection */ - a = proj_trans_obs (P, PJ_IDENT, a); + a = proj_trans (P, PJ_IDENT, a); /* Forward again, to get two linear items for comparison */ - a = proj_trans_obs (P, PJ_FWD, a); + a = proj_trans (P, PJ_FWD, a); - dist = proj_xy_dist (a.coo.xy, b.coo.xy); + dist = proj_xy_dist (a.xy, b.xy); if (dist > 2e-9) return 3; @@ -290,8 +290,8 @@ int pj_cart_selftest (void) { proj_errno_set (P, 0); /* Invalid projection */ - a = proj_trans_obs (P, 42, a); - if (a.coo.lpz.lam!=HUGE_VAL) + a = proj_trans (P, 42, a); + if (a.lpz.lam!=HUGE_VAL) return 4; err = proj_errno (P); if (0==err) @@ -309,45 +309,45 @@ int pj_cart_selftest (void) { return 6; /* zero initialize everything, then set (longitude, latitude, height) to (12, 55, 100) */ - a = b = proj_obs_null; - a.coo.lpz.lam = PJ_TORAD(12); - a.coo.lpz.phi = PJ_TORAD(55); - a.coo.lpz.z = 100; + a = b = proj_coord (0,0,0,0); + a.lpz.lam = PJ_TORAD(12); + a.lpz.phi = PJ_TORAD(55); + a.lpz.z = 100; /* Forward projection: 3D-Cartesian-to-Ellipsoidal */ - b = proj_trans_obs (P, PJ_FWD, a); + b = proj_trans (P, PJ_FWD, a); /* Check roundtrip precision for 10000 iterations each way */ - dist = proj_roundtrip (P, PJ_FWD, 10000, a.coo); - dist = proj_roundtrip (P, PJ_INV, 10000, b.coo); + dist = proj_roundtrip (P, PJ_FWD, 10000, a); + dist = proj_roundtrip (P, PJ_INV, 10000, b); if (dist > 2e-9) return 7; /* Test at the North Pole */ - a = b = proj_obs_null; - a.coo.lpz.lam = PJ_TORAD(0); - a.coo.lpz.phi = PJ_TORAD(90); - a.coo.lpz.z = 100; + a = b = proj_coord (0,0,0,0); + a.lpz.lam = PJ_TORAD(0); + a.lpz.phi = PJ_TORAD(90); + a.lpz.z = 100; /* Forward projection: Ellipsoidal-to-3D-Cartesian */ - dist = proj_roundtrip (P, PJ_FWD, 1, a.coo); + dist = proj_roundtrip (P, PJ_FWD, 1, a); if (dist > 1e-12) return 8; /* Test at the South Pole */ - a = b = proj_obs_null; - a.coo.lpz.lam = PJ_TORAD(0); - a.coo.lpz.phi = PJ_TORAD(-90); - a.coo.lpz.z = 100; + a = b = proj_coord (0,0,0,0); + a.lpz.lam = PJ_TORAD(0); + a.lpz.phi = PJ_TORAD(-90); + a.lpz.z = 100; /* Forward projection: Ellipsoidal-to-3D-Cartesian */ - dist = proj_roundtrip (P, PJ_FWD, 1, a.coo); + dist = proj_roundtrip (P, PJ_FWD, 1, a); if (dist > 1e-12) return 9; /* Inverse projection: 3D-Cartesian-to-Ellipsoidal */ - b = proj_trans_obs (P, PJ_INV, b); + b = proj_trans (P, PJ_INV, b); /* Move p to another context */ ctx = proj_context_create (); @@ -356,7 +356,7 @@ int pj_cart_selftest (void) { proj_context_set (P, ctx); if (ctx != P->ctx) return 11; - b = proj_trans_obs (P, PJ_FWD, b); + b = proj_trans (P, PJ_FWD, b); /* Move it back to the default context */ proj_context_set (P, 0); @@ -365,93 +365,78 @@ int pj_cart_selftest (void) { proj_context_destroy (ctx); /* We go on with the work - now back on the default context */ - b = proj_trans_obs (P, PJ_INV, b); + b = proj_trans (P, PJ_INV, b); proj_destroy (P); - /* Testing the proj_transform nightmare */ + /* Testing proj_trans_generic () */ /* An utm projection on the GRS80 ellipsoid */ P = proj_create (PJ_DEFAULT_CTX, "+proj=utm +zone=32 +ellps=GRS80"); if (0==P) return 13; - obs[0].coo = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); - obs[1].coo = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); - sz = sizeof (PJ_OBS); + obs[0] = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); + obs[1] = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); + sz = sizeof (PJ_COORD); /* Forward projection */ - a = proj_trans_obs (P, PJ_FWD, obs[0]); - b = proj_trans_obs (P, PJ_FWD, obs[1]); + a = proj_trans (P, PJ_FWD, obs[0]); + b = proj_trans (P, PJ_FWD, obs[1]); - n = proj_transform ( + n = proj_trans_generic ( P, PJ_FWD, - &(obs[0].coo.lpz.lam), sz, 2, - &(obs[0].coo.lpz.phi), sz, 2, - &(obs[0].coo.lpz.z), sz, 2, + &(obs[0].lpz.lam), sz, 2, + &(obs[0].lpz.phi), sz, 2, + &(obs[0].lpz.z), sz, 2, 0, sz, 0 ); if (2!=n) return 14; - if (a.coo.lpz.lam != obs[0].coo.lpz.lam) return 15; - if (a.coo.lpz.phi != obs[0].coo.lpz.phi) return 16; - if (a.coo.lpz.z != obs[0].coo.lpz.z) return 17; - if (b.coo.lpz.lam != obs[1].coo.lpz.lam) return 18; - if (b.coo.lpz.phi != obs[1].coo.lpz.phi) return 19; - if (b.coo.lpz.z != obs[1].coo.lpz.z) return 20; + if (a.lpz.lam != obs[0].lpz.lam) return 15; + if (a.lpz.phi != obs[0].lpz.phi) return 16; + if (a.lpz.z != obs[0].lpz.z) return 17; + if (b.lpz.lam != obs[1].lpz.lam) return 18; + if (b.lpz.phi != obs[1].lpz.phi) return 19; + if (b.lpz.z != obs[1].lpz.z) return 20; /* now test the case of constant z */ - obs[0].coo = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); - obs[1].coo = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); + obs[0] = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); + obs[1] = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); h = 27; t = 33; - n = proj_transform ( + n = proj_trans_generic ( P, PJ_FWD, - &(obs[0].coo.lpz.lam), sz, 2, - &(obs[0].coo.lpz.phi), sz, 2, + &(obs[0].lpz.lam), sz, 2, + &(obs[0].lpz.phi), sz, 2, &h, 0, 1, &t, 0, 1 ); if (2!=n) return 21; - if (a.coo.lpz.lam != obs[0].coo.lpz.lam) return 22; - if (a.coo.lpz.phi != obs[0].coo.lpz.phi) return 23; - if (45 != obs[0].coo.lpz.z) return 24; - if (b.coo.lpz.lam != obs[1].coo.lpz.lam) return 25; - if (b.coo.lpz.phi != obs[1].coo.lpz.phi) return 26; - if (50 != obs[1].coo.lpz.z) return 27; /* NOTE: unchanged */ + if (a.lpz.lam != obs[0].lpz.lam) return 22; + if (a.lpz.phi != obs[0].lpz.phi) return 23; + if (45 != obs[0].lpz.z) return 24; + if (b.lpz.lam != obs[1].lpz.lam) return 25; + if (b.lpz.phi != obs[1].lpz.phi) return 26; + if (50 != obs[1].lpz.z) return 27; /* NOTE: unchanged */ if (50==h) return 28; - /* test proj_transform_obs() */ - - obs[0].coo = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); - obs[1].coo = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); - - if (proj_transform_coord(P, PJ_FWD, 2, (PJ_COORD *) obs)) - return 30; - - if (a.coo.lpz.lam != obs[0].coo.lpz.lam) return 31; - if (a.coo.lpz.phi != obs[0].coo.lpz.phi) return 32; - if (a.coo.lpz.z != obs[0].coo.lpz.z) return 33; - if (b.coo.lpz.lam != obs[1].coo.lpz.lam) return 34; - if (b.coo.lpz.phi != obs[1].coo.lpz.phi) return 35; - if (b.coo.lpz.z != obs[1].coo.lpz.z) return 36; - - /* test proj_transform_coord() */ + /* test proj_trans_array () */ coord[0] = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); coord[1] = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); - if (proj_transform_coord(P, PJ_FWD, 2, coord)) + if (proj_trans_array (P, PJ_FWD, 2, coord)) return 40; - if (a.coo.lpz.lam != coord[0].lpz.lam) return 41; - if (a.coo.lpz.phi != coord[0].lpz.phi) return 42; - if (a.coo.lpz.z != coord[0].lpz.z) return 43; - if (b.coo.lpz.lam != coord[1].lpz.lam) return 44; - if (b.coo.lpz.phi != coord[1].lpz.phi) return 45; - if (b.coo.lpz.z != coord[1].lpz.z) return 46; + if (a.lpz.lam != coord[0].lpz.lam) return 41; + if (a.lpz.phi != coord[0].lpz.phi) return 42; + if (a.lpz.z != coord[0].lpz.z) return 43; + if (b.lpz.lam != coord[1].lpz.lam) return 44; + if (b.lpz.phi != coord[1].lpz.phi) return 45; + if (b.lpz.z != coord[1].lpz.z) return 46; - /* Clean up after transform* tests */ + /* Clean up after proj_trans_* tests */ proj_destroy (P); /* test proj_create_crs_to_crs() */ @@ -459,12 +444,12 @@ int pj_cart_selftest (void) { if (P==0) return 50; - a.coo.xy.x = 700000.0; - a.coo.xy.y = 6000000.0; - b.coo.xy.x = 307788.8761171057; - b.coo.xy.y = 5999669.3036037628; + a.xy.x = 700000.0; + a.xy.y = 6000000.0; + b.xy.x = 307788.8761171057; + b.xy.y = 5999669.3036037628; - a = proj_trans_obs(P, PJ_FWD, a); + a = proj_trans(P, PJ_FWD, a); if (dist > 1e-7) return 51; proj_destroy(P); @@ -539,11 +524,11 @@ int pj_cart_selftest (void) { /* test proj_derivatives_retrieve() and proj_factors_retrieve() */ P = proj_create(PJ_DEFAULT_CTX, "+proj=merc"); - a = proj_obs_null; - a.coo.lp.lam = PJ_TORAD(12); - a.coo.lp.phi = PJ_TORAD(55); + a = proj_coord (0,0,0,0); + a.lp.lam = PJ_TORAD(12); + a.lp.phi = PJ_TORAD(55); - derivs = proj_derivatives(P, a.coo.lp); + derivs = proj_derivatives(P, a.lp); if (proj_errno(P)) return 80; /* derivs not created correctly */ @@ -553,7 +538,7 @@ int pj_cart_selftest (void) { if ( fabs(derivs.y_p - 1.73959) > 1e-5 ) return 84; - factors = proj_factors(P, a.coo.lp); + factors = proj_factors(P, a.lp); if (proj_errno(P)) return 85; /* factors not created correctly */ diff --git a/src/PJ_deformation.c b/src/PJ_deformation.c index 05858900..74862efc 100644 --- a/src/PJ_deformation.c +++ b/src/PJ_deformation.c @@ -139,26 +139,26 @@ static XYZ forward_3d(LPZ lpz, PJ *P) { } -static PJ_OBS forward_obs(PJ_OBS in, PJ *P) { +static PJ_COORD forward_4d(PJ_COORD in, PJ *P) { struct pj_opaque *Q = (struct pj_opaque *) P->opaque; double dt; XYZ shift; - PJ_OBS out = in; + PJ_COORD out = in; if (Q->t_obs != HUGE_VAL) { dt = Q->t_obs - Q->t_epoch; } else { - dt = in.coo.xyzt.t - Q->t_epoch; + dt = in.xyzt.t - Q->t_epoch; } if (Q->has_xy_grids) { - shift = get_xygrid_shift(P, in.coo.xyz); - out.coo.xyz.x += dt * shift.x; - out.coo.xyz.y += dt * shift.y; + shift = get_xygrid_shift(P, in.xyz); + out.xyz.x += dt * shift.x; + out.xyz.y += dt * shift.y; } if (Q->has_z_grids) - out.coo.xyz.z += dt * get_zgrid_shift(P, in.coo.xyz); + out.xyz.z += dt * get_zgrid_shift(P, in.xyz); return out; } @@ -188,22 +188,22 @@ static LPZ reverse_3d(XYZ in, PJ *P) { return out.lpz; } -static PJ_OBS reverse_obs(PJ_OBS in, PJ *P) { +static PJ_COORD reverse_4d(PJ_COORD in, PJ *P) { struct pj_opaque *Q = (struct pj_opaque *) P->opaque; - PJ_OBS out = in; + PJ_COORD out = in; double dt; if (Q->t_obs != HUGE_VAL) { dt = Q->t_epoch - Q->t_obs; } else { - dt = Q->t_epoch - in.coo.xyzt.t; + dt = Q->t_epoch - in.xyzt.t; } if (Q->has_xy_grids) - out.coo.xyz = reverse_hshift(P, in.coo.xyz, dt); + out.xyz = reverse_hshift(P, in.xyz, dt); if (Q->has_z_grids) - out.coo.xyz.z = in.coo.xyz.z + dt * get_zgrid_shift(P, in.coo.xyz); + out.xyz.z = in.xyz.z + dt * get_zgrid_shift(P, in.xyz); return out; } @@ -274,8 +274,8 @@ PJ *PROJECTION(deformation) { return destructor(P, PJD_ERR_MISSING_ARGS); } - P->fwdobs = forward_obs; - P->invobs = reverse_obs; + P->fwd4d = forward_4d; + P->inv4d = reverse_4d; P->fwd3d = forward_3d; P->inv3d = reverse_3d; P->fwd = 0; diff --git a/src/PJ_helmert.c b/src/PJ_helmert.c index f49bbe97..39746aaa 100644 --- a/src/PJ_helmert.c +++ b/src/PJ_helmert.c @@ -423,35 +423,35 @@ static LPZ helmert_reverse_3d (XYZ xyz, PJ *P) { } -static PJ_OBS helmert_forward_obs (PJ_OBS point, PJ *P) { +static PJ_COORD helmert_forward_4d (PJ_COORD point, PJ *P) { struct pj_opaque_helmert *Q = (struct pj_opaque_helmert *) P->opaque; /* We only need to rebuild the rotation matrix if the * observation time is different from the last call */ - if (point.coo.xyzt.t != Q->t_obs) { - Q->t_obs = point.coo.xyzt.t; + if (point.xyzt.t != Q->t_obs) { + Q->t_obs = point.xyzt.t; update_parameters(P); build_rot_matrix(P); } - point.coo.xyz = helmert_forward_3d (point.coo.lpz, P); + point.xyz = helmert_forward_3d (point.lpz, P); return point; } -static PJ_OBS helmert_reverse_obs (PJ_OBS point, PJ *P) { +static PJ_COORD helmert_reverse_4d (PJ_COORD point, PJ *P) { struct pj_opaque_helmert *Q = (struct pj_opaque_helmert *) P->opaque; /* We only need to rebuild the rotation matrix if the * observation time is different from the last call */ - if (point.coo.xyzt.t != Q->t_obs) { - Q->t_obs = point.coo.xyzt.t; + if (point.xyzt.t != Q->t_obs) { + Q->t_obs = point.xyzt.t; update_parameters(P); build_rot_matrix(P); } - point.coo.lpz = helmert_reverse_3d (point.coo.xyz, P); + point.lpz = helmert_reverse_3d (point.xyz, P); return point; } @@ -468,8 +468,8 @@ PJ *TRANSFORMATION(helmert, 0) { return pj_default_destructor (P, ENOMEM); P->opaque = (void *) Q; - P->fwdobs = helmert_forward_obs; - P->invobs = helmert_reverse_obs; + P->fwd4d = helmert_forward_4d; + P->inv4d = helmert_reverse_4d; P->fwd3d = helmert_forward_3d; P->inv3d = helmert_reverse_3d; P->fwd = helmert_forward; @@ -671,8 +671,8 @@ int pj_helmert_selftest (void) { matrix is updated when necessary. Test coordinates from GNSStrans. */ XYZ expect4a = {3370658.18890, 711877.42370, 5349787.12430}; XYZ expect4b = {3370658.18087, 711877.42750, 5349787.12648}; - PJ_OBS in4 = {{{3370658.378, 711877.314, 5349787.086, 2017.0}}}; - PJ_OBS out; + PJ_COORD in4 = {{3370658.378, 711877.314, 5349787.086, 2017.0}}; + PJ_COORD out; PJ *helmert = proj_create( 0, @@ -703,20 +703,20 @@ int pj_helmert_selftest (void) { ret = test (args5, in5, expect5, 0.001); if (ret) return ret + 40; /* Run test 4 */ - out = proj_trans_obs (helmert, PJ_FWD, in4); - if (proj_xyz_dist (out.coo.xyz, expect4a) > 1e-4) { + out = proj_trans (helmert, PJ_FWD, in4); + if (proj_xyz_dist (out.xyz, expect4a) > 1e-4) { proj_log_error(helmert, "Tolerance of test 4a not met!"); - proj_log_error(helmert, " In: %10.10f, %10.10f, %10.10f", in4.coo.xyz.x, in4.coo.xyz.y, in4.coo.xyz.z); - proj_log_error(helmert, " Out: %10.10f, %10.10f, %10.10f", out.coo.xyz.x, out.coo.xyz.y, out.coo.xyz.z); + proj_log_error(helmert, " In: %10.10f, %10.10f, %10.10f", in4.xyz.x, in4.xyz.y, in4.xyz.z); + proj_log_error(helmert, " Out: %10.10f, %10.10f, %10.10f", out.xyz.x, out.xyz.y, out.xyz.z); return 31; } - in4.coo.xyzt.t = 2018.0; - out = proj_trans_obs (helmert, PJ_FWD, in4); - if (proj_xyz_dist (out.coo.xyz, expect4b) > 1e-4) { + in4.xyzt.t = 2018.0; + out = proj_trans (helmert, PJ_FWD, in4); + if (proj_xyz_dist (out.xyz, expect4b) > 1e-4) { proj_log_error(helmert, "Tolerance of test 4b not met!"); - proj_log_error(helmert, " In: %10.10f, %10.10f, %10.10f", in4.coo.xyz.x, in4.coo.xyz.y, in4.coo.xyz.z); - proj_log_error(helmert, " Out: %10.10f, %10.10f, %10.10f", out.coo.xyz.x, out.coo.xyz.y, out.coo.xyz.z); + proj_log_error(helmert, " In: %10.10f, %10.10f, %10.10f", in4.xyz.x, in4.xyz.y, in4.xyz.z); + proj_log_error(helmert, " Out: %10.10f, %10.10f, %10.10f", out.xyz.x, out.xyz.y, out.xyz.z); return 32; } diff --git a/src/PJ_hgridshift.c b/src/PJ_hgridshift.c index 659039ab..83680a45 100644 --- a/src/PJ_hgridshift.c +++ b/src/PJ_hgridshift.c @@ -32,25 +32,23 @@ static LPZ reverse_3d(XYZ xyz, PJ *P) { } -static PJ_OBS forward_obs(PJ_OBS obs, PJ *P) { - PJ_OBS point; - point.coo.xyz = forward_3d (obs.coo.lpz, P); - return point; +static PJ_COORD forward_4d (PJ_COORD obs, PJ *P) { + obs.xyz = forward_3d (obs.lpz, P); + return obs; } -static PJ_OBS reverse_obs(PJ_OBS obs, PJ *P) { - PJ_OBS point; - point.coo.lpz = reverse_3d (obs.coo.xyz, P); - return point; +static PJ_COORD reverse_4d (PJ_COORD obs, PJ *P) { + obs.lpz = reverse_3d (obs.xyz, P); + return obs; } PJ *PROJECTION(hgridshift) { - P->fwdobs = forward_obs; - P->invobs = reverse_obs; + P->fwd4d = forward_4d; + P->inv4d = reverse_4d; P->fwd3d = forward_3d; P->inv3d = reverse_3d; P->fwd = 0; @@ -82,7 +80,7 @@ int pj_hgridshift_selftest (void) {return 0;} #else int pj_hgridshift_selftest (void) { PJ *P; - PJ_OBS expect, a, b; + PJ_COORD expect, a, b; double dist; /* fail on purpose: +grids parameter is mandatory*/ @@ -104,20 +102,20 @@ int pj_hgridshift_selftest (void) { if (0==P) return 10; - a = proj_obs_null; - a.coo.lpz.lam = PJ_TORAD(173); - a.coo.lpz.phi = PJ_TORAD(-45); + a = proj_coord (0,0,0,0); + a.lpz.lam = PJ_TORAD(173); + a.lpz.phi = PJ_TORAD(-45); - dist = proj_roundtrip (P, PJ_FWD, 1, a.coo); + dist = proj_roundtrip (P, PJ_FWD, 1, a); if (dist > 0.00000001) { printf("dist: %f\n",dist); return 1; } - expect.coo.lpz.lam = PJ_TORAD(172.999892181021551); - expect.coo.lpz.phi = PJ_TORAD(-45.001620431954613); - b = proj_trans_obs(P, PJ_FWD, a); - if (proj_xy_dist(expect.coo.xy, b.coo.xy) > 1e-4) + expect.lpz.lam = PJ_TORAD(172.999892181021551); + expect.lpz.phi = PJ_TORAD(-45.001620431954613); + b = proj_trans(P, PJ_FWD, a); + if (proj_xy_dist(expect.xy, b.xy) > 1e-4) return 2; proj_destroy(P); diff --git a/src/PJ_horner.c b/src/PJ_horner.c index a9a2c922..c28e3907 100644 --- a/src/PJ_horner.c +++ b/src/PJ_horner.c @@ -287,13 +287,13 @@ summing the tiny high order elements first. -static PJ_OBS horner_forward_obs (PJ_OBS point, PJ *P) { - point.coo.uv = horner ((HORNER *) P->opaque, 1, point.coo.uv); +static PJ_COORD horner_forward_4d (PJ_COORD point, PJ *P) { + point.uv = horner ((HORNER *) P->opaque, 1, point.uv); return point; } -static PJ_OBS horner_reverse_obs (PJ_OBS point, PJ *P) { - point.coo.uv = horner ((HORNER *) P->opaque, -1, point.coo.uv); +static PJ_COORD horner_reverse_4d (PJ_COORD point, PJ *P) { + point.uv = horner ((HORNER *) P->opaque, -1, point.uv); return point; } @@ -369,13 +369,13 @@ polynomial evaluation engine. -static PJ_OBS complex_horner_forward_obs (PJ_OBS point, PJ *P) { - point.coo.uv = complex_horner ((HORNER *) P->opaque, PJ_FWD, point.coo.uv); +static PJ_COORD complex_horner_forward_4d (PJ_COORD point, PJ *P) { + point.uv = complex_horner ((HORNER *) P->opaque, PJ_FWD, point.uv); return point; } -static PJ_OBS complex_horner_reverse_obs (PJ_OBS point, PJ *P) { - point.coo.uv = complex_horner ((HORNER *) P->opaque, PJ_INV, point.coo.uv); +static PJ_COORD complex_horner_reverse_4d (PJ_COORD point, PJ *P) { + point.uv = complex_horner ((HORNER *) P->opaque, PJ_INV, point.uv); return point; } @@ -429,13 +429,13 @@ PJ *PROJECTION(horner) { /*********************************************************************/ int degree = 0, n, complex_horner = 0; HORNER *Q; - P->fwdobs = horner_forward_obs; - P->invobs = horner_reverse_obs; - P->fwd3d = 0; - P->inv3d = 0; - P->fwd = 0; - P->inv = 0; - P->left = P->right = PJ_IO_UNITS_METERS; + P->fwd4d = horner_forward_4d; + P->inv4d = horner_reverse_4d; + P->fwd3d = 0; + P->inv3d = 0; + P->fwd = 0; + P->inv = 0; + P->left = P->right = PJ_IO_UNITS_METERS; P->destructor = horner_freeup; /* Polynomial degree specified? */ @@ -460,8 +460,8 @@ PJ *PROJECTION(horner) { return horner_freeup (P, PJD_ERR_MISSING_ARGS); if (0==parse_coefs (P, Q->inv_c, "inv_c", n)) return horner_freeup (P, PJD_ERR_MISSING_ARGS); - P->fwdobs = complex_horner_forward_obs; - P->invobs = complex_horner_reverse_obs; + P->fwd4d = complex_horner_forward_4d; + P->inv4d = complex_horner_reverse_4d; } else { @@ -518,7 +518,7 @@ char sb_utm32[] = { int pj_horner_selftest (void) { PJ *P; - PJ_OBS a, b, c; + PJ_COORD a, b, c; double dist; /* Real polynonia relating the technical coordinate system TC32 to "System 45 Bornholm" */ @@ -526,12 +526,12 @@ int pj_horner_selftest (void) { if (0==P) return 10; - a = b = proj_obs_null; - a.coo.uv.v = 6125305.4245; - a.coo.uv.u = 878354.8539; + a = b = proj_coord (0,0,0,0); + a.uv.v = 6125305.4245; + a.uv.u = 878354.8539; /* Check roundtrip precision for 1 iteration each way, starting in forward direction */ - dist = proj_roundtrip (P, PJ_FWD, 1, a.coo); + dist = proj_roundtrip (P, PJ_FWD, 1, a); if (dist > 0.01) return 1; @@ -541,26 +541,26 @@ int pj_horner_selftest (void) { return 11; /* Test value: utm32_ed50(620000, 6130000) = sb_ed50(495136.8544, 6130821.2945) */ - a = b = c = proj_obs_null; - a.coo.uv.v = 6130821.2945; - a.coo.uv.u = 495136.8544; - c.coo.uv.v = 6130000.0000; - c.coo.uv.u = 620000.0000; + a = b = c = proj_coord (0,0,0,0); + a.uv.v = 6130821.2945; + a.uv.u = 495136.8544; + c.uv.v = 6130000.0000; + c.uv.u = 620000.0000; /* Forward projection */ - b = proj_trans_obs (P, PJ_FWD, a); - dist = proj_xy_dist (b.coo.xy, c.coo.xy); + b = proj_trans (P, PJ_FWD, a); + dist = proj_xy_dist (b.xy, c.xy); if (dist > 0.001) return 2; /* Inverse projection */ - b = proj_trans_obs (P, PJ_INV, c); - dist = proj_xy_dist (b.coo.xy, a.coo.xy); + b = proj_trans (P, PJ_INV, c); + dist = proj_xy_dist (b.xy, a.xy); if (dist > 0.001) return 3; /* Check roundtrip precision for 1 iteration each way */ - dist = proj_roundtrip (P, PJ_FWD, 1, a.coo); + dist = proj_roundtrip (P, PJ_FWD, 1, a); if (dist > 0.01) return 4; diff --git a/src/PJ_latlong.c b/src/PJ_latlong.c index 7ee41e2a..35c573aa 100644 --- a/src/PJ_latlong.c +++ b/src/PJ_latlong.c @@ -54,12 +54,12 @@ static LP inverse(XY xy, PJ *P) { return lp; } -static PJ_OBS forward_obs(PJ_OBS obs, PJ *P) { +static PJ_COORD forward_4d(PJ_COORD obs, PJ *P) { (void) P; return obs; } -static PJ_OBS inverse_obs(PJ_OBS obs, PJ *P) { +static PJ_COORD inverse_4d(PJ_COORD obs, PJ *P) { (void) P; return obs; } @@ -70,8 +70,8 @@ PJ *PROJECTION(latlong) { P->y0 = 0.0; P->inv = inverse; P->fwd = forward; - P->invobs = inverse_obs; - P->fwdobs = forward_obs; + P->inv4d = inverse_4d; + P->fwd4d = forward_4d; P->left = PJ_IO_UNITS_RADIANS; P->right = PJ_IO_UNITS_RADIANS; @@ -85,8 +85,8 @@ PJ *PROJECTION(longlat) { P->y0 = 0.0; P->inv = inverse; P->fwd = forward; - P->invobs = inverse_obs; - P->fwdobs = forward_obs; + P->inv4d = inverse_4d; + P->fwd4d = forward_4d; P->left = PJ_IO_UNITS_RADIANS; P->right = PJ_IO_UNITS_RADIANS; @@ -100,8 +100,8 @@ PJ *PROJECTION(latlon) { P->y0 = 0.0; P->inv = inverse; P->fwd = forward; - P->invobs = inverse_obs; - P->fwdobs = forward_obs; + P->inv4d = inverse_4d; + P->fwd4d = forward_4d; P->left = PJ_IO_UNITS_RADIANS; P->right = PJ_IO_UNITS_RADIANS; @@ -115,8 +115,8 @@ PJ *PROJECTION(lonlat) { P->y0 = 0.0; P->inv = inverse; P->fwd = forward; - P->invobs = inverse_obs; - P->fwdobs = forward_obs; + P->inv4d = inverse_4d; + P->fwd4d = forward_4d; P->left = PJ_IO_UNITS_RADIANS; P->right = PJ_IO_UNITS_RADIANS; diff --git a/src/PJ_molodensky.c b/src/PJ_molodensky.c index 50423fd8..10ba3fb7 100644 --- a/src/PJ_molodensky.c +++ b/src/PJ_molodensky.c @@ -235,10 +235,9 @@ static XYZ forward_3d(LPZ lpz, PJ *P) { } -static PJ_OBS forward_obs(PJ_OBS obs, PJ *P) { - PJ_OBS point; - point.coo.xyz = forward_3d(obs.coo.lpz, P); - return point; +static PJ_COORD forward_4d(PJ_COORD obs, PJ *P) { + obs.xyz = forward_3d(obs.lpz, P); + return obs; } @@ -263,10 +262,9 @@ static LPZ reverse_3d(XYZ xyz, PJ *P) { } -static PJ_OBS reverse_obs(PJ_OBS obs, PJ *P) { - PJ_OBS point; - point.coo.lpz = reverse_3d(obs.coo.xyz, P); - return point; +static PJ_COORD reverse_4d(PJ_COORD obs, PJ *P) { + obs.lpz = reverse_3d(obs.xyz, P); + return obs; } @@ -276,8 +274,8 @@ PJ *PROJECTION(molodensky) { return pj_default_destructor(P, ENOMEM); P->opaque = (void *) Q; - P->fwdobs = forward_obs; - P->invobs = reverse_obs; + P->fwd4d = forward_4d; + P->inv4d = reverse_4d; P->fwd3d = forward_3d; P->inv3d = reverse_3d; P->fwd = forward_2d; @@ -320,7 +318,7 @@ int pj_molodensky_selftest (void) {return 0;} #else int pj_molodensky_selftest (void) { - PJ_OBS in, res, exp; + PJ_COORD in, res, exp; PJ *P; /* Test the abridged Molodensky first. Example from appendix 3 of Deakin (2004). */ @@ -332,28 +330,28 @@ int pj_molodensky_selftest (void) { if (0==P) return 10; - in.coo.lpz.lam = PJ_TORAD(144.9667); - in.coo.lpz.phi = PJ_TORAD(-37.8); - in.coo.lpz.z = 50.0; + in.lpz.lam = PJ_TORAD(144.9667); + in.lpz.phi = PJ_TORAD(-37.8); + in.lpz.z = 50.0; - exp.coo.lpz.lam = PJ_TORAD(144.968); - exp.coo.lpz.phi = PJ_TORAD(-37.79848); - exp.coo.lpz.z = 46.378; + exp.lpz.lam = PJ_TORAD(144.968); + exp.lpz.phi = PJ_TORAD(-37.79848); + exp.lpz.z = 46.378; - res = proj_trans_obs(P, PJ_FWD, in); + res = proj_trans(P, PJ_FWD, in); - if (proj_lp_dist(P, res.coo.lp, exp.coo.lp) > 2 ) { /* we don't expect much accurecy here... */ + if (proj_lp_dist(P, res.lp, exp.lp) > 2 ) { /* we don't expect much accurecy here... */ proj_destroy(P); return 11; } /* let's try a roundtrip */ - if (proj_roundtrip(P, PJ_FWD, 100, in.coo) > 1) { + if (proj_roundtrip(P, PJ_FWD, 100, in) > 1) { proj_destroy(P); return 12; } - if (res.coo.lpz.z - exp.coo.lpz.z > 1e-3) { + if (res.lpz.z - exp.lpz.z > 1e-3) { proj_destroy(P); return 13; } @@ -369,20 +367,20 @@ int pj_molodensky_selftest (void) { if (0==P) return 20; - res = proj_trans_obs(P, PJ_FWD, in); + res = proj_trans(P, PJ_FWD, in); - if (proj_lp_dist(P, res.coo.lp, exp.coo.lp) > 2 ) { /* we don't expect much accurecy here... */ + if (proj_lp_dist(P, res.lp, exp.lp) > 2 ) { /* we don't expect much accurecy here... */ proj_destroy(P); return 21; } /* let's try a roundtrip */ - if (proj_roundtrip(P, PJ_FWD, 100, in.coo) > 1) { + if (proj_roundtrip(P, PJ_FWD, 100, in) > 1) { proj_destroy(P); return 22; } - if (res.coo.lpz.z - exp.coo.lpz.z > 1e-3) { + if (res.lpz.z - exp.lpz.z > 1e-3) { proj_destroy(P); return 23; } diff --git a/src/PJ_ob_tran.c b/src/PJ_ob_tran.c index d35bb1b3..4f064809 100644 --- a/src/PJ_ob_tran.c +++ b/src/PJ_ob_tran.c @@ -86,10 +86,10 @@ static void *destructor(PJ *P, int errlev) { return 0; if (0==P->opaque) return pj_default_destructor (P, errlev); - + if (P->opaque->link) P->opaque->link->destructor (P->opaque->link, errlev); - + return pj_default_destructor(P, errlev); } @@ -135,7 +135,7 @@ static ARGS ob_tran_target_params (paralist *params) { args.argv = pj_calloc (argc - 1, sizeof (char *)); if (0==args.argv) return args; - + /* Copy all args *except* the proj=ob_tran arg to the argv array */ for (i = 0; params != 0; params = params->next) { if (0==strcmp (params->param, "proj=ob_tran")) @@ -287,14 +287,14 @@ int pj_ob_tran_selftest (void) { a = proj_coord (300000, 400000, 0, 0); b.lpz.lam = -proj_torad (42 + (45 + 22.377/60)/60); b.lpz.phi = proj_torad (85 + (35 + 28.083/60)/60); - a = proj_trans_coord (P, -1, a); + a = proj_trans (P, -1, a); d = proj_lp_dist (P, a.lp, b.lp); if (d > 1e-3) return 2; a = proj_coord (proj_torad(10), proj_torad(20), 0, 0); b = proj_coord (-1384841.18787, 7581707.88240, 0, 0); - a = proj_trans_coord (P, 1, a); + a = proj_trans (P, 1, a); d = proj_xy_dist (a.xy, b.xy); if (d > 1e-3) return 3; diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index 73e15174..c89917a9 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -118,8 +118,8 @@ struct pj_opaque { -static PJ_OBS pipeline_forward_obs (PJ_OBS, PJ *P); -static PJ_OBS pipeline_reverse_obs (PJ_OBS, PJ *P); +static PJ_COORD pipeline_forward_4d (PJ_COORD, PJ *P); +static PJ_COORD pipeline_reverse_4d (PJ_COORD, PJ *P); static XYZ pipeline_forward_3d (LPZ lpz, PJ *P); static LPZ pipeline_reverse_3d (XYZ xyz, PJ *P); static XY pipeline_forward (LP lpz, PJ *P); @@ -174,61 +174,61 @@ static LP pipeline_reverse (XY xyz, PJ *P); -static PJ_OBS pipeline_forward_obs (PJ_OBS point, PJ *P) { +static PJ_COORD pipeline_forward_4d (PJ_COORD point, PJ *P) { int i, first_step, last_step; first_step = 1; last_step = P->opaque->steps + 1; for (i = first_step; i != last_step; i++) - point = proj_trans_obs (P->opaque->pipeline[i], 1, point); + point = proj_trans (P->opaque->pipeline[i], 1, point); return point; } -static PJ_OBS pipeline_reverse_obs (PJ_OBS point, PJ *P) { +static PJ_COORD pipeline_reverse_4d (PJ_COORD point, PJ *P) { int i, first_step, last_step; first_step = P->opaque->steps; last_step = 0; for (i = first_step; i != last_step; i--) - point = proj_trans_obs (P->opaque->pipeline[i], -1, point); + point = proj_trans (P->opaque->pipeline[i], -1, point); return point; } -/* Delegate the work to pipeline_forward_obs() */ +/* Delegate the work to pipeline_forward_4d() */ static XYZ pipeline_forward_3d (LPZ lpz, PJ *P) { - PJ_OBS point = proj_obs_null; - point.coo.lpz = lpz; - point = pipeline_forward_obs (point, P); - return point.coo.xyz; + PJ_COORD point = {{0,0,0,0}}; + point.lpz = lpz; + point = pipeline_forward_4d (point, P); + return point.xyz; } -/* Delegate the work to pipeline_reverse_obs() */ +/* Delegate the work to pipeline_reverse_4d() */ static LPZ pipeline_reverse_3d (XYZ xyz, PJ *P) { - PJ_OBS point = proj_obs_null; - point.coo.xyz = xyz; - point = pipeline_reverse_obs (point, P); - return point.coo.lpz; + PJ_COORD point = {{0,0,0,0}}; + point.xyz = xyz; + point = pipeline_reverse_4d (point, P); + return point.lpz; } static XY pipeline_forward (LP lp, PJ *P) { - PJ_OBS point = proj_obs_null; - point.coo.lp = lp; - point = pipeline_forward_obs (point, P); - return point.coo.xy; + PJ_COORD point = {{0,0,0,0}}; + point.lp = lp; + point = pipeline_forward_4d (point, P); + return point.xy; } static LP pipeline_reverse (XY xy, PJ *P) { - PJ_OBS point = proj_obs_null; - point.coo.xy = xy; - point = pipeline_reverse_obs (point, P); - return point.coo.lp; + PJ_COORD point = {{0,0,0,0}}; + point.xy = xy; + point = pipeline_reverse_4d (point, P); + return point.lp; } @@ -298,8 +298,8 @@ PJ *PROJECTION(pipeline) { int i_pipeline = -1, i_first_step = -1, i_current_step; char **argv, **current_argv; - P->fwdobs = pipeline_forward_obs; - P->invobs = pipeline_reverse_obs; + P->fwd4d = pipeline_forward_4d; + P->inv4d = pipeline_reverse_4d; P->fwd3d = pipeline_forward_3d; P->inv3d = pipeline_reverse_3d; P->fwd = pipeline_forward; @@ -412,7 +412,7 @@ int pj_pipeline_selftest (void) {return 0;} int pj_pipeline_selftest (void) { PJ *P; - PJ_OBS a, b; + PJ_COORD a, b; XY cph_utm32 = {691875.63214, 6098907.82501}; double dist; @@ -421,19 +421,19 @@ int pj_pipeline_selftest (void) { if (0==P) return 1000; /* zero initialize everything, then set (longitude, latitude, height) to (12, 55, 0) */ - a = b = proj_obs_null; - a.coo.lpz.lam = PJ_TORAD(12); - a.coo.lpz.phi = PJ_TORAD(55); - a.coo.lpz.z = 10; + a = b = proj_coord (0,0,0,0); + a.lpz.lam = PJ_TORAD(12); + a.lpz.phi = PJ_TORAD(55); + a.lpz.z = 10; /* Forward projection */ - b = proj_trans_obs (P, PJ_FWD, a); - if (proj_lp_dist (P, a.coo.lp, b.coo.lp) > 1e-4) + b = proj_trans (P, PJ_FWD, a); + if (proj_lp_dist (P, a.lp, b.lp) > 1e-4) return 1001; /* Inverse projection (still same result: pipeline is symmetrical) */ - a = proj_trans_obs (P, PJ_INV, b); - if (proj_lp_dist (P, a.coo.lp, b.coo.lp) > 1e-4) + a = proj_trans (P, PJ_INV, b); + if (proj_lp_dist (P, a.lp, b.lp) > 1e-4) return 1002; proj_destroy (P); @@ -444,19 +444,19 @@ int pj_pipeline_selftest (void) { return 2000; /* zero initialize everything, then set (easting, northing) to utm(12, 55) */ - a = b = proj_obs_null; - a.coo.xy = cph_utm32; + a = b = proj_coord (0,0,0,0); + a.xy = cph_utm32; /* Forward projection */ - b = proj_trans_obs (P, PJ_FWD, a); - if (proj_xy_dist (a.coo.xy, b.coo.xy) > 1e-4) + b = proj_trans (P, PJ_FWD, a); + if (proj_xy_dist (a.xy, b.xy) > 1e-4) return 2001; /* Inverse projection */ - a = proj_trans_obs (P, PJ_INV, b); - if (proj_xy_dist (a.coo.xy, b.coo.xy) > 1e-4) + a = proj_trans (P, PJ_INV, b); + if (proj_xy_dist (a.xy, b.xy) > 1e-4) return 2001; - if (proj_xyz_dist (a.coo.xyz, b.coo.xyz) > 1e-4) + if (proj_xyz_dist (a.xyz, b.xyz) > 1e-4) return 2002; proj_destroy (P); @@ -468,37 +468,37 @@ int pj_pipeline_selftest (void) { return 3000; - a = b = proj_obs_null; - a.coo.lpz.lam = PJ_TORAD(12); - a.coo.lpz.phi = PJ_TORAD(55); + a = b = proj_coord (0,0,0,0); + a.lpz.lam = PJ_TORAD(12); + a.lpz.phi = PJ_TORAD(55); /* Forward projection */ - b = proj_trans_obs (P, PJ_FWD, a); - if (proj_xy_dist (cph_utm32, b.coo.xy) > 1e-4) + b = proj_trans (P, PJ_FWD, a); + if (proj_xy_dist (cph_utm32, b.xy) > 1e-4) return 3001; /* Inverse projection */ - b = proj_trans_obs (P, PJ_INV, b); - if (proj_lp_dist (P, a.coo.lp, b.coo.lp) > 1e-4) + b = proj_trans (P, PJ_INV, b); + if (proj_lp_dist (P, a.lp, b.lp) > 1e-4) return 3002; /* Since we use pj_lp_dist to determine success above, we should also test that it works */ /* Geodesic distance between two points with angular 2D coordinates */ - a.coo.lp.lam = PJ_TORAD(12); - a.coo.lp.phi = PJ_TORAD(60); - b.coo.lp.lam = PJ_TORAD(12); - b.coo.lp.phi = PJ_TORAD(61); - dist = proj_lp_dist (P, a.coo.lp, b.coo.lp); + a.lp.lam = PJ_TORAD(12); + a.lp.phi = PJ_TORAD(60); + b.lp.lam = PJ_TORAD(12); + b.lp.phi = PJ_TORAD(61); + dist = proj_lp_dist (P, a.lp, b.lp); if (fabs (111420.727870234 - dist) > 1e-4) return 4001; - a.coo.lp.lam = PJ_TORAD(12); - a.coo.lp.phi = PJ_TORAD(0.); - b.coo.lp.lam = PJ_TORAD(12); - b.coo.lp.phi = PJ_TORAD(1.); - dist = proj_lp_dist (P, a.coo.lp, b.coo.lp); + a.lp.lam = PJ_TORAD(12); + a.lp.phi = PJ_TORAD(0.); + b.lp.lam = PJ_TORAD(12); + b.lp.phi = PJ_TORAD(1.); + dist = proj_lp_dist (P, a.lp, b.lp); if (fabs (110574.388554153 - dist) > 1e-4) return 4002; @@ -516,11 +516,11 @@ int pj_pipeline_selftest (void) { if (0==P) return 5000; - a.coo.xy.x = 700000.0; - a.coo.xy.y = 6000000.0; + a.xy.x = 700000.0; + a.xy.y = 6000000.0; - b = proj_trans_obs(P, PJ_FWD, a); - dist = proj_xy_dist(a.coo.xy, b.coo.xy); + b = proj_trans(P, PJ_FWD, a); + dist = proj_xy_dist(a.xy, b.xy); if (dist > 1e-7) return 5001; diff --git a/src/PJ_unitconvert.c b/src/PJ_unitconvert.c index c5cf93ae..d8901ee0 100644 --- a/src/PJ_unitconvert.c +++ b/src/PJ_unitconvert.c @@ -19,7 +19,7 @@ date. A time unit conversion is performed like distance units are converted in the same manner, with meter being the central unit. -The modified Julian date is chosen as the pivout unit since it has a +The modified Julian date is chosen as the pivot unit since it has a fairly high precision, goes sufficiently long backwards in time, has no danger of hitting the upper limit in the near future and it is a fairly common time unit in astronomy and geodesy. Note that we are using the @@ -266,40 +266,40 @@ static LPZ reverse_3d(XYZ xyz, PJ *P) { /***********************************************************************/ -static PJ_OBS forward_obs(PJ_OBS obs, PJ *P) { +static PJ_COORD forward_4d(PJ_COORD obs, PJ *P) { /************************************************************************ Forward conversion of time units ************************************************************************/ struct pj_opaque_unitconvert *Q = (struct pj_opaque_unitconvert *) P->opaque; - PJ_OBS out; + PJ_COORD out; /* delegate unit conversion of physical dimensions to the 3D function */ - out.coo.xyz = forward_3d(obs.coo.lpz, P); + out.xyz = forward_3d(obs.lpz, P); if (Q->t_in_id >= 0) - out.coo.xyzt.t = time_units[Q->t_in_id].t_in( obs.coo.xyzt.t ); + out.xyzt.t = time_units[Q->t_in_id].t_in( obs.xyzt.t ); if (Q->t_out_id >= 0) - out.coo.xyzt.t = time_units[Q->t_out_id].t_out( out.coo.xyzt.t ); + out.xyzt.t = time_units[Q->t_out_id].t_out( out.xyzt.t ); return out; } /***********************************************************************/ -static PJ_OBS reverse_obs(PJ_OBS obs, PJ *P) { +static PJ_COORD reverse_4d(PJ_COORD obs, PJ *P) { /************************************************************************ Reverse conversion of time units ************************************************************************/ struct pj_opaque_unitconvert *Q = (struct pj_opaque_unitconvert *) P->opaque; - PJ_OBS out; + PJ_COORD out; /* delegate unit conversion of physical dimensions to the 3D function */ - out.coo.lpz = reverse_3d(obs.coo.xyz, P); + out.lpz = reverse_3d(obs.xyz, P); if (Q->t_out_id >= 0) - out.coo.xyzt.t = time_units[Q->t_out_id].t_in( obs.coo.xyzt.t ); + out.xyzt.t = time_units[Q->t_out_id].t_in( obs.xyzt.t ); if (Q->t_in_id >= 0) - out.coo.xyzt.t = time_units[Q->t_in_id].t_out( out.coo.xyzt.t ); + out.xyzt.t = time_units[Q->t_in_id].t_out( out.xyzt.t ); return out; } @@ -316,8 +316,8 @@ PJ *PROJECTION(unitconvert) { return pj_default_destructor (P, ENOMEM); P->opaque = (void *) Q; - P->fwdobs = forward_obs; - P->invobs = reverse_obs; + P->fwd4d = forward_4d; + P->inv4d = reverse_4d; P->fwd3d = forward_3d; P->inv3d = reverse_3d; P->fwd = forward_2d; @@ -396,23 +396,23 @@ int pj_unitconvert_selftest (void) {return 0;} #else static int test_time(char* args, double tol, double t_in, double t_exp) { - PJ_OBS in, out; + PJ_COORD in, out; PJ *P = proj_create(PJ_DEFAULT_CTX, args); int ret = 0; if (P == 0) return 5; - in.coo.xyzt.t = t_in; + in.xyzt.t = t_in; - out = proj_trans_obs(P, PJ_FWD, in); - if (fabs(out.coo.xyzt.t - t_exp) > tol) { - proj_log_error(P, "out: %10.10g, expect: %10.10g", out.coo.xyzt.t, t_exp); + out = proj_trans(P, PJ_FWD, in); + if (fabs(out.xyzt.t - t_exp) > tol) { + proj_log_error(P, "out: %10.10g, expect: %10.10g", out.xyzt.t, t_exp); ret = 1; } - out = proj_trans_obs(P, PJ_INV, out); - if (fabs(out.coo.xyzt.t - t_in) > tol) { - proj_log_error(P, "out: %10.10g, expect: %10.10g", out.coo.xyzt.t, t_in); + out = proj_trans(P, PJ_INV, out); + if (fabs(out.xyzt.t - t_in) > tol) { + proj_log_error(P, "out: %10.10g, expect: %10.10g", out.xyzt.t, t_in); ret = 2; } pj_free(P); @@ -422,25 +422,25 @@ static int test_time(char* args, double tol, double t_in, double t_exp) { } static int test_xyz(char* args, double tol, PJ_TRIPLET in, PJ_TRIPLET exp) { - PJ_OBS out, obs_in; + PJ_COORD out, obs_in; PJ *P = proj_create(PJ_DEFAULT_CTX, args); int ret = 0; if (P == 0) return 5; - obs_in.coo.xyz = in.xyz; - out = proj_trans_obs(P, PJ_FWD, obs_in); - if (proj_xyz_dist(out.coo.xyz, exp.xyz) > tol) { + obs_in.xyz = in.xyz; + out = proj_trans(P, PJ_FWD, obs_in); + if (proj_xyz_dist(out.xyz, exp.xyz) > tol) { printf("exp: %10.10g, %10.10g, %10.10g\n", exp.xyz.x, exp.xyz.y, exp.xyz.z); - printf("out: %10.10g, %10.10g, %10.10g\n", out.coo.xyz.x, out.coo.xyz.y, out.coo.xyz.z); + printf("out: %10.10g, %10.10g, %10.10g\n", out.xyz.x, out.xyz.y, out.xyz.z); ret = 1; } - out = proj_trans_obs(P, PJ_INV, out); - if (proj_xyz_dist(out.coo.xyz, in.xyz) > tol) { + out = proj_trans(P, PJ_INV, out); + if (proj_xyz_dist(out.xyz, in.xyz) > tol) { printf("exp: %g, %g, %g\n", in.xyz.x, in.xyz.y, in.xyz.z); - printf("out: %g, %g, %g\n", out.coo.xyz.x, out.coo.xyz.y, out.coo.xyz.z); + printf("out: %g, %g, %g\n", out.xyz.x, out.xyz.y, out.xyz.z); ret += 2; } proj_destroy(P); diff --git a/src/PJ_vgridshift.c b/src/PJ_vgridshift.c index 691f791b..9db0b332 100644 --- a/src/PJ_vgridshift.c +++ b/src/PJ_vgridshift.c @@ -33,15 +33,15 @@ static LPZ reverse_3d(XYZ xyz, PJ *P) { } -static PJ_OBS forward_obs(PJ_OBS obs, PJ *P) { - PJ_OBS point; - point.coo.xyz = forward_3d (obs.coo.lpz, P); +static PJ_COORD forward_4d(PJ_COORD obs, PJ *P) { + PJ_COORD point; + point.xyz = forward_3d (obs.lpz, P); return point; } -static PJ_OBS reverse_obs(PJ_OBS obs, PJ *P) { - PJ_OBS point; - point.coo.lpz = reverse_3d (obs.coo.xyz, P); +static PJ_COORD reverse_4d(PJ_COORD obs, PJ *P) { + PJ_COORD point; + point.lpz = reverse_3d (obs.xyz, P); return point; } @@ -62,8 +62,8 @@ PJ *PROJECTION(vgridshift) { return pj_default_destructor(P, PJD_ERR_FAILED_TO_LOAD_GRID); } - P->fwdobs = forward_obs; - P->invobs = reverse_obs; + P->fwd4d = forward_4d; + P->inv4d = reverse_4d; P->fwd3d = forward_3d; P->inv3d = reverse_3d; P->fwd = 0; @@ -82,7 +82,7 @@ int pj_vgridshift_selftest (void) {return 0;} #else int pj_vgridshift_selftest (void) { PJ *P; - PJ_OBS expect, a, b; + PJ_COORD expect, a, b; double dist; int failures = 0; @@ -105,29 +105,29 @@ int pj_vgridshift_selftest (void) { if (0==P) return 10; - a = proj_obs_null; - a.coo.lpz.lam = PJ_TORAD(12.5); - a.coo.lpz.phi = PJ_TORAD(55.5); + 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.coo); + dist = proj_roundtrip (P, PJ_FWD, 1, a); if (dist > 0.00000001) return 1; expect = a; /* Appears there is a difference between the egm96_15.gtx distributed by OSGeo4W, */ /* and the one from http://download.osgeo.org/proj/vdatum/egm96_15/egm96_15.gtx */ - /* Was: expect.coo.lpz.z = -36.021305084228515625; (download.osgeo.org) */ - /* Was: expect.coo.lpz.z = -35.880001068115234000; (OSGeo4W) */ + /* Was: expect.lpz.z = -36.021305084228515625; (download.osgeo.org) */ + /* Was: expect.lpz.z = -35.880001068115234000; (OSGeo4W) */ /* This is annoying, but must be handled elsewhere. So for now, we check for both. */ - expect.coo.lpz.z = -36.021305084228516; + expect.lpz.z = -36.021305084228516; failures = 0; - b = proj_trans_obs(P, PJ_FWD, a); - if (proj_xyz_dist(expect.coo.xyz, b.coo.xyz) > 1e-4) failures++; - expect.coo.lpz.z = -35.880001068115234000; - if (proj_xyz_dist(expect.coo.xyz, b.coo.xyz) > 1e-4) failures++; + b = proj_trans(P, PJ_FWD, a); + 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++; if (failures > 1) return 2; - + proj_destroy (P); return 0; diff --git a/src/cct.c b/src/cct.c index 90b84159..de97f728 100644 --- a/src/cct.c +++ b/src/cct.c @@ -72,6 +72,7 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-25/2017-10-26 ***********************************************************************/ #include "optargpm.h" +#include "proj_internal.h" #include #include "projects.h" #include @@ -80,6 +81,7 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-25/2017-10-26 #include #include + double proj_strtod(const char *str, char **endptr); double proj_atof(const char *str); @@ -211,17 +213,13 @@ int main(int argc, char **argv) { return 1; } - input_unit = P->left; - output_unit = P->right; - if (PJ_IO_UNITS_CLASSIC==P->left) - input_unit = PJ_IO_UNITS_RADIANS; - if (PJ_IO_UNITS_CLASSIC==P->right) - output_unit = PJ_IO_UNITS_METERS; - if (direction==-1) { - enum pj_io_units swap = input_unit; - input_unit = output_unit; - output_unit = swap; - } + /* We have no API call for inverting an operation, so we brute force it. */ + if (direction==-1) + 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); @@ -264,7 +262,7 @@ int main(int argc, char **argv) { point.lpzt.lam = proj_torad (point.lpzt.lam); point.lpzt.phi = proj_torad (point.lpzt.phi); } - point = proj_trans_coord (P, direction, point); + point = proj_trans (P, direction, point); if (PJ_IO_UNITS_RADIANS==output_unit) { 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 269a7239..f874ee93 100644 --- a/src/gie.c +++ b/src/gie.c @@ -532,7 +532,7 @@ static int expect (char *args) { } T.e = torad_if_needed (T.P, T.dir==PJ_FWD? PJ_INV:PJ_FWD, T.e); - T.b = proj_trans_coord (T.P, T.dir, T.a); + 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.nargs < 2) { diff --git a/src/pj_internal.c b/src/pj_internal.c index 19dd6409..efa9bd1f 100644 --- a/src/pj_internal.c +++ b/src/pj_internal.c @@ -30,7 +30,7 @@ *****************************************************************************/ #define PJ_INTERNAL_C #include "proj_internal.h" -#include +#include "projects.h" #include #include @@ -38,34 +38,6 @@ #include - - -/* Used for zero-initializing new objects */ -const PJ_COORD proj_coord_null = {{0, 0, 0, 0}}; -const PJ_OBS proj_obs_null = { - {{0, 0, 0, 0}} -}; - - - -/* Initialize PJ_OBS struct */ -PJ_OBS proj_obs (double x, double y, double z, double t) { - PJ_OBS res; - res.coo = proj_coord (x, y, z, t); - return res; -} - - - - - - - - - - - - enum pj_io_units pj_left (PJ *P) { enum pj_io_units u = P->inverted? P->right: P->left; if (u==PJ_IO_UNITS_RADIANS) @@ -80,29 +52,6 @@ enum pj_io_units pj_right (PJ *P) { return PJ_IO_UNITS_METERS; } -/* Apply the transformation P to the coordinate coo */ -PJ_OBS proj_trans_obs (PJ *P, PJ_DIRECTION direction, PJ_OBS obs) { - if (0==P) - return obs; - - if (P->inverted) - direction = -direction; - - switch (direction) { - case PJ_FWD: - return pj_fwdobs (obs, P); - case PJ_INV: - return pj_invobs (obs, P); - case PJ_IDENT: - return obs; - default: - break; - } - - proj_errno_set (P, EINVAL); - return proj_obs_error (); -} - /* Work around non-constness of MSVC HUGE_VAL by providing functions rather than constants */ PJ_COORD proj_coord_error (void) { @@ -111,60 +60,10 @@ PJ_COORD proj_coord_error (void) { return c; } -PJ_OBS proj_obs_error (void) { - PJ_OBS obs; - obs.coo = proj_coord_error (); - return obs; -} - - -PJ_OBS pj_fwdobs (PJ_OBS obs, PJ *P) { - if (0!=P->fwdobs) { - obs = P->fwdobs (obs, P); - return obs; - } - if (0!=P->fwd3d) { - obs.coo.xyz = pj_fwd3d (obs.coo.lpz, P); - return obs; - } - if (0!=P->fwd) { - obs.coo.xy = pj_fwd (obs.coo.lp, P); - return obs; - } - proj_errno_set (P, EINVAL); - return proj_obs_error (); -} - - -PJ_OBS pj_invobs (PJ_OBS obs, PJ *P) { - if (0!=P->invobs) { - obs = P->invobs (obs, P); - return obs; - } - if (0!=P->inv3d) { - obs.coo.lpz = pj_inv3d (obs.coo.xyz, P); - return obs; - } - if (0!=P->inv) { - obs.coo.lp = pj_inv (obs.coo.xy, P); - return obs; - } - proj_errno_set (P, EINVAL); - return proj_obs_error (); -} - - - -PJ_COORD pj_fwdcoord (PJ_COORD coo, PJ *P) { - if (0!=P->fwdcoord) - return P->fwdcoord (coo, P); - if (0!=P->fwdobs) { - PJ_OBS obs = proj_obs_null; - obs.coo = coo; - obs = P->fwdobs (obs, P); - return obs.coo; - } +PJ_COORD pj_fwd4d (PJ_COORD coo, PJ *P) { + if (0!=P->fwd4d) + return P->fwd4d (coo, P); if (0!=P->fwd3d) { coo.xyz = pj_fwd3d (coo.lpz, P); return coo; @@ -178,15 +77,9 @@ PJ_COORD pj_fwdcoord (PJ_COORD coo, PJ *P) { } -PJ_COORD pj_invcoord (PJ_COORD coo, PJ *P) { - if (0!=P->invcoord) - return P->invcoord (coo, P); - if (0!=P->invobs) { - PJ_OBS obs = proj_obs_null; - obs.coo = coo; - obs = P->invobs (obs, P); - return obs.coo; - } +PJ_COORD pj_inv4d (PJ_COORD coo, PJ *P) { + if (0!=P->inv4d) + return P->inv4d (coo, P); if (0!=P->inv3d) { coo.lpz = pj_inv3d (coo.xyz, P); return coo; diff --git a/src/proj.def b/src/proj.def index 86deb24d..998a260e 100644 --- a/src/proj.def +++ b/src/proj.def @@ -97,52 +97,52 @@ EXPORTS proj_create_crs_to_crs @93 proj_destroy @94 - proj_trans_obs @95 - proj_trans_coord @96 - proj_transform @97 - proj_transform_coord @98 - proj_roundtrip @99 + proj_trans @95 + proj_trans_array @96 + proj_trans_generic @97 + proj_roundtrip @98 - proj_coord @100 - proj_obs @101 - proj_coord_error @102 - proj_obs_error @103 + proj_coord @99 + proj_coord_error @100 - proj_errno @104 - proj_errno_set @105 - proj_errno_reset @106 - proj_errno_restore @107 - proj_context_errno_set @108 + proj_errno @101 + proj_errno_set @102 + proj_errno_reset @103 + proj_errno_restore @104 + proj_context_errno_set @105 - proj_context_create @109 - proj_context_set @110 - proj_context_inherit @111 - proj_context_destroy @112 + proj_context_create @106 + proj_context_set @107 + proj_context_inherit @108 + proj_context_destroy @109 - proj_lp_dist @113 - proj_xy_dist @114 - proj_xyz_dist @115 + proj_lp_dist @110 + proj_xy_dist @111 + proj_xyz_dist @112 - proj_log_level @116 - proj_log_func @117 - proj_log_error @118 - proj_log_debug @119 - proj_log_trace @120 + proj_log_level @113 + proj_log_func @114 + proj_log_error @115 + proj_log_debug @116 + proj_log_trace @117 - proj_info @121 - proj_pj_info @122 - proj_grid_info @123 - proj_init_info @124 + proj_info @118 + proj_pj_info @119 + proj_grid_info @120 + proj_init_info @121 - proj_torad @125 - proj_todeg @126 - proj_rtodms @127 - proj_dmstor @128 + proj_torad @122 + proj_todeg @123 + proj_rtodms @124 + proj_dmstor @125 - proj_derivatives @129 - proj_factors @130 + proj_derivatives @126 + proj_factors @127 - proj_list_operations @131 - proj_list_ellps @132 - proj_list_units @133 - proj_list_prime_meridians @134 + proj_list_operations @128 + proj_list_ellps @129 + proj_list_units @130 + proj_list_prime_meridians @131 + + proj_angular_left @132 + proj_angular_right @133 diff --git a/src/proj.h b/src/proj.h index dd0672f9..7607c3d8 100644 --- a/src/proj.h +++ b/src/proj.h @@ -368,10 +368,16 @@ enum PJ_DIRECTION { }; typedef enum PJ_DIRECTION PJ_DIRECTION; -PJ_COORD proj_trans_coord (PJ *P, PJ_DIRECTION direction, PJ_COORD coord); -size_t proj_transform ( + +int proj_angular_left (PJ *P); +int proj_angular_right (PJ *P); + +PJ_COORD proj_trans (PJ *P, PJ_DIRECTION direction, PJ_COORD coord); + + +size_t proj_trans_generic ( PJ *P, PJ_DIRECTION direction, double *x, size_t sx, size_t nx, @@ -380,7 +386,7 @@ size_t proj_transform ( double *t, size_t st, size_t nt ); -int proj_transform_coord (PJ *P, PJ_DIRECTION direction, size_t n, PJ_COORD *coord); +int proj_trans_array (PJ *P, PJ_DIRECTION direction, size_t n, PJ_COORD *coord); /* Initializers */ PJ_COORD proj_coord (double x, double y, double z, double t); diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c index 4b8fd854..9ae4147f 100644 --- a/src/proj_4D_api.c +++ b/src/proj_4D_api.c @@ -44,6 +44,13 @@ 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) { + return pj_right (P)==PJ_IO_UNITS_RADIANS; +} /* Geodesic distance (in meter) between two points with angular 2D coordinates */ double proj_lp_dist (const PJ *P, LP a, LP b) { @@ -84,14 +91,14 @@ double proj_roundtrip (PJ *P, PJ_DIRECTION direction, int n, PJ_COORD coo) { switch (direction) { case PJ_FWD: for (i = 0; i < n; i++) { - u = pj_fwdcoord (o, P); - o = pj_invcoord (u, P); + u = pj_fwd4d (o, P); + o = pj_inv4d (u, P); } break; case PJ_INV: for (i = 0; i < n; i++) { - u = pj_invcoord (o, P); - o = pj_fwdcoord (u, P); + u = pj_inv4d (o, P); + o = pj_fwd4d (u, P); } break; default: @@ -108,17 +115,18 @@ double proj_roundtrip (PJ *P, PJ_DIRECTION direction, int n, PJ_COORD coo) { } - /* Apply the transformation P to the coordinate coo */ -PJ_COORD proj_trans_coord (PJ *P, PJ_DIRECTION direction, PJ_COORD coo) { +PJ_COORD proj_trans (PJ *P, PJ_DIRECTION direction, PJ_COORD coo) { if (0==P) return coo; + if (P->inverted) + direction = -direction; switch (direction) { case PJ_FWD: - return pj_fwdcoord (coo, P); + return pj_fwd4d (coo, P); case PJ_INV: - return pj_invcoord (coo, P); + return pj_inv4d (coo, P); case PJ_IDENT: return coo; default: @@ -131,8 +139,29 @@ PJ_COORD proj_trans_coord (PJ *P, PJ_DIRECTION direction, PJ_COORD coo) { +/*****************************************************************************/ +int proj_trans_array (PJ *P, PJ_DIRECTION direction, size_t n, PJ_COORD *coord) { +/****************************************************************************** + Batch transform an array of PJ_COORD. + + Returns 0 if all coordinates are transformed without error, otherwise + returns error number. +******************************************************************************/ + size_t i; + + for (i = 0; i < n; i++) { + coord[i] = proj_trans (P, direction, coord[i]); + if (proj_errno(P)) + return proj_errno (P); + } + + return 0; +} + + + /*************************************************************************************/ -size_t proj_transform ( +size_t proj_trans_generic ( PJ *P, PJ_DIRECTION direction, double *x, size_t sx, size_t nx, @@ -189,12 +218,16 @@ size_t proj_transform ( Return value: Number of transformations completed. **************************************************************************************/ - PJ_COORD coord = proj_coord_null; + PJ_COORD coord = {{0,0,0,0}}; size_t i, nmin; double null_broadcast = 0; + if (0==P) return 0; + if (P->inverted) + direction = -direction; + /* ignore lengths of null arrays */ if (0==x) nx = 0; if (0==y) ny = 0; @@ -244,9 +277,9 @@ size_t proj_transform ( coord.xyzt.t = *t; if (PJ_FWD==direction) - coord = pj_fwdcoord (coord, P); + coord = pj_fwd4d (coord, P); else - coord = pj_invcoord (coord, P); + coord = pj_inv4d (coord, P); /* in all full length cases, we overwrite the input with the output */ if (nx > 1) { @@ -281,24 +314,6 @@ size_t proj_transform ( return i; } -/*****************************************************************************/ -int proj_transform_coord (PJ *P, PJ_DIRECTION direction, size_t n, PJ_COORD *coord) { -/****************************************************************************** - Batch transform an array of PJ_COORD. - - Returns 0 if all coordinates are transformed without error, otherwise - returns error number. -******************************************************************************/ - size_t i; - for (i=0; iinv != 0 || P->inv3d != 0 || P->invobs != 0); + info.has_inverse = (P->inv != 0 || P->inv3d != 0 || P->inv4d != 0); return info; } diff --git a/src/proj_internal.h b/src/proj_internal.h index 36ff5767..33cfbdfd 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -48,14 +48,6 @@ extern "C" { #endif - - -struct PJ_OBS { - PJ_COORD coo; /* coordinate data */ -}; -typedef struct PJ_OBS PJ_OBS; - - #ifndef PJ_TODEG #define PJ_TODEG(rad) ((rad)*180.0/M_PI) #endif @@ -67,29 +59,16 @@ typedef struct PJ_OBS PJ_OBS; enum pj_io_units pj_left (PJ *P); enum pj_io_units pj_right (PJ *P); -PJ_OBS proj_obs (double x, double y, double z, double t); -PJ_OBS proj_trans_obs (PJ *P, PJ_DIRECTION direction, PJ_OBS obs); +PJ_COORD proj_trans (PJ *P, PJ_DIRECTION direction, PJ_COORD obs); PJ_COORD proj_coord_error (void); -PJ_OBS proj_obs_error (void); -#ifndef PJ_INTERNAL_C -extern const PJ_COORD proj_coord_null; -extern const PJ_OBS proj_obs_null; -#endif -/* Part of MSVC workaround: Make proj_*_null look function-like for symmetry with proj_*_error */ -#define proj_coord_null(x) proj_coord_null -#define proj_obs_null(x) proj_obs_null - void proj_context_errno_set (PJ_CONTEXT *ctx, int err); void proj_context_set (PJ *P, PJ_CONTEXT *ctx); void proj_context_inherit (PJ *parent, PJ *child); - -PJ_OBS pj_fwdobs (PJ_OBS obs, PJ *P); -PJ_OBS pj_invobs (PJ_OBS obs, PJ *P); -PJ_COORD pj_fwdcoord (PJ_COORD coo, PJ *P); -PJ_COORD pj_invcoord (PJ_COORD coo, PJ *P); +PJ_COORD pj_fwd4d (PJ_COORD coo, PJ *P); +PJ_COORD pj_inv4d (PJ_COORD coo, PJ *P); /* Grid functionality */ int proj_vgrid_init(PJ *P, const char *grids); diff --git a/src/projects.h b/src/projects.h index 0631924c..fad5c7bc 100644 --- a/src/projects.h +++ b/src/projects.h @@ -173,10 +173,7 @@ typedef struct { double u, v, w; } UVW; /* Forward declarations and typedefs for stuff needed inside the PJ object */ struct PJconsts; -struct PJ_OBS; -#ifndef PROJ_INTERNAL_H -typedef struct PJ_OBS PJ_OBS; -#endif + union PJ_COORD; struct geod_geodesic; struct pj_opaque; @@ -212,6 +209,7 @@ struct PJ_AREA { struct projCtx_t; typedef struct projCtx_t projCtx_t; + /* base projection data structure */ struct PJconsts { @@ -254,10 +252,9 @@ struct PJconsts { LP (*inv)(XY, PJ *); XYZ (*fwd3d)(LPZ, PJ *); LPZ (*inv3d)(XYZ, PJ *); - PJ_OBS (*fwdobs)(PJ_OBS, PJ *); - PJ_OBS (*invobs)(PJ_OBS, PJ *); - PJ_COORD (*fwdcoord)(PJ_COORD, PJ *); - PJ_COORD (*invcoord)(PJ_COORD, PJ *); + PJ_COORD (*fwd4d)(PJ_COORD, PJ *); + PJ_COORD (*inv4d)(PJ_COORD, PJ *); + void (*spc)(LP, PJ *, struct FACTORS *); -- cgit v1.2.3 From 0dffb56a59e5ef836005f0a9ddb99dc735202991 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Sun, 5 Nov 2017 21:22:20 +0100 Subject: Move pipeline initialization logic to PJ_pipeline.c and decrease the number of special cases to handle in pj_init.c --- src/PJ_pipeline.c | 43 ++++++++++++++++++++++++++++++++-- src/pj_ell_set.c | 45 +++++++++++++++++++++++++++++++++++ src/pj_init.c | 67 ++++++++--------------------------------------------- src/proj_internal.h | 1 + 4 files changed, 97 insertions(+), 59 deletions(-) (limited to 'src') diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index c89917a9..0729b1da 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -98,8 +98,9 @@ Thomas Knudsen, thokn@sdfe.dk, 2016-05-20 ********************************************************************************/ #define PJ_LIB__ +#include #include "proj_internal.h" -#include +#include "projects.h" #include #include @@ -291,9 +292,45 @@ static char **argv_params (paralist *params, size_t argc) { return argv; } +/* Being the special operator that the pipeline is, we have to handle the */ +/* ellipsoid differently than usual. In general, the pipeline operation does */ +/* not need an ellipsoid, but in some cases it is beneficial nonetheless. */ +/* Unfortunately we can't use the normal ellipsoid setter in pj_init, since */ +/* it adds a +ellps parameter to the global args if nothing else is specified*/ +/* This is problematic since that ellipsoid spec is then passed on to the */ +/* pipeline children. This is rarely what we want, so here we implement our */ +/* own logic instead. If an ellipsoid is set in the global args, it is used */ +/* as the pipeline ellipsoid. Otherwise we use WGS84 parameters as default. */ +/* At last we calculate the rest of the ellipsoid parameters and */ +/* re-initialize P->geod. */ +static void set_ellipsoid(PJ *P) { + paralist *cur, *attachment; + + /* Break the linked list after the global args */ + attachment = 0; + for (cur = P->params; cur != 0; cur = cur->next) + if (strcmp("step", cur->next->param) == 0) { + attachment = cur->next; + cur->next = 0; + break; + } + + /* Check if there's any ellipsoid specification in the global params. */ + /* If not, use WGS84 as default */ + if (pj_ell_set(P->ctx, P->params, &P->a, &P->es)) { + P->a = 6378137.0; + P->es = .00669438002290341575; + } + pj_calc_ellps_params(P, P->a, P->es); + geod_init(P->geod, P->a, (1 - sqrt (1 - P->es))); -PJ *PROJECTION(pipeline) { + /* Re-attach the dangling list */ + cur->next = attachment; +} + + +PJ *OPERATION(pipeline,0) { int i, nsteps = 0, argc; int i_pipeline = -1, i_first_step = -1, i_current_step; char **argv, **current_argv; @@ -353,6 +390,8 @@ PJ *PROJECTION(pipeline) { if (0==pj_create_pipeline (P, nsteps)) return destructor (P, ENOMEM); + set_ellipsoid(P); + /* Now loop over all steps, building a new set of arguments for each init */ for (i_current_step = i_first_step, i = 0; i < nsteps; i++) { int j; diff --git a/src/pj_ell_set.c b/src/pj_ell_set.c index d43feecb..8a9b39a1 100644 --- a/src/pj_ell_set.c +++ b/src/pj_ell_set.c @@ -44,6 +44,51 @@ void pj_inherit_ellipsoid_defs(const PJ *src, PJ *dst) { dst->a_orig = src->a_orig; } +int pj_calc_ellps_params(PJ *P, double a, double es) { + + P->a = a; + P->es = es; + + /* Compute some ancillary ellipsoidal parameters */ + P->e = sqrt(P->es); /* eccentricity */ + P->alpha = asin (P->e); /* angular eccentricity */ + + /* second eccentricity */ + P->e2 = tan (P->alpha); + P->e2s = P->e2 * P->e2; + + /* third eccentricity */ + P->e3 = (0!=P->alpha)? sin (P->alpha) / sqrt(2 - sin (P->alpha)*sin (P->alpha)): 0; + P->e3s = P->e3 * P->e3; + + /* flattening */ + P->f = 1 - cos (P->alpha); /* = 1 - sqrt (1 - PIN->es); */ + P->rf = P->f != 0.0 ? 1.0/P->f: HUGE_VAL; + + /* second flattening */ + P->f2 = (cos(P->alpha)!=0)? 1/cos (P->alpha) - 1: 0; + P->rf2 = P->f2 != 0.0 ? 1/P->f2: HUGE_VAL; + + /* third flattening */ + P->n = pow (tan (P->alpha/2), 2); + P->rn = P->n != 0.0 ? 1/P->n: HUGE_VAL; + + /* ...and a few more */ + P->b = (1 - P->f)*P->a; + P->rb = 1. / P->b; + P->ra = 1. / P->a; + + P->one_es = 1. - P->es; + if (P->one_es == 0.) { + pj_ctx_set_errno( P->ctx, PJD_ERR_ECCENTRICITY_IS_ONE); + return PJD_ERR_ECCENTRICITY_IS_ONE; + } + + P->rone_es = 1./P->one_es; + + return 0; +} + /* initialize geographic shape parameters */ int pj_ell_set(projCtx ctx, paralist *pl, double *a, double *es) { int i; diff --git a/src/pj_init.c b/src/pj_init.c index 2a945397..f69d9eae 100644 --- a/src/pj_init.c +++ b/src/pj_init.c @@ -28,12 +28,13 @@ *****************************************************************************/ #define PJ_LIB__ -#include #include #include #include #include #include +#include "proj_internal.h" +#include "projects.h" /* Maximum size of files using the "escape carriage return" feature */ #define MAX_CR_ESCAPE 65537 @@ -129,7 +130,6 @@ get_opt(projCtx ctx, paralist **start, PAFile fid, char *name, paralist *next, int *found_def) { pj_read_state *state = (pj_read_state*) calloc(1,sizeof(pj_read_state)); char sword[MAX_CR_ESCAPE]; - char *pipeline; int len; int in_target = 0; const char *next_char = NULL; @@ -220,10 +220,7 @@ get_opt(projCtx ctx, paralist **start, PAFile fid, char *name, paralist *next, sword[word_len+1] = '\0'; /* do not override existing parameter value of same name - unless in pipeline definition */ - pipeline = pj_param(ctx, *start, "sproj").s; - if (pipeline && strcmp (pipeline, "pipeline")) - pipeline = 0; - if (pipeline || !pj_param(ctx, *start, sword).i) { + if (!pj_param(ctx, *start, sword).i) { /* don't default ellipse if datum, ellps or any earth model information is set. */ if( strncmp(sword+1,"ellps=",6) != 0 @@ -260,8 +257,7 @@ get_opt(projCtx ctx, paralist **start, PAFile fid, char *name, paralist *next, /************************************************************************/ /* get_defaults() */ /************************************************************************/ -static paralist * -get_defaults(projCtx ctx, paralist **start, paralist *next, char *name) { +static paralist *get_defaults(projCtx ctx, paralist **start, paralist *next, char *name) { PAFile fid; if ( (fid = pj_open_lib(ctx,"proj_def.dat", "rt")) != NULL) { @@ -486,7 +482,6 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { curr = curr->next; } - /* Only expand +init's in non-pipeline operations. +init's in pipelines are */ /* expanded in the individual pipeline steps during pipeline initialization. */ /* Potentially this leads to many nested pipelines, which shouldn't be a */ @@ -522,7 +517,6 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { if (0==PIN) return pj_dealloc_params (ctx, start, ENOMEM); - PIN->ctx = ctx; PIN->params = start; PIN->is_latlong = 0; @@ -541,58 +535,17 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { if (pj_datum_set(ctx, start, PIN)) return pj_default_destructor (PIN, PJD_ERR_MISSING_ARGS); - /* set ellipsoid/sphere parameters. If we are initializing a pipeline we */ - /* override ellipsoid-setter, since it also adds a "+ellps=WGS84" to the */ - /* parameter list which creates problems when the pipeline driver passes */ - /* the global parameters on the it's children. */ - if (n_pipelines > 0) { - PIN->a = 6378137.0; - PIN->es = .00669438002290341575; - } else { + if (PIN->need_ellps) { if (pj_ell_set(ctx, start, &PIN->a, &PIN->es)) { pj_log (ctx, PJ_LOG_DEBUG_MINOR, "pj_init_ctx: Must specify ellipsoid or sphere"); return pj_default_destructor (PIN, PJD_ERR_MISSING_ARGS); } - } - - PIN->a_orig = PIN->a; - PIN->es_orig = PIN->es; - - /* Compute some ancillary ellipsoidal parameters */ - PIN->e = sqrt(PIN->es); /* eccentricity */ - PIN->alpha = asin (PIN->e); /* angular eccentricity */ - - /* second eccentricity */ - PIN->e2 = tan (PIN->alpha); - PIN->e2s = PIN->e2 * PIN->e2; - - /* third eccentricity */ - PIN->e3 = (0!=PIN->alpha)? sin (PIN->alpha) / sqrt(2 - sin (PIN->alpha)*sin (PIN->alpha)): 0; - PIN->e3s = PIN->e3 * PIN->e3; - - /* flattening */ - PIN->f = 1 - cos (PIN->alpha); /* = 1 - sqrt (1 - PIN->es); */ - PIN->rf = PIN->f != 0.0 ? 1.0/PIN->f: HUGE_VAL; - - /* second flattening */ - PIN->f2 = (cos(PIN->alpha)!=0)? 1/cos (PIN->alpha) - 1: 0; - PIN->rf2 = PIN->f2 != 0.0 ? 1/PIN->f2: HUGE_VAL; - - /* third flattening */ - PIN->n = pow (tan (PIN->alpha/2), 2); - PIN->rn = PIN->n != 0.0 ? 1/PIN->n: HUGE_VAL; - - /* ...and a few more */ - PIN->b = (1 - PIN->f)*PIN->a; - PIN->rb = 1. / PIN->b; - PIN->ra = 1. / PIN->a; - - PIN->one_es = 1. - PIN->es; - if (PIN->one_es == 0.) - return pj_default_destructor (PIN, PJD_ERR_ECCENTRICITY_IS_ONE); - PIN->rone_es = 1./PIN->one_es; - + PIN->a_orig = PIN->a; + PIN->es_orig = PIN->es; + if (pj_calc_ellps_params(PIN, PIN->a, PIN->es)) + return pj_default_destructor (PIN, PJD_ERR_ECCENTRICITY_IS_ONE); + } /* Now that we have ellipse information check for WGS84 datum */ if( PIN->datum_type == PJD_3PARAM diff --git a/src/proj_internal.h b/src/proj_internal.h index 33cfbdfd..2d6a2406 100644 --- a/src/proj_internal.h +++ b/src/proj_internal.h @@ -99,6 +99,7 @@ void proj_log_trace (PJ *P, const char *fmt, ...); void proj_log_func (PJ_CONTEXT *ctx, void *app_data, PJ_LOG_FUNCTION log); void pj_inherit_ellipsoid_defs(const PJ *src, PJ *dst); +int pj_calc_ellps_params(PJ *P, double a, double es); /* Lowest level: Minimum support for fileapi */ void proj_fileapi_set (PJ *P, void *fileapi); -- cgit v1.2.3 From c0c95e33abf2f724e5827cbf41ede41e2939e188 Mon Sep 17 00:00:00 2001 From: Aaron Puchert Date: Mon, 6 Nov 2017 17:52:29 +0100 Subject: Use enumerations where appropriate Enumerations have the following advantages over #define: - they clearly connect a variable and the allowed constants, - the meaning of code is not obfuscated by integer values, - they are visible to the compiler, which can warn about (possibly) incorrect usage. There should be no functional change. --- src/PJ_aeqd.c | 14 ++++++++------ src/PJ_airy.c | 14 ++++++++------ src/PJ_aitoff.c | 17 +++++++++++------ src/PJ_gnom.c | 13 ++++++++----- src/PJ_imw_p.c | 24 +++++++++++++++--------- src/PJ_laea.c | 13 ++++++++----- src/PJ_nsper.c | 13 ++++++++----- src/PJ_ortho.c | 13 ++++++++----- src/PJ_qsc.c | 34 +++++++++++++++++++--------------- src/PJ_sconics.c | 21 ++++++++++++--------- src/PJ_stere.c | 13 ++++++++----- 11 files changed, 113 insertions(+), 76 deletions(-) (limited to 'src') diff --git a/src/PJ_aeqd.c b/src/PJ_aeqd.c index f0c813f5..aa1597e4 100644 --- a/src/PJ_aeqd.c +++ b/src/PJ_aeqd.c @@ -31,6 +31,13 @@ #include #include "projects.h" +enum Mode { + N_POLE = 0, + S_POLE = 1, + EQUIT = 2, + OBLIQ = 3, +}; + struct pj_opaque { double sinph0; double cosph0; @@ -40,7 +47,7 @@ struct pj_opaque { double Mp; double He; double G; - int mode; + enum Mode mode; struct geod_geodesic g; }; @@ -49,11 +56,6 @@ PROJ_HEAD(aeqd, "Azimuthal Equidistant") "\n\tAzi, Sph&Ell\n\tlat_0 guam"; #define EPS10 1.e-10 #define TOL 1.e-14 -#define N_POLE 0 -#define S_POLE 1 -#define EQUIT 2 -#define OBLIQ 3 - static void *destructor (PJ *P, int errlev) { /* Destructor */ if (0==P) diff --git a/src/PJ_airy.c b/src/PJ_airy.c index a5ee1f24..3b145475 100644 --- a/src/PJ_airy.c +++ b/src/PJ_airy.c @@ -34,22 +34,24 @@ PROJ_HEAD(airy, "Airy") "\n\tMisc Sph, no inv.\n\tno_cut lat_b="; +enum Mode { + N_POLE = 0, + S_POLE = 1, + EQUIT = 2, + OBLIQ = 3, +}; + struct pj_opaque { double p_halfpi; double sinph0; double cosph0; double Cb; - int mode; + enum Mode mode; int no_cut; /* do not cut at hemisphere limit */ }; # define EPS 1.e-10 -# define N_POLE 0 -# define S_POLE 1 -# define EQUIT 2 -# define OBLIQ 3 - static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ diff --git a/src/PJ_aitoff.c b/src/PJ_aitoff.c index 8e9201d0..4e2f2092 100644 --- a/src/PJ_aitoff.c +++ b/src/PJ_aitoff.c @@ -34,9 +34,14 @@ #include "projects.h" +enum Mode { + AITOFF = 0, + WINKEL_TRIPEL = 1 +}; + struct pj_opaque { double cosphi1; - int mode; + enum Mode mode; }; @@ -60,7 +65,7 @@ static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ xy.y *= d * sin(lp.phi); } else xy.x = xy.y = 0.; - if (Q->mode) { /* Winkel Tripel */ + if (Q->mode == WINKEL_TRIPEL) { xy.x = (xy.x + lp.lam * Q->cosphi1) * 0.5; xy.y = (xy.y + lp.phi) * 0.5; } @@ -112,7 +117,7 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ f1l = cp * cp * sl * sl / C + D * cp * cl * sp * sp; f2p = sp * sp * cl / C + D * sl * sl * cp; f2l = 0.5 * (sp * cp * sl / C - D * sp * cp * cp * sl * cl); - if (Q->mode) { /* Winkel Tripel */ + if (Q->mode == WINKEL_TRIPEL) { f1 = 0.5 * (f1 + lp.lam * Q->cosphi1); f2 = 0.5 * (f2 + lp.phi); f1p *= 0.5; @@ -128,7 +133,7 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, inverse */ } while ((fabs(dp) > EPSILON || fabs(dl) > EPSILON) && (iter++ < MAXITER)); if (lp.phi > M_PI_2) lp.phi -= 2.*(lp.phi-M_PI_2); /* correct if symmetrical solution for Aitoff */ if (lp.phi < -M_PI_2) lp.phi -= 2.*(lp.phi+M_PI_2); /* correct if symmetrical solution for Aitoff */ - if ((fabs(fabs(lp.phi) - M_PI_2) < EPSILON) && (!Q->mode)) lp.lam = 0.; /* if pole in Aitoff, return longitude of 0 */ + if ((fabs(fabs(lp.phi) - M_PI_2) < EPSILON) && (Q->mode == AITOFF)) lp.lam = 0.; /* if pole in Aitoff, return longitude of 0 */ /* calculate x,y coordinates with solution obtained */ if((D = acos(cos(lp.phi) * cos(C = 0.5 * lp.lam))) != 0.0) {/* Aitoff */ @@ -167,7 +172,7 @@ PJ *PROJECTION(aitoff) { return pj_default_destructor(P, ENOMEM); P->opaque = Q; - Q->mode = 0; + Q->mode = AITOFF; return setup(P); } @@ -178,7 +183,7 @@ PJ *PROJECTION(wintri) { return pj_default_destructor(P, ENOMEM); P->opaque = Q; - Q->mode = 1; + Q->mode = WINKEL_TRIPEL; if (pj_param(P->ctx, P->params, "tlat_1").i) { if ((Q->cosphi1 = cos(pj_param(P->ctx, P->params, "rlat_1").f)) == 0.) return pj_default_destructor (P, PJD_ERR_LAT_LARGER_THAN_90); diff --git a/src/PJ_gnom.c b/src/PJ_gnom.c index 2aedefec..e5822f4f 100644 --- a/src/PJ_gnom.c +++ b/src/PJ_gnom.c @@ -6,15 +6,18 @@ PROJ_HEAD(gnom, "Gnomonic") "\n\tAzi, Sph."; #define EPS10 1.e-10 -#define N_POLE 0 -#define S_POLE 1 -#define EQUIT 2 -#define OBLIQ 3 + +enum Mode { + N_POLE = 0, + S_POLE = 1, + EQUIT = 2, + OBLIQ = 3 +}; struct pj_opaque { double sinph0; double cosph0; - int mode; + enum Mode mode; }; diff --git a/src/PJ_imw_p.c b/src/PJ_imw_p.c index 29ed3457..7fd31fbb 100644 --- a/src/PJ_imw_p.c +++ b/src/PJ_imw_p.c @@ -9,11 +9,17 @@ PROJ_HEAD(imw_p, "International Map of the World Polyconic") #define TOL 1e-10 #define EPS 1e-10 +enum Mode { + NONE_IS_ZERO = 0, /* phi_1 and phi_2 != 0 */ + PHI_1_IS_ZERO = 1, /* phi_1 = 0 */ + PHI_2_IS_ZERO = -1 /* phi_2 = 0 */ +}; + struct pj_opaque { - double P, Pp, Q, Qp, R_1, R_2, sphi_1, sphi_2, C2; \ - double phi_1, phi_2, lam_1; \ - double *en; \ - int mode; /* = 0, phi_1 and phi_2 != 0, = 1, phi_1 = 0, = -1 phi_2 = 0 */ + double P, Pp, Q, Qp, R_1, R_2, sphi_1, sphi_2, C2; + double phi_1, phi_2, lam_1; + double *en; + enum Mode mode; }; @@ -53,7 +59,7 @@ static XY loc_for(LP lp, PJ *P, double *yc) { C = sqrt(R * R - xa * xa); if (lp.phi < 0.) C = - C; C += ya - R; - if (Q->mode < 0) { + if (Q->mode == PHI_2_IS_ZERO) { xb = lp.lam; yb = Q->C2; } else { @@ -61,7 +67,7 @@ static XY loc_for(LP lp, PJ *P, double *yc) { xb = Q->R_2 * sin(t); yb = Q->C2 + Q->R_2 * (1. - cos(t)); } - if (Q->mode > 0) { + if (Q->mode == PHI_1_IS_ZERO) { xc = lp.lam; *yc = 0.; } else { @@ -171,18 +177,18 @@ PJ *PROJECTION(imw_p) { else sig = 8.; Q->lam_1 = sig * DEG_TO_RAD; } - Q->mode = 0; + Q->mode = NONE_IS_ZERO; if (Q->phi_1 != 0.0) xy(P, Q->phi_1, &x1, &y1, &Q->sphi_1, &Q->R_1); else { - Q->mode = 1; + Q->mode = PHI_1_IS_ZERO; y1 = 0.; x1 = Q->lam_1; } if (Q->phi_2 != 0.0) xy(P, Q->phi_2, &x2, &T2, &Q->sphi_2, &Q->R_2); else { - Q->mode = -1; + Q->mode = PHI_2_IS_ZERO; T2 = 0.; x2 = Q->lam_1; } diff --git a/src/PJ_laea.c b/src/PJ_laea.c index 270b8dc8..0c5d5db9 100644 --- a/src/PJ_laea.c +++ b/src/PJ_laea.c @@ -5,6 +5,13 @@ PROJ_HEAD(laea, "Lambert Azimuthal Equal Area") "\n\tAzi, Sph&Ell"; +enum Mode { + N_POLE = 0, + S_POLE = 1, + EQUIT = 2, + OBLIQ = 3 +}; + struct pj_opaque { double sinb1; double cosb1; @@ -15,16 +22,12 @@ struct pj_opaque { double dd; double rq; double *apa; - int mode; + enum Mode mode; }; #define EPS10 1.e-10 #define NITER 20 #define CONV 1.e-10 -#define N_POLE 0 -#define S_POLE 1 -#define EQUIT 2 -#define OBLIQ 3 static XY e_forward (LP lp, PJ *P) { /* Ellipsoidal, forward */ XY xy = {0.0,0.0}; diff --git a/src/PJ_nsper.c b/src/PJ_nsper.c index 4975bb17..6c8ef74a 100644 --- a/src/PJ_nsper.c +++ b/src/PJ_nsper.c @@ -3,6 +3,13 @@ #include #include "projects.h" +enum Mode { + N_POLE = 0, + S_POLE = 1, + EQUIT = 2, + OBLIQ = 3 +}; + struct pj_opaque { double height; double sinph0; @@ -16,7 +23,7 @@ struct pj_opaque { double sg; double sw; double cw; - int mode; + enum Mode mode; int tilt; }; @@ -24,10 +31,6 @@ PROJ_HEAD(nsper, "Near-sided perspective") "\n\tAzi, Sph\n\th="; PROJ_HEAD(tpers, "Tilted perspective") "\n\tAzi, Sph\n\ttilt= azi= h="; # define EPS10 1.e-10 -# define N_POLE 0 -# define S_POLE 1 -# define EQUIT 2 -# define OBLIQ 3 static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ diff --git a/src/PJ_ortho.c b/src/PJ_ortho.c index 3179189b..14e228f7 100644 --- a/src/PJ_ortho.c +++ b/src/PJ_ortho.c @@ -5,17 +5,20 @@ PROJ_HEAD(ortho, "Orthographic") "\n\tAzi, Sph."; +enum Mode { + N_POLE = 0, + S_POLE = 1, + EQUIT = 2, + OBLIQ = 3 +}; + struct pj_opaque { double sinph0; double cosph0; - int mode; + enum Mode mode; }; #define EPS10 1.e-10 -#define N_POLE 0 -#define S_POLE 1 -#define EQUIT 2 -#define OBLIQ 3 static XY s_forward (LP lp, PJ *P) { /* Spheroidal, forward */ diff --git a/src/PJ_qsc.c b/src/PJ_qsc.c index f8c760a9..f30a7048 100644 --- a/src/PJ_qsc.c +++ b/src/PJ_qsc.c @@ -42,8 +42,18 @@ #include #include "projects.h" +/* The six cube faces. */ +enum Face { + FACE_FRONT = 0, + FACE_RIGHT = 1, + FACE_BACK = 2, + FACE_LEFT = 3, + FACE_TOP = 4, + FACE_BOTTOM = 5 +}; + struct pj_opaque { - int face; + enum Face face; double a_squared; double b; double one_minus_f; @@ -53,24 +63,18 @@ PROJ_HEAD(qsc, "Quadrilateralized Spherical Cube") "\n\tAzi, Sph."; #define EPS10 1.e-10 -/* The six cube faces. */ -#define FACE_FRONT 0 -#define FACE_RIGHT 1 -#define FACE_BACK 2 -#define FACE_LEFT 3 -#define FACE_TOP 4 -#define FACE_BOTTOM 5 - /* The four areas on a cube face. AREA_0 is the area of definition, * the other three areas are counted counterclockwise. */ -#define AREA_0 0 -#define AREA_1 1 -#define AREA_2 2 -#define AREA_3 3 +enum Area { + AREA_0 = 0, + AREA_1 = 1, + AREA_2 = 2, + AREA_3 = 3 +}; /* Helper function for forward projection: compute the theta angle * and determine the area number. */ -static double qsc_fwd_equat_face_theta(double phi, double y, double x, int *area) { +static double qsc_fwd_equat_face_theta(double phi, double y, double x, enum Area *area) { double theta; if (phi < EPS10) { *area = AREA_0; @@ -111,7 +115,7 @@ static XY e_forward (LP lp, PJ *P) { /* Ellipsoidal, forward */ double lat, lon; double theta, phi; double t, mu; /* nu; */ - int area; + enum Area area; /* Convert the geodetic latitude to a geocentric latitude. * This corresponds to the shift from the ellipsoid to the sphere diff --git a/src/PJ_sconics.c b/src/PJ_sconics.c index 7f6e094c..b434c430 100644 --- a/src/PJ_sconics.c +++ b/src/PJ_sconics.c @@ -4,23 +4,26 @@ #include "projects.h" +enum Type { + EULER = 0, + MURD1 = 1, + MURD2 = 2, + MURD3 = 3, + PCONIC = 4, + TISSOT = 5, + VITK1 = 6 +}; + struct pj_opaque { double n; double rho_c; double rho_0; double sig; double c1, c2; - int type; + enum Type type; }; -#define EULER 0 -#define MURD1 1 -#define MURD2 2 -#define MURD3 3 -#define PCONIC 4 -#define TISSOT 5 -#define VITK1 6 #define EPS10 1.e-10 #define EPS 1e-10 #define LINE2 "\n\tConic, Sph\n\tlat_1= and lat_2=" @@ -106,7 +109,7 @@ static LP s_inverse (XY xy, PJ *P) { /* Spheroidal, (and ellipsoidal?) inverse } -static PJ *setup(PJ *P, int type) { +static PJ *setup(PJ *P, enum Type type) { double del, cs; int err; struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); diff --git a/src/PJ_stere.c b/src/PJ_stere.c index 02b73507..500b512d 100644 --- a/src/PJ_stere.c +++ b/src/PJ_stere.c @@ -7,12 +7,19 @@ PROJ_HEAD(stere, "Stereographic") "\n\tAzi, Sph&Ell\n\tlat_ts="; PROJ_HEAD(ups, "Universal Polar Stereographic") "\n\tAzi, Sph&Ell\n\tsouth"; +enum Mode { + S_POLE = 0, + N_POLE = 1, + OBLIQ = 2, + EQUIT = 3 +}; + struct pj_opaque { double phits; double sinX1; double cosX1; double akm1; - int mode; + enum Mode mode; }; #define sinph0 P->opaque->sinX1 @@ -21,10 +28,6 @@ struct pj_opaque { #define TOL 1.e-8 #define NITER 8 #define CONV 1.e-10 -#define S_POLE 0 -#define N_POLE 1 -#define OBLIQ 2 -#define EQUIT 3 static double ssfn_ (double phit, double sinphi, double eccen) { sinphi *= eccen; -- cgit v1.2.3 From dcd95c505ef188f268671495f7a9950c446d0e72 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Tue, 7 Nov 2017 14:06:05 +0100 Subject: Formally change the initialization type of the TRANSFORMATIONS and CONVERSIONS that are not PROJECTIONS --- src/PJ_axisswap.c | 2 +- src/PJ_cart.c | 4 ++-- src/PJ_deformation.c | 2 +- src/PJ_hgridshift.c | 2 +- src/PJ_molodensky.c | 2 +- src/PJ_unitconvert.c | 2 +- src/PJ_vgridshift.c | 2 +- 7 files changed, 8 insertions(+), 8 deletions(-) (limited to 'src') diff --git a/src/PJ_axisswap.c b/src/PJ_axisswap.c index 84b48afe..7215b9ce 100644 --- a/src/PJ_axisswap.c +++ b/src/PJ_axisswap.c @@ -156,7 +156,7 @@ static PJ_COORD reverse_4d(PJ_COORD coo, PJ *P) { /***********************************************************************/ -PJ *PROJECTION(axisswap) { +PJ *CONVERSION(axisswap,0) { /***********************************************************************/ struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); char *order, *s; diff --git a/src/PJ_cart.c b/src/PJ_cart.c index f5d5a062..d8f4a9b9 100644 --- a/src/PJ_cart.c +++ b/src/PJ_cart.c @@ -42,7 +42,7 @@ #define PJ_LIB__ #include "proj_internal.h" -#include +#include "projects.h" #include #include #include @@ -208,7 +208,7 @@ static LP cart_reverse (XY xy, PJ *P) { /*********************************************************************/ -PJ *PROJECTION(cart) { +PJ *CONVERSION(cart,1) { /*********************************************************************/ P->fwd3d = cartesian; P->inv3d = geodetic; diff --git a/src/PJ_deformation.c b/src/PJ_deformation.c index 74862efc..62a24683 100644 --- a/src/PJ_deformation.c +++ b/src/PJ_deformation.c @@ -222,7 +222,7 @@ static void *destructor(PJ *P, int errlev) { } -PJ *PROJECTION(deformation) { +PJ *TRANSFORMATION(deformation,1) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) return pj_default_destructor(P, ENOMEM); diff --git a/src/PJ_hgridshift.c b/src/PJ_hgridshift.c index 83680a45..26a2f471 100644 --- a/src/PJ_hgridshift.c +++ b/src/PJ_hgridshift.c @@ -45,7 +45,7 @@ static PJ_COORD reverse_4d (PJ_COORD obs, PJ *P) { -PJ *PROJECTION(hgridshift) { +PJ *TRANSFORMATION(hgridshift,0) { P->fwd4d = forward_4d; P->inv4d = reverse_4d; diff --git a/src/PJ_molodensky.c b/src/PJ_molodensky.c index 10ba3fb7..a35cabe4 100644 --- a/src/PJ_molodensky.c +++ b/src/PJ_molodensky.c @@ -268,7 +268,7 @@ static PJ_COORD reverse_4d(PJ_COORD obs, PJ *P) { } -PJ *PROJECTION(molodensky) { +PJ *TRANSFORMATION(molodensky,1) { struct pj_opaque_molodensky *Q = pj_calloc(1, sizeof(struct pj_opaque_molodensky)); if (0==Q) return pj_default_destructor(P, ENOMEM); diff --git a/src/PJ_unitconvert.c b/src/PJ_unitconvert.c index d8901ee0..3a70903c 100644 --- a/src/PJ_unitconvert.c +++ b/src/PJ_unitconvert.c @@ -306,7 +306,7 @@ static PJ_COORD reverse_4d(PJ_COORD obs, PJ *P) { /***********************************************************************/ -PJ *PROJECTION(unitconvert) { +PJ *CONVERSION(unitconvert,0) { /***********************************************************************/ struct pj_opaque_unitconvert *Q = pj_calloc (1, sizeof (struct pj_opaque_unitconvert)); char *s, *name; diff --git a/src/PJ_vgridshift.c b/src/PJ_vgridshift.c index 9db0b332..e3f3cbd3 100644 --- a/src/PJ_vgridshift.c +++ b/src/PJ_vgridshift.c @@ -46,7 +46,7 @@ static PJ_COORD reverse_4d(PJ_COORD obs, PJ *P) { } -PJ *PROJECTION(vgridshift) { +PJ *TRANSFORMATION(vgridshift,0) { if (!pj_param(P->ctx, P->params, "tgrids").i) { proj_log_error(P, "vgridshift: +grids parameter missing."); -- cgit v1.2.3 From bf673102bc86b241976df0d90f8ca1b40880b500 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Tue, 7 Nov 2017 20:40:55 +0100 Subject: Fix misleading indent. Newer GCC's chokes on this when compiling with -Wall. --- src/gie.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/gie.c b/src/gie.c index f874ee93..2bca2f66 100644 --- a/src/gie.c +++ b/src/gie.c @@ -372,7 +372,7 @@ static int banner (char *args) { printf ("\n\n"); if (strlen(args) > 70) thedots = dots; - fprintf (T.fout, "%s%-70.70s%s\n", delim, args, thedots); + fprintf (T.fout, "%s%-70.70s%s\n", delim, args, thedots); return 0; } -- cgit v1.2.3 From 3ff9899dd4407877ace4daf2794cb759ccdbc235 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Wed, 8 Nov 2017 03:30:20 +0100 Subject: Improved IO predicates (#648) * enter proj_angular_input and proj_angular_output, exit proj_angular_left and proj_angular_right * remove unused variable 'unit' * In gie: remove unused func 'torad_if_needed', and add static keyword where needed * In gie: add some comments --- src/PJ_cart.c | 57 ++++++++++++++ src/cct.c | 9 +-- src/gie.c | 216 ++++++++++++++++++++++++++++++++---------------------- src/proj.def | 4 +- src/proj.h | 5 +- src/proj_4D_api.c | 31 +++++--- 6 files changed, 215 insertions(+), 107 deletions(-) (limited to 'src') 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..0a344043 100644 --- a/src/gie.c +++ b/src/gie.c @@ -421,7 +421,13 @@ 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) { @@ -445,38 +451,44 @@ static int operation (char *args) { } -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,7 +496,12 @@ 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; @@ -512,84 +529,99 @@ static int roundtrip (char *args) { 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) { + T.op_ko++; + T.total_ko++; - 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) { + 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; +} - 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; + + 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); + + T.op_ok++; + T.total_ok++; - 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 +635,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..07208698 100644 --- a/src/proj_4D_api.c +++ b/src/proj_4D_api.c @@ -44,14 +44,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 +91,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 +120,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); -- cgit v1.2.3 From 70550ae21c653cceefc2142fa89d0fb6c99101d9 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Wed, 8 Nov 2017 12:41:09 +0100 Subject: minor clean ups in and around proj_4D_api (#649) --- src/proj_4D_api.c | 24 +++++++++++++----------- src/proj_internal.h | 8 +++++++- src/projects.h | 2 ++ 3 files changed, 22 insertions(+), 12 deletions(-) (limited to 'src') diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c index 07208698..aa076f0f 100644 --- a/src/proj_4D_api.c +++ b/src/proj_4D_api.c @@ -294,27 +294,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) 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 fad5c7bc..a43826d2 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; -- cgit v1.2.3 From 634184850a85145f20147c84f5a02fcd6df185a2 Mon Sep 17 00:00:00 2001 From: Aaron Puchert Date: Fri, 10 Nov 2017 00:04:27 +0100 Subject: Ensure C89 compliance and enable more warnings (#650) * Ensure C89 compliance and enable more warnings According to the contributing guidelines, the library is developed strictly in ANSI C 89. However, this is not enforced. Additionally, we enable more warnings: apart from -Wall and -Wextra we enable a warning that makes sure all enumeration values are covered in a switch statement. When compiling with Clang, we also turn on the warnings -Wc99-extensions and -Wc11-extensions. * Enable all warnings that are used on Travis This makes it easier to notice problems before pushing. --- src/PJ_aeqd.c | 2 +- src/PJ_airy.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src') 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 { -- cgit v1.2.3 From 98dd8d5b6c0f24b8e2be1a8e77e4dfac72a2dc50 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Fri, 10 Nov 2017 13:55:12 +0100 Subject: Do not require needless plusses (#651) proj_create is now indifferent whether or not proj definition terms start with a '+' character. Also, improve gie to support testing this. --- src/gie.c | 40 ++++++++++++++----------- src/proj_4D_api.c | 90 +++++++++++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 108 insertions(+), 22 deletions(-) (limited to 'src') diff --git a/src/gie.c b/src/gie.c index 0a344043..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) { @@ -434,19 +443,18 @@ static int operation (char *args) { 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; } @@ -505,6 +513,8 @@ static int roundtrip (char *args) { 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); @@ -518,20 +528,16 @@ 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_message (double d, char *args) { - T.op_ko++; - T.total_ko++; + another_failure (); if (T.verbosity < 0) return 1; @@ -554,8 +560,7 @@ static int expect_message (double d, char *args) { } static int expect_message_cannot_parse (char *args) { - T.op_ko++; - T.total_ko++; + another_failure (); if (T.verbosity > -1) { if (0==T.op_ko && T.verbosity < 2) banner (T.operation); @@ -573,6 +578,8 @@ static int expect (char *args) { ******************************************************************************/ 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]) @@ -609,8 +616,7 @@ static int expect (char *args) { if (d > T.tolerance) return expect_message (d, args); - T.op_ok++; - T.total_ok++; + another_success (); return 0; } diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c index aa076f0f..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 +#include +#include #include #include "proj_internal.h" #include "projects.h" #include "geodesic.h" -#include -#include /* Initialize PJ_COORD struct */ @@ -330,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) { /****************************************************************************** @@ -461,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 (); } -- cgit v1.2.3 From e09999127da8dea56d9af52bc346cf7cc6613547 Mon Sep 17 00:00:00 2001 From: Kristian Evers Date: Tue, 7 Nov 2017 20:45:43 +0100 Subject: Use HAVE_C99_MATH instead of _WIN32_ and __ANSI__ HAVE_C99_MATH was recently added to the build system as a safer way to determine if non-ansi math functions are available on the current system. Previously different combinations of tests including _WIN32_ and __ANSI__ have been in use, but cases where that strategy has failed is known. Hence this change to a hopefully more robust check of math function availability. --- src/projects.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src') diff --git a/src/projects.h b/src/projects.h index fad5c7bc..9ff24f71 100644 --- a/src/projects.h +++ b/src/projects.h @@ -84,7 +84,7 @@ extern "C" { #endif /* prototype hypot for systems where absent */ -#if !defined(_WIN32) || !defined(__ANSI__) +#if !(defined(HAVE_C99_MATH) && HAVE_C99_MATH) extern double hypot(double, double); #endif -- cgit v1.2.3 From d53581ab6840713e4cb24c6f735cf04e9ce0b2db Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 11 Nov 2017 22:20:51 +0100 Subject: Fix various memory leaks. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3573 , https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3643 and https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3641 . Credit to OSS Fuzz --- src/PJ_aea.c | 1 + src/pj_init.c | 5 ++++- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'src') diff --git a/src/PJ_aea.c b/src/PJ_aea.c index 5e8e3333..f48d2e9b 100644 --- a/src/PJ_aea.c +++ b/src/PJ_aea.c @@ -211,6 +211,7 @@ PJ *PROJECTION(leac) { if (0==Q) return pj_default_destructor (P, ENOMEM); P->opaque = Q; + P->destructor = destructor; Q->phi2 = pj_param(P->ctx, P->params, "rlat_1").f; Q->phi1 = pj_param(P->ctx, P->params, "bsouth").i ? - M_HALFPI: M_HALFPI; diff --git a/src/pj_init.c b/src/pj_init.c index f69d9eae..534f0827 100644 --- a/src/pj_init.c +++ b/src/pj_init.c @@ -500,7 +500,7 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { /* find projection selection */ if (!(name = pj_param(ctx, start, "sproj").s)) - return pj_default_destructor (PIN, PJD_ERR_PROJ_NOT_NAMED); + return pj_dealloc_params (ctx, start, PJD_ERR_PROJ_NOT_NAMED); for (i = 0; (s = pj_list[i].id) && strcmp(name, s) ; ++i) ; if (!s) @@ -693,7 +693,10 @@ pj_init_ctx(projCtx ctx, int argc, char **argv) { /* projection specific initialization */ PIN = proj(PIN); if ((0==PIN) || ctx->last_errno) + { + pj_free(PIN); return 0; + } return PIN; } -- cgit v1.2.3 From fd1700e493b7caf2d028d35c86e54935b5f255dc Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 11 Nov 2017 22:31:24 +0100 Subject: PJ_ob_tran: avoid null pointer dereference when underling fwd method is NULL. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3645. Credit to OSS Fuzz --- src/PJ_ob_tran.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/PJ_ob_tran.c b/src/PJ_ob_tran.c index 4f064809..61724202 100644 --- a/src/PJ_ob_tran.c +++ b/src/PJ_ob_tran.c @@ -228,10 +228,10 @@ PJ *PROJECTION(ob_tran) { if (fabs(phip) > TOL) { /* oblique */ Q->cphip = cos(phip); Q->sphip = sin(phip); - P->fwd = o_forward; + P->fwd = Q->link->fwd ? o_forward : 0; P->inv = Q->link->inv ? o_inverse : 0; } else { /* transverse */ - P->fwd = t_forward; + P->fwd = Q->link->fwd ? t_forward : 0; P->inv = Q->link->inv ? t_inverse : 0; } -- cgit v1.2.3 From 451dec5d82c01dcdc20cc954ed834a8042686f84 Mon Sep 17 00:00:00 2001 From: Even Rouault Date: Sat, 11 Nov 2017 22:44:26 +0100 Subject: pj_apply_gridshift_3(): avoid illegal read access with point outside any grid area. Fixes https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=3960. Credit to OSS Fuzz. master only --- src/pj_apply_gridshift.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) (limited to 'src') diff --git a/src/pj_apply_gridshift.c b/src/pj_apply_gridshift.c index 7d9ac94b..a2267cbd 100644 --- a/src/pj_apply_gridshift.c +++ b/src/pj_apply_gridshift.c @@ -112,16 +112,14 @@ int pj_apply_gridshift_2( PJ *defn, int inverse, static struct CTABLE* find_ctable(projCtx ctx, LP input, int grid_count, PJ_GRIDINFO **tables) { int itable; - double epsilon; - struct CTABLE *ct = NULL; /* keep trying till we find a table that works */ for( itable = 0; itable < grid_count; itable++ ) { PJ_GRIDINFO *gi = tables[itable]; - ct = gi->ct; - epsilon = (fabs(ct->del.phi)+fabs(ct->del.lam))/10000.0; + struct CTABLE *ct = gi->ct; + double epsilon = (fabs(ct->del.phi)+fabs(ct->del.lam))/10000.0; /* skip tables that don't match our point at all. */ if ( ct->ll.phi - epsilon > input.phi || ct->ll.lam - epsilon > input.lam @@ -164,9 +162,10 @@ static struct CTABLE* find_ctable(projCtx ctx, LP input, int grid_count, PJ_GRID } } /* if we get this far we have found a suitable grid */ - break; + return ct; } - return ct; + + return NULL; } /************************************************************************/ @@ -204,7 +203,10 @@ int pj_apply_gridshift_3( projCtx ctx, PJ_GRIDINFO **tables, int grid_count, output.lam = HUGE_VAL; ct = find_ctable(ctx, input, grid_count, tables); - output = nad_cvt( input, inverse, ct ); + if( ct != NULL ) + { + output = nad_cvt( input, inverse, ct ); + } if ( output.lam != HUGE_VAL && debug_count++ < 20 ) pj_log( ctx, PJ_LOG_DEBUG_MINOR, "pj_apply_gridshift(): used %s", ct->id ); -- cgit v1.2.3 From 5b0b6cb8d477a39f3f59a38d0a1968cc9ac9f847 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Sun, 12 Nov 2017 05:09:03 +0100 Subject: Remove selftests from projection files starting with h, i, j, k --- src/PJ_hammer.c | 44 +------------------- src/PJ_hatano.c | 52 +----------------------- src/PJ_healpix.c | 119 +------------------------------------------------------ src/PJ_igh.c | 44 +------------------- src/PJ_imw_p.c | 44 +------------------- src/PJ_isea.c | 30 +------------- src/PJ_krovak.c | 44 +------------------- 7 files changed, 8 insertions(+), 369 deletions(-) (limited to 'src') diff --git a/src/PJ_hammer.c b/src/PJ_hammer.c index c18c9a69..443ce247 100644 --- a/src/PJ_hammer.c +++ b/src/PJ_hammer.c @@ -72,46 +72,4 @@ PJ *PROJECTION(hammer) { } -#ifndef PJ_SELFTEST -int pj_hammer_selftest (void) {return 0;} -#else - -int pj_hammer_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=hammer +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223373.78870324057, 111703.90739776699}, - { 223373.78870324057, -111703.90739776699}, - {-223373.78870324057, 111703.90739776699}, - {-223373.78870324057, -111703.90739776699}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.001790493109965961, 0.00089524655487369749}, - { 0.001790493109965961, -0.00089524655487369749}, - {-0.001790493109965961, 0.00089524655487369749}, - {-0.001790493109965961, -0.00089524655487369749}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_hammer_selftest (void) {return 10000;} diff --git a/src/PJ_hatano.c b/src/PJ_hatano.c index be95fe73..ea4bacf8 100644 --- a/src/PJ_hatano.c +++ b/src/PJ_hatano.c @@ -79,54 +79,4 @@ PJ *PROJECTION(hatano) { return P; } -#ifndef PJ_SELFTEST -int pj_hatano_selftest (void) {return 0;} -#else - -int pj_hatano_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=hatano +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 189878.87894652804, 131409.8024406255 -}, - { 189881.08195244463, -131409.14227607418 -}, - {-189878.87894652804, 131409.8024406255 -}, - {-189881.08195244463, -131409.14227607418 -}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0021064624821817597, 0.00076095689425791926 -}, - { 0.0021064624821676096, -0.00076095777439265377 -}, - {-0.0021064624821817597, 0.00076095689425791926 -}, - {-0.0021064624821676096, -0.00076095777439265377 -}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_hatano_selftest (void) {return 10000;} diff --git a/src/PJ_healpix.c b/src/PJ_healpix.c index 438cb595..2d2af805 100644 --- a/src/PJ_healpix.c +++ b/src/PJ_healpix.c @@ -669,120 +669,5 @@ PJ *PROJECTION(rhealpix) { } -#ifndef PJ_SELFTEST -int pj_healpix_selftest (void) {return 0;} -#else - -int pj_healpix_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=healpix +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=healpix +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222390.10394923863, 130406.58866448226}, - { 222390.10394923863, -130406.58866448054}, - {-222390.10394923863, 130406.58866448226}, - {-222390.10394923863, -130406.58866448054}, - }; - - XY s_fwd_expect[] = { - { 223402.14425527418, 131588.04444199943}, - { 223402.14425527418, -131588.04444199943}, - {-223402.14425527418, 131588.04444199943}, - {-223402.14425527418, -131588.04444199943}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017986411845524453, 0.00076679453057823619}, - { 0.0017986411845524453, -0.00076679453057823619}, - {-0.0017986411845524453, 0.00076679453057823619}, - {-0.0017986411845524453, -0.00076679453057823619}, - }; - - LP s_inv_expect[] = { - { 0.0017904931097838226, 0.00075990887733981202}, - { 0.0017904931097838226, -0.00075990887733981202}, - {-0.0017904931097838226, 0.00075990887733981202}, - {-0.0017904931097838226, -0.00075990887733981202}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif - -#ifndef PJ_SELFTEST -int pj_rhealpix_selftest (void) {return 0;} -#else - -int pj_rhealpix_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=rhealpix +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=rhealpix +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222390.10394923863, 130406.58866448226}, - { 222390.10394923863, -130406.58866448054}, - {-222390.10394923863, 130406.58866448226}, - {-222390.10394923863, -130406.58866448054}, - }; - - XY s_fwd_expect[] = { - { 223402.14425527418, 131588.04444199943}, - { 223402.14425527418, -131588.04444199943}, - {-223402.14425527418, 131588.04444199943}, - {-223402.14425527418, -131588.04444199943}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017986411845524453, 0.00076679453057823619}, - { 0.0017986411845524453, -0.00076679453057823619}, - {-0.0017986411845524453, 0.00076679453057823619}, - {-0.0017986411845524453, -0.00076679453057823619}, - }; - - LP s_inv_expect[] = { - { 0.0017904931097838226, 0.00075990887733981202}, - { 0.0017904931097838226, -0.00075990887733981202}, - {-0.0017904931097838226, 0.00075990887733981202}, - {-0.0017904931097838226, -0.00075990887733981202}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_healpix_selftest (void) {return 10000;} +int pj_rhealpix_selftest (void) {return 10000;} diff --git a/src/PJ_igh.c b/src/PJ_igh.c index 33cdde22..01cfa246 100644 --- a/src/PJ_igh.c +++ b/src/PJ_igh.c @@ -222,46 +222,4 @@ PJ *PROJECTION(igh) { } -#ifndef PJ_SELFTEST -int pj_igh_selftest (void) {return 0;} -#else - -int pj_igh_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=igh +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223878.49745627123, 111701.07212763709}, - { 223708.37131305804, -111701.07212763709}, - {-222857.74059699223, 111701.07212763709}, - {-223027.86674020503, -111701.07212763709}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.001790489447892545, 0.00089524655489191132}, - { 0.0017904906685957927, -0.00089524655489191132}, - {-0.001790496772112032, 0.00089524655489191132}, - {-0.0017904955514087843, -0.00089524655489191132}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_igh_selftest (void) {return 10000;} diff --git a/src/PJ_imw_p.c b/src/PJ_imw_p.c index 7fd31fbb..f0c88efb 100644 --- a/src/PJ_imw_p.c +++ b/src/PJ_imw_p.c @@ -212,46 +212,4 @@ PJ *PROJECTION(imw_p) { } -#ifndef PJ_SELFTEST -int pj_imw_p_selftest (void) {return 0;} -#else - -int pj_imw_p_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=imw_p +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222588.4411393762, 55321.128653809537}, - { 222756.90637768712, -165827.58428832365}, - {-222588.4411393762, 55321.128653809537}, - {-222756.90637768712, -165827.58428832365}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017966991379592214, 0.50090492361427374}, - { 0.0017966979081574697, 0.49909507588689922}, - {-0.0017966991379592214, 0.50090492361427374}, - {-0.0017966979081574697, 0.49909507588689922}, - }; - - return pj_generic_selftest (e_args, 0, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, 0, inv_in, e_inv_expect, 0); -} - - -#endif +int pj_imw_p_selftest (void) {return 10000;} diff --git a/src/PJ_isea.c b/src/PJ_isea.c index 223d8f28..72c34744 100644 --- a/src/PJ_isea.c +++ b/src/PJ_isea.c @@ -1148,32 +1148,4 @@ PJ *PROJECTION(isea) { } -#ifndef PJ_SELFTEST -int pj_isea_selftest (void) {return 0;} -#else - -int pj_isea_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=isea +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {-1097074.9480224741, 3442909.3090371834}, - {-1097074.9482647954, 3233611.7285857084}, - {-1575486.3536415542, 3442168.3420281881}, - {-1575486.353880283, 3234352.6955947056}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif +int pj_isea_selftest (void) {return 10000;} diff --git a/src/PJ_krovak.c b/src/PJ_krovak.c index 640ce07f..929a2a6d 100644 --- a/src/PJ_krovak.c +++ b/src/PJ_krovak.c @@ -220,46 +220,4 @@ PJ *PROJECTION(krovak) { } -#ifndef PJ_SELFTEST -int pj_krovak_selftest (void) {return 0;} -#else - -int pj_krovak_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=krovak +ellps=GRS80 +no_defs"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {-3196535.2325636409, -6617878.8675514441}, - {-3260035.4405521089, -6898873.6148780314}, - {-3756305.3288691747, -6478142.5615715114}, - {-3831703.6585019818, -6759107.1701553948}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {24.836218918719162, 59.758403933233858}, - {24.836315484509566, 59.756888425730189}, - {24.830447747947495, 59.758403933233858}, - {24.830351182157091, 59.756888425730189}, - }; - - return pj_generic_selftest (e_args, 0, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, 0, inv_in, e_inv_expect, 0); -} - - -#endif +int pj_krovak_selftest (void) {return 10000;} -- cgit v1.2.3 From 48e476b968ce7cc90234b529d6af1265902be623 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Sun, 12 Nov 2017 05:27:30 +0100 Subject: Remove selftests from projection files starting with l, m --- src/PJ_labrd.c | 44 +--------- src/PJ_laea.c | 59 +------------ src/PJ_lagrng.c | 30 +------ src/PJ_larr.c | 30 +------ src/PJ_lask.c | 30 +------ src/PJ_latlong.c | 8 +- src/PJ_lcc.c | 44 +--------- src/PJ_lcca.c | 44 +--------- src/PJ_loxim.c | 44 +--------- src/PJ_lsat.c | 44 +--------- src/PJ_mbt_fps.c | 44 +--------- src/PJ_mbtfpp.c | 44 +--------- src/PJ_mbtfpq.c | 44 +--------- src/PJ_merc.c | 59 +------------ src/PJ_mill.c | 44 +--------- src/PJ_misrsom.c | 59 +------------ src/PJ_mod_ster.c | 257 ++---------------------------------------------------- src/PJ_moll.c | 138 +---------------------------- 18 files changed, 27 insertions(+), 1039 deletions(-) (limited to 'src') diff --git a/src/PJ_labrd.c b/src/PJ_labrd.c index 4b5d93a5..7db03249 100644 --- a/src/PJ_labrd.c +++ b/src/PJ_labrd.c @@ -129,46 +129,4 @@ PJ *PROJECTION(labrd) { } -#ifndef PJ_SELFTEST -int pj_labrd_selftest (void) {return 0;} -#else - -int pj_labrd_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=labrd +ellps=GRS80 +lon_0=0.5 +lat_0=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 166973.166090228391, -110536.912730266107}, - { 166973.168287157256, -331761.993650884193}, - {-278345.500519976194, -110469.032642031714}, - {-278345.504185269645, -331829.870790275279}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.501797719349373672, 2.00090435742047923}, - {0.501797717380853658, 1.99909564058898681}, - {0.498202280650626328, 2.00090435742047923}, - {0.498202282619146342, 1.99909564058898681}, - }; - - return pj_generic_selftest (e_args, 0, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, 0, inv_in, e_inv_expect, 0); -} - - -#endif +int pj_labrd_selftest (void) {return 10000;} diff --git a/src/PJ_laea.c b/src/PJ_laea.c index 0c5d5db9..5cf5f5cd 100644 --- a/src/PJ_laea.c +++ b/src/PJ_laea.c @@ -296,61 +296,4 @@ PJ *PROJECTION(laea) { } -#ifndef PJ_SELFTEST -int pj_laea_selftest (void) {return 0;} -#else - -int pj_laea_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=laea +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=laea +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222602.471450095181, 110589.82722441027}, - { 222602.471450095181, -110589.827224408786}, - {-222602.471450095181, 110589.82722441027}, - {-222602.471450095181, -110589.827224408786}, - }; - - XY s_fwd_expect[] = { - { 223365.281370124663, 111716.668072915665}, - { 223365.281370124663, -111716.668072915665}, - {-223365.281370124663, 111716.668072915665}, - {-223365.281370124663, -111716.668072915665}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.00179663056847900867, 0.000904369475966495845}, - { 0.00179663056847900867, -0.000904369475966495845}, - {-0.00179663056847900867, 0.000904369475966495845}, - {-0.00179663056847900867, -0.000904369475966495845}, - }; - - LP s_inv_expect[] = { - { 0.00179049311002060264, 0.000895246554791735271}, - { 0.00179049311002060264, -0.000895246554791735271}, - {-0.00179049311002060264, 0.000895246554791735271}, - {-0.00179049311002060264, -0.000895246554791735271}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_laea_selftest (void) {return 10000;} diff --git a/src/PJ_lagrng.c b/src/PJ_lagrng.c index e30f6a36..584f9a7a 100644 --- a/src/PJ_lagrng.c +++ b/src/PJ_lagrng.c @@ -62,32 +62,4 @@ PJ *PROJECTION(lagrng) { } -#ifndef PJ_SELFTEST -int pj_lagrng_selftest (void) {return 0;} -#else - -int pj_lagrng_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=lagrng +a=6400000 +W=2 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 111703.37591722561, 27929.8319080333386}, - { 111699.122088816002, -83784.1780133577704}, - {-111703.37591722561, 27929.8319080333386}, - {-111699.122088816002, -83784.1780133577704}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif +int pj_lagrng_selftest (void) {return 10000;} diff --git a/src/PJ_larr.c b/src/PJ_larr.c index cd6e6c8a..dc791ba0 100644 --- a/src/PJ_larr.c +++ b/src/PJ_larr.c @@ -25,32 +25,4 @@ PJ *PROJECTION(larr) { } -#ifndef PJ_SELFTEST -int pj_larr_selftest (void) {return 0;} -#else - -int pj_larr_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=larr +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {223393.637624200899, 111707.215961255497}, - {223393.637624200899, -111707.215961255497}, - {-223393.637624200899, 111707.215961255497}, - {-223393.637624200899, -111707.215961255497}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif +int pj_larr_selftest (void) {return 10000;} diff --git a/src/PJ_lask.c b/src/PJ_lask.c index d0efeb7d..998b3bbe 100644 --- a/src/PJ_lask.c +++ b/src/PJ_lask.c @@ -37,32 +37,4 @@ PJ *PROJECTION(lask) { return P; } -#ifndef PJ_SELFTEST -int pj_lask_selftest (void) {return 0;} -#else - -int pj_lask_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=lask +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 217928.275907355128, 112144.32922014239}, - { 217928.275907355128, -112144.32922014239}, - {-217928.275907355128, 112144.32922014239}, - {-217928.275907355128, -112144.32922014239}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif +int pj_lask_selftest (void) {return 10000;} diff --git a/src/PJ_latlong.c b/src/PJ_latlong.c index 35c573aa..612bef78 100644 --- a/src/PJ_latlong.c +++ b/src/PJ_latlong.c @@ -131,7 +131,7 @@ PJ *PROJECTION(lonlat) { * * The code should be covered by the tests in nad/. * */ -int pj_latlong_selftest (void) {return 0;} -int pj_longlat_selftest (void) {return 0;} -int pj_latlon_selftest (void) {return 0;} -int pj_lonlat_selftest (void) {return 0;} +int pj_latlong_selftest (void) {return 10000;} +int pj_longlat_selftest (void) {return 10000;} +int pj_latlon_selftest (void) {return 10000;} +int pj_lonlat_selftest (void) {return 10000;} diff --git a/src/PJ_lcc.c b/src/PJ_lcc.c index 78c227b8..4a392690 100644 --- a/src/PJ_lcc.c +++ b/src/PJ_lcc.c @@ -145,46 +145,4 @@ PJ *PROJECTION(lcc) { } -#ifndef PJ_SELFTEST -int pj_lcc_selftest (void) {return 0;} -#else - -int pj_lcc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=lcc +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222588.439735968423, 110660.533870799671}, - { 222756.879700278747, -110532.797660827026}, - {-222588.439735968423, 110660.533870799671}, - {-222756.879700278747, -110532.797660827026}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.00179635940600536667, 0.000904232207322381741}, - { 0.00179635817735249777, -0.000904233135128348995}, - {-0.00179635940600536667, 0.000904232207322381741}, - {-0.00179635817735249777, -0.000904233135128348995}, - }; - - return pj_generic_selftest (e_args, 0, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, 0, inv_in, e_inv_expect, 0); -} - - -#endif +int pj_lcc_selftest (void) {return 10000;} diff --git a/src/PJ_lcca.c b/src/PJ_lcca.c index cf1aa83f..6aa33c4f 100644 --- a/src/PJ_lcca.c +++ b/src/PJ_lcca.c @@ -160,46 +160,4 @@ PJ *PROJECTION(lcca) { -#ifndef PJ_SELFTEST -int pj_lcca_selftest (void) {return 0;} -#else - -int pj_lcca_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=lcca +ellps=GRS80 +lat_0=1 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222605.285770237417, 67.8060072715846616}, - { 222740.037637936533, -221125.539829601563}, - {-222605.285770237417, 67.8060072715846616}, - {-222740.037637936533, -221125.539829601563}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.00179690290525662526, 1.00090436621350798}, - { 0.00179690192174008037, 0.999095632791497268}, - {-0.00179690290525662526, 1.00090436621350798}, - {-0.00179690192174008037, 0.999095632791497268}, - }; - - return pj_generic_selftest (e_args, 0, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, 0, inv_in, e_inv_expect, 0); -} - - -#endif +int pj_lcca_selftest (void) {return 10000;} diff --git a/src/PJ_loxim.c b/src/PJ_loxim.c index a4ae074b..2b3e922d 100644 --- a/src/PJ_loxim.c +++ b/src/PJ_loxim.c @@ -72,46 +72,4 @@ PJ *PROJECTION(loxim) { } -#ifndef PJ_SELFTEST -int pj_loxim_selftest (void) {return 0;} -#else - -int pj_loxim_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=loxim +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223382.295791338867, 55850.5360638185448}, - { 223393.637462243292, -167551.608191455656}, - {-223382.295791338867, 55850.5360638185448}, - {-223393.637462243292, -167551.608191455656}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00179056141104335601, 0.500895246554891926}, - { 0.00179056116683692576, 0.499104753445108074}, - {-0.00179056141104335601, 0.500895246554891926}, - {-0.00179056116683692576, 0.499104753445108074}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_loxim_selftest (void) {return 10000;} diff --git a/src/PJ_lsat.c b/src/PJ_lsat.c index 7319bee7..b3c36fe8 100644 --- a/src/PJ_lsat.c +++ b/src/PJ_lsat.c @@ -209,46 +209,4 @@ PJ *PROJECTION(lsat) { } -#ifndef PJ_SELFTEST -int pj_lsat_selftest (void) {return 0;} -#else - -int pj_lsat_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=lsat +ellps=GRS80 +lat_1=0.5 +lat_2=2 +lsat=1 +path=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {18241950.01455855, 9998256.83982293494}, - {18746856.2533194572, 10215761.669925211}, - {18565503.6836331636, 9085039.14672705345}, - {19019696.9020289108, 9247763.0394328218}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {126.000423834530011, 0.00172378224025701425}, - {126.002213738256714, 0.00188015467480917966}, - {126.000734468914601, -0.00188015467480917966}, - {126.002524372641304, -0.00172378224025701425}, - }; - - return pj_generic_selftest (e_args, 0, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, 0, inv_in, e_inv_expect, 0); -} - - -#endif +int pj_lsat_selftest (void) {return 10000;} diff --git a/src/PJ_mbt_fps.c b/src/PJ_mbt_fps.c index c35da04c..6499249c 100644 --- a/src/PJ_mbt_fps.c +++ b/src/PJ_mbt_fps.c @@ -53,46 +53,4 @@ PJ *PROJECTION(mbt_fps) { return P; } -#ifndef PJ_SELFTEST -int pj_mbt_fps_selftest (void) {return 0;} -#else - -int pj_mbt_fps_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=mbt_fps +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 198798.176129849948, 125512.017254530627}, - { 198798.176129849948, -125512.017254530627}, - {-198798.176129849948, 125512.017254530627}, - {-198798.176129849948, -125512.017254530627}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00201197086238270742, 0.000796711850174446003}, - { 0.00201197086238270742, -0.000796711850174446003}, - {-0.00201197086238270742, 0.000796711850174446003}, - {-0.00201197086238270742, -0.000796711850174446003}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_mbt_fps_selftest (void) {return 10000;} diff --git a/src/PJ_mbtfpp.c b/src/PJ_mbtfpp.c index 2bbb16b1..61254859 100644 --- a/src/PJ_mbtfpp.c +++ b/src/PJ_mbtfpp.c @@ -61,46 +61,4 @@ PJ *PROJECTION(mbtfpp) { return P; } -#ifndef PJ_SELFTEST -int pj_mbtfpp_selftest (void) {return 0;} -#else - -int pj_mbtfpp_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=mbtfpp +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {206804.786929820373, 120649.762565792524}, - {206804.786929820373, -120649.762565792524}, - {-206804.786929820373, 120649.762565792524}, - {-206804.786929820373, -120649.762565792524}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {0.00193395359462902698, 0.00082883725477665357}, - {0.00193395359462902698, -0.00082883725477665357}, - {-0.00193395359462902698, 0.00082883725477665357}, - {-0.00193395359462902698, -0.00082883725477665357}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_mbtfpp_selftest (void) {return 10000;} diff --git a/src/PJ_mbtfpq.c b/src/PJ_mbtfpq.c index 4901401e..a3743b59 100644 --- a/src/PJ_mbtfpq.c +++ b/src/PJ_mbtfpq.c @@ -70,46 +70,4 @@ PJ *PROJECTION(mbtfpq) { return P; } -#ifndef PJ_SELFTEST -int pj_mbtfpq_selftest (void) {return 0;} -#else - -int pj_mbtfpq_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=mbtfpq +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 209391.854738393013, 119161.040199054827}, - { 209391.854738393013, -119161.040199054827}, - {-209391.854738393013, 119161.040199054827}, - {-209391.854738393013, -119161.040199054827}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00191010555824111571, 0.000839185447792341723}, - { 0.00191010555824111571, -0.000839185447792341723}, - {-0.00191010555824111571, 0.000839185447792341723}, - {-0.00191010555824111571, -0.000839185447792341723}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_mbtfpq_selftest (void) {return 10000;} diff --git a/src/PJ_merc.c b/src/PJ_merc.c index d17a2d50..994d540f 100644 --- a/src/PJ_merc.c +++ b/src/PJ_merc.c @@ -77,61 +77,4 @@ PJ *PROJECTION(merc) { } -#ifndef PJ_SELFTEST -int pj_merc_selftest (void) {return 0;} -#else - -int pj_merc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=merc +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=merc +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222638.981586547132, 110579.965218249708}, - { 222638.981586547132, -110579.965218249112}, - {-222638.981586547132, 110579.965218249708}, - {-222638.981586547132, -110579.965218249112}, - }; - - XY s_fwd_expect[] = { - { 223402.144255274179, 111706.743574944077}, - { 223402.144255274179, -111706.743574944485}, - {-223402.144255274179, 111706.743574944077}, - {-223402.144255274179, -111706.743574944485}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.00179663056823904264, 0.00090436947522799056}, - { 0.00179663056823904264, -0.00090436947522799056}, - {-0.00179663056823904264, 0.00090436947522799056}, - {-0.00179663056823904264, -0.00090436947522799056}, - }; - - LP s_inv_expect[] = { - { 0.00179049310978382265, 0.000895246554845297135}, - { 0.00179049310978382265, -0.000895246554858019272}, - {-0.00179049310978382265, 0.000895246554845297135}, - {-0.00179049310978382265, -0.000895246554858019272}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_merc_selftest (void) {return 10000;} diff --git a/src/PJ_mill.c b/src/PJ_mill.c index 829bc3be..c491d79d 100644 --- a/src/PJ_mill.c +++ b/src/PJ_mill.c @@ -34,46 +34,4 @@ PJ *PROJECTION(mill) { } -#ifndef PJ_SELFTEST -int pj_mill_selftest (void) {return 0;} -#else - -int pj_mill_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=mill +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223402.144255274179, 111704.701754393827}, - { 223402.144255274179, -111704.701754396243}, - {-223402.144255274179, 111704.701754393827}, - {-223402.144255274179, -111704.701754396243}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00179049310978382265, 0.000895246554873922024}, - { 0.00179049310978382265, -0.000895246554873922024}, - {-0.00179049310978382265, 0.000895246554873922024}, - {-0.00179049310978382265, -0.000895246554873922024}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_mill_selftest (void) {return 10000;} diff --git a/src/PJ_misrsom.c b/src/PJ_misrsom.c index 5c5a226f..77717f03 100644 --- a/src/PJ_misrsom.c +++ b/src/PJ_misrsom.c @@ -216,61 +216,4 @@ PJ *PROJECTION(misrsom) { } -#ifndef PJ_SELFTEST -int pj_misrsom_selftest (void) {return 0;} -#else - -int pj_misrsom_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=misrsom +ellps=GRS80 +lat_1=0.5 +lat_2=2 +path=1"}; - char s_args[] = {"+proj=misrsom +R=6400000 +lat_1=0.5 +lat_2=2 +path=1"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {18556630.3683698252, 9533394.6753112711}, - {19041866.0067297369, 9707182.17532352544}, - {18816810.1301847994, 8647669.64980295487}, - {19252610.7845367305, 8778164.08580140397}, - }; - - XY s_fwd_expect[] = { - {18641249.2791703865, 9563342.53233416565}, - {19130982.4615812786, 9739539.59350463562}, - {18903483.5150115378, 8675064.50061797537}, - {19343388.3998006098, 8807471.90406848863}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {127.759503987730625, 0.00173515039622462014}, - {127.761295471077958, 0.00187196632421706517}, - {127.759775773557251, -0.00187196632421891525}, - {127.76156725690457, -0.00173515039622462014}, - }; - - LP s_inv_expect[] = { - {127.75950514818588, 0.00171623111593511971}, - {127.761290323778738, 0.00185412132880796244}, - {127.759780920856471, -0.00185412132880796244}, - {127.761566096449329, -0.00171623111593511971}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_misrsom_selftest (void) {return 10000;} diff --git a/src/PJ_mod_ster.c b/src/PJ_mod_ster.c index 767863c1..ca81a43f 100644 --- a/src/PJ_mod_ster.c +++ b/src/PJ_mod_ster.c @@ -278,255 +278,8 @@ PJ *PROJECTION(gs50) { } -#ifndef PJ_SELFTEST -int pj_mil_os_selftest (void) {return 0;} -#else - -int pj_mil_os_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=mil_os +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {-1908527.94959420455, -1726237.4730614475}, - {-1916673.02291848511, -1943133.88812552323}, - {-2344429.41208962305, -1706258.05121891224}, - {-2354637.83553299867, -1926468.60513541684}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {20.0020363939492398, 18.0009683469140498}, - {20.0020363715837419, 17.999031631815086}, - {19.9979636060507602, 18.0009683469140498}, - {19.9979636284162581, 17.999031631815086}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - -#endif - - -#ifndef PJ_SELFTEST -int pj_lee_os_selftest (void) {return 0;} -#else - -int pj_lee_os_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=lee_os +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {-25564478.9526050538, 154490848.8286255}, - { 30115393.9385746419, 125193997.439701974}, - {-31039340.5921660066, 57678685.0448915437}, - {-3088419.93942357088, 58150091.0991110131}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {-164.997479457813824, -9.99875886103541411}, - {-164.997479438558884, -10.0012411200022751}, - {-165.002520542186289, -9.99875886103545142}, - {-165.002520561440946, -10.0012411200022999}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - -#endif - - -#ifndef PJ_SELFTEST -int pj_gs48_selftest (void) {return 0;} -#else - -int pj_gs48_selftest (void) { - double tolerance_lp = 1e-12; - double tolerance_xy = 1e-8; - - char s_args[] = {"+proj=gs48 +R=6370997"}; - - /* All latitudes and longitudes within the continental US */ - LP fwd_in[] = { - { -119.0, 40.0}, - { -70.0, 64.0}, - { -80.0, 25.0}, - { -95.0, 35.0} - }; - - XY s_fwd_expect[] = { - { -1923908.446529345820, 355874.658944479190}, - { 1354020.375109298155, 3040846.007866524626}, - { 1625139.160484319553, -1413614.894029108109}, - { 90241.658071457961, -439595.048485902138}, - }; - - XY inv_in[] = { - { -1923000.0, 355000.0}, - { 1354000.0, 3040000.0}, - { 1625000.0, -1413000.0}, - { 90000.0, -439000.0}, - }; - - LP s_inv_expect[] = { - {-118.987112613284, 39.994449789388}, - { -70.005208999424, 63.993387835525}, - { -80.000346610440, 25.005602546594}, - { -95.002606473071, 35.005424705030}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - -#endif - - -#ifndef PJ_SELFTEST -int pj_alsk_selftest (void) {return 0;} -#else - -int pj_alsk_selftest (void) { - - /* The standard test points are way outside the definition area bounds, hence we relax tolerances */ - double tolerance_lp = 1e-12; - double tolerance_xy = 1e-8; - - char e_args[] = {"+proj=alsk +ellps=clrk66"}; - char s_args[] = {"+proj=alsk +R=6370997"}; - - LP fwd_in[] = { - {-160.0, 55.0}, - {-160.0, 70.0}, - {-145.0, 70.0}, - {-145.0, 60.0} - }; - - XY e_fwd_expect[] = { - {-513253.146950842060, -968928.031867943470}, - {-305001.133897637190, 687494.464958650530}, - {266454.305088600490, 683423.477493030950}, - {389141.322439243960, -423913.251230396680}, - }; - - XY s_fwd_expect[] = { - {-511510.319410844070, -967150.991676078060}, - {-303744.771290368980, 685439.745941123230}, - {265354.974019662940, 681386.892874573010}, - {387711.995394026630, -422980.685505462640}, - }; - - XY inv_in[] = { - {-500000.0, -950000.0}, - {-305000.0, 700000.0}, - { 250000.0, 700000.0}, - { 400000.0, -400000.0} - }; - - LP e_inv_expect[] = { - {-159.830804302926, 55.183195262220}, - {-160.042203155537, 70.111086864056}, - {-145.381043551466, 70.163900908411}, - {-144.758985461448, 60.202929200739}, - }; - - LP s_inv_expect[] = { - {-159.854014457557, 55.165653849074}, - {-160.082332371601, 70.128307617632}, - {-145.347827407243, 70.181566919011}, - {-144.734239827146, 60.193564732505}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - -#endif - - -#ifndef PJ_SELFTEST -int pj_gs50_selftest (void) {return 0;} -#else - -int pj_gs50_selftest (void) { - double tolerance_lp = 1e-12; - double tolerance_xy = 1e-8; - - char e_args[] = {"+proj=gs50 +ellps=clrk66"}; - char s_args[] = {"+proj=gs50 +R=6370997"}; - - LP fwd_in[] = { - {-160.0, 65.0}, - {-130.0, 45.0}, - { -65.0, 45.0}, - { -80.0, 36.0}, - }; - - XY e_fwd_expect[] = { - {-1874628.5377402329, 2660907.942291015300}, - { -771831.51885333552, 48465.166491304852}, - { 4030931.8339815089, 1323687.864777399200}, - { 3450764.2615361013, -175619.041820732440}, - }; - - XY s_fwd_expect[] = { - {-1867268.2534600089, 2656506.230401823300}, - { -769572.18967299373, 48324.312440863941}, - { 4019393.068680791200, 1320191.309350289200}, - { 3442685.615172345700, -178760.423489428680}, - }; - - XY inv_in[] = { - {-1800000.0, 2600000.0}, - { -800000.0, 500000.0}, - { 4000000.0, 1300000.0}, - { 3900000.0, -170000.0}, - }; - - LP e_inv_expect[] = { - {-157.989284999679, 64.851559609698}, - {-131.171390466814, 49.084969745967}, - { -65.491568685301, 44.992837923774}, - { -75.550660091101, 34.191114075743}, - }; - - LP s_inv_expect[] = { - {-158.163295044933, 64.854288364994}, - {-131.206816959506, 49.082915350974}, - { -65.348945220767, 44.957292681774}, - { -75.446820242089, 34.185406225616}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_mil_os_selftest (void) {return 10000;} +int pj_lee_os_selftest (void) {return 10000;} +int pj_gs48_selftest (void) {return 10000;} +int pj_alsk_selftest (void) {return 10000;} +int pj_gs50_selftest (void) {return 10000;} diff --git a/src/PJ_moll.c b/src/PJ_moll.c index 8470bb3e..80dd70d0 100644 --- a/src/PJ_moll.c +++ b/src/PJ_moll.c @@ -106,138 +106,6 @@ PJ *PROJECTION(wag5) { return P; } - -#ifndef PJ_SELFTEST -int pj_moll_selftest (void) {return 0;} -#else - -int pj_moll_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=moll +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {201113.698641813244, 124066.283433859542}, - {201113.698641813244, -124066.283433859542}, - {-201113.698641813244, 124066.283433859542}, - {-201113.698641813244, -124066.283433859542}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {0.00198873782220854774, 0.000806005080362811612}, - {0.00198873782220854774, -0.000806005080362811612}, - {-0.00198873782220854774, 0.000806005080362811612}, - {-0.00198873782220854774, -0.000806005080362811612}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - -#endif - - -#ifndef PJ_SELFTEST -int pj_wag4_selftest (void) {return 0;} -#else - -int pj_wag4_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=wag4 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 192801.218662384286, 129416.216394802992}, - { 192801.218662384286, -129416.216394802992}, - {-192801.218662384286, 129416.216394802992}, - {-192801.218662384286, -129416.216394802992}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00207450259783523421, 0.000772682950537716476}, - { 0.00207450259783523421, -0.000772682950537716476}, - {-0.00207450259783523421, 0.000772682950537716476}, - {-0.00207450259783523421, -0.000772682950537716476}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - -#endif - -#ifndef PJ_SELFTEST -int pj_wag5_selftest (void) {return 0;} -#else - -int pj_wag5_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=wag5 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - - XY s_fwd_expect[] = { - { 203227.05192532466, 138651.631442713202}, - { 203227.05192532466, -138651.631442713202}, - {-203227.05192532466, 138651.631442713202}, - {-203227.05192532466, -138651.631442713202}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - - - - LP s_inv_expect[] = { - { 0.00196807227086416396, 0.00072121615041701424}, - { 0.00196807227086416396, -0.00072121615041701424}, - {-0.00196807227086416396, 0.00072121615041701424}, - {-0.00196807227086416396, -0.00072121615041701424}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_moll_selftest (void) {return 10000;} +int pj_wag4_selftest (void) {return 10000;} +int pj_wag5_selftest (void) {return 10000;} -- cgit v1.2.3 From 4498951c4e5169e922b1640cfec7b3fd9e9c47ca Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Sun, 12 Nov 2017 06:05:22 +0100 Subject: Remove selftests from projection files starting with n,o,p,q --- src/PJ_natearth.c | 44 +------------------------- src/PJ_natearth2.c | 44 +------------------------- src/PJ_nell.c | 44 +------------------------- src/PJ_nell_h.c | 44 +------------------------- src/PJ_nocol.c | 31 +----------------- src/PJ_nsper.c | 44 +------------------------- src/PJ_nzmg.c | 44 +------------------------- src/PJ_ob_tran.c | 34 +------------------- src/PJ_ocea.c | 44 +------------------------- src/PJ_oea.c | 44 +------------------------- src/PJ_omerc.c | 44 +------------------------- src/PJ_ortho.c | 44 +------------------------- src/PJ_patterson.c | 44 +------------------------- src/PJ_poly.c | 59 +--------------------------------- src/PJ_putp2.c | 46 ++------------------------- src/PJ_putp3.c | 92 ++---------------------------------------------------- src/PJ_putp4p.c | 92 ++---------------------------------------------------- src/PJ_putp5.c | 88 ++------------------------------------------------- src/PJ_putp6.c | 88 ++------------------------------------------------- src/PJ_qsc.c | 59 +--------------------------------- 20 files changed, 26 insertions(+), 1047 deletions(-) (limited to 'src') diff --git a/src/PJ_natearth.c b/src/PJ_natearth.c index 9c40f3da..2395ebb5 100644 --- a/src/PJ_natearth.c +++ b/src/PJ_natearth.c @@ -96,46 +96,4 @@ PJ *PROJECTION(natearth) { return P; } -#ifndef PJ_SELFTEST -int pj_natearth_selftest (void) {return 0;} -#else - -int pj_natearth_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=natearth +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 194507.265257889288, 112508.737358294515}, - { 194507.265257889288, -112508.737358294515}, - {-194507.265257889288, 112508.737358294515}, - {-194507.265257889288, -112508.737358294515}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00205638349586440223, 0.000888823913291242177}, - { 0.00205638349586440223, -0.000888823913291242177}, - {-0.00205638349586440223, 0.000888823913291242177}, - {-0.00205638349586440223, -0.000888823913291242177}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_natearth_selftest (void) {return 10000;} diff --git a/src/PJ_natearth2.c b/src/PJ_natearth2.c index 95bb8646..162fd768 100644 --- a/src/PJ_natearth2.c +++ b/src/PJ_natearth2.c @@ -93,46 +93,4 @@ PJ *PROJECTION(natearth2) { return P; } -#ifndef PJ_SELFTEST -int pj_natearth2_selftest (void) {return 0;} -#else - -int pj_natearth2_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=natearth2 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 189255.172934730799, 113022.495810907014}, - { 189255.172934730799, -113022.495810907014}, - {-189255.172934730799, 113022.495810907014}, - {-189255.172934730799, -113022.495810907014}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00211344929691056112, 0.000884779612080993237}, - { 0.00211344929691056112, -0.000884779612080993237}, - {-0.00211344929691056112, 0.000884779612080993237}, - {-0.00211344929691056112, -0.000884779612080993237}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_natearth2_selftest (void) {return 10000;} diff --git a/src/PJ_nell.c b/src/PJ_nell.c index ac071fc9..c4d65b88 100644 --- a/src/PJ_nell.c +++ b/src/PJ_nell.c @@ -47,46 +47,4 @@ PJ *PROJECTION(nell) { return P; } -#ifndef PJ_SELFTEST -int pj_nell_selftest (void) {return 0;} -#else - -int pj_nell_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=nell +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223385.132504695706, 111698.23644718733}, - { 223385.132504695706, -111698.23644718733}, - {-223385.132504695706, 111698.23644718733}, - {-223385.132504695706, -111698.23644718733}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00179049310989310567, 0.000895246554910125161}, - { 0.00179049310989310567, -0.000895246554910125161}, - {-0.00179049310989310567, 0.000895246554910125161}, - {-0.00179049310989310567, -0.000895246554910125161}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_nell_selftest (void) {return 10000;} diff --git a/src/PJ_nell_h.c b/src/PJ_nell_h.c index fe9a75c6..ebc8be90 100644 --- a/src/PJ_nell_h.c +++ b/src/PJ_nell_h.c @@ -50,46 +50,4 @@ PJ *PROJECTION(nell_h) { } -#ifndef PJ_SELFTEST -int pj_nell_h_selftest (void) {return 0;} -#else - -int pj_nell_h_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=nell_h +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223385.131640952837, 111698.236533561678}, - { 223385.131640952837, -111698.236533561678}, - {-223385.131640952837, 111698.236533561678}, - {-223385.131640952837, -111698.236533561678}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00179049310989310567, 0.000895246554910125378}, - { 0.00179049310989310567, -0.000895246554910125378}, - {-0.00179049310989310567, 0.000895246554910125378}, - {-0.00179049310989310567, -0.000895246554910125378}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_nell_h_selftest (void) {return 10000;} diff --git a/src/PJ_nocol.c b/src/PJ_nocol.c index 934ba7ab..aed5c382 100644 --- a/src/PJ_nocol.c +++ b/src/PJ_nocol.c @@ -50,33 +50,4 @@ PJ *PROJECTION(nicol) { return P; } - -#ifndef PJ_SELFTEST -int pj_nicol_selftest (void) {return 0;} -#else - -int pj_nicol_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=nicol +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223374.561814139714, 111732.553988545071}, - { 223374.561814139714, -111732.553988545071}, - {-223374.561814139714, 111732.553988545071}, - {-223374.561814139714, -111732.553988545071}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif +int pj_nicol_selftest (void) {return 10000;} diff --git a/src/PJ_nsper.c b/src/PJ_nsper.c index 6c8ef74a..b83b807b 100644 --- a/src/PJ_nsper.c +++ b/src/PJ_nsper.c @@ -241,46 +241,4 @@ int pj_nsper_selftest (void) { #endif -#ifndef PJ_SELFTEST -int pj_tpers_selftest (void) {return 0;} -#else - -int pj_tpers_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=tpers +a=6400000 +h=1000000 +azi=20"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 170820.288955531199, 180460.865555804776}, - { 246853.941538942483, -28439.8780357754222}, - {-246853.941538942483, 28439.8780357754222}, - {-170820.288955531199, -180460.865555804776} - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00198870552603137678, 0.000228871872278689991}, - { 0.00137632081376749859, -0.00145364129728205432}, - {-0.00137632081376749859, 0.00145364129728205432}, - {-0.00198870552603137678, -0.000228871872278689991}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_tpers_selftest (void) {return 10000;} diff --git a/src/PJ_nzmg.c b/src/PJ_nzmg.c index b489e32f..04128cfb 100644 --- a/src/PJ_nzmg.c +++ b/src/PJ_nzmg.c @@ -119,46 +119,4 @@ PJ *PROJECTION(nzmg) { } -#ifndef PJ_SELFTEST -int pj_nzmg_selftest (void) {return 0;} -#else - -int pj_nzmg_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=nzmg +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {3352675144.74742508, -7043205391.10024357}, - {3691989502.77930641, -6729069415.33210468}, - {4099000768.45323849, -7863208779.66724873}, - {4466166927.36997604, -7502531736.62860489}, - }; - - XY inv_in[] = { - { 200000, 100000}, - { 200000,-100000}, - {-200000, 100000}, - {-200000,-100000} - }; - - LP e_inv_expect[] = { - {175.48208682711271, -69.4226921826331846}, - {175.756819472543611, -69.5335710883796168}, - {134.605119233460016, -61.4599957106629091}, - {134.333684315954827, -61.6215536756024349}, - }; - - return pj_generic_selftest (e_args, 0, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, 0, inv_in, e_inv_expect, 0); -} - - -#endif +int pj_nzmg_selftest (void) {return 10000;} diff --git a/src/PJ_ob_tran.c b/src/PJ_ob_tran.c index 4f064809..4e71165a 100644 --- a/src/PJ_ob_tran.c +++ b/src/PJ_ob_tran.c @@ -243,42 +243,10 @@ int pj_ob_tran_selftest (void) {return 0;} #else int pj_ob_tran_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; double d; PJ *P; PJ_COORD a, b; - char s_args[] = {"+proj=ob_tran +R=6400000 +o_proj=latlon +o_lon_p=20 +o_lat_p=20 +lon_0=180"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {-2.6856872138416592, 1.2374302350496296}, - {-2.6954069748943286, 1.2026833954513816}, - {-2.8993663925401947, 1.2374302350496296}, - {-2.8896466314875244, 1.2026833954513816}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 121.5518748407577, -2.5361001573966084}, - { 63.261184340201858, 17.585319578673531}, - {-141.10073322351622, 26.091712304855108}, - {-65.862385598848391, 51.830295078417215}, - }; - /* -- Tests from nad/testvarious -------------------------------------------- */ P = proj_create (0, "+proj=ob_tran +o_proj=moll +R=6378137.0 +o_lon_p=0 +o_lat_p=0 +lon_0=180"); if (0==P) @@ -303,7 +271,7 @@ int pj_ob_tran_selftest (void) { /* -------------------------------------------------------------------------- */ - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); + return 0; } #endif \ No newline at end of file diff --git a/src/PJ_ocea.c b/src/PJ_ocea.c index d3fe9fe7..b4b6d68c 100644 --- a/src/PJ_ocea.c +++ b/src/PJ_ocea.c @@ -97,46 +97,4 @@ PJ *PROJECTION(ocea) { } -#ifndef PJ_SELFTEST -int pj_ocea_selftest (void) {return 0;} -#else - -int pj_ocea_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=ocea +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {19994423.837934087962, 223322.760576727800}, - {20217962.128015257418, 223322.760576729401}, - {19994423.837934091687, -223322.760576726549}, - {20217962.128015264869, -223322.760576724948}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 179.999104753445, 0.001790493110}, - {-179.999104753445, 0.001790493110}, - { 179.999104753445, -0.001790493110}, - {-179.999104753445, -0.001790493110}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_ocea_selftest (void) {return 10000;} diff --git a/src/PJ_oea.c b/src/PJ_oea.c index 800a266e..aeef87c0 100644 --- a/src/PJ_oea.c +++ b/src/PJ_oea.c @@ -83,46 +83,4 @@ PJ *PROJECTION(oea) { } -#ifndef PJ_SELFTEST -int pj_oea_selftest (void) {return 0;} -#else - -int pj_oea_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=oea +a=6400000 +lat_1=0.5 +lat_2=2 +n=1 +m=2 +theta=3"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 228926.872097864107, 99870.4884300760023}, - { 217242.584036940476, -123247.885607474513}, - {-217242.584036940476, 123247.885607474556}, - {-228926.872097864078, -99870.4884300760168}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017411857167771369, 0.000987726819566195693}, - { 0.00183489288577854998, -0.000800312481495174641}, - {-0.00183489288577854954, 0.000800312481495174966}, - {-0.00174118571677713712, -0.000987726819566195043}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_oea_selftest (void) {return 10000;} diff --git a/src/PJ_omerc.c b/src/PJ_omerc.c index f0b4b439..b29033eb 100644 --- a/src/PJ_omerc.c +++ b/src/PJ_omerc.c @@ -224,46 +224,4 @@ PJ *PROJECTION(omerc) { } -#ifndef PJ_SELFTEST -int pj_omerc_selftest (void) {return 0;} -#else - -int pj_omerc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=omerc +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222650.796885261341, 110642.229314983808}, - { 222650.796885261341, -110642.229314983808}, - {-222650.796885261545, 110642.229314983808}, - {-222650.796885261545, -110642.229314983808}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.00179663056816996357, 0.000904369474808157338}, - { 0.00179663056816996357, -0.000904369474820879583}, - {-0.0017966305681604536, 0.000904369474808157338}, - {-0.0017966305681604536, -0.000904369474820879583}, - }; - - return pj_generic_selftest (e_args, 0, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, 0, inv_in, e_inv_expect, 0); -} - - -#endif +int pj_omerc_selftest (void) {return 10000;} diff --git a/src/PJ_ortho.c b/src/PJ_ortho.c index 14e228f7..a497b160 100644 --- a/src/PJ_ortho.c +++ b/src/PJ_ortho.c @@ -131,46 +131,4 @@ PJ *PROJECTION(ortho) { } -#ifndef PJ_SELFTEST -int pj_ortho_selftest (void) {return 0;} -#else - -int pj_ortho_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=ortho +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223322.76057672748, 111695.401198614476}, - { 223322.76057672748, -111695.401198614476}, - {-223322.76057672748, 111695.401198614476}, - {-223322.76057672748, -111695.401198614476}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017904931102938101, 0.000895246554928338998}, - { 0.0017904931102938101, -0.000895246554928338998}, - {-0.0017904931102938101, 0.000895246554928338998}, - {-0.0017904931102938101, -0.000895246554928338998}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_ortho_selftest (void) {return 10000;} diff --git a/src/PJ_patterson.c b/src/PJ_patterson.c index 40b90010..9f9e3e39 100644 --- a/src/PJ_patterson.c +++ b/src/PJ_patterson.c @@ -114,46 +114,4 @@ PJ *PROJECTION(patterson) { } -#ifndef PJ_SELFTEST -int pj_patterson_selftest (void) {return 0;} -#else - -int pj_patterson_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=patterson +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {223402.144255274179, 113354.250397779804}, - {223402.144255274179, -113354.250397779804}, - {-223402.144255274179, 113354.250397779804}, - {-223402.144255274179, -113354.250397779804}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {0.00179049310978382265, 0.000882190140807953657}, - {0.00179049310978382265, -0.000882190140807953657}, - {-0.00179049310978382265, 0.000882190140807953657}, - {-0.00179049310978382265, -0.000882190140807953657}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_patterson_selftest (void) {return 10000;} diff --git a/src/PJ_poly.c b/src/PJ_poly.c index 209669c0..d748be09 100644 --- a/src/PJ_poly.c +++ b/src/PJ_poly.c @@ -165,61 +165,4 @@ PJ *PROJECTION(poly) { } -#ifndef PJ_SELFTEST -int pj_poly_selftest (void) {return 0;} -#else - -int pj_poly_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=poly +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=poly +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222605.285770237475, 110642.194561440483}, - { 222605.285770237475, -110642.194561440483}, - {-222605.285770237475, 110642.194561440483}, - {-222605.285770237475, -110642.194561440483}, - }; - - XY s_fwd_expect[] = { - { 223368.105210218986, 111769.110491224754}, - { 223368.105210218986, -111769.110491224754}, - {-223368.105210218986, 111769.110491224754}, - {-223368.105210218986, -111769.110491224754}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.00179663056846135222, 0.000904369476631838518}, - { 0.00179663056846135222, -0.000904369476631838518}, - {-0.00179663056846135222, 0.000904369476631838518}, - {-0.00179663056846135222, -0.000904369476631838518}, - }; - - LP s_inv_expect[] = { - { 0.0017904931100023887, 0.000895246554454779222}, - { 0.0017904931100023887, -0.000895246554454779222}, - {-0.0017904931100023887, 0.000895246554454779222}, - {-0.0017904931100023887, -0.000895246554454779222}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_poly_selftest (void) {return 10000;} diff --git a/src/PJ_putp2.c b/src/PJ_putp2.c index 83aa5f45..59eca8a6 100644 --- a/src/PJ_putp2.c +++ b/src/PJ_putp2.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include +#include "projects.h" PROJ_HEAD(putp2, "Putnins P2") "\n\tPCyl., Sph."; @@ -57,46 +57,4 @@ PJ *PROJECTION(putp2) { return P; } -#ifndef PJ_SELFTEST -int pj_putp2_selftest (void) {return 0;} -#else - -int pj_putp2_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=putp2 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 211638.039634339279, 117895.033043379764}, - { 211638.039634339279, -117895.033043379764}, - {-211638.039634339279, 117895.033043379764}, - {-211638.039634339279, -117895.033043379764}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00188980221640386672, 0.000848201580276863377}, - { 0.00188980221640386672, -0.000848201580276863377}, - {-0.00188980221640386672, 0.000848201580276863377}, - {-0.00188980221640386672, -0.000848201580276863377}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_putp2_selftest (void) {return 10000;} diff --git a/src/PJ_putp3.c b/src/PJ_putp3.c index cb216370..dfd152f8 100644 --- a/src/PJ_putp3.c +++ b/src/PJ_putp3.c @@ -63,93 +63,5 @@ PJ *PROJECTION(putp3p) { return P; } - -#ifndef PJ_SELFTEST -int pj_putp3_selftest (void) {return 0;} -#else - -int pj_putp3_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=putp3 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 178227.115507793525, 89124.5607860879827}, - { 178227.115507793525, -89124.5607860879827}, - {-178227.115507793525, 89124.5607860879827}, - {-178227.115507793525, -89124.5607860879827}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00224405032986489889, 0.00112202516475805899}, - { 0.00224405032986489889, -0.00112202516475805899}, - {-0.00224405032986489889, 0.00112202516475805899}, - {-0.00224405032986489889, -0.00112202516475805899}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif - - -#ifndef PJ_SELFTEST -int pj_putp3p_selftest (void) {return 0;} -#else - -int pj_putp3p_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=putp3p +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 178238.118539984745, 89124.5607860879827}, - { 178238.118539984745, -89124.5607860879827}, - {-178238.118539984745, 89124.5607860879827}, - {-178238.118539984745, -89124.5607860879827}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00224405032969050844, 0.00112202516475805899}, - { 0.00224405032969050844, -0.00112202516475805899}, - {-0.00224405032969050844, 0.00112202516475805899}, - {-0.00224405032969050844, -0.00112202516475805899}, - - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_putp3_selftest (void) {return 10000;} +int pj_putp3p_selftest (void) {return 10000;} diff --git a/src/PJ_putp4p.c b/src/PJ_putp4p.c index 197f24c4..576ffbf6 100644 --- a/src/PJ_putp4p.c +++ b/src/PJ_putp4p.c @@ -1,6 +1,6 @@ #define PJ_LIB__ #include -#include +#include "projects.h" struct pj_opaque { double C_x, C_y; @@ -71,91 +71,5 @@ PJ *PROJECTION(weren) { } -#ifndef PJ_SELFTEST -int pj_putp4p_selftest (void) {return 0;} -#else - -int pj_putp4p_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=putp4p +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 195241.47734938623, 127796.782307926231}, - { 195241.47734938623, -127796.782307926231}, - {-195241.47734938623, 127796.782307926231}, - {-195241.47734938623, -127796.782307926231}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00204852830860296001, 0.000782480174932193733}, - { 0.00204852830860296001, -0.000782480174932193733}, - {-0.00204852830860296001, 0.000782480174932193733}, - {-0.00204852830860296001, -0.000782480174932193733}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif - - -#ifndef PJ_SELFTEST -int pj_weren_selftest (void) {return 0;} -#else - -int pj_weren_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=weren +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223378.515757633519, 146214.093042288267}, - { 223378.515757633519, -146214.093042288267}, - {-223378.515757633519, 146214.093042288267}, - {-223378.515757633519, -146214.093042288267}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00179049310987240413, 0.000683917989676492265}, - { 0.00179049310987240413, -0.000683917989676492265}, - {-0.00179049310987240413, 0.000683917989676492265}, - {-0.00179049310987240413, -0.000683917989676492265}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_putp4p_selftest (void) {return 10000;} +int pj_weren_selftest (void) {return 10000;} diff --git a/src/PJ_putp5.c b/src/PJ_putp5.c index f8b431b1..2a847fa7 100644 --- a/src/PJ_putp5.c +++ b/src/PJ_putp5.c @@ -69,89 +69,5 @@ PJ *PROJECTION(putp5p) { return P; } -#ifndef PJ_SELFTEST -int pj_putp5_selftest (void) {return 0;} -#else - -int pj_putp5_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=putp5 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 226367.21338056153, 113204.56855847509}, - { 226367.21338056153, -113204.56855847509}, - {-226367.21338056153, 113204.56855847509}, - {-226367.21338056153, -113204.56855847509}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00176671315102969553, 0.000883356575387199546}, - { 0.00176671315102969553, -0.000883356575387199546}, - {-0.00176671315102969553, 0.000883356575387199546}, - {-0.00176671315102969553, -0.000883356575387199546}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - -#endif - - -#ifndef PJ_SELFTEST -int pj_putp5p_selftest (void) {return 0;} -#else - -int pj_putp5p_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=putp5p +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 226388.175248755841, 113204.56855847509}, - { 226388.175248755841, -113204.56855847509}, - {-226388.175248755841, 113204.56855847509}, - {-226388.175248755841, -113204.56855847509}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00176671315090204742, 0.000883356575387199546}, - { 0.00176671315090204742, -0.000883356575387199546}, - {-0.00176671315090204742, 0.000883356575387199546}, - {-0.00176671315090204742, -0.000883356575387199546}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - -#endif +int pj_putp5_selftest (void) {return 10000;} +int pj_putp5p_selftest (void) {return 10000;} diff --git a/src/PJ_putp6.c b/src/PJ_putp6.c index 50859f14..be86f805 100644 --- a/src/PJ_putp6.c +++ b/src/PJ_putp6.c @@ -92,89 +92,5 @@ PJ *PROJECTION(putp6p) { } -#ifndef PJ_SELFTEST -int pj_putp6_selftest (void) {return 0;} -#else - -int pj_putp6_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=putp6 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 226369.395133402577, 110218.523796520662}, - { 226369.395133402577, -110218.523796520749}, - {-226369.395133402577, 110218.523796520662}, - {-226369.395133402577, -110218.523796520749}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00176671315102969921, 0.000907295534210503544}, - { 0.00176671315102969921, -0.000907295534205924308}, - {-0.00176671315102969921, 0.000907295534210503544}, - {-0.00176671315102969921, -0.000907295534205924308}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - -#endif - - -#ifndef PJ_SELFTEST -int pj_putp6p_selftest (void) {return 0;} -#else - -int pj_putp6p_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=putp6p +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 198034.195132195076, 125989.475461323193}, - { 198034.195132195076, -125989.475461323193}, - {-198034.195132195076, 125989.475461323193}, - {-198034.195132195076, -125989.475461323193}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00201955053120177067, 0.000793716441164738612}, - { 0.00201955053120177067, -0.000793716441164738612}, - {-0.00201955053120177067, 0.000793716441164738612}, - {-0.00201955053120177067, -0.000793716441164738612}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - -#endif +int pj_putp6_selftest (void) {return 10000;} +int pj_putp6p_selftest (void) {return 10000;} diff --git a/src/PJ_qsc.c b/src/PJ_qsc.c index f30a7048..c8079f9e 100644 --- a/src/PJ_qsc.c +++ b/src/PJ_qsc.c @@ -399,61 +399,4 @@ PJ *PROJECTION(qsc) { } -#ifndef PJ_SELFTEST -int pj_qsc_selftest (void) {return 0;} -#else - -int pj_qsc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=qsc +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=qsc +R=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 304638.450843852363, 164123.870923793991}, - { 304638.450843852363, -164123.870923793991}, - {-304638.450843852363, 164123.870923793962}, - {-304638.450843852421, -164123.870923793904}, - }; - - XY s_fwd_expect[] = { - { 305863.792402890511, 165827.722754715243}, - { 305863.792402890511, -165827.722754715243}, - {-305863.792402890511, 165827.722754715243}, - {-305863.792402890569, -165827.722754715156}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.00132134098471627126, 0.000610652900922527926}, - { 0.00132134098471627126, -0.000610652900922527926}, - {-0.00132134098471627126, 0.000610652900922527926}, - {-0.00132134098471627126, -0.000610652900922527926}, - }; - - LP s_inv_expect[] = { - { 0.00131682718763827234, 0.000604493198178676161}, - { 0.00131682718763827234, -0.000604493198178676161}, - {-0.00131682718763827234, 0.000604493198178676161}, - {-0.00131682718763827234, -0.000604493198178676161}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_qsc_selftest (void) {return 10000;} -- cgit v1.2.3 From 0a578911ee7158852eaf62cd9e0cedebf937dc3a Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Sun, 12 Nov 2017 06:30:06 +0100 Subject: Remove selftests from projection files starting with r,s,t,u --- src/PJ_robin.c | 44 +---- src/PJ_rpoly.c | 32 +--- src/PJ_sch.c | 2 +- src/PJ_sconics.c | 477 +------------------------------------------------------ src/PJ_somerc.c | 59 +------ src/PJ_stere.c | 108 +------------ src/PJ_sterea.c | 59 +------ src/PJ_sts.c | 236 +-------------------------- src/PJ_tcc.c | 27 +--- src/PJ_tcea.c | 43 +---- src/PJ_times.c | 44 +---- src/PJ_tmerc.c | 56 +------ src/PJ_tpeqd.c | 57 ------- src/PJ_urm5.c | 29 +--- src/PJ_urmfps.c | 85 +--------- 15 files changed, 28 insertions(+), 1330 deletions(-) (limited to 'src') diff --git a/src/PJ_robin.c b/src/PJ_robin.c index d3f92cd9..a9bac6ec 100644 --- a/src/PJ_robin.c +++ b/src/PJ_robin.c @@ -154,46 +154,4 @@ PJ *PROJECTION(robin) { } -#ifndef PJ_SELFTEST -int pj_robin_selftest (void) {return 0;} -#else - -int pj_robin_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=robin +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 189588.423282507836, 107318.530350702888}, - { 189588.423282507836, -107318.530350702888}, - {-189588.423282507836, 107318.530350702888}, - {-189588.423282507836, -107318.530350702888}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.002109689065506131, 0.000931805533547745983}, - { 0.002109689065506131, -0.000931805533547745983}, - {-0.002109689065506131, 0.000931805533547745983}, - {-0.002109689065506131, -0.000931805533547745983}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_robin_selftest (void) {return 10000;} diff --git a/src/PJ_rpoly.c b/src/PJ_rpoly.c index 8f7b16c6..36e5a63e 100644 --- a/src/PJ_rpoly.c +++ b/src/PJ_rpoly.c @@ -1,6 +1,6 @@ #define PJ_LIB__ #include -#include +#include "projects.h" struct pj_opaque { double phi1; @@ -53,32 +53,4 @@ PJ *PROJECTION(rpoly) { } -#ifndef PJ_SELFTEST -int pj_rpoly_selftest (void) {return 0;} -#else - -int pj_rpoly_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=rpoly +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223368.09830201423, 111769.110486991223}, - { 223368.09830201423, -111769.110486991223}, - {-223368.09830201423, 111769.110486991223}, - {-223368.09830201423, -111769.110486991223}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif +int pj_rpoly_selftest (void) {return 10000;} diff --git a/src/PJ_sch.c b/src/PJ_sch.c index cd4aa95e..4ea3404d 100644 --- a/src/PJ_sch.c +++ b/src/PJ_sch.c @@ -229,4 +229,4 @@ PJ *PROJECTION(sch) { /* Skipping sef-test since the test system is not capable of handling * 3D coordinate systems for the time being. Relying on tests in ../nad/ */ -int pj_sch_selftest (void) {return 0;} +int pj_sch_selftest (void) {return 10000;} diff --git a/src/PJ_sconics.c b/src/PJ_sconics.c index b434c430..1e00a17e 100644 --- a/src/PJ_sconics.c +++ b/src/PJ_sconics.c @@ -215,473 +215,10 @@ PJ *PROJECTION(vitk1) { } -#ifndef PJ_SELFTEST -int pj_euler_selftest (void) {return 0;} -#else - -int pj_euler_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=euler +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=euler +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {222597.63465910763, 111404.24054991946}, - {222767.16563187627, -111234.6764910177}, - {-222597.63465910763, 111404.24054991946}, - {-222767.16563187627, -111234.6764910177}, - }; - - XY s_fwd_expect[] = { - {223360.65559869423, 111786.11238979101}, - {223530.76769031584, -111615.96709862351}, - {-223360.65559869423, 111786.11238979101}, - {-223530.76769031584, -111615.96709862351}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0017962807023075235, 0.0008983146697688839}, - {0.0017962794738334226, -0.00089831589842987965}, - {-0.0017962807023075235, 0.0008983146697688839}, - {-0.0017962794738334226, -0.00089831589842987965}, - }; - - LP s_inv_expect[] = { - {0.0017901444369360026, 0.00089524594522202015}, - {0.001790143216840731, -0.00089524716533368484}, - {-0.0017901444369360026, 0.00089524594522202015}, - {-0.001790143216840731, -0.00089524716533368484}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif - - - - - - -#ifndef PJ_SELFTEST -int pj_murd1_selftest (void) {return 0;} -#else - -int pj_murd1_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=murd1 +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=murd1 +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {222600.81347355421, 111404.24418054636}, - {222770.3492878644, -111234.6728566746}, - {-222600.81347355421, 111404.24418054636}, - {-222770.3492878644, -111234.6728566746}, - }; - - XY s_fwd_expect[] = { - {223363.84530949194, 111786.11603286299}, - {223533.96225925098, -111615.96345182261}, - {-223363.84530949194, 111786.11603286299}, - {-223533.96225925098, -111615.96345182261}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0017962550410516366, 0.0008983146697688839}, - {0.0017962538125775522, -0.00089831589842987965}, - {-0.0017962550410516366, 0.0008983146697688839}, - {-0.0017962538125775522, -0.00089831589842987965}, - }; - - LP s_inv_expect[] = { - {0.0017901188633413715, 0.00089524594522202015}, - {0.0017901176432461162, -0.00089524716492657387}, - {-0.0017901188633413715, 0.00089524594522202015}, - {-0.0017901176432461162, -0.00089524716492657387}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif - - - - - - - - - - - - - - -#ifndef PJ_SELFTEST -int pj_murd2_selftest (void) {return 0;} -#else - -int pj_murd2_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=murd2 +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=murd2 +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {222588.09975123021, 111426.14002741246}, - {222757.72626701824, -111341.43131750476}, - {-222588.09975123021, 111426.14002741246}, - {-222757.72626701824, -111341.43131750476}, - }; - - XY s_fwd_expect[] = { - {223351.08800702673, 111808.08693438848}, - {223521.2959691704, -111723.08785967289}, - {-223351.08800702673, 111808.08693438848}, - {-223521.2959691704, -111723.08785967289}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0017963574947305447, 0.00089788747830845382}, - {0.0017963562661689487, -0.00089788809264252983}, - {-0.0017963574947305447, 0.00089788747830845382}, - {-0.0017963562661689487, -0.00089788809264252983}, - }; - - LP s_inv_expect[] = { - {0.0017902209670287586, 0.00089482021163422854}, - {0.0017902197468465887, -0.00089482082161134206}, - {-0.0017902209670287586, 0.00089482021163422854}, - {-0.0017902197468465887, -0.00089482082161134206}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif - - - - - - - - - - -#ifndef PJ_SELFTEST -int pj_murd3_selftest (void) {return 0;} -#else - -int pj_murd3_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=murd3 +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=murd3 +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {222600.81407757697, 111404.24660137216}, - {222770.35473389886, -111234.67043217793}, - {-222600.81407757697, 111404.24660137216}, - {-222770.35473389886, -111234.67043217793}, - }; - - XY s_fwd_expect[] = { - {223363.84591558515, 111786.11846198692}, - {223533.96772395336, -111615.96101901523}, - {-223363.84591558515, 111786.11846198692}, - {-223533.96772395336, -111615.96101901523}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0017962550166583809, 0.0008983146697688839}, - {0.0017962537881492445, -0.00089831589842987965}, - {-0.0017962550166583809, 0.0008983146697688839}, - {-0.0017962537881492445, -0.00089831589842987965}, - }; - - LP s_inv_expect[] = { - {0.0017901188390313859, 0.00089524594522202015}, - {0.0017901176189013177, -0.00089524716533368484}, - {-0.0017901188390313859, 0.00089524594522202015}, - {-0.0017901176189013177, -0.00089524716533368484}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif - - - - - - - - - - - -#ifndef PJ_SELFTEST -int pj_pconic_selftest (void) {return 0;} -#else - -int pj_pconic_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=pconic +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=pconic +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {222588.09884161691, 111416.60477006658}, - {222757.71809109033, -111331.88153107995}, - {-222588.09884161691, 111416.60477006658}, - {-222757.71809109033, -111331.88153107995}, - }; - - XY s_fwd_expect[] = { - {223351.08709429545, 111798.5189920546}, - {223521.28776521701, -111713.50533845725}, - {-223351.08709429545, 111798.5189920546}, - {-223521.28776521701, -111713.50533845725}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0017963575313784969, 0.0008979644089172499}, - {0.0017963563027642206, -0.00089796502355327969}, - {-0.0017963575313784969, 0.0008979644089172499}, - {-0.0017963563027642206, -0.00089796502355327969}, - }; - - LP s_inv_expect[] = { - {0.0017902210035514285, 0.0008948968793741558}, - {0.0017902197833169374, -0.00089489748965381963}, - {-0.0017902210035514285, 0.0008948968793741558}, - {-0.0017902197833169374, -0.00089489748965381963}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif - - - - - - - - - - - - - - - -#ifndef PJ_SELFTEST -int pj_tissot_selftest (void) {return 0;} -#else - -int pj_tissot_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=tissot +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=tissot +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {222641.07869963095, 54347.828487281469}, - {222810.61451394114, -168291.08854993948}, - {-222641.07869963095, 54347.828487281469}, - {-222810.61451394114, -168291.08854993948}, - }; - - XY s_fwd_expect[] = { - {223404.24855684943, 54534.122161157939}, - {223574.36550660848, -168867.95732352766}, - {-223404.24855684943, 54534.122161157939}, - {-223574.36550660848, -168867.95732352766}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0017962807107425871, 0.51344495513064536}, - {0.0017962794822333915, 0.51164832456244658}, - {-0.0017962807107425871, 0.51344495513064536}, - {-0.0017962794822333915, 0.51164832456244658}, - }; - - LP s_inv_expect[] = { - {0.0017901444453421915, 0.51344188640609856}, - {0.001790143225212064, 0.51165139329554277}, - {-0.0017901444453421915, 0.51344188640609856}, - {-0.001790143225212064, 0.51165139329554277}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif - - - - - - - - -#ifndef PJ_SELFTEST -int pj_vitk1_selftest (void) {return 0;} -#else - -int pj_vitk1_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=vitk1 +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=vitk1 +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {222607.17121145778, 111404.25144243463}, - {222776.71670959776, -111234.66558744459}, - {-222607.17121145778, 111404.25144243463}, - {-222776.71670959776, -111234.66558744459}, - }; - - XY s_fwd_expect[] = { - {223370.22484047143, 111786.12331964359}, - {223540.3515072545, -111615.9561576751}, - {-223370.22484047143, 111786.12331964359}, - {-223540.3515072545, -111615.9561576751}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0017962037198570686, 0.0008983146697688839}, - {0.0017962024913830157, -0.00089831589842987965}, - {-0.0017962037198570686, 0.0008983146697688839}, - {-0.0017962024913830157, -0.00089831589842987965}, - }; - - LP s_inv_expect[] = { - {0.0017900677174648159, 0.00089524594522202015}, - {0.0017900664973695916, -0.00089524716533368484}, - {-0.0017900677174648159, 0.00089524594522202015}, - {-0.0017900664973695916, -0.00089524716533368484}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_euler_selftest (void) {return 10000;} +int pj_murd1_selftest (void) {return 10000;} +int pj_murd2_selftest (void) {return 10000;} +int pj_murd3_selftest (void) {return 10000;} +int pj_pconic_selftest (void) {return 10000;} +int pj_tissot_selftest (void) {return 10000;} +int pj_vitk1_selftest (void) {return 10000;} diff --git a/src/PJ_somerc.c b/src/PJ_somerc.c index 7324d48a..69fb6d47 100644 --- a/src/PJ_somerc.c +++ b/src/PJ_somerc.c @@ -89,61 +89,4 @@ PJ *PROJECTION(somerc) { } -#ifndef PJ_SELFTEST -int pj_somerc_selftest (void) {return 0;} -#else - -int pj_somerc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=somerc +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=somerc +R=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {222638.98158654713, 110579.96521824898}, - {222638.98158654713, -110579.96521825089}, - {-222638.98158654713, 110579.96521824898}, - {-222638.98158654713, -110579.96521825089}, - }; - - XY s_fwd_expect[] = { - {223402.14425527418, 111706.74357494408}, - {223402.14425527418, -111706.74357494518}, - {-223402.14425527418, 111706.74357494408}, - {-223402.14425527418, -111706.74357494518}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0017966305682390426, 0.00090436947704129484}, - {0.0017966305682390426, -0.00090436947704377105}, - {-0.0017966305682390426, 0.00090436947704129484}, - {-0.0017966305682390426, -0.00090436947704377105}, - }; - - LP s_inv_expect[] = { - {0.0017904931097838226, 0.00089524655485801927}, - {0.0017904931097838226, -0.00089524655484529714}, - {-0.0017904931097838226, 0.00089524655485801927}, - {-0.0017904931097838226, -0.00089524655484529714}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_somerc_selftest (void) {return 10000;} diff --git a/src/PJ_stere.c b/src/PJ_stere.c index 500b512d..82d83061 100644 --- a/src/PJ_stere.c +++ b/src/PJ_stere.c @@ -314,109 +314,5 @@ PJ *PROJECTION(ups) { } -#ifndef PJ_SELFTEST -int pj_stere_selftest (void) {return 0;} -#else - -int pj_stere_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=stere +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=stere +R=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222644.8545501172, 110610.8834741739}, - { 222644.8545501172, -110610.8834741739}, - {-222644.8545501172, 110610.8834741739}, - {-222644.8545501172, -110610.8834741739}, - }; - - XY s_fwd_expect[] = { - { 223407.81025950745, 111737.938996443}, - { 223407.81025950745, -111737.938996443}, - {-223407.81025950745, 111737.938996443}, - {-223407.81025950745, -111737.938996443}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017966305682022392, 0.00090436947502443507}, - { 0.0017966305682022392, -0.00090436947502443507}, - {-0.0017966305682022392, 0.00090436947502443507}, - {-0.0017966305682022392, -0.00090436947502443507}, - }; - - LP s_inv_expect[] = { - { 0.001790493109747395, 0.00089524655465513144}, - { 0.001790493109747395, -0.00089524655465513144}, - {-0.001790493109747395, 0.00089524655465513144}, - {-0.001790493109747395, -0.00089524655465513144}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif - - - - - -#ifndef PJ_SELFTEST -int pj_ups_selftest (void) {return 0;} -#else - -int pj_ups_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=ups +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {2433455.5634384668, -10412543.301512826}, - {2448749.1185681992, -10850493.419804076}, - {1566544.4365615332, -10412543.301512826}, - {1551250.8814318008, -10850493.419804076}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {-44.998567498074834, 64.9182362867341}, - {-44.995702709112308, 64.917020250675748}, - {-45.004297076028529, 64.915804280954518}, - {-45.001432287066002, 64.914588377560719}, - }; - - return pj_generic_selftest (e_args, 0, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, 0, inv_in, e_inv_expect, 0); -} - - -#endif +int pj_stere_selftest (void) {return 10000;} +int pj_ups_selftest (void) {return 10000;} diff --git a/src/PJ_sterea.c b/src/PJ_sterea.c index e0ff15e7..8a73f453 100644 --- a/src/PJ_sterea.c +++ b/src/PJ_sterea.c @@ -115,61 +115,4 @@ PJ *PROJECTION(sterea) { } -#ifndef PJ_SELFTEST -int pj_sterea_selftest (void) {return 0;} -#else - -int pj_sterea_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=sterea +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=sterea +R=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222644.89410919772, 110611.09187173686}, - { 222644.89410919772, -110611.09187173827}, - {-222644.89410919772, 110611.09187173686}, - {-222644.89410919772, -110611.09187173827}, - }; - - XY s_fwd_expect[] = { - { 223407.81025950745, 111737.93899644315}, - { 223407.81025950745, -111737.93899644315}, - {-223407.81025950745, 111737.93899644315}, - {-223407.81025950745, -111737.93899644315}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017966305682019911, 0.00090436947683099009}, - { 0.0017966305682019911, -0.00090436947684371233}, - {-0.0017966305682019911, 0.00090436947683099009}, - {-0.0017966305682019911, -0.00090436947684371233}, - }; - - LP s_inv_expect[] = { - { 0.001790493109747395, 0.00089524655465446378}, - { 0.001790493109747395, -0.00089524655465446378}, - {-0.001790493109747395, 0.00089524655465446378}, - {-0.001790493109747395, -0.00089524655465446378}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif +int pj_sterea_selftest (void) {return 10000;} diff --git a/src/PJ_sts.c b/src/PJ_sts.c index 3e6168bd..0349e67b 100644 --- a/src/PJ_sts.c +++ b/src/PJ_sts.c @@ -64,8 +64,6 @@ static PJ *setup(PJ *P, double p, double q, int mode) { - - PJ *PROJECTION(fouc) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); if (0==Q) @@ -75,66 +73,6 @@ PJ *PROJECTION(fouc) { } -#ifndef PJ_SELFTEST -int pj_fouc_selftest (void) {return 0;} -#else -int pj_fouc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=fouc +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=fouc +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {222588.12067589167, 111322.31670069379}, - {222588.12067589167, -111322.31670069379}, - {-222588.12067589167, 111322.31670069379}, - {-222588.12067589167, -111322.31670069379}, - }; - - XY s_fwd_expect[] = { - {223351.10900341379, 111703.9077217125}, - {223351.10900341379, -111703.9077217125}, - {-223351.10900341379, 111703.9077217125}, - {-223351.10900341379, -111703.9077217125}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0017966305685702751, 0.00089831528410111959}, - {0.0017966305685702751, -0.00089831528410111959}, - {-0.0017966305685702751, 0.00089831528410111959}, - {-0.0017966305685702751, -0.00089831528410111959}, - }; - - LP s_inv_expect[] = { - {0.0017904931101116717, 0.00089524655487369749}, - {0.0017904931101116717, -0.00089524655487369749}, - {-0.0017904931101116717, 0.00089524655487369749}, - {-0.0017904931101116717, -0.00089524655487369749}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} -#endif - - - - - PJ *PROJECTION(kav5) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); @@ -146,65 +84,6 @@ PJ *PROJECTION(kav5) { } -#ifndef PJ_SELFTEST -int pj_kav5_selftest (void) {return 0;} -#else -int pj_kav5_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=kav5 +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=kav5 +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {200360.90530882866, 123685.08247699818}, - {200360.90530882866, -123685.08247699818}, - {-200360.90530882866, 123685.08247699818}, - {-200360.90530882866, -123685.08247699818}, - }; - - XY s_fwd_expect[] = { - {201047.7031108776, 124109.05062917093}, - {201047.7031108776, -124109.05062917093}, - {-201047.7031108776, 124109.05062917093}, - {-201047.7031108776, -124109.05062917093}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0019962591348533314, 0.00080848256185253912}, - {0.0019962591348533314, -0.00080848256185253912}, - {-0.0019962591348533314, 0.00080848256185253912}, - {-0.0019962591348533314, -0.00080848256185253912}, - }; - - LP s_inv_expect[] = { - {0.0019894397264987643, 0.00080572070962591153}, - {0.0019894397264987643, -0.00080572070962591153}, - {-0.0019894397264987643, 0.00080572070962591153}, - {-0.0019894397264987643, -0.00080572070962591153}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} -#endif - - - - PJ *PROJECTION(qua_aut) { struct pj_opaque *Q = pj_calloc (1, sizeof (struct pj_opaque)); @@ -214,64 +93,6 @@ PJ *PROJECTION(qua_aut) { return setup(P, 2., 2., 0); } -#ifndef PJ_SELFTEST -int pj_qua_aut_selftest (void) {return 0;} -#else -int pj_qua_aut_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=qua_aut +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=qua_aut +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {222613.54903309655, 111318.07788798446}, - {222613.54903309655, -111318.07788798446}, - {-222613.54903309655, 111318.07788798446}, - {-222613.54903309655, -111318.07788798446}, - }; - - XY s_fwd_expect[] = { - {223376.62452402918, 111699.65437918637}, - {223376.62452402918, -111699.65437918637}, - {-223376.62452402918, 111699.65437918637}, - {-223376.62452402918, -111699.65437918637}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0017966305684046586, 0.00089831528412872229}, - {0.0017966305684046586, -0.00089831528412872229}, - {-0.0017966305684046586, 0.00089831528412872229}, - {-0.0017966305684046586, -0.00089831528412872229}, - }; - - LP s_inv_expect[] = { - {0.0017904931099477471, 0.00089524655490101819}, - {0.0017904931099477471, -0.00089524655490101819}, - {-0.0017904931099477471, 0.00089524655490101819}, - {-0.0017904931099477471, -0.00089524655490101819}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} -#endif - - - PJ *PROJECTION(mbt_s) { @@ -282,58 +103,9 @@ PJ *PROJECTION(mbt_s) { return setup(P, 1.48875, 1.36509, 0); } -#ifndef PJ_SELFTEST -int pj_mbt_s_selftest (void) {return 0;} -#else -int pj_mbt_s_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=mbt_s +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=mbt_s +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - XY e_fwd_expect[] = { - {204131.51785027285, 121400.33022550763}, - {204131.51785027285, -121400.33022550763}, - {-204131.51785027285, 121400.33022550763}, - {-204131.51785027285, -121400.33022550763}, - }; - - XY s_fwd_expect[] = { - {204831.24057099217, 121816.46669603503}, - {204831.24057099217, -121816.46669603503}, - {-204831.24057099217, 121816.46669603503}, - {-204831.24057099217, -121816.46669603503}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0019593827209883237, 0.00082369854658027549}, - {0.0019593827209883237, -0.00082369854658027549}, - {-0.0019593827209883237, 0.00082369854658027549}, - {-0.0019593827209883237, -0.00082369854658027549}, - }; - - LP s_inv_expect[] = { - {0.0019526892859206603, 0.00082088471512331508}, - {0.0019526892859206603, -0.00082088471512331508}, - {-0.0019526892859206603, 0.00082088471512331508}, - {-0.0019526892859206603, -0.00082088471512331508}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} -#endif +int pj_fouc_selftest (void) {return 10000;} +int pj_kav5_selftest (void) {return 10000;} +int pj_qua_aut_selftest (void) {return 10000;} +int pj_mbt_s_selftest (void) {return 10000;} diff --git a/src/PJ_tcc.c b/src/PJ_tcc.c index 26cf67b6..37211fdd 100644 --- a/src/PJ_tcc.c +++ b/src/PJ_tcc.c @@ -31,29 +31,4 @@ PJ *PROJECTION(tcc) { } -#ifndef PJ_SELFTEST -int pj_tcc_selftest (void) {return 0;} -#else -int pj_tcc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=tcc +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {223458.84419245756, 111769.14504058579}, - {223458.84419245756, -111769.14504058579}, - {-223458.84419245756, 111769.14504058579}, - {-223458.84419245756, -111769.14504058579}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} -#endif +int pj_tcc_selftest (void) {return 10000;} diff --git a/src/PJ_tcea.c b/src/PJ_tcea.c index 65b3c604..76249827 100644 --- a/src/PJ_tcea.c +++ b/src/PJ_tcea.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include +#include "projects.h" PROJ_HEAD(tcea, "Transverse Cylindrical Equal Area") "\n\tCyl, Sph"; @@ -33,43 +33,4 @@ PJ *PROJECTION(tcea) { } -#ifndef PJ_SELFTEST -int pj_tcea_selftest (void) {return 0;} -#else -int pj_tcea_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=tcea +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223322.76057672748, 111769.14504058579}, - { 223322.76057672748, -111769.14504058579}, - {-223322.76057672748, 111769.14504058579}, - {-223322.76057672748, -111769.14504058579}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017904931102938101, 0.00089524655445477922}, - { 0.0017904931102938101, -0.00089524655445477922}, - {-0.0017904931102938101, 0.00089524655445477922}, - {-0.0017904931102938101, -0.00089524655445477922}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} -#endif +int pj_tcea_selftest (void) {return 10000;} diff --git a/src/PJ_times.c b/src/PJ_times.c index a8d6e67a..696c9fd5 100644 --- a/src/PJ_times.c +++ b/src/PJ_times.c @@ -76,46 +76,4 @@ PJ *PROJECTION(times) { } -#ifndef PJ_SELFTEST -int pj_times_selftest (void) {return 0;} -#else - -int pj_times_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - int result; - int n = 5; - - char s_args[] = {"+proj=times +ellps=sphere"}; - - XY *inv_in = malloc(n*sizeof(XY)); - LP *s_inv_expect = malloc(n*sizeof(LP)); - - LP fwd_in[] = { - { 0, 0}, - { 80, 70}, - { 25, -10}, - {-35, 20}, - {-45, -30} - }; - - XY s_fwd_expect[] = { - { 0.0, 0.0}, - { 5785183.5760670956, 7615452.0661204215}, - { 2065971.5301078814, -951526.0648494592}, - {-2873054.0454850947, 1917730.9530005211}, - {-3651383.2035214868, -2914213.4578159209}, - }; - - memcpy(inv_in, &s_fwd_expect, n*sizeof(XY)); - memcpy(s_inv_expect, &fwd_in, n*sizeof(LP)); - - result = pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, n, n, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); - free(inv_in); - free(s_inv_expect); - - return result; -} - - -#endif +int pj_times_selftest (void) {return 10000;} diff --git a/src/PJ_tmerc.c b/src/PJ_tmerc.c index b3ec0030..2aa189fd 100644 --- a/src/PJ_tmerc.c +++ b/src/PJ_tmerc.c @@ -205,58 +205,4 @@ PJ *PROJECTION(tmerc) { } -#ifndef PJ_SELFTEST -int pj_tmerc_selftest (void) {return 0;} -#else -int pj_tmerc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=tmerc +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=tmerc +R=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222650.79679577847, 110642.22941192707}, - { 222650.79679577847, -110642.22941192707}, - {-222650.79679577847, 110642.22941192707}, - {-222650.79679577847, -110642.22941192707}, - }; - - XY s_fwd_expect[] = { - { 223413.46640632232, 111769.14504059685}, - { 223413.46640632232, -111769.14504059685}, - {-223413.46640632208, 111769.14504059685}, - {-223413.46640632208, -111769.14504059685}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017966305681649396, 0.00090436947663183841}, - { 0.0017966305681649396, -0.00090436947663183841}, - {-0.0017966305681649396, 0.00090436947663183841}, - {-0.0017966305681649396, -0.00090436947663183841}, - }; - - LP s_inv_expect[] = { - { 0.0017904931097048034, 0.00089524670602767842}, - { 0.0017904931097048034, -0.00089524670602767842}, - {-0.001790493109714345, 0.00089524670602767842}, - {-0.001790493109714345, -0.00089524670602767842}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} -#endif +int pj_tmerc_selftest (void) {return 10000;} diff --git a/src/PJ_tpeqd.c b/src/PJ_tpeqd.c index 6bea3968..dd19da8c 100644 --- a/src/PJ_tpeqd.c +++ b/src/PJ_tpeqd.c @@ -105,61 +105,4 @@ PJ *PROJECTION(tpeqd) { } -#ifndef PJ_SELFTEST int pj_tpeqd_selftest (void) {return 0;} -#else - -int pj_tpeqd_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=tpeqd +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5"}; - char s_args[] = {"+proj=tpeqd +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {-27750.758831679042, -222599.40369177726}, - {-250434.93702403645, -222655.93819326628}, - {-27750.758831679042, 222599.40369177726}, - {-250434.93702403645, 222655.93819326628}, - }; - - XY s_fwd_expect[] = { - {-27845.882978485075, -223362.43069526015}, - {-251293.37876465076, -223419.15898590829}, - {-27845.882978485075, 223362.43069526015}, - {-251293.37876465076, 223419.15898590829}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {-0.00089855554821257374, 1.2517966304145272}, - {0.0008985555481998515, 1.2517966304145272}, - {-0.00089855431859741167, 1.2482033692781642}, - {0.00089855431859741167, 1.2482033692781642}, - }; - - LP s_inv_expect[] = { - {-0.00089548606640108474, 1.2517904929571837}, - {0.0008954860663883625, 1.2517904929571837}, - {-0.000895484845182587, 1.248209506737604}, - {0.00089548484516986475, 1.248209506737604}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, s_fwd_expect, inv_in, e_inv_expect, s_inv_expect); -} - - -#endif diff --git a/src/PJ_urm5.c b/src/PJ_urm5.c index bd073459..e90cc9ee 100644 --- a/src/PJ_urm5.c +++ b/src/PJ_urm5.c @@ -29,7 +29,7 @@ PJ *PROJECTION(urm5) { if (0==Q) return pj_default_destructor(P, ENOMEM); P->opaque = Q; - + if (pj_param(P->ctx, P->params, "tn").i) { Q->n = pj_param(P->ctx, P->params, "dn").f; if (Q->n <= 0. || Q->n > 1.) @@ -51,29 +51,4 @@ PJ *PROJECTION(urm5) { } -#ifndef PJ_SELFTEST -int pj_urm5_selftest (void) {return 0;} -#else -int pj_urm5_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=urm5 +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223393.6384339639, 111696.81878511712}, - { 223393.6384339639, -111696.81878511712}, - {-223393.6384339639, 111696.81878511712}, - {-223393.6384339639, -111696.81878511712}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} -#endif +int pj_urm5_selftest (void) {return 10000;} diff --git a/src/PJ_urmfps.c b/src/PJ_urmfps.c index 64eb5c80..04ee8296 100644 --- a/src/PJ_urmfps.c +++ b/src/PJ_urmfps.c @@ -71,86 +71,5 @@ PJ *PROJECTION(wag1) { } -#ifndef PJ_SELFTEST -int pj_urmfps_selftest (void) {return 0;} -#else -int pj_urmfps_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=urmfps +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 196001.70813419219, 127306.84332999329}, - { 196001.70813419219, -127306.84332999329}, - {-196001.70813419219, 127306.84332999329}, - {-196001.70813419219, -127306.84332999329}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.002040720839642371, 0.00078547381740438178}, - { 0.002040720839642371, -0.00078547381740438178}, - {-0.002040720839642371, 0.00078547381740438178}, - {-0.002040720839642371, -0.00078547381740438178}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} -#endif - - -#ifndef PJ_SELFTEST -int pj_wag1_selftest (void) {return 0;} -#else -int pj_wag1_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=wag1 +a=6400000 +lat_1=0.5 +lat_2=2 +n=0.5"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 195986.78156115755, 127310.07506065986}, - { 195986.78156115755, -127310.07506065986}, - {-195986.78156115755, 127310.07506065986}, - {-195986.78156115755, -127310.07506065986}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.002040720839738254, 0.00078547381739207999}, - { 0.002040720839738254, -0.00078547381739207999}, - {-0.002040720839738254, 0.00078547381739207999}, - {-0.002040720839738254, -0.00078547381739207999}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} -#endif - +int pj_urmfps_selftest (void) {return 10000;} +int pj_wag1_selftest (void) {return 10000;} -- cgit v1.2.3 From 780613cccfde5e9f70850b6b026d310e0003d05b Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Sun, 12 Nov 2017 07:03:27 +0100 Subject: Remove selftests from projection files starting with v,w --- src/PJ_vandg.c | 44 +---------------------------------------- src/PJ_vandg2.c | 61 ++------------------------------------------------------- src/PJ_vandg4.c | 32 ++---------------------------- src/PJ_wag2.c | 46 ++----------------------------------------- src/PJ_wag3.c | 46 ++----------------------------------------- src/PJ_wag7.c | 30 ++-------------------------- src/PJ_wink1.c | 46 ++----------------------------------------- src/PJ_wink2.c | 30 ++-------------------------- 8 files changed, 15 insertions(+), 320 deletions(-) (limited to 'src') diff --git a/src/PJ_vandg.c b/src/PJ_vandg.c index e19d01b8..69c7e55c 100644 --- a/src/PJ_vandg.c +++ b/src/PJ_vandg.c @@ -106,46 +106,4 @@ PJ *PROJECTION(vandg) { } -#ifndef PJ_SELFTEST -int pj_vandg_selftest (void) {return 0;} -#else - -int pj_vandg_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=vandg +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223395.24954340671, 111704.59663367498}, - { 223395.24954340671, -111704.59663367498}, - {-223395.24954340671, 111704.59663367498}, - {-223395.24954340671, -111704.59663367498}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.001790493715929761, 0.00089524655486993867}, - { 0.001790493715929761, -0.00089524655486993867}, - {-0.001790493715929761, 0.00089524655486993867}, - {-0.001790493715929761, -0.00089524655486993867}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_vandg_selftest (void) {return 10000;} diff --git a/src/PJ_vandg2.c b/src/PJ_vandg2.c index 3f11e289..b6b69183 100644 --- a/src/PJ_vandg2.c +++ b/src/PJ_vandg2.c @@ -71,62 +71,5 @@ PJ *PROJECTION(vandg3) { } -#ifndef PJ_SELFTEST -int pj_vandg2_selftest (void) {return 0;} -#else - -int pj_vandg2_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=vandg2 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223395.24785043663, 111718.49103722633}, - { 223395.24785043663, -111718.49103722633}, - {-223395.24785043663, 111718.49103722633}, - {-223395.24785043663, -111718.49103722633}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif - -#ifndef PJ_SELFTEST -int pj_vandg3_selftest (void) {return 0;} -#else - -int pj_vandg3_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=vandg3 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223395.24955283134, 111704.51990442065}, - { 223395.24955283134, -111704.51990442065}, - {-223395.24955283134, 111704.51990442065}, - {-223395.24955283134, -111704.51990442065}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif +int pj_vandg2_selftest (void) {return 10000;} +int pj_vandg3_selftest (void) {return 10000;} diff --git a/src/PJ_vandg4.c b/src/PJ_vandg4.c index f7f48b43..de525810 100644 --- a/src/PJ_vandg4.c +++ b/src/PJ_vandg4.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include +#include "projects.h" PROJ_HEAD(vandg4, "van der Grinten IV") "\n\tMisc Sph, no inv."; @@ -52,32 +52,4 @@ PJ *PROJECTION(vandg4) { } -#ifndef PJ_SELFTEST -int pj_vandg4_selftest (void) {return 0;} -#else - -int pj_vandg4_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=vandg4 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223374.57729435508, 111701.19548415358 }, - { 223374.57729435508, -111701.19548415358 }, - {-223374.57729435508, 111701.19548415358 }, - {-223374.57729435508, -111701.19548415358 }, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} - - -#endif +int pj_vandg4_selftest (void) {return 10000;} diff --git a/src/PJ_wag2.c b/src/PJ_wag2.c index 0588167e..14d8f1c4 100644 --- a/src/PJ_wag2.c +++ b/src/PJ_wag2.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -# include +#include "projects.h" PROJ_HEAD(wag2, "Wagner II") "\n\tPCyl., Sph."; #define C_x 0.92483 #define C_y 1.38725 @@ -33,46 +33,4 @@ PJ *PROJECTION(wag2) { } -#ifndef PJ_SELFTEST -int pj_wag2_selftest (void) {return 0;} -#else - -int pj_wag2_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=wag2 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 206589.88809996162, 120778.04035754716}, - { 206589.88809996162, -120778.04035754716}, - {-206589.88809996162, 120778.04035754716}, - {-206589.88809996162, -120778.04035754716}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0019360240367390709, 0.00082795765763814082}, - { 0.0019360240367390709, -0.00082795765763814082}, - {-0.0019360240367390709, 0.00082795765763814082}, - {-0.0019360240367390709, -0.00082795765763814082}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_wag2_selftest (void) {return 10000;} diff --git a/src/PJ_wag3.c b/src/PJ_wag3.c index 7f300add..09a9291d 100644 --- a/src/PJ_wag3.c +++ b/src/PJ_wag3.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include +#include "projects.h" #include PROJ_HEAD(wag3, "Wagner III") "\n\tPCyl., Sph.\n\tlat_ts="; @@ -45,46 +45,4 @@ PJ *PROJECTION(wag3) { } -#ifndef PJ_SELFTEST -int pj_wag3_selftest (void) {return 0;} -#else - -int pj_wag3_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=wag3 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - {223387.02171816575, 111701.07212763709}, - {223387.02171816575, -111701.07212763709}, - {-223387.02171816575, 111701.07212763709}, - {-223387.02171816575, -111701.07212763709}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - {0.001790493109880963, 0.00089524655489191132}, - {0.001790493109880963, -0.00089524655489191132}, - {-0.001790493109880963, 0.00089524655489191132}, - {-0.001790493109880963, -0.00089524655489191132}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_wag3_selftest (void) {return 10000;} diff --git a/src/PJ_wag7.c b/src/PJ_wag7.c index 9152fdea..55c43534 100644 --- a/src/PJ_wag7.c +++ b/src/PJ_wag7.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include +#include "projects.h" PROJ_HEAD(wag7, "Wagner VII") "\n\tMisc Sph, no inv."; @@ -27,30 +27,4 @@ PJ *PROJECTION(wag7) { } -#ifndef PJ_SELFTEST -int pj_wag7_selftest (void) {return 0;} -#else - -int pj_wag7_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=wag7 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 198601.87695731167, 125637.0457141714}, - { 198601.87695731167, -125637.0457141714}, - {-198601.87695731167, 125637.0457141714}, - {-198601.87695731167, -125637.0457141714}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} -#endif +int pj_wag7_selftest (void) {return 10000;} diff --git a/src/PJ_wink1.c b/src/PJ_wink1.c index c1e2e909..670ff0f6 100644 --- a/src/PJ_wink1.c +++ b/src/PJ_wink1.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include +#include "projects.h" #include PROJ_HEAD(wink1, "Winkel I") "\n\tPCyl., Sph.\n\tlat_ts="; @@ -41,46 +41,4 @@ PJ *PROJECTION(wink1) { } -#ifndef PJ_SELFTEST -int pj_wink1_selftest (void) {return 0;} -#else - -int pj_wink1_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=wink1 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223385.13164095284, 111701.07212763709}, - { 223385.13164095284, -111701.07212763709}, - {-223385.13164095284, 111701.07212763709}, - {-223385.13164095284, -111701.07212763709}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.0017904931098931057, 0.00089524655489191132}, - { 0.0017904931098931057, -0.00089524655489191132}, - {-0.0017904931098931057, 0.00089524655489191132}, - {-0.0017904931098931057, -0.00089524655489191132}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif +int pj_wink1_selftest (void) {return 10000;} diff --git a/src/PJ_wink2.c b/src/PJ_wink2.c index 43b6cfce..512354bb 100644 --- a/src/PJ_wink2.c +++ b/src/PJ_wink2.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -# include +#include "projects.h" #include PROJ_HEAD(wink2, "Winkel II") "\n\tPCyl., Sph., no inv.\n\tlat_1="; @@ -49,30 +49,4 @@ PJ *PROJECTION(wink2) { } -#ifndef PJ_SELFTEST -int pj_wink2_selftest (void) {return 0;} -#else - -int pj_wink2_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=wink2 +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 223387.39643378611, 124752.03279744535}, - { 223387.39643378611, -124752.03279744535}, - {-223387.39643378611, 124752.03279744535}, - {-223387.39643378611, -124752.03279744535}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, 0, 0, 0); -} -#endif +int pj_wink2_selftest (void) {return 10000;} -- cgit v1.2.3 From 1d54ce2b6f47b9d60bfd28ad0d33a883be3d510a Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Sun, 12 Nov 2017 14:27:26 +0100 Subject: Poder autochecking again (WIP) (#652) * Poder dual autochecking implementation * Debugging aid: Improvements in PJ_vgridshift.c and gie.c * Most likely, the bugbeing tripped is in the gridshift code, so. uncomment suspicious lines in deformation.gie and merge this to support the debugging effort --- src/PJ_cart.c | 10 ++++++---- src/PJ_hgridshift.c | 3 ++- src/PJ_horner.c | 5 +++-- src/PJ_molodensky.c | 8 +++++--- src/PJ_vgridshift.c | 7 +++++-- src/gie.c | 53 +++++++++++++++++++++++++++++++++-------------------- src/proj.def | 47 ++++++++++++++++++++++++----------------------- src/proj.h | 5 ++++- src/proj_4D_api.c | 46 ++++++++++++++++++++++++---------------------- 9 files changed, 106 insertions(+), 78 deletions(-) (limited to 'src') 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) -- cgit v1.2.3 From 06b2f944d7844bb898ace8a7973f9182aa2234b1 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Mon, 13 Nov 2017 00:33:40 +0100 Subject: Removed remaining traces of the built in selftest system (#661) * Removed remaining traces of the builtin selftest system. Moved all functionality to test/gie * Updated Appveyor and Travis build scripts * Another appveyor script update --- src/Makefile.am | 2 +- src/PJ_aea.c | 3 - src/PJ_aeqd.c | 1 - src/PJ_airy.c | 1 - src/PJ_aitoff.c | 2 - src/PJ_august.c | 3 +- src/PJ_axisswap.c | 1 - src/PJ_bacon.c | 3 - src/PJ_bipc.c | 1 - src/PJ_boggs.c | 1 - src/PJ_bonne.c | 1 - src/PJ_calcofi.c | 1 - src/PJ_cart.c | 412 -------------------------- src/PJ_cass.c | 1 - src/PJ_cc.c | 1 - src/PJ_cea.c | 1 - src/PJ_chamb.c | 1 - src/PJ_collg.c | 1 - src/PJ_comill.c | 1 - src/PJ_crast.c | 1 - src/PJ_deformation.c | 1 - src/PJ_denoy.c | 1 - src/PJ_eck1.c | 1 - src/PJ_eck2.c | 1 - src/PJ_eck3.c | 5 - src/PJ_eck4.c | 2 - src/PJ_eck5.c | 1 - src/PJ_eqc.c | 1 - src/PJ_eqdc.c | 1 - src/PJ_fahey.c | 1 - src/PJ_fouc_s.c | 1 - src/PJ_gall.c | 1 - src/PJ_geos.c | 1 - src/PJ_gins8.c | 1 - src/PJ_gn_sinu.c | 5 - src/PJ_gnom.c | 2 - src/PJ_goode.c | 1 - src/PJ_gstmerc.c | 2 - src/PJ_hammer.c | 2 - src/PJ_hatano.c | 1 - src/PJ_healpix.c | 3 - src/PJ_helmert.c | 142 --------- src/PJ_hgridshift.c | 50 ---- src/PJ_horner.c | 83 ------ src/PJ_igh.c | 1 - src/PJ_imw_p.c | 2 - src/PJ_isea.c | 2 - src/PJ_krovak.c | 2 - src/PJ_labrd.c | 2 - src/PJ_laea.c | 2 - src/PJ_lagrng.c | 2 - src/PJ_larr.c | 2 - src/PJ_lask.c | 1 - src/PJ_latlong.c | 12 - src/PJ_lcc.c | 2 - src/PJ_lcca.c | 3 - src/PJ_loxim.c | 2 - src/PJ_lsat.c | 2 - src/PJ_mbt_fps.c | 1 - src/PJ_mbtfpp.c | 1 - src/PJ_mbtfpq.c | 1 - src/PJ_merc.c | 2 - src/PJ_mill.c | 2 - src/PJ_misrsom.c | 2 - src/PJ_mod_ster.c | 6 - src/PJ_moll.c | 3 - src/PJ_molodensky.c | 80 ----- src/PJ_natearth.c | 1 - src/PJ_natearth2.c | 1 - src/PJ_nell.c | 1 - src/PJ_nell_h.c | 2 - src/PJ_nocol.c | 1 - src/PJ_nsper.c | 47 --- src/PJ_nzmg.c | 2 - src/PJ_ob_tran.c | 37 --- src/PJ_ocea.c | 2 - src/PJ_oea.c | 2 - src/PJ_omerc.c | 2 - src/PJ_ortho.c | 2 - src/PJ_patterson.c | 2 - src/PJ_pipeline.c | 124 -------- src/PJ_poly.c | 2 - src/PJ_putp2.c | 1 - src/PJ_putp3.c | 2 - src/PJ_putp4p.c | 3 - src/PJ_putp5.c | 2 - src/PJ_putp6.c | 3 - src/PJ_qsc.c | 2 - src/PJ_robin.c | 1 - src/PJ_rpoly.c | 2 - src/PJ_sch.c | 4 - src/PJ_sconics.c | 8 - src/PJ_somerc.c | 2 - src/PJ_stere.c | 3 - src/PJ_sterea.c | 2 - src/PJ_sts.c | 6 - src/PJ_tcc.c | 2 - src/PJ_tcea.c | 2 - src/PJ_times.c | 2 - src/PJ_tmerc.c | 2 - src/PJ_tpeqd.c | 2 - src/PJ_unitconvert.c | 92 ------ src/PJ_urm5.c | 2 - src/PJ_urmfps.c | 3 - src/PJ_vandg.c | 2 - src/PJ_vandg2.c | 3 - src/PJ_vandg4.c | 2 - src/PJ_vgridshift.c | 61 ---- src/PJ_wag2.c | 2 - src/PJ_wag3.c | 2 - src/PJ_wag7.c | 2 - src/PJ_wink1.c | 2 - src/PJ_wink2.c | 2 - src/gie.c | 735 +++++++++++++++++++++++++++++++++++++++++++++- src/lib_proj.cmake | 2 - src/makefile.vc | 3 +- src/pj_generic_selftest.c | 197 ------------- src/pj_geocent.c | 46 --- src/pj_list.c | 25 -- src/pj_run_selftests.c | 80 ----- src/proj.c | 5 +- src/proj.def | 91 +++--- src/proj_api.h | 2 - src/proj_etmerc.c | 102 ------- src/proj_rouss.c | 44 --- src/projects.h | 24 -- 126 files changed, 778 insertions(+), 1916 deletions(-) delete mode 100644 src/pj_generic_selftest.c delete mode 100644 src/pj_run_selftests.c (limited to 'src') diff --git a/src/Makefile.am b/src/Makefile.am index 7edc05b1..58514592 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -73,7 +73,7 @@ libproj_la_SOURCES = \ pj_factors.c pj_fwd.c pj_init.c pj_inv.c pj_fwd3d.c pj_inv3d.c\ pj_list.c pj_malloc.c pj_mlfn.c pj_msfn.c proj_mdist.c \ pj_open_lib.c pj_param.c pj_phi2.c pj_pr_list.c \ - pj_qsfn.c pj_generic_selftest.c pj_run_selftests.c pj_strerrno.c \ + pj_qsfn.c pj_strerrno.c \ pj_tsfn.c pj_units.c pj_ctx.c pj_log.c pj_zpoly1.c rtodms.c \ vector1.c pj_release.c pj_gauss.c \ PJ_healpix.c PJ_natearth.c PJ_natearth2.c PJ_calcofi.c pj_fileapi.c \ diff --git a/src/PJ_aea.c b/src/PJ_aea.c index f48d2e9b..74628f9a 100644 --- a/src/PJ_aea.c +++ b/src/PJ_aea.c @@ -218,6 +218,3 @@ PJ *PROJECTION(leac) { return setup(P); } - -int pj_aea_selftest (void) {return 10000;} -int pj_leac_selftest (void) {return 10000;} diff --git a/src/PJ_aeqd.c b/src/PJ_aeqd.c index c089eed7..b627b438 100644 --- a/src/PJ_aeqd.c +++ b/src/PJ_aeqd.c @@ -320,4 +320,3 @@ PJ *PROJECTION(aeqd) { } -int pj_aeqd_selftest (void) {return 10000;} diff --git a/src/PJ_airy.c b/src/PJ_airy.c index f70e7f7a..c256a07f 100644 --- a/src/PJ_airy.c +++ b/src/PJ_airy.c @@ -149,4 +149,3 @@ PJ *PROJECTION(airy) { } -int pj_airy_selftest (void) {return 10000;} diff --git a/src/PJ_aitoff.c b/src/PJ_aitoff.c index 4e2f2092..8927d39c 100644 --- a/src/PJ_aitoff.c +++ b/src/PJ_aitoff.c @@ -194,5 +194,3 @@ PJ *PROJECTION(wintri) { } -int pj_aitoff_selftest (void) {return 10000;} -int pj_wintri_selftest (void) {return 10000;} diff --git a/src/PJ_august.c b/src/PJ_august.c index c437ca2f..ba9ea5cd 100644 --- a/src/PJ_august.c +++ b/src/PJ_august.c @@ -1,5 +1,5 @@ #define PJ_LIB__ -#include +#include "projects.h" PROJ_HEAD(august, "August Epicycloidal") "\n\tMisc Sph, no inv."; @@ -31,4 +31,3 @@ PJ *PROJECTION(august) { return P; } -int pj_august_selftest (void) {return 0;} diff --git a/src/PJ_axisswap.c b/src/PJ_axisswap.c index 7215b9ce..53c93cc9 100644 --- a/src/PJ_axisswap.c +++ b/src/PJ_axisswap.c @@ -235,4 +235,3 @@ PJ *CONVERSION(axisswap,0) { return P; } -int pj_axisswap_selftest (void) {return 10000;} diff --git a/src/PJ_bacon.c b/src/PJ_bacon.c index 930e9c07..802ddcb8 100644 --- a/src/PJ_bacon.c +++ b/src/PJ_bacon.c @@ -77,6 +77,3 @@ PJ *PROJECTION(ortel) { } -int pj_bacon_selftest (void) {return 10000;} -int pj_apian_selftest (void) {return 10000;} -int pj_ortel_selftest (void) {return 10000;} diff --git a/src/PJ_bipc.c b/src/PJ_bipc.c index 7dd8a30f..4247fc17 100644 --- a/src/PJ_bipc.c +++ b/src/PJ_bipc.c @@ -171,4 +171,3 @@ PJ *PROJECTION(bipc) { } -int pj_bipc_selftest (void) {return 10000;} diff --git a/src/PJ_boggs.c b/src/PJ_boggs.c index 8c35fcb3..fe17eaa6 100644 --- a/src/PJ_boggs.c +++ b/src/PJ_boggs.c @@ -42,4 +42,3 @@ PJ *PROJECTION(boggs) { } -int pj_boggs_selftest (void) {return 10000;} diff --git a/src/PJ_bonne.c b/src/PJ_bonne.c index 596610bb..4611c5d4 100644 --- a/src/PJ_bonne.c +++ b/src/PJ_bonne.c @@ -130,4 +130,3 @@ PJ *PROJECTION(bonne) { } -int pj_bonne_selftest (void) {return 10000;} diff --git a/src/PJ_calcofi.c b/src/PJ_calcofi.c index 2782b152..5c0b64ab 100644 --- a/src/PJ_calcofi.c +++ b/src/PJ_calcofi.c @@ -163,4 +163,3 @@ PJ *PROJECTION(calcofi) { } -int pj_calcofi_selftest (void) {return 10000;} diff --git a/src/PJ_cart.c b/src/PJ_cart.c index e2768c55..2bcf3b4b 100644 --- a/src/PJ_cart.c +++ b/src/PJ_cart.c @@ -219,415 +219,3 @@ PJ *CONVERSION(cart,1) { return P; } -#ifndef PJ_SELFTEST -/* selftest stub */ -int pj_cart_selftest (void) {return 0;} -#else -/* Testing quite a bit of the pj_obs_api as a side effect (inspired by pj_obs_api_test.c) */ -int pj_cart_selftest (void) { - PJ_CONTEXT *ctx; - PJ *P; - PJ_COORD a, b, obs[2]; - PJ_COORD coord[2]; - - PJ_INFO info; - PJ_PROJ_INFO pj_info; - PJ_GRID_INFO grid_info; - PJ_INIT_INFO init_info; - - PJ_DERIVS derivs; - PJ_FACTORS factors; - - const PJ_OPERATIONS *oper_list; - const PJ_ELLPS *ellps_list; - const PJ_UNITS *unit_list; - const PJ_PRIME_MERIDIANS *pm_list; - - int err; - size_t n, sz; - double dist, h, t; - char *args[3] = {"proj=utm", "zone=32", "ellps=GRS80"}; - char *arg = {"+proj=utm +zone=32 +ellps=GRS80"}; - char buf[40]; - - /* An utm projection on the GRS80 ellipsoid */ - P = proj_create (PJ_DEFAULT_CTX, arg); - if (0==P) - return 1; - - - /* Clean up */ - proj_destroy (P); - - /* Same projection, now using argc/argv style initialization */ - P = proj_create_argv (PJ_DEFAULT_CTX, 3, args); - if (0==P) - return 2; - - /* zero initialize everything, then set (longitude, latitude) to (12, 55) */ - a = proj_coord (0,0,0,0); - /* a.lp: The coordinate part of a, interpreted as a classic LP pair */ - a.lp.lam = PJ_TORAD(12); - a.lp.phi = PJ_TORAD(55); - - /* Forward projection */ - b = proj_trans (P, PJ_FWD, a); - - /* Inverse projection */ - a = proj_trans (P, PJ_INV, b); - - /* Null projection */ - a = proj_trans (P, PJ_IDENT, a); - - /* Forward again, to get two linear items for comparison */ - a = proj_trans (P, PJ_FWD, a); - - dist = proj_xy_dist (a.xy, b.xy); - if (dist > 2e-9) - return 3; - - /* Clear any previous error */ - proj_errno_set (P, 0); - - /* Invalid projection */ - a = proj_trans (P, 42, a); - if (a.lpz.lam!=HUGE_VAL) - return 4; - err = proj_errno (P); - if (0==err) - return 5; - - /* Clear error again */ - proj_errno_set (P, 0); - - /* Clean up */ - proj_destroy (P); - - /* Now do some 3D transformations */ - P = proj_create (PJ_DEFAULT_CTX, "+proj=cart +ellps=GRS80"); - if (0==P) - return 6; - - /* zero initialize everything, then set (longitude, latitude, height) to (12, 55, 100) */ - a = b = proj_coord (0,0,0,0); - a.lpz.lam = PJ_TORAD(12); - a.lpz.phi = PJ_TORAD(55); - a.lpz.z = 100; - - /* Forward projection: 3D-Cartesian-to-Ellipsoidal */ - 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); - if (dist > 2e-9) - return 7; - - - /* Test at the North Pole */ - a = b = proj_coord (0,0,0,0); - a.lpz.lam = PJ_TORAD(0); - a.lpz.phi = PJ_TORAD(90); - a.lpz.z = 100; - - /* Forward projection: Ellipsoidal-to-3D-Cartesian */ - dist = proj_roundtrip (P, PJ_FWD, 1, &a); - if (dist > 1e-12) - return 8; - - /* Test at the South Pole */ - a = b = proj_coord (0,0,0,0); - 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); - if (dist > 1e-12) - return 9; - - - /* Inverse projection: 3D-Cartesian-to-Ellipsoidal */ - b = proj_trans (P, PJ_INV, b); - - /* Move p to another context */ - ctx = proj_context_create (); - if (ctx==pj_get_default_ctx()) - return 10; - proj_context_set (P, ctx); - if (ctx != P->ctx) - return 11; - b = proj_trans (P, PJ_FWD, b); - - /* Move it back to the default context */ - proj_context_set (P, 0); - if (pj_get_default_ctx() != P->ctx) - return 12; - proj_context_destroy (ctx); - - /* We go on with the work - now back on the default context */ - b = proj_trans (P, PJ_INV, b); - proj_destroy (P); - - - /* Testing proj_trans_generic () */ - - /* An utm projection on the GRS80 ellipsoid */ - P = proj_create (PJ_DEFAULT_CTX, "+proj=utm +zone=32 +ellps=GRS80"); - if (0==P) - return 13; - - obs[0] = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); - obs[1] = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); - sz = sizeof (PJ_COORD); - - /* Forward projection */ - a = proj_trans (P, PJ_FWD, obs[0]); - b = proj_trans (P, PJ_FWD, obs[1]); - - n = proj_trans_generic ( - P, PJ_FWD, - &(obs[0].lpz.lam), sz, 2, - &(obs[0].lpz.phi), sz, 2, - &(obs[0].lpz.z), sz, 2, - 0, sz, 0 - ); - if (2!=n) - return 14; - if (a.lpz.lam != obs[0].lpz.lam) return 15; - if (a.lpz.phi != obs[0].lpz.phi) return 16; - if (a.lpz.z != obs[0].lpz.z) return 17; - if (b.lpz.lam != obs[1].lpz.lam) return 18; - if (b.lpz.phi != obs[1].lpz.phi) return 19; - if (b.lpz.z != obs[1].lpz.z) return 20; - - /* now test the case of constant z */ - obs[0] = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); - obs[1] = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); - h = 27; - t = 33; - n = proj_trans_generic ( - P, PJ_FWD, - &(obs[0].lpz.lam), sz, 2, - &(obs[0].lpz.phi), sz, 2, - &h, 0, 1, - &t, 0, 1 - ); - if (2!=n) - return 21; - if (a.lpz.lam != obs[0].lpz.lam) return 22; - if (a.lpz.phi != obs[0].lpz.phi) return 23; - if (45 != obs[0].lpz.z) return 24; - if (b.lpz.lam != obs[1].lpz.lam) return 25; - if (b.lpz.phi != obs[1].lpz.phi) return 26; - if (50 != obs[1].lpz.z) return 27; /* NOTE: unchanged */ - if (50==h) return 28; - - /* test proj_trans_array () */ - - coord[0] = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); - coord[1] = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); - if (proj_trans_array (P, PJ_FWD, 2, coord)) - return 40; - - if (a.lpz.lam != coord[0].lpz.lam) return 41; - if (a.lpz.phi != coord[0].lpz.phi) return 42; - if (a.lpz.z != coord[0].lpz.z) return 43; - if (b.lpz.lam != coord[1].lpz.lam) return 44; - if (b.lpz.phi != coord[1].lpz.phi) return 45; - if (b.lpz.z != coord[1].lpz.z) return 46; - - /* Clean up after proj_trans_* tests */ - proj_destroy (P); - - /* test proj_create_crs_to_crs() */ - P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "epsg:25832", "epsg:25833", NULL); - if (P==0) - return 50; - - a.xy.x = 700000.0; - a.xy.y = 6000000.0; - b.xy.x = 307788.8761171057; - b.xy.y = 5999669.3036037628; - - a = proj_trans(P, PJ_FWD, a); - if (dist > 1e-7) - return 51; - proj_destroy(P); - - /* let's make sure that only entries in init-files results in a usable PJ */ - P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "proj=utm +zone=32 +datum=WGS84", "proj=utm +zone=33 +datum=WGS84", NULL); - if (P != 0) { - proj_destroy(P); - return 52; - } - proj_destroy(P); - - /* ********************************************************************** */ - /* Test info functions */ - /* ********************************************************************** */ - - /* proj_info() */ - /* this one is difficult to test, since the output changes with the setup */ - info = proj_info(); - if (info.version[0] != '\0' ) { - char tmpstr[64]; - sprintf(tmpstr, "%d.%d.%d", info.major, info.minor, info.patch); - if (strcmp(info.version, tmpstr)) return 55; - } - if (info.release[0] == '\0') return 56; - if (info.searchpath[0] == '\0') return 57; - - /* proj_pj_info() */ - P = proj_create(PJ_DEFAULT_CTX, "+proj=august"); /* august has no inverse */ - if (proj_pj_info(P).has_inverse) { proj_destroy(P); return 60; } - proj_destroy(P); - - P = proj_create(PJ_DEFAULT_CTX, arg); - pj_info = proj_pj_info(P); - if ( !pj_info.has_inverse ) { proj_destroy(P); return 61; } - if ( strcmp(pj_info.definition, arg) ) { proj_destroy(P); return 62; } - if ( strcmp(pj_info.id, "utm") ) { proj_destroy(P); return 63; } - proj_destroy(P); - - /* proj_grid_info() */ - grid_info = proj_grid_info("egm96_15.gtx"); - if ( strlen(grid_info.filename) == 0 ) return 64; - if ( strcmp(grid_info.gridname, "egm96_15.gtx") ) return 65; - grid_info = proj_grid_info("nonexistinggrid"); - if ( strlen(grid_info.filename) > 0 ) return 66; - - /* proj_init_info() */ - init_info = proj_init_info("unknowninit"); - if ( strlen(init_info.filename) != 0 ) return 67; - - init_info = proj_init_info("epsg"); - /* Need to allow for "Unknown" until all commonly distributed EPSG-files comes with a metadata section */ - if ( strcmp(init_info.origin, "EPSG") && strcmp(init_info.origin, "Unknown") ) return 69; - if ( strcmp(init_info.name, "epsg") ) return 68; - - - - /* test proj_rtodms() and proj_dmstor() */ - if (strcmp("180dN", proj_rtodms(buf, M_PI, 'N', 'S'))) - return 70; - - if (proj_dmstor(&buf[0], NULL) != M_PI) - return 71; - - if (strcmp("114d35'29.612\"S", proj_rtodms(buf, -2.0, 'N', 'S'))) - return 72; - - /* we can't expect perfect numerical accuracy so testing with a tolerance */ - if (fabs(-2.0 - proj_dmstor(&buf[0], NULL)) > 1e-7) - return 73; - - - /* test proj_derivatives_retrieve() and proj_factors_retrieve() */ - P = proj_create(PJ_DEFAULT_CTX, "+proj=merc"); - a = proj_coord (0,0,0,0); - a.lp.lam = PJ_TORAD(12); - a.lp.phi = PJ_TORAD(55); - - derivs = proj_derivatives(P, a.lp); - if (proj_errno(P)) - return 80; /* derivs not created correctly */ - - if ( fabs(derivs.x_l - 1.0) > 1e-5 ) return 81; - if ( fabs(derivs.x_p - 0.0) > 1e-5 ) return 82; - if ( fabs(derivs.y_l - 0.0) > 1e-5 ) return 83; - if ( fabs(derivs.y_p - 1.73959) > 1e-5 ) return 84; - - - factors = proj_factors(P, a.lp); - if (proj_errno(P)) - return 85; /* factors not created correctly */ - - /* check a few key characteristics of the Mercator projection */ - if (factors.omega != 0.0) return 86; /* angular distortion should be 0 */ - if (factors.thetap != M_PI_2) return 87; /* Meridian/parallel angle should be 90 deg */ - if (factors.conv != 0.0) return 88; /* meridian convergence should be 0 */ - - - proj_destroy(P); - - /* Check that proj_list_* functions work by looping through them */ - n = 0; - for (oper_list = proj_list_operations(); oper_list->id; ++oper_list) n++; - if (n == 0) return 90; - - n = 0; - for (ellps_list = proj_list_ellps(); ellps_list->id; ++ellps_list) n++; - if (n == 0) return 91; - - n = 0; - for (unit_list = proj_list_units(); unit_list->id; ++unit_list) n++; - if (n == 0) return 92; - - n = 0; - 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; -} - - -#endif diff --git a/src/PJ_cass.c b/src/PJ_cass.c index 603ce013..ddb3eaf3 100644 --- a/src/PJ_cass.c +++ b/src/PJ_cass.c @@ -118,4 +118,3 @@ PJ *PROJECTION(cass) { } -int pj_cass_selftest (void) {return 10000;} diff --git a/src/PJ_cc.c b/src/PJ_cc.c index a45eaf83..8a7da5b5 100644 --- a/src/PJ_cc.c +++ b/src/PJ_cc.c @@ -38,4 +38,3 @@ PJ *PROJECTION(cc) { } -int pj_cc_selftest (void) {return 10000;} diff --git a/src/PJ_cea.c b/src/PJ_cea.c index 0ffc2f4c..60ed3a37 100644 --- a/src/PJ_cea.c +++ b/src/PJ_cea.c @@ -98,4 +98,3 @@ PJ *PROJECTION(cea) { } -int pj_cea_selftest (void) {return 10000;} diff --git a/src/PJ_chamb.c b/src/PJ_chamb.c index de47c2d9..d0b9250e 100644 --- a/src/PJ_chamb.c +++ b/src/PJ_chamb.c @@ -136,4 +136,3 @@ PJ *PROJECTION(chamb) { } -int pj_chamb_selftest (void) {return 10000;} diff --git a/src/PJ_collg.c b/src/PJ_collg.c index 15e8354c..bf7d9f14 100644 --- a/src/PJ_collg.c +++ b/src/PJ_collg.c @@ -49,4 +49,3 @@ PJ *PROJECTION(collg) { return P; } -int pj_collg_selftest (void) {return 10000;} diff --git a/src/PJ_comill.c b/src/PJ_comill.c index e1994478..a34762e8 100644 --- a/src/PJ_comill.c +++ b/src/PJ_comill.c @@ -81,4 +81,3 @@ PJ *PROJECTION(comill) { } -int pj_comill_selftest (void) {return 10000;} diff --git a/src/PJ_crast.c b/src/PJ_crast.c index 30f2e304..81182117 100644 --- a/src/PJ_crast.c +++ b/src/PJ_crast.c @@ -37,4 +37,3 @@ PJ *PROJECTION(crast) { return P; } -int pj_crast_selftest (void) {return 10000;} diff --git a/src/PJ_deformation.c b/src/PJ_deformation.c index 62a24683..81dd602d 100644 --- a/src/PJ_deformation.c +++ b/src/PJ_deformation.c @@ -288,4 +288,3 @@ PJ *TRANSFORMATION(deformation,1) { return P; } -int pj_deformation_selftest (void) {return 10000;} diff --git a/src/PJ_denoy.c b/src/PJ_denoy.c index aec78b40..d89a7e3e 100644 --- a/src/PJ_denoy.c +++ b/src/PJ_denoy.c @@ -29,4 +29,3 @@ PJ *PROJECTION(denoy) { return P; } -int pj_denoy_selftest (void) {return 10000;} diff --git a/src/PJ_eck1.c b/src/PJ_eck1.c index 10fef421..4a9ac06b 100644 --- a/src/PJ_eck1.c +++ b/src/PJ_eck1.c @@ -39,4 +39,3 @@ PJ *PROJECTION(eck1) { } -int pj_eck1_selftest (void) {return 10000;} diff --git a/src/PJ_eck2.c b/src/PJ_eck2.c index f8adcc7a..b953b54f 100644 --- a/src/PJ_eck2.c +++ b/src/PJ_eck2.c @@ -53,4 +53,3 @@ PJ *PROJECTION(eck2) { } -int pj_eck2_selftest (void) {return 10000;} diff --git a/src/PJ_eck3.c b/src/PJ_eck3.c index 3e64e050..21353be2 100644 --- a/src/PJ_eck3.c +++ b/src/PJ_eck3.c @@ -106,8 +106,3 @@ PJ *PROJECTION(putp1) { return setup(P); } - -int pj_eck3_selftest (void) {return 10000;} -int pj_kav7_selftest (void) {return 10000;} -int pj_wag6_selftest (void) {return 10000;} -int pj_putp1_selftest (void) {return 10000;} diff --git a/src/PJ_eck4.c b/src/PJ_eck4.c index 8c323656..c3e1b677 100644 --- a/src/PJ_eck4.c +++ b/src/PJ_eck4.c @@ -59,5 +59,3 @@ PJ *PROJECTION(eck4) { return P; } - -int pj_eck4_selftest (void) {return 10000;} diff --git a/src/PJ_eck5.c b/src/PJ_eck5.c index 69e83eda..34a258ee 100644 --- a/src/PJ_eck5.c +++ b/src/PJ_eck5.c @@ -36,4 +36,3 @@ PJ *PROJECTION(eck5) { return P; } -int pj_eck5_selftest (void) {return 10000;} diff --git a/src/PJ_eqc.c b/src/PJ_eqc.c index 2b69788f..908147a2 100644 --- a/src/PJ_eqc.c +++ b/src/PJ_eqc.c @@ -49,4 +49,3 @@ PJ *PROJECTION(eqc) { } -int pj_eqc_selftest (void) {return 10000;} diff --git a/src/PJ_eqdc.c b/src/PJ_eqdc.c index 6e9d2c75..e1f8ea16 100644 --- a/src/PJ_eqdc.c +++ b/src/PJ_eqdc.c @@ -130,4 +130,3 @@ PJ *PROJECTION(eqdc) { } -int pj_eqdc_selftest (void) {return 10000;} diff --git a/src/PJ_fahey.c b/src/PJ_fahey.c index 4fcb7849..53606119 100644 --- a/src/PJ_fahey.c +++ b/src/PJ_fahey.c @@ -37,4 +37,3 @@ PJ *PROJECTION(fahey) { return P; } -int pj_fahey_selftest (void) {return 10000;} diff --git a/src/PJ_fouc_s.c b/src/PJ_fouc_s.c index c581e690..b8ae4a0c 100644 --- a/src/PJ_fouc_s.c +++ b/src/PJ_fouc_s.c @@ -67,4 +67,3 @@ PJ *PROJECTION(fouc_s) { } -int pj_fouc_s_selftest (void) {return 10000;} diff --git a/src/PJ_gall.c b/src/PJ_gall.c index 8a003073..cb213e2d 100644 --- a/src/PJ_gall.c +++ b/src/PJ_gall.c @@ -41,4 +41,3 @@ PJ *PROJECTION(gall) { } -int pj_gall_selftest (void) {return 10000;} diff --git a/src/PJ_geos.c b/src/PJ_geos.c index 7d527409..a787db23 100644 --- a/src/PJ_geos.c +++ b/src/PJ_geos.c @@ -234,4 +234,3 @@ PJ *PROJECTION(geos) { } -int pj_geos_selftest (void) {return 10000;} diff --git a/src/PJ_gins8.c b/src/PJ_gins8.c index 26db4f31..ae0d4dee 100644 --- a/src/PJ_gins8.c +++ b/src/PJ_gins8.c @@ -31,4 +31,3 @@ PJ *PROJECTION(gins8) { } -int pj_gins8_selftest (void) {return 10000;} diff --git a/src/PJ_gn_sinu.c b/src/PJ_gn_sinu.c index bfe26b53..585d43ca 100644 --- a/src/PJ_gn_sinu.c +++ b/src/PJ_gn_sinu.c @@ -183,8 +183,3 @@ PJ *PROJECTION(gn_sinu) { return P; } - -int pj_sinu_selftest (void) {return 10000;} -int pj_eck6_selftest (void) {return 10000;} -int pj_mbtfps_selftest (void) {return 10000;} -int pj_gn_sinu_selftest (void) {return 10000;} diff --git a/src/PJ_gnom.c b/src/PJ_gnom.c index e5822f4f..12774569 100644 --- a/src/PJ_gnom.c +++ b/src/PJ_gnom.c @@ -138,5 +138,3 @@ PJ *PROJECTION(gnom) { return P; } - -int pj_gnom_selftest (void) {return 10000;} diff --git a/src/PJ_goode.c b/src/PJ_goode.c index 3c5d172d..34312b3b 100644 --- a/src/PJ_goode.c +++ b/src/PJ_goode.c @@ -79,4 +79,3 @@ PJ *PROJECTION(goode) { } -int pj_goode_selftest (void) {return 10000;} diff --git a/src/PJ_gstmerc.c b/src/PJ_gstmerc.c index efb44b88..81ec4e17 100644 --- a/src/PJ_gstmerc.c +++ b/src/PJ_gstmerc.c @@ -68,5 +68,3 @@ PJ *PROJECTION(gstmerc) { return P; } - -int pj_gstmerc_selftest (void) {return 10000;} diff --git a/src/PJ_hammer.c b/src/PJ_hammer.c index 443ce247..4cdaba89 100644 --- a/src/PJ_hammer.c +++ b/src/PJ_hammer.c @@ -71,5 +71,3 @@ PJ *PROJECTION(hammer) { return P; } - -int pj_hammer_selftest (void) {return 10000;} diff --git a/src/PJ_hatano.c b/src/PJ_hatano.c index ea4bacf8..79f46a7d 100644 --- a/src/PJ_hatano.c +++ b/src/PJ_hatano.c @@ -79,4 +79,3 @@ PJ *PROJECTION(hatano) { return P; } -int pj_hatano_selftest (void) {return 10000;} diff --git a/src/PJ_healpix.c b/src/PJ_healpix.c index 2d2af805..d8e1a921 100644 --- a/src/PJ_healpix.c +++ b/src/PJ_healpix.c @@ -668,6 +668,3 @@ PJ *PROJECTION(rhealpix) { return P; } - -int pj_healpix_selftest (void) {return 10000;} -int pj_rhealpix_selftest (void) {return 10000;} diff --git a/src/PJ_helmert.c b/src/PJ_helmert.c index 39746aaa..478a2c82 100644 --- a/src/PJ_helmert.c +++ b/src/PJ_helmert.c @@ -583,145 +583,3 @@ PJ *TRANSFORMATION(helmert, 0) { return P; } - - -#ifndef PJ_SELFTEST - -int pj_helmert_selftest (void) {return 0;} - -#else - - -static int test (char *args, PJ_TRIPLET in, PJ_TRIPLET expect, double tol) { - PJ_TRIPLET out; - PJ *P = pj_init_plus (args); - - if (0==P) - return 5; - - out.xyz = pj_fwd3d (in.lpz, P); - if (proj_xyz_dist (out.xyz, expect.xyz) > tol) { - proj_log_error(P, "Tolerance of forward calculation not met"); - proj_log_error(P, " Expect: %10.10f, %10.10f, %10.10f", expect.xyz.x, expect.xyz.y, expect.xyz.z); - proj_log_error(P, " Out: %10.10f, %10.10f, %10.10f", out.xyz.x, out.xyz.y, out.xyz.z); - proj_log_level(NULL, 0); - proj_destroy (P); - return 1; - } - - out.lpz = pj_inv3d (out.xyz, P); - if (proj_xyz_dist (out.xyz, in.xyz) > tol) { - proj_log_error(P, "Tolerance of inverse calculation not met"); - proj_log_error(P, " In: %10.10f, %10.10f, %10.10f", in.xyz.x, in.xyz.y, in.xyz.z); - proj_log_error(P, " Out: %10.10f, %10.10f, %10.10f", out.xyz.x, out.xyz.y, out.xyz.z); - proj_log_level(NULL, 0); - proj_destroy (P); - return 2; - } - - proj_destroy (P); - return 0; -} - - - -int pj_helmert_selftest (void) { - int ret; - - /* This example is from - Lotti Jivall: - Simplified transformations from ITRF2008/IGS08 to ETRS89 for maritime applications */ - PJ_TRIPLET in1 = {{3565285.0000, 855949.0000, 5201383.0000}}; - PJ_TRIPLET expect1 = {{3565285.41342351, 855948.67986759, 5201382.72939791}}; - char args1[] = { - " +proj=helmert +ellps=GRS80" - " +x=0.67678 +y=0.65495 +z=-0.52827" - " +rx=-0.022742 +ry=0.012667 +rz=0.022704 +s=-0.01070" - /*" +rx=-22.742 +ry=12.667 +rz=22.704 +s=-0.01070" */ - }; - - - /* This example is a random point, transformed from ED50 to ETRS89 using KMStrans2 */ - PJ_TRIPLET in2 = {{3494994.3012, 1056601.9725, 5212382.1666}}; - PJ_TRIPLET expect2 = {{3494909.84026368, 1056506.78938633, 5212265.66699761}}; - char args2[] = { - " +proj=helmert +ellps=GRS80" - " +x=-81.0703 +y=-89.3603 +z=-115.7526" - " +rx=-0.48488 +ry=-0.02436 +rz=-0.41321 +s=-0.540645" - }; - - - /* This example is a coordinate from the geodetic observatory in Onsala, - Sweden transformed from ITRF2000 @ 2017.0 to ITRF93 @ 2017.0. - The test coordinate was transformed using GNSStrans. - Transformation parameters published by ITRF: - ftp://itrf.ensg.ign.fr/pub/itrf/ITRF.TP */ - PJ_TRIPLET in3 = {{3370658.378, 711877.314, 5349787.086}}; /* ITRF2000@2017.0 */ - PJ_TRIPLET expect3 = {{3370658.18890, 711877.42370, 5349787.12430}}; /* ITRF93@2017.0 */ - char args3[] = { - " +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 +tobs=2017.0 +transpose" - }; - - /* Test the 4D-capabilities of the proj.h API, especially that the rotation - matrix is updated when necessary. Test coordinates from GNSStrans. */ - XYZ expect4a = {3370658.18890, 711877.42370, 5349787.12430}; - XYZ expect4b = {3370658.18087, 711877.42750, 5349787.12648}; - PJ_COORD in4 = {{3370658.378, 711877.314, 5349787.086, 2017.0}}; - PJ_COORD out; - - PJ *helmert = proj_create( - 0, - " +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" - ); - - /* This example is from "A mathematical relationship between NAD27 and NAD83 (91) - State Plane coordinates in Southeastern Wisconsin": - - http://www.sewrpc.org/SEWRPCFiles/Publications/TechRep/tr-034-Mathematical-Relationship-Between-NAD27-and-NAD83-91-State-Plane-Coordinates-Southeastern-Wisconsin.pdf - - The test data is taken from p. 29. Here we are using point 203 and converting it - from NAD27 (ft) -> NAD83 (m). The paper reports a difference of 0.0014 m from measured - to computed coordinates, hence the test tolerance is set accordingly. */ - PJ_TRIPLET in5 = {{2546506.957, 542256.609, 0}}; - PJ_TRIPLET expect5 = {{766563.675, 165282.277, 0}}; - char args5[] = " +proj=helmert +ellps=GRS80 +x=-9597.3572 +y=.6112 +s=0.304794780637 +theta=-1.244048"; - - /* Run tests 1-3 & 5 */ - ret = test (args1, in1, expect1, 1e-4); if (ret) return ret; - ret = test (args2, in2, expect2, 1e-4); if (ret) return ret + 10; - ret = test (args3, in3, expect3, 1e-4); if (ret) return ret + 20; - ret = test (args5, in5, expect5, 0.001); if (ret) return ret + 40; - - /* Run test 4 */ - out = proj_trans (helmert, PJ_FWD, in4); - if (proj_xyz_dist (out.xyz, expect4a) > 1e-4) { - proj_log_error(helmert, "Tolerance of test 4a not met!"); - proj_log_error(helmert, " In: %10.10f, %10.10f, %10.10f", in4.xyz.x, in4.xyz.y, in4.xyz.z); - proj_log_error(helmert, " Out: %10.10f, %10.10f, %10.10f", out.xyz.x, out.xyz.y, out.xyz.z); - return 31; - } - - in4.xyzt.t = 2018.0; - out = proj_trans (helmert, PJ_FWD, in4); - if (proj_xyz_dist (out.xyz, expect4b) > 1e-4) { - proj_log_error(helmert, "Tolerance of test 4b not met!"); - proj_log_error(helmert, " In: %10.10f, %10.10f, %10.10f", in4.xyz.x, in4.xyz.y, in4.xyz.z); - proj_log_error(helmert, " Out: %10.10f, %10.10f, %10.10f", out.xyz.x, out.xyz.y, out.xyz.z); - return 32; - } - - proj_destroy(helmert); - return 0; -} - -#endif diff --git a/src/PJ_hgridshift.c b/src/PJ_hgridshift.c index d57af697..92275e51 100644 --- a/src/PJ_hgridshift.c +++ b/src/PJ_hgridshift.c @@ -73,53 +73,3 @@ PJ *TRANSFORMATION(hgridshift,0) { return P; } - -#ifndef PJ_SELFTEST -/* selftest stub */ -int pj_hgridshift_selftest (void) {return 0;} -#else -int pj_hgridshift_selftest (void) { - PJ *P; - PJ_COORD expect, a, b; - double dist; - - /* fail on purpose: +grids parameter is mandatory*/ - P = proj_create(PJ_DEFAULT_CTX, "+proj=hgridshift"); - if (0!=P) { - proj_destroy (P); - return 99; - } - - /* fail on purpose: open non-existing grid */ - P = proj_create(PJ_DEFAULT_CTX, "+proj=hgridshift +grids=@nonexistinggrid.gsb,anothernonexistinggrid.gsb"); - if (0!=P) { - proj_destroy (P); - return 999; - } - - /* Failure most likely means the grid is missing */ - P = proj_create(PJ_DEFAULT_CTX, "+proj=hgridshift +grids=nzgd2kgrid0005.gsb +ellps=GRS80"); - if (0==P) - return 10; - - 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, &b); - if (dist > 0.00000001) { - printf("dist: %f\n",dist); - return 1; - } - - expect.lpz.lam = PJ_TORAD(172.999892181021551); - expect.lpz.phi = PJ_TORAD(-45.001620431954613); - b = proj_trans(P, PJ_FWD, a); - if (proj_xy_dist(expect.xy, b.xy) > 1e-4) - return 2; - - proj_destroy(P); - return 0; -} -#endif diff --git a/src/PJ_horner.c b/src/PJ_horner.c index 51c271ae..6f1450cd 100644 --- a/src/PJ_horner.c +++ b/src/PJ_horner.c @@ -486,86 +486,3 @@ PJ *PROJECTION(horner) { return P; } -#ifndef PJ_SELFTEST -/* selftest stub */ -int pj_horner_selftest (void) {return 0;} -#else -char tc32_utm32[] = { - " +proj=horner" - " +ellps=intl" - " +range=500000" - " +fwd_origin=877605.269066,6125810.306769" - " +inv_origin=877605.760036,6125811.281773" - " +deg=4" - " +fwd_v=6.1258112678e+06,9.9999971567e-01,1.5372750011e-10,5.9300860915e-15,2.2609497633e-19,4.3188227445e-05,2.8225130416e-10,7.8740007114e-16,-1.7453997279e-19,1.6877465415e-10,-1.1234649773e-14,-1.7042333358e-18,-7.9303467953e-15,-5.2906832535e-19,3.9984284847e-19" - " +fwd_u=8.7760574982e+05,9.9999752475e-01,2.8817299305e-10,5.5641310680e-15,-1.5544700949e-18,-4.1357045890e-05,4.2106213519e-11,2.8525551629e-14,-1.9107771273e-18,3.3615590093e-10,2.4380247154e-14,-2.0241230315e-18,1.2429019719e-15,5.3886155968e-19,-1.0167505000e-18" - " +inv_v=6.1258103208e+06,1.0000002826e+00,-1.5372762184e-10,-5.9304261011e-15,-2.2612705361e-19,-4.3188331419e-05,-2.8225549995e-10,-7.8529116371e-16,1.7476576773e-19,-1.6875687989e-10,1.1236475299e-14,1.7042518057e-18,7.9300735257e-15,5.2881862699e-19,-3.9990736798e-19" - " +inv_u=8.7760527928e+05,1.0000024735e+00,-2.8817540032e-10,-5.5627059451e-15,1.5543637570e-18,4.1357152105e-05,-4.2114813612e-11,-2.8523713454e-14,1.9109017837e-18,-3.3616407783e-10,-2.4382678126e-14,2.0245020199e-18,-1.2441377565e-15,-5.3885232238e-19,1.0167203661e-18" -}; - - -char sb_utm32[] = { - " +proj=horner" - " +ellps=intl" - " +range=500000" - " +tolerance=0.0005" - " +fwd_origin=4.94690026817276e+05,6.13342113183056e+06" - " +inv_origin=6.19480258923588e+05,6.13258568148837e+06" - " +deg=3" - " +fwd_c=6.13258562111350e+06,6.19480105709997e+05,9.99378966275206e-01,-2.82153291753490e-02,-2.27089979140026e-10,-1.77019590701470e-09,1.08522286274070e-14,2.11430298751604e-15" - " +inv_c=6.13342118787027e+06,4.94690181709311e+05,9.99824464710368e-01,2.82279070814774e-02,7.66123542220864e-11,1.78425334628927e-09,-1.05584823306400e-14,-3.32554258683744e-15" -}; - -int pj_horner_selftest (void) { - PJ *P; - PJ_COORD a, b, c; - double dist; - - /* Real polynonia relating the technical coordinate system TC32 to "System 45 Bornholm" */ - P = proj_create (PJ_DEFAULT_CTX, tc32_utm32); - if (0==P) - return 10; - - 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, &c); - if (dist > 0.01) - return 1; - - /* The complex polynomial transformation between the "System Storebaelt" and utm32/ed50 */ - P = proj_create (PJ_DEFAULT_CTX, sb_utm32); - if (0==P) - return 11; - - /* Test value: utm32_ed50(620000, 6130000) = sb_ed50(495136.8544, 6130821.2945) */ - a = b = c = proj_coord (0,0,0,0); - a.uv.v = 6130821.2945; - a.uv.u = 495136.8544; - c.uv.v = 6130000.0000; - c.uv.u = 620000.0000; - - /* Forward projection */ - b = proj_trans (P, PJ_FWD, a); - dist = proj_xy_dist (b.xy, c.xy); - if (dist > 0.001) - return 2; - - /* Inverse projection */ - b = proj_trans (P, PJ_INV, c); - dist = proj_xy_dist (b.xy, a.xy); - if (dist > 0.001) - return 3; - - /* Check roundtrip precision for 1 iteration each way */ - dist = proj_roundtrip (P, PJ_FWD, 1, &a); - if (dist > 0.01) - return 4; - - proj_destroy(P); - return 0; -} -#endif diff --git a/src/PJ_igh.c b/src/PJ_igh.c index 01cfa246..d1d684e7 100644 --- a/src/PJ_igh.c +++ b/src/PJ_igh.c @@ -222,4 +222,3 @@ PJ *PROJECTION(igh) { } -int pj_igh_selftest (void) {return 10000;} diff --git a/src/PJ_imw_p.c b/src/PJ_imw_p.c index f0c88efb..9ebb8b4a 100644 --- a/src/PJ_imw_p.c +++ b/src/PJ_imw_p.c @@ -211,5 +211,3 @@ PJ *PROJECTION(imw_p) { return P; } - -int pj_imw_p_selftest (void) {return 10000;} diff --git a/src/PJ_isea.c b/src/PJ_isea.c index 72c34744..bf006a62 100644 --- a/src/PJ_isea.c +++ b/src/PJ_isea.c @@ -1147,5 +1147,3 @@ PJ *PROJECTION(isea) { return P; } - -int pj_isea_selftest (void) {return 10000;} diff --git a/src/PJ_krovak.c b/src/PJ_krovak.c index 929a2a6d..ef00d715 100644 --- a/src/PJ_krovak.c +++ b/src/PJ_krovak.c @@ -219,5 +219,3 @@ PJ *PROJECTION(krovak) { return P; } - -int pj_krovak_selftest (void) {return 10000;} diff --git a/src/PJ_labrd.c b/src/PJ_labrd.c index 7db03249..16c45a0d 100644 --- a/src/PJ_labrd.c +++ b/src/PJ_labrd.c @@ -128,5 +128,3 @@ PJ *PROJECTION(labrd) { return P; } - -int pj_labrd_selftest (void) {return 10000;} diff --git a/src/PJ_laea.c b/src/PJ_laea.c index 5cf5f5cd..82a341d8 100644 --- a/src/PJ_laea.c +++ b/src/PJ_laea.c @@ -295,5 +295,3 @@ PJ *PROJECTION(laea) { return P; } - -int pj_laea_selftest (void) {return 10000;} diff --git a/src/PJ_lagrng.c b/src/PJ_lagrng.c index 584f9a7a..b4744ed5 100644 --- a/src/PJ_lagrng.c +++ b/src/PJ_lagrng.c @@ -61,5 +61,3 @@ PJ *PROJECTION(lagrng) { return P; } - -int pj_lagrng_selftest (void) {return 10000;} diff --git a/src/PJ_larr.c b/src/PJ_larr.c index dc791ba0..a8d1af56 100644 --- a/src/PJ_larr.c +++ b/src/PJ_larr.c @@ -24,5 +24,3 @@ PJ *PROJECTION(larr) { return P; } - -int pj_larr_selftest (void) {return 10000;} diff --git a/src/PJ_lask.c b/src/PJ_lask.c index 998b3bbe..0bb3812c 100644 --- a/src/PJ_lask.c +++ b/src/PJ_lask.c @@ -37,4 +37,3 @@ PJ *PROJECTION(lask) { return P; } -int pj_lask_selftest (void) {return 10000;} diff --git a/src/PJ_latlong.c b/src/PJ_latlong.c index 612bef78..5919023a 100644 --- a/src/PJ_latlong.c +++ b/src/PJ_latlong.c @@ -123,15 +123,3 @@ PJ *PROJECTION(lonlat) { return P; } - -/* Bogus self-test functions. Self-tests can't be implemented the usual way for - * these "projections" since they can't be used directly from proj. - * We still need them though, as all projections are automatically added to - * the list of self-test functions. - * - * The code should be covered by the tests in nad/. - * */ -int pj_latlong_selftest (void) {return 10000;} -int pj_longlat_selftest (void) {return 10000;} -int pj_latlon_selftest (void) {return 10000;} -int pj_lonlat_selftest (void) {return 10000;} diff --git a/src/PJ_lcc.c b/src/PJ_lcc.c index 4a392690..bc02667a 100644 --- a/src/PJ_lcc.c +++ b/src/PJ_lcc.c @@ -144,5 +144,3 @@ PJ *PROJECTION(lcc) { return P; } - -int pj_lcc_selftest (void) {return 10000;} diff --git a/src/PJ_lcca.c b/src/PJ_lcca.c index 6aa33c4f..61b2ed02 100644 --- a/src/PJ_lcca.c +++ b/src/PJ_lcca.c @@ -158,6 +158,3 @@ PJ *PROJECTION(lcca) { return P; } - - -int pj_lcca_selftest (void) {return 10000;} diff --git a/src/PJ_loxim.c b/src/PJ_loxim.c index 2b3e922d..bb870713 100644 --- a/src/PJ_loxim.c +++ b/src/PJ_loxim.c @@ -71,5 +71,3 @@ PJ *PROJECTION(loxim) { return P; } - -int pj_loxim_selftest (void) {return 10000;} diff --git a/src/PJ_lsat.c b/src/PJ_lsat.c index b3c36fe8..65b20fe4 100644 --- a/src/PJ_lsat.c +++ b/src/PJ_lsat.c @@ -208,5 +208,3 @@ PJ *PROJECTION(lsat) { return P; } - -int pj_lsat_selftest (void) {return 10000;} diff --git a/src/PJ_mbt_fps.c b/src/PJ_mbt_fps.c index 6499249c..2fccf3aa 100644 --- a/src/PJ_mbt_fps.c +++ b/src/PJ_mbt_fps.c @@ -53,4 +53,3 @@ PJ *PROJECTION(mbt_fps) { return P; } -int pj_mbt_fps_selftest (void) {return 10000;} diff --git a/src/PJ_mbtfpp.c b/src/PJ_mbtfpp.c index 61254859..3bf2fa94 100644 --- a/src/PJ_mbtfpp.c +++ b/src/PJ_mbtfpp.c @@ -61,4 +61,3 @@ PJ *PROJECTION(mbtfpp) { return P; } -int pj_mbtfpp_selftest (void) {return 10000;} diff --git a/src/PJ_mbtfpq.c b/src/PJ_mbtfpq.c index a3743b59..4a0d48df 100644 --- a/src/PJ_mbtfpq.c +++ b/src/PJ_mbtfpq.c @@ -70,4 +70,3 @@ PJ *PROJECTION(mbtfpq) { return P; } -int pj_mbtfpq_selftest (void) {return 10000;} diff --git a/src/PJ_merc.c b/src/PJ_merc.c index 994d540f..5e0827b7 100644 --- a/src/PJ_merc.c +++ b/src/PJ_merc.c @@ -76,5 +76,3 @@ PJ *PROJECTION(merc) { return P; } - -int pj_merc_selftest (void) {return 10000;} diff --git a/src/PJ_mill.c b/src/PJ_mill.c index c491d79d..fdb0b2ad 100644 --- a/src/PJ_mill.c +++ b/src/PJ_mill.c @@ -33,5 +33,3 @@ PJ *PROJECTION(mill) { return P; } - -int pj_mill_selftest (void) {return 10000;} diff --git a/src/PJ_misrsom.c b/src/PJ_misrsom.c index 77717f03..d23f5fa8 100644 --- a/src/PJ_misrsom.c +++ b/src/PJ_misrsom.c @@ -215,5 +215,3 @@ PJ *PROJECTION(misrsom) { return P; } - -int pj_misrsom_selftest (void) {return 10000;} diff --git a/src/PJ_mod_ster.c b/src/PJ_mod_ster.c index ca81a43f..c8e4c6b8 100644 --- a/src/PJ_mod_ster.c +++ b/src/PJ_mod_ster.c @@ -277,9 +277,3 @@ PJ *PROJECTION(gs50) { return setup(P); } - -int pj_mil_os_selftest (void) {return 10000;} -int pj_lee_os_selftest (void) {return 10000;} -int pj_gs48_selftest (void) {return 10000;} -int pj_alsk_selftest (void) {return 10000;} -int pj_gs50_selftest (void) {return 10000;} diff --git a/src/PJ_moll.c b/src/PJ_moll.c index 80dd70d0..66e6315a 100644 --- a/src/PJ_moll.c +++ b/src/PJ_moll.c @@ -106,6 +106,3 @@ PJ *PROJECTION(wag5) { return P; } -int pj_moll_selftest (void) {return 10000;} -int pj_wag4_selftest (void) {return 10000;} -int pj_wag5_selftest (void) {return 10000;} diff --git a/src/PJ_molodensky.c b/src/PJ_molodensky.c index 73d0e5c2..1b0eb3a1 100644 --- a/src/PJ_molodensky.c +++ b/src/PJ_molodensky.c @@ -312,83 +312,3 @@ PJ *TRANSFORMATION(molodensky,1) { return P; } - -#ifndef PJ_SELFTEST -int pj_molodensky_selftest (void) {return 0;} -#else -int pj_molodensky_selftest (void) { - - PJ_COORD in, ni, res, exp; - PJ *P; - - /* Test the abridged Molodensky first. Example from appendix 3 of Deakin (2004). */ - 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 10; - - in.lpz.lam = PJ_TORAD(144.9667); - in.lpz.phi = PJ_TORAD(-37.8); - in.lpz.z = 50.0; - - exp.lpz.lam = PJ_TORAD(144.968); - exp.lpz.phi = PJ_TORAD(-37.79848); - exp.lpz.z = 46.378; - - res = proj_trans(P, PJ_FWD, in); - - if (proj_lp_dist(P, res.lp, exp.lp) > 2 ) { /* we don't expect much accurecy here... */ - proj_destroy(P); - return 11; - } - - /* let's try a roundtrip */ - ni = in; - if (proj_roundtrip(P, PJ_FWD, 100, &ni) > 1) { - proj_destroy(P); - return 12; - } - - if (res.lpz.z - exp.lpz.z > 1e-3) { - proj_destroy(P); - return 13; - } - - proj_destroy(P); - - /* Test the abridged Molodensky first. Example from appendix 3 of Deaking (2004). */ - - 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 " - ); - if (0==P) - return 20; - - res = proj_trans(P, PJ_FWD, in); - - if (proj_lp_dist(P, res.lp, exp.lp) > 2 ) { /* we don't expect much accurecy here... */ - proj_destroy(P); - return 21; - } - - /* let's try a roundtrip */ - ni = in; - if (proj_roundtrip(P, PJ_FWD, 100, &ni) > 1) { - proj_destroy(P); - return 22; - } - - if (res.lpz.z - exp.lpz.z > 1e-3) { - proj_destroy(P); - return 23; - } - - proj_destroy(P); - return 0; -} - -#endif diff --git a/src/PJ_natearth.c b/src/PJ_natearth.c index 2395ebb5..10abb23c 100644 --- a/src/PJ_natearth.c +++ b/src/PJ_natearth.c @@ -96,4 +96,3 @@ PJ *PROJECTION(natearth) { return P; } -int pj_natearth_selftest (void) {return 10000;} diff --git a/src/PJ_natearth2.c b/src/PJ_natearth2.c index 162fd768..dbdc8fed 100644 --- a/src/PJ_natearth2.c +++ b/src/PJ_natearth2.c @@ -93,4 +93,3 @@ PJ *PROJECTION(natearth2) { return P; } -int pj_natearth2_selftest (void) {return 10000;} diff --git a/src/PJ_nell.c b/src/PJ_nell.c index c4d65b88..51f9f99a 100644 --- a/src/PJ_nell.c +++ b/src/PJ_nell.c @@ -47,4 +47,3 @@ PJ *PROJECTION(nell) { return P; } -int pj_nell_selftest (void) {return 10000;} diff --git a/src/PJ_nell_h.c b/src/PJ_nell_h.c index ebc8be90..24957786 100644 --- a/src/PJ_nell_h.c +++ b/src/PJ_nell_h.c @@ -49,5 +49,3 @@ PJ *PROJECTION(nell_h) { return P; } - -int pj_nell_h_selftest (void) {return 10000;} diff --git a/src/PJ_nocol.c b/src/PJ_nocol.c index aed5c382..13688a9f 100644 --- a/src/PJ_nocol.c +++ b/src/PJ_nocol.c @@ -50,4 +50,3 @@ PJ *PROJECTION(nicol) { return P; } -int pj_nicol_selftest (void) {return 10000;} diff --git a/src/PJ_nsper.c b/src/PJ_nsper.c index b83b807b..0b3a1d1b 100644 --- a/src/PJ_nsper.c +++ b/src/PJ_nsper.c @@ -195,50 +195,3 @@ PJ *PROJECTION(tpers) { return setup(P); } - -#ifndef PJ_SELFTEST -int pj_nsper_selftest (void) {return 0;} -#else - -int pj_nsper_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char s_args[] = {"+proj=nsper +a=6400000 +h=1000000"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY s_fwd_expect[] = { - { 222239.816114099842, 111153.763991924759}, - { 222239.816114099842, -111153.763991924759}, - {-222239.816114099842, 111153.763991924759}, - {-222239.816114099842, -111153.763991924759}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP s_inv_expect[] = { - { 0.00179049311728792437, 0.000895246558425396135}, - { 0.00179049311728792437, -0.000895246558425396135}, - {-0.00179049311728792437, 0.000895246558425396135}, - {-0.00179049311728792437, -0.000895246558425396135}, - }; - - return pj_generic_selftest (0, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, 0, s_fwd_expect, inv_in, 0, s_inv_expect); -} - - -#endif - - -int pj_tpers_selftest (void) {return 10000;} diff --git a/src/PJ_nzmg.c b/src/PJ_nzmg.c index 04128cfb..2d65a6e1 100644 --- a/src/PJ_nzmg.c +++ b/src/PJ_nzmg.c @@ -118,5 +118,3 @@ PJ *PROJECTION(nzmg) { return P; } - -int pj_nzmg_selftest (void) {return 10000;} diff --git a/src/PJ_ob_tran.c b/src/PJ_ob_tran.c index 3add8b29..4ce4bd4d 100644 --- a/src/PJ_ob_tran.c +++ b/src/PJ_ob_tran.c @@ -238,40 +238,3 @@ PJ *PROJECTION(ob_tran) { return P; } -#ifndef PJ_SELFTEST -int pj_ob_tran_selftest (void) {return 0;} -#else - -int pj_ob_tran_selftest (void) { - double d; - PJ *P; - PJ_COORD a, b; - - /* -- Tests from nad/testvarious -------------------------------------------- */ - P = proj_create (0, "+proj=ob_tran +o_proj=moll +R=6378137.0 +o_lon_p=0 +o_lat_p=0 +lon_0=180"); - if (0==P) - return 1; - - a = proj_coord (300000, 400000, 0, 0); - b.lpz.lam = -proj_torad (42 + (45 + 22.377/60)/60); - b.lpz.phi = proj_torad (85 + (35 + 28.083/60)/60); - a = proj_trans (P, -1, a); - d = proj_lp_dist (P, a.lp, b.lp); - if (d > 1e-3) - return 2; - - a = proj_coord (proj_torad(10), proj_torad(20), 0, 0); - b = proj_coord (-1384841.18787, 7581707.88240, 0, 0); - a = proj_trans (P, 1, a); - d = proj_xy_dist (a.xy, b.xy); - if (d > 1e-3) - return 3; - - proj_destroy (P); - /* -------------------------------------------------------------------------- */ - - - return 0; -} - -#endif \ No newline at end of file diff --git a/src/PJ_ocea.c b/src/PJ_ocea.c index b4b6d68c..33760180 100644 --- a/src/PJ_ocea.c +++ b/src/PJ_ocea.c @@ -96,5 +96,3 @@ PJ *PROJECTION(ocea) { return P; } - -int pj_ocea_selftest (void) {return 10000;} diff --git a/src/PJ_oea.c b/src/PJ_oea.c index aeef87c0..58ea7e93 100644 --- a/src/PJ_oea.c +++ b/src/PJ_oea.c @@ -82,5 +82,3 @@ PJ *PROJECTION(oea) { return P; } - -int pj_oea_selftest (void) {return 10000;} diff --git a/src/PJ_omerc.c b/src/PJ_omerc.c index b29033eb..22f0daca 100644 --- a/src/PJ_omerc.c +++ b/src/PJ_omerc.c @@ -223,5 +223,3 @@ PJ *PROJECTION(omerc) { return P; } - -int pj_omerc_selftest (void) {return 10000;} diff --git a/src/PJ_ortho.c b/src/PJ_ortho.c index a497b160..4da8247f 100644 --- a/src/PJ_ortho.c +++ b/src/PJ_ortho.c @@ -130,5 +130,3 @@ PJ *PROJECTION(ortho) { return P; } - -int pj_ortho_selftest (void) {return 10000;} diff --git a/src/PJ_patterson.c b/src/PJ_patterson.c index 9f9e3e39..0a1113ac 100644 --- a/src/PJ_patterson.c +++ b/src/PJ_patterson.c @@ -113,5 +113,3 @@ PJ *PROJECTION(patterson) { return P; } - -int pj_patterson_selftest (void) {return 10000;} diff --git a/src/PJ_pipeline.c b/src/PJ_pipeline.c index 0729b1da..e1568423 100644 --- a/src/PJ_pipeline.c +++ b/src/PJ_pipeline.c @@ -444,127 +444,3 @@ PJ *OPERATION(pipeline,0) { return P; } -#ifndef PJ_SELFTEST -/* selftest stub */ -int pj_pipeline_selftest (void) {return 0;} -#else - -int pj_pipeline_selftest (void) { - PJ *P; - PJ_COORD a, b; - XY cph_utm32 = {691875.63214, 6098907.82501}; - double dist; - - /* forward-reverse geo->utm->geo */ - P = proj_create (PJ_DEFAULT_CTX, "+proj=pipeline +zone=32 +step +proj=utm +ellps=GRS80 +step +proj=utm +ellps=GRS80 +inv"); - if (0==P) - return 1000; - /* zero initialize everything, then set (longitude, latitude, height) to (12, 55, 0) */ - a = b = proj_coord (0,0,0,0); - a.lpz.lam = PJ_TORAD(12); - a.lpz.phi = PJ_TORAD(55); - a.lpz.z = 10; - - /* Forward projection */ - b = proj_trans (P, PJ_FWD, a); - if (proj_lp_dist (P, a.lp, b.lp) > 1e-4) - return 1001; - - /* Inverse projection (still same result: pipeline is symmetrical) */ - a = proj_trans (P, PJ_INV, b); - if (proj_lp_dist (P, a.lp, b.lp) > 1e-4) - return 1002; - - proj_destroy (P); - - /* And now the back-to-back situation utm->geo->utm */ - P = proj_create (PJ_DEFAULT_CTX, "+proj=pipeline +zone=32 +step +proj=utm +ellps=GRS80 +inv +step +proj=utm +ellps=GRS80"); - if (0==P) - return 2000; - - /* zero initialize everything, then set (easting, northing) to utm(12, 55) */ - a = b = proj_coord (0,0,0,0); - a.xy = cph_utm32; - - /* Forward projection */ - b = proj_trans (P, PJ_FWD, a); - if (proj_xy_dist (a.xy, b.xy) > 1e-4) - return 2001; - - /* Inverse projection */ - a = proj_trans (P, PJ_INV, b); - if (proj_xy_dist (a.xy, b.xy) > 1e-4) - return 2001; - if (proj_xyz_dist (a.xyz, b.xyz) > 1e-4) - return 2002; - - proj_destroy (P); - - - /* Finally testing a corner case: A rather pointless one-step pipeline geo->utm */ - P = proj_create (PJ_DEFAULT_CTX, "+proj=pipeline +zone=32 +step +proj=utm +ellps=GRS80 "); - if (0==P) - return 3000; - - - a = b = proj_coord (0,0,0,0); - a.lpz.lam = PJ_TORAD(12); - a.lpz.phi = PJ_TORAD(55); - - /* Forward projection */ - b = proj_trans (P, PJ_FWD, a); - if (proj_xy_dist (cph_utm32, b.xy) > 1e-4) - return 3001; - - /* Inverse projection */ - b = proj_trans (P, PJ_INV, b); - if (proj_lp_dist (P, a.lp, b.lp) > 1e-4) - return 3002; - - - /* Since we use pj_lp_dist to determine success above, we should also test that it works */ - - /* Geodesic distance between two points with angular 2D coordinates */ - a.lp.lam = PJ_TORAD(12); - a.lp.phi = PJ_TORAD(60); - b.lp.lam = PJ_TORAD(12); - b.lp.phi = PJ_TORAD(61); - dist = proj_lp_dist (P, a.lp, b.lp); - if (fabs (111420.727870234 - dist) > 1e-4) - return 4001; - - a.lp.lam = PJ_TORAD(12); - a.lp.phi = PJ_TORAD(0.); - b.lp.lam = PJ_TORAD(12); - b.lp.phi = PJ_TORAD(1.); - dist = proj_lp_dist (P, a.lp, b.lp); - if (fabs (110574.388554153 - dist) > 1e-4) - return 4002; - - proj_destroy (P); - - /* test a pipeline with several +init steps */ - P = proj_create( - 0, - "+proj=pipeline " - "+step +init=epsg:25832 +inv " - "+step +init=epsg:25833 " - "+step +init=epsg:25833 +inv " - "+step +init=epsg:25832 " - ); - if (0==P) - return 5000; - - a.xy.x = 700000.0; - a.xy.y = 6000000.0; - - b = proj_trans(P, PJ_FWD, a); - dist = proj_xy_dist(a.xy, b.xy); - if (dist > 1e-7) - return 5001; - - - proj_destroy (P); - return 0; -} -#endif diff --git a/src/PJ_poly.c b/src/PJ_poly.c index d748be09..7a8fc44d 100644 --- a/src/PJ_poly.c +++ b/src/PJ_poly.c @@ -164,5 +164,3 @@ PJ *PROJECTION(poly) { return P; } - -int pj_poly_selftest (void) {return 10000;} diff --git a/src/PJ_putp2.c b/src/PJ_putp2.c index 59eca8a6..51cf263d 100644 --- a/src/PJ_putp2.c +++ b/src/PJ_putp2.c @@ -57,4 +57,3 @@ PJ *PROJECTION(putp2) { return P; } -int pj_putp2_selftest (void) {return 10000;} diff --git a/src/PJ_putp3.c b/src/PJ_putp3.c index dfd152f8..acc777bc 100644 --- a/src/PJ_putp3.c +++ b/src/PJ_putp3.c @@ -63,5 +63,3 @@ PJ *PROJECTION(putp3p) { return P; } -int pj_putp3_selftest (void) {return 10000;} -int pj_putp3p_selftest (void) {return 10000;} diff --git a/src/PJ_putp4p.c b/src/PJ_putp4p.c index 576ffbf6..958f9681 100644 --- a/src/PJ_putp4p.c +++ b/src/PJ_putp4p.c @@ -70,6 +70,3 @@ PJ *PROJECTION(weren) { return P; } - -int pj_putp4p_selftest (void) {return 10000;} -int pj_weren_selftest (void) {return 10000;} diff --git a/src/PJ_putp5.c b/src/PJ_putp5.c index 2a847fa7..14bfea23 100644 --- a/src/PJ_putp5.c +++ b/src/PJ_putp5.c @@ -69,5 +69,3 @@ PJ *PROJECTION(putp5p) { return P; } -int pj_putp5_selftest (void) {return 10000;} -int pj_putp5p_selftest (void) {return 10000;} diff --git a/src/PJ_putp6.c b/src/PJ_putp6.c index be86f805..8c4efa66 100644 --- a/src/PJ_putp6.c +++ b/src/PJ_putp6.c @@ -91,6 +91,3 @@ PJ *PROJECTION(putp6p) { return P; } - -int pj_putp6_selftest (void) {return 10000;} -int pj_putp6p_selftest (void) {return 10000;} diff --git a/src/PJ_qsc.c b/src/PJ_qsc.c index c8079f9e..36dabeb9 100644 --- a/src/PJ_qsc.c +++ b/src/PJ_qsc.c @@ -398,5 +398,3 @@ PJ *PROJECTION(qsc) { return P; } - -int pj_qsc_selftest (void) {return 10000;} diff --git a/src/PJ_robin.c b/src/PJ_robin.c index a9bac6ec..7532ff71 100644 --- a/src/PJ_robin.c +++ b/src/PJ_robin.c @@ -154,4 +154,3 @@ PJ *PROJECTION(robin) { } -int pj_robin_selftest (void) {return 10000;} diff --git a/src/PJ_rpoly.c b/src/PJ_rpoly.c index 36e5a63e..d7241719 100644 --- a/src/PJ_rpoly.c +++ b/src/PJ_rpoly.c @@ -52,5 +52,3 @@ PJ *PROJECTION(rpoly) { return P; } - -int pj_rpoly_selftest (void) {return 10000;} diff --git a/src/PJ_sch.c b/src/PJ_sch.c index 4ea3404d..c404fc9a 100644 --- a/src/PJ_sch.c +++ b/src/PJ_sch.c @@ -226,7 +226,3 @@ PJ *PROJECTION(sch) { return setup(P); } -/* Skipping sef-test since the test system is not capable of handling - * 3D coordinate systems for the time being. Relying on tests in ../nad/ - */ -int pj_sch_selftest (void) {return 10000;} diff --git a/src/PJ_sconics.c b/src/PJ_sconics.c index 1e00a17e..93a2f2f4 100644 --- a/src/PJ_sconics.c +++ b/src/PJ_sconics.c @@ -214,11 +214,3 @@ PJ *PROJECTION(vitk1) { return setup(P, VITK1); } - -int pj_euler_selftest (void) {return 10000;} -int pj_murd1_selftest (void) {return 10000;} -int pj_murd2_selftest (void) {return 10000;} -int pj_murd3_selftest (void) {return 10000;} -int pj_pconic_selftest (void) {return 10000;} -int pj_tissot_selftest (void) {return 10000;} -int pj_vitk1_selftest (void) {return 10000;} diff --git a/src/PJ_somerc.c b/src/PJ_somerc.c index 69fb6d47..8222ca24 100644 --- a/src/PJ_somerc.c +++ b/src/PJ_somerc.c @@ -88,5 +88,3 @@ PJ *PROJECTION(somerc) { return P; } - -int pj_somerc_selftest (void) {return 10000;} diff --git a/src/PJ_stere.c b/src/PJ_stere.c index 82d83061..c01b86f0 100644 --- a/src/PJ_stere.c +++ b/src/PJ_stere.c @@ -313,6 +313,3 @@ PJ *PROJECTION(ups) { return setup(P); } - -int pj_stere_selftest (void) {return 10000;} -int pj_ups_selftest (void) {return 10000;} diff --git a/src/PJ_sterea.c b/src/PJ_sterea.c index 8a73f453..38b26117 100644 --- a/src/PJ_sterea.c +++ b/src/PJ_sterea.c @@ -114,5 +114,3 @@ PJ *PROJECTION(sterea) { return P; } - -int pj_sterea_selftest (void) {return 10000;} diff --git a/src/PJ_sts.c b/src/PJ_sts.c index 0349e67b..d8866b66 100644 --- a/src/PJ_sts.c +++ b/src/PJ_sts.c @@ -103,9 +103,3 @@ PJ *PROJECTION(mbt_s) { return setup(P, 1.48875, 1.36509, 0); } - - -int pj_fouc_selftest (void) {return 10000;} -int pj_kav5_selftest (void) {return 10000;} -int pj_qua_aut_selftest (void) {return 10000;} -int pj_mbt_s_selftest (void) {return 10000;} diff --git a/src/PJ_tcc.c b/src/PJ_tcc.c index 37211fdd..c6600ae0 100644 --- a/src/PJ_tcc.c +++ b/src/PJ_tcc.c @@ -30,5 +30,3 @@ PJ *PROJECTION(tcc) { return P; } - -int pj_tcc_selftest (void) {return 10000;} diff --git a/src/PJ_tcea.c b/src/PJ_tcea.c index 76249827..415b42de 100644 --- a/src/PJ_tcea.c +++ b/src/PJ_tcea.c @@ -32,5 +32,3 @@ PJ *PROJECTION(tcea) { return P; } - -int pj_tcea_selftest (void) {return 10000;} diff --git a/src/PJ_times.c b/src/PJ_times.c index 696c9fd5..74b79393 100644 --- a/src/PJ_times.c +++ b/src/PJ_times.c @@ -75,5 +75,3 @@ PJ *PROJECTION(times) { return P; } - -int pj_times_selftest (void) {return 10000;} diff --git a/src/PJ_tmerc.c b/src/PJ_tmerc.c index 2aa189fd..77fb5826 100644 --- a/src/PJ_tmerc.c +++ b/src/PJ_tmerc.c @@ -204,5 +204,3 @@ PJ *PROJECTION(tmerc) { return setup(P); } - -int pj_tmerc_selftest (void) {return 10000;} diff --git a/src/PJ_tpeqd.c b/src/PJ_tpeqd.c index dd19da8c..eee5b3c3 100644 --- a/src/PJ_tpeqd.c +++ b/src/PJ_tpeqd.c @@ -104,5 +104,3 @@ PJ *PROJECTION(tpeqd) { return P; } - -int pj_tpeqd_selftest (void) {return 0;} diff --git a/src/PJ_unitconvert.c b/src/PJ_unitconvert.c index 3a70903c..523d8897 100644 --- a/src/PJ_unitconvert.c +++ b/src/PJ_unitconvert.c @@ -389,95 +389,3 @@ PJ *CONVERSION(unitconvert,0) { return P; } -#ifndef PJ_SELFTEST - -int pj_unitconvert_selftest (void) {return 0;} - -#else - -static int test_time(char* args, double tol, double t_in, double t_exp) { - PJ_COORD in, out; - PJ *P = proj_create(PJ_DEFAULT_CTX, args); - int ret = 0; - - if (P == 0) - return 5; - - in.xyzt.t = t_in; - - out = proj_trans(P, PJ_FWD, in); - if (fabs(out.xyzt.t - t_exp) > tol) { - proj_log_error(P, "out: %10.10g, expect: %10.10g", out.xyzt.t, t_exp); - ret = 1; - } - out = proj_trans(P, PJ_INV, out); - if (fabs(out.xyzt.t - t_in) > tol) { - proj_log_error(P, "out: %10.10g, expect: %10.10g", out.xyzt.t, t_in); - ret = 2; - } - pj_free(P); - - proj_log_level(NULL, 0); - return ret; -} - -static int test_xyz(char* args, double tol, PJ_TRIPLET in, PJ_TRIPLET exp) { - PJ_COORD out, obs_in; - PJ *P = proj_create(PJ_DEFAULT_CTX, args); - int ret = 0; - - if (P == 0) - return 5; - - obs_in.xyz = in.xyz; - out = proj_trans(P, PJ_FWD, obs_in); - if (proj_xyz_dist(out.xyz, exp.xyz) > tol) { - printf("exp: %10.10g, %10.10g, %10.10g\n", exp.xyz.x, exp.xyz.y, exp.xyz.z); - printf("out: %10.10g, %10.10g, %10.10g\n", out.xyz.x, out.xyz.y, out.xyz.z); - ret = 1; - } - - out = proj_trans(P, PJ_INV, out); - if (proj_xyz_dist(out.xyz, in.xyz) > tol) { - printf("exp: %g, %g, %g\n", in.xyz.x, in.xyz.y, in.xyz.z); - printf("out: %g, %g, %g\n", out.xyz.x, out.xyz.y, out.xyz.z); - ret += 2; - } - proj_destroy(P); - proj_log_level(NULL, 0); - return ret; -} - - -int pj_unitconvert_selftest (void) { - int ret = 0; - char args1[] = "+proj=unitconvert +t_in=decimalyear +t_out=decimalyear"; - double in1 = 2004.25; - - char args2[] = "+proj=unitconvert +t_in=gps_week +t_out=gps_week"; - double in2 = 1782.0; - - char args3[] = "+proj=unitconvert +t_in=mjd +t_out=mjd"; - double in3 = 57390.0; - - char args4[] = "+proj=unitconvert +t_in=gps_week +t_out=decimalyear"; - double in4 = 1877.71428, exp4 = 2016.0; - - char args5[] = "+proj=unitconvert +xy_in=m +xy_out=dm +z_in=cm +z_out=mm"; - PJ_TRIPLET in5 = {{55.25, 23.23, 45.5}}, exp5 = {{552.5, 232.3, 455.0}}; - - char args6[] = "+proj=unitconvert +xy_in=m +xy_out=m +z_in=m +z_out=m"; - PJ_TRIPLET in6 = {{12.3, 45.6, 7.89}}; - - ret = test_time(args1, 1e-6, in1, in1); if (ret) return ret + 10; - ret = test_time(args2, 1e-6, in2, in2); if (ret) return ret + 20; - ret = test_time(args3, 1e-6, in3, in3); if (ret) return ret + 30; - ret = test_time(args4, 1e-6, in4, exp4); if (ret) return ret + 40; - ret = test_xyz (args5, 1e-10, in5, exp5); if (ret) return ret + 50; - ret = test_xyz (args6, 1e-10, in6, in6); if (ret) return ret + 50; - - return 0; - -} - -#endif diff --git a/src/PJ_urm5.c b/src/PJ_urm5.c index e90cc9ee..9960f501 100644 --- a/src/PJ_urm5.c +++ b/src/PJ_urm5.c @@ -50,5 +50,3 @@ PJ *PROJECTION(urm5) { return P; } - -int pj_urm5_selftest (void) {return 10000;} diff --git a/src/PJ_urmfps.c b/src/PJ_urmfps.c index 04ee8296..19719a26 100644 --- a/src/PJ_urmfps.c +++ b/src/PJ_urmfps.c @@ -70,6 +70,3 @@ PJ *PROJECTION(wag1) { return setup(P); } - -int pj_urmfps_selftest (void) {return 10000;} -int pj_wag1_selftest (void) {return 10000;} diff --git a/src/PJ_vandg.c b/src/PJ_vandg.c index 69c7e55c..b6b84bd0 100644 --- a/src/PJ_vandg.c +++ b/src/PJ_vandg.c @@ -105,5 +105,3 @@ PJ *PROJECTION(vandg) { return P; } - -int pj_vandg_selftest (void) {return 10000;} diff --git a/src/PJ_vandg2.c b/src/PJ_vandg2.c index b6b69183..81f28a74 100644 --- a/src/PJ_vandg2.c +++ b/src/PJ_vandg2.c @@ -70,6 +70,3 @@ PJ *PROJECTION(vandg3) { return P; } - -int pj_vandg2_selftest (void) {return 10000;} -int pj_vandg3_selftest (void) {return 10000;} diff --git a/src/PJ_vandg4.c b/src/PJ_vandg4.c index de525810..afffe41f 100644 --- a/src/PJ_vandg4.c +++ b/src/PJ_vandg4.c @@ -51,5 +51,3 @@ PJ *PROJECTION(vandg4) { return P; } - -int pj_vandg4_selftest (void) {return 10000;} diff --git a/src/PJ_vgridshift.c b/src/PJ_vgridshift.c index 5ab4a162..97faa240 100644 --- a/src/PJ_vgridshift.c +++ b/src/PJ_vgridshift.c @@ -75,64 +75,3 @@ PJ *TRANSFORMATION(vgridshift,0) { return P; } - -#ifndef PJ_SELFTEST -/* selftest stub */ -int pj_vgridshift_selftest (void) {return 0;} -#else -int pj_vgridshift_selftest (void) { - PJ *P; - PJ_COORD expect, a, b; - double dist; - int failures = 0; - - /* fail on purpose: +grids parameter is mandatory*/ - P = proj_create(PJ_DEFAULT_CTX, "+proj=vgridshift"); - if (0!=P) { - proj_destroy (P); - return 99; - } - - /* fail on purpose: open non-existing grid */ - P = proj_create(PJ_DEFAULT_CTX, "+proj=vgridshift +grids=nonexistinggrid.gtx"); - if (0!=P) { - proj_destroy (P); - return 999; - } - - /* Failure most likely means the grid is missing */ - P = proj_create(PJ_DEFAULT_CTX, "+proj=vgridshift +grids=egm96_15.gtx +ellps=GRS80"); - if (0==P) - return 10; - - a = proj_coord(0,0,0,0); - a.lpz.lam = PJ_TORAD(12.5); - a.lpz.phi = PJ_TORAD(55.5); - b = a; - dist = proj_roundtrip (P, PJ_FWD, 1, &b); - if (dist > 0.00000001) - return 1; - - expect = a; - /* Appears there is a difference between the egm96_15.gtx distributed by OSGeo4W, */ - /* and the one from http://download.osgeo.org/proj/vdatum/egm96_15/egm96_15.gtx */ - /* Was: expect.lpz.z = -36.021305084228515625; (download.osgeo.org) */ - /* Was: expect.lpz.z = -35.880001068115234000; (OSGeo4W) */ - /* This is annoying, but must be handled elsewhere. So for now, we check for both. */ - expect.lpz.z = -36.021305084228516; - failures = 0; - b = proj_trans(P, PJ_FWD, a); - 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; - - proj_destroy (P); - - return 0; -} -#endif diff --git a/src/PJ_wag2.c b/src/PJ_wag2.c index 14d8f1c4..059494d7 100644 --- a/src/PJ_wag2.c +++ b/src/PJ_wag2.c @@ -32,5 +32,3 @@ PJ *PROJECTION(wag2) { return P; } - -int pj_wag2_selftest (void) {return 10000;} diff --git a/src/PJ_wag3.c b/src/PJ_wag3.c index 09a9291d..5db1e50f 100644 --- a/src/PJ_wag3.c +++ b/src/PJ_wag3.c @@ -44,5 +44,3 @@ PJ *PROJECTION(wag3) { return P; } - -int pj_wag3_selftest (void) {return 10000;} diff --git a/src/PJ_wag7.c b/src/PJ_wag7.c index 55c43534..a820b2cd 100644 --- a/src/PJ_wag7.c +++ b/src/PJ_wag7.c @@ -26,5 +26,3 @@ PJ *PROJECTION(wag7) { return P; } - -int pj_wag7_selftest (void) {return 10000;} diff --git a/src/PJ_wink1.c b/src/PJ_wink1.c index 670ff0f6..f64f97d2 100644 --- a/src/PJ_wink1.c +++ b/src/PJ_wink1.c @@ -40,5 +40,3 @@ PJ *PROJECTION(wink1) { return P; } - -int pj_wink1_selftest (void) {return 10000;} diff --git a/src/PJ_wink2.c b/src/PJ_wink2.c index 512354bb..d715074e 100644 --- a/src/PJ_wink2.c +++ b/src/PJ_wink2.c @@ -48,5 +48,3 @@ PJ *PROJECTION(wink2) { return P; } - -int pj_wink2_selftest (void) {return 10000;} diff --git a/src/gie.c b/src/gie.c index 09a33069..df4a0b07 100644 --- a/src/gie.c +++ b/src/gie.c @@ -435,8 +435,25 @@ static int operation (char *args) { an operation is the general term describing something that can be either a conversion or a transformation) ******************************************************************************/ + int i, j, n; T.op_id++; + + /* compactify the args, so we can fit more info on a line in verbose mode */ + n = (int) strlen (args); + for (i = j = 0; i < n; ) { + /* skip prefix whitespace */ + while (isspace (args[i])) + i++; + /* move a whitespace delimited text string to the left, skipping over superfluous whitespace */ + while ((0!=args[i]) && (!isspace (args[i]))) + args[j++] = args[i++]; + if (args[j+1]!=0) + args[j++] = ' '; + i++; + } + args[j++] = 0; strcpy (&(T.operation[0]), args); + if (T.verbosity > 1) { finish_previous_operation (args); banner (args); @@ -448,15 +465,67 @@ static int operation (char *args) { direction ("forward"); tolerance ("0.5 mm"); + if (T.P) proj_destroy (T.P); T.P = proj_create (0, args); - if (0==T.P) - errmsg(3, "Invalid operation definition!\n %s\n", args); + return 0; } + + +static int pj_unitconvert_selftest (void); +static int pj_cart_selftest (void); +static int pj_horner_selftest (void); +/*****************************************************************************/ +static int builtins (char *args) { +/***************************************************************************** + There are still a few tests that cannot be described using gie + primitives. Instead, they are implemented as builtins, and invoked + using the "builtins" command verb. +******************************************************************************/ + int i; + if (T.verbosity > 1) { + finish_previous_operation (args); + banner ("builtins: unitconvert, horner, cart"); + } + T.op_ok = 0; + T.op_ko = 0; + + i = pj_unitconvert_selftest (); + if (i!=0) { + printf ("pj_unitconvert_selftest fails with %d\n", i); + another_failure(); + } + else + another_success (); + + + i = pj_cart_selftest (); + if (i!=0) { + printf ("pj_cart_selftest fails with %d\n", i); + another_failure(); + } + else + another_success (); + + i = pj_horner_selftest (); + if (i!=0) { + printf ("pj_horner_selftest fails with %d\n", i); + another_failure(); + } + else + another_success (); + + return 0; +} + + + + + static PJ_COORD torad_coord (PJ_COORD a) { PJ_COORD c = a; c.lpz.lam = proj_torad (a.lpz.lam); @@ -496,7 +565,7 @@ static int accept (char *args) { ******************************************************************************/ T.a = parse_coord (args); if (T.verbosity > 3) - printf ("# %s", args); + printf ("# %s\n", args); return 0; } @@ -583,22 +652,58 @@ static int expect (char *args) { ******************************************************************************/ PJ_COORD ci, co, ce; double d; - if (0==T.P) + int expect_failure = 0; + + if (0==strcmp (args, "failure")) + expect_failure = 1; + + if (0==T.P && !expect_failure) { + errmsg(3, "Invalid operation definition!\n %s\n", args); + return another_failure (); + } + + + if (expect_failure) { + /* If we expect failure, and fail, then it's a success... */ + if (0==T.P) + return another_success (); + /* We may still successfully fail even if the proj_create succeeded */ + ci = proj_angular_input (T.P, T.dir)? torad_coord (T.a): T.a; + co = proj_trans (T.P, T.dir, ci); + if (co.xyz.x==HUGE_VAL) + return another_success (); + /* no - we didn't manage to purportedly fail */ return another_failure (); + } + + + if (T.verbosity > 3) { + puts (T.P->inverted? "INVERTED": "NOT INVERTED"); + puts (T.dir== 1? "forward": "reverse"); + puts (proj_angular_input (T.P, T.dir)? "angular in": "linear in"); + puts (proj_angular_output (T.P, T.dir)? "angular out": "linear out"); + } T.e = parse_coord (args); if (HUGE_VAL==T.e.v[0]) return expect_message_cannot_parse (args); - /* expected angular values probably in degrees */ + /* expected angular values, probably in degrees */ ce = proj_angular_output (T.P, T.dir)? torad_coord (T.e): T.e; + if (T.verbosity > 3) + printf ("EXPECTS %.4f %.4f %.4f %.4f\n", ce.v[0],ce.v[1],ce.v[2],ce.v[3]); - /* input ("accepted") values also probably in degrees */ + /* input ("accepted") values, also probably in degrees */ ci = proj_angular_input (T.P, T.dir)? torad_coord (T.a): T.a; + if (T.verbosity > 3) + printf ("ACCEPTS %.4f %.4f %.4f %.4f\n", ci.v[0],ci.v[1],ci.v[2],ci.v[3]); + /* 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; + if (T.verbosity > 3) + printf ("GOT %.4f %.4f %.4f %.4f\n", ci.v[0],ci.v[1],ci.v[2],ci.v[3]); /* but there are a few more possible input conventions... */ if (proj_angular_output (T.P, T.dir)) { @@ -693,6 +798,8 @@ static int dispatch (char *cmnd, char *args) { if (0==strcmp (cmnd, "direction")) return direction (args); if (0==strcmp (cmnd, "TOLERANCE")) return tolerance (args); if (0==strcmp (cmnd, "tolerance")) return tolerance (args); + if (0==strcmp (cmnd, "BUILTINS")) return builtins (args); + if (0==strcmp (cmnd, "builtins")) return builtins (args); if (0==strcmp (cmnd, "ECHO")) return echo (args); if (0==strcmp (cmnd, "echo")) return echo (args); if (0==strcmp (cmnd, "END")) return finish_previous_operation (args), level++, 0; @@ -806,3 +913,619 @@ static char *get_args (char *inp) { return args; return --args; } + + + + + + + + + + + + + + + + + + + +char tc32_utm32[] = { + " +proj=horner" + " +ellps=intl" + " +range=500000" + " +fwd_origin=877605.269066,6125810.306769" + " +inv_origin=877605.760036,6125811.281773" + " +deg=4" + " +fwd_v=6.1258112678e+06,9.9999971567e-01,1.5372750011e-10,5.9300860915e-15,2.2609497633e-19,4.3188227445e-05,2.8225130416e-10,7.8740007114e-16,-1.7453997279e-19,1.6877465415e-10,-1.1234649773e-14,-1.7042333358e-18,-7.9303467953e-15,-5.2906832535e-19,3.9984284847e-19" + " +fwd_u=8.7760574982e+05,9.9999752475e-01,2.8817299305e-10,5.5641310680e-15,-1.5544700949e-18,-4.1357045890e-05,4.2106213519e-11,2.8525551629e-14,-1.9107771273e-18,3.3615590093e-10,2.4380247154e-14,-2.0241230315e-18,1.2429019719e-15,5.3886155968e-19,-1.0167505000e-18" + " +inv_v=6.1258103208e+06,1.0000002826e+00,-1.5372762184e-10,-5.9304261011e-15,-2.2612705361e-19,-4.3188331419e-05,-2.8225549995e-10,-7.8529116371e-16,1.7476576773e-19,-1.6875687989e-10,1.1236475299e-14,1.7042518057e-18,7.9300735257e-15,5.2881862699e-19,-3.9990736798e-19" + " +inv_u=8.7760527928e+05,1.0000024735e+00,-2.8817540032e-10,-5.5627059451e-15,1.5543637570e-18,4.1357152105e-05,-4.2114813612e-11,-2.8523713454e-14,1.9109017837e-18,-3.3616407783e-10,-2.4382678126e-14,2.0245020199e-18,-1.2441377565e-15,-5.3885232238e-19,1.0167203661e-18" +}; + + +char sb_utm32[] = { + " +proj=horner" + " +ellps=intl" + " +range=500000" + " +tolerance=0.0005" + " +fwd_origin=4.94690026817276e+05,6.13342113183056e+06" + " +inv_origin=6.19480258923588e+05,6.13258568148837e+06" + " +deg=3" + " +fwd_c=6.13258562111350e+06,6.19480105709997e+05,9.99378966275206e-01,-2.82153291753490e-02,-2.27089979140026e-10,-1.77019590701470e-09,1.08522286274070e-14,2.11430298751604e-15" + " +inv_c=6.13342118787027e+06,4.94690181709311e+05,9.99824464710368e-01,2.82279070814774e-02,7.66123542220864e-11,1.78425334628927e-09,-1.05584823306400e-14,-3.32554258683744e-15" +}; + +static int pj_horner_selftest (void) { + PJ *P; + PJ_COORD a, b, c; + double dist; + + /* Real polynonia relating the technical coordinate system TC32 to "System 45 Bornholm" */ + P = proj_create (PJ_DEFAULT_CTX, tc32_utm32); + if (0==P) + return 10; + + 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, &c); + if (dist > 0.01) + return 1; + + /* The complex polynomial transformation between the "System Storebaelt" and utm32/ed50 */ + P = proj_create (PJ_DEFAULT_CTX, sb_utm32); + if (0==P) + return 11; + + /* Test value: utm32_ed50(620000, 6130000) = sb_ed50(495136.8544, 6130821.2945) */ + a = b = c = proj_coord (0,0,0,0); + a.uv.v = 6130821.2945; + a.uv.u = 495136.8544; + c.uv.v = 6130000.0000; + c.uv.u = 620000.0000; + + /* Forward projection */ + b = proj_trans (P, PJ_FWD, a); + dist = proj_xy_dist (b.xy, c.xy); + if (dist > 0.001) + return 2; + + /* Inverse projection */ + b = proj_trans (P, PJ_INV, c); + dist = proj_xy_dist (b.xy, a.xy); + if (dist > 0.001) + return 3; + + /* Check roundtrip precision for 1 iteration each way */ + dist = proj_roundtrip (P, PJ_FWD, 1, &a); + if (dist > 0.01) + return 4; + + proj_destroy(P); + return 0; +} + + + + + + + + + + + + +/* Testing quite a bit of the pj_obs_api as a side effect (inspired by pj_obs_api_test.c) */ +static int pj_cart_selftest (void) { + PJ_CONTEXT *ctx; + PJ *P; + PJ_COORD a, b, obs[2]; + PJ_COORD coord[2]; + + PJ_INFO info; + PJ_PROJ_INFO pj_info; + PJ_GRID_INFO grid_info; + PJ_INIT_INFO init_info; + + PJ_DERIVS derivs; + PJ_FACTORS factors; + + const PJ_OPERATIONS *oper_list; + const PJ_ELLPS *ellps_list; + const PJ_UNITS *unit_list; + const PJ_PRIME_MERIDIANS *pm_list; + + int err; + size_t n, sz; + double dist, h, t; + char *args[3] = {"proj=utm", "zone=32", "ellps=GRS80"}; + char *arg = {"+proj=utm +zone=32 +ellps=GRS80"}; + char buf[40]; + + /* An utm projection on the GRS80 ellipsoid */ + P = proj_create (PJ_DEFAULT_CTX, arg); + if (0==P) + return 1; + + + /* Clean up */ + proj_destroy (P); + + /* Same projection, now using argc/argv style initialization */ + P = proj_create_argv (PJ_DEFAULT_CTX, 3, args); + if (0==P) + return 2; + + /* zero initialize everything, then set (longitude, latitude) to (12, 55) */ + a = proj_coord (0,0,0,0); + /* a.lp: The coordinate part of a, interpreted as a classic LP pair */ + a.lp.lam = PJ_TORAD(12); + a.lp.phi = PJ_TORAD(55); + + /* Forward projection */ + b = proj_trans (P, PJ_FWD, a); + + /* Inverse projection */ + a = proj_trans (P, PJ_INV, b); + + /* Null projection */ + a = proj_trans (P, PJ_IDENT, a); + + /* Forward again, to get two linear items for comparison */ + a = proj_trans (P, PJ_FWD, a); + + dist = proj_xy_dist (a.xy, b.xy); + if (dist > 2e-9) + return 3; + + /* Clear any previous error */ + proj_errno_set (P, 0); + + /* Invalid projection */ + a = proj_trans (P, 42, a); + if (a.lpz.lam!=HUGE_VAL) + return 4; + err = proj_errno (P); + if (0==err) + return 5; + + /* Clear error again */ + proj_errno_set (P, 0); + + /* Clean up */ + proj_destroy (P); + + /* Now do some 3D transformations */ + P = proj_create (PJ_DEFAULT_CTX, "+proj=cart +ellps=GRS80"); + if (0==P) + return 6; + + /* zero initialize everything, then set (longitude, latitude, height) to (12, 55, 100) */ + a = b = proj_coord (0,0,0,0); + a.lpz.lam = PJ_TORAD(12); + a.lpz.phi = PJ_TORAD(55); + a.lpz.z = 100; + + /* Forward projection: 3D-Cartesian-to-Ellipsoidal */ + 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); + if (dist > 2e-9) + return 7; + + + /* Test at the North Pole */ + a = b = proj_coord (0,0,0,0); + a.lpz.lam = PJ_TORAD(0); + a.lpz.phi = PJ_TORAD(90); + a.lpz.z = 100; + + /* Forward projection: Ellipsoidal-to-3D-Cartesian */ + dist = proj_roundtrip (P, PJ_FWD, 1, &a); + if (dist > 1e-12) + return 8; + + /* Test at the South Pole */ + a = b = proj_coord (0,0,0,0); + 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); + if (dist > 1e-12) + return 9; + + + /* Inverse projection: 3D-Cartesian-to-Ellipsoidal */ + b = proj_trans (P, PJ_INV, b); + + /* Move p to another context */ + ctx = proj_context_create (); + if (ctx==pj_get_default_ctx()) + return 10; + proj_context_set (P, ctx); + if (ctx != P->ctx) + return 11; + b = proj_trans (P, PJ_FWD, b); + + /* Move it back to the default context */ + proj_context_set (P, 0); + if (pj_get_default_ctx() != P->ctx) + return 12; + proj_context_destroy (ctx); + + /* We go on with the work - now back on the default context */ + b = proj_trans (P, PJ_INV, b); + proj_destroy (P); + + + /* Testing proj_trans_generic () */ + + /* An utm projection on the GRS80 ellipsoid */ + P = proj_create (PJ_DEFAULT_CTX, "+proj=utm +zone=32 +ellps=GRS80"); + if (0==P) + return 13; + + obs[0] = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); + obs[1] = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); + sz = sizeof (PJ_COORD); + + /* Forward projection */ + a = proj_trans (P, PJ_FWD, obs[0]); + b = proj_trans (P, PJ_FWD, obs[1]); + + n = proj_trans_generic ( + P, PJ_FWD, + &(obs[0].lpz.lam), sz, 2, + &(obs[0].lpz.phi), sz, 2, + &(obs[0].lpz.z), sz, 2, + 0, sz, 0 + ); + if (2!=n) + return 14; + if (a.lpz.lam != obs[0].lpz.lam) return 15; + if (a.lpz.phi != obs[0].lpz.phi) return 16; + if (a.lpz.z != obs[0].lpz.z) return 17; + if (b.lpz.lam != obs[1].lpz.lam) return 18; + if (b.lpz.phi != obs[1].lpz.phi) return 19; + if (b.lpz.z != obs[1].lpz.z) return 20; + + /* now test the case of constant z */ + obs[0] = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); + obs[1] = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); + h = 27; + t = 33; + n = proj_trans_generic ( + P, PJ_FWD, + &(obs[0].lpz.lam), sz, 2, + &(obs[0].lpz.phi), sz, 2, + &h, 0, 1, + &t, 0, 1 + ); + if (2!=n) + return 21; + if (a.lpz.lam != obs[0].lpz.lam) return 22; + if (a.lpz.phi != obs[0].lpz.phi) return 23; + if (45 != obs[0].lpz.z) return 24; + if (b.lpz.lam != obs[1].lpz.lam) return 25; + if (b.lpz.phi != obs[1].lpz.phi) return 26; + if (50 != obs[1].lpz.z) return 27; /* NOTE: unchanged */ + if (50==h) return 28; + + /* test proj_trans_array () */ + + coord[0] = proj_coord (PJ_TORAD(12), PJ_TORAD(55), 45, 0); + coord[1] = proj_coord (PJ_TORAD(12), PJ_TORAD(56), 50, 0); + if (proj_trans_array (P, PJ_FWD, 2, coord)) + return 40; + + if (a.lpz.lam != coord[0].lpz.lam) return 41; + if (a.lpz.phi != coord[0].lpz.phi) return 42; + if (a.lpz.z != coord[0].lpz.z) return 43; + if (b.lpz.lam != coord[1].lpz.lam) return 44; + if (b.lpz.phi != coord[1].lpz.phi) return 45; + if (b.lpz.z != coord[1].lpz.z) return 46; + + /* Clean up after proj_trans_* tests */ + proj_destroy (P); + + /* test proj_create_crs_to_crs() */ + P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "epsg:25832", "epsg:25833", NULL); + if (P==0) + return 50; + + a.xy.x = 700000.0; + a.xy.y = 6000000.0; + b.xy.x = 307788.8761171057; + b.xy.y = 5999669.3036037628; + + a = proj_trans(P, PJ_FWD, a); + if (dist > 1e-7) + return 51; + proj_destroy(P); + + /* let's make sure that only entries in init-files results in a usable PJ */ + P = proj_create_crs_to_crs(PJ_DEFAULT_CTX, "proj=utm +zone=32 +datum=WGS84", "proj=utm +zone=33 +datum=WGS84", NULL); + if (P != 0) { + proj_destroy(P); + return 52; + } + proj_destroy(P); + + /* ********************************************************************** */ + /* Test info functions */ + /* ********************************************************************** */ + + /* proj_info() */ + /* this one is difficult to test, since the output changes with the setup */ + info = proj_info(); + if (info.version[0] != '\0' ) { + char tmpstr[64]; + sprintf(tmpstr, "%d.%d.%d", info.major, info.minor, info.patch); + if (strcmp(info.version, tmpstr)) return 55; + } + if (info.release[0] == '\0') return 56; + if (info.searchpath[0] == '\0') return 57; + + /* proj_pj_info() */ + P = proj_create(PJ_DEFAULT_CTX, "+proj=august"); /* august has no inverse */ + if (proj_pj_info(P).has_inverse) { proj_destroy(P); return 60; } + proj_destroy(P); + + P = proj_create(PJ_DEFAULT_CTX, arg); + pj_info = proj_pj_info(P); + if ( !pj_info.has_inverse ) { proj_destroy(P); return 61; } + if ( strcmp(pj_info.definition, arg) ) { proj_destroy(P); return 62; } + if ( strcmp(pj_info.id, "utm") ) { proj_destroy(P); return 63; } + proj_destroy(P); + + /* proj_grid_info() */ + grid_info = proj_grid_info("egm96_15.gtx"); + if ( strlen(grid_info.filename) == 0 ) return 64; + if ( strcmp(grid_info.gridname, "egm96_15.gtx") ) return 65; + grid_info = proj_grid_info("nonexistinggrid"); + if ( strlen(grid_info.filename) > 0 ) return 66; + + /* proj_init_info() */ + init_info = proj_init_info("unknowninit"); + if ( strlen(init_info.filename) != 0 ) return 67; + + init_info = proj_init_info("epsg"); + /* Need to allow for "Unknown" until all commonly distributed EPSG-files comes with a metadata section */ + if ( strcmp(init_info.origin, "EPSG") && strcmp(init_info.origin, "Unknown") ) return 69; + if ( strcmp(init_info.name, "epsg") ) return 68; + + + + /* test proj_rtodms() and proj_dmstor() */ + if (strcmp("180dN", proj_rtodms(buf, M_PI, 'N', 'S'))) + return 70; + + if (proj_dmstor(&buf[0], NULL) != M_PI) + return 71; + + if (strcmp("114d35'29.612\"S", proj_rtodms(buf, -2.0, 'N', 'S'))) + return 72; + + /* we can't expect perfect numerical accuracy so testing with a tolerance */ + if (fabs(-2.0 - proj_dmstor(&buf[0], NULL)) > 1e-7) + return 73; + + + /* test proj_derivatives_retrieve() and proj_factors_retrieve() */ + P = proj_create(PJ_DEFAULT_CTX, "+proj=merc"); + a = proj_coord (0,0,0,0); + a.lp.lam = PJ_TORAD(12); + a.lp.phi = PJ_TORAD(55); + + derivs = proj_derivatives(P, a.lp); + if (proj_errno(P)) + return 80; /* derivs not created correctly */ + + if ( fabs(derivs.x_l - 1.0) > 1e-5 ) return 81; + if ( fabs(derivs.x_p - 0.0) > 1e-5 ) return 82; + if ( fabs(derivs.y_l - 0.0) > 1e-5 ) return 83; + if ( fabs(derivs.y_p - 1.73959) > 1e-5 ) return 84; + + + factors = proj_factors(P, a.lp); + if (proj_errno(P)) + return 85; /* factors not created correctly */ + + /* check a few key characteristics of the Mercator projection */ + if (factors.omega != 0.0) return 86; /* angular distortion should be 0 */ + if (factors.thetap != M_PI_2) return 87; /* Meridian/parallel angle should be 90 deg */ + if (factors.conv != 0.0) return 88; /* meridian convergence should be 0 */ + + + proj_destroy(P); + + /* Check that proj_list_* functions work by looping through them */ + n = 0; + for (oper_list = proj_list_operations(); oper_list->id; ++oper_list) n++; + if (n == 0) return 90; + + n = 0; + for (ellps_list = proj_list_ellps(); ellps_list->id; ++ellps_list) n++; + if (n == 0) return 91; + + n = 0; + for (unit_list = proj_list_units(); unit_list->id; ++unit_list) n++; + if (n == 0) return 92; + + n = 0; + 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; +} + + + + + + + + + + + + + + + +static int test_time(char* args, double tol, double t_in, double t_exp) { + PJ_COORD in, out; + PJ *P = proj_create(PJ_DEFAULT_CTX, args); + int ret = 0; + + if (P == 0) + return 5; + + in.xyzt.t = t_in; + + out = proj_trans(P, PJ_FWD, in); + if (fabs(out.xyzt.t - t_exp) > tol) { + proj_log_error(P, "out: %10.10g, expect: %10.10g", out.xyzt.t, t_exp); + ret = 1; + } + out = proj_trans(P, PJ_INV, out); + if (fabs(out.xyzt.t - t_in) > tol) { + proj_log_error(P, "out: %10.10g, expect: %10.10g", out.xyzt.t, t_in); + ret = 2; + } + pj_free(P); + + proj_log_level(NULL, 0); + return ret; +} + +static int test_xyz(char* args, double tol, PJ_TRIPLET in, PJ_TRIPLET exp) { + PJ_COORD out, obs_in; + PJ *P = proj_create(PJ_DEFAULT_CTX, args); + int ret = 0; + + if (P == 0) + return 5; + + obs_in.xyz = in.xyz; + out = proj_trans(P, PJ_FWD, obs_in); + if (proj_xyz_dist(out.xyz, exp.xyz) > tol) { + printf("exp: %10.10g, %10.10g, %10.10g\n", exp.xyz.x, exp.xyz.y, exp.xyz.z); + printf("out: %10.10g, %10.10g, %10.10g\n", out.xyz.x, out.xyz.y, out.xyz.z); + ret = 1; + } + + out = proj_trans(P, PJ_INV, out); + if (proj_xyz_dist(out.xyz, in.xyz) > tol) { + printf("exp: %g, %g, %g\n", in.xyz.x, in.xyz.y, in.xyz.z); + printf("out: %g, %g, %g\n", out.xyz.x, out.xyz.y, out.xyz.z); + ret += 2; + } + proj_destroy(P); + proj_log_level(NULL, 0); + return ret; +} + + +static int pj_unitconvert_selftest (void) { + int ret = 0; + char args1[] = "+proj=unitconvert +t_in=decimalyear +t_out=decimalyear"; + double in1 = 2004.25; + + char args2[] = "+proj=unitconvert +t_in=gps_week +t_out=gps_week"; + double in2 = 1782.0; + + char args3[] = "+proj=unitconvert +t_in=mjd +t_out=mjd"; + double in3 = 57390.0; + + char args4[] = "+proj=unitconvert +t_in=gps_week +t_out=decimalyear"; + double in4 = 1877.71428, exp4 = 2016.0; + + char args5[] = "+proj=unitconvert +xy_in=m +xy_out=dm +z_in=cm +z_out=mm"; + PJ_TRIPLET in5 = {{55.25, 23.23, 45.5}}, exp5 = {{552.5, 232.3, 455.0}}; + + char args6[] = "+proj=unitconvert +xy_in=m +xy_out=m +z_in=m +z_out=m"; + PJ_TRIPLET in6 = {{12.3, 45.6, 7.89}}; + + ret = test_time(args1, 1e-6, in1, in1); if (ret) return ret + 10; + ret = test_time(args2, 1e-6, in2, in2); if (ret) return ret + 20; + ret = test_time(args3, 1e-6, in3, in3); if (ret) return ret + 30; + ret = test_time(args4, 1e-6, in4, exp4); if (ret) return ret + 40; + ret = test_xyz (args5, 1e-10, in5, exp5); if (ret) return ret + 50; + ret = test_xyz (args6, 1e-10, in6, in6); if (ret) return ret + 50; + + return 0; + +} + + + diff --git a/src/lib_proj.cmake b/src/lib_proj.cmake index 4b701886..81de451e 100644 --- a/src/lib_proj.cmake +++ b/src/lib_proj.cmake @@ -186,7 +186,6 @@ SET(SRC_LIBPROJ_CORE pj_fwd3d.c pj_gauss.c pj_gc_reader.c - pj_generic_selftest.c pj_geocent.c pj_gridcatalog.c pj_gridinfo.c @@ -212,7 +211,6 @@ SET(SRC_LIBPROJ_CORE pj_pr_list.c pj_qsfn.c pj_release.c - pj_run_selftests.c pj_strerrno.c pj_transform.c pj_tsfn.c diff --git a/src/makefile.vc b/src/makefile.vc index ae2dc587..6bc06bd1 100644 --- a/src/makefile.vc +++ b/src/makefile.vc @@ -56,8 +56,7 @@ support = \ pj_utils.obj pj_gridlist.obj pj_gridinfo.obj \ proj_mdist.obj pj_mutex.obj pj_initcache.obj \ pj_ctx.obj pj_fileapi.obj pj_log.obj pj_apply_vgridshift.obj \ - pj_strtod.obj pj_run_selftests.obj pj_generic_selftest.obj \ - pj_internal.obj + pj_strtod.obj pj_internal.obj pipeline = \ proj_4D_api.obj PJ_cart.obj PJ_pipeline.obj PJ_horner.obj PJ_helmert.obj \ diff --git a/src/pj_generic_selftest.c b/src/pj_generic_selftest.c deleted file mode 100644 index 88b5c308..00000000 --- a/src/pj_generic_selftest.c +++ /dev/null @@ -1,197 +0,0 @@ -/****************************************************************************** - * Project: PROJ.4 - * Purpose: Generic regression test for PROJ.4 projection algorithms. - * Author: Thomas Knudsen - * - ****************************************************************************** - * Copyright (c) 2016, Thomas Knudsen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - *****************************************************************************/ - - -#include -#define PJ_LIB__ -#include - - -static int deviates_xy (XY expected, XY got, double tolerance); -static int deviates_lp (LP expected, LP got, double tolerance); -static XY pj_fwd_deg (LP in, PJ *P); - - -/**********************************************************************/ -int pj_generic_selftest ( -/**********************************************************************/ - char *e_args, - char *s_args, - double tolerance_xy, - double tolerance_lp, - int n_fwd, - int n_inv, - LP *fwd_in, - XY *e_fwd_expect, - XY *s_fwd_expect, - XY *inv_in, - LP *e_inv_expect, - LP *s_inv_expect -) { -/*********************************************************************** - -Generic regression test for PROJ.4 projection algorithms, testing both -ellipsoidal ("e_") and spheroidal ("s_") versions of the projection -algorithms in both forward ("_fwd_") and inverse ("_inv_") mode. - -Compares the "known good" results in and -with the actual results obtained by transforming the forward input data -set in with pj_fwd() using setup arguments and -, respectively. - -Then - -Compares the "known good" results in and -with the actual results obtained by transforming the inverse input data -set in with pj_inv() using setup arguments and -, respectively. - -Any of the pointers passed may be set to 0, indicating "don't test this -part". - -Returns 0 if all data agree to within the accuracy specified in - and . Non-zero otherwise. - -***********************************************************************/ - int i; - - PJ *P; - - if (e_args) { - P = pj_init_plus(e_args); - if (0==P) - return 2; - - /* Test forward ellipsoidal */ - if (e_fwd_expect) { - for (i = 0; i < n_fwd; i++) - if (deviates_xy (e_fwd_expect[i], pj_fwd_deg ( fwd_in[i], P ), tolerance_xy)) - break; - if ( i != n_fwd ) - return 100 + i; - } - - /* Test inverse ellipsoidal */ - if (e_inv_expect) { - for (i = 0; i < n_inv; i++) - if (deviates_lp (e_inv_expect[i], pj_inv ( inv_in[i], P ), tolerance_lp)) - break; - if ( i != n_inv ) - return 200 + i; - } - - pj_free (P); - } - - - if (s_args) { - P = pj_init_plus(s_args); - if (0==P) - return 3; - - /* Test forward spherical */ - if (s_fwd_expect) { - for (i = 0; i < n_fwd; i++) - if (deviates_xy (s_fwd_expect[i], pj_fwd_deg ( fwd_in[i], P ), tolerance_xy)) - break; - if ( i != n_fwd ) - return 300 + i; - } - - /* Test inverse spherical */ - if (s_inv_expect) { - for (i = 0; i < n_inv; i++) - if (deviates_lp (s_inv_expect[i], pj_inv ( inv_in[i], P ), tolerance_lp)) - break; - if ( i != n_inv ) - return 400 + i; - } - - pj_free (P); - } - - return 0; -} - - - -/**********************************************************************/ -static int deviates_xy (XY expected, XY got, double tolerance) { -/*********************************************************************** - - Determine whether two XYs deviate by more than . - - The test material ("expected" values) may contain coordinates that - are indeterminate. For those cases, we test the other coordinate - only by forcing expected and actual ("got") coordinates to 0. - -***********************************************************************/ - if (HUGE_VAL== expected.x) - return 0; - if (HUGE_VAL== expected.y) - return 0; - if (hypot ( expected.x - got.x, expected.y - got.y ) > tolerance) - return 1; - return 0; -} - - -/**********************************************************************/ -static int deviates_lp (LP expected, LP got, double tolerance) { -/*********************************************************************** - - Determine whether two LPs deviate by more than . - - This one is slightly tricky, since the LP is - supposed to be represented as degrees (since it was at some - time written down by a real human), whereas the LP is - represented in radians (since it is supposed to be the result - output from pj_inv) - -***********************************************************************/ - if (HUGE_VAL== expected.lam) - return 0; - if (HUGE_VAL== expected.phi) - return 0; - if (hypot ( DEG_TO_RAD * expected.lam - got.lam, DEG_TO_RAD * expected.phi - got.phi ) > tolerance) - return 1; - return 0; -} - - -/**********************************************************************/ -static XY pj_fwd_deg (LP in, PJ *P) { -/*********************************************************************** - - Wrapper for pj_fwd, accepting input in degrees. - -***********************************************************************/ - LP in_rad; - in_rad.lam = DEG_TO_RAD * in.lam; - in_rad.phi = DEG_TO_RAD * in.phi; - return pj_fwd (in_rad, P); -} diff --git a/src/pj_geocent.c b/src/pj_geocent.c index 667c29bd..eca62080 100644 --- a/src/pj_geocent.c +++ b/src/pj_geocent.c @@ -58,49 +58,3 @@ PJ *PROJECTION(geocent) { return P; } - -#ifndef PJ_SELFTEST -int pj_geocent_selftest (void) {return 0;} -#else - -int pj_geocent_selftest (void) { - - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=geocent +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - char s_args[] = {"+proj=geocent +a=6400000 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222638.98158654713, 111319.49079327357}, - { 222638.98158654713, -111319.49079327357}, - {-222638.98158654713, 111319.49079327357}, - {-222638.98158654713, -111319.49079327357}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017966305682390426, 0.00089831528411952132}, - { 0.0017966305682390426, -0.00089831528411952132}, - {-0.0017966305682390426, 0.00089831528411952132}, - {-0.0017966305682390426, -0.00089831528411952132}, - }; - - return pj_generic_selftest (e_args, s_args, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, 0, inv_in, e_inv_expect, 0); -} - -#endif - diff --git a/src/pj_list.c b/src/pj_list.c index 9fde000f..2bdd3053 100644 --- a/src/pj_list.c +++ b/src/pj_list.c @@ -6,26 +6,16 @@ #include "projects.h" - -#define PASTE(a,b) a##b - /* Generate prototypes for projection functions */ #define PROJ_HEAD(id, name) struct PJconsts *pj_##id(struct PJconsts*); #include "pj_list.h" #undef PROJ_HEAD -/* Generate prototypes for projection selftest functions */ -#define PROJ_HEAD(id, name) int PASTE(pj_##id, _selftest) (void); -#include "pj_list.h" -#undef PROJ_HEAD - - /* Generate extern declarations for description strings */ #define PROJ_HEAD(id, name) extern char * const pj_s_##id; #include "pj_list.h" #undef PROJ_HEAD - /* Generate the null-terminated list of projection functions with associated mnemonics and descriptions */ #define PROJ_HEAD(id, name) {#id, pj_##id, &pj_s_##id}, struct PJ_LIST pj_list[] = { @@ -35,21 +25,6 @@ struct PJ_LIST pj_list[] = { #undef PROJ_HEAD -/* Generate the null-terminated list of projection selftest functions with associated mnemonics */ -#define PROJ_HEAD(id, name) {#id, PASTE(pj_##id, _selftest)}, -struct PJ_SELFTEST_LIST pj_selftest_list[] = { -#include "pj_list.h" - {0, 0}, - }; -#undef PROJ_HEAD -#undef PASTE - - struct PJ_LIST *pj_get_list_ref (void) { return pj_list; } - - -struct PJ_SELFTEST_LIST *pj_get_selftest_list_ref (void) { - return pj_selftest_list; -} diff --git a/src/pj_run_selftests.c b/src/pj_run_selftests.c deleted file mode 100644 index 90193af8..00000000 --- a/src/pj_run_selftests.c +++ /dev/null @@ -1,80 +0,0 @@ -/****************************************************************************** - * Project: PROJ.4 - * Purpose: Generic regression test for PROJ.4 projection algorithms. - * Author: Thomas Knudsen - * - ****************************************************************************** - * Copyright (c) 2016, Thomas Knudsen - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the "Software"), - * to deal in the Software without restriction, including without limitation - * the rights to use, copy, modify, merge, publish, distribute, sublicense, - * and/or sell copies of the Software, and to permit persons to whom the - * Software is furnished to do so, subject to the following conditions: - * - * The above copyright notice and this permission notice shall be included - * in all copies or substantial portions of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL - * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER - * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING - * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER - * DEALINGS IN THE SOFTWARE. - *****************************************************************************/ - -#include -#define PJ_LIB__ -#include - - -#ifndef PJ_SELFTEST -int pj_run_selftests (int verbosity) { - (void)verbosity; - printf ("This version of libproj is not configured for internal regression tests.\n"); - return 0; -} -#else - - -static void run_one_test (const char *mnemonic, int (testfunc)(void), int verbosity, int *n_ok, int *n_ko, int *n_stubs) { - int ret; - ret = testfunc (); - switch (ret) { - case 0: (*n_ok)++; break; - case 10000: (*n_stubs)++; break; - default: (*n_ko)++; - } - - if (verbosity) { - if (ret==10000) - printf ("Testing: %10s - [stub]\n", mnemonic); - else - printf ("Testing: %10s - return code: %d\n", mnemonic, ret); - } - return; -} - - -int pj_run_selftests (int verbosity) { - int n_ok = 0, n_ko = 0, n_stubs = 0, i = 0; - - struct PJ_SELFTEST_LIST *tests = pj_get_selftest_list_ref (); - - if (0==tests) - printf ("This version of libproj is not configured for internal regression tests.\n"); - - if (verbosity) - printf ("Running internal regression tests\n"); - - for (i = 0; tests[i].testfunc != 0; i++) - run_one_test (tests[i].id, tests[i].testfunc, verbosity, &n_ok, &n_ko, &n_stubs); - - if (0==verbosity) - printf ("Internal regression tests done. "); - printf ("[Stubs: %d] Total: %d. Failure: %d. Success: %d\n", n_stubs, n_ok+n_ko, n_ko, n_ok); - return n_ko; -} -#endif diff --git a/src/proj.c b/src/proj.c index 049593c9..57d33a73 100644 --- a/src/proj.c +++ b/src/proj.c @@ -42,7 +42,7 @@ static char *cheby_str, /* string controlling Chebychev evaluation */ *oform = (char *)0, /* output format for x-y or decimal degrees */ *oterr = "*\t*", /* output line for unprojectable input */ - *usage = "%s\nusage: %s [ -bCeEfiIlormsStTvVwW [args] ] [ +opts[=arg] ] [ files ]\n"; + *usage = "%s\nusage: %s [ -beEfiIlormsStTvVwW [args] ] [ +opts[=arg] ] [ files ]\n"; static struct FACTORS facs; @@ -329,9 +329,6 @@ int main(int argc, char **argv) { case 'b': /* binary I/O */ bin_in = bin_out = 1; continue; - case 'C': /* Check - run internal regression tests */ - return pj_run_selftests (very_verby); - continue; case 'v': /* monitor dump of initialization */ mon = 1; continue; diff --git a/src/proj.def b/src/proj.def index cc1793e1..dd4a456c 100644 --- a/src/proj.def +++ b/src/proj.def @@ -88,62 +88,61 @@ EXPORTS geod_polygon_testedge @86 geod_polygon_testpoint @87 geod_polygon_clear @88 - pj_run_selftests @89 - pj_find_file @90 + pj_find_file @89 - proj_create @91 - proj_create_argv @92 - proj_create_crs_to_crs @93 - proj_destroy @94 + proj_create @90 + proj_create_argv @91 + proj_create_crs_to_crs @92 + proj_destroy @93 - proj_trans @95 - proj_trans_array @96 - proj_trans_generic @97 - proj_roundtrip @98 + proj_trans @94 + proj_trans_array @95 + proj_trans_generic @96 + proj_roundtrip @97 - proj_coord @99 - proj_coord_error @100 + proj_coord @98 + proj_coord_error @99 - proj_errno @101 - proj_errno_set @102 - proj_errno_reset @103 - proj_errno_restore @104 - proj_context_errno_set @105 + proj_errno @100 + proj_errno_set @101 + proj_errno_reset @102 + proj_errno_restore @103 + proj_context_errno_set @104 - proj_context_create @106 - proj_context_set @107 - proj_context_inherit @108 - proj_context_destroy @109 + proj_context_create @105 + proj_context_set @106 + proj_context_inherit @107 + proj_context_destroy @108 - proj_lp_dist @110 - proj_lpz_dist @111 - proj_xy_dist @112 - proj_xyz_dist @113 + proj_lp_dist @109 + proj_lpz_dist @110 + proj_xy_dist @111 + proj_xyz_dist @112 - proj_log_level @114 - proj_log_func @115 - proj_log_error @116 - proj_log_debug @117 - proj_log_trace @118 + proj_log_level @113 + proj_log_func @114 + proj_log_error @115 + proj_log_debug @116 + proj_log_trace @117 - proj_info @119 - proj_pj_info @120 - proj_grid_info @121 - proj_init_info @122 + proj_info @118 + proj_pj_info @119 + proj_grid_info @120 + proj_init_info @121 - proj_torad @123 - proj_todeg @124 - proj_rtodms @125 - proj_dmstor @126 + proj_torad @122 + proj_todeg @123 + proj_rtodms @124 + proj_dmstor @125 - proj_derivatives @127 - proj_factors @128 + proj_derivatives @126 + proj_factors @127 - proj_list_operations @129 - proj_list_ellps @130 - proj_list_units @131 - proj_list_prime_meridians @132 + proj_list_operations @128 + proj_list_ellps @129 + proj_list_units @130 + proj_list_prime_meridians @131 - proj_angular_input @133 - proj_angular_output @134 + proj_angular_input @132 + proj_angular_output @133 diff --git a/src/proj_api.h b/src/proj_api.h index 151a824d..b0c4b71f 100644 --- a/src/proj_api.h +++ b/src/proj_api.h @@ -175,8 +175,6 @@ void pj_acquire_lock(void); void pj_release_lock(void); void pj_cleanup_lock(void); -int pj_run_selftests (int verbosity); - void pj_set_ctx( projPJ, projCtx ); projCtx pj_ctx_alloc(void); void pj_ctx_free( projCtx ); diff --git a/src/proj_etmerc.c b/src/proj_etmerc.c index a756a7ac..b03862f8 100644 --- a/src/proj_etmerc.c +++ b/src/proj_etmerc.c @@ -332,63 +332,6 @@ PJ *PROJECTION(etmerc) { - - - - -#ifndef PJ_SELFTEST -int pj_etmerc_selftest (void) {return 0;} -#else - -int pj_etmerc_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=etmerc +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5 +zone=30"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {222650.79679758562, 110642.22941193319}, - {222650.79679758562, -110642.22941193319}, - {-222650.79679758562, 110642.22941193319}, - {-222650.79679758562, -110642.22941193319}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {0.0017966305681649398, 0.00090436947663183873}, - {0.0017966305681649398, -0.00090436947663183873}, - {-0.0017966305681649398, 0.00090436947663183873}, - {-0.0017966305681649398, -0.00090436947663183873}, - }; - - return pj_generic_selftest (e_args, 0, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, 0, inv_in, e_inv_expect, 0); -} -#endif - - - - - - - - - - - - /* utm uses etmerc for the underlying projection */ @@ -429,48 +372,3 @@ PJ *PROJECTION(utm) { return setup (P); } - -#ifndef PJ_SELFTEST -int pj_utm_selftest (void) {return 0;} -#else - -int pj_utm_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=utm +ellps=GRS80 +lat_1=0.5 +lat_2=2 +n=0.5 +zone=30"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - {1057002.4054912981, 110955.14117594929}, - {1057002.4054912981, -110955.14117594929}, - {611263.81227890507, 110547.10569680421}, - {611263.81227890507, -110547.10569680421}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - {-7.4869520833902357, 0.00090193980983462605}, - {-7.4869520833902357, -0.00090193980983462605}, - {-7.4905356820622613, 0.00090193535121489081}, - {-7.4905356820622613, -0.00090193535121489081}, - }; - - return pj_generic_selftest (e_args, 0, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, 0, inv_in, e_inv_expect, 0); -} -#endif - - - diff --git a/src/proj_rouss.c b/src/proj_rouss.c index 952e5c55..5555e3e4 100644 --- a/src/proj_rouss.c +++ b/src/proj_rouss.c @@ -152,47 +152,3 @@ PJ *PROJECTION(rouss) { return P; } - -#ifndef PJ_SELFTEST -int pj_rouss_selftest (void) {return 0;} -#else - -int pj_rouss_selftest (void) { - double tolerance_lp = 1e-10; - double tolerance_xy = 1e-7; - - char e_args[] = {"+proj=rouss +ellps=GRS80 +lat_1=0.5 +lat_2=2"}; - - LP fwd_in[] = { - { 2, 1}, - { 2,-1}, - {-2, 1}, - {-2,-1} - }; - - XY e_fwd_expect[] = { - { 222644.89413161727, 110611.09186837047}, - { 222644.89413161727, -110611.09186837047}, - {-222644.89413161727, 110611.09186837047}, - {-222644.89413161727, -110611.09186837047}, - }; - - XY inv_in[] = { - { 200, 100}, - { 200,-100}, - {-200, 100}, - {-200,-100} - }; - - LP e_inv_expect[] = { - { 0.0017966305682019911, 0.00090436947683699559}, - { 0.0017966305682019911, -0.00090436947683699559}, - {-0.0017966305682019911, 0.00090436947683699559}, - {-0.0017966305682019911, -0.00090436947683699559}, - }; - - return pj_generic_selftest (e_args, 0, tolerance_xy, tolerance_lp, 4, 4, fwd_in, e_fwd_expect, 0, inv_in, e_inv_expect, 0); -} - - -#endif diff --git a/src/projects.h b/src/projects.h index a28c08d1..1d4fff50 100644 --- a/src/projects.h +++ b/src/projects.h @@ -561,7 +561,6 @@ struct PJ_LIST { #ifndef USE_PJ_LIST_H extern struct PJ_LIST pj_list[]; -extern struct PJ_SELFTEST_LIST pj_selftest_list[]; #endif #ifndef PJ_ELLPS__ @@ -588,7 +587,6 @@ extern struct PJ_PRIME_MERIDIANS pj_prime_meridians[]; \ pj_projection_specific_setup_##name (PJ *P); \ C_NAMESPACE PJ *pj_##name (PJ *P); \ -int pj_ ## name ## _selftest (void); \ \ C_NAMESPACE_VAR const char * const pj_s_##name = des_##name; \ \ @@ -618,27 +616,6 @@ PJ *pj_projection_specific_setup_##name (PJ *P) #endif /* def PJ_LIB__ */ - - - -int pj_generic_selftest ( - char *e_args, - char *s_args, - double tolerance_xy, - double tolerance_lp, - int n_fwd, - int n_inv, - LP *fwd_in, - XY *e_fwd_expect, - XY *s_fwd_expect, - XY *inv_in, - LP *e_inv_expect, - LP *s_inv_expect -); - - - - #define MAX_TAB_ID 80 typedef struct { float lam, phi; } FLP; typedef struct { int lam, phi; } ILP; @@ -816,7 +793,6 @@ struct PJ_ELLPS *pj_get_ellps_ref( void ); struct PJ_DATUMS *pj_get_datums_ref( void ); struct PJ_UNITS *pj_get_units_ref( void ); struct PJ_LIST *pj_get_list_ref( void ); -struct PJ_SELFTEST_LIST *pj_get_selftest_list_ref ( void ); struct PJ_PRIME_MERIDIANS *pj_get_prime_meridians_ref( void ); void *pj_default_destructor (PJ *P, int errlev); -- cgit v1.2.3 From 4ef2f40bcddb10c7cea3b6c2a6442f84f103ffd7 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Wed, 15 Nov 2017 08:56:10 +0100 Subject: Give definition and definition line no. in message about invalid operations --- src/gie.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/gie.c b/src/gie.c index df4a0b07..4b89fe8f 100644 --- a/src/gie.c +++ b/src/gie.c @@ -150,12 +150,13 @@ typedef struct { int op_ok, op_ko; int total_ok, total_ko; int grand_ok, grand_ko; + size_t operation_lineno; double tolerance; char *curr_file; FILE *fout; } gie_ctx; -gie_ctx T = {{""}, 0, {{0,0,0,0}}, {{0,0,0,0}}, {{0,0,0,0}}, {{0,0,0,0}}, PJ_FWD, 1, 0, 0,0,0,0,0,0,0, 0.0005, 0, 0}; +gie_ctx T = {{""}, 0, {{0,0,0,0}}, {{0,0,0,0}}, {{0,0,0,0}}, {{0,0,0,0}}, PJ_FWD, 1, 0, 0,0,0,0,0,0,0,0, 0.0005, 0, 0}; OPTARGS *o; @@ -438,6 +439,8 @@ static int operation (char *args) { int i, j, n; T.op_id++; + T.operation_lineno = lineno; + /* compactify the args, so we can fit more info on a line in verbose mode */ n = (int) strlen (args); for (i = j = 0; i < n; ) { @@ -658,7 +661,8 @@ static int expect (char *args) { expect_failure = 1; if (0==T.P && !expect_failure) { - errmsg(3, "Invalid operation definition!\n %s\n", args); + banner (T.operation); + errmsg(3, "%sInvalid operation definition in line no. %d\n", delim, (int) T.operation_lineno); return another_failure (); } -- cgit v1.2.3 From 7aeb1fb3aaf5a7c14ba2a0513d5eca13a9ddd9d0 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Wed, 15 Nov 2017 09:03:39 +0100 Subject: Support numerical factors only (#664) * Support numerical factors only * Make sure h positive. Improve some comments * Let pole overshoot check have effect even for geocentric latitudes * Factor-typological constants, now all returning false, for backwards compatibility --- src/PJ_eqdc.c | 14 ----- src/PJ_lcc.c | 16 ------ src/pj_factors.c | 155 +++++++++++++++++++++++++++--------------------------- src/proj.c | 20 +++---- src/proj.h | 6 --- src/proj_4D_api.c | 3 -- src/projects.h | 16 +++--- 7 files changed, 92 insertions(+), 138 deletions(-) (limited to 'src') diff --git a/src/PJ_eqdc.c b/src/PJ_eqdc.c index e1f8ea16..6846abaa 100644 --- a/src/PJ_eqdc.c +++ b/src/PJ_eqdc.c @@ -54,19 +54,6 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ } -static void special(LP lp, PJ *P, struct FACTORS *fac) { - struct pj_opaque *Q = P->opaque; - double sinphi, cosphi; - - sinphi = sin(lp.phi); - cosphi = cos(lp.phi); - fac->code |= IS_ANAL_HK; - fac->h = 1.; - fac->k = Q->n * (Q->c - (Q->ellips ? pj_mlfn(lp.phi, sinphi, - cosphi, Q->en) : lp.phi)) / pj_msfn(sinphi, cosphi, P->es); -} - - static void *destructor (PJ *P, int errlev) { /* Destructor */ if (0==P) return 0; @@ -124,7 +111,6 @@ PJ *PROJECTION(eqdc) { P->inv = e_inverse; P->fwd = e_forward; - P->spc = special; return P; } diff --git a/src/PJ_lcc.c b/src/PJ_lcc.c index bc02667a..a24d5ac0 100644 --- a/src/PJ_lcc.c +++ b/src/PJ_lcc.c @@ -73,21 +73,6 @@ static LP e_inverse (XY xy, PJ *P) { /* Ellipsoidal, inverse */ return lp; } -static void special(LP lp, PJ *P, struct FACTORS *fac) { - struct pj_opaque *Q = P->opaque; - double rho; - if (fabs(fabs(lp.phi) - M_HALFPI) < EPS10) { - if ((lp.phi * Q->n) <= 0.) return; - rho = 0.; - } else - rho = Q->c * (Q->ellips ? pow(pj_tsfn(lp.phi, sin(lp.phi), - P->e), Q->n) : pow(tan(M_FORTPI + .5 * lp.phi), -Q->n)); - fac->code |= IS_ANAL_HK + IS_ANAL_CONV; - fac->k = fac->h = P->k0 * Q->n * rho / - pj_msfn(sin(lp.phi), cos(lp.phi), P->es); - fac->conv = Q->n * lp.lam; -} - PJ *PROJECTION(lcc) { double cosphi, sinphi; @@ -139,7 +124,6 @@ PJ *PROJECTION(lcc) { P->inv = e_inverse; P->fwd = e_forward; - P->spc = special; return P; } diff --git a/src/pj_factors.c b/src/pj_factors.c index 6c1b4978..69d59e49 100644 --- a/src/pj_factors.c +++ b/src/pj_factors.c @@ -1,6 +1,8 @@ /* projection scale factors */ #define PJ_LIB__ -#include +#include +#include "projects.h" + #include #ifndef DEFAULT_H @@ -10,88 +12,85 @@ #define EPS 1.0e-12 int pj_factors(LP lp, PJ *P, double h, struct FACTORS *fac) { - struct DERIVS der; double cosphi, t, n, r; + int err; + + err = proj_errno_reset (P); + + if (0==fac) { + proj_errno_set (P, ENOMEM); + return 1; + } - der.x_l = 0.0; - der.x_p = 0.0; - der.y_l = 0.0; - der.y_p = 0.0; + /* Indicate that all factors are numerical approximations */ + fac->code = 0; - /* check for forward and latitude or longitude overange */ - if ((t = fabs(lp.phi)-M_HALFPI) > EPS || fabs(lp.lam) > 10.) { - pj_ctx_set_errno( P->ctx, -14); + /* Check for latitude or longitude overange */ + if ((fabs (lp.phi)-M_HALFPI) > EPS || fabs (lp.lam) > 10.) { + proj_errno_set (P, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT); return 1; - } else { /* proceed */ - errno = pj_errno = 0; - P->ctx->last_errno = 0; - - if (h < EPS) - h = DEFAULT_H; - if (fabs(lp.phi) > (M_HALFPI - h)) - /* adjust to value around pi/2 where derived still exists*/ - lp.phi = lp.phi < 0. ? (-M_HALFPI+h) : (M_HALFPI-h); - else if (P->geoc) - lp.phi = atan(P->rone_es * tan(lp.phi)); - lp.lam -= P->lam0; /* compute del lp.lam */ - if (!P->over) - lp.lam = adjlon(lp.lam); /* adjust del longitude */ - if (P->spc) /* get what projection analytic values */ - P->spc(lp, P, fac); - if (((fac->code & (IS_ANAL_XL_YL+IS_ANAL_XP_YP)) != - (IS_ANAL_XL_YL+IS_ANAL_XP_YP)) && pj_deriv(lp, h, P, &der)) - return 1; - - if (!(fac->code & IS_ANAL_XL_YL)) { - fac->der.x_l = der.x_l; - fac->der.y_l = der.y_l; - } - if (!(fac->code & IS_ANAL_XP_YP)) { - fac->der.x_p = der.x_p; - fac->der.y_p = der.y_p; - } - cosphi = cos(lp.phi); - if (!(fac->code & IS_ANAL_HK)) { - fac->h = hypot(fac->der.x_p, fac->der.y_p); - fac->k = hypot(fac->der.x_l, fac->der.y_l) / cosphi; - if (P->es != 0.0) { - t = sin(lp.phi); - t = 1. - P->es * t * t; - n = sqrt(t); - fac->h *= t * n / P->one_es; - fac->k *= n; - r = t * t / P->one_es; - } else - r = 1.; - } else if (P->es != 0.0) { - r = sin(lp.phi); - r = 1. - P->es * r * r; - r = r * r / P->one_es; - } else - r = 1.; - - /* convergence */ - if (!(fac->code & IS_ANAL_CONV)) { - fac->conv = - atan2(fac->der.x_p, fac->der.y_p); - if (fac->code & IS_ANAL_XL_YL) - fac->code |= IS_ANAL_CONV; - } - /* areal scale factor */ - fac->s = (fac->der.y_p * fac->der.x_l - fac->der.x_p * fac->der.y_l) * r / cosphi; - - /* meridian-parallel angle theta prime */ - fac->thetap = aasin(P->ctx,fac->s / (fac->h * fac->k)); - - /* Tissot ellips axis */ - t = fac->k * fac->k + fac->h * fac->h; - fac->a = sqrt(t + 2. * fac->s); - t = (t = t - 2. * fac->s) <= 0. ? 0. : sqrt(t); - fac->b = 0.5 * (fac->a - t); - fac->a = 0.5 * (fac->a + t); - - /* omega */ - fac->omega = 2. * aasin(P->ctx,(fac->a - fac->b)/(fac->a + fac->b)); } + /* Set a reasonable step size for the numerical derivatives */ + h = fabs (h); + if (h < EPS) + h = DEFAULT_H; + + /* If input latitudes are geocentric, convert to geographic */ + if (P->geoc) + lp.phi = atan(P->rone_es * tan(lp.phi)); + + /* If latitude + one step overshoots the pole, move it slightly inside, */ + /* so the numerical derivative still exists */ + if (fabs (lp.phi) > (M_HALFPI - h)) + lp.phi = lp.phi < 0. ? -(M_HALFPI-h) : (M_HALFPI-h); + + /* Longitudinal distance from central meridian */ + lp.lam -= P->lam0; + if (!P->over) + lp.lam = adjlon(lp.lam); + + /* Derivatives */ + if (pj_deriv (lp, h, P, &(fac->der))) { + proj_errno_set (P, PJD_ERR_LAT_OR_LON_EXCEED_LIMIT); + return 1; + } + + /* Scale factors */ + cosphi = cos (lp.phi); + fac->h = hypot (fac->der.x_p, fac->der.y_p); + fac->k = hypot (fac->der.x_l, fac->der.y_l) / cosphi; + + if (P->es != 0.0) { + t = sin(lp.phi); + t = 1. - P->es * t * t; + n = sqrt(t); + fac->h *= t * n / P->one_es; + fac->k *= n; + r = t * t / P->one_es; + } else + r = 1.; + + /* Convergence */ + fac->conv = -atan2 (fac->der.x_p, fac->der.y_p); + + /* Areal scale factor */ + fac->s = (fac->der.y_p * fac->der.x_l - fac->der.x_p * fac->der.y_l) * r / cosphi; + + /* Meridian-parallel angle (theta prime) */ + fac->thetap = aasin(P->ctx,fac->s / (fac->h * fac->k)); + + /* Tissot ellipse axis */ + t = fac->k * fac->k + fac->h * fac->h; + fac->a = sqrt(t + 2. * fac->s); + t = t - 2. * fac->s; + t = t > 0? sqrt(t): 0; + fac->b = 0.5 * (fac->a - t); + fac->a = 0.5 * (fac->a + t); + + /* Angular distortion */ + fac->omega = 2. * aasin(P->ctx, (fac->a - fac->b) / (fac->a + fac->b) ); + + proj_errno_restore (P, err); return 0; } diff --git a/src/proj.c b/src/proj.c index 57d33a73..77d6b28b 100644 --- a/src/proj.c +++ b/src/proj.c @@ -287,21 +287,15 @@ static void vprocess(FILE *fid) { (void)printf(oform, dat_xy.u); putchar('\n'); (void)fputs("Northing (y): ", stdout); (void)printf(oform, dat_xy.v); putchar('\n'); - (void)printf("Meridian scale (h)%c: %.8f ( %.4g %% error )\n", - facs.code & IS_ANAL_HK ? '*' : ' ', facs.h, (facs.h-1.)*100.); - (void)printf("Parallel scale (k)%c: %.8f ( %.4g %% error )\n", - facs.code & IS_ANAL_HK ? '*' : ' ', facs.k, (facs.k-1.)*100.); - (void)printf("Areal scale (s): %.8f ( %.4g %% error )\n", - facs.s, (facs.s-1.)*100.); - (void)printf("Angular distortion (w): %.3f\n", facs.omega * - RAD_TO_DEG); - (void)printf("Meridian/Parallel angle: %.5f\n", - facs.thetap * RAD_TO_DEG); - (void)printf("Convergence%c: ",facs.code & IS_ANAL_CONV ? '*' : ' '); + (void)printf("Meridian scale (h) : %.8f ( %.4g %% error )\n", facs.h, (facs.h-1.)*100.); + (void)printf("Parallel scale (k) : %.8f ( %.4g %% error )\n", facs.k, (facs.k-1.)*100.); + (void)printf("Areal scale (s): %.8f ( %.4g %% error )\n", facs.s, (facs.s-1.)*100.); + (void)printf("Angular distortion (w): %.3f\n", facs.omega * RAD_TO_DEG); + (void)printf("Meridian/Parallel angle: %.5f\n", facs.thetap * RAD_TO_DEG); + (void)printf("Convergence : "); (void)fputs(rtodms(pline, facs.conv, 0, 0), stdout); (void)printf(" [ %.8f ]\n", facs.conv * RAD_TO_DEG); - (void)printf("Max-min (Tissot axis a-b) scale error: %.5f %.5f\n\n", - facs.a, facs.b); + (void)printf("Max-min (Tissot axis a-b) scale error: %.5f %.5f\n\n", facs.a, facs.b); } } diff --git a/src/proj.h b/src/proj.h index 19bb2192..cb689621 100644 --- a/src/proj.h +++ b/src/proj.h @@ -289,12 +289,6 @@ union PJ_PAIR { double v[2]; /* Yes - It's really just a vector! */ }; - -#define PJ_IS_ANAL_XL_YL 01 /* derivatives of lon analytic */ -#define PJ_IS_ANAL_XP_YP 02 /* derivatives of lat analytic */ -#define PJ_IS_ANAL_HK 04 /* h and k analytic */ -#define PJ_IS_ANAL_CONV 010 /* convergence analytic */ - struct PJ_INFO { char release[64]; /* Release info. Version + date */ char version[64]; /* Full version number */ diff --git a/src/proj_4D_api.c b/src/proj_4D_api.c index ee4cb20f..6e89fb60 100644 --- a/src/proj_4D_api.c +++ b/src/proj_4D_api.c @@ -816,9 +816,6 @@ PJ_FACTORS proj_factors(PJ *P, const LP lp) { ******************************************************************************/ PJ_FACTORS factors; - /* pj_factors rely code being zero */ - factors.code = 0; - if (pj_factors(lp, P, 0.0, &factors)) { /* errno set in pj_factors */ memset(&factors, 0, sizeof(PJ_FACTORS)); diff --git a/src/projects.h b/src/projects.h index 1d4fff50..32b74b08 100644 --- a/src/projects.h +++ b/src/projects.h @@ -257,9 +257,6 @@ struct PJconsts { PJ_COORD (*fwd4d)(PJ_COORD, PJ *); PJ_COORD (*inv4d)(PJ_COORD, PJ *); - - void (*spc)(LP, PJ *, struct FACTORS *); - void *(*destructor)(PJ *, int); @@ -460,14 +457,17 @@ struct FACTORS { double conv; /* convergence */ double s; /* areal scale factor */ double a, b; /* max-min scale error */ - int code; /* info as to analytics, see following */ + int code; /* always 0 */ +}; + +enum deprecated_constants_for_now_dropped_analytical_factors { + IS_ANAL_XL_YL = 01, /* derivatives of lon analytic */ + IS_ANAL_XP_YP = 02, /* derivatives of lat analytic */ + IS_ANAL_HK = 04, /* h and k analytic */ + IS_ANAL_CONV = 010 /* convergence analytic */ }; -#define IS_ANAL_XL_YL 01 /* derivatives of lon analytic */ -#define IS_ANAL_XP_YP 02 /* derivatives of lat analytic */ -#define IS_ANAL_HK 04 /* h and k analytic */ -#define IS_ANAL_CONV 010 /* convergence analytic */ /* datum_type values */ #define PJD_UNKNOWN 0 -- cgit v1.2.3 From cff58ea23f20306d7cc0410b808f0d46d73e6978 Mon Sep 17 00:00:00 2001 From: Thomas Knudsen Date: Wed, 15 Nov 2017 09:05:41 +0100 Subject: Adjust adjlon to use canonical M_PI defines (#665) A year or so ago, @micahcochran put quite some effort into rationalizing the PI usage in PROJ.4, by ensuring that a useful number of M_PI related constants were defined in projects.h. But apparently adjlon.c was left behind still using its own set of definitions - perhaps because it bends the values slightly, to avoid unwanted sign switching near the date line. In this PR the "bending trick" is reimplemented using the rationalized M_PI constants only. --- src/adjlon.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'src') diff --git a/src/adjlon.c b/src/adjlon.c index 09b3b14b..784a90aa 100644 --- a/src/adjlon.c +++ b/src/adjlon.c @@ -1,15 +1,20 @@ /* reduce argument to range +/- PI */ #include -#include - -#define SPI 3.14159265359 -#define TWOPI 6.2831853071795864769 -#define ONEPI 3.14159265358979323846 +#include "projects.h" double adjlon (double lon) { - if (fabs(lon) <= SPI) return( lon ); - lon += ONEPI; /* adjust to 0..2pi rad */ - lon -= TWOPI * floor(lon / TWOPI); /* remove integral # of 'revolutions'*/ - lon -= ONEPI; /* adjust back to -pi..pi rad */ - return( lon ); + /* Let lon slightly overshoot, to avoid spurious sign switching at the date line */ + if (fabs (lon) < M_PI + 1e-12) + return lon; + + /* adjust to 0..2pi range */ + lon += M_PI; + + /* remove integral # of 'revolutions'*/ + lon -= M_TWOPI * floor(lon / M_TWOPI); + + /* adjust back to -pi..pi range */ + lon -= M_PI; + + return lon; } -- cgit v1.2.3