int main (int argc, char **argv) { GMT_LONG error = FALSE; GMT_LONG i, k, nx_old, ny_old, nx_new, ny_new, one_or_zero; GMT_LONG nm; char *grd_in, format[BUFSIZ], za[GMT_TEXT_LEN], zb[GMT_TEXT_LEN]; float *grd = NULL; double w_new = 0.0, e_new = 0.0, s_new = 0.0, n_new = 0.0; double w_old, e_old, s_old, n_old; struct GRD_HEADER header, test_header; struct GRDCUT_CTRL *Ctrl = NULL; void *New_grdcut_Ctrl (), Free_grdcut_Ctrl (struct GRDCUT_CTRL *C); argc = (int)GMT_begin (argc, argv); Ctrl = (struct GRDCUT_CTRL *) New_grdcut_Ctrl (); /* Allocate and initialize a new control structure */ grd_in = CNULL; za[0] = zb[0] = '\0'; /* Check and interpret the command line arguments */ for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch(argv[i][1]) { /* Common parameters */ case 'R': case 'V': case 'f': case '\0': error += GMT_parse_common_options (argv[i], &w_new, &e_new, &s_new, &n_new); break; case 'G': Ctrl->G.active = TRUE; Ctrl->G.file = strdup (&argv[i][2]); break; case 'Z': Ctrl->Z.active = TRUE; k = 2; if (argv[i][k] == 'n') { Ctrl->Z.mode = NAN_IS_OUTSIDE; k = 3; } if (sscanf (&argv[i][k], "%[^/]/%s", za, zb) == 2) { if (!(za[0] == '-' && za[1] == '\0')) error += GMT_verify_expectations (GMT_io.in_col_type[GMT_Z], GMT_scanf_arg (za, GMT_io.in_col_type[GMT_Z], &Ctrl->Z.min), za); if (!(zb[0] == '-' && zb[1] == '\0')) error += GMT_verify_expectations (GMT_io.in_col_type[GMT_Z], GMT_scanf_arg (zb, GMT_io.in_col_type[GMT_Z], &Ctrl->Z.max), zb); } break; default: /* Options not recognized */ error = TRUE; GMT_default_error (argv[i][1]); break; } } else grd_in = argv[i]; } if (argc == 1 || GMT_give_synopsis_and_exit) { fprintf (stderr,"grdcut %s - Extract subsets from grid files\n\n", GMT_VERSION); fprintf (stderr, "usage: grdcut <input_grd> -G<output_grd> %s [-V] [-Z[n][min/max]] [%s]\n", GMT_Rgeo_OPT, GMT_f_OPT); if (GMT_give_synopsis_and_exit) exit (EXIT_FAILURE); fprintf (stderr, "\t<input_grd> is file to extract a subset from.\n"); fprintf (stderr, "\t-G specifies output grid file.\n"); GMT_explain_option ('R'); fprintf (stderr, "\t Obviously, the WESN you specify must be within the WESN of the input file.\n"); fprintf (stderr, "\t If in doubt, run grdinfo first and check range of old file.\n"); fprintf (stderr, "\n\tOPTIONS:\n"); GMT_explain_option ('V'); fprintf (stderr, "\t-Z Specify a range and determine the corresponding rectangular region so that\n"); fprintf (stderr, "\t all values outside this region are outside the range [-inf/+inf].\n"); fprintf (stderr, "\t Use -Zn to consider NaNs outside as well [Default just ignores NaNs].\n"); GMT_explain_option ('f'); exit (EXIT_FAILURE); } /* Check that the options selected make sense */ if ((project_info.region_supplied + Ctrl->Z.active) != 1) { fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify either the -R or the -Z options\n", GMT_program); error++; } if (!Ctrl->G.file) { fprintf (stderr, "%s: GMT SYNTAX ERROR -G option: Must specify output file\n", GMT_program); error++; } if (!grd_in) { fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify input file\n", GMT_program); error++; } if (error) exit (EXIT_FAILURE); GMT_err_fail (GMT_read_grd_info (grd_in, &header), grd_in); if (Ctrl->Z.active) { /* Must determine new region via -Z */ GMT_LONG i0, i1, j0, j1, j, ij; nm = GMT_get_nm (header.nx, header.ny); grd = (float *) GMT_memory (VNULL, (size_t)nm, sizeof (float), GMT_program); GMT_err_fail (GMT_read_grd (grd_in, &header, grd, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE), grd_in); for (i = 0, i0 = -1; i0 == -1 && i < header.nx; i++) { /* Scan from xmin towards xmax */ for (j = 0, ij = i; i0 == -1 && j < header.ny; j++, ij += header.ny) { if (GMT_is_fnan (grd[ij])) { if (Ctrl->Z.mode == NAN_IS_OUTSIDE) i0 = i; /* Must stop since this value defines the inner box */ } else if (grd[ij] >= Ctrl->Z.min && grd[ij] <= Ctrl->Z.max) i0 = i; } } if (i0 == -1) { fprintf (stderr, "%s: The sub-region is empty - no file written\n", GMT_program); GMT_free ((void *)grd); exit (EXIT_FAILURE); } for (i = header.nx-1, i1 = -1; i1 == -1 && i > i0; i--) { /* Scan from xmax towards xmin */ for (j = 0, ij = i; i1 == -1 && j < header.ny; j++, ij += header.ny) { if (GMT_is_fnan (grd[ij])) { if (Ctrl->Z.mode == NAN_IS_INSIDE) i1 = i; /* Must stop since this value defines the inner box */ } else if (grd[ij] >= Ctrl->Z.min && grd[ij] <= Ctrl->Z.max) i1 = i; } } for (j = 0, j0 = -1; j0 == -1 && j < header.ny; j++) { /* Scan from ymin towards ymax */ for (i = i0, ij = GMT_IJ(j,i0,header.nx); j0 == -1 && i < i1; i++, ij++) { if (GMT_is_fnan (grd[ij])) { if (Ctrl->Z.mode == NAN_IS_INSIDE) j0 = j; /* Must stop since this value defines the inner box */ } else if (grd[ij] >= Ctrl->Z.min && grd[ij] <= Ctrl->Z.max) j0 = j; } } for (j = header.ny-1, j1 = -1; j1 == -1 && j >= j0; j--) { /* Scan from ymax towards ymin */ for (i = i0, ij = GMT_IJ(j,i0,header.nx); j1 == -1 && i < i1; i++, ij++) { if (GMT_is_fnan (grd[ij])) { if (Ctrl->Z.mode == NAN_IS_INSIDE) j1 = j; /* Must stop since this value defines the inner box */ } else if (grd[ij] >= Ctrl->Z.min && grd[ij] <= Ctrl->Z.max) j1 = j; } } if (i0 == 0 && j0 == 0 && i1 == (header.nx-1) && j1 == (header.ny-1)) { fprintf (stderr, "%s: Your -Z limits produced no subset - output grid is identical to input grid\n", GMT_program); w_new = header.x_min; e_new = header.x_max; s_new = header.y_min; n_new = header.y_max; } else { /* Adjust boundaries inwards */ w_new = header.x_min + i0 * header.x_inc; e_new = header.x_max - (header.nx - 1 - i1) * header.x_inc; s_new = header.y_min + (header.ny - 1 - j1) * header.y_inc; n_new = header.y_max - j0 * header.y_inc; } GMT_free ((void *)grd); } if (s_new < header.y_min || s_new > header.y_max) error = TRUE; if (n_new < header.y_min || n_new > header.y_max) error = TRUE; if (GMT_io.in_col_type[GMT_X] == GMT_IS_LON) { /* Geographic data */ if (w_new < header.x_min && e_new < header.x_min) { header.x_min -= 360.0; header.x_max -= 360.0; } if (w_new > header.x_max && e_new > header.x_max) { header.x_min += 360.0; header.x_max += 360.0; } if (!GMT_grd_is_global (&header) && (w_new < header.x_min || e_new > header.x_max)) error = TRUE; } else if (w_new < header.x_min || e_new > header.x_max) error = TRUE; if (error) { fprintf (stderr, "%s: Subset exceeds data domain!\n", GMT_program); exit (EXIT_FAILURE); } /* Make sure output grid is kosher */ GMT_adjust_loose_wesn (&w_new, &e_new, &s_new, &n_new, &header); test_header.x_min = w_new; test_header.x_max = e_new; test_header.x_inc = header.x_inc; test_header.y_min = s_new; test_header.y_max = n_new; test_header.y_inc = header.y_inc; GMT_err_fail (GMT_grd_RI_verify (&test_header, 1), Ctrl->G.file); /* OK, so far so good. Check if new wesn differs from old wesn by integer dx/dy */ if (GMT_minmaxinc_verify (header.x_min, w_new, header.x_inc, GMT_SMALL) == 1) { fprintf (stderr, "%s: Old and new x_min do not differ by N * dx\n", GMT_program); exit (EXIT_FAILURE); } if (GMT_minmaxinc_verify (e_new, header.x_max, header.x_inc, GMT_SMALL) == 1) { fprintf (stderr, "%s: Old and new x_max do not differ by N * dx\n", GMT_program); exit (EXIT_FAILURE); } if (GMT_minmaxinc_verify (header.y_min, s_new, header.y_inc, GMT_SMALL) == 1) { fprintf (stderr, "%s: Old and new y_min do not differ by N * dy\n", GMT_program); exit (EXIT_FAILURE); } if (GMT_minmaxinc_verify (n_new, header.y_max, header.y_inc, GMT_SMALL) == 1) { fprintf (stderr, "%s: Old and new y_max do not differ by N * dy\n", GMT_program); exit (EXIT_FAILURE); } GMT_grd_init (&header, argc, argv, TRUE); w_old = header.x_min; e_old = header.x_max; s_old = header.y_min; n_old = header.y_max; nx_old = header.nx; ny_old = header.ny; one_or_zero = (header.node_offset) ? 0 : 1; nx_new = irint ((e_new - w_new) / header.x_inc) + one_or_zero; ny_new = irint ((n_new - s_new) / header.y_inc) + one_or_zero; nm = GMT_get_nm (nx_new, ny_new); grd = (float *) GMT_memory (VNULL, (size_t)nm, sizeof (float), GMT_program); GMT_err_fail (GMT_read_grd (grd_in, &header, grd, w_new, e_new, s_new, n_new, GMT_pad, FALSE), grd_in); if (gmtdefs.verbose) { sprintf (format, "\t%s\t%s\t%s\t%s\t%s\t%s\t%%ld\t%%ld\n", gmtdefs.d_format, gmtdefs.d_format, gmtdefs.d_format, gmtdefs.d_format, gmtdefs.d_format, gmtdefs.d_format); fprintf (stderr, "%s: File spec:\tW E S N dx dy nx ny:\n", GMT_program); fprintf (stderr, "%s: Old:", GMT_program); fprintf (stderr, format, w_old, e_old, s_old, n_old, header.x_inc, header.y_inc, nx_old, ny_old); fprintf (stderr, "%s: New:", GMT_program); fprintf (stderr, format, w_new, e_new, s_new, n_new, header.x_inc, header.y_inc, nx_new, ny_new); } GMT_err_fail (GMT_write_grd (Ctrl->G.file, &header, grd, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE), Ctrl->G.file); GMT_free ((void *) grd); Free_grdcut_Ctrl (Ctrl); /* Deallocate control structure */ GMT_end (argc, argv); exit (EXIT_SUCCESS); }
int read_esri_info (struct GMT_CTRL *GMT, FILE *fp, struct GMT_GRID_HEADER *header) { int c; char record[GMT_BUFSIZ]; FILE *fp2 = NULL, *fpBAK = NULL; header->registration = GMT_GRID_NODE_REG; header->z_scale_factor = 1.0; header->z_add_offset = 0.0; if (header->flags[0] == 'M' || header->flags[0] == 'I') { /* We are dealing with a ESRI .hdr file */ int error; if ((error = read_esri_info_hdr (GMT, header))) /* Continue the work someplace else */ return (error); else return (GMT_NOERROR); } else if (header->flags[0] == 'B' && header->flags[1] == '0') { /* A GTOPO30 or SRTM30 file */ size_t len = strlen (header->title); header->inc[GMT_X] = header->inc[GMT_Y] = 30.0 * GMT_SEC2DEG; /* 30 arc seconds */ header->wesn[YHI] = atof (&header->title[len-2]); if ( header->title[len-3] == 'S' || header->title[len-3] == 's' ) header->wesn[YHI] *= -1; c = header->title[len-3]; header->title[len-3] = '\0'; header->wesn[XLO] = atof (&header->title[len-6]); header->title[len-3] = (char)c; /* Reset because this function is called at least twice */ if ( header->title[len-7] == 'W' || header->title[len-7] == 'w' ) header->wesn[XLO] *= -1; if (header->wesn[YHI] > -60) { header->wesn[YLO] = header->wesn[YHI] - 50; header->wesn[XHI] = header->wesn[XLO] + 40; header->nx = 4800; header->ny = 6000; } else { /* Antarctica tiles cover 30 degrees of latitude and 60 degrees of longitude each have 3,600 rows and 7,200 columns */ header->wesn[YLO] = -90; header->wesn[XHI] = header->wesn[XLO] + 60; header->nx = 7200; header->ny = 3600; } header->registration = GMT_GRID_PIXEL_REG; GMT_set_geographic (GMT, GMT_IN); gmt_grd_set_units (GMT, header); /* Different sign of NaN value between GTOPO30 and SRTM30 grids */ if (strstr (header->name, ".DEM") || strstr (header->name, ".dem")) header->nan_value = -9999.0f; else header->nan_value = 9999.0f; header->bits = 16; /* Temp pocket to store number of bits */ return (GMT_NOERROR); } else if (header->flags[0] == 'B' && header->flags[1] == '1') { /* A SRTM3 or SRTM1 file */ size_t len = strlen (header->title); struct stat F; header->wesn[XLO] = atof (&header->title[len-3]); if ( header->title[len-4] == 'W' || header->title[len-4] == 'W' ) header->wesn[XLO] *= -1; c = header->title[len-4]; header->title[len-4] = '\0'; header->wesn[YLO] = atof (&header->title[len-6]); header->title[len-4] = (char)c; /* Reset because this function is called at least twice */ if ( header->title[len-7] == 'S' || header->title[len-7] == 's' ) header->wesn[YLO] *= -1; header->wesn[YHI] = header->wesn[YLO] + 1; header->wesn[XHI] = header->wesn[XLO] + 1; header->nan_value = -32768.0f; header->bits = 16; /* Temp pocket to store number of bits */ stat (header->name, &F); /* Must finally find out if it is a 1 or 3 arcseconds file */ if (F.st_size < 3e6) { /* Actually the true size is 2884802 */ header->inc[GMT_X] = header->inc[GMT_Y] = 3.0 * GMT_SEC2DEG; /* 3 arc seconds */ strcpy (header->remark, "Assumed to be a SRTM3 tile"); } else { header->inc[GMT_X] = header->inc[GMT_Y] = 1.0 * GMT_SEC2DEG; /* 1 arc second */ strcpy (header->remark, "Assumed to be a SRTM1 tile"); } GMT_set_geographic (GMT, GMT_IN); gmt_grd_set_units (GMT, header); return (GMT_NOERROR); } else if ((header->flags[0] == 'L' || header->flags[0] == 'B') && header->flags[1] == '2') { /* A Arc/Info BINARY file */ if ((fp2 = GMT_fopen (GMT, header->title, "r")) == NULL) return (GMT_GRDIO_OPEN_FAILED); /* To use the same parsing header code as in the ASCII file case where header and data are in the same file, we will swap the file pointers and undo the swap at the end of this function */ fpBAK = fp; /* Copy of the input argument '*fp' */ fp = fp2; } GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %d", &header->nx) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding ncols record\n"); return (GMT_GRDIO_READ_FAILED); } GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %d", &header->ny) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding nrows record\n"); return (GMT_GRDIO_READ_FAILED); } GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %lf", &header->wesn[XLO]) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding xll record\n"); return (GMT_GRDIO_READ_FAILED); } GMT_str_tolower (record); if (!strncmp (record, "xllcorner", 9U)) header->registration = GMT_GRID_PIXEL_REG; /* Pixel grid */ GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %lf", &header->wesn[YLO]) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding yll record\n"); return (GMT_GRDIO_READ_FAILED); } GMT_str_tolower (record); if (!strncmp (record, "yllcorner", 9U)) header->registration = GMT_GRID_PIXEL_REG; /* Pixel grid */ GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %lf", &header->inc[GMT_X]) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding cellsize record\n"); return (GMT_GRDIO_READ_FAILED); } /* Handle the optional nodata_value record */ c = fgetc (fp); /* Get first char of next line... */ ungetc (c, fp); /* ...and put it back where it came from */ if (c == 'n' || c == 'N') { /* Assume this is a nodata_value record since we found an 'n|N' */ GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %f", &header->nan_value) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding nan_value_value record\n"); return (GMT_GRDIO_READ_FAILED); } } header->inc[GMT_Y] = header->inc[GMT_X]; header->wesn[XHI] = header->wesn[XLO] + (header->nx - 1 + header->registration) * header->inc[GMT_X]; header->wesn[YHI] = header->wesn[YLO] + (header->ny - 1 + header->registration) * header->inc[GMT_Y]; GMT_err_fail (GMT, GMT_grd_RI_verify (GMT, header, 1), header->name); if (fpBAK) { /* Case of Arc/Info binary file with a separate header file. We still have things to do. */ char tmp[16]; /* Read an extra record containing the endianness info */ GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %s", tmp) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info BINARY Grid: Error decoding endianness record\n"); return (GMT_GRDIO_READ_FAILED); } header->flags[0] = (tmp[0] == 'L') ? 'L' : 'B'; header->bits = 32; /* Those float binary files */ /* Ok, now as mentioned above undo the file pointer swapping (point again to data file) */ fp = fpBAK; GMT_fclose (GMT, fp2); } return (GMT_NOERROR); }
int main (int argc, char **argv) { GMT_LONG i, j, ij, ij_f, n = 0; GMT_LONG n_expected_fields, n_args, m, n_fields, fno, n_files = 0; size_t n_alloc = GMT_CHUNK, nm; GMT_LONG error = FALSE, nofile = TRUE, done = FALSE; double sx, sy, cx, cy, w_min, w_max, sf = 1.0; double *xx = NULL, *yy = NULL, *zz = NULL, *ww = NULL, *surfd = NULL, *in = NULL; float *surf = NULL; char line[BUFSIZ], *not_used = NULL; FILE *fp = NULL; struct SPHINTERPOLATE_CTRL *Ctrl = NULL; struct GRD_HEADER h; void *New_sphinterpolate_Ctrl (), Free_sphinterpolate_Ctrl (struct SPHINTERPOLATE_CTRL *C); GMT_LONG get_args (char *arg, double pars[], char *msg); argc = (int)GMT_begin (argc, argv); Ctrl = (struct SPHINTERPOLATE_CTRL *)New_sphinterpolate_Ctrl (); /* Allocate and initialize a new control structure */ GMT_grd_init (&h, argc, argv, FALSE); for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { /* Common parameters */ case 'H': case 'M': case 'R': case 'V': case ':': case 'b': case 'm': case '\0': error += GMT_parse_common_options (argv[i], &h.x_min, &h.x_max, &h.y_min, &h.y_max); break; /* Supplemental parameters */ case 'F': Ctrl->F.active = TRUE; break; case 'G': Ctrl->G.active = TRUE; Ctrl->G.file = strdup (&argv[i][2]); break; case 'I': Ctrl->I.active = TRUE; if (GMT_getinc (&argv[i][2], &Ctrl->I.xinc, &Ctrl->I.yinc)) { GMT_inc_syntax ('I', 1); error = TRUE; } break; case 'Q': Ctrl->Q.active = TRUE; switch (argv[i][2]) { case '0': /* Linear */ Ctrl->Q.mode = 0; break; case '1': Ctrl->Q.mode = 1; break; case '2': Ctrl->Q.mode = 2; if (argv[i][3] == '/') { /* Gave optional n/m/dgmx */ if ((m = get_args (&argv[i][4], Ctrl->Q.value, "-Q3/N[/M[/U]]")) < 0) error = TRUE; } break; case '3': Ctrl->Q.mode = 3; if (argv[i][3] == '/') { /* Gave optional e/sm/niter */ if ((m = get_args (&argv[i][4], Ctrl->Q.value, "-Q3/E[/U[/niter]]")) < 0) error = TRUE; } break; default: error = TRUE; fprintf (stderr, "GMT ERROR %s: -%c Mode must be in 0-3 range\n", GMT_program, argv[i][1]); break; } break; case 'T': Ctrl->T.active = TRUE; break; case 'Z': Ctrl->Z.active = TRUE; break; default: error = TRUE; GMT_default_error (argv[i][1]); break; } } else n_files++; } if (argc == 1 || GMT_give_synopsis_and_exit) { fprintf (stderr, "sphinterpolate %s - Spherical gridding in tension of data on a sphere\n", GMT_VERSION); fprintf (stderr, "==> The hard work is done by algorithms 772 (STRIPACK) & 773 (SSRFPACK) by R. J. Renka [1997] <==\n\n"); fprintf (stderr, "usage: sphinterpolate [<infiles>] -G<grdfile> %s [-F] [%s]\n", GMT_I_OPT, GMT_H_OPT); fprintf (stderr, "\t[-Q<mode>][/args] [-T] [-V] [-Z] [%s] [%s] [%s]\n\n", GMT_t_OPT, GMT_b_OPT, GMT_m_OPT); fprintf (stderr, "\t-G Specify file name for the final gridded solution.\n"); GMT_inc_syntax ('I', 0); if (GMT_give_synopsis_and_exit) exit (EXIT_FAILURE); fprintf (stderr, "\n\tOPTIONS:\n"); fprintf (stderr, "\tinfiles (in ASCII) has 3 or more columns. If no file(s) is given, standard input is read.\n"); fprintf (stderr, "\t-F Force pixel registration for output grid [Default is gridline orientation]\n"); GMT_explain_option ('H'); fprintf (stderr, "\t-Q Select tension factors to achive the following [Default is no tension]:\n"); fprintf (stderr, "\t 0: Piecewise linear interpolation ; no tension [Default]\n"); fprintf (stderr, "\t 1: Smooth interpolation with local gradient estimates.\n"); fprintf (stderr, "\t 2: Smooth interpolation with global gradient estimates and tension. Optionally append /N/M/U:\n"); fprintf (stderr, "\t N = Number of iterations to converge solutions for gradients and variable tensions (-T only) [3]\n"); fprintf (stderr, "\t M = Number of Gauss-Seidel iterations when determining gradients [10]\n"); fprintf (stderr, "\t U = Maximum change in a gradient at the last iteration [0.01]\n"); fprintf (stderr, "\t 3: Smoothing. Optionally append /E/U/N, where\n"); fprintf (stderr, "\t E = Expected squared error in a typical (scaled) data value [0.01]\n"); fprintf (stderr, "\t U = Upper bound on weighted sum of squares of deviations from data [npoints]\n"); fprintf (stderr, "\t N = Number of iterations to converge solutions for gradients and variable tensions (-T only) [3]\n"); GMT_explain_option ('R'); fprintf (stderr, "\t If no region is specified we default to the entire world [-Rg]\n"); fprintf (stderr, "\t-T Use variable tension (ignored for -Q0) [constant]\n"); GMT_explain_option ('V'); fprintf (stderr, "\t-Z Scale data by 1/(max-min) prior to gridding [no scaling]\n"); GMT_explain_option (':'); GMT_explain_option ('i'); GMT_explain_option ('n'); fprintf (stderr, "\t Default is 3 input columns\n"); GMT_explain_option ('m'); GMT_explain_option ('.'); exit (EXIT_FAILURE); } GMT_check_lattice (&Ctrl->I.xinc, &Ctrl->I.yinc, &Ctrl->F.active, &Ctrl->I.active); if (GMT_io.binary[GMT_IN] && GMT_io.io_header[GMT_IN]) { fprintf (stderr, "%s: GMT SYNTAX ERROR. Binary input data cannot have header -H\n", GMT_program); error++; } if (GMT_io.binary[GMT_IN] && GMT_io.ncol[GMT_IN] == 0) GMT_io.ncol[GMT_IN] = 3; if (GMT_io.binary[GMT_IN] && GMT_io.ncol[GMT_IN] < 3) { fprintf (stderr, "%s: GMT SYNTAX ERROR. Binary input data (-bi) must have at least 3 columns\n", GMT_program); error++; } if (Ctrl->I.xinc <= 0.0 || Ctrl->I.yinc <= 0.0) { fprintf (stderr, "%s: GMT SYNTAX ERROR -I option. Must specify positive increment(s)\n", GMT_program); error = TRUE; } if (!Ctrl->G.file) { fprintf (stderr, "%s: GMT SYNTAX ERROR -G: Must specify output file\n", GMT_program); error = TRUE; } if (Ctrl->Q.mode < 0 || Ctrl->Q.mode > 3) { fprintf (stderr, "%s: GMT SYNTAX ERROR -T: Must specify a mode in the 0-3 range\n", GMT_program); error = TRUE; } if (error) exit (EXIT_FAILURE); if (GMT_io.binary[GMT_IN] && gmtdefs.verbose) { char *type[2] = {"double", "single"}; fprintf (stderr, "%s: Expects %ld-column %s-precision binary data\n", GMT_program, GMT_io.ncol[GMT_IN], type[GMT_io.single_precision[GMT_IN]]); } if (!project_info.region_supplied) { /* Default is global region */ h.x_min = 0.0; h.x_max = 360.0; h.y_min = -90.0; h.y_max = 90.0; } #ifdef SET_IO_MODE GMT_setmode (GMT_OUT); #endif /* Now we are ready to take on some input values */ if (n_files > 0) nofile = FALSE; else n_files = 1; n_args = (argc > 1) ? argc : 3; n_expected_fields = (GMT_io.ncol[GMT_IN]) ? GMT_io.ncol[GMT_IN] : 3; n_alloc = GMT_CHUNK; xx = (double *) GMT_memory (VNULL, (size_t)n_alloc, sizeof (double), GMT_program); yy = (double *) GMT_memory (VNULL, (size_t)n_alloc, sizeof (double), GMT_program); zz = (double *) GMT_memory (VNULL, (size_t)n_alloc, sizeof (double), GMT_program); ww = (double *) GMT_memory (VNULL, (size_t)n_alloc, sizeof (double), GMT_program); n = 0; w_min = DBL_MAX; w_max = -DBL_MAX; for (fno = 1; !done && fno < n_args; fno++) { /* Loop over input files, if any */ if (!nofile && argv[fno][0] == '-') continue; if (nofile) { /* Just read standard input */ fp = GMT_stdin; done = TRUE; #ifdef SET_IO_MODE GMT_setmode (GMT_IN); #endif } else if ((fp = GMT_fopen (argv[fno], GMT_io.r_mode)) == NULL) { fprintf (stderr, "%s: Cannot open file %s\n", GMT_program, argv[fno]); continue; } if (!nofile && gmtdefs.verbose) fprintf (stderr, "%s: Reading file %s\n", GMT_program, argv[fno]); if (GMT_io.io_header[GMT_IN]) for (i = 0; i < GMT_io.n_header_recs; i++) not_used = GMT_fgets (line, BUFSIZ, fp); while ((n_fields = GMT_input (fp, &n_expected_fields, &in)) >= 0 && !(GMT_io.status & GMT_IO_EOF)) { /* Not yet EOF */ if (GMT_io.status & GMT_IO_MISMATCH) { fprintf (stderr, "%s: Mismatch between actual (%ld) and expected (%ld) fields near line %ld\n", GMT_program, n_fields, n_expected_fields, n); exit (EXIT_FAILURE); } while (GMT_io.status & GMT_IO_SEGMENT_HEADER) { /* Segment header, get next record */ n_fields = GMT_input (fp, &n_expected_fields, &in); } sincosd (in[GMT_Y], &sy, &cy); sincosd (in[GMT_X], &sx, &cx); xx[n] = cy * cx; yy[n] = cy * sx; zz[n] = sy; ww[n] = in[GMT_Z]; if (Ctrl->Z.active) { if (ww[n] < w_min) w_min = ww[n]; if (ww[n] > w_max) w_max = ww[n]; } n++; if (n == (int)n_alloc) { /* Get more memory */ n_alloc <<= 1; xx = (double *) GMT_memory ((void *)xx, (size_t)n_alloc, sizeof (double), GMT_program); yy = (double *) GMT_memory ((void *)yy, (size_t)n_alloc, sizeof (double), GMT_program); zz = (double *) GMT_memory ((void *)zz, (size_t)n_alloc, sizeof (double), GMT_program); ww = (double *) GMT_memory ((void *)ww, (size_t)n_alloc, sizeof (double), GMT_program); } } if (fp != GMT_stdin) GMT_fclose (fp); } xx = (double *) GMT_memory ((void *)xx, (size_t)n, sizeof (double), GMT_program); yy = (double *) GMT_memory ((void *)yy, (size_t)n, sizeof (double), GMT_program); zz = (double *) GMT_memory ((void *)zz, (size_t)n, sizeof (double), GMT_program); ww = (double *) GMT_memory ((void *)ww, (size_t)n, sizeof (double), GMT_program); if (gmtdefs.verbose) fprintf (stderr, "%s: Do Delaunay triangulation using %ld points\n", GMT_program, n); if (Ctrl->Z.active && w_max > w_min) { /* Scale the data */ sf = 1.0 / (w_max - w_min); for (i = 0; i < n; i++) ww[i] *= sf; } /* Set up output grid */ if (gmtdefs.verbose) fprintf (stderr, "%s: Evaluate output grid\n", GMT_program); h.node_offset = (int)Ctrl->F.active; h.x_inc = Ctrl->I.xinc; h.y_inc = Ctrl->I.yinc; GMT_RI_prepare (&h); /* Ensure -R -I consistency and set nx, ny */ GMT_err_fail (GMT_grd_RI_verify (&h, 1), Ctrl->G.file); h.xy_off = 0.5 * h.node_offset; nm = GMT_get_nm (h.nx, h.ny); surfd = (double *) GMT_memory (VNULL, (size_t)nm, sizeof(double), GMT_program); /* Do the interpolation */ ssrfpack_grid (xx, yy, zz, ww, n, Ctrl->Q.mode, Ctrl->Q.value, Ctrl->T.active, gmtdefs.verbose, &h, surfd); GMT_free ((void *)xx); GMT_free ((void *)yy); GMT_free ((void *)zz); GMT_free ((void *)ww); /* Convert the doubles to float and unto the Fortran transpose order */ sf = (w_max - w_min); surf = (float *) GMT_memory (VNULL, (size_t)nm, sizeof(float), GMT_program); for (j = ij = 0; j < h.ny; j++) { for (i = 0; i < h.nx; i++, ij++) { ij_f = i * h.ny + j; surf[ij] = (float)surfd[ij_f]; if (Ctrl->Z.active) surf[ij] *= (float)sf; } } GMT_free ((void *)surfd); /* Write solution */ GMT_err_fail (GMT_write_grd (Ctrl->G.file, &h, surf, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE), Ctrl->G.file); /* Free variables */ GMT_free ((void *)surf); if (gmtdefs.verbose) fprintf (stderr, "%s: Done!\n", GMT_program); Free_sphinterpolate_Ctrl (Ctrl); /* Deallocate control structure */ GMT_end (argc, argv); exit (EXIT_SUCCESS); }
int read_esri_info_hdr (struct GMT_CTRL *GMT, struct GMT_GRID_HEADER *header) { /* Parse the contents of a .HDR file */ int nB; char record[GMT_BUFSIZ]; FILE *fp = NULL; if ((fp = GMT_fopen (GMT, header->title, "r")) == NULL) return (GMT_GRDIO_OPEN_FAILED); header->registration = GMT_GRID_NODE_REG; header->z_scale_factor = 1.0; header->z_add_offset = 0.0; GMT_fgets (GMT, record, GMT_BUFSIZ, fp); /* BYTEORDER */ GMT_fgets (GMT, record, GMT_BUFSIZ, fp); /* LAYOUT */ GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %d", &header->ny) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding NROWS record\n"); return (GMT_GRDIO_READ_FAILED); } GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %d", &header->nx) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding NCOLS record\n"); return (GMT_GRDIO_READ_FAILED); } GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %d", &nB) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding NBANDS record\n"); return (GMT_GRDIO_READ_FAILED); } if (nB != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Cannot read file with number of Bands != 1 \n"); return (GMT_GRDIO_READ_FAILED); } GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %d", &header->bits) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding NBITS record\n"); return (GMT_GRDIO_READ_FAILED); } if ( header->bits != 16 && header->bits != 32 ) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: This data type (%d bits) is not supported\n", header->bits); return (GMT_GRDIO_READ_FAILED); } GMT_fgets (GMT, record, GMT_BUFSIZ, fp); /* BANDROWBYTES */ GMT_fgets (GMT, record, GMT_BUFSIZ, fp); /* TOTALROWBYTES */ GMT_fgets (GMT, record, GMT_BUFSIZ, fp); /* BANDGAPBYTES */ GMT_fgets (GMT, record, GMT_BUFSIZ, fp); while (strncmp (record, "NODATA", 4) ) /* Keep reading till find this keyword */ GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %f", &header->nan_value) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding nan_value_value record\n"); return (GMT_GRDIO_READ_FAILED); } GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %lf", &header->wesn[XLO]) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding ULXMAP record\n"); return (GMT_GRDIO_READ_FAILED); } GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %lf", &header->wesn[YHI]) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding ULYMAP record\n"); return (GMT_GRDIO_READ_FAILED); } GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %lf", &header->inc[GMT_X]) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding XDIM record\n"); return (GMT_GRDIO_READ_FAILED); } GMT_fgets (GMT, record, GMT_BUFSIZ, fp); if (sscanf (record, "%*s %lf", &header->inc[GMT_Y]) != 1) { GMT_Report (GMT->parent, GMT_MSG_NORMAL, "Arc/Info ASCII Grid: Error decoding YDIM record\n"); return (GMT_GRDIO_READ_FAILED); } GMT_fclose (GMT, fp); header->wesn[XHI] = header->wesn[XLO] + (header->nx - 1 + header->registration) * header->inc[GMT_X]; header->wesn[YLO] = header->wesn[YHI] - (header->ny - 1 + header->registration) * header->inc[GMT_Y]; GMT_err_fail (GMT, GMT_grd_RI_verify (GMT, header, 1), header->name); return (GMT_NOERROR); }