~ubuntu-branches/ubuntu/vivid/proj/vivid

« back to all changes in this revision

Viewing changes to src/cs2cs.c

  • Committer: Bazaar Package Importer
  • Author(s): Peter S Galbraith
  • Date: 2002-01-11 10:27:12 UTC
  • Revision ID: james.westby@ubuntu.com-20020111102712-ayi18r8y2eesv0y9
Tags: upstream-4.4.5
ImportĀ upstreamĀ versionĀ 4.4.5

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************************************
 
2
 * $Id: cs2cs.c,v 1.4 2001/04/05 19:32:19 warmerda Exp $
 
3
 *
 
4
 * Project:  PROJ.4
 
5
 * Purpose:  Mainline program sort of like ``proj'' for converting between
 
6
 *           two coordinate systems.
 
7
 * Author:   Frank Warmerdam, warmerda@home.com
 
8
 *
 
9
 ******************************************************************************
 
10
 * Copyright (c) 2000, Frank Warmerdam
 
11
 *
 
12
 * Permission is hereby granted, free of charge, to any person obtaining a
 
13
 * copy of this software and associated documentation files (the "Software"),
 
14
 * to deal in the Software without restriction, including without limitation
 
15
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 
16
 * and/or sell copies of the Software, and to permit persons to whom the
 
17
 * Software is furnished to do so, subject to the following conditions:
 
18
 *
 
19
 * The above copyright notice and this permission notice shall be included
 
20
 * in all copies or substantial portions of the Software.
 
21
 *
 
22
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
 
23
 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 
24
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 
25
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 
26
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 
27
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 
28
 * DEALINGS IN THE SOFTWARE.
 
29
 ******************************************************************************
 
30
 *
 
31
 * $Log: cs2cs.c,v $
 
32
 * Revision 1.4  2001/04/05 19:32:19  warmerda
 
33
 * use projPJ, and pj_is_latlong()
 
34
 *
 
35
 * Revision 1.3  2001/04/05 04:23:28  warmerda
 
36
 * use pj_latlong_from_proj
 
37
 *
 
38
 * Revision 1.2  2001/02/03 18:36:55  warmerda
 
39
 * removed some unavailable options from usage string
 
40
 *
 
41
 * Revision 1.1  2000/07/06 23:32:27  warmerda
 
42
 * New
 
43
 *
 
44
 */
 
45
 
 
46
#include <stdio.h>
 
47
#include <stdlib.h>
 
48
#include <ctype.h>
 
49
#include <string.h>
 
50
#include <math.h>
 
51
#include "projects.h"
 
52
#include "emess.h"
 
53
 
 
54
#define MAX_LINE 200
 
55
#define MAX_PARGS 100
 
56
 
 
57
static projPJ   fromProj, toProj;
 
58
 
 
59
static int
 
60
reversein = 0,  /* != 0 reverse input arguments */
 
61
reverseout = 0, /* != 0 reverse output arguments */
 
62
echoin = 0,     /* echo input data to output line */
 
63
tag = '#';      /* beginning of line tag character */
 
64
        static char
 
65
*oform = (char *)0,     /* output format for x-y or decimal degrees */
 
66
*oterr = "*\t*",        /* output line for unprojectable input */
 
67
*usage =
 
68
"%s\nusage: %s [ -eEfIlrstvwW [args] ] [ +opts[=arg] ]\n"
 
69
"                   [+to [+opts[=arg] [ files ]\n";
 
70
 
 
71
static struct FACTORS facs;
 
72
static double (*informat)(const char *, 
 
73
                          char **); /* input data deformatter function */
 
74
 
 
75
 
 
76
/************************************************************************/
 
77
/*                              process()                               */
 
78
/*                                                                      */
 
79
/*      File processing function.                                       */
 
80
/************************************************************************/
 
81
static void process(FILE *fid) 
 
