Statistics
| Revision:

svn-gvsig-desktop / tags / v1_9_Build_1246 / libraries / libjni-proj4 / src / nad2nad.c @ 33782

History | View | Annotate | Download (7.7 KB)

1
/* <<<< North American Datum Transfer Program >>>> */
2
#ifndef lint
3
static const char SCCSID[]="@(#)nad2nad.c        4.5        94/02/15        GIE        REL";
4
#endif
5
#include <stdio.h>
6
#include <stdlib.h>
7
#include <ctype.h>
8
#include <string.h>
9
#define PJ_LIST_H <nad_list.h>
10
#include <projects.h>
11
#include <emess.h>
12

    
13
#define MAX_LINE 200
14
#define MAX_PARGS 100
15
#define PJ_INVERS(P) (P->inv ? 1 : 0)
16
        static int
17
echoin = 0,        /* echo input data to output line */
18
tag = '#';        /* beginning of line tag character */
19
        static char
20
*oform = (char *)0,        /* output format for x-y or decimal degrees */
21
*oterr = "*\t*",        /* output line for unprojectable input */
22
*inargs = 0,
23
*outargs = 0,
24
*czone = 0,
25
*usage =
26
"%s\nusage: %s [ -eEfihortwW [args] ] [ files ]\n";
27
        struct CTABLE
28
*ctab = 0,
29
*htab = 0;
30
static struct TAG_LIST {
31
        char *tag;
32
        short sw;
33
} ops_list[] = {
34
        "utm=",        0,
35
        "spcs=", 1,
36
        "feet", 2,
37
        "27", 3,
38
        "83", 4,
39
        "hp", 5,
40
        "bin", 6,
41
        "rev", 7,
42
        0, 0,
43
};
44
static struct IO_CON {
45
        short rev;        /* reverse lon/lat or x/y */
46
        short bin;        /* io binary */
47
        short ll;        /* io lat-lon */
48
        short t83;        /* data in 83 datum */
49
        short zone;        /* <100 utm zone, ==0 geog,  else state plane zone */
50
        short nprojc; /* number of entries in projc */
51
        char *hp;        /* high precision name */
52
        char *projc[10];        /* params for pj_init */
53
        PJ *cnv;
54
} input = {
55
        0, 0, 0, 0, 0, 0, 0,
56
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
57
        0,
58
}, output = {
59
        0, 0, 0, 0, 0, 0, 0,
60
        0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
61
        0,
62
};
63
        static void
64
set_zone(int in, struct IO_CON *io) {
65
        char tmp[20];
66

    
67
        if (io->hp) {
68
                io->t83 = 1;
69
                if (!(htab = nad_init(io->hp)))
70
                        emess(1,"hp datum file: %s, failed: %s", io->hp,
71
                                pj_strerrno(pj_errno));
72
        }
73
        if (io->zone > 0) {
74
                if (io->zone <= 60) { /* UTM zone */
75
                        io->nprojc = 2; /* no other options allowed */
76
                        io->projc[0] = "proj=utm";
77
                        sprintf(tmp, "zone=%d", io->zone);
78
                        io->projc[1] = io->t83 ? "ellps=GRS80" : "ellps=clrk66";
79
                } else /* SPCS zone */
80
                        sprintf(tmp, "init=nad%s:%d", io->t83 ? "83" : "27", io->zone);
81
                io->projc[io->nprojc++] = tmp;
82
                io->projc[io->nprojc++] = "no_defs";
83
                if (!(io->cnv = pj_init(io->nprojc, io->projc)))
84
                        emess(1,pj_strerrno(pj_errno));
85
                io->ll = 0;
86
        }
87
}
88
        static void
89
setup() {
90
        /* check and set zone operations */
91
        if (input.hp && output.hp)
92
                emess(1,"both input and output cannot be high precision");
93
        set_zone(1, &input);
94
        set_zone(0, &output);
95
        if (input.cnv && !output.cnv)
96
                output.ll = 1;
97
        if (output.cnv && !input.cnv)
98
                input.ll = 1;
99
        if (!input.cnv && !output.cnv)
100
                output.ll = input.ll = 1;
101
        if (czone) {
102
                if (!input.hp && !output.hp && input.t83 == output.t83)
103
                        emess(1,"identical datums");
104
                if (!(ctab = nad_init(czone)))
105
                        emess(1,"datum file: %s, failed: %s", czone, pj_strerrno(pj_errno));
106
        } else if (input.t83 != output.t83)
107
                emess(1,"conversion region (-r) not specified");
108
}
109
        static void
