/*----------------------------------------------------------------------------------------*/ 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; }
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, ®ion_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, ®ion_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; } }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
/*--------------------------------------------------------------------------------*/ 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); }
/*------------------------------------------------------------------------------------------------*/ 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; }
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; }
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); }
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); }
/* 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; }
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); }
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); }