82
 
 
83
{
 
84
    char line[MAX_LINE+3], *s, pline[40];
 
85
    projUV data;
 
86
 
 
87
    for (;;) {
 
88
        double z;
 
89
 
 
90
        ++emess_dat.File_line;
 
91
        if (!(s = fgets(line, MAX_LINE, fid)))
 
92
            break;
 
93
        if (!strchr(s, '\n')) { /* overlong line */
 
94
            int c;
 
95
            (void)strcat(s, "\n");
 
96
                                /* gobble up to newline */
 
97
            while ((c = fgetc(fid)) != EOF && c != '\n') ;
 
98
        }
 
99
        if (*s == tag) {
 
100
            fputs(line, stdout);
 
101
            continue;
 
102
        }
 
103
 
 
104
        if (reversein) {
 
105
            data.v = (*informat)(s, &s);
 
106
            data.u = (*informat)(s, &s);
 
107
        } else {
 
108
            data.u = (*informat)(s, &s);
 
109
            data.v = (*informat)(s, &s);
 
110
        }
 
111
 
 
112
        z = strtod( s, &s );
 
113
 
 
114
        if (data.v == HUGE_VAL)
 
115
            data.u = HUGE_VAL;
 
116
 
 
117
        if (!*s && (s > line)) --s; /* assumed we gobbled \n */
 
118
 
 
119
        if ( echoin) {
 
120
            int t;
 
121
            t = *s;
 
122
            *s = '\0';
 
123
            (void)fputs(line, stdout);
 
124
            *s = t;
 
125
            putchar('\t');
 
126
        }
 
127
 
 
128
        if (data.u != HUGE_VAL) {
 
129
            if( pj_transform( fromProj, toProj, 1, 0, 
 
130
                              &(data.u), &(data.v), &z ) != 0 )
 
131
            {
 
132
                data.u = HUGE_VAL;
 
133
                data.v = HUGE_VAL;
 
134
            }
 
135
        }
 
136
 
 
137
        if (data.u == HUGE_VAL) /* error output */
 
138
            fputs(oterr, stdout);
 
139
 
 
140
        else if (pj_is_latlong(toProj) && !oform) {     /*ascii DMS output */
 
141
            if (reverseout) {
 
142
                fputs(rtodms(pline, data.v, 'N', 'S'), stdout);
 
143
                putchar('\t');
 
144
                fputs(rtodms(pline, data.u, 'E', 'W'), stdout);
 
145
            } else {
 
146
                fputs(rtodms(pline, data.u, 'E', 'W'), stdout);
 
147
                putchar('\t');
 
148
                fputs(rtodms(pline, data.v, 'N', 'S'), stdout);
 
149
            }
 
150
 
 
151
        } else {        /* x-y or decimal degree ascii output */
 
152
            if ( pj_is_latlong(toProj) ) {
 
153
                data.v *= RAD_TO_DEG;
 
154
                data.u *= RAD_TO_DEG;
 
155
            }
 
156
            if (reverseout) {
 
157
                printf(oform,data.v); putchar('\t');
 
158
                printf(oform,data.u);
 
159
            } else {
 
160
                printf(oform,data.u); putchar('\t');
 
161
                printf(oform,data.v);
 
162
            }
 
163
        }
 
164
 
 
165
        putchar(' ');
 
166
        printf( "%.3f", z );
 
167
        fputs("\n", stdout );
 
168
    }
 
169
}
 
170
 
 
171
/************************************************************************/
 
172
/*                                main()                                */
 
173
/************************************************************************/
 
174
 
 
175
int main(int argc, char **argv) 
 
