/*-------------------------------------------------------------------- * $Id: psxy.c,v 1.3.4.3 2002/02/27 17:41:10 pwessel Exp $ * * Copyright (c) 1991-2002 by P. Wessel and W. H. F. Smith * See COPYING file for copying and redistribution conditions. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * Contact info: gmt.soest.hawaii.edu *--------------------------------------------------------------------*/ /* * psxy will read pairs (or ) from GMT_stdin and plot * the lines, polygons, or symbols on a map. A variety of symbols * may be specified, some of which require additional columns of * data, like symbol-size etc. Only one symbol may be plotted * at the time. PostScript code is written to GMT_stdout. * * Author: Paul Wessel * Date: 29-AUG-2000 * Version: 3.4.1 * */ #include "gmt.h" #define NONE 99 #define UNSPECIFIED 999 #define LINE 0 #define BAR 1 #define CROSS 2 #define POINT 3 #define CIRCLE 4 #define SQUARE 5 #define TRIANGLE 6 #define DIAMOND 7 #define STAR 8 #define HEXAGON 9 #define ITRIANGLE 10 #define ELLIPSE 11 #define VECTOR 12 #define VECTOR2 13 #define TEXT 14 #define PIE 15 #define FRONT -16 /* FRONT symbols */ #define F_FAULT 0 #define F_TRIANGLE 1 #define F_SLIP 2 #define F_CIRCLE 3 #define F_BOX 4 /* Direction of front symbols: */ #define F_LEFT +1 #define F_CENTERED 0 #define F_RIGHT -1 #define POINTSIZE 0.005 struct FRONTLINE { /* A sub-symbol for symbols along a front */ double f_gap; /* Gap between front symbols in inches */ double f_len; /* Length of front symbols in inches */ double f_off; /* Offset of first symbol from start of front in inches */ int f_sense; /* Draw symbols to left (+1), centered (0), or right (-1) of line */ int f_symbol; /* Which symbol to draw along the front line */ }; struct PSXY_SYMBOL { int symbol; /* Symbol id */ int n_required; /* Number of additional columns necessary to decode chosen symbol */ int u; /* Measure unit id (0 = cm, 1 = inch, 2 = m, 3 = point */ double size; /* Current symbol size */ double given_size; /* Symbol size read from file or command line */ BOOLEAN read_size; /* TRUE when we must read symbol size from file */ int font_no; /* font to use for the -Sl symbol */ /* These apply to bar symbols */ double base; /* From what level to draw the bar */ BOOLEAN user_unit; /* if TRUE */ /* These apply to vectors */ BOOLEAN convert_angles; /* If TRUE, convert azimuth to angle on map */ BOOLEAN read_vector; /* if TRUE must read vector attributes */ BOOLEAN shrink; /* If TRUE, shrink vector attributes for small lengths */ double v_norm; /* shrink when lengths are smaller than this */ double v_shrink; /* Required scale factor */ double v_width; /* Width of vector stem in inches */ double h_length; /* Length of vector head in inches */ double h_width; /* Width of vector head in inches */ char string[64]; /* Character code to plot (could be octal) */ struct FRONTLINE f; /* paramters needed for a front */ } S; double *xx, *yy, *xp, *yp; int *plot_pen; int decode_symbol_option (char *text, struct PSXY_SYMBOL *p); void GMT_plot_ellipse (double lon, double lat, double major, double minor, double azimuth, struct GMT_FILL fill, int outline); void GMT_draw_fence (double x[], double y[], int n, struct FRONTLINE *f, struct GMT_FILL *g, BOOLEAN outline); void plot_x_errorbar (double x, double y, double delta_x, double error_width, double error_width2, int line); void plot_y_errorbar (double x, double y, double delta_y, double error_width, double error_width2, int line); void plot_x_whiskerbar (double x, double y, double hinge[], double error_width, double error_width2, int rgb[], int line); void plot_y_whiskerbar (double x, double y, double hinge[], double error_width, double error_width2, int rgb[], int line); main (int argc, char **argv) { int i, j, n, j0, n_files = 0, fno, xy_errors[2], two, three, four, error_type[2] = {0,0}; int n_alloc = GMT_CHUNK, plot_n, n_use, start, n_args, n_fields, n_cols_start = 2; int font_size, n_required, n_total_read = 0, n_expected = 0, error_cols[2] = {1,4}; BOOLEAN error = FALSE, nofile = TRUE, polygon = FALSE, read_symbol = FALSE; BOOLEAN outline = FALSE, default_outline = FALSE, draw_arc = TRUE, error_bars = FALSE; BOOLEAN done, get_rgb = FALSE, greenwich, default_polygon = FALSE, resample; BOOLEAN old_GMT_world_map, skip_if_outside = TRUE, close_polygon = FALSE, cpt_given = FALSE; BOOLEAN error_x = FALSE, error_y = FALSE, fill_set = FALSE, def_err_xy = FALSE, clip_set = FALSE; double west = 0.0, east = 0.0, south = 0.0, north = 0.0; double plot_x, plot_y, x_1, x_2, y_1, y_2, y0, error_width = 0.1, error_width2; double direction, length, major, minor, x2, y2, z, dir1, dir2; double v_w, h_l, h_w, tmp, step = 1.0, *in; char line[BUFSIZ], *cpt, *p, *symb_arg = CNULL, txt_a[32]; FILE *fp = NULL; struct GMT_PEN pen, epen, default_pen; struct GMT_FILL fill, default_fill; xy_errors[0] = xy_errors[1] = 0; /* These will be col # of where to find this info in data */ argc = GMT_begin (argc, argv); GMT_init_pen (&pen, GMT_PENWIDTH); GMT_init_pen (&epen, GMT_PENWIDTH); GMT_init_fill (&fill, -1, -1, -1); /* Default is no fill */ /* Initialize PSXY_SYMBOL structure */ S.symbol = S.n_required = 0; S.size = S.base = S.v_norm = S.v_shrink = 0.0; S.read_size = S.user_unit = S.convert_angles = S.shrink = S.read_vector = FALSE; S.v_width = 0.03; memset ((void *)S.string, 0, (size_t)(16 * sizeof (char))); S.h_length = 0.12; S.h_width = 0.1; S.font_no = gmtdefs.anot_font; if ((S.u = gmtdefs.measure_unit) == GMT_CM) { S.v_width = 0.075 / 2.54; S.h_length = 0.3 / 2.54; S.h_width = 0.25 / 2.54; error_width = 0.25 / 2.54; } /* Check and interpret the command line arguments */ for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch(argv[i][1]) { /* Common parameters */ case 'B': case 'H': case 'J': case 'K': case 'O': case 'P': case 'R': case 'U': case 'V': case 'X': case 'x': case 'Y': case 'y': case 'c': case ':': case '\0': error += GMT_get_common_args (argv[i], &west, &east, &south, &north); break; /* Supplemental parameters */ case 'b': error += GMT_io_selection (&argv[i][2]); break; case 'A': /* Turn off draw_arc mode */ if (argv[i][2]) step = atof (&argv[i][2]); /* Undocumented test feature */ else draw_arc = FALSE; break; case 'C': /* Vary symbol color with z */ cpt = &argv[i][2]; cpt_given = TRUE; break; case 'E': /* Get info for error bars and bow-whisker bars */ for (j = 2; argv[i][j] && argv[i][j] != '/'; j++) { if (argv[i][j] == 'x') { xy_errors[0] = j; error_type[0] = 0; } else if (argv[i][j] == 'X') { /* Box-whisker instead */ xy_errors[0] = j; error_type[0] = 1; } else if (argv[i][j] == 'y') { xy_errors[1] = j; error_type[1] = 0; } else if (argv[i][j] == 'Y') { /* Box-whisker instead */ xy_errors[1] = j; error_type[1] = 1; } else { /* Get error 'cap' width */ strcpy (txt_a, &argv[i][j]); j0 = 0; while (txt_a[j0] && txt_a[j0] != '/') j0++; txt_a[j0] = 0; error_width = GMT_convert_units (txt_a, GMT_INCH); while (argv[i][j] && argv[i][j] != '/') j++; j--; } } error_bars = TRUE; if (!(xy_errors[0] || xy_errors[1])) { /* Default is plain error bars for both */ def_err_xy = TRUE; xy_errors[0] = 2; /* Assumes xy input, later check for -: */ xy_errors[1] = 3; error_type[0] = error_type[1] = 1; } if (argv[i][j] == '/') GMT_getpen (&argv[i][j+1], &epen); break; case 'G': /* Set fill for symbols or polygon */ if (!argv[i][2] || (argv[i][2] && GMT_getfill (&argv[i][2], &fill))) { GMT_fill_syntax ('G'); error++; } fill_set = TRUE; break; case 'L': /* Close line segments */ close_polygon = TRUE; break; case 'M': /* Multiple line segments */ GMT_multisegment (&argv[i][2]); break; case 'N': /* Do not skip points outside border */ skip_if_outside = FALSE; break; case 'S': /* Get symbol [and size] */ symb_arg = &argv[i][2]; error += decode_symbol_option (&argv[i][2], &S); break; case 'W': /* Set line attributes */ if (argv[i][2] && GMT_getpen (&argv[i][2], &pen)) { GMT_pen_syntax ('W'); error++; } default_outline = outline = TRUE; break; /* Illegal options */ default: /* Options not recognized */ error = TRUE; GMT_default_error (argv[i][1]); break; } } else n_files++; } if (argc == 1 || GMT_quick) { /* Display usage */ fprintf (stderr,"psxy %s - Plot lines, polygons, and symbols on maps\n\n", GMT_VERSION); fprintf (stderr,"usage: psxy -J -R [-A] [-B]\n"); fprintf (stderr, "\t[-C] [-E[x|y|X|Y][cap][/]] [-G] [-H[]] [-K] [-L] [-M] [-N]\n"); fprintf (stderr, "\t[-O] [-P] [-S[][]] [-U[