home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- * The GMT-system: @(#)grdsample.c 2.20 4/28/95
- *
- * Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
- * See README file for copying and redistribution conditions.
- *--------------------------------------------------------------------*/
- /*
- * grdsample reads a grdfile and evaluates the grid at new grid positions
- * specified by new dx/dy values using a 2-D Taylor expansion of order 3.
- * In order to evaluate derivatives along the edges of the surface, I assume
- * natural bi-cubic spline conditions, i.e. both the second and third normal
- * derivatives are zero, and that the dxdy derivative in the corners are zero, too.
- *
- * Author: Paul Wessel
- * Date: 19-JUL-1989
- * Revised: 6-JAN-1990 PW: Updated to v.2.0
- */
-
- #include "gmt.h"
- #include "gmt_bcr.h"
-
- float *a, *b;
-
- main (argc, argv)
- int argc;
- char **argv; {
- int i, j, ij, one, pad[4];
-
- BOOLEAN error = FALSE, greenwich = FALSE, offset = FALSE, bilinear = FALSE;
- BOOLEAN area_set = FALSE, n_set = FALSE, inc_set = FALSE, geo = FALSE, toggle = FALSE, global_grid;
-
- double *lon, lat, dx2, dy2;
-
- char *infile, *outfile;
-
- struct GRD_HEADER grd_a, grd_b;
-
- argc = gmt_begin (argc, argv);
-
- infile = outfile = CNULL;
-
- grd_init (&grd_b, argc, argv, FALSE);
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
-
- /* Common parameters */
-
- case 'R':
- case 'V':
- case '\0':
- error += get_common_args (argv[i], &grd_b.x_min, &grd_b.x_max, &grd_b.y_min, &grd_b.y_max);
- break;
-
- /* Supplemental parameters */
-
- case 'F':
- offset = TRUE;
- break;
- case 'G':
- outfile = &argv[i][2];
- break;
- case 'N':
- sscanf (&argv[i][2], "%d/%d", &grd_b.nx, &grd_b.ny);
- if (grd_b.ny == 0) grd_b.ny = grd_b.nx;
- n_set = TRUE;
- break;
- case 'I':
- gmt_getinc (&argv[i][2], &grd_b.x_inc, &grd_b.y_inc);
- inc_set = TRUE;
- break;
- case 'L':
- geo = TRUE;
- break;
- case 'Q':
- bilinear = TRUE;
- break;
- case 'T': /* Convert from pixel file <-> gridfile */
- toggle = TRUE;
- break;
- default:
- error = TRUE;
- gmt_default_error (argv[i][1]);
- break;
- }
- }
- else
- infile = argv[i];
- }
-
- if (argc == 1 || gmt_quick) {
- fprintf(stderr, "grdsample %s - Resample a gridded file onto a new grid\n\n", GMT_VERSION);
- fprintf(stderr, "usage: grdsample <old_grdfile> -G<new_grdfile> [-F] [-I<dx>[m|c][/<dy>[m|c]]]\n");
- fprintf(stderr, " [-L] [-N<nx/ny>] [-Q] [-R<west/east/south/north>] [-T] [-V]\n");
-
- if (gmt_quick) exit (-1);
-
- fprintf(stderr, " <old_grdfile> is data set to be resampled\n");
- fprintf(stderr, " -G sets the name of the interpolated output grdfile\n");
- fprintf(stderr, "\n\tOPTIONS:\n");
- fprintf(stderr, " -F force pixel node registration [Default is centered]\n");
- fprintf(stderr, " -I sets the grid spacing (dx, dy) for the new grid\n");
- fprintf(stderr, " -L means these are geographical grids\n");
- fprintf(stderr, " -N specifies number of columns (nx) and rows (ny) of new grid\n");
- fprintf(stderr, " -Q do quick, bilinear interpolation [Default is bicubic]\n");
- fprintf(stderr, " -R specifies a subregion [Default is old region]\n");
- fprintf(stderr, " -T Toggles between grid registration and pixel registration\n");
- explain_option ('V');
- fprintf(stderr, " One only of -N -I must be specified\n");
-
- exit (-1);
- }
-
- if (!infile) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify input file\n", gmt_program);
- error++;
- }
- if (!outfile) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -G: Must specify output file\n", gmt_program);
- error++;
- }
- if (!toggle) {
- if (grd_b.x_min != grd_b.x_max && grd_b.y_min != grd_b.y_max) area_set = TRUE;
- if (inc_set && n_set) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: Only one of -I, -N may be specified\n", gmt_program);
- error++;
- }
- if (n_set && (grd_b.nx <= 0 || grd_b.ny <= 0)) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -N: Must specify positive integers\n", gmt_program);
- error++;
- }
- if (inc_set && (grd_b.x_inc <= 0.0 || grd_b.y_inc <= 0.0)) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -I: Must specify positive increments\n", gmt_program);
- error++;
- }
- if (!(inc_set || n_set)) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR: One of -I, -N must be specified\n", gmt_program);
- error++;
- }
- }
-
- if (error) exit (-1);
-
- if (read_grd_info (infile, &grd_a)) {
- fprintf (stderr, "grdsample: Error opening file %s\n", infile);
- exit (-1);
- }
-
- if (toggle) {
- offset = !grd_a.node_offset; /* Change to the opposite of what it is */
- grd_b.nx = (offset) ? grd_a.nx - 1 : grd_a.nx + 1;
- grd_b.ny = (offset) ? grd_a.ny - 1 : grd_a.ny + 1;
- area_set = inc_set = FALSE;
- }
-
- a = (float *) memory (CNULL, (int)((grd_a.nx + 4) * (grd_a.ny + 4)), sizeof(float), "grdsample");
-
- global_grid = (fabs (grd_a.x_max - grd_a.x_min) == 360.0);
-
- if (area_set) {
- if (grd_b.y_min < grd_a.y_min || grd_b.y_max > grd_a.y_max) {
- fprintf (stderr, "grdsample: Selected region exceeds the boundaries of the grdfile!\n");
- exit (-1);
- }
- else if (!global_grid && (grd_b.x_min < grd_a.x_min || grd_b.x_max > grd_a.x_max)) {
- fprintf (stderr, "grdsample: Selected region exceeds the boundaries of the grdfile!\n");
- exit (-1);
- }
- }
-
- if (!offset && !toggle) offset = grd_a.node_offset;
- one = !offset;
- grd_b.node_offset = offset;
-
- if (!area_set) {
- grd_b.x_min = grd_a.x_min;
- grd_b.x_max = grd_a.x_max;
- grd_b.y_min = grd_a.y_min;
- grd_b.y_max = grd_a.y_max;
- }
-
- if (geo && grd_b.x_min < 0.0 && grd_b.x_max > 0.0)
- greenwich = TRUE;
- else if (geo && grd_b.x_max > 360.0) {
- greenwich = TRUE;
- grd_b.x_min -= 360.0;
- grd_b.x_max -= 360.0;
- }
- if (inc_set) {
- grd_b.nx = rint ((grd_b.x_max - grd_b.x_min) / grd_b.x_inc) + one;
- grd_b.ny = rint ((grd_b.y_max - grd_b.y_min) / grd_b.y_inc) + one;
- grd_b.x_inc = (grd_b.x_max - grd_b.x_min) / (grd_b.nx - one);
- grd_b.y_inc = (grd_b.y_max - grd_b.y_min) / (grd_b.ny - one);
- }
- else {
- grd_b.x_inc = (grd_b.x_max - grd_b.x_min) / (grd_b.nx - one);
- grd_b.y_inc = (grd_b.y_max - grd_b.y_min) / (grd_b.ny - one);
- }
-
- b = (float *) memory (CNULL, (int)(grd_b.nx * grd_b.ny), sizeof(float), "grdsample");
-
- if (gmtdefs.verbose) fprintf (stderr, "grdsample: New grid (%lg/%lg/%lg/%lg) nx = %d ny = %d dx = %lg dy = %lg\n",
- grd_b.x_min, grd_b.x_max, grd_b.y_min, grd_b.y_max, grd_b.nx, grd_b.ny, grd_b.x_inc, grd_b.y_inc);
-
- pad[0] = pad[1] = pad[2] = pad[3] = 2; /* Leave room for 2 empty boundary rows/cols */
-
- if (read_grd (infile, &grd_a, a, grd_a.x_min, grd_a.x_max, grd_a.y_min, grd_a.y_max, pad, FALSE)) {
- fprintf (stderr, "grdsample: Error reading file %s\n", infile);
- exit (-1);
- }
-
- /* Initialize bcr structure: */
-
- bcr_init (&grd_a, pad, bilinear);
-
- /* Set boundary conditions */
-
- set_bcr_boundaries (&grd_a, a);
-
- /* Precalculate longitudes */
-
- dx2 = 0.5 * grd_a.x_inc;
- dy2 = 0.5 * grd_a.y_inc;
- lon = (double *) memory (CNULL, grd_b.nx, sizeof (double), "grdsample");
- for (i = 0; i < grd_b.nx; i++) {
- lon[i] = grd_b.x_min + (i * grd_b.x_inc) + ((offset) ? dx2 : 0.0);
- if (geo && greenwich && lon[i] > 180.0) lon[i] -= 360.0;
- }
-
- for (j = ij = 0; j < grd_b.ny; j++) {
- lat = grd_b.y_max - (j * grd_b.y_inc);
- if (offset) lat -= dy2;
- for (i = 0; i < grd_b.nx; i++, ij++) b[ij] = get_bcr_z (&grd_a, lon[i], lat, a);
- }
-
- if (write_grd (outfile, &grd_b, b, 0.0, 0.0, 0.0, 0.0, pad, FALSE)) {
- fprintf (stderr, "grdsample: Error writing file %s\n", outfile);
- exit (-1);
- }
-
- free ((char *)a);
- free ((char *)b);
- free ((char *)lon);
-
- gmt_end (argc, argv);
- }
-