176
{
 
177
    char *arg, **eargv = argv, *from_argv[MAX_PARGS], *to_argv[MAX_PARGS],
 
178
        **iargv = argv;
 
179
    FILE *fid;
 
180
    int from_argc=0, to_argc=0, iargc = argc, eargc = 0, c, mon = 0;
 
181
    int have_to_flag = 0, inverse = 0, i;
 
182
 
 
183
    if (emess_dat.Prog_name = strrchr(*argv,DIR_CHAR))
 
184
        ++emess_dat.Prog_name;
 
185
    else emess_dat.Prog_name = *argv;
 
186
    inverse = ! strncmp(emess_dat.Prog_name, "inv", 3);
 
187
    if (argc <= 1 ) {
 
188
        (void)fprintf(stderr, usage, pj_release, emess_dat.Prog_name);
 
189
        exit (0);
 
190
    }
 
191
    /* process run line arguments */
 
192
    while (--argc > 0) { /* collect run line arguments */
 
193
        if(**++argv == '-') for(arg = *argv;;) {
 
194
            switch(*++arg) {
 
195
              case '\0': /* position of "stdin" */
 
196
                if (arg[-1] == '-') eargv[eargc++] = "-";
 
197
                break;
 
198
              case 'v': /* monitor dump of initialization */
 
199
                mon = 1;
 
200
                continue;
 
201
              case 'I': /* alt. method to spec inverse */
 
202
                inverse = 1;
 
203
                continue;
 
204
              case 'E': /* echo ascii input to ascii output */
 
205
                echoin = 1;
 
206
                continue;
 
207
              case 't': /* set col. one char */
 
208
                if (arg[1]) tag = *++arg;
 
209
                else emess(1,"missing -t col. 1 tag");
 
210
                continue;
 
211
              case 'l': /* list projections, ellipses or units */
 
212
                if (!arg[1] || arg[1] == 'p' || arg[1] == 'P') {
 
213
                    /* list projections */
 
214
                    struct PJ_LIST *lp;
 
215
                    int do_long = arg[1] == 'P', c;
 
216
                    char *str;
 
217
 
 
218
                    for (lp = pj_list ; lp->id ; ++lp) {
 
219
                        (void)printf("%s : ", lp->id);
 
220
                        if (do_long)  /* possibly multiline description */
 
221
                            (void)puts(*lp->descr);
 
222
                        else { /* first line, only */
 
223
                            str = *lp->descr;
 
224
                            while ((c = *str++) && c != '\n')
 
225
                                putchar(c);
 
226
                            putchar('\n');
 
227
                        }
 
228
                    }
 
229
                } else if (arg[1] == '=') { /* list projection 'descr' */
 
230
                    struct PJ_LIST *lp;
 
231
 
 
232
                    arg += 2;
 
233
                    for (lp = pj_list ; lp->id ; ++lp)
 
234
                        if (!strcmp(lp->id, arg)) {
 
235
                            (void)printf("%9s : %s\n", lp->id, *lp->descr);
 
236
                            break;
 
237
                        }
 
238
                } else if (arg[1] == 'e') { /* list ellipses */
 
239
                    struct PJ_ELLPS *le;
 
240
 
 
241
                    for (le = pj_ellps; le->id ; ++le)
 
242
                        (void)printf("%9s %-16s %-16s %s\n",
 
243
                                     le->id, le->major, le->ell, le->name);
 
244
                } else if (arg[1] == 'u') { /* list units */
 
245
                    struct PJ_UNITS *lu;
 
246
 
 
247
                    for (lu = pj_units; lu->id ; ++lu)
 
248
                        (void)printf("%12s %-20s %s\n",
 
249
                                     lu->id, lu->to_meter, lu->name);
 
250
                } else if (arg[1] == 'd') { /* list datums */
 
251
                    struct PJ_DATUMS *ld;
 
252
 
 
253
                    printf("__datum_id__ __ellipse___ __definition/comments______________________________\n" );
 
254
                    for (ld = pj_datums; ld->id ; ++ld)
 
255
                    {
 
256
                        printf("%12s %-12s %-30s\n",
 
257
                               ld->id, ld->ellipse_id, ld->defn);
 
258
                        if( ld->comments != NULL && strlen(ld->comments) > 0 )
 
259
                            printf( "%25s %s\n", " ", ld->comments );
 
260
                    }
 
261
                } else
 
262
                    emess(1,"invalid list option: l%c",arg[1]);
 
263
                exit(0);
 
264
                continue; /* artificial */
 
265
              case 'e': /* error line alternative */
 
266
                if (--argc <= 0)
 
267
                    noargument:                    
 
268
                emess(1,"missing argument for -%c",*arg);
 
269
                oterr = *++argv;
 
270
                continue;
 
271
              case 'W': /* specify seconds precision */
 
272
              case 'w': /* -W for constant field width */
 
273
                if ((c = arg[1]) != 0 && isdigit(c)) {
 
274
                    set_rtodms(c - '0', *arg == 'W');
 
275
                    ++arg;
 
276
                } else
 
277
                    emess(1,"-W argument missing or non-digit");
 
278
                continue;
 
279
              case 'f': /* alternate output format degrees or xy */
 
280
                if (--argc <= 0) goto noargument;
 
281
                oform = *++argv;
 
282
                continue;
 
283
              case 'r': /* reverse input */
 
284
                reversein = 1;
 
285
                continue;
 
286
              case 's': /* reverse output */
 
287
                reverseout = 1;
 
288
                continue;
 
289
              default:
 
290
                emess(1, "invalid option: -%c",*arg);
 
291
                break;
 
292
            }
 
293
            break;
 
294
 
 
295
        } else if (strcmp(*argv,"+to") == 0 ) {
 
296
            have_to_flag = 1;
 
297
 
 
298
        } else if (**argv == '+') { /* + argument */
 
299
            if( have_to_flag )
 
300
            {
 
301
                if( to_argc < MAX_PARGS )
 
302
                    to_argv[to_argc++] = *argv + 1;
 
303
                else
 
304
                    emess(1,"overflowed + argument table");
 
305
            }
 
306
            else 
 
307
            {
 
308
                if (from_argc < MAX_PARGS)
 
309
                    from_argv[from_argc++] = *argv + 1;
 
310
                else
 
311
                    emess(1,"overflowed + argument table");
 
312
            }
 
313
        } else /* assumed to be input file name(s) */
 
314
            eargv[eargc++] = *argv;
 
315
    }
 
316
    if (eargc == 0 ) /* if no specific files force sysin */
 
317
        eargv[eargc++] = "-";
 
318
 
 
319
    /* 
 
320
     * If the user has requested inverse, then just reverse the
 
321
     * coordinate systems.
 
322
     */
 
323
    if( inverse )
 
324
    {
 
325
        int     argcount;
 
326
        
 
327
        for( i = 0; i < MAX_PARGS; i++ )
 
328
        {
 
329
            char *arg;
 
330
 
 
331
            arg = from_argv[i];
 
332
            from_argv[i] = to_argv[i];
 
333
            to_argv[i] = arg;
 
334
        }
 
335
 
 
336
        argcount = from_argc;
 
337
        from_argc = to_argc;
 
338
        to_argc = argcount;
 
339
    }
 
340
 
 
341
    if (!(fromProj = pj_init(from_argc, from_argv)))
 
342
    {
 
343
        printf( "Using from definition: " );
 
344
        for( i = 0; i < from_argc; i++ )
 
345
            printf( "%s ", from_argv[i] );
 
346
        printf( "\n" );
 
347
 
 
348
        emess(3,"projection initialization failure\ncause: %s",
 
349
              pj_strerrno(pj_errno));
 
350
    }
 
351
 
 
352
    if( to_argc == 0 )
 
353
    {
 
354
        if (!(toProj = pj_latlong_from_proj( fromProj )))
 
355
        {
 
356
            printf( "Using to definition: " );
 
357
            for( i = 0; i < to_argc; i++ )
 
358
                printf( "%s ", to_argv[i] );
 
359
            printf( "\n" );
 
360
            
 
361
            emess(3,"projection initialization failure\ncause: %s",
 
362
                  pj_strerrno(pj_errno));
 
363
        }   
 
364
    }
 
365
    else if (!(toProj = pj_init(to_argc, to_argv)))
 
366
    {
 
367
        printf( "Using to definition: " );
 
368
        for( i = 0; i < to_argc; i++ )
 
369
            printf( "%s ", to_argv[i] );
 
370
        printf( "\n" );
 
371
 
 
372
        emess(3,"projection initialization failure\ncause: %s",
 
373
              pj_strerrno(pj_errno));
 
374
    }
 
375
 
 
376
    if (mon) {
 
377
        printf( "%c ---- From Coordinate System ----\n", tag );
 
378
        pj_pr_list(fromProj);
 
379
        printf( "%c ---- To Coordinate System ----\n", tag );
 
380
        pj_pr_list(toProj);
 
381
    }
 
382
 
 
383
    /* set input formating control */
 
384
    if( !fromProj->is_latlong )
 
385
        informat = strtod;
 
386
    else {
 
387
        informat = dmstor;
 
388
    }
 
389
 
 
390
    if( !toProj->is_latlong && !oform )
 
391
        oform = "%.2f";
 
392
 
 
393
    /* process input file list */
 
394
    for ( ; eargc-- ; ++eargv) {
 
395
        if (**eargv == '-') {
 
396
            fid = stdin;
 
397
            emess_dat.File_name = "<stdin>";
 
398
 
 
399
        } else {
 
400
            if ((fid = fopen(*eargv, "rt")) == NULL) {
 
401
                emess(-2, *eargv, "input file");
 
402
                continue;
 
403
            }
 
404
            emess_dat.File_name = *eargv;
 
405
        }
 
406
        emess_dat.File_line = 0;
 
407
        process(fid);
 
408
        fclose(fid);
 
409
        emess_dat.File_name = 0;
 
410
    }
 
411
    exit(0); /* normal completion */
 
412
}