home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- * The GMT-system: @(#)mapproject.c 2.17 18 Jun 1995
- *
- * Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
- * See README file for copying and redistribution conditions.
- *--------------------------------------------------------------------*/
- /*
- * mapproject reads a pair of coordinates [+ optional data fields] from
- * standard input or file(s) and transforms the coordinates according to the
- * map projection selected. See man gmt-system for projections currently supported.
- *
- * The default is to expect longitude, latitude, [and optional datavalues],
- * and return x, y, [ and optional datavalues], but if the -I option is used,
- * the reverse is true. Specifying -C means that the origin of projected coordinates
- * should be set to origin of projection [Default origin is lower left corner of "map"].
- * If your data is lat lon instead of lon lat [Default], use -: to toggle x/y -> y/x.
- * Note that only unprojected values are affected by the -: switch. True x,y values are
- * always printed out as x,y.
- *
- *
- * Author: Paul Wessel
- * Date: 1-MAR-1990
- * Version: 2.0, based on old version 1.1
- *
- */
-
- #include "gmt.h"
-
- main (argc, argv)
- int argc;
- char **argv; {
- int i, fno, n = 0, n_read = 0, n_cols = 0, n_files = 0, x, y, n_args;
-
- BOOLEAN error = FALSE, inverse = FALSE, suppress = FALSE, one_to_one = FALSE;
- BOOLEAN map_center = FALSE, nofile = TRUE, done = FALSE, first = TRUE, km = FALSE;
- BOOLEAN multi_segments = FALSE;
-
- double west = 0.0, east = 0.0, south = 0.0, north = 0.0;
- double xmin, xmax, ymin, ymax, xy_in[2], xy_out[2];
- double x_in_min, x_in_max, y_in_min, y_in_max;
- double x_out_min, x_out_max, y_out_min, y_out_max, u_scale;
-
- char data[512], line[512], format1[512], format2[512], EOL_flag = '>';
-
- FILE *fp = NULL;
-
- argc = gmt_begin (argc, argv);
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
-
- /* Common parameters */
-
- case 'H':
- case 'J':
- case 'R':
- case 'V':
- case ':':
- case '\0':
- error += get_common_args (argv[i], &west, &east, &south, &north);
- break;
-
- /* Supplemental parameters */
-
- case 'C':
- map_center = TRUE;
- break;
- case 'F':
- one_to_one = TRUE;
- if (argv[i][2] == 'k' || argv[i][2] == 'K') km = TRUE;
- if (argv[i][2] == 'm' || argv[i][2] == 'M') km = 2;
- break;
- case 'I':
- inverse = TRUE;
- break;
- case 'M': /* Multiple line segments */
- multi_segments = TRUE;
- if (argv[i][2]) EOL_flag = argv[i][2];
- break;
- case 'S':
- suppress = TRUE;
- break;
- default:
- error = TRUE;
- gmt_default_error (argv[i][1]);
- break;
- }
- }
- else
- n_files++;
- }
-
- if (argc == 1 || gmt_quick) {
- fprintf (stderr, "mapproject %s - Forward and Inverse map transformation of 2-D coordinates\n\n", GMT_VERSION);
- fprintf (stderr, "usage: mapproject <infiles> -J<parameters> -R<west/east/south/north>\n");
- fprintf (stderr, " [-C] [-F[k|m]] [-H] [-I] [-M[<flag>]] [-S] [-V] [-:]\n\n");
-
- if (gmt_quick) exit (-1);
-
- fprintf (stderr, " infiles (in ASCII) has 2 or more columns. If no file(s) is given, standard input is read.\n");
- explain_option ('J');
- explain_option ('R');
- fprintf (stderr, "\n\tOPTIONS:\n");
- fprintf (stderr, " -C returns x/y relative to projection center [Default is relative to lower left corner]\n");
- fprintf (stderr, " -F force projected values to be in actual meters [Default uses the given plot scale]\n");
- fprintf (stderr, " Append k to use km as the unit or m for miles\n");
- explain_option ('H');
- fprintf (stderr, " -I means Inverse, i.e., get lon/lat from x/y input. [Default is lon/lat -> x/y]\n");
- fprintf (stderr, " -M Input files each consist of multiple segments separated by a record\n");
- fprintf (stderr, " whose first character is <flag> ['>']\n");
- fprintf (stderr, " -S means Suppress points outside region\n");
- explain_option ('V');
- explain_option (':');
- explain_option ('.');
- exit (-1);
- }
-
- if (!project_info.region_supplied) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify -R option\n", gmt_program);
- error++;
- }
-
- if (error) exit (-1);
-
- map_setup (west, east, south, north);
-
- if (gmtdefs.verbose) {
- xmin = (map_center) ? project_info.xmin - project_info.x0 : project_info.xmin;
- xmax = (map_center) ? project_info.xmax - project_info.x0 : project_info.xmax;
- ymin = (map_center) ? project_info.ymin - project_info.y0 : project_info.ymin;
- ymax = (map_center) ? project_info.ymax - project_info.y0 : project_info.ymax;
- if (one_to_one) {
- xmin /= project_info.x_scale;
- xmax /= project_info.x_scale;
- ymin /= project_info.y_scale;
- ymax /= project_info.y_scale;
- }
- fprintf (stderr, "mapproject: Transform (%lg/%lg/%lg/%lg ",
- project_info.w, project_info.e, project_info.s, project_info.n);
- (inverse) ? fprintf (stderr, " <- ") : fprintf (stderr, " -> ");
- fprintf (stderr, "%lg/%lg/%lg/%lg\n", xmin, xmax, ymin, ymax);
- }
-
- /* Now we are ready to take on some input values */
-
- x = (gmtdefs.xy_toggle) ? 1 : 0; y = 1 - x; /* Set up which columns have x and y */
-
- sprintf (format1, "%s\t%s\t%%s\n\0", gmtdefs.d_format, gmtdefs.d_format);
- sprintf (format2, "%s\t%s\n\0", gmtdefs.d_format, gmtdefs.d_format);
-
- if (n_files > 0)
- nofile = FALSE;
- else
- n_files = 1;
- n_args = (argc > 1) ? argc : 2;
-
- x_in_min = y_in_min = x_out_min = y_out_min = MAXDOUBLE;
- x_in_max = y_in_max = x_out_max = y_out_max = -MAXDOUBLE;
-
- if (km == 2)
- u_scale = (inverse) ? 1609.334 : 0.0006213711922;
- else
- u_scale = (inverse) ? 1000.0 : 0.001;
-
- for (fno = 1; !done && fno < n_args; fno++) { /* Loop over input files, if any */
- if (!nofile && argv[fno][0] == '-') continue;
-
- if (nofile) { /* Just read standard input */
- fp = stdin;
- done = TRUE;
- if (gmtdefs.verbose) fprintf (stderr, "mapproject: Reading from standard input\n");
- }
- else if ((fp = fopen (argv[fno], "r")) == NULL) {
- fprintf (stderr, "mapproject: Cannot open file %s\n", argv[fno]);
- continue;
- }
-
- if (!nofile && gmtdefs.verbose) fprintf (stderr, "mapproject: Working on file %s\n", argv[fno]);
-
- if (gmtdefs.io_header) {
- for (i = 0; i < gmtdefs.n_header_recs; i++) {
- fgets (data, 512, fp);
- if (first) printf ("%s", data);
- }
- first = FALSE;
- }
- if (multi_segments) {
- fgets (line, 512, fp);
- printf ("%s", line);
- }
-
- if (inverse) { /* Do inverse transformation */
- while (fgets (line, 512, fp)) { /* Read x,y */
- if (multi_segments && line[0] == EOL_flag) {
- printf ("%s", line);
- continue;
- }
-
- n_cols = sscanf (line, "%lf %lf%[^\n]\n", &xy_in[0], &xy_in[1], data);
- if (one_to_one) { /* Convert from 1:1 scale */
- if (km) {
- xy_in[0] *= u_scale;
- xy_in[1] *= u_scale;
- }
- xy_in[0] *= project_info.x_scale;
- xy_in[1] *= project_info.y_scale;
- }
- if (map_center) { /* Then correct so lower left corner is (0,0) */
- xy_in[0] += project_info.x0;
- xy_in[1] += project_info.y0;
- }
- xy_to_geo (&xy_out[0], &xy_out[1], xy_in[0], xy_in[1]);
- n_read++;
- if (suppress && map_outside (xy_out[0], xy_out[1])) continue;
- if (gmtdefs.verbose) {
- x_in_min = MIN (x_in_min, xy_in[0]);
- x_in_max = MAX (x_in_max, xy_in[0]);
- y_in_min = MIN (y_in_min, xy_in[1]);
- y_in_max = MAX (y_in_max, xy_in[1]);
- x_out_min = MIN (x_out_min, xy_out[0]);
- x_out_max = MAX (x_out_max, xy_out[0]);
- y_out_min = MIN (y_out_min, xy_out[1]);
- y_out_max = MAX (y_out_max, xy_out[1]);
- }
- if (n_cols == 2)
- printf (format2, xy_out[x], xy_out[y]);
- else
- printf (format1, xy_out[x], xy_out[y], data);
- n++;
- }
- }
- else { /* Do forward transformation */
- while (fgets (line, 512, fp)) { /* Read lon,lat OR lat,lon */
- if (multi_segments && line[0] == EOL_flag) {
- printf ("%s", line);
- continue;
- }
- n_cols = sscanf (line, "%lf %lf%[^\n]", &xy_in[x], &xy_in[y], data);
- n_read++;
- if (suppress && map_outside (xy_in[0], xy_in[1])) continue;
- geo_to_xy (xy_in[0], xy_in[1], &xy_out[0], &xy_out[1]);
- if (map_center) { /* Change origin from lower left to projection center */
- xy_out[0] -= project_info.x0;
- xy_out[1] -= project_info.y0;
- }
- if (one_to_one) { /* Convert to 1:1 scale */
- xy_out[0] /= project_info.x_scale;
- xy_out[1] /= project_info.y_scale;
- if (km) {
- xy_out[0] *= u_scale;
- xy_out[1] *= u_scale;
- }
- }
- if (gmtdefs.verbose) {
- x_in_min = MIN (x_in_min, xy_in[0]);
- x_in_max = MAX (x_in_max, xy_in[0]);
- y_in_min = MIN (y_in_min, xy_in[1]);
- y_in_max = MAX (y_in_max, xy_in[1]);
- x_out_min = MIN (x_out_min, xy_out[0]);
- x_out_max = MAX (x_out_max, xy_out[0]);
- y_out_min = MIN (y_out_min, xy_out[1]);
- y_out_max = MAX (y_out_max, xy_out[1]);
- }
- if (n_cols == 2)
- printf (format2, xy_out[0], xy_out[1]);
- else
- printf (format1, xy_out[0], xy_out[1], data);
- n++;
- }
- }
- if (fp != stdin) fclose (fp);
- }
-
- if (gmtdefs.verbose && n_read > 0) {
- fprintf (stderr, "mapproject: Input extreme values: Xmin: %lg Xmax: %lg Ymin: %lg Ymax %lg\n",
- x_in_min, x_in_max, y_in_min, y_in_max);
- fprintf (stderr, "mapproject: Output extreme values: Xmin: %lg Xmax: %lg Ymin: %lg Ymax %lg\n",
- x_out_min, x_out_max, y_out_min, y_out_max);
- if (inverse)
- fprintf (stderr, "mapproject: Mapped %d x-y pairs to lon-lat\n", n);
- else
- fprintf (stderr, "mapproject: Mapped %d lon-lat pairs to x-y\n", n);
- if (suppress && n != n_read) fprintf (stderr, "mapproject: %d fell outside region\n", n_read - n);
- }
-
- gmt_end (argc, argv);
- }
-