/*-------------------------------------------------------------------- * $Id: grdpaste.c,v 1.2.4.2 2002/02/27 17:41:10 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 *--------------------------------------------------------------------*/ /* * grdpaste.c reads two grdfiles and writes a new file with * the first two pasted together along their common edge. * * Author: Walter Smith * Date: 5 august, 1988 * Updated to v2.0 20-May-1991 Paul Wessel * Updated to v3.1 23-May-1998 Paul Wessel * 3.3.5 23-JUN-2000 Paul Wessel * Version: 3.4.1 * */ #include "gmt.h" main (int argc, char **argv) { BOOLEAN error = FALSE; int i, way, one_or_zero, n_in = 0; char *grd_a, *grd_b, *grd_c, format[BUFSIZ]; double x_noise, y_noise; float *c; struct GRD_HEADER ha, hb, hc; argc = GMT_begin (argc, argv); grd_a = grd_b = grd_c = CNULL; /* Check and interpret the command line arguments */ for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch(argv[i][1]) { /* Common parameters */ case 'V': case '\0': error += GMT_get_common_args (argv[i], 0, 0, 0, 0); break; /* Supplemental parameters */ case 'G': grd_c = &argv[i][2]; break; default: /* Options not recognized */ error = TRUE; GMT_default_error (argv[i][1]); break; } } else if (n_in == 0) { grd_a = argv[i]; n_in++; } else if (n_in == 1) { grd_b = argv[i]; n_in++; } else { error = TRUE; fprintf (stderr, "%s: GMT SYNTAX ERROR: Only two files may be pasted\n", GMT_program); } } if (GMT_quick || argc == 1) { fprintf (stderr,"grdpaste %s - Join two grdfiles along common edge\n\n", GMT_VERSION); fprintf (stderr, "usage: grdpaste -G [-V]\n\n"); if (GMT_quick) exit (EXIT_FAILURE); fprintf (stderr, " where file_a and file_b are to be combined into outfile.\n"); fprintf (stderr, " file_a and file_b must have same dx,dy and one edge in common.\n"); fprintf (stderr, " If in doubt, run grdinfo first and check your files.\n"); fprintf (stderr, " Use grdcut and/or grdsample to adjust files as necessary.\n"); fprintf (stderr, "\n\tOPTIONS:\n"); GMT_explain_option ('V'); exit (EXIT_FAILURE); } if (!grd_a || !grd_b) { fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify two input files\n", GMT_program); error++; } if (!grd_c) { fprintf (stderr, "%s: GMT SYNTAX ERROR -G: Must specify output file\n", GMT_program); error++; } if (error) exit (EXIT_FAILURE); GMT_put_history (argc, argv); /* Update .gmtcommands */ /* Check that the options selected make sense */ /* Try to find a common side to join on */ GMT_grd_init (&hc, argc, argv, FALSE); if (GMT_read_grd_info (grd_a, &ha)) { fprintf (stderr, "%s: Error opening file %s\n", GMT_program, grd_a); exit (EXIT_FAILURE); } if (GMT_read_grd_info (grd_b, &hb)) { fprintf (stderr, "%s: Error opening file %s\n", GMT_program, grd_b); exit (EXIT_FAILURE); } if (ha.node_offset != hb.node_offset) error = TRUE; if ((ha.z_scale_factor != hb.z_scale_factor) || (ha.z_add_offset != hb.z_add_offset)) { fprintf (stderr, "%s: Scale/offset not compatible!\n", GMT_program); exit (EXIT_FAILURE); } if ( fabs (ha.x_inc - hb.x_inc) < 1.0e-6 && fabs (ha.y_inc - hb.y_inc) < 1.0e-6) { hc.x_inc = ha.x_inc; hc.y_inc = ha.y_inc; } else { fprintf (stderr, "%s: Grid intervals do not match!\n", GMT_program); exit (EXIT_FAILURE); } one_or_zero = 1 - ha.node_offset; x_noise = SMALL * hc.x_inc; y_noise = SMALL * hc.y_inc; if ( fabs (ha.x_min - hb.x_min) < x_noise && fabs (ha.x_max - hb.x_max) < x_noise ) { if (fabs (ha.y_max - hb.y_min) < y_noise) { way = 1; hc.nx = ha.nx; hc.ny = ha.ny + hb.ny - one_or_zero; hc.x_min = ha.x_min; hc.x_max = ha.x_max; hc.y_min = ha.y_min; hc.y_max = hb.y_max; } else if (fabs (ha.y_min - hb.y_max) < y_noise) { way = 2; hc.nx = ha.nx; hc.ny = ha.ny + hb.ny - one_or_zero; hc.x_min = ha.x_min; hc.x_max = ha.x_max; hc.y_min = hb.y_min; hc.y_max = ha.y_max; } else { fprintf (stderr, "%s: Grids do not share a common edge!\n", GMT_program); exit (EXIT_FAILURE); } } else if ( fabs (ha.y_min - hb.y_min) < y_noise && fabs (ha.y_max - hb.y_max) < y_noise ) { if (fabs (ha.x_min - hb.x_max) < x_noise) { way = 3; hc.nx = ha.nx + hb.nx - one_or_zero; hc.ny = ha.ny; hc.x_min = hb.x_min; hc.x_max = ha.x_max; hc.y_min = ha.y_min; hc.y_max = ha.y_max; } else if (fabs (ha.x_max - hb.x_min) < x_noise) { way = 4; hc.nx = ha.nx + hb.nx - one_or_zero; hc.ny = ha.ny; hc.x_min = ha.x_min; hc.x_max = hb.x_max; hc.y_min = ha.y_min; hc.y_max = ha.y_max; } else { fprintf (stderr, "%s: Grids do not share a common edge!\n", GMT_program); exit (EXIT_FAILURE); } } else { fprintf (stderr, "%s: Grids do not share a common edge!\n", GMT_program); exit (EXIT_FAILURE); } /* Now we can do it */ sprintf (format, "%%s: \t%s\t%s\t%s\t%s\t%s\t%s\t%%d\t%%d\n", gmtdefs.d_format, gmtdefs.d_format, gmtdefs.d_format, gmtdefs.d_format, gmtdefs.d_format, gmtdefs.d_format); if (gmtdefs.verbose) { fprintf (stderr, "File spec:\tW E S N dx dy nx ny:\n"); fprintf (stderr, format, grd_a, ha.x_min, ha.x_max, ha.y_min, ha.y_max, ha.x_inc, ha.y_inc, ha.nx, ha.ny); fprintf (stderr, format, grd_b, hb.x_min, hb.x_max, hb.y_min, hb.y_max, hb.x_inc, hb.y_inc, hb.nx, hb.ny); fprintf (stderr, format, grd_c, hc.x_min, hc.x_max, hc.y_min, hc.y_max, hc.x_inc, hc.y_inc, hc.nx, hc.ny); } c = (float *) GMT_memory (VNULL, (size_t)(hc.nx*hc.ny), sizeof (float), GMT_program); hc.node_offset = ha.node_offset; hc.z_scale_factor = ha.z_scale_factor; hc.z_add_offset = ha.z_add_offset; switch (way) { case 1: GMT_pad[3] = hb.ny - one_or_zero; if (GMT_read_grd (grd_a, &ha, c, ha.x_min, ha.x_max, ha.y_min, ha.y_max, GMT_pad, FALSE)) { fprintf (stderr, "%s: Error reading file %s\n", GMT_program, grd_a); exit (EXIT_FAILURE); } GMT_pad[3] = 0; GMT_pad[2] = ha.ny - one_or_zero; if (GMT_read_grd (grd_b, &hb, c, hb.x_min, hb.x_max, hb.y_min, hb.y_max, GMT_pad, FALSE)) { fprintf (stderr, "%s: Error reading file %s\n", GMT_program, grd_b); exit (EXIT_FAILURE); } break; case 2: GMT_pad[2] = hb.ny - one_or_zero; if (GMT_read_grd (grd_a, &ha, c, ha.x_min, ha.x_max, ha.y_min, ha.y_max, GMT_pad, FALSE)) { fprintf (stderr, "%s: Error reading file %s\n", GMT_program, grd_a); exit (EXIT_FAILURE); } GMT_pad[2] = 0; GMT_pad[3] = ha.ny - one_or_zero; if (GMT_read_grd (grd_b, &hb, c, hb.x_min, hb.x_max, hb.y_min, hb.y_max, GMT_pad, FALSE)) { fprintf (stderr, "%s: Error reading file %s\n", GMT_program, grd_b); exit (EXIT_FAILURE); } break; case 3: GMT_pad[0] = hb.nx - one_or_zero; if (GMT_read_grd (grd_a, &ha, c, ha.x_min, ha.x_max, ha.y_min, ha.y_max, GMT_pad, FALSE)) { fprintf (stderr, "%s: Error reading file %s\n", GMT_program, grd_a); exit (EXIT_FAILURE); } GMT_pad[0] = 0; GMT_pad[1] = ha.nx - one_or_zero; if (GMT_read_grd (grd_b, &hb, c, hb.x_min, hb.x_max, hb.y_min, hb.y_max, GMT_pad, FALSE)) { fprintf (stderr, "%s: Error reading file %s\n", GMT_program, grd_b); exit (EXIT_FAILURE); } break; case 4: GMT_pad[1] = hb.nx - one_or_zero; if (GMT_read_grd (grd_a, &ha, c, ha.x_min, ha.x_max, ha.y_min, ha.y_max, GMT_pad, FALSE)) { fprintf (stderr, "%s: Error reading file %s\n", GMT_program, grd_a); exit (EXIT_FAILURE); } GMT_pad[1] = 0; GMT_pad[0] = ha.nx - one_or_zero; if (GMT_read_grd (grd_b, &hb, c, hb.x_min, hb.x_max, hb.y_min, hb.y_max, GMT_pad, FALSE)) { fprintf (stderr, "%s: Error reading file %s\n", GMT_program, grd_b); exit (EXIT_FAILURE); } break; } GMT_pad[0] = GMT_pad[1] = GMT_pad[2] = GMT_pad[3] = 0; if (GMT_write_grd (grd_c, &hc, c, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE)) { fprintf (stderr, "%s: Error writing file %s\n", GMT_program, grd_c); exit (EXIT_FAILURE); } GMT_free ((void *) c); GMT_end (argc, argv); }