home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- * The GMT-system: @(#)psxy.c 2.39 05 Jul 1995
- *
- * Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
- * See README file for copying and redistribution conditions.
- *--------------------------------------------------------------------*/
- /*
- * psxy will read <x,y> pairs (or <lon,lat>) from 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 stdout.
- *
- * Author: Paul Wessel
- * Date: 5-JAN-1995
- * Version: 3.0, based on old v2.1
- *
- */
-
- #include "gmt.h"
-
- #define NONE 99
- #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 ELLIPSE 8
- #define STAR 9
- #define HEXAGON 10
- #define ITRIANGLE 11
- #define VECTOR 12
- #define VECTOR2 13
- #define TEXT 14
- #define FAULT -15
-
- #define POINTSIZE 0.005
-
- double *xx, *yy, *xp, *yp;
- int *plot_pen;
-
- main (argc, argv)
- int argc;
- char **argv; {
-
- int i, j, symbol = 0, n, ix = 0, iy = 1, n_files = 0, fno, xy_errors[2], two, three, four;
- int n_alloc = GMT_CHUNK, plot_n, n_use, start, n_args, slash, f_sense = 0, n_got, n_expected = 2;
- int font_size;
-
- BOOLEAN error = FALSE, nofile = TRUE, error_bars = FALSE, polygon = FALSE, user_unit = FALSE;
- BOOLEAN read_size = FALSE, outline = FALSE, multi_segments = FALSE, draw_arc = TRUE, f_triangle = FALSE;
- BOOLEAN done, read_vector = FALSE, read_ellipse = FALSE, get_rgb = FALSE, greenwich, check;
- BOOLEAN convert_angles = FALSE, pen_set = FALSE, old_gmt_world_map, skip_if_outside = TRUE;
-
- double xy[2], west = 0.0, east = 0.0, south = 0.0, north = 0.0, delta_x, delta_y;
- double plot_x, plot_y, symbol_size = 0.0, x_1, x_2, y_1, y_2, y0;
- double direction, length1, length2, x2, y2, error_width2, f_gap = 0.0, f_len = 0.05;
- double v_width = 0.03, h_length = 0.12, h_width = 0.1, error_width = 0.1;
- double v_w, h_l, h_w, v_shrink, v_norm = 0.0, base = 0.0, z, tmp, step = 1.0;
-
- char line[512], header[512], symbol_type, col[6][100], *cpt, *more, EOL_flag = '>', *string = 0;
-
- FILE *fp = NULL;
-
- struct PEN pen, epen;
- struct FILL fill;
-
- xy_errors[0] = xy_errors[1] = 0;
-
- argc = gmt_begin (argc, argv);
-
- gmt_init_pen (&pen, 1);
- gmt_init_pen (&epen, 1);
- gmt_init_fill (&fill, -1, -1, -1); /* Default is no fill */
-
- if (gmtdefs.measure_unit) {
- v_width = 0.075; h_length = 0.3; h_width = 0.25; error_width = 0.25;
- }
-
- /* 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 += get_common_args (argv[i], &west, &east, &south, &north);
- break;
-
- /* Supplemental parameters */
-
- 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];
- get_rgb = TRUE;
- break;
- case 'E': /* Get info for error bars */
- for (j = 2; argv[i][j] && argv[i][j] != '/'; j++) {
- if (argv[i][j] == 'x')
- xy_errors[0] = j;
- else if (argv[i][j] == 'y')
- xy_errors[1] = j;
- else { /* Get error 'cap' width */
- error_width = atof (&argv[i][j]);
- while (argv[i][j] && argv[i][j] != '/') j++;
- j--;
- }
- }
- error_bars = TRUE;
- if (argv[i][j] == '/') gmt_getpen (&argv[i][j+1], &epen);
- break;
- case 'F':
- if (gmt_getrgb (&argv[i][2], &gmtdefs.basemap_frame_rgb[0], &gmtdefs.basemap_frame_rgb[1], &gmtdefs.basemap_frame_rgb[2])) {
- gmt_pen_syntax ('F');
- error++;
- }
- break;
- case 'G': /* Set Gray shade for polygon */
- if (gmt_getfill (&argv[i][2], &fill)) {
- gmt_fill_syntax ('G');
- error++;
- }
- polygon = TRUE;
- break;
- case 'L': /* Draw the outline */
- outline = TRUE;
- break;
- case 'M': /* Multiple line segments */
- multi_segments = TRUE;
- if (argv[i][2]) EOL_flag = argv[i][2];
- break;
- case 'N': /* Do not skip points outside border */
- skip_if_outside = FALSE;
- break;
- case 'S': /* Get symbol [and size] */
- n = sscanf (&argv[i][2], "%c%lf", &symbol_type, &symbol_size);
- check = TRUE;
- switch (symbol_type) {
- case 'a':
- symbol = STAR;
- break;
- case 'b':
- symbol = BAR;
- symbol_size *= 0.5;
- for (j = 3, slash = -1; argv[i][j] && slash < 0; j++) if (argv[i][j] == '/') slash = j;
- if (slash > 0) base = atof (&argv[i][j]);
- if (argv[i][strlen(argv[i])-1] == 'u') user_unit = TRUE;
- break;
- case 'c':
- symbol = CIRCLE;
- symbol_size *= 0.5;
- break;
- case 'd':
- symbol = DIAMOND;
- break;
- case 'e':
- symbol = ELLIPSE;
- read_ellipse = TRUE;
- n_expected += 3;
- check = FALSE;
- break;
- case 'f':
- symbol = FAULT;
- sscanf (&argv[i][3], "%lf/%lf", &f_gap, &f_len);
- switch (argv[i][strlen(argv[i])-1]) {
- case 'L':
- f_triangle = TRUE;
- case 'l':
- f_sense = 1;
- break;
- case 'R':
- f_triangle = TRUE;
- case 'r':
- f_sense = -1;
- break;
- default:
- f_sense = 0;
- break;
- }
- break;
- case 'h':
- symbol = HEXAGON;
- break;
- case 'i':
- symbol = ITRIANGLE;
- break;
- case 'l':
- symbol = TEXT;
- for (j = 3, slash = 0; argv[i][j] && !slash; j++) if (argv[i][j] == '/') slash = j;
- if (slash && argv[i][slash+1])
- string = &argv[i][slash+1];
- else if (!slash && argv[i][3] && symbol_size == 0.0)
- string = &argv[i][3];
- else {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -Sl option: No string given\n", gmt_program);
- error++;
- }
- break;
- case 'p':
- symbol = POINT;
- check = FALSE;
- break;
- case 's':
- symbol = SQUARE;
- break;
- case 't':
- symbol = TRIANGLE;
- break;
- case 'V':
- convert_angles = TRUE;
- case 'v':
- symbol = VECTOR;
- if (argv[i][3]) sscanf (&argv[i][3], "%lf/%lf/%lf", &v_width, &h_length, &h_width);
- for (j = 3; argv[i][j] && argv[i][j] != 'n'; j++);
- if (argv[i][j]) { /* Normalize option used */
- v_norm = atof (&argv[i][j+1]);
- if (v_norm > 0.0) {
- v_shrink = 1.0 / v_norm;
- symbol = VECTOR2;
- }
- }
- read_vector = TRUE;
- n_expected += 2;
- check = FALSE;
- break;
- case 'x':
- symbol = CROSS;
- break;
- default:
- error = TRUE;
- fprintf (stderr, "%s: GMT SYNTAX ERROR -S option: Unrecognized symbol type %c\n", gmt_program, symbol_type);
- break;
- }
- if (symbol_size == 0.0 && check) {
- read_size = TRUE;
- n_expected++;
- }
- break;
- case 'W': /* Set line attributes */
- if (gmt_getpen (&argv[i][2], &pen)) {
- gmt_pen_syntax ('W');
- error++;
- }
- pen_set = 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 <infiles> -J<params> -R<west/east/south/north> [-A] [-B<tickinfo>]\n");
- fprintf (stderr, " [-C<cpt>] [-E[x][y][cap][/<pen>]] [-F<r/g/b>] [-G<fill>] [-H] [-K] [-L] [-M<flag>] [-N]\n");
- fprintf (stderr, " [-O] [-P] [-S<symbol><size>] [-U[<label>]] [-V] [-W<pen>] [-c<ncopies>]\n");
- fprintf (stderr, " [-X<x_shift>] [-Y<y_shift>] [-:]\n\n");
-
- if (gmt_quick) exit(-1);
-
- fprintf (stderr, " <infiles> is one or more files. If no, read standard input\n");
- explain_option ('j');
- explain_option ('R');
- fprintf (stderr, "\n\tOPTIONS:\n");
- explain_option ('b');
- fprintf (stderr, " -A Suppress drawing line segments as great circle arcs\n");
- fprintf (stderr, " -C Use cpt-file to assign colors based on z-value in 3rd column\n");
- fprintf (stderr, " Must be used with -S\n");
- fprintf (stderr, " -E means draw error bars for x [and/or y]. Add cap-width [%lg]. Append pen attributes.\n", error_width);
- fprintf (stderr, " -F Set color used for Frame and anotation [%d/%d/%d]\n",
- gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
- fprintf (stderr, " -G Specify color (for symbols/polygons) or pattern (for polygons). fill can be either\n");
- fprintf (stderr, " 1) <r/g/b> (each 0-255) for color or <gray> (0-255) for gray-shade [0].\n");
- fprintf (stderr, " 2) p[or P]<iconsize>/<pattern> for predefined patterns (0-31).\n");
- fprintf (stderr, " Default is no fill (transparent symbols or polygons)\n");
- explain_option ('H');
- explain_option ('K');
- fprintf (stderr, " -L close polygon OR draw symbol outline with current pen (see -W).\n");
- fprintf (stderr, " -M Input files each consist of multiple segments separated by one record.\n");
- fprintf (stderr, " whose first character is <flag> [>].\n");
- fprintf (stderr, " -N Do Not skip/clip symbols that fall outside map border [Default will ignore those outside]\n");
- explain_option ('O');
- explain_option ('P');
- fprintf (stderr, " -S to select symbol type and symbol size (in %s). Choose between\n", gmt_unit_names[gmtdefs.measure_unit]);
- fprintf (stderr, " st(a)r, (b)ar, (c)ircle, (d)iamond, (e)llipse, (f)ault, (h)exagon,\n");
- fprintf (stderr, " (i)nvtriangle, (l)etter, (p)oint, (s)quare, (t)riangle, (v)ector, (x)cross\n");
- fprintf (stderr, " If no size is specified, psxy expects the 3rd column to have sizes.\n");
- fprintf (stderr, " [Note: if -C is selected then 3rd means 4th column, etc.]\n");
- fprintf (stderr, " Bars: Append /base to give the y-value of the base [Default = 0]\n");
- fprintf (stderr, " Append u if width is in x-input units [Default is %s]\n", gmt_unit_names[gmtdefs.measure_unit]);
- fprintf (stderr, " Ellipses: the direction, major, and minor axis must be in input columns 3, 4 and 5.\n");
- fprintf (stderr, " Faults: Give tickgap/ticklen[type], where type is:\n");
- fprintf (stderr, " l - draw tick to left, r - draw tick to right [Default is centered]\n");
- fprintf (stderr, " Upper case L or R gives filled triangle\n");
- fprintf (stderr, " Letter: append /<string> after symbol size\n");
- fprintf (stderr, " Vectors: the direction and length must be in input columns 3 and 4.\n");
- fprintf (stderr, " Furthermore, <size> means arrowwidth/headlength/headwith [Default is %lg/%lg/%lg]\n", v_width, h_length, h_width);
- fprintf (stderr, " If -SV rather than -Sv is selected, psxy will expect aximuth and length\n");
- fprintf (stderr, " and convert azimuths based on the chosen map projection\n");
- explain_option ('U');
- explain_option ('V');
- fprintf (stderr, " -W sets pen attributes [width = %d, color = (%d/%d/%d), texture = solid line].\n",
- pen.width, pen.r, pen.g, pen.b);
- explain_option ('X');
- explain_option ('c');
- explain_option (':');
- explain_option ('.');
- exit(-1);
- }
-
- /* Check that the options selected are mutually consistant */
-
- if (error_bars && (read_vector || read_ellipse || symbol == FAULT)) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -E option: Incompatible with -Se, -Sf, -Sv\n", gmt_program);
- error++;
- }
- if (fill.use_pattern && symbol != LINE) { /* fill-pattern only for polygons */
- error++;
- fprintf (stderr, "%s: GMT SYNTAX ERROR -G option: Fill-pattern only used with polygons\n", gmt_program);
- }
- if (get_rgb && symbol == 0) {
- error++;
- fprintf (stderr, "%s: GMT SYNTAX ERROR -C option: Must also specify a symbol (see -S)\n", gmt_program);
- }
- if (!project_info.region_supplied) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify -R option\n", gmt_program);
- error++;
- }
- if (error) exit (-1);
-
- if (error_bars && symbol == 0) /* Assume user only wants error bars */
- symbol = NONE;
-
- if (symbol == 0 && outline) polygon = TRUE;
- if (symbol != LINE && pen_set) outline = TRUE;
-
- if (get_rgb) read_cpt (cpt);
-
- if (n_files > 0)
- nofile = FALSE;
- else
- n_files = 1;
- n_args = (argc > 1) ? argc : 2;
-
- if (xy_errors[0] == 0 && xy_errors[1] == 0) error_bars = FALSE; /* Must specify x and/or y */
- if (error_bars) {
- if (xy_errors[0]) n_expected++;
- if (xy_errors[1]) n_expected++;
- xy_errors[0] += read_size; /* Move 1 column over */
- xy_errors[1] += read_size;
- error_width2 = 0.5 * error_width;
- }
- two = (get_rgb) ? 3 : 2;
- three = (get_rgb) ? 4 : 3;
- four = (get_rgb) ? 5 : 4;
-
- greenwich = (west < 0.0 || east <= 0.0);
-
- map_setup (west, east, south, north);
-
- ps_plotinit (CNULL, gmtdefs.overlay, gmtdefs.page_orientation, gmtdefs.x_origin, gmtdefs.y_origin,
- gmtdefs.global_x_scale, gmtdefs.global_y_scale, gmtdefs.n_copies,
- gmtdefs.dpi, gmtdefs.measure_unit, gmtdefs.paper_width, gmtdefs.page_rgb, gmt_epsinfo (argv[0]));
- echo_command (argc, argv);
- if (gmtdefs.unix_time) timestamp (argc, argv);
-
- ps_setline (pen.width);
- if (pen.texture) ps_setdash (pen.texture, pen.offset);
- if (symbol == TEXT && polygon && !outline)
- ps_setpaint (fill.r, fill.g, fill.b);
- else
- ps_setpaint (pen.r, pen.g, pen.b);
-
- if (symbol == TEXT) {
- font_size = rint (symbol_size * 72.0); /* To get points */
- ps_setfont (gmtdefs.anot_font);
- }
- if (symbol > 0 && skip_if_outside) map_clip_on (-1, -1, -1, 3);
-
- geo_to_xy (west, base, &plot_x, &y0); /* Zero level for bars */
- old_gmt_world_map = gmt_world_map;
-
- ix = (gmtdefs.xy_toggle); iy = 1 - ix;
- if (symbol <= 0) {
- xx = (double *) memory (CNULL, n_alloc, sizeof (double), "psxy");
- yy = (double *) memory (CNULL, n_alloc, sizeof (double), "psxy");
- }
- done = FALSE;
- for (fno = 1; !done && fno < n_args; fno++) { /* Loop over all input files */
- if (!nofile && argv[fno][0] == '-') continue;
- if (nofile) {
- fp = stdin;
- done = TRUE;
- }
- else if ((fp = fopen (argv[fno], "r")) == NULL) {
- fprintf (stderr, "psxy: Cannot open file %s\n", argv[fno]);
- continue;
- }
-
- if (!nofile && gmtdefs.verbose) {
- fprintf (stderr, "psxy: Working on file %s\n", argv[fno]);
- sprintf (line, "File: %s\0", argv[fno]);
- ps_comment (line);
- }
- if (gmtdefs.io_header) for (i = 0; i < gmtdefs.n_header_recs; i++) fgets (line, 512, fp);
-
- if (multi_segments) fgets (header, 512, fp);
-
- if (symbol > 0) { /* symbol part */
-
- gmt_world_map = TRUE;
-
- if (multi_segments && gmtdefs.verbose) ps_comment (header);
- while (fgets (line, 512, fp)) {
- n_got = sscanf (line, "%s %s %s %s %s %s", col[0], col[1], col[2], col[3], col[4], col[5]);
-
- if (col[0][0] == EOL_flag) {
- ps_comment (line);
- continue;
- }
-
- if (n_got < n_expected) {
- fprintf (stderr, "psxy: Mismatch between expected (%d) and actual (%d) columns!\n", n_expected, n_got);
- fprintf (stderr, "--> %s\n", line);
- exit (-1);
- }
-
- xy[ix] = atof (col[0]);
- xy[iy] = atof (col[1]);
-
- if (get_rgb) {
- z = atof (col[2]);
- get_rgb24 (z, &fill.r, &fill.g, &fill.b);
- if (symbol == CROSS || symbol == POINT || symbol == TEXT) ps_setpaint (fill.r, fill.g, fill.b);
- }
- if (read_size) {
- symbol_size = atof (col[two]);
- if (symbol == BAR || symbol == CIRCLE)
- symbol_size *= 0.5;
- else
- font_size = rint (symbol_size * 72.0);
- }
- else if (read_vector) {
- direction = atof (col[two]);
- length1 = atof (col[three]);
- }
- else if (read_ellipse) {
- direction = atof (col[two]);
- length1 = atof (col[three]);
- length2 = atof (col[four]);
- }
-
- /* Skip zero-size symbols */
-
- if (symbol != POINT && symbol < VECTOR && symbol_size <= 0.0) continue;
- if (read_vector && length1 <= 0.0) continue;
- if (read_ellipse && (length1 <= 0.0 || length2 <= 0.0)) continue;
-
- if (xy_errors[0]) delta_x = atof (col[xy_errors[0]]);
- if (xy_errors[1]) delta_y = atof (col[xy_errors[1]]);
-
- if (skip_if_outside) {
- map_outside (xy[0], xy[1]);
- if ( abs (gmt_x_status_new) > 1 || abs (gmt_y_status_new) > 1) continue;
- }
-
- geo_to_xy (xy[0], xy[1], &plot_x, &plot_y);
-
- if (error_bars) {
- ps_setline (epen.width);
- ps_setpaint (epen.r, epen.g, epen.b);
- if (xy_errors[0]) {
- geo_to_xy (xy[0] - delta_x, xy[1], &x_1, &y_1);
- geo_to_xy (xy[0] + delta_x, xy[1], &x_2, &y_2);
- ps_plot (x_1, y_1, 3);
- ps_plot (x_2, y_2, 2);
- if (error_width > 0.0) {
- ps_plot (x_1, y_1 - error_width2, 3);
- ps_plotr (0.0, error_width, 2);
- ps_plot (x_2, y_2 - error_width2, 3);
- ps_plotr (0.0, error_width, 2);
- }
- }
- if (xy_errors[1]) {
- geo_to_xy (xy[0], xy[1] - delta_y, &x_1, &y_1);
- geo_to_xy (xy[0], xy[1] + delta_y, &x_2, &y_2);
- ps_plot (x_1, y_1, 3);
- ps_plot (x_2, y_2, 2);
- if (error_width > 0.0) {
- ps_plot (x_1 - error_width2, y_1, 3);
- ps_plotr (error_width, 0.0, 2);
- ps_plot (x_2 - error_width2, y_2, 3);
- ps_plotr (error_width, 0.0, 2);
- }
- }
- ps_setline (pen.width);
- ps_setpaint (pen.r, pen.g, pen.b);
- }
-
- switch (symbol) {
- case NONE:
- break;
- case STAR:
- ps_star (plot_x, plot_y, symbol_size, fill.r, fill.g, fill.b, outline);
- break;
- case BAR:
- if (user_unit) { /* Width measured in x units */
- geo_to_xy (xy[0]-symbol_size, base, &x_1, &y_1);
- geo_to_xy (xy[0]+symbol_size, xy[1], &x_2, &y_2);
-
- ps_rect (x_1, y_1, x_2, y_2, fill.r, fill.g, fill.b, outline);
- }
- else
- ps_rect (plot_x-symbol_size, y0, plot_x+symbol_size, plot_y, fill.r, fill.g, fill.b, outline);
- break;
- case CROSS:
- ps_cross (plot_x, plot_y, symbol_size);
- break;
- case POINT:
- ps_cross (plot_x, plot_y, POINTSIZE);
- break;
- case CIRCLE:
- ps_circle (plot_x, plot_y, symbol_size, fill.r, fill.g, fill.b, outline);
- break;
- case SQUARE:
- ps_square (plot_x, plot_y, symbol_size, fill.r, fill.g, fill.b, outline);
- break;
- case HEXAGON:
- ps_hexagon (plot_x, plot_y, symbol_size, fill.r, fill.g, fill.b, outline);
- break;
- case TRIANGLE:
- ps_triangle (plot_x, plot_y, symbol_size, fill.r, fill.g, fill.b, outline);
- break;
- case ITRIANGLE:
- ps_itriangle (plot_x, plot_y, symbol_size, fill.r, fill.g, fill.b, outline);
- break;
- case DIAMOND:
- ps_diamond (plot_x, plot_y, symbol_size, fill.r, fill.g, fill.b, outline);
- break;
- case TEXT:
- if (outline && polygon) {
- ps_setpaint (fill.r, fill.g, fill.b);
- ps_text (plot_x, plot_y, font_size, string, 0.0, 6, FALSE);
- ps_setpaint (pen.r, pen.g, pen.b);
- ps_text (plot_x, plot_y, font_size, string, 0.0, 6, TRUE);
- }
- else if (polygon)
- ps_text (plot_x, plot_y, font_size, string, 0.0, 6, FALSE);
- else
- ps_text (plot_x, plot_y, font_size, string, 0.0, 6, TRUE);
- break;
- case ELLIPSE:
- ps_ellipse (plot_x, plot_y, direction, length1, length2, fill.r, fill.g, fill.b, outline);
- break;
- case VECTOR:
- if (length1 == 0.0) continue;
- if (convert_angles) {
- azim_2_angle (xy[0], xy[1], 0.1, direction, &tmp);
- direction = tmp;
- }
- x2 = plot_x + length1 * cos (direction * D2R);
- y2 = plot_y + length1 * sin (direction * D2R);
- ps_vector (plot_x, plot_y, x2, y2, v_width, h_length, h_width, gmtdefs.vector_shape, fill.r, fill.g, fill.b, outline);
- break;
- case VECTOR2:
- if (length1 == 0.0) continue;
- if (convert_angles) {
- azim_2_angle (xy[0], xy[1], 1.0, direction, &tmp);
- direction = tmp;
- }
- x2 = plot_x + length1 * cos (direction * D2R);
- y2 = plot_y + length1 * sin (direction * D2R);
- if (length1 < v_norm) { /* Scale arrow attributes down with length */
- v_w = v_width * length1 * v_shrink;
- h_l = h_length * length1 * v_shrink;
- h_w = h_width * length1 * v_shrink;
- ps_vector (plot_x, plot_y, x2, y2, v_w, h_l, h_w, gmtdefs.vector_shape, fill.r, fill.g, fill.b, outline);
- }
- else /* Leave as specified */
- ps_vector (plot_x, plot_y, x2, y2, v_width, h_length, h_width, gmtdefs.vector_shape, fill.r, fill.g, fill.b, outline);
- break;
- }
- }
- }
- else { /* Line/polygon part */
-
- more = fgets (line, 512, fp);
- while (more) {
- if (multi_segments && gmtdefs.verbose) ps_comment (header);
- n = 0;
- while ((more && !multi_segments) || (more && multi_segments && line[0] != EOL_flag)) {
- if (line[0] == EOL_flag) {
- more = fgets (line, 512, fp);
- continue;
- }
-
- sscanf (line, "%lf %lf", &xy[ix], &xy[iy]);
- xx[n] = xy[0]; yy[n] = xy[1];
- n++;
- if (n == n_alloc) {
- n_alloc += GMT_CHUNK;
- xx = (double *) memory ((char *)xx, n_alloc, sizeof (double), "psxy");
- yy = (double *) memory ((char *)yy, n_alloc, sizeof (double), "psxy");
- }
- more = fgets (line, 512, fp);
- }
- if (polygon && !(xx[0] == xx[n-1] && yy[0] == yy[n-1])) { /* Explicitly close polygon so that arc will work */
- xx[n] = xx[0];
- yy[n] = yy[0];
- n++;
- if (n == n_alloc) {
- n_alloc += GMT_CHUNK;
- xx = (double *) memory ((char *)xx, n_alloc, sizeof (double), "psxy");
- yy = (double *) memory ((char *)yy, n_alloc, sizeof (double), "psxy");
- }
- }
- if (multi_segments && gmtdefs.verbose) strcpy (header, line);
-
- xx = (double *) memory ((char *)xx, n, sizeof (double), "psxy");
- yy = (double *) memory ((char *)yy, n, sizeof (double), "psxy");
- n_alloc = n;
-
- if (draw_arc && project_info.projection > 5) n = fix_up_path (&xx, &yy, n, greenwich, step);
-
- if (polygon) {
- if ((plot_n = clip_to_map (xx, yy, n, &xp, &yp)) == 0) {
- if (more) more = fgets (line, 512, fp);
- continue;
- }
- while (plot_n > gmt_n_alloc) get_plot_array ();
- memcpy ((char *)gmt_x_plot, (char *)xp, plot_n * sizeof (double));
- memcpy ((char *)gmt_y_plot, (char *)yp, plot_n * sizeof (double));
- }
- else {
- plot_n = geo_to_xy_line (xx, yy, n);
- xp = (double *) memory (CNULL, plot_n, sizeof (double), "psxy");
- yp = (double *) memory (CNULL, plot_n, sizeof (double), "psxy");
- plot_pen = (int *) memory (CNULL, plot_n, sizeof (int), "psxy");
- memcpy ((char *)xp, (char *)gmt_x_plot, plot_n * sizeof (double));
- memcpy ((char *)yp, (char *)gmt_y_plot, plot_n * sizeof (double));
- memcpy ((char *)plot_pen, (char *)gmt_pen, plot_n * sizeof (int));
- }
-
- if (polygon) {
-
- if (will_it_wrap (xp, yp, plot_n, &start)) { /* Polygon wraps */
-
- /* First truncate agains left border */
-
- gmt_n_plot = truncate_left (xp, yp, plot_n, start);
- n_use = compact_line (gmt_x_plot, gmt_y_plot, gmt_n_plot, FALSE, 0);
- if (fill.use_pattern)
- ps_imagefill (gmt_x_plot, gmt_y_plot, n_use, fill.pattern_no, fill.pattern, fill.inverse, fill.icon_size, outline);
- else
- ps_polygon (gmt_x_plot, gmt_y_plot, n_use, fill.r, fill.g, fill.b, outline);
-
- /* Then truncate agains right border */
-
- gmt_n_plot = truncate_right (xp, yp, plot_n, start);
- n_use = compact_line (gmt_x_plot, gmt_y_plot, gmt_n_plot, FALSE, 0);
- if (fill.use_pattern)
- ps_imagefill (gmt_x_plot, gmt_y_plot, n_use, fill.pattern_no, fill.pattern, fill.inverse, fill.icon_size, outline);
- else
- ps_polygon (gmt_x_plot, gmt_y_plot, n_use, fill.r, fill.g, fill.b, outline);
-
- }
- else {
- if (fill.use_pattern)
- ps_imagefill (xp, yp, plot_n, fill.pattern_no, fill.pattern, fill.inverse, fill.icon_size, outline);
- else
- ps_polygon (xp, yp, plot_n, fill.r, fill.g, fill.b, outline);
- }
- }
- else
- gmt_plot_line (xp, yp, plot_pen, plot_n);
-
- if (symbol == FAULT) draw_fence (xp, yp, plot_n, f_gap, f_len, f_sense, f_triangle, &fill, outline); /* Must draw crossbars */
-
- free ((char *)xp);
- free ((char *)yp);
- if (!polygon) free ((char *)plot_pen);
-
- if (more) more = fgets (line, 512, fp);
- }
- }
- if (fp != stdin) fclose (fp);
- }
-
- if (symbol > 0 && skip_if_outside) map_clip_off ();
-
- gmt_world_map = old_gmt_world_map;
-
- if (pen.texture) ps_setdash (CNULL, 0);
- if (frame_info.plot) {
- ps_setpaint (gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
- map_basemap ();
- ps_setpaint (gmtdefs.background_rgb[0], gmtdefs.background_rgb[1], gmtdefs.background_rgb[2]);
- }
- ps_plotend (gmtdefs.last_page);
-
- if (symbol == 0) {
- free ((char *)xx);
- free ((char *)yy);
- }
-
- gmt_end (argc, argv);
- }
-
- int draw_fence (x, y, n, gap, len, sense, triangle, fill, outline)
- double x[], y[];
- int n;
- double gap, len;
- int sense, triangle;
- struct FILL *fill;
- BOOLEAN outline; {
- int i, ngap;
- double *s, xx[3], yy[3], dist = 0.0, frac, dx, dy, angle;
- double x0, y0, len2, len3, cosa, sina;
-
- s = (double *) memory (CNULL, n, sizeof (double), "psxy");
- for (i = 1, s[0] = 0.0; i < n; i++)
- s[i] = s[i-1] + hypot (x[i] - x[i-1], y[i] - y[i-1]);
-
- if (gap > 0.0) {
- ngap = rint (s[n-1] / gap);
- gap = s[n-1] / ngap;
- ngap++;
- }
- else {
- ngap = (int) fabs (gap);
- gap = s[n-1] / (ngap - 1);
- if (ngap == 1) dist = 0.5 * s[n-1];
- }
-
- len2 = 0.5 * len;
- len3 = 0.866025404 * len;
- i = 0;
- while (i < n) {
- while ((s[i] - dist) > -SMALL) { /* Time for tick */
- if (i > 0) {
- dx = x[i] - x[i-1];
- dy = y[i] - y[i-1];
- }
- else {
- dx = x[1] - x[0];
- dy = y[1] - y[0];
- }
- if (fabs (dist - s[i]) < SMALL) {
- x0 = x[i];
- y0 = y[i];
- }
- else {
- frac = (s[i] - dist) / (s[i] - s[i-1]);
- x0 = x[i] - dx * frac;
- y0 = y[i] - dy * frac;
- }
- angle = atan2 (dy, dx);
-
- if (triangle) {
- if (sense == -1) angle += M_PI;
- cosa = cos (angle);
- sina = sin (angle);
- xx[0] = x0 + len2 * cosa;
- yy[0] = y0 + len2 * sina;
- xx[1] = x0 - len3 * sina;
- yy[1] = y0 + len3 * cosa;
- xx[2] = x0 - len2 * cosa;
- yy[2] = y0 - len2 * sina;
- if (project_info.three_D) two_d_to_three_d (xx, yy, 3);
- ps_patch (xx, yy, 3, fill->r, fill->g, fill->b, outline);
- }
- else {
- xx[0] = xx[1] = x0; yy[0] = yy[1] = y0;
- if (sense == 0) {
- angle -= M_PI_2;
- cosa = cos (angle);
- sina = sin (angle);
- xx[0] += len2 * cosa;
- yy[0] += len2 * sina;
- xx[1] -= len2 * cosa;
- yy[1] -= len2 * sina;
- }
- else {
- angle += (sense * M_PI_2);
- xx[1] += len * cos (angle);
- yy[1] += len * sin (angle);
- }
- if (project_info.three_D) two_d_to_three_d (xx, yy, 2);
- ps_plot (xx[0], yy[0], 3);
- ps_plot (xx[1], yy[1], 2);
- }
- dist += gap;
- }
- i++;
- }
- free ((char *)s);
- }
-
-