110
set_ops(char *s, struct IO_CON *io) {
111
        char *intag;
112
        struct TAG_LIST *p;
113

    
114
        for ( ; intag = strtok(s, " ,\t"); s = 0) {
115
                for (p = ops_list; p->tag; ++p) {
116
                        if (!strncmp(intag, p->tag, strlen(p->tag)))
117
                                break;
118
                }
119
                if (!p->tag)
120
                        emess(1,"invalid selection");
121
                switch (p->sw) {
122
                case 0:
123
                case 1:
124
                        s = strchr(intag, '=') + 1;
125
                        io->zone = atoi(s);
126
                        break;
127
                case 2:
128
                        if (io->zone <= 60)
129
                                emess(1,"spcs zone must be selected");
130
                        io->projc[io->nprojc++] = "units=us-ft";
131
                        break;
132
                case 3: io->t83 = 0; break;
133
                case 4: io->t83 = 1; break;
134
                case 5:
135
                        if (!(intag = strchr(intag, '=')) || *++intag == '\0')
136
                                emess(1,"hp missing name");
137
                        strcpy(io->hp = (char*)malloc(strlen(intag)+1), intag);
138
                        break;
139
                case 6: io->bin = 1; break;
140
                case 7: io->rev = 1; break;
141
                }
142
        }
143
}
144
        static void
