예제 #1
0
파일: zones.c 프로젝트: GRASS-GIS/grass-ci
/*----------------------------------------------------------------------------------------*/
double
P_Mean_Calc(struct Cell_head *Elaboration, struct Point *obs, int npoints)
{
    int i, mean_count = 0;
    double mean = 0.0;
    struct bound_box mean_box;

    Vect_region_box(Elaboration, &mean_box);
    mean_box.W -= CONTOUR;
    mean_box.E += CONTOUR;
    mean_box.N += CONTOUR;
    mean_box.S -= CONTOUR;

    for (i = 0; i < npoints; i++) {	/*  */
	if (Vect_point_in_box
	    (obs[i].coordX, obs[i].coordY, obs[i].coordZ, &mean_box)) {
	    mean_count++;
	    mean += obs[i].coordZ;
	}
    }
    if (mean_count == 0)
	mean = .0;
    else
	mean /= (double)mean_count;

    return mean;
}
예제 #2
0
파일: zones.c 프로젝트: GRASS-GIS/grass-ci
double P_estimate_splinestep(struct Map_info *Map, double *dens, double *dist)
{
    int type, npoints = 0;
    double xmin = 0, xmax = 0, ymin = 0, ymax = 0;
    double x, y, z;
    struct line_pnts *points;
    struct line_cats *categories;
    struct bound_box region_box;
    struct Cell_head orig;

    G_get_set_window(&orig);
    Vect_region_box(&orig, &region_box);

    points = Vect_new_line_struct();
    categories = Vect_new_cats_struct();

    Vect_rewind(Map);
    while ((type = Vect_read_next_line(Map, points, categories)) > 0) {
	if (!(type & GV_POINT))
	    continue;

	x = points->x[0];
	y = points->y[0];
	if (points->z != NULL)
	    z = points->z[0];
	else
	    z = 0.0;

	/* only use points in current region */
	if (Vect_point_in_box(x, y, z, &region_box)) {
	    npoints++;

	    if (npoints > 1) {
		if (xmin > x)
		    xmin = x;
		else if (xmax < x)
		    xmax = x;
		if (ymin > y)
		    ymin = y;
		else if (ymax < y)
		    ymax = y;
	    }
	    else {
		xmin = xmax = x;
		ymin = ymax = y;
	    }
	}
    }
    if (npoints > 0) {
	/* estimated average distance between points in map units */
	*dist = sqrt(((xmax - xmin) * (ymax - ymin)) / npoints);
	/* estimated point density as number of points per square map unit */
	*dens = npoints / ((xmax - xmin) * (ymax - ymin));
	return 0;
    }
    else {
	return -1;
    }
}
예제 #3
0
파일: read.c 프로젝트: rashadkm/grass_cmake
int loadSiteCoordinates(struct Map_info *Map, struct Point **points, int region,
			struct Cell_head *window, int field, struct cat_list *cat_list)
{
    int i, pointIdx;
    struct line_pnts *sites;
    struct line_cats *cats;
    struct bound_box box;
    int type;

    sites = Vect_new_line_struct();
    cats = Vect_new_cats_struct();

    *points = NULL;
    pointIdx = 0;
    
    /* copy window to box */
    Vect_region_box(window, &box);

    while ((type = Vect_read_next_line(Map, sites, cats)) > -1) {

	if (type != GV_POINT && !(type & GV_LINES))
	    continue;

	if (field > 0 && !Vect_cats_in_constraint(cats, field, cat_list))
	    continue;
	
	for (i = 0; i < sites->n_points; i++) {
	    G_debug(4, "Point: %f|%f|%f", sites->x[i], sites->y[i],
		    sites->z[i]);
	    
	    if (region && !Vect_point_in_box(sites->x[i], sites->y[i], sites->z[i], &box))
		continue;
	    
	    G_debug(4, "Point in the box");

	    if ((pointIdx % ALLOC_CHUNK) == 0)
		*points = (struct Point *) G_realloc(*points,
						     (pointIdx + ALLOC_CHUNK) * sizeof(struct Point));
	    
	    (*points)[pointIdx].x = sites->x[i];
	    (*points)[pointIdx].y = sites->y[i];
	    (*points)[pointIdx].z = sites->z[i];
	    pointIdx++;
	}
    }

    if (pointIdx > 0)
	*points = (struct Point *)G_realloc(*points,
					    (pointIdx + 1) * sizeof(struct Point));
    
