svn-gvsig-desktop / trunk / libraries / libjni-proj4 / src / nad2nad.c @ 7098
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 |
} |