Ejemplo n.º 1
0
int main (int argc, char **argv)
{
	GMT_LONG error = FALSE, set_n = FALSE, shift_xy = FALSE, offset;

	char *infile = NULL, format[BUFSIZ], unit_name[GRD_UNIT_LEN], scale_unit_name[GRD_UNIT_LEN];

	GMT_LONG i, j, unit = 0, n_read;
	
	GMT_LONG nm;
	
	float *geo = NULL, *rect = NULL;
	
	double w, e, s, n;
	double xmin, xmax, ymin, ymax, inch_to_unit, unit_to_inch, fwd_scale, inv_scale;

	struct GRD_HEADER g_head, r_head;
	struct GMT_EDGEINFO edgeinfo;
	struct GRDPROJECT_CTRL *Ctrl = NULL;

	void *New_grdproject_Ctrl (), Free_grdproject_Ctrl (struct GRDPROJECT_CTRL *C);

	argc = (int)GMT_begin (argc, argv);

	Ctrl = (struct GRDPROJECT_CTRL *)New_grdproject_Ctrl ();	/* Allocate and initialize a new control structure */
	
	infile = CNULL;
	w = e = s = n = 0.0;

	for (i = 1; i < argc; i++) {
		if (argv[i][0] == '-') {
			switch (argv[i][1]) {
				/* Common parameters */

				case 'J':
				case 'R':
				case 'V':
				case '\0':
					error += GMT_parse_common_options (argv[i], &w, &e, &s, &n);
					break;

				/* Supplemental parameters */

				case 'C':
					Ctrl->C.active = TRUE;
					if (argv[i][2]) {	/* Also gave shifts */
	 					n_read = sscanf (&argv[i][2], "%lf/%lf", &Ctrl->C.easting, &Ctrl->C.northing);
						if (n_read != 2) {
							fprintf (stderr, "%s: GMT SYNTAX ERROR.  Expected -C[<false_easting>/<false_northing>]\n", GMT_program);
							error++;
						}
					}
					break;
				case 'D':
					Ctrl->D.active = TRUE;
					if (GMT_getinc (&argv[i][2], &Ctrl->D.xinc, &Ctrl->D.yinc)) {
						GMT_inc_syntax ('D', 1);
						error = TRUE;
					}
					break;
				case 'E':
					Ctrl->E.active = TRUE;
					Ctrl->E.dpi = atoi (&argv[i][2]);
					break;
				case 'A':
					Ctrl->A.active = TRUE;
					Ctrl->A.unit = argv[i][2];
					break;
				case 'F':
					Ctrl->F.active = TRUE;
					break;
				case 'G':
					Ctrl->G.file = strdup (&argv[i][2]);
					break;
				case 'I':
					Ctrl->I.active = TRUE;
					break;
				case 'M':	/* Directly specify units */
					Ctrl->M.active = TRUE;
					Ctrl->M.unit = argv[i][2];
					break;
				case 'N':
					sscanf (&argv[i][2], "%" GMT_LL "d/%" GMT_LL "d", &Ctrl->N.nx, &Ctrl->N.ny);
					if (Ctrl->N.ny == 0) Ctrl->N.ny = Ctrl->N.nx;
					Ctrl->N.active = TRUE;
					break;
				case 'S':
					Ctrl->S.active = TRUE;
					for (j = 2; j < 5 && argv[i][j]; j++) {
						switch (argv[i][j]) {
							case '-':
								Ctrl->S.antialias = FALSE; break;
							case 'n':
								Ctrl->S.interpolant = BCR_NEARNEIGHBOR; break;
							case 'l':
								Ctrl->S.interpolant = BCR_BILINEAR; break;
							case 'b':
								Ctrl->S.interpolant = BCR_BSPLINE; break;
							case 'c':
								Ctrl->S.interpolant = BCR_BICUBIC; break;
							case '/':
								Ctrl->S.threshold = atof (&argv[i][j+1]);
								j = 5; break;
							default:
								fprintf (stderr, "%s: Warning: The -S option has changed meaning. Use -S[-]b|c|l|n[/threshold] to specify interpolation mode.\n", GMT_program);
								j = 5; break;
						}
					}
					break;
				default:
					error = TRUE;
					GMT_default_error (argv[i][1]);
					break;
			}
		}
		else 
			infile = argv[i];
	}

	if ((Ctrl->D.active + Ctrl->E.active + Ctrl->N.active) == 0) Ctrl->N.active = set_n = TRUE;

	if (argc == 1 || GMT_give_synopsis_and_exit) {
		fprintf (stderr, "grdproject %s - Project geographical grid to/from rectangular grid\n\n", GMT_VERSION);
		fprintf (stderr, "usage: grdproject <in_grdfile> -G<out_grdfile> %s\n", GMT_J_OPT);
		fprintf (stderr, "\t[-A[k|m|n|i|c|p]] [-C[<dx/dy>]] [-D%s] [-E<dpi>] [-F]\n", GMT_inc_OPT);
		fprintf (stderr, "\t[-I] [-Mc|i|m] [-N<nx/ny>] [%s]\n", GMT_Rgeo_OPT);
		fprintf (stderr, "\t[-S[-]b|c|l|n[/<threshold>]] [-V]\n\n");

		if (GMT_give_synopsis_and_exit) exit (EXIT_FAILURE);

		fprintf (stderr, "\t<in_grdfile> is data set to be transformed.\n");
		fprintf (stderr, "\t-G name of output grid.\n");
		GMT_explain_option ('J');
		fprintf (stderr, "\n\tOPTIONS:\n");
		fprintf (stderr, "\t-A force projected values to be in actual meters [Default uses the given map scale].\n");
		fprintf (stderr, "\t   Specify another unit by appending k (km), m (miles), n (nautical miles), i (inch), c (cm), or p (points).\n");
		fprintf (stderr, "\t-C coordinates relative to projection center [Default is relative to lower left corner].\n");
		fprintf (stderr, "\t   Optionally append dx/dy to add (or subtract if -I) (i.e., false easting & northing) [0/0].\n");
		GMT_inc_syntax ('D', 0);
		fprintf (stderr, "\t-E sets dpi for output grid.\n");
		fprintf (stderr, "\t-F toggle between pixel and grid registration [Default is same as input].\n");
		fprintf (stderr, "\t-I Inverse transformation from rectangular to geographical.\n");
		fprintf (stderr, "\t-M Temporarily reset MEASURE_UNIT to be c (cm), i (inch), m (meter), or p (point).\n");
		fprintf (stderr, "\t   Cannot be used if -A is set.\n");
		fprintf (stderr, "\t-N sets the number of nodes for the new grid.\n");
		fprintf (stderr, "\t   Only one of -D, -E, and -N can be specified!\n");
		fprintf (stderr, "\t   If none are specified, nx,ny of the input file is used.\n");
		GMT_explain_option ('R');
		fprintf (stderr, "\t-S Determines the interpolation mode (b = B-spline, c = bicubic, l = bilinear,\n");
		fprintf (stderr, "\t   n = nearest-neighbor) [Default: bicubic].\n");
		fprintf (stderr, "\t   Optionally, prepend - to switch off antialiasing [Default: on].\n");
		fprintf (stderr, "\t   Append /<threshold> to change the minimum weight in vicinity of NaNs. A threshold of\n");
		fprintf (stderr, "\t   1.0 requires all nodes involved in interpolation to be non-NaN; 0.5 will interpolate\n");
		fprintf (stderr, "\t   about half way from a non-NaN to a NaN node [Default: 0.5].\n");
		GMT_explain_option ('V');

		exit (EXIT_FAILURE);
	}

	GMT_check_lattice (&Ctrl->D.xinc, &Ctrl->D.yinc, &Ctrl->F.active, &Ctrl->D.active);

	if (!infile) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR:  Must specify input file\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 (!project_info.region_supplied) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR:  Must specify -R option\n", GMT_program);
		error++;
	}*/
	if ((Ctrl->M.active + Ctrl->A.active) == 2) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR:  Can specify only one of -A and -M\n", GMT_program);
		error++;
	}
	if ((Ctrl->D.active + Ctrl->E.active + Ctrl->N.active) != 1) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR:  Must specify only one of -D, -E, or -N\n", GMT_program);
		error++;
	}
	if (Ctrl->D.active && (Ctrl->D.xinc <= 0.0 || Ctrl->D.yinc < 0.0)) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR -D option.  Must specify positive increment(s)\n", GMT_program);
		error++;
	}
	if (Ctrl->N.active && !set_n && (Ctrl->N.nx <= 0 || Ctrl->N.ny <= 0)) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR -N option.  Must specify positive integers\n", GMT_program);
		error++;
	}
	if (Ctrl->E.active && Ctrl->E.dpi <= 0) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR -E option.  Must specify positive dpi\n", GMT_program);
		error++;
	}
	if (Ctrl->S.active && (Ctrl->S.threshold < 0.0 || Ctrl->S.threshold > 1.0)) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR -S option:  threshold must be in [0,1] range\n", GMT_program);
		error++;
	}

	if (error) exit (EXIT_FAILURE);

	if (Ctrl->M.active) GMT_err_fail (GMT_set_measure_unit (Ctrl->M.unit), "-M");
	shift_xy = !(Ctrl->C.easting == 0.0 && Ctrl->C.northing == 0.0);
	
	unit = GMT_check_scalingopt ('A', Ctrl->A.unit, scale_unit_name);
	GMT_init_scales (unit, &fwd_scale, &inv_scale, &inch_to_unit, &unit_to_inch, unit_name);

	if (Ctrl->I.active) {	/* Must flip the column types since in is Cartesian and out is geographic */
		GMT_io.out_col_type[0] = GMT_IS_LON;	GMT_io.out_col_type[1] = GMT_IS_LAT;	/* Inverse projection expects x,y and gives lon, lat */
		GMT_io.in_col_type[0] = GMT_io.in_col_type[1] = GMT_IS_FLOAT;
		project_info.degree[0] = project_info.degree[1] = FALSE;
	}

	if (!project_info.region_supplied) {
		double ww, ee, ss, nn;
		char opt_R[BUFSIZ];
		struct GRD_HEADER head;
		if (project_info.projection == GMT_UTM && project_info.utm_hemisphere == 0) {
			fprintf (stderr, "%s: GMT SYNTAX ERROR -JU|u option: When -R is not provided you have to specify the hemisphere\n", GMT_program);
			exit (EXIT_FAILURE);
		}
		GMT_err_fail (GMT_read_grd_info (infile, &head), infile);
		w = head.x_min;		e = head.x_max;
		s = head.y_min;		n = head.y_max;
		if (!Ctrl->I.active) {
			sprintf (opt_R, "-R%.12f/%.12f/%.12f/%.12f", w, e, s, n);
			GMT_parse_R_option (opt_R, &ww, &ee, &ss, &nn);
			GMT_err_fail (GMT_map_setup (w, e, s, n), "");
		}
		else {			/* Do inverse transformation */
			double x_c, y_c, lon_t, lat_t;
			/* Obtain a first crude estimation of the good -R */
			x_c = (w + e) / 2.; 		/* mid point of projected coords */
			y_c = (s + n) / 2.;
			if (project_info.projection == GMT_UTM && !project_info.north_pole && y_c > 0) y_c *= -1;
			if (y_c > 0)
				GMT_parse_R_option ("-R-180/180/0/80", &ww, &ee, &ss, &nn);
			else
				GMT_parse_R_option ("-R-180/180/-80/0", &ww, &ee, &ss, &nn);
			if (project_info.projection == GMT_UTM && !project_info.north_pole && y_c < 0) y_c *= -1;	/* Undo the *-1 (only for the UTM case) */
			if (shift_xy) {
				x_c -= Ctrl->C.easting;
				y_c -= Ctrl->C.northing;
			}
			/* Convert from 1:1 scale */ 
			if (unit) {
				x_c *= fwd_scale;
				y_c *= fwd_scale;
			}

			GMT_err_fail (GMT_map_setup (ww, ee, ss, nn), "");

			x_c *= project_info.x_scale;
			y_c *= project_info.y_scale;

			if (Ctrl->C.active) {	/* Then correct so lower left corner is (0,0) */
				x_c += project_info.x0;
				y_c += project_info.y0;
			}
			GMT_xy_to_geo (&lon_t, &lat_t, x_c, y_c);
			sprintf (opt_R, "-R%.12f/%.12f/%.12f/%.12f", lon_t-1, lon_t+1, lat_t-1, lat_t+1);
			if (gmtdefs.verbose) fprintf (stderr, "First opt_R\t %s\t%g\t%g\n", opt_R, x_c, y_c);
			GMT_parse_R_option (opt_R, &ww, &ee, &ss, &nn);
			project_info.region = 0;	/* We need to reset this to not fall into non-wanted branch deeper down */
			GMT_err_fail (GMT_map_setup (ww, ee, ss, nn), "");

			/* Finally obtain the good limits */
			if (shift_xy) {
				w -= Ctrl->C.easting;	e -= Ctrl->C.easting;
				s -= Ctrl->C.northing;	n -= Ctrl->C.northing;
			}
			if (unit) {
				w *= fwd_scale;		e *= fwd_scale;
				s *= fwd_scale;		n *= fwd_scale;
			}
			w *= project_info.x_scale;	e *= project_info.x_scale;
			s *= project_info.y_scale;	n *= project_info.y_scale;

			if (Ctrl->C.active) {
				w += project_info.x0;	e += project_info.x0;
				s += project_info.y0;	n += project_info.y0;
			}

			GMT_xy_to_geo (&ww, &ss, w, s);		/* SW corner */
			GMT_xy_to_geo (&ee, &nn, e, n);		/* NE corner */
			sprintf (opt_R, "-R%.12f/%.12f/%.12f/%.12fr", ww, ss, ee, nn);
			if (gmtdefs.verbose) fprintf (stderr, "Second opt_R\t %s\n", opt_R);
			GMT_parse_common_options (opt_R, &ww, &ee, &ss, &nn);
			w = ww;		e = ee;
			s = ss;		n = nn;
		}
	}

	GMT_err_fail (GMT_map_setup (w, e, s, n), "");

	xmin = (Ctrl->C.active) ? project_info.xmin - project_info.x0 : project_info.xmin;
	xmax = (Ctrl->C.active) ? project_info.xmax - project_info.x0 : project_info.xmax;
	ymin = (Ctrl->C.active) ? project_info.ymin - project_info.y0 : project_info.ymin;
	ymax = (Ctrl->C.active) ? project_info.ymax - project_info.y0 : project_info.ymax;
	if (Ctrl->A.active) {	/* Convert to chosen units */
		strncpy (unit_name, scale_unit_name, (size_t)GRD_UNIT_LEN);
		xmin /= project_info.x_scale;
		xmax /= project_info.x_scale;
		ymin /= project_info.y_scale;
		ymax /= project_info.y_scale;
		if (unit) {	/* Change the 1:1 unit used */
			xmin *= fwd_scale;
			xmax *= fwd_scale;
			ymin *= fwd_scale;
			ymax *= fwd_scale;
		}
	}
	else {	/* Convert inches to chosen MEASURE */
		xmin *= inch_to_unit;
		xmax *= inch_to_unit;
		ymin *= inch_to_unit;
		ymax *= inch_to_unit;
	}
	if (shift_xy) {
		xmin += Ctrl->C.easting;
		xmax += Ctrl->C.easting;
		ymin += Ctrl->C.northing;
		ymax += Ctrl->C.northing;
	}

	GMT_grd_init (&r_head, argc, argv, FALSE);
	GMT_grd_init (&g_head, argc, argv, FALSE);

	sprintf (format, "(%s/%s/%s/%s)", gmtdefs.d_format, gmtdefs.d_format, gmtdefs.d_format, gmtdefs.d_format);

	if (Ctrl->I.active) {	/* Transforming from rectangular projection to geographical */

		/* if (!project_info.region) d_swap (s, e); */  /* Got w/s/e/n, make into w/e/s/n */

		if (GMT_IS_AZIMUTHAL && project_info.polar) {	/* Watch out for polar cap grids */
			if (project_info.pole == -90.0) {	/* Covers S pole; implies 360 longitude range */
				w = -180.0;	e = +180.0;	n = MAX(s, n);	s = -90.0;
			}
			else if (project_info.pole == +90.0) {	/* Covers N pole; implies 360 longitude range */
				w = -180.0;	e = +180.0;	s = MIN(s, n);	n = +90.0;
			}
		}
		g_head.x_min = w;	g_head.x_max = e;	g_head.y_min = s;	g_head.y_max = n;

		GMT_err_fail (GMT_read_grd_info (infile, &r_head), infile);

		GMT_boundcond_init (&edgeinfo);
		nm = GMT_get_nm (4 + r_head.nx, 4 + r_head.ny);
		GMT_pad[0] = GMT_pad[1] = GMT_pad[2] = GMT_pad[3] = 2;

		rect = (float *) GMT_memory (VNULL, (size_t)nm, sizeof (float), GMT_program);
		GMT_err_fail (GMT_read_grd (infile, &r_head, rect, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE), infile);
		offset = r_head.node_offset;		/* Same as input */
		if (Ctrl->F.active) offset = !offset;	/* Toggle */
		if (set_n) {
			Ctrl->N.nx = r_head.nx;
			Ctrl->N.ny = r_head.ny;
		}
		GMT_err_fail (GMT_grdproject_init (&g_head, Ctrl->D.xinc, Ctrl->D.yinc, Ctrl->N.nx, Ctrl->N.ny, Ctrl->E.dpi, offset), Ctrl->G.file);
		nm = GMT_get_nm (g_head.nx, g_head.ny);
		geo = (float *) GMT_memory (VNULL, (size_t)nm, sizeof (float), GMT_program);
		if (gmtdefs.verbose) {
			fprintf (stderr, "%s: Transform ", GMT_program);
			fprintf (stderr, format, g_head.x_min, g_head.x_max, g_head.y_min, g_head.y_max);
			fprintf (stderr, " <-- ");
			fprintf (stderr, format, xmin, xmax, ymin, ymax);
			fprintf (stderr, " [%s]\n", unit_name);
		}

		/* Modify input rect header if -A, -C, -M have been set */

		if (shift_xy) {
			r_head.x_min -= Ctrl->C.easting;
			r_head.x_max -= Ctrl->C.easting;
			r_head.y_min -= Ctrl->C.northing;
			r_head.y_max -= Ctrl->C.northing;

		}
		if (Ctrl->A.active) {	/* Convert from 1:1 scale */
			if (unit) {	/* Undo the 1:1 unit used */
				r_head.x_min *= inv_scale;
				r_head.x_max *= inv_scale;
				r_head.y_min *= inv_scale;
				r_head.y_max *= inv_scale;
			}
			r_head.x_min *= project_info.x_scale;
			r_head.x_max *= project_info.x_scale;
			r_head.y_min *= project_info.y_scale;
			r_head.y_max *= project_info.y_scale;
		}
		else if (gmtdefs.measure_unit != GMT_INCH) {	/* Convert from inch to whatever */
			r_head.x_min *= unit_to_inch;
			r_head.x_max *= unit_to_inch;
			r_head.y_min *= unit_to_inch;
			r_head.y_max *= unit_to_inch;
		}
		if (Ctrl->C.active) {	/* Then correct so lower left corner is (0,0) */
			r_head.x_min += project_info.x0;
			r_head.x_max += project_info.x0;
			r_head.y_min += project_info.y0;
			r_head.y_max += project_info.y0;
		}
		r_head.x_inc = GMT_get_inc (r_head.x_min, r_head.x_max, r_head.nx, r_head.node_offset);
		r_head.y_inc = GMT_get_inc (r_head.y_min, r_head.y_max, r_head.ny, r_head.node_offset);

		GMT_grd_project (rect, &r_head, geo, &g_head, &edgeinfo, Ctrl->S.antialias, Ctrl->S.interpolant, Ctrl->S.threshold, TRUE);

		GMT_pad[0] = GMT_pad[1] = GMT_pad[2] = GMT_pad[3] = 0;
		sprintf (g_head.x_units, "longitude [degrees_east]");
		sprintf (g_head.y_units, "latitude [degrees_north]");
		GMT_err_fail (GMT_write_grd (Ctrl->G.file, &g_head, geo, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE), Ctrl->G.file);
	}
	else {	/* Forward projection from geographical to rectangular grid */

		GMT_err_fail (GMT_read_grd_info (infile, &g_head), infile);

		GMT_boundcond_init (&edgeinfo);
		nm = GMT_get_nm (4 + g_head.nx, 4 + g_head.ny);
		GMT_pad[0] = GMT_pad[1] = GMT_pad[2] = GMT_pad[3] = 2;

		geo = (float *) GMT_memory (VNULL, (size_t)nm, sizeof (float), GMT_program);
		GMT_err_fail (GMT_read_grd (infile, &g_head, geo, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE), infile);

		r_head.x_min = project_info.xmin;	r_head.x_max = project_info.xmax;
		r_head.y_min = project_info.ymin;	r_head.y_max = project_info.ymax;
		if (Ctrl->A.active) {	/* Convert from 1:1 scale */
			if (unit) {	/* Undo the 1:1 unit used */
				Ctrl->D.xinc *= inv_scale;
				Ctrl->D.yinc *= inv_scale;
			}
			Ctrl->D.xinc *= project_info.x_scale;
			Ctrl->D.yinc *= project_info.y_scale;
		}
		else if (gmtdefs.measure_unit != GMT_INCH) {	/* Convert from inch to whatever */
			Ctrl->D.xinc *= unit_to_inch;
			Ctrl->D.yinc *= unit_to_inch;
		}
		if (set_n) {
			Ctrl->N.nx = g_head.nx;
			Ctrl->N.ny = g_head.ny;
		}

		if (gmtdefs.verbose) {
			fprintf (stderr, "%s: Transform ", GMT_program);
			fprintf (stderr, format, g_head.x_min, g_head.x_max, g_head.y_min, g_head.y_max);
			fprintf (stderr, " --> ");
			fprintf (stderr, format, xmin, xmax, ymin, ymax);
			fprintf (stderr, " [%s]\n", unit_name);
		}

		offset = g_head.node_offset;		/* Same as input */
		if (Ctrl->F.active) offset = !offset;	/* Toggle */

		GMT_err_fail (GMT_grdproject_init (&r_head, Ctrl->D.xinc, Ctrl->D.yinc, Ctrl->N.nx, Ctrl->N.ny, Ctrl->E.dpi, offset), Ctrl->G.file);
		nm = GMT_get_nm (r_head.nx, r_head.ny);
		rect = (float *) GMT_memory (VNULL, (size_t)nm, sizeof (float), GMT_program);
		GMT_grd_project (geo, &g_head, rect, &r_head, &edgeinfo, Ctrl->S.antialias, Ctrl->S.interpolant, Ctrl->S.threshold, FALSE);

		/* Modify output rect header if -A, -C, -M have been set */

		if (Ctrl->C.active) {	/* Change origin from lower left to projection center */
			r_head.x_min -= project_info.x0;
			r_head.x_max -= project_info.x0;
			r_head.y_min -= project_info.y0;
			r_head.y_max -= project_info.y0;
		}
		if (Ctrl->A.active) {	/* Convert to 1:1 scale */
			r_head.x_min /= project_info.x_scale;
			r_head.x_max /= project_info.x_scale;
			r_head.y_min /= project_info.y_scale;
			r_head.y_max /= project_info.y_scale;
			if (unit) {	/* Change the 1:1 unit used */
				r_head.x_min *= fwd_scale;
				r_head.x_max *= fwd_scale;
				r_head.y_min *= fwd_scale;
				r_head.y_max *= fwd_scale;
			}
		}
		else if (gmtdefs.measure_unit != GMT_INCH) {	/* Convert from inch to whatever */
			r_head.x_min /= unit_to_inch;
			r_head.x_max /= unit_to_inch;
			r_head.y_min /= unit_to_inch;
			r_head.y_max /= unit_to_inch;
		}
		if (shift_xy) {
			r_head.x_min += Ctrl->C.easting;
			r_head.x_max += Ctrl->C.easting;
			r_head.y_min += Ctrl->C.northing;
			r_head.y_max += Ctrl->C.northing;

		}
		r_head.x_inc = GMT_get_inc (r_head.x_min, r_head.x_max, r_head.nx, r_head.node_offset);
		r_head.y_inc = GMT_get_inc (r_head.y_min, r_head.y_max, r_head.ny, r_head.node_offset);

		/* rect xy values are here in GMT projected units chosen by user */

		GMT_pad[0] = GMT_pad[1] = GMT_pad[2] = GMT_pad[3] = 0;
		strcpy (r_head.x_units, unit_name);
		strcpy (r_head.y_units, unit_name);
		GMT_err_fail (GMT_write_grd (Ctrl->G.file, &r_head, rect, 0.0, 0.0, 0.0, 0.0, GMT_pad, FALSE), Ctrl->G.file);
	}

	GMT_free ((void *)geo);
	GMT_free ((void *)rect);

	Free_grdproject_Ctrl (Ctrl);	/* Deallocate control structure */

	GMT_end (argc, argv);

	exit (EXIT_SUCCESS);
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
int main (int argc, char **argv)
{
#include "grdreformat.h"	/* Defines N_GRDTXT_LINES and char *grd_formats[N_GRDTXT_LINES] array used in usage message */
	GMT_LONG error = FALSE, global = FALSE, no_header;

	GMT_LONG i, nfiles = 0, nx, ny, type[2];

	size_t nm;
	
	double w, e, s, n;

	float *z = NULL;

	char *file[2], fname[2][BUFSIZ];

	struct GRD_HEADER grd;
	struct GRDREFORMAT_CTRL *Ctrl = NULL;

	void *New_grdreformat_Ctrl (), Free_grdreformat_Ctrl (struct GRDREFORMAT_CTRL *C);

	argc = (int)GMT_begin (argc, argv);

	Ctrl = (struct GRDREFORMAT_CTRL *)New_grdreformat_Ctrl ();	/* Allocate and initialize a new control structure */
	
	file[0] = file[1] = CNULL;
	w = e = s = n = 0.0;

	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, &e, &s, &n);
					break;

				case 'N':
					Ctrl->N.active = TRUE;
					break;
				default:
					error = TRUE;
					GMT_default_error (argv[i][1]);
					break;
			}
		}
		else if (nfiles < 2) {
			file[nfiles] = argv[i];
			nfiles++;
		}
		else
			nfiles++;
	}

	if (argc == 1 || GMT_give_synopsis_and_exit) {	/* Display usage */
		fprintf (stderr, "grdreformat %s - Converting between different grid file formats\n\n", GMT_VERSION);
		fprintf( stderr, "usage: grdreformat ingrdfile[=id[/scale/offset]] outgrdfile[=id[/scale/offset]] [-N]\n\t[%s] [%s] [-V]\n", GMT_Rgeo_OPT, GMT_f_OPT);

		if (GMT_give_synopsis_and_exit) exit (EXIT_FAILURE);

		fprintf (stderr, "\tingrdfile is the grid file to convert.\n");
		fprintf (stderr, "\toutgrdfile is the new converted grid file.\n");
		fprintf( stderr, "\tscale and offset, if given, will multiply data by scale and add offset.\n");
		fprintf (stderr, "\n\tOPTIONS:\n");
		fprintf (stderr, "\t-N  Do NOT write the header (native grids only - ignored otherwise).\n");
		fprintf (stderr, "\t\t  Useful when creating files to be used by grdraster.\n");
		GMT_explain_option ('r');
		GMT_explain_option ('f');
		GMT_explain_option ('V');

		fprintf (stderr, "\n	The following grid file formats are supported:\n\n");
#ifdef USE_GDAL
		for (i = 0; i < N_GRDTXT_LINES; i++) fprintf (stderr, "\t%s\n", grd_formats[i]);
#else
		for (i = 0; i < N_GRDTXT_LINES; i++) if (i != 33) fprintf (stderr, "\t%s\n", grd_formats[i]);
#endif
		exit (EXIT_FAILURE);
	}

	if (nfiles != 2) {
		fprintf (stderr, "%s: GMT SYNTAX ERROR: Must specify both input and output file names.\n", GMT_program);
		error++;
	}

	if (error) exit (EXIT_FAILURE);

	GMT_grd_init (&grd, argc, argv, FALSE);
	no_header = (Ctrl->N.active) ? 64 : 0;
	GMT_err_fail (GMT_grd_get_format (file[0], &grd, TRUE), file[0]);
	type[0] = grd.type;
	strcpy (fname[0], grd.name);
	GMT_err_fail (GMT_grd_get_format (file[1], &grd, FALSE), file[1]);
	type[1] = grd.type;
	strcpy (fname[1], grd.name);

	if (type[1] == 20) {	/* Golden Surfer format 7 (double) is read-only */
		fprintf (stderr, "%s: Grid format sd (Golden Software Surfer format 7 (double)) is read-only!\n", GMT_program);
		exit (EXIT_FAILURE);
	}