    return pointIdx;
}
예제 #4
0
int write_ep(struct Edge *e)
{
    static struct line_pnts *Points = NULL;
    static struct line_cats *Cats = NULL;

    if (!Points) {
	Points = Vect_new_line_struct();
	Cats = Vect_new_cats_struct();
    }

    if (!triangulate) {
	double x1, y1, x2, y2;

	if (e->ep[le] != NULL && e->ep[re] != NULL) {	/* both end defined */
	    x1 = e->ep[le]->coord.x;
	    y1 = e->ep[le]->coord.y;
	    x2 = e->ep[re]->coord.x;
	    y2 = e->ep[re]->coord.y;

	    if (!Vect_point_in_box(x1, y1, 0.0, &Box) ||
		!Vect_point_in_box(x2, y2, 0.0, &Box)) {
		Vect_box_clip(&x1, &y1, &x2, &y2, &Box);
	    }

	    /* Don't write zero length */
	    if (x1 == x2 && y1 == y2)
		return 0;

	    Vect_reset_line(Points);
	    Vect_append_point(Points, x1, y1, 0.0);
	    Vect_append_point(Points, x2, y2, 0.0);
	    Vect_write_line(&Out, Type, Points, Cats);
	}
	else {
	    int knownPointAtLeft;

	    if (e->ep[le] != NULL) {
		x1 = e->ep[le]->coord.x;
		y1 = e->ep[le]->coord.y;
		knownPointAtLeft = 1;
	    }
	    else {
		x1 = e->ep[re]->coord.x;
		y1 = e->ep[re]->coord.y;
		knownPointAtLeft = 0;
	    }

	    if (extend_line(Box.S, Box.N, Box.W, Box.E,
			    e->a, e->b, e->c, x1, y1, &x2, &y2,
			    knownPointAtLeft)
		) {
		/* Don't write zero length */
		if (x1 == x2 && y1 == y2)
		    return 0;

		Vect_reset_line(Points);
		Vect_append_point(Points, x1, y1, 0.0);
		Vect_append_point(Points, x2, y2, 0.0);
		Vect_write_line(&Out, Type, Points, Cats);
	    }
	}
    }

    return 0;
}
예제 #5
0
int extend_line(double s, double n, double w, double e,
		double a, double b, double c, double x, double y,
		double *c_x, double *c_y, int knownPointAtLeft)
{
    double nx, ny;		/* intersection coordinates */

    if (x >= w && x <= e && y >= s && y <= n) {
	/* horizontal line? */
	if (a == 0) {
	    *c_x = knownPointAtLeft ? e : w;
	    *c_y =  y;
	    return 1;
	}

	/* vertical line? */
	if (b == 0) {
	    *c_x = x;
	    *c_y = knownPointAtLeft ? s : n;
	    return 1;
	}

	/* south */
	nx = (c - b * s) / a;
	if (Vect_point_in_box(nx, s, 0.0, &Box) &&
	    ((nx > x && knownPointAtLeft) || (nx <= x && !knownPointAtLeft)))
	{
	    *c_x = nx;
	    *c_y = s;
	    return 1;
	}

	/* north */
	nx = (c - b * n) / a;
	if (Vect_point_in_box(nx, n, 0.0, &Box) &&
	    ((nx > x && knownPointAtLeft) || (nx <= x && !knownPointAtLeft)))
	{
	    *c_x = nx;
	    *c_y = n;
	    return 1;
	}

	if (knownPointAtLeft) {
	    /* east */
	    ny = (c - a * e) / b;
	    if (Vect_point_in_box(e, ny, 0.0, &Box)) {
		*c_x = e;
		*c_y = ny;
		return 1;
	    }
	}
	else {
	    /* west */
	    ny = (c - a * w) / b;
	    if (Vect_point_in_box(w, ny, 0.0, &Box)) {
		*c_x = w;
		*c_y = ny;
		return 1;
	    }
	}
    }
    return 0;
}
예제 #6
0
struct Point *P_Read_Raster_Region_masked(SEGMENT *mask_seg,
				       struct Cell_head *Original,
				       struct bound_box output_box,
				       struct bound_box General,
				       int *num_points, int dim_vect,
				       double mean)
{
    int col, row, startcol, endcol, startrow, endrow, nrows, ncols;
    int pippo, npoints;
    double X, Y;
    struct Point *obs;
    char mask_val;

    pippo = dim_vect;
    obs = (struct Point *)G_calloc(pippo, sizeof(struct Point));

    /* Reading points inside output box and inside General box */

    npoints = 0;
    nrows = Original->rows;
    ncols = Original->cols;

    /* original region = output region
     * -> General box is somewhere inside output region */
    if (Original->north > General.N) {
	startrow = (double)((Original->north - General.N) / Original->ns_res - 1);
	if (startrow < 0)
	    startrow = 0;
    }
    else
	startrow = 0;
    if (Original->south < General.S) {
	endrow = (double)((Original->north - General.S) / Original->ns_res + 1);
	if (endrow > nrows)
	    endrow = nrows;
    }
    else
	endrow = nrows;
    if (General.W > Original->west) {
	startcol = (double)((General.W - Original->west) / Original->ew_res - 1);
	if (startcol < 0)
	    startcol = 0;
    }
    else
	startcol = 0;
    if (General.E < Original->east) {
	endcol = (double)((General.E - Original->west) / Original->ew_res + 1);
	if (endcol > ncols)
	    endcol = ncols;
    }
    else
	endcol = ncols;

    for (row = startrow; row < endrow; row++) {
	for (col = startcol; col < endcol; col++) {

	    Segment_get(mask_seg, &mask_val, row, col);
	    if (!mask_val)
		continue;

	    X = Rast_col_to_easting((double)(col) + 0.5, Original);
	    Y = Rast_row_to_northing((double)(row) + 0.5, Original);

	    /* Here, mean is just for asking if obs point is in box */
	    if (Vect_point_in_box(X, Y, mean, &General)) { /* General */
		if (npoints >= pippo) {
		    pippo += dim_vect;
		    obs =
			(struct Point *)G_realloc((void *)obs,
						  (signed int)pippo *
						  sizeof(struct Point));
		}

		/* Storing observation vector */
		obs[npoints].coordX = X;
		obs[npoints].coordY = Y;
		obs[npoints].coordZ = 0;
		npoints++;
	    }
	}
    }

    *num_points = npoints;
    return obs;
}
예제 #7
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;
}
예제 #8
0
파일: zones.c 프로젝트: GRASS-GIS/grass-ci
struct Point *P_Read_Raster_Region_Map(SEGMENT *in_seg,
				       struct Cell_head *Elaboration,
				       struct Cell_head *Original,
				       int *num_points, int dim_vect)
{
    int col, row, startcol, endcol, startrow, endrow, nrows, ncols;
    int pippo, npoints;
    double x, y, z;
    struct Point *obs;
    struct bound_box elaboration_box;

    pippo = dim_vect;
    obs = (struct Point *)G_calloc(pippo, sizeof(struct Point));

    /* Reading points inside elaboration zone */
    Vect_region_box(Elaboration, &elaboration_box);

    npoints = 0;
    nrows = Original->rows;
    ncols = Original->cols;
    
    if (Original->north > Elaboration->north)
	startrow = (Original->north - Elaboration->north) / Original->ns_res - 1;
    else
	startrow = 0;
    if (Original->north > Elaboration->south) {
	endrow = (Original->north - Elaboration->south) / Original->ns_res + 1;
	if (endrow > nrows)
	    endrow = nrows;
    }
    else
	endrow = nrows;
    if (Elaboration->west > Original->west)
	startcol = (Elaboration->west - Original->west) / Original->ew_res - 1;
    else
	startcol = 0;
    if (Elaboration->east > Original->west) {
	endcol = (Elaboration->east - Original->west) / Original->ew_res + 1;
	if (endcol > ncols)
	    endcol = ncols;
    }
    else
	endcol = ncols;

    for (row = startrow; row < endrow; row++) {
	for (col = startcol; col < endcol; col++) {

	    Segment_get(in_seg, &z, row, col);

	    if (!Rast_is_d_null_value(&z)) {

		x = Rast_col_to_easting((double)(col) + 0.5, Original);
		y = Rast_row_to_northing((double)(row) + 0.5, Original);

		if (Vect_point_in_box(x, y, 0, &elaboration_box)) {
		    npoints++;
		    if (npoints >= pippo) {
			pippo += dim_vect;
			obs =
			    (struct Point *)G_realloc((void *)obs,
						      (signed int)pippo *
						      sizeof(struct Point));
		    }

		    /* Storing observation vector */
		    obs[npoints - 1].coordX = x;
		    obs[npoints - 1].coordY = y;
		    obs[npoints - 1].coordZ = z;
		}
	    }
	}
    }

    *num_points = npoints;
    return obs;
}
예제 #9
0
파일: zones.c 프로젝트: GRASS-GIS/grass-ci
struct Point *P_Read_Vector_Region_Map(struct Map_info *Map,
				       struct Cell_head *Elaboration,
				       int *num_points, int dim_vect,
				       int layer)
{
    int line_num, pippo, npoints, cat, type;
    double x, y, z;
    struct Point *obs;
    struct line_pnts *points;
    struct line_cats *categories;
    struct bound_box elaboration_box;

    pippo = dim_vect;
    obs = (struct Point *)G_calloc(pippo, sizeof(struct Point));

    points = Vect_new_line_struct();
    categories = Vect_new_cats_struct();

    /* Reading points inside elaboration zone */
    Vect_region_box(Elaboration, &elaboration_box);

    npoints = 0;
    line_num = 0;

    Vect_rewind(Map);
    while ((type = Vect_read_next_line(Map, points, categories)) > 0) {

	if (!(type & GV_POINT))
	    continue;

	line_num++;

	x = points->x[0];
	y = points->y[0];
	if (points->z != NULL)
	    z = points->z[0];
	else
	    z = 0.0;

	/* Reading and storing points only if in elaboration_reg */
	if (Vect_point_in_box(x, y, z, &elaboration_box)) {
	    npoints++;
	    if (npoints >= pippo) {
		pippo += dim_vect;
		obs =
		    (struct Point *)G_realloc((void *)obs,
					      (signed int)pippo *
					      sizeof(struct Point));
	    }

	    /* Storing observation vector */
	    obs[npoints - 1].coordX = x;
	    obs[npoints - 1].coordY = y;
	    obs[npoints - 1].coordZ = z;
	    obs[npoints - 1].lineID = line_num;	/* Storing also the line's number */

	    Vect_cat_get(categories, layer, &cat);
	    obs[npoints - 1].cat = cat;
	}
    }
    Vect_destroy_line_struct(points);
    Vect_destroy_cats_struct(categories);

    *num_points = npoints;
    return obs;
}
예제 #10
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);
}
예제 #11
0
파일: raster.c 프로젝트: imincik/pkg-grass
/*------------------------------------------------------------------------------------------------*/
void
P_Sparse_Points(struct Map_info *Out, struct Cell_head *Elaboration,
		BOUND_BOX General, BOUND_BOX Overlap, double **obs,
		double *param, int *line_num, double pe, double pn,
		double overlap, int nsplx, int nsply, int num_points,
		int bilin, struct line_cats *categories, dbDriver * driver,
		double mean, char *tab_name)
{
    int i;
    char buf[1024];
    dbString sql;

    double interpolation, csi, eta, weight;
    struct line_pnts *point;

    point = Vect_new_line_struct();

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

	if (Vect_point_in_box(obs[i][0], obs[i][1], mean, &General)) {	/*Here mean is just for asking if obs point is in box */

	    if (bilin)
		interpolation =
		    dataInterpolateBilin(obs[i][0], obs[i][1], pe, pn, nsplx,
					 nsply, Elaboration->west,
					 Elaboration->south, param);
	    else
		interpolation =
		    dataInterpolateBicubic(obs[i][0], obs[i][1], pe, pn,
					   nsplx, nsply, Elaboration->west,
					   Elaboration->south, param);

	    interpolation += mean;
	    Vect_copy_xyz_to_pnts(point, &obs[i][0], &obs[i][1],
				  &interpolation, 1);

	    if (Vect_point_in_box(obs[i][0], obs[i][1], interpolation, &Overlap)) {	/*(5) */
		Vect_write_line(Out, GV_POINT, point, categories);
	    }
	    else {
		db_init_string(&sql);

		sprintf(buf, "INSERT INTO %s (ID, X, Y, Interp)", tab_name);
		db_append_string(&sql, buf);

		sprintf(buf, " VALUES (");
		db_append_string(&sql, buf);
		sprintf(buf, "%d, %f, %f, ", line_num[i], obs[i][0],
			obs[i][1]);
		db_append_string(&sql, buf);

		if ((*point->x > Overlap.E) && (*point->x < General.E)) {
		    if ((*point->y > Overlap.N) && (*point->y < General.N)) {	/*(3) */
			csi = (General.E - *point->x) / overlap;
			eta = (General.N - *point->y) / overlap;
			weight = csi * eta;
			*point->z = weight * interpolation;

			sprintf(buf, "%lf", *point->z);
			db_append_string(&sql, buf);
			sprintf(buf, ")");
			db_append_string(&sql, buf);

			if (db_execute_immediate(driver, &sql) != DB_OK)
			    G_fatal_error(_("Unable to access table <%s>"),
					  buf);
		    }
		    else if ((*point->y < Overlap.S) && (*point->y > General.S)) {	/*(1) */
			csi = (General.E - *point->x) / overlap;
			eta = (*point->y - General.S) / overlap;
			weight = csi * eta;
			*point->z = weight * interpolation;

			sprintf(buf, "%lf", *point->z);
			db_append_string(&sql, buf);
			sprintf(buf, ")");
			db_append_string(&sql, buf);

			if (db_execute_immediate(driver, &sql) != DB_OK)
			    G_fatal_error(_("Unable to access table <%s>"),
					  buf);
		    }
		    else if ((*point->y <= Overlap.N) && (*point->y >= Overlap.S)) {	/*(1) */
			weight = (General.E - *point->x) / overlap;
			*point->z = weight * interpolation;

			sprintf(buf, "%lf", *point->z);
			db_append_string(&sql, buf);
			sprintf(buf, ")");
			db_append_string(&sql, buf);

			if (db_execute_immediate(driver, &sql) != DB_OK)
			    G_fatal_error(_("Unable to access table <%s>"),
					  buf);
		    }
		}
		else if ((*point->x < Overlap.W) && (*point->x > General.W)) {
		    if ((*point->y > Overlap.N) && (*point->y < General.N)) {	/*(4) */
			csi = (*point->x - General.W) / overlap;
			eta = (General.N - *point->y) / overlap;
			weight = eta * csi;
			*point->z = weight * interpolation;

			sprintf(buf, "%lf", *point->z);
			db_append_string(&sql, buf);
			sprintf(buf, ")");
			db_append_string(&sql, buf);

			if (db_execute_immediate(driver, &sql) != DB_OK)
			    G_fatal_error(_("Unable to access table <%s>"),
					  buf);
		    }
		    else if ((*point->y < Overlap.S) && (*point->y > General.S)) {	/*(2) */
			csi = (*point->x - General.W) / overlap;
			eta = (*point->y - General.S) / overlap;
			weight = csi * eta;
			*point->z = weight * interpolation;

			sprintf(buf, "%lf", *point->z);
			db_append_string(&sql, buf);
			sprintf(buf, ")");
			db_append_string(&sql, buf);

			if (db_execute_immediate(driver, &sql) != DB_OK)
			    G_fatal_error(_("Unable to access table <%s>"),
					  buf);
		    }
		    else if ((*point->y >= Overlap.S) && (*point->y <= Overlap.N)) {	/*(2) */
			weight = (*point->x - General.W) / overlap;
			*point->z = weight * interpolation;

			sprintf(buf, "%lf", *point->z);
			db_append_string(&sql, buf);
			sprintf(buf, ")");
			db_append_string(&sql, buf);

			if (db_execute_immediate(driver, &sql) != DB_OK)
			    G_fatal_error(_("Unable to access table <%s>"),
					  buf);
		    }
		}
		else if ((*point->x >= Overlap.W) && (*point->x <= Overlap.E)){
		    if ((*point->y > Overlap.N) && (*point->y < General.N)) {	/*(3) */
			weight = (General.N - *point->y) / overlap;
			*point->z = weight * interpolation;

			sprintf(buf, "%lf", *point->z);
			db_append_string(&sql, buf);
			sprintf(buf, ")");
			db_append_string(&sql, buf);

			if (db_execute_immediate(driver, &sql) != DB_OK)
			    G_fatal_error(_("Unable to access table <%s>"),
					  buf);
		    }
		    else if ((*point->y < Overlap.S) && (*point->y > General.S)) {	/*(1) */
			weight = (*point->y - General.S) / overlap;
			*point->z = (1 - weight) * interpolation;

			sprintf(buf, "%lf", *point->z);
			db_append_string(&sql, buf);
			sprintf(buf, ")");
			db_append_string(&sql, buf);

			if (db_execute_immediate(driver, &sql) != DB_OK)
			    G_fatal_error(_("Unable to access table <%s>"),
					  buf);
		    }
		}
	    }
	}  /*IF*/
    }  /*FOR*/

    db_commit_transaction(driver);

    return;
}
예제 #12
0
int edge_detection(struct Cell_head elaboration_reg, struct bound_box Overlap_Box,
		   double *parBilin, double obsX, double obsY,
		   double *partial, double alpha, double residual,
		   double gradHigh, double gradLow)
{
    /* 1 = PRE_TERRAIN */
    /* 2 = PRE_EDGE */
    /* 3 = PRE_UNKNOWN */

    int c1, c2;
    double g[9][2], gradient[2], gradPto, dirPto;
    extern double stepE, stepN;
    static struct Cell_head Elaboration;

    g[0][0] = partial[0];
    g[0][1] = partial[1];

    gradPto = g[0][0] * g[0][0] + g[0][1] * g[0][1];
    dirPto = atan(g[0][1] / g[0][0]) + M_PI / 2;	/* radiants */

    Elaboration = elaboration_reg;

    if ((gradPto > gradHigh) && (residual > 0))
	return PRE_EDGE;	/* Strong condition for 'edge' points */

    else if ((gradPto > gradLow) && (residual > 0)) {	/* Soft condition for 'edge' points */

	if (Vect_point_in_box(obsX, obsY, 0.0, &Overlap_Box)) {
	    Get_Gradient(Elaboration, obsX + stepE * cos(dirPto),
			     obsY + stepN * sin(dirPto), parBilin, gradient);
	    g[2][0] = gradient[0];
	    g[2][1] = gradient[1];

	    Get_Gradient(Elaboration, obsX + stepE * cos(dirPto + M_PI),
			     obsY + stepN * sin(dirPto + M_PI), parBilin, gradient);
	    g[7][0] = gradient[0];
	    g[7][1] = gradient[1];

	    if ((fabs(atan(g[2][1] / g[2][0]) + M_PI / 2 - dirPto) < alpha) &&
		(fabs(atan(g[7][1] / g[7][0]) + M_PI / 2 - dirPto) < alpha)) {

		Get_Gradient(Elaboration,
				 obsX + stepE * cos(dirPto + M_PI / 4),
				 obsY + stepN * sin(dirPto + M_PI / 4),
				 parBilin, gradient);
		g[1][0] = gradient[0];
		g[1][1] = gradient[1];

		Get_Gradient(Elaboration,
				 obsX + stepE * cos(dirPto - M_PI / 4),
				 obsY + stepN * sin(dirPto - M_PI / 4),
				 parBilin, gradient);
		g[3][0] = gradient[0];
		g[3][1] = gradient[1];

		Get_Gradient(Elaboration,
				 obsX + stepE * cos(dirPto + M_PI / 2),
				 obsY + stepN * sin(dirPto + M_PI / 2),
				 parBilin, gradient);
		g[4][0] = gradient[0];
		g[4][1] = gradient[1];

		Get_Gradient(Elaboration,
				 obsX + stepE * cos(dirPto - M_PI / 2),
				 obsY + stepN * sin(dirPto - M_PI / 2),
				 parBilin, gradient);
		g[5][0] = gradient[0];
		g[5][1] = gradient[1];

		Get_Gradient(Elaboration,
				 obsX + stepE * cos(dirPto + M_PI * 3 / 4),
				 obsY + stepN * sin(dirPto + M_PI * 3 / 4),
				 parBilin, gradient);
		g[6][0] = gradient[0];
		g[6][1] = gradient[1];

		Get_Gradient(Elaboration,
				 obsX + stepE * cos(dirPto - M_PI * 3 / 4),
				 obsY + stepN * sin(dirPto - M_PI * 3 / 4),
				 parBilin, gradient);
		g[8][0] = gradient[0];
		g[8][1] = gradient[1];

		c2 = 0;
		for (c1 = 0; c1 < 9; c1++)
		    if (g[c1][0] * g[c1][0] + g[c1][1] * g[c1][1] >
			gradHigh)
			c2++;

		if (c2 > 2)
		    return PRE_EDGE;
		else
		    return PRE_TERRAIN;
	    }
	    else
		return PRE_TERRAIN;
	}
	else
	    return PRE_UNKNOWN;
    }				/* END ELSE IF */
    else
	return PRE_TERRAIN;
}
예제 #13
0
void classification(struct Map_info *Out, struct Cell_head Elaboration,
		    struct bound_box General, struct bound_box Overlap, double **obs,
		    double *parBilin, double *parBicub, double mean,
		    double alpha, double gradHigh, double gradLow,
		    double overlap, int *line_num, int num_points,
		    dbDriver * driver, char *tabint_name, char *tab_name)
{
    int i, edge;
    double interpolation, weight, residual, eta, csi, gradient[2];

    extern int nsplx, nsply, line_out_counter;
    extern double stepN, stepE;

    struct line_pnts *point;
    struct line_cats *categories;

    point = Vect_new_line_struct();
    categories = Vect_new_cats_struct();

    db_begin_transaction(driver);
    
    for (i = 0; i < num_points; i++) {	/* Sparse points */
	G_percent(i, num_points, 2);

	Vect_reset_line(point);
	Vect_reset_cats(categories);

	if (Vect_point_in_box(obs[i][0], obs[i][1], mean, &General)) {
	    interpolation =
		dataInterpolateBicubic(obs[i][0], obs[i][1], stepE, stepN,
				       nsplx, nsply, Elaboration.west,
				       Elaboration.south, parBicub);
	    interpolation += mean;

	    Vect_copy_xyz_to_pnts(point, &obs[i][0], &obs[i][1], &obs[i][2], 1);

	    Get_Gradient(Elaboration, obs[i][0], obs[i][1], parBilin, gradient);

	    *point->z += mean;
	    /*Vect_cat_set (categories, F_INTERPOLATION, line_out_counter); */

	    if (Vect_point_in_box(obs[i][0], obs[i][1], interpolation, &Overlap)) {	/*(5) */
		residual = *point->z - interpolation;
		edge =
		    edge_detection(Elaboration, Overlap, parBilin, *point->x,
				   *point->y, gradient, alpha, residual,
				   gradHigh, gradLow);

		Vect_cat_set(categories, F_EDGE_DETECTION_CLASS, edge);
		Vect_cat_set(categories, F_INTERPOLATION, line_out_counter);
		Vect_write_line(Out, GV_POINT, point, categories);
		Insert_Interpolation(interpolation, line_out_counter, driver,
				     tabint_name);
		line_out_counter++;
	    }
	    else {
		if ((*point->x > Overlap.E) && (*point->x < General.E)) {
		    if ((*point->y > Overlap.N) && (*point->y < General.N)) {	/*(3) */
			csi = (General.E - *point->x) / overlap;
			eta = (General.N - *point->y) / overlap;
			weight = csi * eta;

			gradient[0] *= weight;
			gradient[1] *= weight;
			interpolation *= weight;

			if (Select(&gradient[0], &gradient[1],
			           &interpolation, line_num[i], driver,
				   tab_name) != DB_OK)
			    G_fatal_error(_("Impossible to read from aux table"));

			if (UpDate(gradient[0], gradient[1],
			           interpolation, line_num[i], driver,
			           tab_name) != DB_OK)
			    G_fatal_error(_("Impossible to update aux table"));
		    }
		    else if ((*point->y < Overlap.S) && (*point->y > General.S)) {	/*(1) */
			csi = (General.E - *point->x) / overlap;
			eta = (*point->y - General.S) / overlap;
			weight = csi * eta;

			gradient[0] *= weight;
			gradient[1] *= weight;
			interpolation *= weight;

			if (Insert(gradient[0], gradient[1], interpolation,
			           line_num[i], driver, tab_name) != DB_OK)
			    G_fatal_error(_("Impossible to write to aux table"));

		    }
		    else if ((*point->y <= Overlap.N) && (*point->y >= Overlap.S)) {	/*(1) */
			weight = (General.E - *point->x) / overlap;

			gradient[0] *= weight;
			gradient[1] *= weight;
			interpolation *= weight;

			if (Insert(gradient[0], gradient[1], interpolation,
			           line_num[i], driver, tab_name) != DB_OK)
			    G_fatal_error(_("Impossible to write to aux table"));
		    }
		}
		else if ((*point->x < Overlap.W) && (*point->x > General.W)) {
		    if ((*point->y > Overlap.N) && (*point->y < General.N)) {	/*(4) */
			csi = (*point->x - General.W) / overlap;
			eta = (General.N - *point->y) / overlap;
			weight = eta * csi;

			gradient[0] *= weight;
			gradient[1] *= weight;
			interpolation *= weight;

			if (Select(&gradient[0], &gradient[1],
			           &interpolation, line_num[i], driver,
			           tab_name) != DB_OK)
			    G_fatal_error(_("Impossible to read from aux table"));

			residual = *point->z - interpolation;
			edge =
			    edge_detection(Elaboration, Overlap, parBilin,
					   *point->x, *point->y, gradient,
					   alpha, residual, gradHigh,
					   gradLow);

			Vect_cat_set(categories, F_EDGE_DETECTION_CLASS,
				     edge);
			Vect_cat_set(categories, F_INTERPOLATION,
				     line_out_counter);
			Vect_write_line(Out, GV_POINT, point, categories);
			Insert_Interpolation(interpolation, line_out_counter,
					     driver, tabint_name);
			line_out_counter++;
		    }
		    else if ((*point->y < Overlap.S) && (*point->y > General.S)) {	/*(2) */
			csi = (*point->x - General.W) / overlap;
			eta = (*point->y - General.S) / overlap;
			weight = csi * eta;

			gradient[0] *= weight;
			gradient[1] *= weight;
			interpolation *= weight;

			if (Select(&gradient[0], &gradient[1],
			           &interpolation, line_num[i], driver,
			           tab_name) != DB_OK)
			    G_fatal_error(_("Impossible to read from aux table"));

			if (UpDate(gradient[0], gradient[1],
			           interpolation, line_num[i], driver,
			    tab_name) != DB_OK)
			    G_fatal_error(_("Impossible to update aux table"));

		    }
		    else if ((*point->y <= Overlap.N) && (*point->y >= Overlap.S)) {	/*(2) */
			weight = (*point->x - General.W) / overlap;

			gradient[0] *= weight;
			gradient[1] *= weight;
			interpolation *= weight;

			if (Select(&gradient[0], &gradient[1],
			           &interpolation, line_num[i], driver,
			           tab_name) != DB_OK)
			    G_fatal_error(_("Impossible to read from aux table"));

			residual = *point->z - interpolation;
			edge =
			    edge_detection(Elaboration, Overlap, parBilin,
					   *point->x, *point->y, gradient,
					   alpha, residual, gradHigh,
					   gradLow);

			Vect_cat_set(categories, F_EDGE_DETECTION_CLASS,
				     edge);
			Vect_cat_set(categories, F_INTERPOLATION,
				     line_out_counter);
			Vect_write_line(Out, GV_POINT, point, categories);
			Insert_Interpolation(interpolation, line_out_counter,
					     driver, tabint_name);
			line_out_counter++;
		    }
		}
		else if ((*point->x <= Overlap.E) && (*point->x >= Overlap.W)) {
		    if ((*point->y > Overlap.N) && (*point->y < General.N)) {	/*(3) */
			weight = (General.N - *point->y) / overlap;

			gradient[0] *= weight;
			gradient[1] *= weight;
			interpolation *= weight;

			if (Select(&gradient[0], &gradient[1],
			           &interpolation, line_num[i], driver,
			           tab_name) != DB_OK)
			    G_fatal_error(_("Impossible to read from aux table"));

			residual = *point->z - interpolation;
			edge =
			    edge_detection(Elaboration, Overlap, parBilin,
					   *point->x, *point->y, gradient,
					   alpha, residual, gradHigh,
					   gradLow);

			Vect_cat_set(categories, F_EDGE_DETECTION_CLASS,
				     edge);
			Vect_cat_set(categories, F_INTERPOLATION,
				     line_out_counter);
			Vect_write_line(Out, GV_POINT, point, categories);
			Insert_Interpolation(interpolation, line_out_counter,
					     driver, tabint_name);
			line_out_counter++;
		    }
		    else if ((*point->y < Overlap.S) && (*point->y > General.S)) {	/*(1) */
			weight = (*point->y - General.S) / overlap;

			gradient[0] *= weight;
			gradient[1] *= weight;
			interpolation *= weight;

			if (Insert(gradient[0], gradient[1], interpolation,
			           line_num[i], driver, tab_name) != DB_OK)
			    G_fatal_error(_("Impossible to write to aux table"));

		    }		/*else (1) */
		}		/*else */
	    }
	}			/*end if obs */
    }				/*end for */
    G_percent(num_points, num_points, 2); /* finish it */

    db_commit_transaction(driver);

    Vect_destroy_line_struct(point);
    Vect_destroy_cats_struct(categories);
}
예제 #14
0
int main(int argc, char **argv)
{
    int i;
    int **cats, *ncats, nfields, *fields;
    struct Flag *line_flag;

    /* struct Flag *all_flag; */
    struct Option *in_opt, *out_opt;
    struct Flag *table_flag;
    struct GModule *module;
    struct line_pnts *Points;
    struct line_cats *Cats;
    int node, nnodes;
    COOR *coor;
    int ncoor, acoor;
    int line, nlines, type, ctype, area, nareas;
    int err_boundaries, err_centr_out, err_centr_dupl, err_nocentr;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("geometry"));
    G_add_keyword(_("triangulation"));
    module->description = _("Creates a Voronoi diagram from an input vector "
			    "map containing points or centroids.");

    in_opt = G_define_standard_option(G_OPT_V_INPUT);
    out_opt = G_define_standard_option(G_OPT_V_OUTPUT);

    /*
       all_flag = G_define_flag ();
       all_flag->key = 'a';
       all_flag->description = _("Use all points (do not limit to current region)");
     */

    line_flag = G_define_flag();
    line_flag->key = 'l';
    line_flag->description =
	_("Output tessellation as a graph (lines), not areas");

    table_flag = G_define_flag();
    table_flag->key = 't';
    table_flag->description = _("Do not create attribute table");

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


    if (line_flag->answer)
	Type = GV_LINE;
    else
	Type = GV_BOUNDARY;

    All = 0;

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    /* open files */
    Vect_set_open_level(2);
    Vect_open_old(&In, in_opt->answer, "");

    if (Vect_open_new(&Out, out_opt->answer, 0) < 0)
	G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer);

    Vect_hist_copy(&In, &Out);
    Vect_hist_command(&Out);

    /* initialize working region */
    G_get_window(&Window);
    Vect_region_box(&Window, &Box);
    Box.T = 0.5;
    Box.B = -0.5;

    freeinit(&sfl, sizeof(struct Site));

    G_message(_("Reading sites..."));
    readsites();

    siteidx = 0;
    geominit();

    triangulate = 0;
    plot = 0;
    debug = 0;

    G_message(_("Voronoi triangulation..."));
    voronoi(triangulate, nextone);

    /* Close free ends by current region */
    Vect_build_partial(&Out, GV_BUILD_BASE);

    ncoor = 0;
    acoor = 100;
    coor = (COOR *) G_malloc(sizeof(COOR) * acoor);

    nnodes = Vect_get_num_nodes(&Out);
    for (node = 1; node <= nnodes; node++) {
	double x, y;

	if (Vect_get_node_n_lines(&Out, node) < 2) {	/* add coordinates */
	    Vect_get_node_coor(&Out, node, &x, &y, NULL);

	    if (ncoor == acoor - 5) {	/* always space for 5 region corners */
		acoor += 100;
		coor = (COOR *) G_realloc(coor, sizeof(COOR) * acoor);
	    }

	    coor[ncoor].x = x;
	    coor[ncoor].y = y;
	    ncoor++;
	}
    }

    /* Add region corners */
    coor[ncoor].x = Box.W;
    coor[ncoor].y = Box.S;
    ncoor++;
    coor[ncoor].x = Box.E;
    coor[ncoor].y = Box.S;
    ncoor++;
    coor[ncoor].x = Box.E;
    coor[ncoor].y = Box.N;
    ncoor++;
    coor[ncoor].x = Box.W;
    coor[ncoor].y = Box.N;
    ncoor++;

    /* Sort */
    qsort(coor, ncoor, sizeof(COOR), (void *)cmp);

    /* add last (first corner) */
    coor[ncoor].x = Box.W;
    coor[ncoor].y = Box.S;
    ncoor++;

    for (i = 1; i < ncoor; i++) {
	if (coor[i].x == coor[i - 1].x && coor[i].y == coor[i - 1].y)
	    continue;		/* duplicate */

	Vect_reset_line(Points);
	Vect_append_point(Points, coor[i].x, coor[i].y, 0.0);
	Vect_append_point(Points, coor[i - 1].x, coor[i - 1].y, 0.0);
	Vect_write_line(&Out, Type, Points, Cats);
    }

    G_free(coor);

    /* Copy input points as centroids */
    nfields = Vect_cidx_get_num_fields(&In);
    cats = (int **)G_malloc(nfields * sizeof(int *));
    ncats = (int *)G_malloc(nfields * sizeof(int));
    fields = (int *)G_malloc(nfields * sizeof(int));
    for (i = 0; i < nfields; i++) {
	ncats[i] = 0;
	cats[i] =
	    (int *)G_malloc(Vect_cidx_get_num_cats_by_index(&In, i) *
			    sizeof(int));
	fields[i] = Vect_cidx_get_field_number(&In, i);
    }

    if (line_flag->answer)
	ctype = GV_POINT;
    else
	ctype = GV_CENTROID;

    nlines = Vect_get_num_lines(&In);

    G_message(_("Writing sites to output..."));

    for (line = 1; line <= nlines; line++) {

	G_percent(line, nlines, 2);

	type = Vect_read_line(&In, Points, Cats, line);
	if (!(type & GV_POINTS))
	    continue;

	if (!Vect_point_in_box(Points->x[0], Points->y[0], 0.0, &Box))
	    continue;

	Vect_write_line(&Out, ctype, Points, Cats);


	for (i = 0; i < Cats->n_cats; i++) {
	    int f, j;

	    f = -1;
	    for (j = 0; j < nfields; j++) {	/* find field */
		if (fields[j] == Cats->field[i]) {
		    f = j;
		    break;
		}
	    }
	    if (f > -1) {
		cats[f][ncats[f]] = Cats->cat[i];
		ncats[f]++;
	    }
	}
    }

    /* Copy tables */
    if (!(table_flag->answer)) {
	int ttype, ntabs = 0;
	struct field_info *IFi, *OFi;

	/* Number of output tabs */
	for (i = 0; i < Vect_get_num_dblinks(&In); i++) {
	    int f, j;

	    IFi = Vect_get_dblink(&In, i);

	    f = -1;
	    for (j = 0; j < nfields; j++) {	/* find field */
		if (fields[j] == IFi->number) {
		    f = j;
		    break;
		}
	    }
	    if (f > -1) {
		if (ncats[f] > 0)
		    ntabs++;
	    }
	}

	if (ntabs > 1)
	    ttype = GV_MTABLE;
	else
	    ttype = GV_1TABLE;

	for (i = 0; i < nfields; i++) {
	    int ret;

	    if (fields[i] == 0)
		continue;

	    G_message(_("Layer %d"), fields[i]);

	    /* Make a list of categories */
	    IFi = Vect_get_field(&In, fields[i]);
	    if (!IFi) {		/* no table */
		G_message(_("No table"));
		continue;
	    }

	    OFi =
		Vect_default_field_info(&Out, IFi->number, IFi->name, ttype);

	    ret =
		db_copy_table_by_ints(IFi->driver, IFi->database, IFi->table,
				      OFi->driver,
				      Vect_subst_var(OFi->database, &Out),
				      OFi->table, IFi->key, cats[i],
				      ncats[i]);

	    if (ret == DB_FAILED) {
		G_warning(_("Cannot copy table"));
	    }
	    else {
		Vect_map_add_dblink(&Out, OFi->number, OFi->name, OFi->table,
				    IFi->key, OFi->database, OFi->driver);
	    }
	}
    }


    Vect_close(&In);

    /* cleaning part 1: count errors */
    Vect_build_partial(&Out, GV_BUILD_CENTROIDS);
    err_boundaries = err_centr_out = err_centr_dupl = err_nocentr = 0;
    nlines = Vect_get_num_lines(&Out);
    for (line = 1; line <= nlines; line++) {

	if (!Vect_line_alive(&Out, line))
	    continue;

	type = Vect_get_line_type(&Out, line);
	if (type == GV_BOUNDARY) {
	    int left, right;

	    Vect_get_line_areas(&Out, line, &left, &right);

	    if (left == 0 || right == 0) {
		G_debug(3, "line = %d left = %d right = %d", line, 
			left, right);
		err_boundaries++;
	    }
	}
	if (type == GV_CENTROID) {
	    area = Vect_get_centroid_area(&Out, line);
	    if (area == 0)
		err_centr_out++;
	    else if (area < 0)
		err_centr_dupl++;
	}
    }

    err_nocentr = 0;
    nareas = Vect_get_num_areas(&Out);
    for (area = 1; area <= nareas; area++) {
	if (!Vect_area_alive(&Out, area))
	    continue;
	line = Vect_get_area_centroid(&Out, area);
	if (line == 0)
	    err_nocentr++;
    }

    /* cleaning part 2: snap */
    if (err_nocentr || err_centr_dupl || err_centr_out) {
	int nmod;

	G_important_message(_("Output needs topological cleaning"));
	Vect_snap_lines(&Out, GV_BOUNDARY, 1e-7, NULL);
	do {
	    Vect_break_lines(&Out, GV_BOUNDARY, NULL);
	    Vect_remove_duplicates(&Out, GV_BOUNDARY, NULL);
	    nmod =
		Vect_clean_small_angles_at_nodes(&Out, GV_BOUNDARY, NULL);
	} while (nmod > 0);

	err_boundaries = 0;
	nlines = Vect_get_num_lines(&Out);
	for (line = 1; line <= nlines; line++) {

	    if (!Vect_line_alive(&Out, line))
		continue;

	    type = Vect_get_line_type(&Out, line);
	    if (type == GV_BOUNDARY) {
		int left, right;

		Vect_get_line_areas(&Out, line, &left, &right);

		if (left == 0 || right == 0) {
		    G_debug(3, "line = %d left = %d right = %d", line, 
			    left, right);
		    err_boundaries++;
		}
	    }
	}
    }
    /* cleaning part 3: remove remaining incorrect boundaries */
    if (err_boundaries) {
	G_important_message(_("Removing incorrect boundaries from output"));
	nlines = Vect_get_num_lines(&Out);
	for (line = 1; line <= nlines; line++) {

	    if (!Vect_line_alive(&Out, line))
		continue;

	    type = Vect_get_line_type(&Out, line);
	    if (type == GV_BOUNDARY) {
		int left, right;

		Vect_get_line_areas(&Out, line, &left, &right);

		/* &&, not ||, no typo */
		if (left == 0 && right == 0) {
		    G_debug(3, "line = %d left = %d right = %d", line, 
			    left, right);
		    Vect_delete_line(&Out, line);
		}
	    }
	}
    }

    /* build clean topology */
    Vect_build_partial(&Out, GV_BUILD_NONE);
    Vect_build(&Out);
    Vect_close(&Out);

    G_done_msg(" ");
    exit(EXIT_SUCCESS);
}
예제 #15
0
/* shortest distance between line and area
 * return 1 inside area 
 * return 2 inside isle of area 
 * return 3 outside area */