145
process(FILE *fid) {
146
        char line[MAX_LINE], *s, t, pline[100];
147
        projUV val;
148
        double tmp;
149

    
150
        for (;;) {
151
                if (input.bin)
152
                        fread(&val, sizeof(projUV), 1, fid);
153
                else if (s = fgets(line, MAX_LINE, fid)) {
154
                        if (*s == tag) {
155
                                fputs(line, stdout);
156
                                continue;
157
                        } else if (input.ll) {
158
                                val.u = dmstor(s, &s);
159
                                val.v = dmstor(s, &s);
160
                        } else {
161
                                val.u = strtod(s, &s);
162
                                val.v = strtod(s, &s);
163
                        }
164
                }
165
                if (feof(fid))
166
                        break;
167
                if (input.rev) {
168
                        tmp = val.u;
169
                        val.u = val.v;
170
                        val.v = tmp;
171
                }
172
                /* data in, manupulate */
173
                if (input.cnv)
174
                        val = pj_inv(val, input.cnv);
175
                if (input.hp)
176
                        val = nad_cvt(val, 1, htab);
177
                /* nad conversion */
178
                if (ctab)
179
                        val = nad_cvt(val, input.t83 ? 1 : 0, ctab);
180
                if (output.hp)
181
                        val = nad_cvt(val, 0, htab);
182
                if (output.cnv)
183
                        val = pj_fwd(val, output.cnv);
184
                /* output data */
185
                if (output.rev) {
186
                        tmp = val.u;
187
                        val.u = val.v;
188
                        val.v = tmp;
189
                }
190
                if (output.bin)
191
                        (void)fwrite(&val, sizeof(projUV), 1, stdout);
192
                else {
193
                        if (echoin) {
194
                                t = *s;
195
                                *s = '\0';
196
                                (void)fputs(line, stdout);
197
                                (void)putchar('\t');
198
                                *s = t;
199
                        }
200
                        if (val.u == HUGE_VAL)
201
                                (void)fputs(oterr, stdout);
202
                        else if (output.ll)
203
                                if (oform) {
204
                                        (void)printf(oform, val.u * RAD_TO_DEG);
205
                                        (void)putchar('\t');
206
                                        (void)printf(oform, val.v * RAD_TO_DEG);
207
                                } else if (output.rev) {
208
                                        (void)fputs(rtodms(pline, val.u, 'N', 'S'), stdout);
209
                                        (void)putchar('\t');
210
                                        (void)fputs(rtodms(pline, val.v, 'E', 'W'), stdout);
211
                                } else {
212
                                        (void)fputs(rtodms(pline, val.u, 'E', 'W'), stdout);
213
                                        (void)putchar('\t');
214
                                        (void)fputs(rtodms(pline, val.v, 'N', 'S'), stdout);
215
                                }
216
                        else {
217
                                (void)printf(oform ? oform : "%.2f", val.u);
218
                                (void)putchar('\t');
219
                                (void)printf(oform ? oform : "%.2f", val.v);
220
                        }
221
                        if (input.bin)
222
                                putchar('\n');
223
                        else
224
                                (void)fputs(s, stdout);
225
                }
226
        }
227
}
228
int 
229
main(int argc, char **argv) {
230
        char *arg, **eargv = argv, work[MAX_PARGS];
231
        FILE *fid;
232
        int eargc = 0, c;
233

    
234
        if (emess_dat.Prog_name = strrchr(*argv,DIR_CHAR))
235
                ++emess_dat.Prog_name;
236
        else emess_dat.Prog_name = *argv;
237
        if (argc <= 1 ) {
238
                (void)fprintf(stderr, usage, pj_release, emess_dat.Prog_name);
239
                exit (0);
240
        }
241
                /* process run line arguments */
242
        while (--argc > 0) { /* collect run line arguments */
243
                if(**++argv == '-') for(arg = *argv;;) {
244
                        switch(*++arg) {
245
                        case '\0': /* position of "stdin" */
246
                                if (arg[-1] == '-') eargv[eargc++] = "-";
247
                                break;
248
                        case 'i': /* input control */
249
                        case 'o': /* output control */
250
                                if (--argc <= 0) goto noargument;
251
                                strncpy(work, *++argv, MAX_PARGS);
252
                                set_ops(work, *arg == 'i' ? &input : &output);
253
                                continue;
254
                        case 'r': /* nad27/83 conversion zone */
255
                                if (--argc <= 0) goto noargument;
256
                                czone = *++argv;
257
                                continue;
258
                        case 'E': /* echo ascii input to ascii output */
259
                                echoin = 1;
260
                                continue;
261
                        case 't': /* set col. one char */
262
                                if (arg[1]) tag = *++arg;
263
                                else emess(1,"missing -t col. 1 tag");
264
                                continue;
265
                        case 'W': /* specify seconds precision */
266
                        case 'w': /* -W for constant field width */
267
                                if ((c = arg[1]) != 0 && isdigit(c)) {
268
                                        set_rtodms(c - '0', *arg == 'W');
269
                                        ++arg;
270
                                } else
271
                                    emess(1,"-W argument missing or non-digit");
272
                                continue;
273
                        case 'f': /* alternate output format degrees or xy */
274
                                if (--argc <= 0) goto noargument;
275
                                oform = *++argv;
276
                                continue;
277
                        case 'e': /* error line alternative */
278
                                if (--argc <= 0)
279
noargument:                           emess(1,"missing argument for -%c",*arg);
280
                                oterr = *++argv;
281
                                continue;
282
                        default:
283
                                emess(1, "invalid option: -%c",*arg);
284
                                break;
285
                        }
286
                        break;
287
                } else /* assumed to be input file name(s) */
288
                        eargv[eargc++] = *argv;
289
        }
290
        if (eargc == 0) /* if no specific files force sysin */
291
                eargv[eargc++] = "-";
292
        /* done with parameter and control input */
293
        setup();
294
        /* process input file list */
295
        for ( ; eargc-- ; ++eargv) {
296
                if (**eargv == '-') {
297
                        fid = stdin;
298
                        emess_dat.File_name = "<stdin>";
299
                } else {
300
                        if ((fid = fopen(*eargv, "r")) == NULL) {
301
                                emess(-2, *eargv, "input file");
302
                                continue;
303
                        }
304
                        emess_dat.File_name = *eargv;
305
                }
306
                emess_dat.File_line = 0;
307
                /* process file */
308
                process(fid);
309
                (void)fclose(fid);
310
                emess_dat.File_name = 0;
311
        }
312
        exit(0); /* normal completion */
313
}