Пример #1
0
void Rast_align_window(struct Cell_head *window, const struct Cell_head *ref)
{
    int preserve;

    window->ns_res = ref->ns_res;
    window->ew_res = ref->ew_res;
    window->zone = ref->zone;
    window->proj = ref->proj;

    preserve = window->proj == PROJECTION_LL &&
               window->east == (window->west + 360);
    window->south =
        Rast_row_to_northing(ceil(Rast_northing_to_row(window->south, ref)), ref);
    window->north =
        Rast_row_to_northing(floor(Rast_northing_to_row(window->north, ref)), ref);
    window->east =
        Rast_col_to_easting(ceil(Rast_easting_to_col(window->east, ref)), ref);
    window->west =
        Rast_col_to_easting(floor(Rast_easting_to_col(window->west, ref)), ref);

    if (window->proj == PROJECTION_LL) {
        while (window->north > 90.0)
            window->north -= window->ns_res;
        while (window->south < -90.0)
            window->south += window->ns_res;

        if (preserve)
            window->east = window->west + 360;
        else
            while (window->east - window->west > 360.0)
                window->east -= window->ew_res;
    }

    G_adjust_Cell_head(window, 0, 0);
}
Пример #2
0
static void snap_to_grid(struct Cell_head *cur_hd, const struct Cell_head *ref_hd)
{
    int lidx = (int) floor(Rast_easting_to_col( cur_hd->west,  ref_hd));
    int ridx = (int) floor(Rast_easting_to_col( cur_hd->east,  ref_hd));
    int bidx = (int) floor(Rast_northing_to_row(cur_hd->south, ref_hd));
    int tidx = (int) floor(Rast_northing_to_row(cur_hd->north, ref_hd));

    cur_hd->west  = Rast_col_to_easting( lidx + 0.0, ref_hd);
    cur_hd->east  = Rast_col_to_easting( ridx + 1.0, ref_hd);
    cur_hd->south = Rast_row_to_northing(bidx + 1.0, ref_hd);
    cur_hd->north = Rast_row_to_northing(tidx + 0.0, ref_hd);
}
Пример #3
0
/*!
 *  \brief Extract a cell value from raster map (neighbor interpolation)
 *
 *  Extract a cell value from raster map at given northing and easting
 *  with a sampled 3x3 window using a neighbor interpolation.
 *
 *  \param fd file descriptor
 *  \param window region settings
 *  \param cats categories
 *  \param north northing position
 *  \param east easting position
 *  \param usedesc flag to scan category label
 *
 *  \return cell value at given position
 */