int line2area(const struct Map_info *To,
	      struct line_pnts *Points, int type,
	      int area, const struct bound_box *abox,
	      double *fx, double *fy, double *fz,
	      double *falong, double *fangle,
	      double *tx, double *ty, double *tz,
	      double *talong, double *tangle,
	      double *dist,
	      int with_z)
{
    int i, j;
    double tmp_dist;
    int isle, nisles;
    int all_inside_outer, all_outside_outer, all_outside_inner;
    static struct line_pnts *aPoints = NULL;
    static struct line_pnts **iPoints = NULL;
    static struct bound_box *ibox = NULL;
    static int isle_alloc = 0;

    if (!aPoints)
	aPoints = Vect_new_line_struct();

    *dist = PORT_DOUBLE_MAX;

    /* fangle and tangle are angles in radians, counter clockwise from x axis
     * initialize to invalid angle */
    *fangle = *tangle = -9.;
    *falong = *talong = 0.;

    *fx = Points->x[0];
    *fy = Points->y[0];
    *fz = Points->z[0];

    *tx = Points->x[0];
    *ty = Points->y[0];
    *tz = Points->z[0];

    Vect_get_area_points(To, area, aPoints);
    nisles = Vect_get_area_num_isles(To, area);
    
    if (nisles > isle_alloc) {
	iPoints = G_realloc(iPoints, nisles * sizeof(struct line_pnts *));
	ibox = G_realloc(ibox, nisles * sizeof(struct bound_box));
	for (i = isle_alloc; i < nisles; i++)
	    iPoints[i] = Vect_new_line_struct();
	isle_alloc = nisles;
    }
    for (i = 0; i < nisles; i++) {
	isle = Vect_get_area_isle(To, area, i);
	Vect_get_isle_points(To, isle, iPoints[i]);
	Vect_get_isle_box(To, isle, &ibox[i]);
    }

    /* inside area ? */
    all_inside_outer = all_outside_outer = 1;
    all_outside_inner = 1;

    int in_box;
    for (i = 0; i < Points->n_points; i++) {
        if (with_z)
            in_box = Vect_point_in_box(Points->x[i], Points->y[i],
                                       Points->z[i], abox);
        else
            in_box = Vect_point_in_box_2d(Points->x[i], Points->y[i], abox);
        if (in_box) {

	    int poly;
	    
	    poly = Vect_point_in_poly(Points->x[i], Points->y[i], aPoints);
	    
	    if (poly > 0) {
		/* inside outer ring */
		all_outside_outer = 0;
	    }
	    else {
		/* outside outer ring */
		all_inside_outer = 0;
	    }
	    
	    /* exactly on boundary */
	    if (poly == 2) {
		line2line(Points, type, aPoints, GV_BOUNDARY,
		          fx, fy, fz, falong, fangle,
		          tx, ty, tz, talong, tangle,
			  dist, with_z);

		*talong = 0;
		*tangle = -9;
		
		return 1;
	    }
	    /* inside outer ring */
	    else if (poly == 1) {
		int inside_isle = 0;

		for (j = 0; j < nisles; j++) {
                    if (with_z)
                        in_box = Vect_point_in_box(Points->x[i], Points->y[i],
                                                   Points->z[i], &ibox[j]);
                    else
                        in_box = Vect_point_in_box_2d(Points->x[i],
                                                      Points->y[i], &ibox[j]);
                    if (in_box) {

			poly = Vect_point_in_poly(Points->x[i], Points->y[i], iPoints[j]);
			
			/* inside or exactly on boundary */
			if (poly > 0) {
			    double tmp_fx, tmp_fy, tmp_fz, tmp_fangle, tmp_falong;
			    double tmp_tx, tmp_ty, tmp_tz, tmp_tangle, tmp_talong;

			    /* pass all points of the line, 
			     * this will catch an intersection */
			    line2line(Points, type, iPoints[j], GV_BOUNDARY,
				      &tmp_fx, &tmp_fy, &tmp_fz, &tmp_falong, &tmp_fangle,
				      &tmp_tx, &tmp_ty, &tmp_tz, &tmp_talong, &tmp_tangle,
				      &tmp_dist, with_z);

			    if (*dist > tmp_dist) {
				*dist = tmp_dist;

				*fx = tmp_fx;
				*fy = tmp_fy;
				*fz = tmp_fz;
				*falong = tmp_falong;
				*fangle = tmp_fangle;

				*tx = tmp_tx;
				*ty = tmp_ty;
				*tz = tmp_tz;
				*talong = 0;
				*tangle = tmp_tangle;
			    }

			    if (poly == 1) /* excludes isle boundary */
				inside_isle = 1;
			    
			}
		    }
		    if (*dist == 0)
			break;
		}
		/* inside area (inside outer ring, outside inner rings
		 * or exactly on one of the inner rings) */
		if (!inside_isle) {
		    *fx = Points->x[i];
		    *fy = Points->y[i];
		    *fz = Points->z[i];

		    *tx = Points->x[i];
		    *ty = Points->y[i];
		    *tz = Points->z[i];

		    *fangle = *tangle = -9.;
		    *falong = *talong = 0.;
		    
		    *dist = 0;

		    return 1;
		}
		else {
		    /* inside one of the islands */
		    all_outside_inner = 0;
		    if (*dist == 0) {
			/* the line intersected with the isle boundary
			 * -> line is partially inside the area */

			*fangle = *tangle = -9.;
			*falong = *talong = 0.;

			return 1;
		    }
		    /* else continue with next point */
		}
	    } /* end inside outer ring */
	}
	else {
	    /* point not in box of outer ring */
	    all_inside_outer = 0;
	}
	/* exactly on boundary */
	if (*dist == 0)
	    return 1;
    }
    
    /* if all points are inside the outer ring and inside inner rings,
     * there could still be an intersection with one of the inner rings */
     if (all_inside_outer) {
	 if (all_outside_inner) {
	     /* at least one point is really inside the area!
	      * that should have been detected above */
	     G_fatal_error(_("At least one point is really inside the area!"));
	 }
	 /* else all points are inside one of the area isles 
	  * and we already have the minimum distance */
	  return 2;
     }

    /* if at least one point was found to be inside the outer ring, 
     * but no point really inside the area,
     * and at least one point outside,
     * then there must be an intersection of the line with both 
     * the outer ring and one of the isle boundaries */

    /* if all line points are outside of the area,
     * intersection is still possible */

    line2line(Points, type, aPoints, GV_BOUNDARY,
	      fx, fy, fz, falong, fangle,
	      tx, ty, tz, talong, tangle,
	      dist, with_z);

    *talong = 0;

    if (*dist == 0)
	return 1;

    return 3;
}
예제 #16
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);
}
예제 #17
0
파일: main.c 프로젝트: rashadkm/grass_cmake
int main(int argc, char **argv)
{
    int i, nsites, warn_once = 0;
    int all;
    long x, y;
    struct Cell_head window;
    struct GModule *module;
    struct
    {
	struct Option *input, *tests, *dfield, *layer;
    } parm;
    struct
    {
	struct Flag *q, *l, *region;
    } flag;
    double *w, *z;

    struct Map_info Map;
    int line, nlines, npoints;
    int field;
    struct line_pnts *Points;
    struct line_cats *Cats;
    struct bound_box box;

    /* Attributes */
    int nrecords;
    int ctype;
    struct field_info *Fi;
    dbDriver *Driver;
    dbCatValArray cvarr;

    G_gisinit(argv[0]);

    module = G_define_module();
    G_add_keyword(_("vector"));
    G_add_keyword(_("statistics"));
    G_add_keyword(_("points"));
    G_add_keyword(_("point pattern"));
    module->description = _("Tests for normality for vector points.");

    parm.input = G_define_standard_option(G_OPT_V_MAP);

    parm.layer = G_define_standard_option(G_OPT_V_FIELD);
    
    parm.tests = G_define_option();
    parm.tests->key = "tests";
    parm.tests->key_desc = "range";
    parm.tests->type = TYPE_STRING;
    parm.tests->multiple = YES;
    parm.tests->required = YES;
    parm.tests->label = _("Lists of tests (1-15)");
    parm.tests->description = _("E.g. 1,3-8,13");

    parm.dfield = G_define_standard_option(G_OPT_DB_COLUMN);
    parm.dfield->required = YES;

    flag.region = G_define_flag();
    flag.region->key = 'r';
    flag.region->description = _("Use only points in current region");

    flag.l = G_define_flag();
    flag.l->key = 'l';
    flag.l->description = _("Lognormality instead of normality");
    
    if (G_parser(argc, argv))
	exit(EXIT_FAILURE);
    
    all = flag.region->answer ? 0 : 1;

    /* Open input */
    Vect_set_open_level(2);
    if (Vect_open_old2(&Map, parm.input->answer, "", parm.layer->answer) < 0)
	G_fatal_error(_("Unable to open vector map <%s>"), parm.input->answer);

    field = Vect_get_field_number(&Map, parm.layer->answer);
    
    /* Read attributes */
    Fi = Vect_get_field(&Map, field);
    if (Fi == NULL) {
	G_fatal_error("Database connection not defined for layer %d", field);
    }
    
    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);

    nrecords = db_select_CatValArray(Driver, Fi->table, Fi->key, parm.dfield->answer,
				     NULL, &cvarr);
    G_debug(1, "nrecords = %d", nrecords);

    ctype = cvarr.ctype;
    if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE)
	G_fatal_error(_("Only numeric column type supported"));

    if (nrecords < 0)
	G_fatal_error(_("Unable to select data from table"));
    G_verbose_message(_("%d records selected from table"), nrecords);

    db_close_database_shutdown_driver(Driver);

    /* Read points */
    npoints = Vect_get_num_primitives(&Map, GV_POINT);
    z = (double *)G_malloc(npoints * sizeof(double));

    G_get_window(&window);
    Vect_region_box(&window, &box);

    Points = Vect_new_line_struct();
    Cats = Vect_new_cats_struct();

    nlines = Vect_get_num_lines(&Map);
    nsites = 0;
    for (line = 1; line <= nlines; line++) {
	int type, cat, ret, cval;
	double dval;

	G_debug(3, "line = %d", line);

	type = Vect_read_line(&Map, Points, Cats, line);
	if (!(type & GV_POINT))
	    continue;

	if (!all) {
	    if (!Vect_point_in_box(Points->x[0], Points->y[0], 0.0, &box))
		continue;
	}

	Vect_cat_get(Cats, 1, &cat);

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

	/* find actual value */
	if (ctype == DB_C_TYPE_INT) {
	    ret = db_CatValArray_get_value_int(&cvarr, cat, &cval);
	    if (ret != DB_OK) {
		G_warning(_("No record for cat %d"), cat);
		continue;
	    }
	    dval = cval;
	}
	else if (ctype == DB_C_TYPE_DOUBLE) {
	    ret = db_CatValArray_get_value_double(&cvarr, cat, &dval);
	    if (ret != DB_OK) {
		G_warning(_("No record for cat %d"), cat);
		continue;
	    }
	}

	G_debug(3, "dval = %e", dval);
	z[nsites] = dval;
	nsites++;
    }

    G_verbose_message(_("Number of points: %d"), nsites);
    
    if (nsites <= 0)
	G_fatal_error(_("No points found"));

    if (nsites < 4)
	G_warning(_("Too small sample"));
    
    if (flag.l->answer) {
	warn_once = 0;
	for (i = 0; i < nsites; ++i) {
	    if (z[i] > 1.0e-10)
		z[i] = log10(z[i]);
	    else if (!warn_once) {
		G_warning(_("Negative or very small point values set to -10.0"));
		z[i] = -10.0;
		warn_once = 1;
	    }
	}
    }

    for (i = 0; parm.tests->answers[i]; i++)
	if (!scan_cats(parm.tests->answers[i], &x, &y)) {
	    G_usage();
	    exit(EXIT_FAILURE);
	}
    for (i = 0; parm.tests->answers[i]; i++) {
	scan_cats(parm.tests->answers[i], &x, &y);
	while (x <= y)
	    switch (x++) {
	    case 1:		/* moments */
		fprintf(stdout, _("Moments \\sqrt{b_1} and b_2: "));
		w = Cdhc_omnibus_moments(z, nsites);
		fprintf(stdout, "%g %g\n", w[0], w[1]);
		break;
	    case 2:		/* geary */
		fprintf(stdout, _("Geary's a-statistic & an approx. normal: "));
		w = Cdhc_geary_test(z, nsites);
		fprintf(stdout, "%g %g\n", w[0], w[1]);
		break;
	    case 3:		/* extreme deviates */
		fprintf(stdout, _("Extreme normal deviates: "));
		w = Cdhc_extreme(z, nsites);
		fprintf(stdout, "%g %g\n", w[0], w[1]);
		break;
	    case 4:		/* D'Agostino */
		fprintf(stdout, _("D'Agostino's D & an approx. normal: "));
		w = Cdhc_dagostino_d(z, nsites);
		fprintf(stdout, "%g %g\n", w[0], w[1]);
		break;
	    case 5:		/* Kuiper */
		fprintf(stdout,
			_("Kuiper's V (regular & modified for normality): "));
		w = Cdhc_kuipers_v(z, nsites);
		fprintf(stdout, "%g %g\n", w[1], w[0]);
		break;
	    case 6:		/* Watson */
		fprintf(stdout,
			_("Watson's U^2 (regular & modified for normality): "));
		w = Cdhc_watson_u2(z, nsites);
		fprintf(stdout, "%g %g\n", w[1], w[0]);
		break;
	    case 7:		/* Durbin */
		fprintf(stdout,
			_("Durbin's Exact Test (modified Kolmogorov): "));
		w = Cdhc_durbins_exact(z, nsites);
		fprintf(stdout, "%g\n", w[0]);
		break;
	    case 8:		/* Anderson-Darling */
		fprintf(stdout,
			_("Anderson-Darling's A^2 (regular & modified for normality): "));
		w = Cdhc_anderson_darling(z, nsites);
		fprintf(stdout, "%g %g\n", w[1], w[0]);
		break;
	    case 9:		/* Cramer-Von Mises */
		fprintf(stdout,
			_("Cramer-Von Mises W^2(regular & modified for normality): "));
		w = Cdhc_cramer_von_mises(z, nsites);
		fprintf(stdout, "%g %g\n", w[1], w[0]);
		break;
	    case 10:		/* Kolmogorov-Smirnov */
		fprintf(stdout,
			_("Kolmogorov-Smirnov's D (regular & modified for normality): "));
		w = Cdhc_kolmogorov_smirnov(z, nsites);
		fprintf(stdout, "%g %g\n", w[1], w[0]);
		break;
	    case 11:		/* chi-square */
		fprintf(stdout,
			_("Chi-Square stat (equal probability classes) and d.f.: "));
		w = Cdhc_chi_square(z, nsites);
		fprintf(stdout, "%g %d\n", w[0], (int)w[1]);
		break;
	    case 12:		/* Shapiro-Wilk */
		if (nsites > 50) {
		    G_warning(_("Shapiro-Wilk's W cannot be used for n > 50"));
		    if (nsites < 99)
			G_message(_("Use Weisberg-Binghams's W''"));
		}
		else {
		    fprintf(stdout, _("Shapiro-Wilk W: "));
		    w = Cdhc_shapiro_wilk(z, nsites);
		    fprintf(stdout, "%g\n", w[0]);
		}
		break;
	    case 13:		/* Weisberg-Bingham */
		if (nsites > 99 || nsites < 50)
		    G_warning(_("Weisberg-Bingham's W'' cannot be used for n < 50 or n > 99"));
		else {
		    fprintf(stdout, _("Weisberg-Bingham's W'': "));
		    w = Cdhc_weisberg_bingham(z, nsites);
		    fprintf(stdout, "%g\n", w[0]);
		}
		break;
	    case 14:		/* Royston */
		if (nsites > 2000)
		    G_warning(_("Royston only extended Shapiro-Wilk's W up to n = 2000"));
		else {
		    fprintf(stdout, _("Shapiro-Wilk W'': "));
		    w = Cdhc_royston(z, nsites);
		    fprintf(stdout, "%g\n", w[0]);
		}
		break;
	    case 15:		/* Kotz */
		fprintf(stdout, _("Kotz' T'_f (Lognormality vs. Normality): "));
		w = Cdhc_kotz_families(z, nsites);
		fprintf(stdout, "%g\n", w[0]);
		break;
	    default:
		break;
	    }
    }
    exit(EXIT_SUCCESS);
}