/*-------------------------------------------------------------------- * $Id: psmask.c,v 1.4.4.4 2002/02/27 17:58:55 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 *--------------------------------------------------------------------*/ /* * psmask tries to achieve masking using one of two different approachs: * The default way of operation is: Instead of painting tiles where there's no * data [or where there is data] psmask uses contouring to find the polygons * that contain the data [or contain the regions with no data]. For many types * of data coverage, this results in a managable path instead of thousands of * tiles. So, instead of painting polygons, psmask sets up actual clip paths. * As an option, the user may specify a rgb combination to fill the clipped areas. * To avoid having to deal with the problems that arise if the data distribution * is such that part of the map boundary should be part of the clip paths, we * internally enlarge the grid by one gridsize unit so no nodes along the edges * have data. Before using the clippaths we move points outside the real region * onto the boundary. * Should the paths be too long for PostScript to handle, the user may override * the default with the -T switch. Then, masking is achieved using tiling * * Author: Paul Wessel * Date: 01-JUL-2000 * Version: 3.4.1 * */ #include "gmt.h" #define IJ(i,j) ((i) + (j) * nx) /* Global variables for contour_sub routines */ int p[5], i_off[5], j_off[5], k_off[5], offset; unsigned int bit[32]; char *grd; int *edge; double *x, *y; /* Arrays holding the contour xy values */ double *x_grid, *y_grid; void draw_clip_contours (double *xx, double *yy, int nn, int rgb[], int id, int flag); void dump_clip_countours (double *xx, double *yy, int nn, int id, char *file); void shrink_clip_contours (double *x, double *y, int n, double w, double e); int trace_clip_contours (char *grd, int nx, int *edge, double west, double north, double dx, double dy, double xinc2, double yinc2, double **xx, double **yy, int i, int j, int kk, int *max); int clip_contours (char *grd, int nx, int ny, double west, double north, double dx, double dy, double xinc2, double yinc2, int *edge, int first, double **x, double **y, int *max); main (int argc, char **argv) { int i, j, ij, n, nm, n_edges, di, dj, ii, jj, n_expected_fields; int nx, ny, section, n_alloc, n_read, n_fields, one_or_zero = 1; BOOLEAN error = FALSE, first = TRUE, dump = FALSE, invert = FALSE; BOOLEAN end_of_clip = FALSE, find_paths = TRUE, use_poly; BOOLEAN map_units = FALSE, pixel = FALSE, node_only; char dfile[BUFSIZ], line[BUFSIZ]; double west, east, north, south, dx, dy, radius = 0.0, *in, distance; double x0, y0, x1, y1, xx[4], yy[4], dummy, shrink, km_pr_deg, offset = 0.5; double xinc2, yinc2, idx, idy; FILE *fp = NULL; struct GMT_FILL fill; west = east = north = south = xinc2 = yinc2 = 0.0; argc = GMT_begin (argc, argv); GMT_init_fill (&fill, -1, -1, -1); strcpy (dfile, "mask"); dx = dy = 0.0; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { /* Common parameters */ case 'B': 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': /* Input pairs are binary, not ascii */ error += GMT_io_selection (&argv[i][2]); break; case 'C': end_of_clip = TRUE; break; case 'D': /* Dump the polygons to files */ strcpy (dfile, &argv[i][2]); dump = TRUE; break; case 'E': sscanf (&argv[i][2], "%lf/%lf", &z_project.view_azimuth, &z_project.view_elevation); break; case 'F': pixel = TRUE; break; case 'G': if (GMT_getfill (&argv[i][2], &fill)) { GMT_fill_syntax ('G'); error++; } break; case 'I': GMT_getinc (&argv[i][2], &dx, &dy); break; case 'N': invert = TRUE; break; case 'S': /* Radius of influence */ GMT_getinc(&argv[i][2], &radius, &radius); map_units = (argv[i][strlen(argv[i])-1] == 'k'); break; case 'T': find_paths = FALSE; break; default: error = TRUE; GMT_default_error (argv[i][1]); break; } } else { if ((fp = GMT_fopen(argv[i], GMT_io.r_mode)) == NULL) { fprintf (stderr, "%s: Could not open file %s\n", GMT_program, argv[i]); exit (EXIT_FAILURE); } } } if (argc == 1 || GMT_quick) { fprintf (stderr,"psmask %s - Clipping of 2-D data sets\n\n", GMT_VERSION); fprintf (stderr, "usage: psmask -I[m|c][/[m|c]] -J -R\n"); fprintf (stderr, "\t[-B] [-C] -D [-Eaz/el] [-F] [-G] [-H[]] [-K] [-M[]]\n"); fprintf (stderr, "\t[-N] [-O] [-P] [-S[k]] [-T] [-U[