DCELL Rast_get_sample_nearest(int fd,
			      const struct Cell_head * window,
			      struct Categories * cats,
			      double north, double east, int usedesc)
{
    int row, col;
    DCELL result;
    DCELL *maprow = Rast_allocate_d_buf();

    /* convert northing and easting to row and col, resp */
    row = (int)floor(Rast_northing_to_row(north, window));
    col = (int)floor(Rast_easting_to_col(east, window));

    if (row < 0 || row >= Rast_window_rows() ||
	col < 0 || col >= Rast_window_cols()) {
	Rast_set_d_null_value(&result, 1);
	goto done;
    }

    Rast_get_d_row(fd, maprow, row);

    if (Rast_is_d_null_value(&maprow[col])) {
	Rast_set_d_null_value(&result, 1);
	goto done;
    }

    if (usedesc) {
	char *buf = Rast_get_c_cat((CELL *) & (maprow[col]), cats);

	G_squeeze(buf);
	result = scancatlabel(buf);
    }
    else
	result = maprow[col];

  done:
    G_free(maprow);

    return result;
}
Пример #4
0
/* 0 on out of region or NULL, 1 on success */
int rast_segment_get_value_xy(SEGMENT * base_segment,
                              struct Cell_head *input_region,
                              RASTER_MAP_TYPE rtype, double x, double y,
                              double *value)
{
    /* Rast gives double, Segment needs off_t */
    off_t base_row = Rast_northing_to_row(y, input_region);
    off_t base_col = Rast_easting_to_col(x, input_region);

    /* skip points which are outside the base raster
     * (null propagation) */
    if (base_row < 0 || base_col < 0 ||
            base_row >= input_region->rows || base_col >= input_region->cols)
        return 0;
    if (rtype == DCELL_TYPE) {
        DCELL tmp;

        Segment_get(base_segment, &tmp, base_row, base_col);
        if (Rast_is_d_null_value(&tmp))
            return 0;
        *value = (double)tmp;
    }
    else if (rtype == FCELL_TYPE) {
        FCELL tmp;

        Segment_get(base_segment, &tmp, base_row, base_col);
        if (Rast_is_f_null_value(&tmp))
            return 0;
        *value = (double)tmp;
    }
    else {
        CELL tmp;

        Segment_get(base_segment, &tmp, base_row, base_col);
        if (Rast_is_c_null_value(&tmp))
            return 0;
        *value = (double)tmp;
    }
    return 1;
}
Пример #5
0
int P_Sparse_Raster_Points(SEGMENT *out_seg, struct Cell_head *Elaboration,
		struct Cell_head *Original, struct bound_box General, struct bound_box Overlap,
		struct Point *obs, double *param, double pe, double pn,
		double overlap, int nsplx, int nsply, int num_points,
		int bilin, double mean)
{
    int i, row, col;
    double X, Y, interpolation, csi, eta, weight, dval;
    int points_in_box = 0;

    /* Reading points inside output region and inside general box */
    /* all points available here are inside the output box,
     * selected by P_Read_Raster_Region_Nulls(), no check needed */

    for (i = 0; i < num_points; i++) {

	X = obs[i].coordX;
	Y = obs[i].coordY;

	/* X,Y are cell center cordinates, MUST be inside General box */
	row = (int) (floor(Rast_northing_to_row(Y, Original)) + 0.1);
	col = (int) (floor((X - Original->west) / Original->ew_res) + 0.1);

	if (row < 0 || row >= Original->rows) {
	    G_fatal_error("row index out of range");
	    continue;
	}

	if (col < 0 || col >= Original->cols) {
	    G_fatal_error("col index out of range");
	    continue;
	}
	points_in_box++;

	G_debug(3, "P_Sparse_Raster_Points: interpolate point %d...", i);
	if (bilin)
	    interpolation =
		dataInterpolateBilin(X, Y, pe, pn, nsplx,
				     nsply, Elaboration->west,
				     Elaboration->south, param);
	else
	    interpolation =
		dataInterpolateBicubic(X, Y, pe, pn, nsplx,
				       nsply, Elaboration->west,
				       Elaboration->south, param);

	interpolation += mean;

	if (Vect_point_in_box(X, Y, interpolation, &Overlap)) {	/* (5) */
	    dval = interpolation;
	}
	else {
	    Segment_get(out_seg, &dval, row, col);
	    if ((X > Overlap.E) && (X < General.E)) {
		if ((Y > Overlap.N) && (Y < General.N)) {	/* (3) */
		    csi = (General.E - X) / overlap;
		    eta = (General.N - Y) / overlap;
		    weight = csi * eta;
		    interpolation *= weight;
		    dval += interpolation;
		}
		else if ((Y < Overlap.S) && (Y > General.S)) {	/* (1) */
		    csi = (General.E - X) / overlap;
		    eta = (Y - General.S) / overlap;
		    weight = csi * eta;
		    interpolation *= weight;
		    dval = interpolation;
		}
		else if ((Y >= Overlap.S) && (Y <= Overlap.N)) {	/* (1) */
		    weight = (General.E - X ) / overlap;
		    interpolation *= weight;
		    dval = interpolation;
		}
	    }
	    else if ((X < Overlap.W) && (X > General.W)) {
		if ((Y > Overlap.N) && (Y < General.N)) {	/* (4) */
		    csi = (X - General.W) / overlap;
		    eta = (General.N - Y) / overlap;
		    weight = eta * csi;
		    interpolation *= weight;
		    dval += interpolation;
		}
		else if ((Y < Overlap.S) && (Y > General.S)) {	/* (2) */
		    csi = (X - General.W) / overlap;
		    eta = (Y - General.S) / overlap;
		    weight = csi * eta;
		    interpolation *= weight;
		    dval += interpolation;
		}
		else if ((Y >= Overlap.S) && (Y <= Overlap.N)) {	/* (2) */
		    weight = (X - General.W) / overlap;
		    interpolation *= weight;
		    dval += interpolation;
		}
	    }
	    else if ((X >= Overlap.W) && (X <= Overlap.E)) {
		if ((Y > Overlap.N) && (Y < General.N)) {	/* (3) */
		    weight = (General.N - Y) / overlap;
		    interpolation *= weight;
		    dval += interpolation;
		}
		else if ((Y < Overlap.S) && (Y > General.S)) {	/* (1) */
		    weight = (Y - General.S) / overlap;
		    interpolation *= weight;
		    dval = interpolation;
		}
	    }
	} /* end not in overlap */
	Segment_put(out_seg, &dval, row, col);
    }  /* for num_points */

    return 1;
}
Пример #6
0
static void resamp_unweighted(void)
{
    stat_func *method_fn;
    DCELL *values;
    int *col_map, *row_map;
    int row, col;

    method_fn = menu[method].method;

    values = G_malloc(row_scale * col_scale * sizeof(DCELL));

    col_map = G_malloc((dst_w.cols + 1) * sizeof(int));
    row_map = G_malloc((dst_w.rows + 1) * sizeof(int));

    for (col = 0; col <= dst_w.cols; col++) {
	double x = Rast_col_to_easting(col, &dst_w);

	col_map[col] = (int)floor(Rast_easting_to_col(x, &src_w) + 0.5);
    }

    for (row = 0; row <= dst_w.rows; row++) {
	double y = Rast_row_to_northing(row, &dst_w);

	row_map[row] = (int)floor(Rast_northing_to_row(y, &src_w) + 0.5);
    }

    for (row = 0; row < dst_w.rows; row++) {
	int maprow0 = row_map[row + 0];
	int maprow1 = row_map[row + 1];
	int count = maprow1 - maprow0;
	int i;

	G_percent(row, dst_w.rows, 2);

	for (i = 0; i < count; i++)
	    Rast_get_d_row(infile, bufs[i], maprow0 + i);

	for (col = 0; col < dst_w.cols; col++) {
	    int mapcol0 = col_map[col + 0];
	    int mapcol1 = col_map[col + 1];
	    int null = 0;
	    int n = 0;
	    int i, j;

	    for (i = maprow0; i < maprow1; i++)
		for (j = mapcol0; j < mapcol1; j++) {
		    DCELL *src = &bufs[i - maprow0][j];
		    DCELL *dst = &values[n++];

		    if (Rast_is_d_null_value(src)) {
			Rast_set_d_null_value(dst, 1);
			null = 1;
		    }
		    else
			*dst = *src;
		}

	    if (null && nulls)
		Rast_set_d_null_value(&outbuf[col], 1);
	    else
		(*method_fn) (&outbuf[col], values, n, closure);
	}

	Rast_put_d_row(outfile, outbuf);
    }
}
Пример #7
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct
    {
	struct Option *rastin, *rastout, *method, *quantile;
    } parm;
    struct
    {
	struct Flag *nulls, *weight;
    } flag;
    struct History history;
    char title[64];
    char buf_nsres[100], buf_ewres[100];
    struct Colors colors;
    int row;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("resample"));
    module->description =
	_("Resamples raster map layers to a coarser grid using aggregation.");

    parm.rastin = G_define_standard_option(G_OPT_R_INPUT);

    parm.rastout = G_define_standard_option(G_OPT_R_OUTPUT);

    parm.method = G_define_option();
    parm.method->key = "method";
    parm.method->type = TYPE_STRING;
    parm.method->required = NO;
    parm.method->description = _("Aggregation method");
    parm.method->options = build_method_list();
    parm.method->answer = "average";

    parm.quantile = G_define_option();
    parm.quantile->key = "quantile";
    parm.quantile->type = TYPE_DOUBLE;
    parm.quantile->required = NO;
    parm.quantile->description = _("Quantile to calculate for method=quantile");
    parm.quantile->options = "0.0-1.0";
    parm.quantile->answer = "0.5";

    flag.nulls = G_define_flag();
    flag.nulls->key = 'n';
    flag.nulls->description = _("Propagate NULLs");

    flag.weight = G_define_flag();
    flag.weight->key = 'w';
    flag.weight->description = _("Weight according to area (slower)");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    nulls = flag.nulls->answer;

    method = find_method(parm.method->answer);
    if (method < 0)
	G_fatal_error(_("Unknown method <%s>"), parm.method->answer);

    if (menu[method].method == c_quant) {
	quantile = atoi(parm.quantile->answer);
	closure = &quantile;
    }

    G_get_set_window(&dst_w);

    /* set window to old map */
    Rast_get_cellhd(parm.rastin->answer, "", &src_w);

    /* enlarge source window */
    {
	int r0 = (int)floor(Rast_northing_to_row(dst_w.north, &src_w));
	int r1 = (int)ceil(Rast_northing_to_row(dst_w.south, &src_w));
	int c0 = (int)floor(Rast_easting_to_col(dst_w.west, &src_w));
	int c1 = (int)ceil(Rast_easting_to_col(dst_w.east, &src_w));

	src_w.south -= src_w.ns_res * (r1 - src_w.rows);
	src_w.north += src_w.ns_res * (-r0);
	src_w.west -= src_w.ew_res * (-c0);
	src_w.east += src_w.ew_res * (c1 - src_w.cols);
	src_w.rows = r1 - r0;
	src_w.cols = c1 - c0;
    }

    Rast_set_input_window(&src_w);
    Rast_set_output_window(&dst_w);

    row_scale = 2 + ceil(dst_w.ns_res / src_w.ns_res);
    col_scale = 2 + ceil(dst_w.ew_res / src_w.ew_res);

    /* allocate buffers for input rows */
    bufs = G_malloc(row_scale * sizeof(DCELL *));
    for (row = 0; row < row_scale; row++)
	bufs[row] = Rast_allocate_d_input_buf();

    /* open old map */
    infile = Rast_open_old(parm.rastin->answer, "");

    /* allocate output buffer */
    outbuf = Rast_allocate_d_output_buf();

    /* open new map */
    outfile = Rast_open_new(parm.rastout->answer, DCELL_TYPE);

    if (flag.weight->answer && menu[method].method_w)
	resamp_weighted();
    else
	resamp_unweighted();

    G_percent(dst_w.rows, dst_w.rows, 2);

    Rast_close(infile);
    Rast_close(outfile);

    /* record map metadata/history info */
    sprintf(title, "Aggregate resample by %s", parm.method->answer);
    Rast_put_cell_title(parm.rastout->answer, title);

    Rast_short_history(parm.rastout->answer, "raster", &history);
    Rast_set_history(&history, HIST_DATSRC_1, parm.rastin->answer);
    G_format_resolution(src_w.ns_res, buf_nsres, src_w.proj);
    G_format_resolution(src_w.ew_res, buf_ewres, src_w.proj);
    Rast_format_history(&history, HIST_DATSRC_2,
			"Source map NS res: %s   EW res: %s",
			buf_nsres, buf_ewres);
    Rast_command_history(&history);
    Rast_write_history(parm.rastout->answer, &history);

    /* copy color table from source map */
    if (strcmp(parm.method->answer, "sum") != 0) {
	if (Rast_read_colors(parm.rastin->answer, "", &colors) < 0)
	    G_fatal_error(_("Unable to read color table for %s"),
			  parm.rastin->answer);
	Rast_mark_colors_as_fp(&colors);
	Rast_write_colors(parm.rastout->answer, G_mapset(), &colors);
    }

    return (EXIT_SUCCESS);
}
Пример #8
0
static void resamp_weighted(void)
{
    stat_func_w *method_fn;

    DCELL(*values)[2];
    double *col_map, *row_map;
    int row, col;

    method_fn = menu[method].method_w;

    values = G_malloc(row_scale * col_scale * 2 * sizeof(DCELL));

    col_map = G_malloc((dst_w.cols + 1) * sizeof(double));
    row_map = G_malloc((dst_w.rows + 1) * sizeof(double));

    for (col = 0; col <= dst_w.cols; col++) {
	double x = Rast_col_to_easting(col, &dst_w);

	col_map[col] = Rast_easting_to_col(x, &src_w);
    }

    for (row = 0; row <= dst_w.rows; row++) {
	double y = Rast_row_to_northing(row, &dst_w);

	row_map[row] = Rast_northing_to_row(y, &src_w);
    }

    for (row = 0; row < dst_w.rows; row++) {
	double y0 = row_map[row + 0];
	double y1 = row_map[row + 1];
	int maprow0 = (int)floor(y0);
	int maprow1 = (int)ceil(y1);
	int count = maprow1 - maprow0;
	int i;

	G_percent(row, dst_w.rows, 2);

	for (i = 0; i < count; i++)
	    Rast_get_d_row(infile, bufs[i], maprow0 + i);

	for (col = 0; col < dst_w.cols; col++) {
	    double x0 = col_map[col + 0];
	    double x1 = col_map[col + 1];
	    int mapcol0 = (int)floor(x0);
	    int mapcol1 = (int)ceil(x1);
	    int null = 0;
	    int n = 0;
	    int i, j;

	    for (i = maprow0; i < maprow1; i++) {
		double ky = (i == maprow0) ? 1 - (y0 - maprow0)
		    : (i == maprow1 - 1) ? 1 - (maprow1 - y1)
		    : 1;

		for (j = mapcol0; j < mapcol1; j++) {
		    double kx = (j == mapcol0) ? 1 - (x0 - mapcol0)
			: (j == mapcol1 - 1) ? 1 - (mapcol1 - x1)
			: 1;

		    DCELL *src = &bufs[i - maprow0][j];
		    DCELL *dst = &values[n++][0];

		    if (Rast_is_d_null_value(src)) {
			Rast_set_d_null_value(&dst[0], 1);
			null = 1;
		    }
		    else {
			dst[0] = *src;
			dst[1] = kx * ky;
		    }
		}
	    }

	    if (null && nulls)
		Rast_set_d_null_value(&outbuf[col], 1);
	    else
		(*method_fn) (&outbuf[col], values, n, closure);
	}

	Rast_put_d_row(outfile, outbuf);
    }
}
Пример #9
0
/* *************************************************************** */
int main(int argc, char *argv[])
{
    int i, j;
    int nfiles;
    int fd[NFILES];
    struct Categories cats[NFILES];
    struct Cell_head window;
    struct Colors ncolor[NFILES];
    struct Colors colors;
    RASTER_MAP_TYPE out_type[NFILES];
    CELL *cell[NFILES];
    DCELL *dcell[NFILES];

    /*   int row, col; */
    double drow, dcol;
    int row_in_window, in_window;
    double east, north;
    int line;
    char buffer[1024];
    char **ptr;
    struct Option *opt1, *opt2, *opt3, *opt4, *opt_fs;
    struct Flag *label_flag, *cache_flag, *int_flag, *color_flag, *header_flag;
    char fs;
    int Cache_size;
    int done = FALSE;
    int point, point_cnt;
    struct order *cache;
    int cur_row;
    int projection;
    int cache_hit = 0, cache_miss = 0;
    int cache_hit_tot = 0, cache_miss_tot = 0;
    int pass = 0;
    int cache_report = FALSE;
    char tmp_buf[500], *null_str;
    int red, green, blue;
    struct GModule *module;


    G_gisinit(argv[0]);

    /* Set description */
    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("position"));
    G_add_keyword(_("querying"));
    module->description =
	_("Queries raster map layers on their category values and category labels.");

    opt1 = G_define_option();
    opt1->key = "input";
    opt1->type = TYPE_STRING;
    opt1->required = YES;
    opt1->multiple = YES;
    opt1->gisprompt = "old,cell,raster";
    opt1->description = _("Name of existing raster map(s) to query");

    opt2 = G_define_option();
    opt2->key = "cache";
    opt2->type = TYPE_INTEGER;
    opt2->required = NO;
    opt2->multiple = NO;
    opt2->description = _("Size of point cache");
    opt2->answer = "500";
    opt2->guisection = _("Advanced");

    opt3 = G_define_option();
    opt3->key = "null";
    opt3->type = TYPE_STRING;
    opt3->required = NO;
    opt3->answer = "*";
    opt3->description = _("Char string to represent no data cell");

    opt_fs = G_define_standard_option(G_OPT_F_SEP);

    opt4 = G_define_option();
    opt4->key = "east_north";
    opt4->type = TYPE_DOUBLE;
    opt4->key_desc = "east,north";
    opt4->required = NO;
    opt4->multiple = YES;
    opt4->description = _("Coordinates for query");

    header_flag = G_define_flag();
    header_flag->key = 'n';
    header_flag->description = _("Output header row");

    label_flag = G_define_flag();
    label_flag->key = 'f';
    label_flag->description = _("Show the category labels of the grid cell(s)");

    color_flag = G_define_flag();
    color_flag->key = 'r';
    color_flag->description = _("Output color values as RRR:GGG:BBB");

    int_flag = G_define_flag();
    int_flag->key = 'i';
    int_flag->description = _("Output integer category values, not cell values");

    cache_flag = G_define_flag();
    cache_flag->key = 'c';
    cache_flag->description = _("Turn on cache reporting");
    cache_flag->guisection = _("Advanced");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);


    tty = isatty(0);

    projection = G_projection();

    /* see v.in.ascii for a better solution */
    if (opt_fs->answer != NULL) {
	if (strcmp(opt_fs->answer, "space") == 0)
	    fs = ' ';
	else if (strcmp(opt_fs->answer, "tab") == 0)
	    fs = '\t';
	else if (strcmp(opt_fs->answer, "\\t") == 0)
	    fs = '\t';
	else
	    fs = opt_fs->answer[0];
    }

    null_str = opt3->answer;


    if (tty)
	Cache_size = 1;
    else
	Cache_size = atoi(opt2->answer);

    if (Cache_size < 1)
	Cache_size = 1;

    cache = (struct order *)G_malloc(sizeof(struct order) * Cache_size);

    /*enable cache report */
    if (cache_flag->answer)
	cache_report = TRUE;


    ptr = opt1->answers;
    nfiles = 0;
    for (; *ptr != NULL; ptr++) {
	char name[GNAME_MAX];

	if (nfiles >= NFILES)
	    G_fatal_error(_("can only do up to %d raster maps"),
			  NFILES);

	strcpy(name, *ptr);
	fd[nfiles] = Rast_open_old(name, "");

	out_type[nfiles] = Rast_get_map_type(fd[nfiles]);
	if (int_flag->answer)
	    out_type[nfiles] = CELL_TYPE;

	if (color_flag->answer) {
	    Rast_read_colors(name, "", &colors);
	    ncolor[nfiles] = colors;
	}

	if (label_flag->answer && Rast_read_cats(name, "", &cats[nfiles]) < 0)
	    G_fatal_error(_("Unable to read category file for <%s>"), name);

	nfiles++;
    }

    for (i = 0; i < nfiles; i++) {
	if (int_flag->answer)
	    out_type[i] = CELL_TYPE;

	cell[i] = Rast_allocate_c_buf();
	if (out_type[i] != CELL_TYPE)
	    dcell[i] = Rast_allocate_d_buf();
    }

    G_get_window(&window);


    if(header_flag->answer) {
	fprintf(stdout, "easting%cnorthing%csite_name", fs, fs);

	ptr = opt1->answers;
	for (; *ptr != NULL; ptr++) {
	    char name[GNAME_MAX];
	    strcpy(name, *ptr);

	    fprintf(stdout, "%c%s", fs, name);

	    if (label_flag->answer)
		fprintf(stdout, "%c%s_label", fs, name);
	    if (color_flag->answer)
		fprintf(stdout, "%c%s_color", fs, name);
	}

	fprintf(stdout, "\n");
    }

    line = 0;
    if (!opt4->answers && tty)
	fprintf(stderr, "enter points, \"end\" to quit\n");

    j = 0;
    done = FALSE;
    while (!done) {
	pass++;
	if (cache_report & !tty)
	    fprintf(stderr, "Pass %3d  Line %6d   - ", pass, line);

	cache_hit = cache_miss = 0;

	if (!opt4->answers && tty) {
	    fprintf(stderr, "\neast north [label] >  ");
	    Cache_size = 1;
	}
	{
	    point_cnt = 0;
	    for (i = 0; i < Cache_size; i++) {
		if (!opt4->answers && fgets(buffer, 1000, stdin) == NULL)
		    done = TRUE;
		else {
		    line++;
		    if ((!opt4->answers &&
			 (strncmp(buffer, "end\n", 4) == 0 ||
			  strncmp(buffer, "exit\n", 5) == 0)) ||
			(opt4->answers && !opt4->answers[j]))
			done = TRUE;
		    else {
			*(cache[point_cnt].lab_buf) =
			    *(cache[point_cnt].east_buf) =
			    *(cache[point_cnt].north_buf) = 0;
			if (!opt4->answers)
			    sscanf(buffer, "%s %s %[^\n]",
				   cache[point_cnt].east_buf,
				   cache[point_cnt].north_buf,
				   cache[point_cnt].lab_buf);
			else {
			    strcpy(cache[point_cnt].east_buf,
				   opt4->answers[j++]);
			    strcpy(cache[point_cnt].north_buf,
				   opt4->answers[j++]);
			}
			if (*(cache[point_cnt].east_buf) == 0)
			    continue;	/* skip blank lines */

			if (*(cache[point_cnt].north_buf) == 0) {
			    oops(line, buffer,
				 "two coordinates (east north) required");
			    continue;
			}
			if (!G_scan_northing
			    (cache[point_cnt].north_buf, &north, window.proj)
			    || !G_scan_easting(cache[point_cnt].east_buf,
					       &east, window.proj)) {
			    oops(line, buffer, "invalid coordinate(s)");
			    continue;
			}

			/* convert north, east to row and col */
			drow = Rast_northing_to_row(north, &window);
			dcol = Rast_easting_to_col(east, &window);

			/* a special case.
			 *   if north falls at southern edge, or east falls on eastern edge,
			 *   the point will appear outside the window.
			 *   So, for these edges, bring the point inside the window
			 */
			if (drow == window.rows)
			    drow--;
			if (dcol == window.cols)
			    dcol--;

			cache[point_cnt].row = (int)drow;
			cache[point_cnt].col = (int)dcol;
			cache[point_cnt].point = point_cnt;
			point_cnt++;
		    }
		}
	    }
	}

	if (Cache_size > 1)
	    qsort(cache, point_cnt, sizeof(struct order), by_row);

	/* extract data from files and store in cache */

	cur_row = -99;

	for (point = 0; point < point_cnt; point++) {
	    row_in_window = 1;
	    in_window = 1;
	    if (cache[point].row < 0 || cache[point].row >= window.rows)
		row_in_window = in_window = 0;
	    if (cache[point].col < 0 || cache[point].col >= window.cols)
		in_window = 0;

	    if (!in_window) {
		if (tty)
		    fprintf(stderr,
			    "** note ** %s %s is outside your current window\n",
			    cache[point].east_buf, cache[point].north_buf);
	    }

	    if (cur_row != cache[point].row) {
		cache_miss++;
		if (row_in_window)
		    for (i = 0; i < nfiles; i++) {
			Rast_get_c_row(fd[i], cell[i], cache[point].row);

			if (out_type[i] != CELL_TYPE)
			    Rast_get_d_row(fd[i], dcell[i], cache[point].row);
		    }

		cur_row = cache[point].row;
	    }
	    else
		cache_hit++;

	    for (i = 0; i < nfiles; i++) {
		if (in_window)
		    cache[point].value[i] = cell[i][cache[point].col];
		else
		    Rast_set_c_null_value(&(cache[point].value[i]), 1);

		if (out_type[i] != CELL_TYPE) {
		    if (in_window)
			cache[point].dvalue[i] = dcell[i][cache[point].col];
		    else
			Rast_set_d_null_value(&(cache[point].dvalue[i]), 1);
		}
		if (color_flag->answer) {
		    if (out_type[i] == CELL_TYPE)
			Rast_get_c_color(&cell[i][cache[point].col],
					     &red, &green, &blue, &ncolor[i]);
		    else
			Rast_get_d_color(&dcell[i][cache[point].col],
					     &red, &green, &blue, &ncolor[i]);

		    sprintf(cache[point].clr_buf[i], "%03d:%03d:%03d", red,
			    green, blue);
		}

	    }
	}			/* point loop */

	if (Cache_size > 1)
	    qsort(cache, point_cnt, sizeof(struct order), by_point);

	/* report data from re-ordered cache */

	for (point = 0; point < point_cnt; point++) {

	    G_debug(1, "%s|%s at col %d, row %d\n",
		    cache[point].east_buf, cache[point].north_buf,
		    cache[point].col, cache[point].row);


	    fprintf(stdout, "%s%c%s%c%s", cache[point].east_buf, fs,
		    cache[point].north_buf, fs, cache[point].lab_buf);

	    for (i = 0; i < nfiles; i++) {
		if (out_type[i] == CELL_TYPE) {
		    if (Rast_is_c_null_value(&cache[point].value[i])) {
			fprintf(stdout, "%c%s", fs, null_str);
			if (label_flag->answer)
			    fprintf(stdout, "%c", fs);
			if (color_flag->answer)
			    fprintf(stdout, "%c", fs);
			continue;
		    }
		    fprintf(stdout, "%c%ld", fs, (long)cache[point].value[i]);
		}
		else {		/* FCELL or DCELL */

		    if (Rast_is_d_null_value(&cache[point].dvalue[i])) {
			fprintf(stdout, "%c%s", fs, null_str);
			if (label_flag->answer)
			    fprintf(stdout, "%c", fs);
			if (color_flag->answer)
			    fprintf(stdout, "%c", fs);
			continue;
		    }
		    if (out_type[i] == FCELL_TYPE)
			sprintf(tmp_buf, "%.7g", cache[point].dvalue[i]);
		    else /* DCELL */
			sprintf(tmp_buf, "%.15g", cache[point].dvalue[i]);
		    G_trim_decimal(tmp_buf); /* not needed with %g? */
		    fprintf(stdout, "%c%s", fs, tmp_buf);
		}
		if (label_flag->answer)
		    fprintf(stdout, "%c%s", fs,
			    Rast_get_c_cat(&(cache[point].value[i]), &cats[i]));
		if (color_flag->answer)
		    fprintf(stdout, "%c%s", fs, cache[point].clr_buf[i]);
	    }
	    fprintf(stdout, "\n");
	}

	if (cache_report & !tty)
	    fprintf(stderr, "Cache  Hit: %6d  Miss: %6d\n",
		    cache_hit, cache_miss);

	cache_hit_tot += cache_hit;
	cache_miss_tot += cache_miss;
	cache_hit = cache_miss = 0;
    }

    if (!opt4->answers && tty)
	fprintf(stderr, "\n");
    if (cache_report & !tty)
	fprintf(stderr, "Total:    Cache  Hit: %6d  Miss: %6d\n",
		cache_hit_tot, cache_miss_tot);

    exit(EXIT_SUCCESS);
}
Пример #10
0
/*!
 *  \brief Extract a cell value from raster map (bilinear interpolation).
 *
 *  Extract a cell value from raster map at given northing and easting
 *  with a sampled 3x3 window using a bilinear interpolation.
 *
 *  \param fd file descriptor
 *  \param window region settings
 *  \param cats categories
 *  \param north northing position
 *  \param east easting position
 *  \param usedesc flag to scan category label
 *
 *  \return cell value at given position
 */
