home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------------------------
- * The GMT-system: @(#)xyz2grd.c 2.23 4/28/95
- *
- * Copyright (c) 1991-1995 by P. Wessel and W. H. F. Smith
- * See README file for copying and redistribution conditions.
- *--------------------------------------------------------------------*/
- /*
- * xyz2grd reads a xyz file from standard input and creates the
- * corresponding grd-file. The input file does not have to be
- * sorted. xyz2grd will report if some nodes are missing. nx and
- * ny are computed as:
- * nx = rint((east-west)/dx) + 1, ny = rint((north-south)/dy) + 1
- *
- * Author: Paul Wessel
- * Date: 3-JAN-1991-1995
- * Version: 2.0 Based on old v1.x
- */
-
- #include "gmt.h"
-
- int *flag;
- float *a;
-
- main (argc, argv)
- int argc;
- char **argv; {
- int error = FALSE, got_input = FALSE, pixel = FALSE, z_only = FALSE, more, binary = FALSE, skip;
- int single_precision = FALSE, xy_units = TRUE;
-
- int i, ij, x, y, z, nm, n_read = 0, n_filled = 0, n_used = 0, one_or_zero, dummy[4];
- int n_empty = 0, n_stuffed = 0, n_bad = 0, entry, n_in, n_fields;
-
- double w, e, s, n, dx = 0.0, dy = 0.0, *in, no_data;
- double off, idx, idy;
-
- char *grdfile, line[512], input[512], *ptr;
-
- FILE *fpi = NULL;
-
- struct GRD_HEADER grd;
-
- grdfile = CNULL;
- input[0] = 0;
- w = e = s = n = 0.0;
- dummy[0] = dummy[1] = dummy[2] = dummy[3] = 0;
-
- argc = gmt_begin (argc, argv);
-
- no_data = gmt_NaN;
-
- for (i = 1; i < argc; i++) {
- if (argv[i][0] == '-') {
- switch (argv[i][1]) {
- /* Common parameters */
-
- case 'H':
- case 'R':
- case 'V':
- case ':':
- case '\0':
- error += get_common_args (argv[i], &w, &e, &s, &n);
- break;
-
- case 'b':
- single_precision = !(argv[i][strlen(argv[i])-1] == 'd');
- binary = TRUE;
- break;
- case 'D':
- strcpy (input, &argv[i][2]);
- got_input = TRUE;
- break;
- case 'F':
- pixel = TRUE;
- break;
- case 'G':
- grdfile = &argv[i][2];
- break;
- case 'I':
- gmt_getinc (&argv[i][2], &dx, &dy);
- break;
- case 'L':
- xy_units = FALSE;
- break;
- case 'N':
- if (!argv[i][2]) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -N option: Must specify value or NaN\n", gmt_program);
- error++;
- }
- else
- no_data = (!strcmp (&argv[i][2], "NaN")) ? gmt_NaN : atof (&argv[i][2]);
- break;
- case 'Z':
- z_only = TRUE;
- break;
- default:
- error = TRUE;
- gmt_default_error (argv[i][1]);
- break;
- }
- }
- else if ((fpi = fopen (argv[i], "r")) == NULL) {
- fprintf (stderr, "xyz2grd: Cannot find ascii file %s\n", argv[i]);
- exit (-1);
- }
- }
-
- if (argc == 1 || gmt_quick) {
- fprintf (stderr, "xyz2grd %s - Converting an ASCII xyz-file to a netCDF grdfile\n\n", GMT_VERSION);
- fprintf (stderr, "usage: xyz2grd [<xyzfile>] -G<grdfile> -I<dx[m|c]>[/<dy[m|c]>] -R<west/east/south/north>\n");
- fprintf (stderr, " [-D<xunit/yunit/zunit/scale/offset/title/remark>] [-F] [-H] [-L] [-N<nodata>] [-V] [-Z] [-:] [-b[d]]\n");
-
- if (gmt_quick) exit (-1);
-
- fprintf (stderr, " xyzfile is a 3-column ascii file [or standard input] with x,y,z values\n");
- fprintf (stderr, " -G to name the output grdfile.\n");
- fprintf (stderr, " -I specifies grid size(s). Append m [or c] to <dx> and/or <dy> for minutes [or seconds]\n");
- explain_option ('R');
- fprintf (stderr, "\n\tOPTIONS:\n");
- fprintf (stderr, " -D to enter information. Specify '=' to get default value\n");
- fprintf (stderr, " -F will force pixel registration [Default is grid registration]\n");
- explain_option ('H');
- fprintf (stderr, " -L means that x is longitude\n");
- fprintf (stderr, " -N set value for nodes without data [Default is NaN]\n");
- explain_option ('V');
- fprintf (stderr, " -Z Input data is z-array in scanline orientation (no x,y pair)\n");
- fprintf (stderr, " This assumes all nodes have data values.\n");
- explain_option (':');
- fprintf (stderr, " -b Input data is binary [Default is ascii].\n");
- fprintf (stderr, "\t Append d for double precision [Default is single precision].\n"); 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 (dx <= 0.0 || dy <= 0.0) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR -I option. Must specify positive increment(s)\n", gmt_program);
- error++;
- }
- if (!grdfile) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR option -G: Must specify output file\n", gmt_program);
- error++;
- }
- if (binary && gmtdefs.io_header) {
- fprintf (stderr, "%s: GMT SYNTAX ERROR. Binary input data cannot have header -H\n", gmt_program);
- error++;
- }
-
- if (error) exit (-1);
-
- if (binary) gmt_input = (single_precision) ? bin_float_input : bin_double_input;
-
- if (fpi == NULL) fpi = stdin;
-
- grd_init (&grd, argc, argv, FALSE);
-
- /* Decode grd information given, if any */
-
- if (got_input) {
- for (i = 0; input[i]; i++) if (input[i] == '_') input[i] = ' ';
- ptr = strtok (input, "/");
- entry = 0;
- while (ptr) {
- switch (entry) {
- case 0:
- if (ptr[0] != '=') strcpy (grd.x_units, ptr);
- break;
- case 1:
- if (ptr[0] != '=') strcpy (grd.y_units, ptr);
- break;
- case 2:
- if (ptr[0] != '=') strcpy (grd.z_units, ptr);
- break;
- case 3:
- if (ptr[0] != '=') grd.z_scale_factor = atof (ptr);
- break;
- case 4:
- if (ptr[0] != '=') grd.z_add_offset = atof (ptr);
- break;
- case 5:
- if (ptr[0] != '=') strcpy (grd.title, ptr);
- break;
- case 6:
- if (ptr[0] != '=') strcpy (grd.remark, ptr);
- break;
- default:
- break;
- }
- ptr = strtok (CNULL, "/");
- entry++;
- }
- }
-
- if (pixel) {
- grd.node_offset = 1;
- one_or_zero = 0;
- off = 0.0;
- }
- else {
- grd.node_offset = 0;
- one_or_zero = 1;
- off = 0.5;
- }
-
- grd.nx = rint ((e-w)/dx) + one_or_zero;
- grd.ny = rint ((n-s)/dy) + one_or_zero;
- grd.x_min = w; grd.x_max = e;
- grd.y_min = s; grd.y_max = n;
- grd.x_inc = dx; grd.y_inc = dy;
-
- if (gmtdefs.verbose) fprintf (stderr, "xyz2grd: nx = %d ny = %d\n", grd.nx, grd.ny);
-
- nm = grd.nx * grd.ny;
-
- a = (float *) memory (CNULL, nm, sizeof (float), "xyz2grd");
- flag = (int *) memory (CNULL, nm, sizeof (int), "xyz2grd");
-
- x = (gmtdefs.xy_toggle) ? 1 : 0; y = 1 - x; /* Set up which columns have x and y */
-
- if (gmtdefs.io_header) for (i = 0; i < gmtdefs.n_header_recs; i++) fgets (line, 512, fpi);
-
- idx = 1.0 / dx; idy = 1.0 / dy;
- n_in = (z_only) ? 1 : 3;
- z = (z_only) ? 0 : 2;
-
- more = ((n_fields = gmt_input (fpi, n_in, &in)) == n_in);
-
- ij = -1; /* Will be incremented to 0 or set first time around */
-
- while (more) {
- skip = FALSE;
- n_read++;
-
- if (!z_only) {
- if (in[y] >= s && in[y] <= n) { /* y ok, check x */
- if (xy_units && (in[x] < w || in[x] > e))
- skip = TRUE;
- else {
- while (in[x] < w) in[x] += 360.0;
- if (in[x] > e) skip = TRUE;
- }
- }
- else
- skip = TRUE;
- }
-
- if (!skip) {
- ij = (z_only) ? ij + 1 : floor ((n - in[y]) * idy + off) * grd.nx + floor ((in[x] - w) * idx + off);
- a[ij] = in[z];
- flag[ij]++;
- n_used++;
- }
-
- more = ((n_fields = gmt_input (fpi, n_in, &in)) == n_in);
- }
- if (fpi != stdin) fclose (fpi);
- if (n_fields == -1) n_fields = 0; /* Ok to get EOF */
- if (n_fields%n_in) { /* Got garbage or multiple segment subheader */
- fprintf (stderr, "%s: Cannot read line %d, aborts\n", gmt_program, n_read);
- exit (-1);
- }
-
- for (ij = 0; ij < nm; ij++) { /* Check if all nodes got one value only */
- if (flag[ij] == 1)
- n_filled++;
- else if (flag[ij] == 0) {
- n_empty++;
- a[ij] = no_data;
- }
- else /* More than 1 value went to this node */
- n_stuffed++;
- }
- if (n_read != n_used || n_filled != nm || n_empty > 0) gmtdefs.verbose = TRUE;
- if (gmtdefs.verbose) {
- fprintf (stderr, "xyz2grd: %d n_used: %d n_filled: %d n_empty: %d set to ",
- n_read, n_used, n_filled, n_empty);
- (bad_float (no_data)) ? fprintf (stderr, "NaN\n") : fprintf (stderr, "%lg\n", no_data);
- }
- if (n_bad) fprintf (stderr, "xyz2grd: %d records unreadable\n", n_bad);
- if (n_stuffed) fprintf (stderr, "xyz2grd: Warning - %d nodes had multiple entries\n", n_stuffed);
- if (write_grd (grdfile, &grd, a, 0.0, 0.0, 0.0, 0.0, dummy, FALSE)) {
- fprintf (stderr, "xyz2grd: Error writing file %s\n", grdfile);
- exit (-1);
- }
-
- free ((char *)a);
- free ((char *)flag);
-
- gmt_end (argc, argv);
- }
-