svn-gvsig-desktop / branches / v2_0_0_prep / libraries / libjni-proj4 / src / libcs2cs.c @ 28773
History | View | Annotate | Download (12.4 KB)
1 |
#include <stdio.h> |
---|---|
2 |
#include <stdlib.h> |
3 |
#include <ctype.h> |
4 |
#include <string.h> |
5 |
#include <math.h> |
6 |
#include "projects.h" |
7 |
#include "emess.h" |
8 |
|
9 |
#define MAX_LINE 200 |
10 |
#define MAX_PARGS 100 |
11 |
|
12 |
static projPJ fromProj, toProj;
|
13 |
|
14 |
static int |
15 |
reversein = 0, /* != 0 reverse input arguments */ |
16 |
reverseout = 0, /* != 0 reverse output arguments */ |
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 |
*usage = |
23 |
"%s\nusage: %s [ -eEfIlrstvwW [args] ] [ +opts[=arg] ]\n"
|
24 |
" [+to [+opts[=arg] [ files ]\n";
|
25 |
|
26 |
static struct FACTORS facs; |
27 |
//static double (*informat)(const char *,
|
28 |
// char **); /* input data deformatter function */
|
29 |
|
30 |
|
31 |
/************************************************************************/
|
32 |
/* process() */
|
33 |
/* */
|
34 |
/* File processing function. */
|
35 |
/************************************************************************/
|
36 |
//static void process(FILE *fid)
|
37 |
//
|
38 |
//{
|
39 |
// char line[MAX_LINE+3], *s, pline[40];
|
40 |
// projUV data;
|
41 |
//
|
42 |
// for (;;) {
|
43 |
// double z;
|
44 |
//
|
45 |
// ++emess_dat.File_line;
|
46 |
// if (!(s = fgets(line, MAX_LINE, fid)))
|
47 |
// break;
|
48 |
// if (!strchr(s, '\n')) { /* overlong line */
|
49 |
// int c;
|
50 |
// (void)strcat(s, "\n");
|
51 |
// /* gobble up to newline */
|
52 |
// while ((c = fgetc(fid)) != EOF && c != '\n') ;
|
53 |
// }
|
54 |
// if (*s == tag) {
|
55 |
// fputs(line, stdout);
|
56 |
// continue;
|
57 |
// }
|
58 |
//
|
59 |
// if (reversein) {
|
60 |
// data.v = (*informat)(s, &s);
|
61 |
// data.u = (*informat)(s, &s);
|
62 |
// } else {
|
63 |
// data.u = (*informat)(s, &s);
|
64 |
// data.v = (*informat)(s, &s);
|
65 |
// }
|
66 |
//
|
67 |
// z = strtod( s, &s );
|
68 |
//
|
69 |
// if (data.v == HUGE_VAL)
|
70 |
// data.u = HUGE_VAL;
|
71 |
//
|
72 |
// if (!*s && (s > line)) --s; /* assumed we gobbled \n */
|
73 |
//
|
74 |
// if ( echoin) {
|
75 |
// int t;
|
76 |
// t = *s;
|
77 |
// *s = '\0';
|
78 |
// (void)fputs(line, stdout);
|
79 |
// *s = t;
|
80 |
// putchar('\t');
|
81 |
// }
|
82 |
//
|
83 |
// if (data.u != HUGE_VAL) {
|
84 |
// if( pj_transform( fromProj, toProj, 1, 0,
|
85 |
// &(data.u), &(data.v), &z ) != 0 )
|
86 |
// {
|
87 |
// data.u = HUGE_VAL;
|
88 |
// data.v = HUGE_VAL;
|
89 |
// }
|
90 |
// }
|
91 |
//
|
92 |
// if (data.u == HUGE_VAL) /* error output */
|
93 |
// fputs(oterr, stdout);
|
94 |
//
|
95 |
// else if (pj_is_latlong(toProj) && !oform) { /*ascii DMS output */
|
96 |
// if (reverseout) {
|
97 |
// fputs(rtodms(pline, data.v, 'N', 'S'), stdout);
|
98 |
// putchar('\t');
|
99 |
// fputs(rtodms(pline, data.u, 'E', 'W'), stdout);
|
100 |
// } else {
|
101 |
// fputs(rtodms(pline, data.u, 'E', 'W'), stdout);
|
102 |
// putchar('\t');
|
103 |
// fputs(rtodms(pline, data.v, 'N', 'S'), stdout);
|
104 |
// }
|
105 |
//
|
106 |
// } else { /* x-y or decimal degree ascii output */
|
107 |
// if ( pj_is_latlong(toProj) ) {
|
108 |
// data.v *= RAD_TO_DEG;
|
109 |
// data.u *= RAD_TO_DEG;
|
110 |
// }
|
111 |
// if (reverseout) {
|
112 |
// printf(oform,data.v); putchar('\t');
|
113 |
// printf(oform,data.u);
|
114 |
// } else {
|
115 |
// printf(oform,data.u); putchar('\t');
|
116 |
// printf(oform,data.v);
|
117 |
// }
|
118 |
// }
|
119 |
//
|
120 |
// putchar(' ');
|
121 |
// if( oform != NULL )
|
122 |
// printf( oform, z );
|
123 |
// else
|
124 |
// printf( "%.3f", z );
|
125 |
// fputs("\n", stdout );
|
126 |
// }
|
127 |
//}
|
128 |
|
129 |
/************************************************************************/
|
130 |
/* main() */
|
131 |
/************************************************************************/
|
132 |
|
133 |
int libcs2cs(int argc,char** argv,double* input1,double* input2,double* input3) |
134 |
{ |
135 |
char *arg, **eargv = argv, *from_argv[MAX_PARGS], *to_argv[MAX_PARGS],
|
136 |
**iargv = argv; |
137 |
FILE *fid; |
138 |
int from_argc=0, to_argc=0, iargc = argc, eargc = 0, c, mon = 0; |
139 |
int have_to_flag = 0, inverse = 0, i; |
140 |
projUV data; |
141 |
double z;
|
142 |
|
143 |
if (emess_dat.Prog_name = strrchr(*argv,DIR_CHAR))
|
144 |
++emess_dat.Prog_name; |
145 |
else emess_dat.Prog_name = *argv;
|
146 |
inverse = ! strncmp(emess_dat.Prog_name, "inv", 3); |
147 |
if (argc <= 1 ) { |
148 |
(void)fprintf(stderr, usage, pj_get_release(), emess_dat.Prog_name);
|
149 |
exit (0);
|
150 |
} |
151 |
/* process run line arguments */
|
152 |
while (--argc > 0) { /* collect run line arguments */ |
153 |
if(**++argv == '-') for(arg = *argv;;) { |
154 |
switch(*++arg) {
|
155 |
case '\0': /* position of "stdin" */ |
156 |
if (arg[-1] == '-') eargv[eargc++] = "-"; |
157 |
break;
|
158 |
case 'v': /* monitor dump of initialization */ |
159 |
mon = 1;
|
160 |
continue;
|
161 |
case 'I': /* alt. method to spec inverse */ |
162 |
inverse = 1;
|
163 |
continue;
|
164 |
case 'E': /* echo ascii input to ascii output */ |
165 |
echoin = 1;
|
166 |
continue;
|
167 |
case 't': /* set col. one char */ |
168 |
if (arg[1]) tag = *++arg; |
169 |
else emess(1,"missing -t col. 1 tag"); |
170 |
continue;
|
171 |
case 'l': /* list projections, ellipses or units */ |
172 |
if (!arg[1] || arg[1] == 'p' || arg[1] == 'P') { |
173 |
/* list projections */
|
174 |
struct PJ_LIST *lp;
|
175 |
int do_long = arg[1] == 'P', c; |
176 |
char *str;
|
177 |
|
178 |
for (lp = pj_get_list_ref() ; lp->id ; ++lp) {
|
179 |
(void)printf("%s : ", lp->id); |
180 |
if (do_long) /* possibly multiline description */ |
181 |
(void)puts(*lp->descr);
|
182 |
else { /* first line, only */ |
183 |
str = *lp->descr; |
184 |
while ((c = *str++) && c != '\n') |
185 |
putchar(c); |
186 |
putchar('\n');
|
187 |
} |
188 |
} |
189 |
} else if (arg[1] == '=') { /* list projection 'descr' */ |
190 |
struct PJ_LIST *lp;
|
191 |
|
192 |
arg += 2;
|
193 |
for (lp = pj_get_list_ref() ; lp->id ; ++lp)
|
194 |
if (!strcmp(lp->id, arg)) {
|
195 |
(void)printf("%9s : %s\n", lp->id, *lp->descr); |
196 |
break;
|
197 |
} |
198 |
} else if (arg[1] == 'e') { /* list ellipses */ |
199 |
struct PJ_ELLPS *le;
|
200 |
|
201 |
for (le = pj_get_ellps_ref(); le->id ; ++le)
|
202 |
(void)printf("%9s %-16s %-16s %s\n", |
203 |
le->id, le->major, le->ell, le->name); |
204 |
} else if (arg[1] == 'u') { /* list units */ |
205 |
struct PJ_UNITS *lu;
|
206 |
|
207 |
for (lu = pj_get_units_ref(); lu->id ; ++lu)
|
208 |
(void)printf("%12s %-20s %s\n", |
209 |
lu->id, lu->to_meter, lu->name); |
210 |
} else if (arg[1] == 'd') { /* list datums */ |
211 |
struct PJ_DATUMS *ld;
|
212 |
|
213 |
printf("__datum_id__ __ellipse___ __definition/comments______________________________\n" );
|
214 |
for (ld = pj_get_datums_ref(); ld->id ; ++ld)
|
215 |
{ |
216 |
printf("%12s %-12s %-30s\n",
|
217 |
ld->id, ld->ellipse_id, ld->defn); |
218 |
if( ld->comments != NULL && strlen(ld->comments) > 0 ) |
219 |
printf( "%25s %s\n", " ", ld->comments ); |
220 |
} |
221 |
} else if( arg[1] == 'm') { /* list prime meridians */ |
222 |
struct PJ_PRIME_MERIDIANS *lpm;
|
223 |
|
224 |
for (lpm = pj_get_prime_meridians_ref(); lpm->id ; ++lpm)
|
225 |
(void)printf("%12s %-30s\n", |
226 |
lpm->id, lpm->defn); |
227 |
} else
|
228 |
emess(1,"invalid list option: l%c",arg[1]); |
229 |
exit(0);
|
230 |
continue; /* artificial */ |
231 |
case 'e': /* error line alternative */ |
232 |
if (--argc <= 0) |
233 |
noargument: |
234 |
emess(1,"missing argument for -%c",*arg); |
235 |
oterr = *++argv; |
236 |
continue;
|
237 |
case 'W': /* specify seconds precision */ |
238 |
case 'w': /* -W for constant field width */ |
239 |
if ((c = arg[1]) != 0 && isdigit(c)) { |
240 |
set_rtodms(c - '0', *arg == 'W'); |
241 |
++arg; |
242 |
} else
|
243 |
emess(1,"-W argument missing or non-digit"); |
244 |
continue;
|
245 |
case 'f': /* alternate output format degrees or xy */ |
246 |
if (--argc <= 0) goto noargument; |
247 |
oform = *++argv; |
248 |
continue;
|
249 |
case 'r': /* reverse input */ |
250 |
reversein = 1;
|
251 |
continue;
|
252 |
case 's': /* reverse output */ |
253 |
reverseout = 1;
|
254 |
continue;
|
255 |
default:
|
256 |
emess(1, "invalid option: -%c",*arg); |
257 |
break;
|
258 |
} |
259 |
break;
|
260 |
|
261 |
} else if (strcmp(*argv,"+to") == 0 ) { |
262 |
have_to_flag = 1;
|
263 |
|
264 |
} else if (**argv == '+') { /* + argument */ |
265 |
if( have_to_flag )
|
266 |
{ |
267 |
if( to_argc < MAX_PARGS )
|
268 |
to_argv[to_argc++] = *argv + 1;
|
269 |
else
|
270 |
emess(1,"overflowed + argument table"); |
271 |
} |
272 |
else
|
273 |
{ |
274 |
if (from_argc < MAX_PARGS)
|
275 |
from_argv[from_argc++] = *argv + 1;
|
276 |
else
|
277 |
emess(1,"overflowed + argument table"); |
278 |
} |
279 |
} else /* assumed to be input file name(s) */ |
280 |
eargv[eargc++] = *argv; |
281 |
} |
282 |
if (eargc == 0 ) /* if no specific files force sysin */ |
283 |
eargv[eargc++] = "-";
|
284 |
|
285 |
/*
|
286 |
* If the user has requested inverse, then just reverse the
|
287 |
* coordinate systems.
|
288 |
*/
|
289 |
if( inverse )
|
290 |
{ |
291 |
int argcount;
|
292 |
|
293 |
for( i = 0; i < MAX_PARGS; i++ ) |
294 |
{ |
295 |
char *arg;
|
296 |
|
297 |
arg = from_argv[i]; |
298 |
from_argv[i] = to_argv[i]; |
299 |
to_argv[i] = arg; |
300 |
} |
301 |
|
302 |
argcount = from_argc; |
303 |
from_argc = to_argc; |
304 |
to_argc = argcount; |
305 |
} |
306 |
|
307 |
if (!(fromProj = pj_init(from_argc, from_argv)))
|
308 |
{ |
309 |
printf( "Using from definition: " );
|
310 |
for( i = 0; i < from_argc; i++ ) |
311 |
printf( "%s ", from_argv[i] );
|
312 |
printf( "\n" );
|
313 |
|
314 |
emess(3,"projection initialization failure\ncause: %s", |
315 |
pj_strerrno(pj_errno)); |
316 |
} |
317 |
|
318 |
if( to_argc == 0 ) |
319 |
{ |
320 |
if (!(toProj = pj_latlong_from_proj( fromProj )))
|
321 |
{ |
322 |
printf( "Using to definition: " );
|
323 |
for( i = 0; i < to_argc; i++ ) |
324 |
printf( "%s ", to_argv[i] );
|
325 |
printf( "\n" );
|
326 |
|
327 |
emess(3,"projection initialization failure\ncause: %s", |
328 |
pj_strerrno(pj_errno)); |
329 |
} |
330 |
} |
331 |
else if (!(toProj = pj_init(to_argc, to_argv))) |
332 |
{ |
333 |
printf( "Using to definition: " );
|
334 |
for( i = 0; i < to_argc; i++ ) |
335 |
printf( "%s ", to_argv[i] );
|
336 |
printf( "\n" );
|
337 |
|
338 |
emess(3,"projection initialization failure\ncause: %s", |
339 |
pj_strerrno(pj_errno)); |
340 |
} |
341 |
|
342 |
if (mon) {
|
343 |
printf( "%c ---- From Coordinate System ----\n", tag );
|
344 |
pj_pr_list(fromProj); |
345 |
printf( "%c ---- To Coordinate System ----\n", tag );
|
346 |
pj_pr_list(toProj); |
347 |
} |
348 |
|
349 |
if (reversein)
|
350 |
{ |
351 |
data.v = *input1; |
352 |
data.u = *input2; |
353 |
} |
354 |
else
|
355 |
{ |
356 |
data.u = *input1; |
357 |
data.v = *input2; |
358 |
} |
359 |
z = *input3; |
360 |
if (data.v == HUGE_VAL) data.u = HUGE_VAL;
|
361 |
if (data.u != HUGE_VAL)
|
362 |
{ |
363 |
if( pj_transform( fromProj, toProj, 1, 0, &(data.u), &(data.v), &z ) != 0 ) |
364 |
{ |
365 |
data.u = HUGE_VAL; |
366 |
data.v = HUGE_VAL; |
367 |
} |
368 |
} |
369 |
if (data.u == HUGE_VAL) return(1);/* error output */ |
370 |
*input1=data.u; |
371 |
*input2=data.v; |
372 |
*input3=z; |
373 |
|
374 |
if( fromProj != NULL ) |
375 |
pj_free( fromProj ); |
376 |
if( toProj != NULL ) |
377 |
pj_free( toProj ); |
378 |
|
379 |
pj_deallocate_grids(); |
380 |
|
381 |
return(0); /* normal completion */ |
382 |
} |