home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- * The GMT-system: @(#)pswiggle.c 2.24 30 Jun 1995
- *
- * Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
- * See README file for copying and redistribution conditions.
- *--------------------------------------------------------------------*/
- /*
- * pswiggle reads x,y,z from stdin and plots a wiggleplot using the
- * specified map projection. If the distance between 2 consecutive points
- * exceeds the value of dist_gap, a data gap is assumed. The user may
- * select a preferred direction where s/he wants the positive anomalies
- * to be pointing towards. Positive normal vectors to the trackline
- * will then always be withing +- 90 degrees of this direction.
- * Separate colors may be specified for positive anomaly, outline of
- * anomaly, and trackline. Plotting of the outline and track is optional.
- *
- * Author: Paul Wessel
- * Date: 24-JAN-1995
- * Version: 3.0, based on old v2.x
- *
- */
-
- #include "gmt.h"
-
- #define MAX_POINTS 400
-
- double *xx, *yy, *zz, *lon, *lat, *z;
- double start_az, stop_az;
-
- main (argc, argv)
- int argc;
- char **argv; {
- int i, j, n, k, ix, iy, n_files = 0, fno, n_alloc = GMT_CHUNK, n_args;
-
- BOOLEAN error = FALSE, nofile = TRUE, outline = FALSE, track = FALSE, paint_wiggle, draw_scale = FALSE;
- BOOLEAN multi_segments = FALSE, do_fill = FALSE, negative = FALSE, fix = FALSE, done, gave_xy = FALSE;
-
- double west = 0.0, east = 360.0, south = 0.0, north = 0.0, x_2, y_2, bias = 0.0, fix_az;
- double zscale = 0.0, dx, dy, dz, ds, x0, y0, length, dist_gap = MAXDOUBLE, xy[2], pref_dir = 0.0;
-
- char line[512], *more, EOF_flag = '>', *units, txt_a[32], txt_b[32];
-
- FILE *fp = NULL;
-
- struct FILL fill;
- struct PEN pen_o, pen_t;
-
- argc = gmt_begin (argc, argv);
-
- gmt_init_pen (&pen_o, 1);
- gmt_init_pen (&pen_t, 1);
- gmt_init_fill (&fill, gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
-
- 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':
- pref_dir = atof (&argv[i][2]);
- break;
- case 'D':
- dist_gap = atof (&argv[i][2]) * 1000.0;
- break;
- case 'E':
- sscanf (&argv[i][2], "%lf/%lf", &z_project.view_azimuth, &z_project.view_elevation);
- 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':
- if (gmt_getfill (&argv[i][2], &fill)) {
- gmt_fill_syntax ('G');
- error++;
- }
- do_fill = TRUE;
- break;
- case 'I':
- fix_az = atof (&argv[i][2]) * D2R;
- fix = TRUE;
- break;
- case 'M':
- if (argv[i][2]) EOF_flag = argv[i][2];
- multi_segments = TRUE;
- break;
- case 'N':
- negative = TRUE;
- break;
- case 'C':
- bias = atof (&argv[i][2]);
- break;
- case 'T':
- if (gmt_getpen (&argv[i][2], &pen_t)) {
- gmt_pen_syntax ('T');
- error++;
- }
- track = TRUE;
- break;
- case 'W':
- if (gmt_getpen (&argv[i][2], &pen_o)) {
- gmt_pen_syntax ('W');
- error++;
- }
- outline = TRUE;
- break;
- case 'S':
- j = 0;
- if (argv[i][2] == 'x') gave_xy = TRUE, j = 1;
- k = sscanf (&argv[i][2+j], "%[^/]/%[^/]/%lf", txt_a, txt_b, &length);
- x0 = ddmmss_to_degree (txt_a);
- y0 = ddmmss_to_degree (txt_b);
- units = strrchr (argv[i], '/'); units++;
- if (k != 3) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -S option: Correct syntax\n", gmt_program);
- fprintf (stderr, " -S[x]<x0>/<y0>/<length>[/<units>]\n");
- error++;
- }
- draw_scale = TRUE;
- break;
-
- case 'Z':
- zscale = atof (&argv[i][2]);
- break;
-
- /* Illegal options */
-
- default:
- error = TRUE;
- gmt_default_error (argv[i][1]);
- break;
- }
- }
- else
- n_files++;
- }
-
- if (argc == 1 || gmt_quick) {
- fprintf (stderr,"pswiggle %s - Plot xyz-series along tracks\n\n", GMT_VERSION);
- fprintf (stderr, "usage: pswiggle <xyz-files> -J<params> -R<west/east/south/north> -Z<scale>\n");
- fprintf (stderr, " [-A<direction>] [-B<tickinfo>] [-C<center>] [-D<gap>] [-Eaz/el] [-F<r/g/b>] [-G<fill>] [-H]\n");
- fprintf (stderr, " [-I<az>] [-K] [-M[<flag>]] [-N] [-O] [-P] [-S[x]<lon0>/<lat0>/<length>/<units>] [-T<trackpen>]\n");
- fprintf (stderr, " [-U] [-V] [-W<outlinepen>] [-X<x_shift>] [-Y<y_shift>] [-c<ncopies>] [-:]\n");
-
- if (gmt_quick) exit (-1);
-
- fprintf (stderr, " <xyz_files> is one or more files. If none, read standard input\n");
- explain_option ('j');
- explain_option ('R');
- fprintf (stderr, "\n\tOPTIONS:\n");
- fprintf (stderr, " -A set azimuth for preferred positive wiggle direction [0.0]\n");
- explain_option ('b');
- fprintf (stderr, " -C sets center value to be removed from z before plotting. [0]\n");
- fprintf (stderr, " -D means there is a datagap if 2 points are more than <gap> distance units apart\n");
- fprintf (stderr, " gap is in km for map projections, user-units otherwise\n");
- fprintf (stderr, " -E set azimuth and elevation of viewpoint for 3-D perspective [180/90]\n");
- 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 or pattern for positive areas. 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");
- explain_option ('H');
- fprintf (stderr, " -I set fixed projection angle for wiggles\n");
- explain_option ('K');
- 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 Fill negative wiggles instead [Default is positive]\n");
- explain_option ('O');
- explain_option ('P');
- fprintf (stderr, " -S draws a simple vertical scale centered on <lon0>/<lat0>. Use -Sx to specify cartesian coordinates instead.\n");
- fprintf (stderr, " <length> is in z-units, append unit name for labeling\n");
- fprintf (stderr, " -T specifies track pen attributes. [Default is no track]\n");
- explain_option ('U');
- explain_option ('V');
- fprintf (stderr, " -W specifies outline pen attributes. [Default is no outline]\n");
- explain_option ('X');
- fprintf (stderr, " -Z gives the wiggle scale in data-units per %s\n", gmt_unit_names[gmtdefs.measure_unit]);
- explain_option ('c');
- 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 (!(outline || do_fill)) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify at least one of -G, -W\n", gmt_program);
- error++;
- }
- if (z_project.view_azimuth > 360.0 || z_project.view_elevation <= 0.0 || z_project.view_elevation > 90.0) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -E option: Enter azimuth in 0-360 range, elevation in 0-90 range\n", gmt_program);
- error++;
- }
- if (zscale == 0.0) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -Z option: scale must be nonzero\n", gmt_program);
- error++;
- }
-
- if (error) exit (-1);
-
- 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);
- if (project_info.three_D) ps_transrotate (-z_project.xmin, -z_project.ymin, 0.0);
-
- zscale = 1.0 / zscale;
- start_az = pref_dir - 90.0;
- stop_az = pref_dir + 90.0;
- map_clip_on (-1, -1, -1, 3);
-
- /* Allocate memory */
-
- lon = (double *) memory (CNULL, n_alloc, sizeof (double), "psxy");
- lat = (double *) memory (CNULL, n_alloc, sizeof (double), "psxy");
- z = (double *) memory (CNULL, n_alloc, sizeof (double), "psxy");
- xx = (double *) memory (CNULL, n_alloc, sizeof (double), "psxy");
- yy = (double *) memory (CNULL, n_alloc, sizeof (double), "psxy");
- zz = (double *) memory (CNULL, n_alloc, sizeof (double), "psxy");
-
- if (n_files != 0) nofile = FALSE;
- done = FALSE;
- n_args = (argc > 1) ? argc : 2;
-
- for (fno = 1; !done && fno < n_args; fno++) { /* Loop over all the files */
- if (!nofile && argv[fno][0] == '-') continue;
- if (nofile) {
- fp = stdin;
- done = TRUE;
- if (gmtdefs.verbose) fprintf (stderr, "pswiggle: Reading data from standard input\n");
- }
- else if ((fp = fopen (argv[fno], "r")) == NULL) {
- fprintf (stderr, "pswiggle: Cannot open file %s\n", argv[fno]);
- continue;
- }
-
- if (!nofile && gmtdefs.verbose) {
- fprintf (stderr, "pswiggle: Working on file %s\n", argv[fno]);
- printf ("%% file %s\n", argv[fno]);
- }
-
- ix = (gmtdefs.xy_toggle); iy = 1 - ix;
-
-
- if (gmtdefs.io_header) for (i = 0; i < gmtdefs.n_header_recs; i++) fgets (line, 512, fp);
- if (multi_segments) {
- fgets (line, 512, fp);
- if (gmtdefs.verbose) ps_comment (line);
- }
- more = fgets (line, 512, fp);
- while (more) {
- n = 0;
- while ((more && !multi_segments) || (more && multi_segments && line[0] != EOF_flag)) {
- sscanf (line, "%lf %lf %lf", &xy[ix], &xy[iy], &z[n]);
- lon[n] = xy[0]; lat[n] = xy[1];
- z[n] -= bias;
- n++;
- if (n >= n_alloc) {
- n_alloc += GMT_CHUNK;
- lon = (double *) memory ((char *)lon, n_alloc, sizeof (double), "psxy");
- lat = (double *) memory ((char *)lat, n_alloc, sizeof (double), "psxy");
- z = (double *) memory ((char *)z, n_alloc, sizeof (double), "psxy");
- xx = (double *) memory ((char *)xx, n_alloc, sizeof (double), "psxy");
- yy = (double *) memory ((char *)yy, n_alloc, sizeof (double), "psxy");
- zz = (double *) memory ((char *)zz, n_alloc, sizeof (double), "psxy");
- }
- more = fgets (line, 512, fp);
- }
-
- geo_to_xy (lon[0], lat[0], &xx[0], &yy[0]);
- zz[0] = z[0];
- paint_wiggle = (do_fill && ((negative && z[0] <= 0.0) || (!negative && z[0] >= 0.0)));
- j = 1;
- for (i = 1; i < n; i++) { /* Convert to inches/cm and get distance increments */
- dx = lon[i] - lon[i-1];
- dy = lat[i] - lat[i-1];
- if (project_info.projection > 5) {
- dx *= cos (0.5 * (lat[i] + lat[i-1]) * D2R);
- ds = hypot (dx, dy) * M_PR_DEG;
- }
- else
- ds = hypot (dx, dy);
-
- geo_to_xy (lon[i], lat[i], &x_2, &y_2);
-
- if (j > 0 && (ds > dist_gap || bad_float (z[i]))) { /* Data gap, plot what we have */
- paint_wiggle = (do_fill && ((negative && zz[j-1] <= 0.0) || (!negative && zz[j-1] >= 0.0)));
- plot_wiggle (xx, yy, zz, j, zscale, fix, fix_az, &fill, &pen_o, &pen_t, paint_wiggle, outline, track);
- j = 0;
- }
- else if (j >= MAX_POINTS) {
- paint_wiggle = (do_fill && ((negative && zz[j-1] <= 0.0) || (!negative && zz[j-1] >= 0.0)));
- plot_wiggle (xx, yy, zz, j, zscale, fix, fix_az, &fill, &pen_o, &pen_t, paint_wiggle, outline, track);
- xx[0] = xx[j-1];
- yy[0] = yy[j-1];
- zz[0] = zz[j-1];
- j = 1;
- }
- else if (!bad_float (z[i-1]) && (z[i]*z[i-1] < 0.0 || z[i] == 0.0)) { /* Crossed 0, add new point and plot */
- dz = z[i] - z[i-1];
- xx[j] = (dz == 0.0) ? xx[j-1] : xx[j-1] + fabs (z[i-1] / dz) * (x_2 - xx[j-1]);
- yy[j] = (dz == 0.0) ? yy[j-1] : yy[j-1] + fabs (z[i-1] / dz) * (y_2 - yy[j-1]);
- zz[j] = 0.0;
- j++;
- paint_wiggle = (do_fill && ((negative && zz[j-2] <= 0.0) || (!negative && zz[j-2] >= 0.0)));
- plot_wiggle (xx, yy, zz, j, zscale, fix, fix_az, &fill, &pen_o, &pen_t, paint_wiggle, outline, track);
- xx[0] = xx[j-1];
- yy[0] = yy[j-1];
- zz[0] = zz[j-1];
- j = 1;
- }
- xx[j] = x_2;
- yy[j] = y_2;
- zz[j] = z[i];
- if (!bad_float (z[i])) j++;
- }
-
- if (j > 1) {
- paint_wiggle = (do_fill && ((negative && zz[j-1] <= 0.0) || (!negative && zz[j-1] >= 0.0)));
- plot_wiggle (xx, yy, zz, j, zscale, fix, fix_az, &fill, &pen_o, &pen_t, paint_wiggle, outline, track);
- }
- more = fgets (line, 512, fp);
- }
- if (fp != stdin) fclose (fp);
- }
-
- map_clip_off();
- if (frame_info.plot) {
- ps_setpaint (gmtdefs.basemap_frame_rgb[0], gmtdefs.basemap_frame_rgb[1], gmtdefs.basemap_frame_rgb[2]);
- map_basemap ();
- }
- if (draw_scale) draw_z_scale (x0, y0, length, zscale, gave_xy, units);
- ps_setpaint (gmtdefs.background_rgb[0], gmtdefs.background_rgb[1], gmtdefs.background_rgb[2]);
-
- if (project_info.three_D) ps_rotatetrans (z_project.xmin, z_project.ymin, 0.0);
- ps_plotend (gmtdefs.last_page);
-
- free ((char *)lon);
- free ((char *)lat);
- free ((char *)z);
- free ((char *)xx);
- free ((char *)yy);
- free ((char *)zz);
-
- gmt_end (argc, argv);
- }
-
- int plot_wiggle (x, y, z, np, zscale, fixed, fix_az, fill, pen_o, pen_t, paint_wiggle, outline, track)
- double x[], y[], z[], zscale, fix_az;
- int np;
- struct FILL *fill;
- struct PEN *pen_o, *pen_t;
- BOOLEAN fixed, paint_wiggle, outline, track; {
- double dx, dy, az = 0.0, x_inc, y_inc;
- int n, i;
-
- if (fixed) az = fix_az;
-
- if (paint_wiggle || outline) {
- if (!gmt_n_alloc) get_plot_array ();
- gmt_x_plot[0] = x[0];
- gmt_y_plot[0] = y[0];
- n = 1;
- for (i = 0; i < np; i++) {
- if (!fixed && i < np-1) {
- dx = x[i+1] - x[i];
- dy = y[i+1] - y[i];
- if (!(dx == 0.0 && dy == 0.0)) az = d_atan2 (dy, dx) * R2D - 360.0;
- while (az < start_az) az += 360.0;
- if (az > stop_az) az -= 180.0;
- az *= D2R;
- }
- if (fabs (z[i]) > 0.0) {
- x_inc = -zscale * z[i] * sin (az);
- y_inc = zscale * z[i]* cos (az);
- }
- else
- x_inc = y_inc = 0.0;
-
- gmt_x_plot[n] = x[i] + x_inc;
- gmt_y_plot[n] = y[i] + y_inc;
- n++;
- if (n == gmt_n_alloc) get_plot_array ();
- }
- gmt_x_plot[n] = x[np-1];
- gmt_y_plot[n] = y[np-1];
- n++;
-
- if (paint_wiggle) {
- for (i = np - 2; i >= 0; i--, n++) { /* Go back to 1st point along track */
- if (n == gmt_n_alloc) get_plot_array ();
- gmt_x_plot[n] = x[i];
- gmt_y_plot[n] = y[i];
- }
- }
- if (project_info.three_D) two_d_to_three_d (gmt_x_plot, gmt_y_plot, n);
- }
-
-
- if (paint_wiggle) { /* First shade wiggles */
- printf ("%% Positive wiggle\n");
- if (fill->use_pattern)
- ps_imagefill (gmt_x_plot, gmt_y_plot, n, fill->pattern_no, fill->pattern, fill->inverse, fill->icon_size, FALSE);
- else
- ps_polygon (gmt_x_plot, gmt_y_plot, n, fill->r, fill->g, fill->b, FALSE);
- }
-
- if (outline) { /* Then draw wiggle outline */
- printf ("%% Wiggle line\n");
- ps_setpaint (pen_o->r, pen_o->g, pen_o->b);
- ps_setline (pen_o->width);
- if (pen_o->texture) ps_setdash (pen_o->texture, pen_o->offset);
- ps_line (&gmt_x_plot[1], &gmt_y_plot[1], np, 3, FALSE, TRUE);
- if (pen_o->texture) ps_setdash (CNULL, 0);
- }
-
- if (track) { /* Finally draw track line */
- if (project_info.three_D) two_d_to_three_d (x, y, np);
- printf ("%% Track line\n");
- ps_setline (pen_t->width);
- ps_setpaint (pen_t->r, pen_t->g, pen_t->b);
- if (pen_t->texture) ps_setdash (pen_t->texture, pen_t->offset);
- ps_line (x, y, np, 3, FALSE, TRUE);
- if (pen_t->texture) ps_setdash (CNULL, 0);
- }
- }
-
- int draw_z_scale (x0, y0, length, zscale, gave_xy, units)
- double x0, y0, length, zscale;
- BOOLEAN gave_xy;
- char *units; {
- double dy, a, b, off;
- char txt[80];
-
- if (!gave_xy) geo_to_xy (x0, y0, &x0, &y0);
-
- if (units)
- sprintf (txt, "%lg %s\0", length, units);
- else
- sprintf (txt, "%lg\0", length);
- dy = 0.5 * length * zscale;
- xyz_to_xy (x0 + gmtdefs.tick_length, y0 - dy, 0.0, &a, &b);
- ps_plot (a, b, 3);
- xyz_to_xy (x0, y0 - dy, 0.0, &a, &b);
- ps_plot (a, b, 2);
- xyz_to_xy (x0, y0 + dy, 0.0, &a, &b);
- ps_plot (a, b, 2);
- xyz_to_xy (x0 + gmtdefs.tick_length, y0 + dy, 0.0, &a, &b);
- ps_plot (a, b, 2);
- off = ((gmtdefs.tick_length > 0.0) ? gmtdefs.tick_length : 0.0) + gmtdefs.anot_offset;
- gmt_text3d (x0 + off, y0, project_info.z_level, gmtdefs.anot_font_size, gmtdefs.anot_font, txt, 0.0, 5, 0);
- }
-