diff options
| author | Even Rouault <even.rouault@spatialys.com> | 2018-11-22 23:12:54 +0100 |
|---|---|---|
| committer | Even Rouault <even.rouault@spatialys.com> | 2018-11-22 23:16:45 +0100 |
| commit | a7f696c0772c558c41c7050496bc658706902af2 (patch) | |
| tree | c74759b24237253d12e2a47fe343857868173c63 /src/cs2cs.cpp | |
| parent | 549268ff39d4ef614bc8a32d7bd735e87802d78b (diff) | |
| download | PROJ-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.cpp | 466 |
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 */ +} |