DCELL Rast_get_sample_bilinear(int fd,
			       const struct Cell_head * window,
			       struct Categories * cats,
			       double north, double east, int usedesc)
{
    int row, col;
    double grid[2][2];
    DCELL *arow = Rast_allocate_d_buf();
    DCELL *brow = Rast_allocate_d_buf();
    double frow, fcol, trow, tcol;
    DCELL result;

    frow = Rast_northing_to_row(north, window);
    fcol = Rast_easting_to_col(east, window);

    /* convert northing and easting to row and col, resp */
    row = (int)floor(frow - 0.5);
    col = (int)floor(fcol - 0.5);

    trow = frow - row - 0.5;
    tcol = fcol - col - 0.5;

    if (row < 0 || row + 1 >= Rast_window_rows() ||
	col < 0 || col + 1 >= Rast_window_cols()) {
	Rast_set_d_null_value(&result, 1);
	goto done;
    }

    Rast_get_d_row(fd, arow, row);
    Rast_get_d_row(fd, brow, row + 1);

    if (Rast_is_d_null_value(&arow[col]) ||
	Rast_is_d_null_value(&arow[col + 1]) ||
	Rast_is_d_null_value(&brow[col]) ||
	Rast_is_d_null_value(&brow[col + 1])) {
	Rast_set_d_null_value(&result, 1);
	goto done;
    }

    /*-
     * now were ready to do bilinear interpolation over
     * arow[col], arow[col+1],
     * brow[col], brow[col+1]
     */

    if (usedesc) {
	char *buf;

	G_squeeze(buf = Rast_get_c_cat((int *)&(arow[col]), cats));
	grid[0][0] = scancatlabel(buf);
	G_squeeze(buf = Rast_get_c_cat((CELL *) & (arow[col + 1]), cats));
	grid[0][1] = scancatlabel(buf);
	G_squeeze(buf = Rast_get_c_cat((CELL *) & (brow[col]), cats));
	grid[1][0] = scancatlabel(buf);
	G_squeeze(buf = Rast_get_c_cat((CELL *) & (brow[col + 1]), cats));
	grid[1][1] = scancatlabel(buf);
    }
    else {
	grid[0][0] = arow[col];
	grid[0][1] = arow[col + 1];
	grid[1][0] = brow[col];
	grid[1][1] = brow[col + 1];
    }

    result = Rast_interp_bilinear(tcol, trow,
				  grid[0][0], grid[0][1], grid[1][0],
				  grid[1][1]);

  done:
    G_free(arow);
    G_free(brow);

    return result;
}
Пример #11
0
int main(int argc, char *argv[])
{
    char *terrainmap, *seedmap, *lakemap;
    int rows, cols, in_terran_fd, out_fd, lake_fd, row, col, pases, pass;
    int lastcount, curcount, start_col = 0, start_row = 0;
    double east, north, area = 0, volume = 0;
    FCELL **in_terran, **out_water, water_level, max_depth = 0, min_depth = 0;
    FCELL water_window[3][3];
    struct Option *tmap_opt, *smap_opt, *wlvl_opt, *lake_opt, *sdxy_opt;
    struct Flag *negative_flag, *overwrite_flag;
    struct GModule *module;
    struct Colors colr;
    struct Cell_head window;
    struct History history;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("hydrology"));
    G_add_keyword(_("hazard"));
    G_add_keyword(_("flood"));
    module->description = _("Fills lake at given point to given level.");

    tmap_opt = G_define_standard_option(G_OPT_R_ELEV);

    wlvl_opt = G_define_option();
    wlvl_opt->key = "water_level";
    wlvl_opt->description = _("Water level");
    wlvl_opt->type = TYPE_DOUBLE;
    wlvl_opt->required = YES;

    lake_opt = G_define_standard_option(G_OPT_R_OUTPUT);
    lake_opt->key = "lake";
    lake_opt->required = NO;
    lake_opt->guisection = _("Output");

    sdxy_opt = G_define_standard_option(G_OPT_M_COORDS);
    sdxy_opt->label = _("Seed point coordinates");
    sdxy_opt->description = _("Either this coordinates pair or a seed"
	" map have to be specified");
    sdxy_opt->required = NO;
    sdxy_opt->multiple = NO;
    sdxy_opt->guisection = _("Seed");

    smap_opt = G_define_standard_option(G_OPT_R_MAP);
    smap_opt->key = "seed";
    smap_opt->label =
	_("Input raster map with given starting point(s) (at least 1 cell > 0)");
    smap_opt->description =
	_("Either this parameter or a coordinates pair have to be specified");
    smap_opt->required = NO;
    smap_opt->guisection = _("Seed");

    negative_flag = G_define_flag();
    negative_flag->key = 'n';
    negative_flag->description =
	_("Use negative depth values for lake raster map");

    overwrite_flag = G_define_flag();
    overwrite_flag->key = 'o';
    overwrite_flag->description =
	_("Overwrite seed map with result (lake) map");
    overwrite_flag->guisection = _("Output");

    if (G_parser(argc, argv))	/* Returns 0 if successful, non-zero otherwise */
	exit(EXIT_FAILURE);

    if (smap_opt->answer && sdxy_opt->answer)
	G_fatal_error(_("Both seed map and coordinates cannot be specified"));

    if (!smap_opt->answer && !sdxy_opt->answer)
	G_fatal_error(_("Seed map or seed coordinates must be set!"));

    if (sdxy_opt->answer && !lake_opt->answer)
	G_fatal_error(_("Seed coordinates and output map lake= must be set!"));

    if (lake_opt->answer && overwrite_flag->answer)
	G_fatal_error(_("Both lake and overwrite cannot be specified"));

    if (!lake_opt->answer && !overwrite_flag->answer)
	G_fatal_error(_("Output lake map or overwrite flag must be set!"));

    terrainmap = tmap_opt->answer;
    seedmap = smap_opt->answer;
    sscanf(wlvl_opt->answer, "%f", &water_level);
    lakemap = lake_opt->answer;

    /* If lakemap is set, write to it, else is set overwrite flag and we should write to seedmap. */
    if (lakemap)
	lake_fd = Rast_open_new(lakemap, 1);

    rows = Rast_window_rows();
    cols = Rast_window_cols();

    /* If we use x,y as seed... */
    if (sdxy_opt->answer) {
	G_get_window(&window);
	east = window.east;
	north = window.north;

	G_scan_easting(sdxy_opt->answers[0], &east, G_projection());
	G_scan_northing(sdxy_opt->answers[1], &north, G_projection());
	start_col = (int)Rast_easting_to_col(east, &window);
	start_row = (int)Rast_northing_to_row(north, &window);

	if (start_row < 0 || start_row > rows ||
	    start_col < 0 || start_col > cols)
	    G_fatal_error(_("Seed point outside the current region"));
    }

    /* Open terrain map */
    in_terran_fd = Rast_open_old(terrainmap, "");

    /* Open seed map */
    if (smap_opt->answer)
	out_fd = Rast_open_old(seedmap, "");

    /* Pointers to rows. Row = ptr to 'col' size array. */
    in_terran = (FCELL **) G_malloc(rows * sizeof(FCELL *));
    out_water = (FCELL **) G_malloc(rows * sizeof(FCELL *));
    if (in_terran == NULL || out_water == NULL)
	G_fatal_error(_("G_malloc: out of memory"));


    G_debug(1, "Loading maps...");
    /* foo_rows[row] == array with data (2d array). */
    for (row = 0; row < rows; row++) {
	in_terran[row] = (FCELL *) G_malloc(cols * sizeof(FCELL));
	out_water[row] = (FCELL *) G_calloc(cols, sizeof(FCELL));

	/* In newly created space load data from file. */
	Rast_get_f_row(in_terran_fd, in_terran[row], row);

	if (smap_opt->answer)
	    Rast_get_f_row(out_fd, out_water[row], row);

	G_percent(row + 1, rows, 5);
    }

    /* Set seed point */
    if (sdxy_opt->answer)
	/* Check is water level higher than seed point */
	if (in_terran[start_row][start_col] >= water_level)
	    G_fatal_error(_("Given water level at seed point is below earth surface. "
			   "Increase water level or move seed point."));
    out_water[start_row][start_col] = 1;

    /* Close seed map for reading. */
    if (smap_opt->answer)
	Rast_close(out_fd);

    /* Open output map for writing. */
    if (lakemap)
	out_fd = lake_fd;
    else
	out_fd = Rast_open_new(seedmap, 1);

    /* More pases are renudant. Real pases count is controlled by altered cell count. */
    pases = (int)(rows * cols) / 2;

    G_debug(1,
	    "Starting lake filling at level of %8.4f in %d passes. Percent done:",
	    water_level, pases);

    lastcount = 0;

    for (pass = 0; pass < pases; pass++) {
	G_debug(3, "Pass: %d", pass);
	curcount = 0;
	/* Move from left upper corner to right lower corner. */
	for (row = 0; row < rows; row++) {
	    for (col = 0; col < cols; col++) {
		/* Loading water data into window. */
		load_window_values(out_water, water_window, rows, cols, row,
				   col);

		/* Cheking presence of water. */
		if (is_near_water(water_window) == 1) {
		    if (in_terran[row][col] < water_level) {
			out_water[row][col] =
			    water_level - in_terran[row][col];
			curcount++;
		    }
		    else {
			out_water[row][col] = 0;	/* Cell is higher than water level -> NULL. */
		    }
		}
	    }
	}
	if (curcount == lastcount)
	    break;		/* We done. */
	lastcount = curcount;
	curcount = 0;
	/* Move backwards - from lower right corner to upper left corner. */
	for (row = rows - 1; row >= 0; row--) {
	    for (col = cols - 1; col >= 0; col--) {
		load_window_values(out_water, water_window, rows, cols, row,
				   col);

		if (is_near_water(water_window) == 1) {
		    if (in_terran[row][col] < water_level) {
			out_water[row][col] =
			    water_level - in_terran[row][col];
			curcount++;
		    }
		    else {
			out_water[row][col] = 0;
		    }
		}
	    }
	}
	G_percent(pass + 1, pases, 10);
	if (curcount == lastcount)
	    break;		/* We done. */
	lastcount = curcount;
    }				/*pases */

    G_percent(pases, pases, 10);	/* Show 100%. */

    save_map(out_water, out_fd, rows, cols, negative_flag->answer, &min_depth,
	     &max_depth, &area, &volume);

    G_message(_("Lake depth from %f to %f (specified water level is taken as zero)"), min_depth, max_depth);
    G_message(_("Lake area %f square meters"), area);
    G_message(_("Lake volume %f cubic meters"), volume);
    G_important_message(_("Volume is correct only if lake depth (terrain raster map) is in meters"));

    /* Close all files. Lake map gets written only now. */
    Rast_close(in_terran_fd);
    Rast_close(out_fd);

    /* Add blue color gradient from light bank to dark depth */
    Rast_init_colors(&colr);
    if (negative_flag->answer == 1) {
	Rast_add_f_color_rule(&max_depth, 0, 240, 255,
				  &min_depth, 0, 50, 170, &colr);
    }
    else {
	Rast_add_f_color_rule(&min_depth, 0, 240, 255,
				  &max_depth, 0, 50, 170, &colr);
    }

    Rast_write_colors(lakemap, G_mapset(), &colr);

    Rast_short_history(lakemap, "raster", &history);
    Rast_command_history(&history);
    Rast_write_history(lakemap, &history);

    return EXIT_SUCCESS;
}
Пример #12
0
int main(int argc, char *argv[])
{
    struct GModule *module;
    struct Option *rastin, *rastout, *method;
    struct History history;
    char title[64];
    char buf_nsres[100], buf_ewres[100];
    struct Colors colors;
    int infile, outfile;
    DCELL *outbuf;
    int row, col;
    struct Cell_head dst_w, src_w;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("resample"));
    module->description =
	_("Resamples raster map layers to a finer grid using interpolation.");

    rastin = G_define_standard_option(G_OPT_R_INPUT);
    rastout = G_define_standard_option(G_OPT_R_OUTPUT);

    method = G_define_option();
    method->key = "method";
    method->type = TYPE_STRING;
    method->required = NO;
    method->description = _("Interpolation method");
    method->options = "nearest,bilinear,bicubic,lanczos";
    method->answer = "bilinear";

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    if (G_strcasecmp(method->answer, "nearest") == 0)
	neighbors = 1;
    else if (G_strcasecmp(method->answer, "bilinear") == 0)
	neighbors = 2;
    else if (G_strcasecmp(method->answer, "bicubic") == 0)
	neighbors = 4;
    else if (G_strcasecmp(method->answer, "lanczos") == 0)
	neighbors = 5;
    else
	G_fatal_error(_("Invalid method: %s"), method->answer);

    G_get_set_window(&dst_w);

    /* set window to old map */
    Rast_get_cellhd(rastin->answer, "", &src_w);

    /* enlarge source window */
    {
	double north = Rast_row_to_northing(0.5, &dst_w);
	double south = Rast_row_to_northing(dst_w.rows - 0.5, &dst_w);
	int r0 = (int)floor(Rast_northing_to_row(north, &src_w) - 0.5) - 2;
	int r1 = (int)floor(Rast_northing_to_row(south, &src_w) - 0.5) + 3;
	double west = Rast_col_to_easting(0.5, &dst_w);
	double east = Rast_col_to_easting(dst_w.cols - 0.5, &dst_w);
	int c0 = (int)floor(Rast_easting_to_col(west, &src_w) - 0.5) - 2;
	int c1 = (int)floor(Rast_easting_to_col(east, &src_w) - 0.5) + 3;

	src_w.south -= src_w.ns_res * (r1 - src_w.rows);
	src_w.north += src_w.ns_res * (-r0);
	src_w.west -= src_w.ew_res * (-c0);
	src_w.east += src_w.ew_res * (c1 - src_w.cols);
	src_w.rows = r1 - r0;
	src_w.cols = c1 - c0;
    }

    Rast_set_input_window(&src_w);

    /* allocate buffers for input rows */
    for (row = 0; row < neighbors; row++)
	bufs[row] = Rast_allocate_d_input_buf();

    cur_row = -100;

    /* open old map */
    infile = Rast_open_old(rastin->answer, "");

    /* reset window to current region */
    Rast_set_output_window(&dst_w);

    outbuf = Rast_allocate_d_output_buf();

    /* open new map */
    outfile = Rast_open_new(rastout->answer, DCELL_TYPE);

    switch (neighbors) {
    case 1:			/* nearest */
	for (row = 0; row < dst_w.rows; row++) {
	    double north = Rast_row_to_northing(row + 0.5, &dst_w);
	    double maprow_f = Rast_northing_to_row(north, &src_w) - 0.5;
	    int maprow0 = (int)floor(maprow_f + 0.5);

	    G_percent(row, dst_w.rows, 2);

	    read_rows(infile, maprow0);

	    for (col = 0; col < dst_w.cols; col++) {
		double east = Rast_col_to_easting(col + 0.5, &dst_w);
		double mapcol_f = Rast_easting_to_col(east, &src_w) - 0.5;
		int mapcol0 = (int)floor(mapcol_f + 0.5);

		double c = bufs[0][mapcol0];

		if (Rast_is_d_null_value(&c)) {
		    Rast_set_d_null_value(&outbuf[col], 1);
		}
		else {
		    outbuf[col] = c;
		}
	    }

	    Rast_put_d_row(outfile, outbuf);
	}
	break;

    case 2:			/* bilinear */
	for (row = 0; row < dst_w.rows; row++) {
	    double north = Rast_row_to_northing(row + 0.5, &dst_w);
	    double maprow_f = Rast_northing_to_row(north, &src_w) - 0.5;
	    int maprow0 = (int)floor(maprow_f);
	    double v = maprow_f - maprow0;

	    G_percent(row, dst_w.rows, 2);

	    read_rows(infile, maprow0);

	    for (col = 0; col < dst_w.cols; col++) {
		double east = Rast_col_to_easting(col + 0.5, &dst_w);
		double mapcol_f = Rast_easting_to_col(east, &src_w) - 0.5;
		int mapcol0 = (int)floor(mapcol_f);
		int mapcol1 = mapcol0 + 1;
		double u = mapcol_f - mapcol0;

		double c00 = bufs[0][mapcol0];
		double c01 = bufs[0][mapcol1];
		double c10 = bufs[1][mapcol0];
		double c11 = bufs[1][mapcol1];

		if (Rast_is_d_null_value(&c00) ||
		    Rast_is_d_null_value(&c01) ||
		    Rast_is_d_null_value(&c10) || Rast_is_d_null_value(&c11)) {
		    Rast_set_d_null_value(&outbuf[col], 1);
		}
		else {
		    outbuf[col] = Rast_interp_bilinear(u, v, c00, c01, c10, c11);
		}
	    }

	    Rast_put_d_row(outfile, outbuf);
	}
	break;

    case 4:			/* bicubic */
	for (row = 0; row < dst_w.rows; row++) {
	    double north = Rast_row_to_northing(row + 0.5, &dst_w);
	    double maprow_f = Rast_northing_to_row(north, &src_w) - 0.5;
	    int maprow1 = (int)floor(maprow_f);
	    int maprow0 = maprow1 - 1;
	    double v = maprow_f - maprow1;

	    G_percent(row, dst_w.rows, 2);

	    read_rows(infile, maprow0);

	    for (col = 0; col < dst_w.cols; col++) {
		double east = Rast_col_to_easting(col + 0.5, &dst_w);
		double mapcol_f = Rast_easting_to_col(east, &src_w) - 0.5;
		int mapcol1 = (int)floor(mapcol_f);
		int mapcol0 = mapcol1 - 1;
		int mapcol2 = mapcol1 + 1;
		int mapcol3 = mapcol1 + 2;
		double u = mapcol_f - mapcol1;

		double c00 = bufs[0][mapcol0];
		double c01 = bufs[0][mapcol1];
		double c02 = bufs[0][mapcol2];
		double c03 = bufs[0][mapcol3];

		double c10 = bufs[1][mapcol0];
		double c11 = bufs[1][mapcol1];
		double c12 = bufs[1][mapcol2];
		double c13 = bufs[1][mapcol3];

		double c20 = bufs[2][mapcol0];
		double c21 = bufs[2][mapcol1];
		double c22 = bufs[2][mapcol2];
		double c23 = bufs[2][mapcol3];

		double c30 = bufs[3][mapcol0];
		double c31 = bufs[3][mapcol1];
		double c32 = bufs[3][mapcol2];
		double c33 = bufs[3][mapcol3];

		if (Rast_is_d_null_value(&c00) ||
		    Rast_is_d_null_value(&c01) ||
		    Rast_is_d_null_value(&c02) ||
		    Rast_is_d_null_value(&c03) ||
		    Rast_is_d_null_value(&c10) ||
		    Rast_is_d_null_value(&c11) ||
		    Rast_is_d_null_value(&c12) ||
		    Rast_is_d_null_value(&c13) ||
		    Rast_is_d_null_value(&c20) ||
		    Rast_is_d_null_value(&c21) ||
		    Rast_is_d_null_value(&c22) ||
		    Rast_is_d_null_value(&c23) ||
		    Rast_is_d_null_value(&c30) ||
		    Rast_is_d_null_value(&c31) ||
		    Rast_is_d_null_value(&c32) || Rast_is_d_null_value(&c33)) {
		    Rast_set_d_null_value(&outbuf[col], 1);
		}
		else {
		    outbuf[col] = Rast_interp_bicubic(u, v,
						   c00, c01, c02, c03,
						   c10, c11, c12, c13,
						   c20, c21, c22, c23,
						   c30, c31, c32, c33);
		}
	    }

	    Rast_put_d_row(outfile, outbuf);
	}
	break;

    case 5:			/* lanczos */
	for (row = 0; row < dst_w.rows; row++) {
	    double north = Rast_row_to_northing(row + 0.5, &dst_w);
	    double maprow_f = Rast_northing_to_row(north, &src_w) - 0.5;
	    int maprow1 = (int)floor(maprow_f + 0.5);
	    int maprow0 = maprow1 - 2;
	    double v = maprow_f - maprow1;

	    G_percent(row, dst_w.rows, 2);

	    read_rows(infile, maprow0);

	    for (col = 0; col < dst_w.cols; col++) {
		double east = Rast_col_to_easting(col + 0.5, &dst_w);
		double mapcol_f = Rast_easting_to_col(east, &src_w) - 0.5;
		int mapcol2 = (int)floor(mapcol_f + 0.5);
		int mapcol0 = mapcol2 - 2;
		int mapcol4 = mapcol2 + 2;
		double u = mapcol_f - mapcol2;
		double c[25];
		int ci = 0, i, j, do_lanczos = 1;

		for (i = 0; i < 5; i++) {
		    for (j = mapcol0; j <= mapcol4; j++) {
			c[ci] = bufs[i][j];
			if (Rast_is_d_null_value(&(c[ci]))) {
			    Rast_set_d_null_value(&outbuf[col], 1);
			    do_lanczos = 0;
			    break;
			}
			ci++;
		    }
		    if (!do_lanczos)
			break;
		}

		if (do_lanczos) {
		    outbuf[col] = Rast_interp_lanczos(u, v, c);
		}
	    }

	    Rast_put_d_row(outfile, outbuf);
	}
	break;
    }

    G_percent(dst_w.rows, dst_w.rows, 2);

    Rast_close(infile);
    Rast_close(outfile);


    /* record map metadata/history info */
    sprintf(title, "Resample by %s interpolation", method->answer);
    Rast_put_cell_title(rastout->answer, title);

    Rast_short_history(rastout->answer, "raster", &history);
    Rast_set_history(&history, HIST_DATSRC_1, rastin->answer);
    G_format_resolution(src_w.ns_res, buf_nsres, src_w.proj);
    G_format_resolution(src_w.ew_res, buf_ewres, src_w.proj);
    Rast_format_history(&history, HIST_DATSRC_2,
			"Source map NS res: %s   EW res: %s",
			buf_nsres, buf_ewres);
    Rast_command_history(&history);
    Rast_write_history(rastout->answer, &history);

    /* copy color table from source map */
    if (Rast_read_colors(rastin->answer, "", &colors) < 0)
	G_fatal_error(_("Unable to read color table for %s"), rastin->answer);
    Rast_mark_colors_as_fp(&colors);
    Rast_write_colors(rastout->answer, G_mapset(), &colors);

    return (EXIT_SUCCESS);
}
Пример #13
0
int main(int argc, char *argv[])
{
    extern struct Cell_head window;
    union RASTER_PTR elevbuf, tmpbuf, outbuf;
    CELL min, max;
    DCELL dvalue, dvalue2, dmin, dmax;
    struct History hist;
    RASTER_MAP_TYPE data_type;
    struct Range range;
    struct FPRange fprange;
    double drow, dcol;
    int elev_fd, output_fd, zeros;
    struct
    {
	struct Option *opt1, *opt2, *opt3, *opt4, *north, *east, *year,
	    *month, *day, *hour, *minutes, *seconds, *timezone;
    } parm;
    struct Flag *flag1, *flag3, *flag4;
    struct GModule *module;
    char *name, *outname;
    double dazi, dalti;
    double azi, alti;
    double nstep, estep;
    double maxh;
    double east, east1, north, north1;
    int row1, col1;
    char OK;
    double timezone;
    int year, month, day, hour, minutes, seconds;
    long retval;
    int solparms, locparms, use_solpos;
    double sunrise, sunset, current_time;
    int sretr = 0, ssetr = 0, sretr_sec = 0, ssetr_sec = 0;
    double dsretr, dssetr;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("raster"));
    G_add_keyword(_("sun position"));
    module->label = _("Calculates cast shadow areas from sun position and elevation raster map.");
    module->description = _("Either exact sun position (A) is specified, or date/time to calculate "
			    "the sun position (B) by r.sunmask itself.");
    
    parm.opt1 = G_define_standard_option(G_OPT_R_ELEV);
    
    parm.opt2 = G_define_standard_option(G_OPT_R_OUTPUT);
    parm.opt2->required = NO;
    
    parm.opt3 = G_define_option();
    parm.opt3->key = "altitude";
    parm.opt3->type = TYPE_DOUBLE;
    parm.opt3->required = NO;
    parm.opt3->options = "0-89.999";
    parm.opt3->description =
	_("Altitude of the sun above horizon, degrees (A)");
    parm.opt3->guisection = _("Position");

    parm.opt4 = G_define_option();
    parm.opt4->key = "azimuth";
    parm.opt4->type = TYPE_DOUBLE;
    parm.opt4->required = NO;
    parm.opt4->options = "0-360";
    parm.opt4->description =
	_("Azimuth of the sun from the north, degrees (A)");
    parm.opt4->guisection = _("Position");

    parm.year = G_define_option();
    parm.year->key = "year";
    parm.year->type = TYPE_INTEGER;
    parm.year->required = NO;
    parm.year->description = _("Year (B)");
    parm.year->options = "1950-2050";
    parm.year->guisection = _("Time");

    parm.month = G_define_option();
    parm.month->key = "month";
    parm.month->type = TYPE_INTEGER;
    parm.month->required = NO;
    parm.month->description = _("Month (B)");
    parm.month->options = "0-12";
    parm.month->guisection = _("Time");

    parm.day = G_define_option();
    parm.day->key = "day";
    parm.day->type = TYPE_INTEGER;
    parm.day->required = NO;
    parm.day->description = _("Day (B)");
    parm.day->options = "0-31";
    parm.day->guisection = _("Time");

    parm.hour = G_define_option();
    parm.hour->key = "hour";
    parm.hour->type = TYPE_INTEGER;
    parm.hour->required = NO;
    parm.hour->description = _("Hour (B)");
    parm.hour->options = "0-24";
    parm.hour->guisection = _("Time");

    parm.minutes = G_define_option();
    parm.minutes->key = "minute";
    parm.minutes->type = TYPE_INTEGER;
    parm.minutes->required = NO;
    parm.minutes->description = _("Minutes (B)");
    parm.minutes->options = "0-60";
    parm.minutes->guisection = _("Time");

    parm.seconds = G_define_option();
    parm.seconds->key = "second";
    parm.seconds->type = TYPE_INTEGER;
    parm.seconds->required = NO;
    parm.seconds->description = _("Seconds (B)");
    parm.seconds->options = "0-60";
    parm.seconds->guisection = _("Time");

    parm.timezone = G_define_option();
    parm.timezone->key = "timezone";
    parm.timezone->type = TYPE_INTEGER;
    parm.timezone->required = NO;
    parm.timezone->label =
	_("Timezone");
    parm.timezone->description = _("East positive, offset from GMT, also use to adjust daylight savings");
    parm.timezone->guisection = _("Time");

    parm.east = G_define_option();
    parm.east->key = "east";
    parm.east->key_desc = "value";
    parm.east->type = TYPE_STRING;
    parm.east->required = NO;
    parm.east->label =
	_("Easting coordinate (point of interest)");
    parm.east->description = _("Default: map center");
    parm.east->guisection = _("Position");

    parm.north = G_define_option();
    parm.north->key = "north";
    parm.north->key_desc = "value";
    parm.north->type = TYPE_STRING;
    parm.north->required = NO;
    parm.north->label =
	_("Northing coordinate (point of interest)");
    parm.north->description = _("Default: map center");
    parm.north->guisection = _("Position");

    flag1 = G_define_flag();
    flag1->key = 'z';
    flag1->description = _("Don't ignore zero elevation");

    flag3 = G_define_flag();
    flag3->key = 's';
    flag3->description = _("Calculate sun position only and exit");
    flag3->guisection = _("Print");
    
    flag4 = G_define_flag();
    flag4->key = 'g';
    flag4->description =
	_("Print the sun position output in shell script style");
    flag4->guisection = _("Print");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    zeros = flag1->answer;

    G_get_window(&window);

    /* if not given, get east and north: XX */
    if (!parm.north->answer || !parm.east->answer) {
	north = (window.north - window.south) / 2. + window.south;
	east = (window.west - window.east) / 2. + window.east;
	G_verbose_message(_("Using map center coordinates: %f %f"), east, north);
    }
    else {			/* user defined east, north: */

	sscanf(parm.north->answer, "%lf", &north);
	sscanf(parm.east->answer, "%lf", &east);
	if (strlen(parm.east->answer) == 0)
	    G_fatal_error(_("Empty east coordinate specified"));
	if (strlen(parm.north->answer) == 0)
	    G_fatal_error(_("Empty north coordinate specified"));
    }

    /* check which method to use for sun position:
       either user defines directly sun position or it is calculated */

    if (parm.opt3->answer && parm.opt4->answer)
	solparms = 1;		/* opt3 & opt4 complete */
    else
	solparms = 0;		/* calculate sun position */

    if (parm.year->answer && parm.month->answer && parm.day->answer &&
	parm.hour->answer && parm.minutes->answer && parm.seconds->answer &&
	parm.timezone->answer)
	locparms = 1;		/* complete */
    else
	locparms = 0;

    if (solparms && locparms)	/* both defined */
	G_fatal_error(_("Either define sun position or location/date/time parameters"));

    if (!solparms && !locparms)	/* nothing defined */
	G_fatal_error(_("Neither sun position nor east/north, date/time/timezone definition are complete"));

    /* if here, one definition was complete */
    if (locparms) {
	G_message(_("Calculating sun position... (using solpos (V. %s) from NREL)"),
		  SOLPOSVERSION);
	use_solpos = 1;
    }
    else {
	G_message(_("Using user defined sun azimuth, altitude settings (ignoring eventual other values)"));
	use_solpos = 0;
    }

    name = parm.opt1->answer;
    outname = parm.opt2->answer;
    if (!use_solpos) {
	sscanf(parm.opt3->answer, "%lf", &dalti);
	sscanf(parm.opt4->answer, "%lf", &dazi);
    }
    else {
	sscanf(parm.year->answer, "%i", &year);
	sscanf(parm.month->answer, "%i", &month);
	sscanf(parm.day->answer, "%i", &day);
	sscanf(parm.hour->answer, "%i", &hour);
	sscanf(parm.minutes->answer, "%i", &minutes);
	sscanf(parm.seconds->answer, "%i", &seconds);
	sscanf(parm.timezone->answer, "%lf", &timezone);
    }

    /* NOTES: G_calc_solar_position ()
       - the algorithm will compensate for leap year.
       - longitude, latitude: decimal degree
       - timezone: DO NOT ADJUST FOR DAYLIGHT SAVINGS TIME.
       - timezone: negative for zones west of Greenwich
       - lat/long: east and north positive
       - the atmospheric refraction is calculated for 1013hPa, 15�C 
       - time: local time from your watch

       Order of parameters:
       long, lat, timezone, year, month, day, hour, minutes, seconds 
     */

    if (use_solpos) {
	G_debug(3, "\nlat:%f  long:%f", north, east);
	retval =
	    calc_solar_position(east, north, timezone, year, month, day,
				hour, minutes, seconds);

	/* Remove +0.5 above if you want round-down instead of round-to-nearest */
	sretr = (int)floor(pdat->sretr);	/* sunrise */
	dsretr = pdat->sretr;
	sretr_sec =
	    (int)
	    floor(((dsretr - floor(dsretr)) * 60 -
		   floor((dsretr - floor(dsretr)) * 60)) * 60);
	ssetr = (int)floor(pdat->ssetr);	/* sunset */
	dssetr = pdat->ssetr;
	ssetr_sec =
	    (int)
	    floor(((dssetr - floor(dssetr)) * 60 -
		   floor((dssetr - floor(dssetr)) * 60)) * 60);

	/* print the results */
	if (retval == 0) {	/* error check */
	    if (flag3->answer) {
		if (flag4->answer) {
		    fprintf(stdout, "date=%d/%02d/%02d\n", pdat->year,
			    pdat->month, pdat->day);
		    fprintf(stdout, "daynum=%d\n", pdat->daynum);
		    fprintf(stdout, "time=%02i:%02i:%02i\n", pdat->hour,
			    pdat->minute, pdat->second);
		    fprintf(stdout, "decimaltime=%f\n",
			    pdat->hour + (pdat->minute * 100.0 / 60.0 +
					  pdat->second * 100.0 / 3600.0) /
			    100.);
		    fprintf(stdout, "longitudine=%f\n", pdat->longitude);
		    fprintf(stdout, "latitude=%f\n", pdat->latitude);
		    fprintf(stdout, "timezone=%f\n", pdat->timezone);
		    fprintf(stdout, "sunazimuth=%f\n", pdat->azim);
		    fprintf(stdout, "sunangleabovehorizon=%f\n",
			    pdat->elevref);

		    if (sretr / 60 <= 24.0) {
			fprintf(stdout, "sunrise=%02d:%02d:%02d\n",
				sretr / 60, sretr % 60, sretr_sec);
			fprintf(stdout, "sunset=%02d:%02d:%02d\n", ssetr / 60,
				ssetr % 60, ssetr_sec);
		    }
		}
		else {
		    fprintf(stdout, "%d/%02d/%02d, daynum: %d, time: %02i:%02i:%02i (decimal time: %f)\n",
			    pdat->year, pdat->month, pdat->day,
			    pdat->daynum, pdat->hour, pdat->minute,
			    pdat->second,
			    pdat->hour + (pdat->minute * 100.0 / 60.0 +
					  pdat->second * 100.0 / 3600.0) /
			    100.);
		    fprintf(stdout, "long: %f, lat: %f, timezone: %f\n",
			    pdat->longitude, pdat->latitude,
			    pdat->timezone);
		    fprintf(stdout, "Solar position: sun azimuth: %f, sun angle above horz. (refraction corrected): %f\n",
			    pdat->azim, pdat->elevref);
		    
		    if (sretr / 60 <= 24.0) {
			fprintf(stdout, "Sunrise time (without refraction): %02d:%02d:%02d\n",
				sretr / 60, sretr % 60, sretr_sec);
			fprintf(stdout, "Sunset time  (without refraction): %02d:%02d:%02d\n",
				ssetr / 60, ssetr % 60, ssetr_sec);
		    }
		}
	    }
	    sunrise = pdat->sretr / 60.;	/* decimal minutes */
	    sunset = pdat->ssetr / 60.;
	    current_time =
		pdat->hour + (pdat->minute / 60.) + (pdat->second / 3600.);
	}
	else			/* fatal error in G_calc_solar_position() */
	    G_fatal_error(_("Please correct settings"));
    }

    if (use_solpos) {
	dalti = pdat->elevref;
	dazi = pdat->azim;
    }				/* otherwise already defined */


    /* check sunrise */
    if (use_solpos) {
	G_debug(3, "current_time:%f sunrise:%f", current_time, sunrise);
	if ((current_time < sunrise)) {
	    if (sretr / 60 <= 24.0)
		G_message(_("Time (%02i:%02i:%02i) is before sunrise (%02d:%02d:%02d)"),
			  pdat->hour, pdat->minute, pdat->second, sretr / 60,
			  sretr % 60, sretr_sec);
	    else
		G_message(_("Time (%02i:%02i:%02i) is before sunrise"),
			  pdat->hour, pdat->minute, pdat->second);

	    G_warning(_("Nothing to calculate. Please verify settings."));
	}
	if ((current_time > sunset)) {
	    if (sretr / 60 <= 24.0)
		G_message(_("Time (%02i:%02i:%02i) is after sunset (%02d:%02d:%02d)"),
			  pdat->hour, pdat->minute, pdat->second, ssetr / 60,
			  ssetr % 60, ssetr_sec);
	    else
		G_message(_("Time (%02i:%02i:%02i) is after sunset"),
			  pdat->hour, pdat->minute, pdat->second);
	    G_warning(_("Nothing to calculate. Please verify settings."));
	}
    }

    if (flag3->answer && (use_solpos == 1)) {	/* we only want the sun position */
	exit(EXIT_SUCCESS);
    }
    else if (flag3->answer && (use_solpos == 0)) {
	/* are you joking ? */
	G_message(_("You already know the sun position"));
	exit(EXIT_SUCCESS);
    }

    if (!outname)
	G_fatal_error(_("Option <%s> required"), parm.opt2->key);

    elev_fd = Rast_open_old(name, "");
    output_fd = Rast_open_c_new(outname);
    
    data_type = Rast_get_map_type(elev_fd);
    elevbuf.v = Rast_allocate_buf(data_type);
    tmpbuf.v = Rast_allocate_buf(data_type);
    outbuf.v = Rast_allocate_buf(CELL_TYPE);	/* binary map */

    if (data_type == CELL_TYPE) {
	if ((Rast_read_range(name, "", &range)) < 0)
	    G_fatal_error(_("Unable to open range file for raster map <%s>"), name);
	Rast_get_range_min_max(&range, &min, &max);
	dmin = (double)min;
	dmax = (double)max;
    }
    else {
	Rast_read_fp_range(name, "", &fprange);
	Rast_get_fp_range_min_max(&fprange, &dmin, &dmax);
    }

    azi = 2 * M_PI * dazi / 360;
    alti = 2 * M_PI * dalti / 360;
    nstep = cos(azi) * window.ns_res;
    estep = sin(azi) * window.ew_res;
    row1 = 0;

    G_message(_("Calculating shadows from DEM..."));
    while (row1 < window.rows) {
	G_percent(row1, window.rows, 2);
	col1 = 0;
	drow = -1;
	Rast_get_row(elev_fd, elevbuf.v, row1, data_type);
	
	while (col1 < window.cols) {
	    dvalue = raster_value(elevbuf, data_type, col1);
	    /*              outbuf.c[col1]=1; */
	    Rast_set_null_value(&outbuf.c[col1], 1, CELL_TYPE);
	    OK = 1;
	    east = Rast_col_to_easting(col1 + 0.5, &window);
	    north = Rast_row_to_northing(row1 + 0.5, &window);
	    east1 = east;
	    north1 = north;
	    if (dvalue == 0.0 && !zeros)
		OK = 0;
	    while (OK == 1)
	    {
		east += estep;
		north += nstep;
		if (north > window.north || north < window.south
		    || east > window.east || east < window.west)
		    OK = 0;
		else {
		    maxh = tan(alti) *
			sqrt((north1 - north) * (north1 - north) +
			     (east1 - east) * (east1 - east));
		    if ((maxh) > (dmax - dvalue))
			OK = 0;
		    else {
			dcol = Rast_easting_to_col(east, &window);
			if (drow != Rast_northing_to_row(north, &window)) {
			    drow = Rast_northing_to_row(north, &window);
			    Rast_get_row(elev_fd, tmpbuf.v, (int)drow,
					 data_type);
			}
			dvalue2 = raster_value(tmpbuf, data_type, (int)dcol);
			if ((dvalue2 - dvalue) > (maxh)) {
			    OK = 0;
			    outbuf.c[col1] = 1;
			}
		    }
		}
	    }
	    G_debug(3, "Analysing col %i", col1);
	    col1 += 1;
	}
	G_debug(3, "Writing result row %i of %i", row1, window.rows);
	Rast_put_row(output_fd, outbuf.c, CELL_TYPE);
	row1 += 1;
    }
    G_percent(1, 1, 1);

    Rast_close(output_fd);
    Rast_close(elev_fd);

    /* writing history file */
    Rast_short_history(outname, "raster", &hist);
    Rast_format_history(&hist, HIST_DATSRC_1, "raster elevation map %s", name);
    Rast_command_history(&hist);
    Rast_write_history(outname, &hist);

    exit(EXIT_SUCCESS);
}
Пример #14
0
Файл: main.c Проект: caomw/grass
int main(int argc, char **argv)
{
    struct GModule *module;
    struct Option *map, *profile;
    struct Flag *stored;
    struct Cell_head window;
    struct point *points = NULL;
    int num_points, max_points = 0;
    double length;
    double t, b, l, r;
    int fd;
    int i;
    double sx;
    int last;

    /* Initialize the GIS calls */
    G_gisinit(argv[0]);

    /* Set description */
    module = G_define_module();
    G_add_keyword(_("display"));
    G_add_keyword(_("profile"));
    G_add_keyword(_("raster"));
    module->description = _("Plots profile of a transect.");

    /* set up command line */
    map = G_define_standard_option(G_OPT_R_INPUT);
    map->description = _("Raster map to be profiled");

    profile = G_define_option();
    profile->key = "profile";
    profile->type = TYPE_DOUBLE;
    profile->required = YES;
    profile->multiple = YES;
    profile->key_desc = "east,north";
    profile->description = _("Profile coordinate pairs");

    stored = G_define_flag();
    stored->key = 'r';
    stored->description = _("Use map's range recorded range");

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    mapname = map->answer;

    fd = Rast_open_old(mapname, "");

    if (stored->answer)
	get_map_range();
    else
	get_region_range(fd);

    G_get_window(&window);

    num_points = 0;
    length = 0;
    for (i = 0; profile->answers[i]; i += 2) {
	struct point *p;
	double x, y;

	if (num_points >= max_points) {
	    max_points = num_points + 100;
	    points = G_realloc(points, max_points * sizeof(struct point));
	}

	p = &points[num_points];

	G_scan_easting( profile->answers[i+0], &x, G_projection());
	G_scan_northing(profile->answers[i+1], &y, G_projection());

	p->x = Rast_easting_to_col (x, &window);
	p->y = Rast_northing_to_row(y, &window);

	if (num_points > 0) {
	    const struct point *prev = &points[num_points-1];
	    double dx = fabs(p->x - prev->x);
	    double dy = fabs(p->y - prev->y);
	    double d = sqrt(dx * dx + dy * dy);
	    length += d;
	    p->d = length;
	}

	num_points++;
    }
    points[0].d = 0;

    if (num_points < 2)
	G_fatal_error(_("At least two points are required"));

    /* establish connection with graphics driver */
    if (D_open_driver() != 0)
	G_fatal_error(_("No graphics device selected. "
			"Use d.mon to select graphics device."));
    
    D_setup2(1, 0, 1.05, -0.05, -0.15, 1.05);

    plot_axes();

    D_use_color(D_translate_color(DEFAULT_FG_COLOR));

    D_get_src(&t, &b, &l, &r);
    t -= 0.1 * (t - b);
    b += 0.1 * (t - b);
    l += 0.1 * (r - l);
    r -= 0.1 * (r - l);

    D_begin();

    i = 0;
    last = 0;
    for (sx = 0; sx < 1; sx += D_get_d_to_u_xconv()) {
	double d = length * (sx - l);
	const struct point *p, *next;
	double k, sy, x, y;
	DCELL v;

	for (;;) {
	    p = &points[i];
	    next = &points[i + 1];
	    k = (d - p->d) / (next->d - p->d);
	    if (k < 1)
		break;
	    i++;
	}

	x = p->x * (1 - k) + next->x * k;
	y = p->y * (1 - k) + next->y * k;

	if (!get_cell(&v, fd, x, y)) {
	    last = 0;
	    continue;
	}

	sy = (v - min) / (max - min);

	if (last)
	    D_cont_abs(sx, sy);
	else
	    D_move_abs(sx, sy);

	last = 1;
    }

    D_end();
    D_stroke();
    
    D_close_driver();

    exit(EXIT_SUCCESS);
}
Пример #15
0
int main(int argc, char *argv[])
{
    int i, j, nlines, type, field, cat;
    int fd;

    /* struct Categories RCats; *//* TODO */
    struct Cell_head window;
    RASTER_MAP_TYPE out_type;
    CELL *cell;
    DCELL *dcell;
    double drow, dcol;
    char buf[2000];
    struct Option *vect_opt, *rast_opt, *field_opt, *col_opt, *where_opt;
    int Cache_size;
    struct order *cache;
    int cur_row;
    struct GModule *module;

    struct Map_info Map;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int point;
    int point_cnt;		/* number of points in cache */
    int outside_cnt;		/* points outside region */
    int nocat_cnt;		/* points inside region but without category */
    int dupl_cnt;		/* duplicate categories */
    struct bound_box box;

    int *catexst, *cex;
    struct field_info *Fi;
    dbString stmt;
    dbDriver *driver;
    int select, norec_cnt, update_cnt, upderr_cnt, col_type;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("raster"));
    G_add_keyword(_("position"));
    G_add_keyword(_("querying"));
    G_add_keyword(_("attribute table"));
    module->description =
	_("Uploads raster values at positions of vector points to the table.");

    vect_opt = G_define_standard_option(G_OPT_V_INPUT);
    vect_opt->key = "vector";
    vect_opt->description =
	_("Name of input vector points map for which to edit attribute table");

    rast_opt = G_define_standard_option(G_OPT_R_INPUT);
    rast_opt->key = "raster";
    rast_opt->description = _("Name of existing raster map to be queried");

    field_opt = G_define_standard_option(G_OPT_V_FIELD);

    col_opt = G_define_option();
    col_opt->key = "column";
    col_opt->type = TYPE_STRING;
    col_opt->required = YES;
    col_opt->description =
	_("Column name (will be updated by raster values)");

    where_opt = G_define_standard_option(G_OPT_DB_WHERE);

    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);


    field = atoi(field_opt->answer);

    db_init_string(&stmt);
    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    G_get_window(&window);
    Vect_region_box(&window, &box);	/* T and B set to +/- PORT_DOUBLE_MAX */

    /* Open vector */
    Vect_set_open_level(2);
    Vect_open_old(&Map, vect_opt->answer, "");

    Fi = Vect_get_field(&Map, field);
    if (Fi == NULL)
	G_fatal_error(_("Database connection not defined for layer %d"),
		      field);

    /* Open driver */
    driver = db_start_driver_open_database(Fi->driver, Fi->database);
    if (driver == NULL) {
	G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
		      Fi->database, Fi->driver);
    }

    /* Open raster */
    fd = Rast_open_old(rast_opt->answer, "");

    out_type = Rast_get_map_type(fd);

    /* TODO: Later possibly category labels */
    /* 
       if ( Rast_read_cats (name, "", &RCats) < 0 )
       G_fatal_error ( "Cannot read category file");
     */

    /* Check column type */
    col_type = db_column_Ctype(driver, Fi->table, col_opt->answer);

    if (col_type == -1)
	G_fatal_error(_("Column <%s> not found"), col_opt->answer);

    if (col_type != DB_C_TYPE_INT && col_type != DB_C_TYPE_DOUBLE)
	G_fatal_error(_("Column type not supported"));

    if (out_type == CELL_TYPE && col_type == DB_C_TYPE_DOUBLE)
	G_warning(_("Raster type is integer and column type is float"));

    if (out_type != CELL_TYPE && col_type == DB_C_TYPE_INT)
	G_warning(_("Raster type is float and column type is integer, some data lost!!"));

    /* Read vector points to cache */
    Cache_size = Vect_get_num_primitives(&Map, GV_POINT);
    /* Note: Some space may be wasted (outside region or no category) */

    cache = (struct order *)G_calloc(Cache_size, sizeof(struct order));

    point_cnt = outside_cnt = nocat_cnt = 0;

    nlines = Vect_get_num_lines(&Map);

    G_debug(1, "Reading %d vector features fom map", nlines);

    for (i = 1; i <= nlines; i++) {
	type = Vect_read_line(&Map, Points, Cats, i);
	G_debug(4, "line = %d type = %d", i, type);

	/* check type */
	if (!(type & GV_POINT))
	    continue;		/* Points only */

	/* check region */
	if (!Vect_point_in_box(Points->x[0], Points->y[0], 0.0, &box)) {
	    outside_cnt++;
	    continue;
	}

	Vect_cat_get(Cats, field, &cat);
	if (cat < 0) {		/* no category of given field */
	    nocat_cnt++;
	    continue;
	}

	G_debug(4, "    cat = %d", cat);

	/* Add point to cache */
	drow = Rast_northing_to_row(Points->y[0], &window);
	dcol = Rast_easting_to_col(Points->x[0], &window);

	/* a special case.
	 *   if north falls at southern edge, or east falls on eastern edge,
	 *   the point will appear outside the window.
	 *   So, for these edges, bring the point inside the window
	 */
	if (drow == window.rows)
	    drow--;
	if (dcol == window.cols)
	    dcol--;

	cache[point_cnt].row = (int)drow;
	cache[point_cnt].col = (int)dcol;
	cache[point_cnt].cat = cat;
	cache[point_cnt].count = 1;
	point_cnt++;
    }

    Vect_set_db_updated(&Map);
    Vect_hist_command(&Map);
    Vect_close(&Map);

    G_debug(1, "Read %d vector points", point_cnt);
    /* Cache may contain duplicate categories, sort by cat, find and remove duplicates 
     * and recalc count and decrease point_cnt  */
    qsort(cache, point_cnt, sizeof(struct order), by_cat);

    G_debug(1, "Points are sorted, starting duplicate removal loop");

    for (i = 0, j = 1; j < point_cnt; j++)
	if (cache[i].cat != cache[j].cat)
	    cache[++i] = cache[j];
	else
	    cache[i].count++;
    point_cnt = i + 1;

    G_debug(1, "%d vector points left after removal of duplicates",
	    point_cnt);

    /* Report number of points not used */
    if (outside_cnt)
	G_warning(_("%d points outside current region were skipped"),
		  outside_cnt);

    if (nocat_cnt)
	G_warning(_("%d points without category were skipped"), nocat_cnt);

    /* Sort cache by current region row */
    qsort(cache, point_cnt, sizeof(struct order), by_row);

    /* Allocate space for raster row */
    if (out_type == CELL_TYPE)
	cell = Rast_allocate_c_buf();
    else
	dcell = Rast_allocate_d_buf();

    /* Extract raster values from file and store in cache */
    G_debug(1, "Extracting raster values");

    cur_row = -1;

    for (point = 0; point < point_cnt; point++) {
	if (cache[point].count > 1)
	    continue;		/* duplicate cats */

	if (cur_row != cache[point].row) {
	    if (out_type == CELL_TYPE)
		Rast_get_c_row(fd, cell, cache[point].row);
	    else
		Rast_get_d_row(fd, dcell, cache[point].row);
	}
	cur_row = cache[point].row;

	if (out_type == CELL_TYPE) {
	    cache[point].value = cell[cache[point].col];
	}
	else {
	    cache[point].dvalue = dcell[cache[point].col];
	}
    }				/* point loop */

    /* Update table from cache */
    G_debug(1, "Updating db table");

    /* select existing categories to array (array is sorted) */
    select = db_select_int(driver, Fi->table, Fi->key, NULL, &catexst);

    db_begin_transaction(driver);

    norec_cnt = update_cnt = upderr_cnt = dupl_cnt = 0;

    for (point = 0; point < point_cnt; point++) {
	if (cache[point].count > 1) {
	    G_warning(_("More points (%d) of category %d, value set to 'NULL'"),
		      cache[point].count, cache[point].cat);
	    dupl_cnt++;
	}

	/* category exist in DB ? */
	cex =
	    (int *)bsearch((void *)&(cache[point].cat), catexst, select,
			   sizeof(int), srch_cat);
	if (cex == NULL) {	/* cat does not exist in DB */
	    norec_cnt++;
	    G_warning(_("No record for category %d in table <%s>"),
		      cache[point].cat, Fi->table);
	    continue;
	}

	sprintf(buf, "update %s set %s = ", Fi->table, col_opt->answer);

	db_set_string(&stmt, buf);

	if (out_type == CELL_TYPE) {
	    if (cache[point].count > 1 ||
		Rast_is_c_null_value(&cache[point].value)) {
		sprintf(buf, "NULL");
	    }
	    else {
		sprintf(buf, "%d ", cache[point].value);
	    }
	}
	else {			/* FCELL or DCELL */
	    if (cache[point].count > 1 ||
		Rast_is_d_null_value(&cache[point].dvalue)) {
		sprintf(buf, "NULL");
	    }
	    else {
		sprintf(buf, "%.10f", cache[point].dvalue);
	    }
	}
	db_append_string(&stmt, buf);

	sprintf(buf, " where %s = %d", Fi->key, cache[point].cat);
	db_append_string(&stmt, buf);
	/* user provides where condition: */
	if (where_opt->answer) {
	    sprintf(buf, " AND %s", where_opt->answer);
	    db_append_string(&stmt, buf);
	}
	G_debug(3, db_get_string(&stmt));

	/* Update table */
	if (db_execute_immediate(driver, &stmt) == DB_OK) {
	    update_cnt++;
	}
	else {
	    upderr_cnt++;
	}
    }

    G_debug(1, "Committing DB transaction");
    db_commit_transaction(driver);
    G_free(catexst);
    db_close_database_shutdown_driver(driver);
    db_free_string(&stmt);

    /* Report */
    G_message(_("%d categories loaded from table"), select);
    G_message(_("%d categories loaded from vector"), point_cnt);
    G_message(_("%d categories from vector missing in table"), norec_cnt);
    G_message(_("%d duplicate categories in vector"), dupl_cnt);
    if (!where_opt->answer)
	G_message(_("%d records updated"), update_cnt);
    G_message(_("%d update errors"), upderr_cnt);

    exit(EXIT_SUCCESS);
}
Пример #16
0
/*!
 *  \brief Extract a cell value from raster map (cubic interpolation).
 *
 *  Extract a cell value from raster map at given northing and easting
 *  with a sampled 3x3 window using a cubic interpolation.
 *
 *  \param fd file descriptor
 *  \param window region settings
 *  \param cats categories
 *  \param north northing position
 *  \param east easting position
 *  \param usedesc flag to scan category label
 *
 *  \return cell value at given position
 */