#ifdef USE_GDAL
	if (type[1] == 22) {	/* GDAL format is read-only */
		fprintf (stderr, "%s: Grid format gd (GDAL) is read-only!\n", GMT_program);
		exit (EXIT_FAILURE);
	}
#endif	
	if (gmtdefs.verbose) {
		if (file[0][0] == '=') strcpy (fname[0], "<stdin>");
		if (file[1][0] == '=') strcpy (fname[1], "<stdout>");
		fprintf (stderr, "%s: Translating file %s (format = %ld) to file %s (format = %ld)\n", GMT_program, fname[0], type[0], fname[1], type[1]);
		if (no_header && GMT_grdformats[type[1]][0] != 'c' && GMT_grdformats[type[1]][0] != 'n') fprintf (stderr, "%s: No grd header will be written\n", GMT_program);
	}

	GMT_err_fail (GMT_read_grd_info (file[0], &grd), fname[0]);

	if (e > w && n > s) {
		global = GMT_grd_is_global (&grd);
		if (!global && (w < grd.x_min || e > grd.x_max)) error = TRUE;
		if (s < grd.y_min || n > grd.y_max) error = TRUE;
		if (error) {
			fprintf (stderr, "%s: Subset exceeds data domain!\n", GMT_program);
			exit (EXIT_FAILURE);
		}
		nx = GMT_get_n (w, e, grd.x_inc, grd.node_offset);
		ny = GMT_get_n (s, n, grd.y_inc, grd.node_offset);
		nm = GMT_get_nm (nx, ny);
	}
	else
		nm = GMT_get_nm (grd.nx, grd.ny);

	z = (float *) GMT_memory (VNULL, nm, sizeof (float), GMT_program);
	GMT_err_fail (GMT_read_grd (file[0], &grd, z, w, e, s, n, GMT_pad, FALSE), fname[0]);

	grd.type = type[1];

	GMT_grd_init (&grd, argc, argv, TRUE);

	GMT_err_fail (GMT_write_grd (file[1], &grd, z, 0.0, 0.0, 0.0, 0.0, GMT_pad, no_header), fname[1]);

	GMT_free ((void *)z);

	Free_grdreformat_Ctrl (Ctrl);	/* Deallocate control structure */

	GMT_end (argc, argv);

	exit (EXIT_SUCCESS);
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
/*
 * function write_cdfgrd writes output grid to a 
 * GMT version 2 netCDF grd file 
 */
