aboutsummaryrefslogtreecommitdiff
path: root/src/cs2cs.cpp
diff options
context:
space:
mode:
authorEven Rouault <even.rouault@spatialys.com>2018-11-22 23:12:54 +0100
committerEven Rouault <even.rouault@spatialys.com>2018-11-22 23:16:45 +0100
commita7f696c0772c558c41c7050496bc658706902af2 (patch)
treec74759b24237253d12e2a47fe343857868173c63 /src/cs2cs.cpp
parent549268ff39d4ef614bc8a32d7bd735e87802d78b (diff)
downloadPROJ-a7f696c0772c558c41c7050496bc658706902af2.tar.gz
PROJ-a7f696c0772c558c41c7050496bc658706902af2.zip
Rename cs2cs.c to cs2cs.cpp with minimal changes to make it compile
Diffstat (limited to 'src/cs2cs.cpp')
-rw-r--r--src/cs2cs.cpp466
1 files changed, 466 insertions, 0 deletions
diff --git a/src/cs2cs.cpp b/src/cs2cs.cpp
new file mode 100644
index 00000000..439b172c
--- /dev/null
+++ b/src/cs2cs.cpp
@@ -0,0 +1,466 @@
+/******************************************************************************
+ * Project: PROJ.4
+ * Purpose: Mainline program sort of like ``proj'' for converting between
+ * two coordinate systems.
+ * Author: Frank Warmerdam, warmerda@home.com
+ *
+ ******************************************************************************
+ * Copyright (c) 2000, Frank Warmerdam
+ *
+ * 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 <ctype.h>
+#include <locale.h>
+#include <math.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "proj.h"
+#include "projects.h"
+#include "emess.h"
+
+#define MAX_LINE 1000
+#define MAX_PARGS 100
+
+static projPJ fromProj, toProj;
+
+static int
+reversein = 0, /* != 0 reverse input arguments */
+reverseout = 0, /* != 0 reverse output arguments */
+echoin = 0, /* echo input data to output line */
+tag = '#'; /* beginning of line tag character */
+
+static const char *oform = nullptr; /* output format for x-y or decimal degrees */
+static char oform_buffer[16]; /* buffer for oform when using -d */
+static const char *oterr = "*\t*"; /* output line for unprojectable input */
+static const char *usage =
+"%s\nusage: %s [ -dDeEfIlrstvwW [args] ] [ +opts[=arg] ]\n"
+" [+to [+opts[=arg] [ files ]\n";
+
+static double (*informat)(const char *,
+ char **); /* input data deformatter function */
+
+
+/************************************************************************/
+/* process() */
+/* */
+/* File processing function. */
+/************************************************************************/
+static void process(FILE *fid)
+
+{
+ char line[MAX_LINE+3], *s, pline[40];
+ projUV data;
+
+ for (;;) {
+ double z;
+
+ ++emess_dat.File_line;
+ if (!(s = fgets(line, MAX_LINE, fid)))
+ break;
+ if (!strchr(s, '\n')) { /* overlong line */
+ int c;
+ (void)strcat(s, "\n");
+ /* gobble up to newline */
+ while ((c = fgetc(fid)) != EOF && c != '\n') ;
+ }
+ if (*s == tag) {
+ fputs(line, stdout);
+ continue;
+ }
+
+ if (reversein) {
+ data.v = (*informat)(s, &s);
+ data.u = (*informat)(s, &s);
+ } else {
+ data.u = (*informat)(s, &s);
+ data.v = (*informat)(s, &s);
+ }
+
+ z = strtod( s, &s );
+
+ if (data.v == HUGE_VAL)
+ data.u = HUGE_VAL;
+
+ if (!*s && (s > line)) --s; /* assumed we gobbled \n */
+
+ if ( echoin) {
+ char t;
+ t = *s;
+ *s = '\0';
+ (void)fputs(line, stdout);
+ *s = t;
+ putchar('\t');
+ }
+
+ if (data.u != HUGE_VAL) {
+ if( pj_transform( fromProj, toProj, 1, 0,
+ &(data.u), &(data.v), &z ) != 0 )
+ {
+ data.u = HUGE_VAL;
+ data.v = HUGE_VAL;
+ emess(-3,"pj_transform(): %s", pj_strerrno(pj_errno));
+ }
+ }
+
+ if (data.u == HUGE_VAL) /* error output */
+ fputs(oterr, stdout);
+
+ else if (pj_is_latlong(toProj) && !oform) { /*ascii DMS output */
+ if (reverseout) {
+ fputs(rtodms(pline, data.v, 'N', 'S'), stdout);
+ putchar('\t');
+ fputs(rtodms(pline, data.u, 'E', 'W'), stdout);
+ } else {
+ fputs(rtodms(pline, data.u, 'E', 'W'), stdout);
+ putchar('\t');
+ fputs(rtodms(pline, data.v, 'N', 'S'), stdout);
+ }
+
+ } else { /* x-y or decimal degree ascii output */
+ if ( proj_angular_output(toProj, PJ_FWD) ) {
+ data.v *= RAD_TO_DEG;
+ data.u *= RAD_TO_DEG;
+ }
+ if (reverseout) {
+ printf(oform,data.v); putchar('\t');
+ printf(oform,data.u);
+ } else {
+ printf(oform,data.u); putchar('\t');
+ printf(oform,data.v);
+ }
+ }
+
+ putchar(' ');
+ if( oform != nullptr )
+ printf( oform, z );
+ else
+ printf( "%.3f", z );
+ if( s )
+ printf( "%s", s );
+ else
+ printf( "\n" );
+ }
+}
+
+/************************************************************************/
+/* main() */
+/************************************************************************/
+
+int main(int argc, char **argv)
+{
+ char *arg;
+ char **eargv = argv;
+ char *from_argv[MAX_PARGS];
+ char *to_argv[MAX_PARGS];
+ FILE *fid;
+ int from_argc=0, to_argc=0, eargc = 0, mon = 0;
+ int have_to_flag = 0, inverse = 0, i;
+ int use_env_locale = 0;
+
+ /* This is just to check that pj_init() is locale-safe */
+ /* Used by nad/testvarious */
+ if( getenv("PROJ_USE_ENV_LOCALE") != nullptr )
+ use_env_locale = 1;
+
+ if ((emess_dat.Prog_name = strrchr(*argv,DIR_CHAR)) != nullptr)
+ ++emess_dat.Prog_name;
+ else emess_dat.Prog_name = *argv;
+ inverse = ! strncmp(emess_dat.Prog_name, "inv", 3);
+ if (argc <= 1 ) {
+ (void)fprintf(stderr, usage, pj_get_release(), emess_dat.Prog_name);
+ exit (0);
+ }
+ /* process run line arguments */
+ while (--argc > 0) { /* collect run line arguments */
+ if(**++argv == '-') for(arg = *argv;;) {
+ switch(*++arg) {
+ case '\0': /* position of "stdin" */
+ if (arg[-1] == '-') eargv[eargc++] = const_cast<char*>("-");
+ break;
+ case 'v': /* monitor dump of initialization */
+ mon = 1;
+ continue;
+ case 'I': /* alt. method to spec inverse */
+ inverse = 1;
+ continue;
+ case 'E': /* echo ascii input to ascii output */
+ echoin = 1;
+ continue;
+ case 't': /* set col. one char */
+ if (arg[1]) tag = *++arg;
+ else emess(1,"missing -t col. 1 tag");
+ continue;
+ case 'l': /* list projections, ellipses or units */
+ if (!arg[1] || arg[1] == 'p' || arg[1] == 'P') {
+ /* list projections */
+ const struct PJ_LIST *lp;
+ int do_long = arg[1] == 'P', c;
+ const char *str;
+
+ for (lp = proj_list_operations() ; lp->id ; ++lp) {
+ (void)printf("%s : ", lp->id);
+ if (do_long) /* possibly multiline description */
+ (void)puts(*lp->descr);
+ else { /* first line, only */
+ str = *lp->descr;
+ while ((c = *str++) && c != '\n')
+ putchar(c);
+ putchar('\n');
+ }
+ }
+ } else if (arg[1] == '=') { /* list projection 'descr' */
+ const struct PJ_LIST *lp;
+
+ arg += 2;
+ for (lp = proj_list_operations() ; lp->id ; ++lp)
+ if (!strcmp(lp->id, arg)) {
+ (void)printf("%9s : %s\n", lp->id, *lp->descr);
+ break;
+ }
+ } else if (arg[1] == 'e') { /* list ellipses */
+ const struct PJ_ELLPS *le;
+
+ for (le = proj_list_ellps(); le->id ; ++le)
+ (void)printf("%9s %-16s %-16s %s\n",
+ le->id, le->major, le->ell, le->name);
+ } else if (arg[1] == 'u') { /* list units */
+ const struct PJ_UNITS *lu;
+
+ for (lu = proj_list_units(); lu->id ; ++lu)
+ (void)printf("%12s %-20s %s\n",
+ lu->id, lu->to_meter, lu->name);
+ } else if (arg[1] == 'd') { /* list datums */
+ const struct PJ_DATUMS *ld;
+
+ printf("__datum_id__ __ellipse___ __definition/comments______________________________\n" );
+ for (ld = pj_get_datums_ref(); ld->id ; ++ld)
+ {
+ printf("%12s %-12s %-30s\n",
+ ld->id, ld->ellipse_id, ld->defn);
+ if( ld->comments != nullptr && strlen(ld->comments) > 0 )
+ printf( "%25s %s\n", " ", ld->comments );
+ }
+ } else if( arg[1] == 'm') { /* list prime meridians */
+ const struct PJ_PRIME_MERIDIANS *lpm;
+
+ for (lpm = proj_list_prime_meridians(); lpm->id ; ++lpm)
+ (void)printf("%12s %-30s\n",
+ lpm->id, lpm->defn);
+ } else
+ emess(1,"invalid list option: l%c",arg[1]);
+ exit(0);
+ /* cppcheck-suppress duplicateBreak */
+ continue; /* artificial */
+ case 'e': /* error line alternative */
+ if (--argc <= 0)
+ noargument:
+ emess(1,"missing argument for -%c",*arg);
+ oterr = *++argv;
+ continue;
+ case 'W': /* specify seconds precision */
+ case 'w': /* -W for constant field width */
+ {
+ char c = arg[1];
+ if (c != 0 && isdigit(c)) {
+ set_rtodms(c - '0', *arg == 'W');
+ ++arg;
+ } else
+ emess(1,"-W argument missing or non-digit");
+ continue;
+ }
+ case 'f': /* alternate output format degrees or xy */
+ if (--argc <= 0) goto noargument;
+ oform = *++argv;
+ continue;
+ case 'r': /* reverse input */
+ reversein = 1;
+ continue;
+ case 's': /* reverse output */
+ reverseout = 1;
+ continue;
+ case 'D': /* set debug level */
+ if (--argc <= 0) goto noargument;
+ pj_ctx_set_debug( pj_get_default_ctx(), atoi(*++argv));
+ continue;
+ case 'd':
+ if (--argc <= 0) goto noargument;
+ sprintf(oform_buffer, "%%.%df", atoi(*++argv));
+ oform = oform_buffer;
+ break;
+ default:
+ emess(1, "invalid option: -%c",*arg);
+ break;
+ }
+ break;
+
+ } else if (strcmp(*argv,"+to") == 0 ) {
+ have_to_flag = 1;
+
+ } else if (**argv == '+') { /* + argument */
+ if( have_to_flag )
+ {
+ if( to_argc < MAX_PARGS )
+ to_argv[to_argc++] = *argv + 1;
+ else
+ emess(1,"overflowed + argument table");
+ }
+ else
+ {
+ if (from_argc < MAX_PARGS)
+ from_argv[from_argc++] = *argv + 1;
+ else
+ emess(1,"overflowed + argument table");
+ }
+ } else /* assumed to be input file name(s) */
+ eargv[eargc++] = *argv;
+ }
+ if (eargc == 0 ) /* if no specific files force sysin */
+ eargv[eargc++] = const_cast<char*>("-");
+
+ /*
+ * If the user has requested inverse, then just reverse the
+ * coordinate systems.
+ */
+ if( inverse )
+ {
+ int argcount;
+
+ for( i = 0; i < MAX_PARGS; i++ )
+ {
+ arg = from_argv[i];
+ from_argv[i] = to_argv[i];
+ to_argv[i] = arg;
+ }
+
+ argcount = from_argc;
+ from_argc = to_argc;
+ to_argc = argcount;
+ }
+
+ if( use_env_locale )
+ {
+ /* Set locale from environment */
+ setlocale(LC_ALL, "");
+ }
+
+ if( from_argc == 0 && to_argc != 0 )
+ {
+ /* we will generate the from proj as the latlong of the +to in a bit */
+ }
+ else if (!(fromProj = pj_init(from_argc, from_argv)))
+ {
+ printf( "Using from definition: " );
+ for( i = 0; i < from_argc; i++ )
+ printf( "%s ", from_argv[i] );
+ printf( "\n" );
+
+ emess(3,"projection initialization failure\ncause: %s",
+ pj_strerrno(pj_errno));
+ }
+
+ if( to_argc == 0 )
+ {
+ if (!(toProj = pj_latlong_from_proj( fromProj )))
+ {
+ printf( "Using to definition: " );
+ for( i = 0; i < to_argc; i++ )
+ printf( "%s ", to_argv[i] );
+ printf( "\n" );
+
+ emess(3,"projection initialization failure\ncause: %s",
+ pj_strerrno(pj_errno));
+ }
+ }
+ else if (!(toProj = pj_init(to_argc, to_argv)))
+ {
+ printf( "Using to definition: " );
+ for( i = 0; i < to_argc; i++ )
+ printf( "%s ", to_argv[i] );
+ printf( "\n" );
+
+ emess(3,"projection initialization failure\ncause: %s",
+ pj_strerrno(pj_errno));
+ }
+
+ if( from_argc == 0 && toProj != nullptr)
+ {
+ if (!(fromProj = pj_latlong_from_proj( toProj )))
+ {
+ printf( "Using to definition: " );
+ for( i = 0; i < to_argc; i++ )
+ printf( "%s ", to_argv[i] );
+ printf( "\n" );
+
+ emess(3,"projection initialization failure\ncause: %s",
+ pj_strerrno(pj_errno));
+ }
+ }
+
+ if( use_env_locale )
+ {
+ /* Restore C locale to avoid issues in parsing/outputting numbers*/
+ setlocale(LC_ALL, "C");
+ }
+
+ if (mon) {
+ printf( "%c ---- From Coordinate System ----\n", tag );
+ pj_pr_list(fromProj);
+ printf( "%c ---- To Coordinate System ----\n", tag );
+ pj_pr_list(toProj);
+ }
+
+ /* set input formatting control */
+ if( !fromProj->is_latlong )
+ informat = strtod;
+ else {
+ informat = dmstor;
+ }
+
+ if( !toProj->is_latlong && !oform )
+ oform = "%.2f";
+
+ /* process input file list */
+ for ( ; eargc-- ; ++eargv) {
+ if (**eargv == '-') {
+ fid = stdin;
+ emess_dat.File_name = const_cast<char*>("<stdin>");
+
+ } else {
+ if ((fid = fopen(*eargv, "rt")) == nullptr) {
+ emess(-2, *eargv, "input file");
+ continue;
+ }
+ emess_dat.File_name = *eargv;
+ }
+ emess_dat.File_line = 0;
+ process(fid);
+ fclose(fid);
+ emess_dat.File_name = nullptr;
+ }
+
+ pj_free( fromProj );
+ pj_free( toProj );
+
+ pj_deallocate_grids();
+
+ exit(0); /* normal completion */
+}