DCELL Rast_get_sample_cubic(int fd,
			    const struct Cell_head * window,
			    struct Categories * cats,
			    double north, double east, int usedesc)
{
    int i, j, row, col;
    double grid[4][4];
    DCELL *rows[4];
    double frow, fcol, trow, tcol;
    DCELL result;

    for (i = 0; i < 4; i++)
	rows[i] = Rast_allocate_d_buf();

    frow = Rast_northing_to_row(north, window);
    fcol = Rast_easting_to_col(east, window);

    /* convert northing and easting to row and col, resp */
    row = (int)floor(frow - 1.5);
    col = (int)floor(fcol - 1.5);

    trow = frow - row - 1.5;
    tcol = fcol - col - 1.5;

    if (row < 0 || row + 3 >= Rast_window_rows() ||
	col < 0 || col + 3 >= Rast_window_cols()) {
	Rast_set_d_null_value(&result, 1);
	goto done;
    }

    for (i = 0; i < 4; i++)
	Rast_get_d_row(fd, rows[i], row + i);

    for (i = 0; i < 4; i++)
	for (j = 0; j < 4; j++)
	    if (Rast_is_d_null_value(&rows[i][col + j])) {
		Rast_set_d_null_value(&result, 1);
		goto done;
	    }

    /*
     * now were ready to do cubic interpolation over
     * arow[col], arow[col+1], arow[col+2], arow[col+3],
     * brow[col], brow[col+1], brow[col+2], brow[col+3],
     * crow[col], crow[col+1], crow[col+2], crow[col+3],
     * drow[col], drow[col+1], drow[col+2], drow[col+3],
     */

    if (usedesc) {
	char *buf;

	for (i = 0; i < 4; i++) {
	    for (j = 0; j < 4; j++) {
		G_squeeze(buf =
			  Rast_get_c_cat((CELL *) & (rows[i][col + j]),
					 cats));
		grid[i][j] = scancatlabel(buf);
	    }
	}
    }
    else {
	for (i = 0; i < 4; i++)
	    for (j = 0; j < 4; j++)
		grid[i][j] = rows[i][col + j];
    }

    result = Rast_interp_bicubic(tcol, trow,
				 grid[0][0], grid[0][1], grid[0][2],
				 grid[0][3], grid[1][0], grid[1][1],
				 grid[1][2], grid[1][3], grid[2][0],
				 grid[2][1], grid[2][2], grid[2][3],
				 grid[3][0], grid[3][1], grid[3][2],
				 grid[3][3]);

  done:
    for (i = 0; i < 4; i++)
	G_free(rows[i]);

    return result;
}
Пример #17
0
/*--------------------------------------------------------------------------------*/
int main(int argc, char *argv[])
{

    /* Variables' declarations */
    int row, nrows, col, ncols, MaxPoints;
    int nsubregion_col, nsubregion_row;
    int subregion = 0, nsubregions = 0;
    int last_row, last_column;
    int nlines, nlines_first, line_num;
    int more;
    int clas, region = TRUE;
    double Z_interp;
    double Thres_j, Thres_d, ew_resol, ns_resol;
    double minNS, minEW, maxNS, maxEW;
    const char *mapset;
    char buf[1024], table_name[GNAME_MAX];
    char xname[GNAME_MAX], xmapset[GMAPSET_MAX];

    int colorBordo, ripieno, conta, lungPunti, lungHull, xi, c1, c2;
    double altPiano;
    extern double **P, **cvxHull, **punti_bordo;

    /* Struct declarations */
    struct Cell_head elaboration_reg, original_reg;
    struct element_grow **raster_matrix;

    struct Map_info In, Out, First;
    struct Option *in_opt, *out_opt, *first_opt, *Thres_j_opt, *Thres_d_opt;
    struct GModule *module;

    struct line_pnts *points, *points_first;
    struct line_cats *Cats, *Cats_first;

    struct field_info *field;
    dbDriver *driver;
    dbString sql;
    dbTable *table;
    dbCursor cursor;

/*------------------------------------------------------------------------------------------*/
    /* Options' declaration */ ;
    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("LIDAR"));
    module->description =
	_("Building contour determination and Region Growing "
	  "algorithm for determining the building inside");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);
    in_opt->description =
	_("Input vector (v.lidar.edgedetection output");

    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);

    first_opt = G_define_option();
    first_opt->key = "first";
    first_opt->type = TYPE_STRING;
    first_opt->key_desc = "name";
    first_opt->required = YES;
    first_opt->gisprompt = "old,vector,vector";
    first_opt->description = _("Name of the first pulse vector map");

    Thres_j_opt = G_define_option();
    Thres_j_opt->key = "tj";
    Thres_j_opt->type = TYPE_DOUBLE;
    Thres_j_opt->required = NO;
    Thres_j_opt->description =
	_("Threshold for cell object frequency in region growing");
    Thres_j_opt->answer = "0.2";

    Thres_d_opt = G_define_option();
    Thres_d_opt->key = "td";
    Thres_d_opt->type = TYPE_DOUBLE;
    Thres_d_opt->required = NO;
    Thres_d_opt->description =
	_("Threshold for double pulse in region growing");
    Thres_d_opt->answer = "0.6";

    /* Parsing */
    G_gisinit(argv[0]);
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);

    Thres_j = atof(Thres_j_opt->answer);
    Thres_d = atof(Thres_d_opt->answer);

    Thres_j += 1;

    /* Open input vector */
    Vect_check_input_output_name(in_opt->answer, out_opt->answer,
				 GV_FATAL_EXIT);

    if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) {
	G_fatal_error(_("Vector map <%s> not found"), in_opt->answer);
    }

    /* Setting auxiliar table's name */
    if (G_name_is_fully_qualified(in_opt->answer, xname, xmapset)) {
	sprintf(table_name, "%s_edge_Interpolation", xname);
    }
    else
	sprintf(table_name, "%s_edge_Interpolation", in_opt->answer);

    Vect_set_open_level(1);	/* WITHOUT TOPOLOGY */
    if (Vect_open_old(&In, in_opt->answer, mapset) < 1)
	G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer);

    Vect_set_open_level(1);	/* WITHOUT TOPOLOGY */
    if (Vect_open_old(&First, first_opt->answer, mapset) < 1)
	G_fatal_error(_("Unable to open vector map <%s>"), first_opt->answer);

    /* Open output vector */
    if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) {
	Vect_close(&In);
	Vect_close(&First);
	exit(EXIT_FAILURE);
    }

    /* Copy vector Head File */
    Vect_copy_head_data(&In, &Out);
    Vect_hist_copy(&In, &Out);
    Vect_hist_command(&Out);

    /* Starting driver and open db for edgedetection interpolation table */
    field = Vect_get_field(&In, F_INTERPOLATION);
    /*if (field == NULL)
       G_fatal_error (_("Cannot read field info")); */

    driver = db_start_driver_open_database(field->driver, field->database);
    if (driver == NULL)
	G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."),
		      field->driver);

    /* is this the right place to open the cursor ??? */
    
    db_init_string(&sql);
    db_zero_string(&sql);

    sprintf(buf, "SELECT Interp,ID FROM %s", table_name);
    G_debug(1, "buf: %s", buf);
    db_append_string(&sql, buf);

    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK)
	G_fatal_error(_("Unable to open table <%s>"), table_name);

    count_obj = 1;

    /* no topology, get number of lines in input vector */
    nlines = 0;
    points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();
    Vect_rewind(&In);
    while (Vect_read_next_line(&In, points, Cats) > 0) {
	nlines++;
    }
    Vect_rewind(&In);

    /* no topology, get number of lines in first pulse input vector */
    nlines_first = 0;
    points_first = Vect_new_line_struct();
    Cats_first = Vect_new_cats_struct();
    Vect_rewind(&First);
    while (Vect_read_next_line(&First, points_first, Cats_first) > 0) {
	nlines_first++;
    }
    Vect_rewind(&First);

    /* Setting regions and boxes */
    G_debug(1, _("Setting regions and boxes"));
    G_get_set_window(&original_reg);
    G_get_set_window(&elaboration_reg);

    /*  Fixing parameters of the elaboration region */
    /*! The original_region will be divided into subregions */
    ew_resol = original_reg.ew_res;
    ns_resol = original_reg.ns_res;

    /* calculate number of subregions */
    nsubregion_col = ceil((original_reg.east - original_reg.west) / (LATO * ew_resol)) + 0.5;
    nsubregion_row = ceil((original_reg.north - original_reg.south) / (LATO * ns_resol)) + 0.5;

    if (nsubregion_col < 0)
	nsubregion_col = 0;
    if (nsubregion_row < 0)
	nsubregion_row = 0;

    nsubregions = nsubregion_row * nsubregion_col;

    /* Subdividing and working with tiles */
    elaboration_reg.south = original_reg.north;
    last_row = FALSE;

    while (last_row == FALSE) {	/* For each strip of LATO rows */

	elaboration_reg.north = elaboration_reg.south;

	if (elaboration_reg.north > original_reg.north)	/* First row */
	    elaboration_reg.north = original_reg.north;

	elaboration_reg.south = elaboration_reg.north - LATO * ns_resol;
	if (elaboration_reg.south <= original_reg.south) {	/* Last row */
	    elaboration_reg.south = original_reg.south;
	    last_row = TRUE;
	}

	elaboration_reg.east = original_reg.west;
	last_column = FALSE;

	while (last_column == FALSE) {	/* For each strip of LATO columns */
	    struct bound_box elaboration_box;

	    subregion++;
	    if (nsubregions > 1)
		G_message(_("subregion %d of %d"), subregion, nsubregions);

	    elaboration_reg.west = elaboration_reg.east;
	    if (elaboration_reg.west < original_reg.west)	/* First column */
		elaboration_reg.west = original_reg.west;

	    elaboration_reg.east = elaboration_reg.west + LATO * ew_resol;

	    if (elaboration_reg.east >= original_reg.east) {	/* Last column */
		elaboration_reg.east = original_reg.east;
		last_column = TRUE;
	    }

	    /* Setting the active region */
	    elaboration_reg.ns_res = ns_resol;
	    elaboration_reg.ew_res = ew_resol;
	    nrows = (elaboration_reg.north - elaboration_reg.south) / ns_resol + 0.1;
	    ncols = (elaboration_reg.east - elaboration_reg.west) / ew_resol + 0.1;
	    elaboration_reg.rows = nrows;
	    elaboration_reg.cols = ncols;

	    G_debug(1, _("Rows = %d"), nrows);
	    G_debug(1, _("Columns = %d"), ncols);

	    raster_matrix = structMatrix(0, nrows, 0, ncols);
	    MaxPoints = nrows * ncols;

	    /* Initializing matrix */
	    for (row = 0; row <= nrows; row++) {
		for (col = 0; col <= ncols; col++) {
		    raster_matrix[row][col].interp = 0;
		    raster_matrix[row][col].fi = 0;
		    raster_matrix[row][col].bordo = 0;
		    raster_matrix[row][col].dueImp = SINGLE_PULSE;
		    raster_matrix[row][col].orig = 0;
		    raster_matrix[row][col].fo = 0;
		    raster_matrix[row][col].clas = PRE_TERRAIN;
		    raster_matrix[row][col].fc = 0;
		    raster_matrix[row][col].obj = 0;
		}
	    }

	    G_verbose_message(_("read points in input vector"));
	    Vect_region_box(&elaboration_reg, &elaboration_box);
	    line_num = 0;
	    Vect_rewind(&In);
	    while (Vect_read_next_line(&In, points, Cats) > 0) {
		line_num++;

		if ((Vect_point_in_box
		     (points->x[0], points->y[0], points->z[0],
		      &elaboration_box)) &&
		    ((points->x[0] != elaboration_reg.west) ||
		     (points->x[0] == original_reg.west)) &&
		    ((points->y[0] != elaboration_reg.north) ||
		     (points->y[0] == original_reg.north))) {

		    row =
			(int)(Rast_northing_to_row
			      (points->y[0], &elaboration_reg));
		    col =
			(int)(Rast_easting_to_col
			      (points->x[0], &elaboration_reg));

		    Z_interp = 0;
		    /* TODO: make sure the current db_fetch() usage works */
		    /* why not: */
		    /*
		    db_init_string(&sql);
		    sprintf(buf, "SELECT Interp,ID FROM %s WHERE ID=%d", table_name, line_num);
		    db_append_string(&sql, buf);

		    if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK)
			G_fatal_error(_("Unable to open table <%s>"), table_name);

		    while (db_fetch(&cursor, DB_NEXT, &more) == DB_OK && more) {
			dbColumn *Z_Interp_col;
			dbValue *Z_Interp_value;
			table = db_get_cursor_table(&cursor);

			Z_Interp_col = db_get_table_column(table, 1);

			if (db_sqltype_to_Ctype(db_get_column_sqltype(Z_Interp_col)) ==
			    DB_C_TYPE_DOUBLE)
			    Z_Interp_value = db_get_column_value(Z_Interp_col);
			else
			    continue;

			Z_interp = db_get_value_double(Z_Interp_value);
			break;
		    }
		    db_close_cursor(&cursor);
		    db_free_string(&sql);
		    */
		    /* instead of */
		    while (1) {
			if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK ||
			    !more)
			    break;
			dbColumn *Z_Interp_col, *ID_col;
			dbValue *Z_Interp_value, *ID_value;

			table = db_get_cursor_table(&cursor);

			ID_col = db_get_table_column(table, 1);
			if (db_sqltype_to_Ctype(db_get_column_sqltype(ID_col))
			    == DB_C_TYPE_INT)
			    ID_value = db_get_column_value(ID_col);
			else
			    continue;

			if (db_get_value_int(ID_value) == line_num) {
			    Z_Interp_col = db_get_table_column(table, 0);
			    if (db_sqltype_to_Ctype
				(db_get_column_sqltype(Z_Interp_col)) ==
				DB_C_TYPE_DOUBLE)
				Z_Interp_value =
				    db_get_column_value(Z_Interp_col);
			    else
				continue;
			    Z_interp = db_get_value_double(Z_Interp_value);
			    break;
			}
		    }

		    raster_matrix[row][col].interp += Z_interp;
		    raster_matrix[row][col].fi++;

		    /*if (( clas = Vect_get_line_cat (&In, line_num, F_EDGE_DETECTION_CLASS) ) != UNKNOWN_EDGE) { */
		    if (Vect_cat_get(Cats, F_EDGE_DETECTION_CLASS, &clas)) {
			raster_matrix[row][col].clas += clas;
			raster_matrix[row][col].fc++;
		    }

		    raster_matrix[row][col].orig += points->z[0];
		    raster_matrix[row][col].fo++;
		}

		Vect_reset_cats(Cats);
		Vect_reset_line(points);
	    }

	    for (row = 0; row <= nrows; row++) {
		for (col = 0; col <= ncols; col++) {

		    if (raster_matrix[row][col].fc != 0) {
			raster_matrix[row][col].clas--;
			raster_matrix[row][col].
			    clas /= raster_matrix[row][col].fc;
		    }

		    if (raster_matrix[row][col].fi != 0)
			raster_matrix[row][col].
			    interp /= raster_matrix[row][col].fi;

		    if (raster_matrix[row][col].fo != 0)
			raster_matrix[row][col].
			    orig /= raster_matrix[row][col].fo;
		}
	    }

	    /* DOUBLE IMPULSE */
	    Vect_rewind(&First);
	    while (Vect_read_next_line(&First, points_first, Cats_first) > 0) {

		if ((Vect_point_in_box
		     (points_first->x[0], points_first->y[0],
		      points_first->z[0], &elaboration_box)) &&
		    ((points->x[0] != elaboration_reg.west) ||
		     (points->x[0] == original_reg.west)) &&
		    ((points->y[0] != elaboration_reg.north) ||
		     (points->y[0] == original_reg.north))) {

		    row =
			(int)(Rast_northing_to_row
			      (points_first->y[0], &elaboration_reg));
		    col =
			(int)(Rast_easting_to_col
			      (points_first->x[0], &elaboration_reg));

		    if (fabs
			(points_first->z[0] - raster_matrix[row][col].orig) >=
			Thres_d)
			raster_matrix[row][col].dueImp = DOUBLE_PULSE;
		}
		Vect_reset_cats(Cats_first);
		Vect_reset_line(points_first);
	    }

	    /* REGION GROWING */
	    if (region == TRUE) {
		G_verbose_message(_("Region Growing"));

		punti_bordo = G_alloc_matrix(MaxPoints, 3);
		P = Pvector(0, MaxPoints);

		colorBordo = 5;
		ripieno = 6;

		for (row = 0; row <= nrows; row++) {
		    G_percent(row, nrows, 2);
		    for (col = 0; col <= ncols; col++) {

			if ((raster_matrix[row][col].clas >= Thres_j) &&
			    (raster_matrix[row][col].clas < colorBordo)
			    && (raster_matrix[row][col].fi != 0) &&
			    (raster_matrix[row][col].dueImp ==
			     SINGLE_PULSE)) {

			    /* Selecting a connected Object zone */
			    ripieno++;
			    if (ripieno > 10)
				ripieno = 6;

			    /* Selecting points on a connected edge */
			    for (conta = 0; conta < MaxPoints; conta++) {
				punti_bordo[conta][0] = 0;
				punti_bordo[conta][1] = 0;
				punti_bordo[conta][2] = 0;
				P[conta] = punti_bordo[conta];	/* It only makes indexes to be equal, not coord values!! */
			    }

			    lungPunti = 0;
			    lungHull = 0;

			    regGrow8(elaboration_reg, raster_matrix,
				     punti_bordo, &lungPunti, row, col,
				     colorBordo, Thres_j, MaxPoints);

			    /* CONVEX-HULL COMPUTATION */
			    lungHull = ch2d(P, lungPunti);
			    cvxHull = G_alloc_matrix(lungHull, 3);


			    for (xi = 0; xi < lungHull; xi++) {
				cvxHull[xi][0] = P[xi][0];
				cvxHull[xi][1] = P[xi][1];
				cvxHull[xi][2] = P[xi][2];
			    }

			    /* Computes the interpoling plane based only on Object points */
			    altPiano =
				pianOriz(punti_bordo, lungPunti, &minNS,
					 &minEW, &maxNS, &maxEW,
					 raster_matrix, colorBordo);

			    for (c1 = minNS; c1 <= maxNS; c1++) {
				for (c2 = minEW; c2 <= maxEW; c2++) {
				    if (checkHull(c1, c2, cvxHull, lungHull)
					== 1) {
					raster_matrix[c1][c2].obj = count_obj;

					if ((raster_matrix[c1][c2].clas ==
					     PRE_TERRAIN)
					    && (raster_matrix[c1][c2].orig >=
						altPiano) && (lungHull > 3))
					    raster_matrix[c1][c2].clas =
						ripieno;
				    }
				}
			    }
			    G_free_matrix(cvxHull);
			    count_obj++;
			}
		    }
		}
		G_free_matrix(punti_bordo);
		free_Pvector(P, 0, MaxPoints);
	    }

	    /* WRITING THE OUTPUT VECTOR CATEGORIES */
	    Vect_rewind(&In);
	    while (Vect_read_next_line(&In, points, Cats) > 0) {	/* Read every line for buffering points */

		if ((Vect_point_in_box
		     (points->x[0], points->y[0], points->z[0],
		      &elaboration_box)) &&
		    ((points->x[0] != elaboration_reg.west) ||
		     (points->x[0] == original_reg.west)) &&
		    ((points->y[0] != elaboration_reg.north) ||
		     (points->y[0] == original_reg.north))) {

		    row =
			(int)(Rast_northing_to_row
			      (points->y[0], &elaboration_reg));
		    col =
			(int)(Rast_easting_to_col
			      (points->x[0], &elaboration_reg));

		    if (raster_matrix[row][col].clas == PRE_TERRAIN) {
			if (raster_matrix[row][col].dueImp == SINGLE_PULSE)
			    Vect_cat_set(Cats, F_CLASSIFICATION,
					 TERRAIN_SINGLE);
			else
			    Vect_cat_set(Cats, F_CLASSIFICATION,
					 TERRAIN_DOUBLE);
		    }
		    else {
			if (raster_matrix[row][col].dueImp == SINGLE_PULSE)
			    Vect_cat_set(Cats, F_CLASSIFICATION,
					 OBJECT_SINGLE);
			else
			    Vect_cat_set(Cats, F_CLASSIFICATION,
					 OBJECT_DOUBLE);
		    }

		    Vect_cat_set(Cats, F_COUNTER_OBJ,
				 raster_matrix[row][col].obj);
		    Vect_write_line(&Out, GV_POINT, points, Cats);
		}
		Vect_reset_cats(Cats);
		Vect_reset_line(points);
	    }
	    free_structmatrix(raster_matrix, 0, nrows - 1, 0, ncols - 1);
	}			/*! END WHILE; last_column = TRUE */
    }				/*! END WHILE; last_row = TRUE */

    Vect_close(&In);
    Vect_close(&First);
    Vect_close(&Out);

    db_close_database_shutdown_driver(driver);

    G_done_msg(" ");
    exit(EXIT_SUCCESS);
}