int write_cdfgrd(int verbose, char *outfile, float *grid,
		int nx, int ny, 
		double xmin, double xmax, double ymin, double ymax,
		double zmin, double zmax, double dx, double dy, 
		char *xlab, char *ylab, char *zlab, char *titl, 
		char *projection, int argc, char **argv, 
		int *error)
{
	char	*function_name = "write_cdfgrd";
	int	status = MB_SUCCESS;
	struct GRD_HEADER grd;
	double	w, e, s, n;
#ifdef GMT_MINOR_VERSION
	GMT_LONG	pad[4];
#else
	int	pad[4];
#endif
	time_t	right_now;
	char	date[MB_PATH_MAXLINE], user[MB_PATH_MAXLINE], *user_ptr, host[MB_PATH_MAXLINE];
	char	remark[MB_PATH_MAXLINE];
	char	*ctime();
	char	*getenv();
	int	i;

	/* print input debug statements */
	if (verbose >= 2)
		{
		fprintf(outfp,"\ndbg2  Function <%s> called\n",
			function_name);
		fprintf(outfp,"dbg2  Input arguments:\n");
		fprintf(outfp,"dbg2       verbose:    %d\n",verbose);
		fprintf(outfp,"dbg2       outfile:    %s\n",outfile);
		fprintf(outfp,"dbg2       grid:       %lu\n",(size_t)grid);
		fprintf(outfp,"dbg2       nx:         %d\n",nx);
		fprintf(outfp,"dbg2       ny:         %d\n",ny);
		fprintf(outfp,"dbg2       xmin:       %f\n",xmin);
		fprintf(outfp,"dbg2       xmax:       %f\n",xmax);
		fprintf(outfp,"dbg2       ymin:       %f\n",ymin);
		fprintf(outfp,"dbg2       ymax:       %f\n",ymax);
		fprintf(outfp,"dbg2       zmin:       %f\n",zmin);
		fprintf(outfp,"dbg2       zmax:       %f\n",zmax);
		fprintf(outfp,"dbg2       dx:         %f\n",dx);
		fprintf(outfp,"dbg2       dy:         %f\n",dy);
		fprintf(outfp,"dbg2       xlab:       %s\n",xlab);
		fprintf(outfp,"dbg2       ylab:       %s\n",ylab);
		fprintf(outfp,"dbg2       zlab:       %s\n",zlab);
		fprintf(outfp,"dbg2       titl:       %s\n",titl);
		fprintf(outfp,"dbg2       argc:       %d\n",(int)argc);
		fprintf(outfp,"dbg2       *argv:      %lu\n",(size_t)*argv);
		}

	/* inititialize grd header */
	GMT_program = program_name;
	GMT_grd_init (&grd, 1, argv, FALSE);
	GMT_io_init ();
	GMT_grdio_init ();
	GMT_make_fnan (GMT_f_NaN);
	GMT_make_dnan (GMT_d_NaN);

	/* copy values to grd header */
	grd.nx = nx;
	grd.ny = ny;
	grd.node_offset = 1; /* pixel registration */
	grd.x_min = xmin;
	grd.x_max = xmax;
	grd.y_min = ymin;
	grd.y_max = ymax;
	grd.z_min = zmin;
	grd.z_max = zmax;
	grd.x_inc = dx;
	grd.y_inc = dy;
	grd.z_scale_factor = 1.0;
	grd.z_add_offset = 0.0;
	strcpy(grd.x_units,xlab);
	strcpy(grd.y_units,ylab);
	strcpy(grd.z_units,zlab);
	strcpy(grd.title,titl);
	strcpy(grd.command,"\0");
	strncpy(date,"\0",MB_PATH_MAXLINE);
	right_now = time((time_t *)0);
	strncpy(date,ctime(&right_now),24);date[24]='\0';
	if ((user_ptr = getenv("USER")) == NULL)
		user_ptr = getenv("LOGNAME");
	if (user_ptr != NULL)
		strcpy(user,user_ptr);
	else
		strcpy(user, "unknown");
	gethostname(host,MB_PATH_MAXLINE);
	sprintf(remark,"\n\tProjection: %s\n\tGrid created by %s\n\tMB-system Version %s\n\tRun by <%s> on <%s> at <%s>",
		projection,program_name,MB_VERSION,user,host,date);
	strncpy(grd.remark, remark, 159);

	/* set extract wesn,pad */
	w = 0.0;
	e = 0.0;
	s = 0.0;
	n = 0.0;
	for (i=0;i<4;i++)
		pad[i] = 0;

	/* write grid to GMT netCDF grd file */
/*for (i=0;i<nx;i++)
for (j=0;j<ny;j++)
{
k = j * nx + i;
fprintf(outfp,"%d %d %d %f\n",i,j,k,grid[k]);
}*/
	GMT_write_grd(outfile, &grd, grid, w, e, s, n, pad, FALSE);
	    
	/* free GMT memory */
	GMT_free ((void *)GMT_io.skip_if_NaN);
	GMT_free ((void *)GMT_io.in_col_type);
	GMT_free ((void *)GMT_io.out_col_type);

	/* print output debug statements */
	if (verbose >= 2)
		{
		fprintf(outfp,"\ndbg2  MBIO function <%s> completed\n",
			function_name);
		fprintf(outfp,"dbg2  Return values:\n");
		fprintf(outfp,"dbg2       error:      %d\n",*error);
		fprintf(outfp,"dbg2  Return status:\n");
		fprintf(outfp,"dbg2       status:     %d\n",status);
		}

	/* return status */
	return(status);
}