diff options
| author | Frank Warmerdam <warmerdam@pobox.com> | 1999-03-18 16:34:52 +0000 |
|---|---|---|
| committer | Frank Warmerdam <warmerdam@pobox.com> | 1999-03-18 16:34:52 +0000 |
| commit | 565a4bd035b9d4a83955808efef20f1d8dfa24cf (patch) | |
| tree | 75785fc897708023f1ccdaf40079afcbaaf0fd3a /src/nad2nad.c | |
| download | PROJ-565a4bd035b9d4a83955808efef20f1d8dfa24cf.tar.gz PROJ-565a4bd035b9d4a83955808efef20f1d8dfa24cf.zip | |
New
git-svn-id: http://svn.osgeo.org/metacrs/proj/trunk@776 4e78687f-474d-0410-85f9-8d5e500ac6b2
Diffstat (limited to 'src/nad2nad.c')
| -rw-r--r-- | src/nad2nad.c | 313 |
1 files changed, 313 insertions, 0 deletions
diff --git a/src/nad2nad.c b/src/nad2nad.c new file mode 100644 index 00000000..210854e6 --- /dev/null +++ b/src/nad2nad.c @@ -0,0 +1,313 @@ +/* <<<< North American Datum Transfer Program >>>> */ +#ifndef lint +static const char SCCSID[]="@(#)nad2nad.c 4.5 94/02/15 GIE REL"; +#endif +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include <string.h> +#define PJ_LIST_H <nad_list.h> +#include <projects.h> +#include "emess.h" + +#define MAX_LINE 200 +#define MAX_PARGS 100 +#define PJ_INVERS(P) (P->inv ? 1 : 0) + static int +echoin = 0, /* echo input data to output line */ +tag = '#'; /* beginning of line tag character */ + static char +*oform = (char *)0, /* output format for x-y or decimal degrees */ +*oterr = "*\t*", /* output line for unprojectable input */ +*inargs = 0, +*outargs = 0, +*czone = 0, +*usage = +"%s\nusage: %s [ -eEfihortwW [args] ] [ files ]\n"; + struct CTABLE +*ctab = 0, +*htab = 0; +static struct TAG_LIST { + char *tag; + short sw; +} ops_list[] = { + "utm=", 0, + "spcs=", 1, + "feet", 2, + "27", 3, + "83", 4, + "hp", 5, + "bin", 6, + "rev", 7, + 0, 0, +}; +static struct IO_CON { + short rev; /* reverse lon/lat or x/y */ + short bin; /* io binary */ + short ll; /* io lat-lon */ + short t83; /* data in 83 datum */ + short zone; /* <100 utm zone, ==0 geog, else state plane zone */ + short nprojc; /* number of entries in projc */ + char *hp; /* high precision name */ + char *projc[10]; /* params for pj_init */ + PJ *cnv; +} input = { + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}, output = { + 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, +}; + static void +set_zone(int in, struct IO_CON *io) { + char tmp[20]; + + if (io->hp) { + io->t83 = 1; + if (!(htab = nad_init(io->hp))) + emess(1,"hp datum file: %s, failed: %s", io->hp, + pj_strerrno(pj_errno)); + } + if (io->zone > 0) { + if (io->zone <= 60) { /* UTM zone */ + io->nprojc = 2; /* no other options allowed */ + io->projc[0] = "proj=utm"; + sprintf(tmp, "zone=%d", io->zone); + io->projc[1] = io->t83 ? "ellps=GRS80" : "ellps=clrk66"; + } else /* SPCS zone */ + sprintf(tmp, "init=nad%s:%d", io->t83 ? "83" : "27", io->zone); + io->projc[io->nprojc++] = tmp; + io->projc[io->nprojc++] = "no_defs"; + if (!(io->cnv = pj_init(io->nprojc, io->projc))) + emess(1,pj_strerrno(pj_errno)); + io->ll = 0; + } +} + static void +setup() { + /* check and set zone operations */ + if (input.hp && output.hp) + emess(1,"both input and output cannot be high precision"); + set_zone(1, &input); + set_zone(0, &output); + if (input.cnv && !output.cnv) + output.ll = 1; + if (output.cnv && !input.cnv) + input.ll = 1; + if (!input.cnv && !output.cnv) + output.ll = input.ll = 1; + if (czone) { + if (!input.hp && !output.hp && input.t83 == output.t83) + emess(1,"identical datums"); + if (!(ctab = nad_init(czone))) + emess(1,"datum file: %s, failed: %s", czone, pj_strerrno(pj_errno)); + } else if (input.t83 != output.t83) + emess(1,"conversion region (-r) not specified"); +} + static void +set_ops(char *s, struct IO_CON *io) { + char *intag; + struct TAG_LIST *p; + + for ( ; intag = strtok(s, " ,\t"); s = 0) { + for (p = ops_list; p->tag; ++p) { + if (!strncmp(intag, p->tag, strlen(p->tag))) + break; + } + if (!p->tag) + emess(1,"invalid selection"); + switch (p->sw) { + case 0: + case 1: + s = strchr(intag, '=') + 1; + io->zone = atoi(s); + break; + case 2: + if (io->zone <= 60) + emess(1,"spcs zone must be selected"); + io->projc[io->nprojc++] = "units=us-ft"; + break; + case 3: io->t83 = 0; break; + case 4: io->t83 = 1; break; + case 5: + if (!(intag = strchr(intag, '=')) || *++intag == '\0') + emess(1,"hp missing name"); + strcpy(io->hp = malloc(strlen(intag)+1), intag); + break; + case 6: io->bin = 1; break; + case 7: io->rev = 1; break; + } + } +} + static void +process(FILE *fid) { + char line[MAX_LINE], *s, t, pline[100]; + UV val; + double tmp; + + for (;;) { + if (input.bin) + fread(&val, sizeof(UV), 1, fid); + else if (s = fgets(line, MAX_LINE, fid)) { + if (*s == tag) { + fputs(line, stdout); + continue; + } else if (input.ll) { + val.u = dmstor(s, &s); + val.v = dmstor(s, &s); + } else { + val.u = strtod(s, &s); + val.v = strtod(s, &s); + } + } + if (feof(fid)) + break; + if (input.rev) { + tmp = val.u; + val.u = val.v; + val.v = tmp; + } + /* data in, manupulate */ + if (input.cnv) + val = pj_inv(val, input.cnv); + if (input.hp) + val = nad_cvt(val, 1, htab); + /* nad conversion */ + if (ctab) + val = nad_cvt(val, input.t83 ? 1 : 0, ctab); + if (output.hp) + val = nad_cvt(val, 0, htab); + if (output.cnv) + val = pj_fwd(val, output.cnv); + /* output data */ + if (output.rev) { + tmp = val.u; + val.u = val.v; + val.v = tmp; + } + if (output.bin) + (void)fwrite(&val, sizeof(UV), 1, stdout); + else { + if (echoin) { + t = *s; + *s = '\0'; + (void)fputs(line, stdout); + (void)putchar('\t'); + *s = t; + } + if (val.u == HUGE_VAL) + (void)fputs(oterr, stdout); + else if (output.ll) + if (oform) { + (void)printf(oform, val.u * RAD_TO_DEG); + (void)putchar('\t'); + (void)printf(oform, val.v * RAD_TO_DEG); + } else if (output.rev) { + (void)fputs(rtodms(pline, val.u, 'N', 'S'), stdout); + (void)putchar('\t'); + (void)fputs(rtodms(pline, val.v, 'E', 'W'), stdout); + } else { + (void)fputs(rtodms(pline, val.u, 'E', 'W'), stdout); + (void)putchar('\t'); + (void)fputs(rtodms(pline, val.v, 'N', 'S'), stdout); + } + else { + (void)printf(oform ? oform : "%.2f", val.u); + (void)putchar('\t'); + (void)printf(oform ? oform : "%.2f", val.v); + } + if (input.bin) + putchar('\n'); + else + (void)fputs(s, stdout); + } + } +} + void +main(int argc, char **argv) { + char *arg, **eargv = argv, work[MAX_PARGS]; + FILE *fid; + int eargc = 0, c; + + if (emess_dat.Prog_name = strrchr(*argv,DIR_CHAR)) + ++emess_dat.Prog_name; + else emess_dat.Prog_name = *argv; + if (argc <= 1 ) { + (void)fprintf(stderr, usage, pj_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++] = "-"; + break; + case 'i': /* input control */ + case 'o': /* output control */ + if (--argc <= 0) goto noargument; + strncpy(work, *++argv, MAX_PARGS); + set_ops(work, *arg == 'i' ? &input : &output); + continue; + case 'r': /* nad27/83 conversion zone */ + if (--argc <= 0) goto noargument; + czone = *++argv; + 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 'W': /* specify seconds precision */ + case 'w': /* -W for constant field width */ + if ((c = arg[1]) != 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 'e': /* error line alternative */ + if (--argc <= 0) +noargument: emess(1,"missing argument for -%c",*arg); + oterr = *++argv; + continue; + default: + emess(1, "invalid option: -%c",*arg); + break; + } + break; + } else /* assumed to be input file name(s) */ + eargv[eargc++] = *argv; + } + if (eargc == 0) /* if no specific files force sysin */ + eargv[eargc++] = "-"; + /* done with parameter and control input */ + setup(); + /* process input file list */ + for ( ; eargc-- ; ++eargv) { + if (**eargv == '-') { + fid = stdin; + emess_dat.File_name = "<stdin>"; + } else { + if ((fid = fopen(*eargv, "r")) == NULL) { + emess(-2, *eargv, "input file"); + continue; + } + emess_dat.File_name = *eargv; + } + emess_dat.File_line = 0; + /* process file */ + process(fid); + (void)fclose(fid); + emess_dat.File_name = 0; + } + exit(0); /* normal completion */ +} |
