/*- * Reads ptr and returns 0 on success, * -1 on EOF, * -2 on other fatal error or insufficient data, * 1 on format mismatch (extra data) */ int G_site_get(struct Map_info *Map, Site * s) { int i, type, cat; static struct line_pnts *Points = NULL; static struct line_cats *Cats = NULL; SITE_ATT *sa; if (Points == NULL) Points = Vect_new_line_struct(); if (Cats == NULL) Cats = Vect_new_cats_struct(); while (1) { type = Vect_read_next_line(Map, Points, Cats); if (type == -1) return -2; /* Error */ if (type == -2) return -1; /* EOF */ if (type != GV_POINT) continue; /* Is not point */ Vect_cat_get(Cats, 1, &cat); G_debug(4, "Site: %f|%f|%f|#%d", Points->x[0], Points->y[0], Points->z[0], cat); s->east = Points->x[0]; s->north = Points->y[0]; if (Vect_is_3d(Map)) s->dim[0] = Points->z[0]; s->ccat = cat; /* find att */ if (Map->n_site_att > 0) { sa = (SITE_ATT *) bsearch((void *)&cat, (void *)Map->site_att, Map->n_site_att, sizeof(SITE_ATT), site_att_cmp); if (sa == NULL) { G_warning(_("Attributes for category %d not found"), cat); for (i = 0; i < Map->n_site_dbl; i++) s->dbl_att[i] = 0; for (i = 0; i < Map->n_site_str; i++) G_strncpy(s->str_att[i], "", MAX_SITE_STRING); } else { for (i = 0; i < Map->n_site_dbl; i++) s->dbl_att[i] = sa->dbl[i]; for (i = 0; i < Map->n_site_str; i++) G_strncpy(s->str_att[i], sa->str[i], MAX_SITE_STRING); } } return 0; } }
OGRGeometryH create_polygon(struct Map_info *In, int area, struct line_pnts *Points) { int j, k; OGRGeometryH Ogr_geometry, ring; Vect_get_area_points(In, area, Points); Ogr_geometry = OGR_G_CreateGeometry(wkbPolygon); ring = OGR_G_CreateGeometry(wkbLinearRing); /* Area */ for (j = 0; j < Points->n_points; j++) { if (Vect_is_3d(In)) OGR_G_AddPoint(ring, Points->x[j], Points->y[j], Points->z[j]); else OGR_G_AddPoint_2D(ring, Points->x[j], Points->y[j]); } OGR_G_AddGeometryDirectly(Ogr_geometry, ring); /* Isles */ for (k = 0; k < Vect_get_area_num_isles(In, area); k++) { Vect_get_isle_points(In, Vect_get_area_isle(In, area, k), Points); ring = OGR_G_CreateGeometry(wkbLinearRing); for (j = 0; j < Points->n_points; j++) { if(Vect_is_3d(In)) OGR_G_AddPoint(ring, Points->x[j], Points->y[j], Points->z[j]); else OGR_G_AddPoint_2D(ring, Points->x[j], Points->y[j]); } OGR_G_AddGeometryDirectly(Ogr_geometry, ring); } return Ogr_geometry; }
/*- * Tries to guess the format of a sites list (the dimensionality, * the presence/type of a category, and the number of string and decimal * attributes) by reading the first record in the file. * Reads ptr and returns 0 on success, * -1 on EOF, * -2 for other error. */ int G_site_describe(struct Map_info *Map, int *dims, int *cat, int *strs, int *dbls) { if (Vect_is_3d(Map)) { G_debug(1, "Vector is 3D -> number of site dimensions is 3"); *dims = 3; } else { G_debug(1, "Vector is 2D -> number of site dimensions is 2"); *dims = 2; } *cat = CELL_TYPE; /* attributes ignored for now, later read from DB */ *dbls = Map->n_site_dbl; *strs = Map->n_site_str; return 0; }
int main(int argc, char *argv[]) { int i, type, stat; int day, yr, Out_proj; int out_zone = 0; int overwrite; /* overwrite output map */ const char *mapset; const char *omap_name, *map_name, *iset_name, *iloc_name; struct pj_info info_in; struct pj_info info_out; const char *gbase; char date[40], mon[4]; struct GModule *module; struct Option *omapopt, *mapopt, *isetopt, *ilocopt, *ibaseopt, *smax; struct Key_Value *in_proj_keys, *in_unit_keys; struct Key_Value *out_proj_keys, *out_unit_keys; struct line_pnts *Points, *Points2; struct line_cats *Cats; struct Map_info Map; struct Map_info Out_Map; struct bound_box src_box, tgt_box; int nowrap = 0, recommend_nowrap = 0; double lmax; struct { struct Flag *list; /* list files in source location */ struct Flag *transformz; /* treat z as ellipsoidal height */ struct Flag *wrap; /* latlon output: wrap to 0,360 */ struct Flag *no_topol; /* do not build topology */ } flag; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("projection")); G_add_keyword(_("transformation")); G_add_keyword(_("import")); module->description = _("Re-projects a vector map from one location to the current location."); /* set up the options and flags for the command line parser */ ilocopt = G_define_standard_option(G_OPT_M_LOCATION); ilocopt->required = YES; ilocopt->label = _("Location containing input vector map"); ilocopt->guisection = _("Source"); isetopt = G_define_standard_option(G_OPT_M_MAPSET); isetopt->label = _("Mapset containing input vector map"); isetopt->description = _("Default: name of current mapset"); isetopt->guisection = _("Source"); mapopt = G_define_standard_option(G_OPT_V_INPUT); mapopt->required = NO; mapopt->label = _("Name of input vector map to re-project"); mapopt->description = NULL; mapopt->guisection = _("Source"); ibaseopt = G_define_standard_option(G_OPT_M_DBASE); ibaseopt->label = _("Path to GRASS database of input location"); smax = G_define_option(); smax->key = "smax"; smax->type = TYPE_DOUBLE; smax->required = NO; smax->answer = "10000"; smax->label = _("Maximum segment length in meters in output vector map"); smax->description = _("Increases accuracy of reprojected shapes, disable with smax=0"); smax->guisection = _("Target"); omapopt = G_define_standard_option(G_OPT_V_OUTPUT); omapopt->required = NO; omapopt->description = _("Name for output vector map (default: input)"); omapopt->guisection = _("Target"); flag.list = G_define_flag(); flag.list->key = 'l'; flag.list->description = _("List vector maps in input mapset and exit"); flag.transformz = G_define_flag(); flag.transformz->key = 'z'; flag.transformz->description = _("3D vector maps only"); flag.transformz->label = _("Assume z coordinate is ellipsoidal height and " "transform if possible"); flag.transformz->guisection = _("Target"); flag.wrap = G_define_flag(); flag.wrap->key = 'w'; flag.wrap->description = _("Latlon output only, default is -180,180"); flag.wrap->label = _("Disable wrapping to -180,180 for latlon output"); flag.transformz->guisection = _("Target"); flag.no_topol = G_define_flag(); flag.no_topol->key = 'b'; flag.no_topol->label = _("Do not build vector topology"); flag.no_topol->description = _("Recommended for massive point projection"); /* The parser checks if the map already exists in current mapset, we switch out the check and do it in the module after the parser */ overwrite = G_check_overwrite(argc, argv); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* start checking options and flags */ /* set input vector map name and mapset */ map_name = mapopt->answer; if (omapopt->answer) omap_name = omapopt->answer; else omap_name = map_name; if (omap_name && !flag.list->answer && !overwrite && G_find_vector2(omap_name, G_mapset())) G_fatal_error(_("option <%s>: <%s> exists. To overwrite, use the --overwrite flag"), omapopt->key, omap_name); if (isetopt->answer) iset_name = isetopt->answer; else iset_name = G_store(G_mapset()); iloc_name = ilocopt->answer; if (ibaseopt->answer) gbase = ibaseopt->answer; else gbase = G_store(G_gisdbase()); if (!ibaseopt->answer && strcmp(iloc_name, G_location()) == 0) G_fatal_error(_("Input and output locations can not be the same")); lmax = atof(smax->answer); if (lmax < 0) lmax = 0; Out_proj = G_projection(); if (Out_proj == PROJECTION_LL && flag.wrap->answer) nowrap = 1; G_begin_distance_calculations(); /* Change the location here and then come back */ select_target_env(); G_setenv_nogisrc("GISDBASE", gbase); G_setenv_nogisrc("LOCATION_NAME", iloc_name); stat = G_mapset_permissions(iset_name); if (stat >= 0) { /* yes, we can access the mapset */ /* if requested, list the vector maps in source location - MN 5/2001 */ if (flag.list->answer) { int i; char **list; G_verbose_message(_("Checking location <%s> mapset <%s>"), iloc_name, iset_name); list = G_list(G_ELEMENT_VECTOR, G_getenv_nofatal("GISDBASE"), G_getenv_nofatal("LOCATION_NAME"), iset_name); if (list[0]) { for (i = 0; list[i]; i++) { fprintf(stdout, "%s\n", list[i]); } fflush(stdout); } else { G_important_message(_("No vector maps found")); } exit(EXIT_SUCCESS); /* leave v.proj after listing */ } if (mapopt->answer == NULL) { G_fatal_error(_("Required parameter <%s> not set"), mapopt->key); } G_setenv_nogisrc("MAPSET", iset_name); /* Make sure map is available */ mapset = G_find_vector2(map_name, iset_name); if (mapset == NULL) G_fatal_error(_("Vector map <%s> in location <%s> mapset <%s> not found"), map_name, iloc_name, iset_name); /*** Get projection info for input mapset ***/ in_proj_keys = G_get_projinfo(); if (in_proj_keys == NULL) exit(EXIT_FAILURE); /* apparently the +over switch must be set in the input projection, * not the output latlon projection */ if (Out_proj == PROJECTION_LL && nowrap == 1) G_set_key_value("+over", "defined", in_proj_keys); in_unit_keys = G_get_projunits(); if (in_unit_keys == NULL) exit(EXIT_FAILURE); if (pj_get_kv(&info_in, in_proj_keys, in_unit_keys) < 0) exit(EXIT_FAILURE); Vect_set_open_level(1); G_debug(1, "Open old: location: %s mapset : %s", G_location_path(), G_mapset()); if (Vect_open_old(&Map, map_name, mapset) < 0) G_fatal_error(_("Unable to open vector map <%s>"), map_name); } else if (stat < 0) { /* allow 0 (i.e. denied permission) */ /* need to be able to read from others */ if (stat == 0) G_fatal_error(_("Mapset <%s> in input location <%s> - permission denied"), iset_name, iloc_name); else G_fatal_error(_("Mapset <%s> in input location <%s> not found"), iset_name, iloc_name); } select_current_env(); /****** get the output projection parameters ******/ out_proj_keys = G_get_projinfo(); if (out_proj_keys == NULL) exit(EXIT_FAILURE); out_unit_keys = G_get_projunits(); if (out_unit_keys == NULL) exit(EXIT_FAILURE); if (pj_get_kv(&info_out, out_proj_keys, out_unit_keys) < 0) exit(EXIT_FAILURE); G_free_key_value(in_proj_keys); G_free_key_value(in_unit_keys); G_free_key_value(out_proj_keys); G_free_key_value(out_unit_keys); if (G_verbose() == G_verbose_max()) { pj_print_proj_params(&info_in, &info_out); } /* Initialize the Point / Cat structure */ Points = Vect_new_line_struct(); Points2 = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); /* test if latlon wrapping to -180,180 should be disabled */ if (Out_proj == PROJECTION_LL && nowrap == 0) { int first = 1, counter = 0; double x, y; /* Cycle through all lines */ Vect_rewind(&Map); while (1) { type = Vect_read_next_line(&Map, Points, Cats); /* read line */ if (type == 0) continue; /* Dead */ if (type == -1) G_fatal_error(_("Reading input vector map")); if (type == -2) break; if (first && Points->n_points > 0) { first = 0; src_box.E = src_box.W = Points->x[0]; src_box.N = src_box.S = Points->y[0]; src_box.T = src_box.B = Points->z[0]; } for (i = 0; i < Points->n_points; i++) { if (src_box.E < Points->x[i]) src_box.E = Points->x[i]; if (src_box.W > Points->x[i]) src_box.W = Points->x[i]; if (src_box.N < Points->y[i]) src_box.N = Points->y[i]; if (src_box.S > Points->y[i]) src_box.S = Points->y[i]; } counter++; } if (counter == 0) { G_warning(_("Input vector map <%s> is empty"), omap_name); exit(EXIT_SUCCESS); } /* NW corner */ x = src_box.W; y = src_box.N; if (pj_do_transform(1, &x, &y, NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Error in pj_do_transform")); } tgt_box.E = x; tgt_box.W = x; tgt_box.N = y; tgt_box.S = y; /* SW corner */ x = src_box.W; y = src_box.S; if (pj_do_transform(1, &x, &y, NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Error in pj_do_transform")); } if (tgt_box.W > x) tgt_box.W = x; if (tgt_box.E < x) tgt_box.E = x; if (tgt_box.N < y) tgt_box.N = y; if (tgt_box.S > y) tgt_box.S = y; /* NE corner */ x = src_box.E; y = src_box.N; if (pj_do_transform(1, &x, &y, NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Error in pj_do_transform")); } if (tgt_box.W > x) { tgt_box.E = x + 360; recommend_nowrap = 1; } if (tgt_box.N < y) tgt_box.N = y; if (tgt_box.S > y) tgt_box.S = y; /* SE corner */ x = src_box.E; y = src_box.S; if (pj_do_transform(1, &x, &y, NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Error in pj_do_transform")); } if (tgt_box.W > x) { if (tgt_box.E < x + 360) tgt_box.E = x + 360; recommend_nowrap = 1; } if (tgt_box.N < y) tgt_box.N = y; if (tgt_box.S > y) tgt_box.S = y; } G_debug(1, "Open new: location: %s mapset : %s", G_location_path(), G_mapset()); if (Vect_open_new(&Out_Map, omap_name, Vect_is_3d(&Map)) < 0) G_fatal_error(_("Unable to create vector map <%s>"), omap_name); Vect_set_error_handler_io(NULL, &Out_Map); /* register standard i/o error handler */ Vect_copy_head_data(&Map, &Out_Map); Vect_hist_copy(&Map, &Out_Map); Vect_hist_command(&Out_Map); out_zone = info_out.zone; Vect_set_zone(&Out_Map, out_zone); /* Read and write header info */ sprintf(date, "%s", G_date()); sscanf(date, "%*s%s%d%*s%d", mon, &day, &yr); if (yr < 2000) yr = yr - 1900; else yr = yr - 2000; sprintf(date, "%s %d %d", mon, day, yr); Vect_set_date(&Out_Map, date); /* line densification works only with vector topology */ if (Map.format != GV_FORMAT_NATIVE) lmax = 0; /* Cycle through all lines */ Vect_rewind(&Map); i = 0; G_message(_("Reprojecting primitives ...")); while (TRUE) { ++i; G_progress(i, 1e3); type = Vect_read_next_line(&Map, Points, Cats); /* read line */ if (type == 0) continue; /* Dead */ if (type == -1) G_fatal_error(_("Reading input vector map")); if (type == -2) break; Vect_line_prune(Points); if (lmax > 0 && (type & GV_LINES) && Points->n_points > 1) { double x1, y1, z1, x2, y2, z2; double dx, dy, dz; double l; int i, n; Vect_reset_line(Points2); for (i = 0; i < Points->n_points - 1; i++) { x1 = Points->x[i]; y1 = Points->y[i]; z1 = Points->z[i]; n = i + 1; x2 = Points->x[n]; y2 = Points->y[n]; z2 = Points->z[n]; dx = x2 - x1; dy = y2 - y1; dz = z2 - z1; if (pj_do_transform(1, &x1, &y1, flag.transformz->answer ? &z1 : NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"), Vect_get_full_name(&Map), ilocopt->answer); } if (pj_do_transform(1, &x2, &y2, flag.transformz->answer ? &z2 : NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"), Vect_get_full_name(&Map), ilocopt->answer); } Vect_append_point(Points2, x1, y1, z1); l = G_distance(x1, y1, x2, y2); if (l > lmax) { int j; double x, y, z; x1 = Points->x[i]; y1 = Points->y[i]; z1 = Points->z[i]; n = ceil(l / lmax); for (j = 1; j < n; j++) { x = x1 + dx * j / n; y = y1 + dy * j / n; z = z1 + dz * j / n; if (pj_do_transform(1, &x, &y, flag.transformz->answer ? &z : NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"), Vect_get_full_name(&Map), ilocopt->answer); } Vect_append_point(Points2, x, y, z); } } } Vect_append_point(Points2, x2, y2, z2); Vect_write_line(&Out_Map, type, Points2, Cats); /* write line */ } else { if (pj_do_transform(Points->n_points, Points->x, Points->y, flag.transformz->answer ? Points->z : NULL, &info_in, &info_out) < 0) { G_fatal_error(_("Unable to re-project vector map <%s> from <%s>"), Vect_get_full_name(&Map), ilocopt->answer); } Vect_write_line(&Out_Map, type, Points, Cats); /* write line */ } } /* end lines section */ G_progress(1, 1); /* Copy tables */ if (Vect_copy_tables(&Map, &Out_Map, 0)) G_warning(_("Failed to copy attribute table to output map")); Vect_close(&Map); if (!flag.no_topol->answer) Vect_build(&Out_Map); Vect_close(&Out_Map); if (recommend_nowrap) G_important_message(_("Try to disable wrapping to -180,180 " "if topological errors occurred")); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct GModule *module; struct { struct Flag *r, *w, *l, *g, *a, *n, *c; } flag; struct { struct Option *map, *field, *colr, *rast, *volume, *rules, *attrcol, *rgbcol, *range, *use; } opt; int layer; int overwrite, remove, is_from_stdin, stat, have_colors, convert, use; const char *mapset, *cmapset; const char *style, *rules, *cmap, *attrcolumn, *rgbcolumn; char *name; struct Map_info Map; struct FPRange range; struct Colors colors, colors_tmp; /* struct Cell_stats statf; */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("color table")); module->description = _("Creates/modifies the color table associated with a vector map."); opt.map = G_define_standard_option(G_OPT_V_MAP); opt.field = G_define_standard_option(G_OPT_V_FIELD); opt.use = G_define_option(); opt.use->key = "use"; opt.use->type = TYPE_STRING; opt.use->required = YES; opt.use->multiple = NO; opt.use->options = "attr,cat,z"; opt.use->description = _("Source values"); G_asprintf((char **) &(opt.use->descriptions), "attr;%s;cat;%s;z;%s", _("read values from attribute table (requires <column> option)"), _("use category values"), _("use z coordinate (3D points or centroids only)")); opt.use->answer = "cat"; opt.attrcol = G_define_standard_option(G_OPT_DB_COLUMN); opt.attrcol->label = _("Name of column containing numeric data"); opt.attrcol->description = _("Required for use=attr"); opt.attrcol->guisection = _("Define"); opt.range = G_define_option(); opt.range->key = "range"; opt.range->type = TYPE_DOUBLE; opt.range->required = NO; opt.range->label = _("Manually set range (refers to 'column' option)"); opt.range->description = _("Ignored when 'rules' given"); opt.range->key_desc = "min,max"; opt.colr = G_define_standard_option(G_OPT_M_COLR); opt.colr->guisection = _("Define"); opt.rast = G_define_standard_option(G_OPT_R_INPUT); opt.rast->key = "raster"; opt.rast->required = NO; opt.rast->description = _("Raster map from which to copy color table"); opt.rast->guisection = _("Define"); opt.volume = G_define_standard_option(G_OPT_R3_INPUT); opt.volume->key = "raster_3d"; opt.volume->required = NO; opt.volume->description = _("3D raster map from which to copy color table"); opt.volume->guisection = _("Define"); opt.rules = G_define_standard_option(G_OPT_F_INPUT); opt.rules->key = "rules"; opt.rules->required = NO; opt.rules->description = _("Path to rules file"); opt.rules->guisection = _("Define"); opt.rgbcol = G_define_standard_option(G_OPT_DB_COLUMN); opt.rgbcol->key = "rgb_column"; opt.rgbcol->label = _("Name of color column to populate RGB values"); opt.rgbcol->description = _("If not given writes color table"); flag.r = G_define_flag(); flag.r->key = 'r'; flag.r->description = _("Remove existing color table"); flag.r->guisection = _("Remove"); flag.w = G_define_flag(); flag.w->key = 'w'; flag.w->description = _("Only write new color table if it does not already exist"); flag.l = G_define_flag(); flag.l->key = 'l'; flag.l->description = _("List available rules then exit"); flag.l->suppress_required = YES; flag.l->guisection = _("Print"); flag.n = G_define_flag(); flag.n->key = 'n'; flag.n->description = _("Invert colors"); flag.n->guisection = _("Define"); flag.g = G_define_flag(); flag.g->key = 'g'; flag.g->description = _("Logarithmic scaling"); flag.g->guisection = _("Define"); flag.a = G_define_flag(); flag.a->key = 'a'; flag.a->description = _("Logarithmic-absolute scaling"); flag.a->guisection = _("Define"); flag.c = G_define_flag(); flag.c->key = 'c'; flag.c->label = _("Convert color rules from RGB values to color table"); flag.c->description = _("Option 'rgb_column' with valid RGB values required"); /* TODO ? flag.e = G_define_flag(); flag.e->key = 'e'; flag.e->description = _("Histogram equalization"); flag.e->guisection = _("Define"); */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (flag.l->answer) { G_list_color_rules(stdout); return EXIT_SUCCESS; } overwrite = !flag.w->answer; remove = flag.r->answer; name = opt.map->answer; style = opt.colr->answer; rules = opt.rules->answer; attrcolumn = opt.attrcol->answer; rgbcolumn = opt.rgbcol->answer; convert = flag.c->answer; use = USE_CAT; if (opt.use->answer) { switch (opt.use->answer[0]) { case 'a': use = USE_ATTR; break; case 'c': use = USE_CAT; break; case 'z': use = USE_Z; break; default: break; } } G_debug(1, "use=%d", use); if (!name) G_fatal_error(_("No vector map specified")); if (use == USE_ATTR && !attrcolumn) G_fatal_error(_("Option <%s> required"), opt.attrcol->key); if (use != USE_ATTR && attrcolumn) { G_important_message(_("Option <%s> given, assuming <use=attr>..."), opt.attrcol->key); use = USE_ATTR; } if (opt.rast->answer && opt.volume->answer) G_fatal_error(_("%s= and %s= are mutually exclusive"), opt.rast->key, opt.volume->key); cmap = NULL; if (opt.rast->answer) cmap = opt.rast->answer; if (opt.volume->answer) cmap = opt.volume->answer; if (!cmap && !style && !rules && !remove && !convert) G_fatal_error(_("One of -%c, -%c or %s=, %s= or %s= " "must be specified"), flag.r->key, flag.c->key, opt.colr->key, opt.rast->key, opt.rules->key); if (!!style + !!cmap + !!rules > 1) G_fatal_error(_("%s=, %s= and %s= are mutually exclusive"), opt.colr->key, opt.rules->key, opt.rast->key); if (flag.g->answer && flag.a->answer) G_fatal_error(_("-%c and -%c are mutually exclusive"), flag.g->key, flag.a->key); if (flag.c->answer && !rgbcolumn) G_fatal_error(_("%s= required for -%c"), opt.rgbcol->key, flag.c->key); is_from_stdin = rules && strcmp(rules, "-") == 0; if (is_from_stdin) G_fatal_error(_("Reading rules from standard input is not implemented yet, please provide path to rules file instead.")); mapset = G_find_vector(name, ""); if (!mapset) G_fatal_error(_("Vector map <%s> not found"), name); stat = -1; if (remove) { stat = Vect_remove_colors(name, mapset); if (stat < 0) G_fatal_error(_("Unable to remove color table of vector map <%s>"), name); if (stat == 0) G_warning(_("Color table of vector map <%s> not found"), name); return EXIT_SUCCESS; } G_suppress_warnings(TRUE); have_colors = Vect_read_colors(name, mapset, NULL); if (have_colors > 0 && !overwrite) { G_fatal_error(_("Color table exists. Exiting.")); } G_suppress_warnings(FALSE); /* open map and get min/max values */ Vect_set_open_level(1); /* no topology required */ if (Vect_open_old2(&Map, name, mapset, opt.field->answer) < 0) G_fatal_error(_("Unable to open vector map <%s>"), name); Vect_set_error_handler_io(&Map, NULL); if (use == USE_Z && !Vect_is_3d(&Map)) G_fatal_error(_("Vector map <%s> is not 3D"), Vect_get_full_name(&Map)); layer = Vect_get_field_number(&Map, opt.field->answer); if (layer < 1) G_fatal_error(_("Layer <%s> not found"), opt.field->answer); if (opt.range->answer) { range.min = atof(opt.range->answers[0]); range.max = atof(opt.range->answers[1]); if (range.min > range.max) G_fatal_error(_("Option <%s>: min must be greater or equal to max"), opt.range->key); } Rast_init_colors(&colors); if (is_from_stdin) { G_fatal_error(_("Reading color rules from standard input is currently not supported")); /* if (!read_color_rules(stdin, &colors, min, max, fp)) exit(EXIT_FAILURE); */ } else if (style || rules) { if (style && !G_find_color_rule(style)) G_fatal_error(_("Color table <%s> not found"), style); if (use == USE_CAT) { scan_cats(&Map, layer, style, rules, opt.range->answer ? &range : NULL, &colors); } else if (use == USE_Z) { scan_z(&Map, layer, style, rules, opt.range->answer ? &range : NULL, &colors); } else { scan_attr(&Map, layer, attrcolumn, style, rules, opt.range->answer ? &range : NULL, &colors); } } else { /* use color from another map (cmap) */ if (opt.rast->answer) { cmapset = G_find_raster2(cmap, ""); if (!cmapset) G_fatal_error(_("Raster map <%s> not found"), cmap); if (Rast_read_colors(cmap, cmapset, &colors) < 0) G_fatal_error(_("Unable to read color table for raster map <%s>"), cmap); } else if (opt.volume->answer) { cmapset = G_find_raster3d(cmap, ""); if (!cmapset) G_fatal_error(_("3D raster map <%s> not found"), cmap); if (Rast3d_read_colors(cmap, cmapset, &colors) < 0) G_fatal_error(_("Unable to read color table for 3D raster map <%s>"), cmap); } } if (flag.n->answer) Rast_invert_colors(&colors); /* TODO ? if (flag.e->answer) { if (!have_stats) have_stats = get_stats(name, mapset, &statf); Rast_histogram_eq_colors(&colors_tmp, &colors, &statf); colors = colors_tmp; } */ if (flag.g->answer) { Rast_log_colors(&colors_tmp, &colors, 100); colors = colors_tmp; } if (flag.a->answer) { Rast_abs_log_colors(&colors_tmp, &colors, 100); colors = colors_tmp; } G_important_message(_("Writing color rules...")); if (style || rules || opt.rast->answer || opt.volume->answer) { if (rgbcolumn) write_rgb_values(&Map, layer, rgbcolumn, &colors); else Vect_write_colors(name, mapset, &colors); } if (convert) { /* convert RGB values to color tables */ rgb2colr(&Map, layer, rgbcolumn, &colors); Vect_write_colors(name, mapset, &colors); } Vect_close(&Map); G_message(_("Color table for vector map <%s> set to '%s'"), G_fully_qualified_name(name, mapset), is_from_stdin || convert ? "rules" : style ? style : rules ? rules : cmap); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { struct Option *input_opt, *output_opt, *afield_opt, *nfield_opt, *tfield_opt, *tucfield_opt, *afcol, *abcol, *ncol, *type_opt; struct Option *max_dist, *file_opt; struct Flag *geo_f, *segments_f, *turntable_f; struct GModule *module; struct Map_info In, Out; int type, afield, nfield, tfield, tucfield, geo; double maxdist; /* Initialize the GIS calls */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("network")); G_add_keyword(_("shortest path")); module->description = _("Finds shortest path on vector network."); input_opt = G_define_standard_option(G_OPT_V_INPUT); output_opt = G_define_standard_option(G_OPT_V_OUTPUT); afield_opt = G_define_standard_option(G_OPT_V_FIELD); afield_opt->key = "arc_layer"; afield_opt->answer = "1"; afield_opt->required = YES; afield_opt->label = _("Arc layer"); type_opt = G_define_standard_option(G_OPT_V_TYPE); type_opt->key = "arc_type"; type_opt->options = "line,boundary"; type_opt->answer = "line,boundary"; type_opt->required = YES; type_opt->label = _("Arc type"); nfield_opt = G_define_standard_option(G_OPT_V_FIELD); nfield_opt->key = "node_layer"; nfield_opt->answer = "2"; nfield_opt->required = YES; nfield_opt->label = _("Node layer"); file_opt = G_define_standard_option(G_OPT_F_INPUT); file_opt->key = "file"; file_opt->required = NO; file_opt->description = _("Name of file containing start and end points. " "If not given, read from stdin"); afcol = G_define_option(); afcol->key = "arc_column"; afcol->type = TYPE_STRING; afcol->required = NO; afcol->description = _("Arc forward/both direction(s) cost column (number)"); afcol->guisection = _("Cost"); abcol = G_define_option(); abcol->key = "arc_backward_column"; abcol->type = TYPE_STRING; abcol->required = NO; abcol->description = _("Arc backward direction cost column (number)"); abcol->guisection = _("Cost"); ncol = G_define_option(); ncol->key = "node_column"; ncol->type = TYPE_STRING; ncol->required = NO; ncol->description = _("Node cost column (number)"); ncol->guisection = _("Cost"); max_dist = G_define_option(); max_dist->key = "dmax"; max_dist->type = TYPE_DOUBLE; max_dist->required = NO; max_dist->answer = "1000"; max_dist->label = _("Maximum distance to the network"); max_dist->description = _("If start/end are given as coordinates. " "If start/end point is outside this threshold, " "the path is not found " "and error message is printed. To speed up the process, keep this " "value as low as possible."); turntable_f = G_define_flag(); turntable_f->key = 't'; turntable_f->description = _("Use turntable"); turntable_f->guisection = _("Turntable"); tfield_opt = G_define_standard_option(G_OPT_V_FIELD); tfield_opt->key = "turn_layer"; tfield_opt->answer = "3"; tfield_opt->label = _("Layer with turntable"); tfield_opt->description = _("Relevant only with -t flag"); tfield_opt->guisection = _("Turntable"); tucfield_opt = G_define_standard_option(G_OPT_V_FIELD); tucfield_opt->key = "turn_cat_layer"; tucfield_opt->answer = "4"; tucfield_opt->label = _("Layer with unique categories used in turntable"); tucfield_opt->description = _("Relevant only with -t flag"); tucfield_opt->guisection = _("Turntable"); geo_f = G_define_flag(); geo_f->key = 'g'; geo_f->description = _("Use geodesic calculation for longitude-latitude locations"); segments_f = G_define_flag(); segments_f->key = 's'; segments_f->description = _("Write output as original input segments, " "not each path as one line."); if (G_parser(argc, argv)) exit(EXIT_FAILURE); type = Vect_option_to_types(type_opt); maxdist = atof(max_dist->answer); if (geo_f->answer) { geo = 1; if (G_projection() != PROJECTION_LL) G_warning(_("The current projection is not longitude-latitude")); } else geo = 0; Vect_check_input_output_name(input_opt->answer, output_opt->answer, G_FATAL_EXIT); Vect_set_open_level(2); if (Vect_open_old(&In, input_opt->answer, "") < 0) G_fatal_error(_("Unable to open vector map <%s>"), input_opt->answer); afield = Vect_get_field_number(&In, afield_opt->answer); nfield = Vect_get_field_number(&In, nfield_opt->answer); tfield = Vect_get_field_number(&In, tfield_opt->answer); tucfield = Vect_get_field_number(&In, tucfield_opt->answer); if (1 > Vect_open_new(&Out, output_opt->answer, Vect_is_3d(&In))) { Vect_close(&In); G_fatal_error(_("Unable to create vector map <%s>"), output_opt->answer); } Vect_hist_command(&Out); if (turntable_f->answer) Vect_net_ttb_build_graph(&In, type, afield, nfield, tfield, tucfield, afcol->answer, abcol->answer, ncol->answer, geo, 0); else Vect_net_build_graph(&In, type, afield, nfield, afcol->answer, abcol->answer, ncol->answer, geo, 0); path(&In, &Out, file_opt->answer, nfield, maxdist, segments_f->answer, tucfield, turntable_f->answer); Vect_close(&In); Vect_build(&Out); Vect_close(&Out); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { struct GModule *module; struct Option *map_opt, *field_opt, *fs_opt, *vs_opt, *nv_opt, *col_opt, *where_opt, *file_opt; struct Flag *c_flag, *v_flag, *r_flag; dbDriver *driver; dbString sql, value_string; dbCursor cursor; dbTable *table; dbColumn *column; dbValue *value; struct field_info *Fi; int ncols, col, more; struct Map_info Map; char query[1024]; struct ilist *list_lines; struct bound_box *min_box, *line_box; int i, line, area, init_box, cat; module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("database")); G_add_keyword(_("attribute table")); module->description = _("Prints vector map attributes."); map_opt = G_define_standard_option(G_OPT_V_MAP); field_opt = G_define_standard_option(G_OPT_V_FIELD); col_opt = G_define_standard_option(G_OPT_DB_COLUMNS); where_opt = G_define_standard_option(G_OPT_DB_WHERE); fs_opt = G_define_standard_option(G_OPT_F_SEP); fs_opt->description = _("Output field separator"); fs_opt->guisection = _("Format"); vs_opt = G_define_standard_option(G_OPT_F_SEP); vs_opt->key = "vs"; vs_opt->description = _("Output vertical record separator"); vs_opt->answer = NULL; vs_opt->guisection = _("Format"); nv_opt = G_define_option(); nv_opt->key = "nv"; nv_opt->type = TYPE_STRING; nv_opt->required = NO; nv_opt->description = _("Null value indicator"); nv_opt->guisection = _("Format"); file_opt = G_define_standard_option(G_OPT_F_OUTPUT); file_opt->key = "file"; file_opt->required = NO; file_opt->description = _("Name for output file (if omitted or \"-\" output to stdout)"); r_flag = G_define_flag(); r_flag->key = 'r'; r_flag->description = _("Print minimal region extent of selected vector features instead of attributes"); c_flag = G_define_flag(); c_flag->key = 'c'; c_flag->description = _("Do not include column names in output"); c_flag->guisection = _("Format"); v_flag = G_define_flag(); v_flag->key = 'v'; v_flag->description = _("Vertical output (instead of horizontal)"); v_flag->guisection = _("Format"); G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* set input vector map name and mapset */ if (file_opt->answer && strcmp(file_opt->answer, "-") != 0) { if (NULL == freopen(file_opt->answer, "w", stdout)) { G_fatal_error(_("Unable to open file <%s> for writing"), file_opt->answer); } } if (r_flag->answer) { min_box = (struct bound_box *) G_malloc(sizeof(struct bound_box)); G_zero((void *)min_box, sizeof(struct bound_box)); line_box = (struct bound_box *) G_malloc(sizeof(struct bound_box)); list_lines = Vect_new_list(); } else { min_box = line_box = NULL; list_lines = NULL; } db_init_string(&sql); db_init_string(&value_string); /* open input vector */ if (!r_flag->answer) Vect_open_old_head2(&Map, map_opt->answer, "", field_opt->answer); else { if (2 > Vect_open_old2(&Map, map_opt->answer, "", field_opt->answer)) { Vect_close(&Map); G_fatal_error(_("Unable to open vector map <%s> at topology level. " "Flag '%c' requires topology level."), map_opt->answer, r_flag->key); } } if ((Fi = Vect_get_field2(&Map, field_opt->answer)) == NULL) G_fatal_error(_("Database connection not defined for layer <%s>"), field_opt->answer); driver = db_start_driver_open_database(Fi->driver, Fi->database); if (!driver) G_fatal_error(_("Unable to open database <%s> by driver <%s>"), Fi->database, Fi->driver); if (col_opt->answer) sprintf(query, "SELECT %s FROM ", col_opt->answer); else sprintf(query, "SELECT * FROM "); db_set_string(&sql, query); db_append_string(&sql, Fi->table); if (where_opt->answer) { char *buf = NULL; buf = G_malloc((strlen(where_opt->answer) + 8)); sprintf(buf, " WHERE %s", where_opt->answer); db_append_string(&sql, buf); G_free(buf); } if (db_open_select_cursor(driver, &sql, &cursor, DB_SEQUENTIAL) != DB_OK) G_fatal_error(_("Unable to open select cursor")); table = db_get_cursor_table(&cursor); ncols = db_get_table_number_of_columns(table); /* column names if horizontal output (ignore for -r) */ if (!v_flag->answer && !c_flag->answer && !r_flag->answer) { for (col = 0; col < ncols; col++) { column = db_get_table_column(table, col); if (col) fprintf(stdout, "%s", fs_opt->answer); fprintf(stdout, "%s", db_get_column_name(column)); } fprintf(stdout, "\n"); } init_box = 1; /* fetch the data */ while (1) { if (db_fetch(&cursor, DB_NEXT, &more) != DB_OK) G_fatal_error(_("Unable to fetch data from table <%s>"), Fi->table); if (!more) break; cat = -1; for (col = 0; col < ncols; col++) { column = db_get_table_column(table, col); value = db_get_column_value(column); if (cat < 0 && strcmp(Fi->key, db_get_column_name(column)) == 0) { cat = db_get_value_int(value); if (r_flag->answer) break; } if (r_flag->answer) continue; db_convert_column_value_to_string(column, &value_string); if (!c_flag->answer && v_flag->answer) fprintf(stdout, "%s%s", db_get_column_name(column), fs_opt->answer); if (col && !v_flag->answer) fprintf(stdout, "%s", fs_opt->answer); if (nv_opt->answer && db_test_value_isnull(value)) fprintf(stdout, "%s", nv_opt->answer); else fprintf(stdout, "%s", db_get_string(&value_string)); if (v_flag->answer) fprintf(stdout, "\n"); } if (r_flag->answer) { /* get minimal region extent */ Vect_cidx_find_all(&Map, Vect_get_field_number(&Map, field_opt->answer), -1, cat, list_lines); for (i = 0; i < list_lines->n_values; i++) { line = list_lines->value[i]; area = Vect_get_centroid_area(&Map, line); if (area > 0) { if (!Vect_get_area_box(&Map, area, line_box)) G_fatal_error(_("Unable to get bounding box of area %d"), area); } else { if (!Vect_get_line_box(&Map, line, line_box)) G_fatal_error(_("Unable to get bounding box of line %d"), line); } if (init_box) { Vect_box_copy(min_box, line_box); init_box = 0; } else { Vect_box_extend(min_box, line_box); } } } else { if (!v_flag->answer) fprintf(stdout, "\n"); else if (vs_opt->answer) fprintf(stdout, "%s\n", vs_opt->answer); } } if (r_flag->answer) { fprintf(stdout, "n=%f\n", min_box->N); fprintf(stdout, "s=%f\n", min_box->S); fprintf(stdout, "w=%f\n", min_box->W); fprintf(stdout, "e=%f\n", min_box->E); if (Vect_is_3d(&Map)) { fprintf(stdout, "t=%f\n", min_box->T); fprintf(stdout, "b=%f\n", min_box->B); } fflush(stdout); G_free((void *)min_box); G_free((void *)line_box); Vect_destroy_list(list_lines); } db_close_cursor(&cursor); db_close_database_shutdown_driver(driver); Vect_close(&Map); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct Map_info In, Out, Error; struct line_pnts *Points; struct line_cats *Cats; int i, type, iter; struct GModule *module; /* GRASS module for parsing arguments */ struct Option *map_in, *map_out, *error_out, *thresh_opt, *method_opt, *look_ahead_opt; struct Option *iterations_opt, *cat_opt, *alpha_opt, *beta_opt, *type_opt; struct Option *field_opt, *where_opt, *reduction_opt, *slide_opt; struct Option *angle_thresh_opt, *degree_thresh_opt, *closeness_thresh_opt; struct Option *betweeness_thresh_opt; struct Flag *notab_flag, *loop_support_flag; int with_z; int total_input, total_output; /* Number of points in the input/output map respectively */ double thresh, alpha, beta, reduction, slide, angle_thresh; double degree_thresh, closeness_thresh, betweeness_thresh; int method; int look_ahead, iterations; int loop_support; int layer; int n_lines; int simplification, mask_type; struct cat_list *cat_list = NULL; char *s, *descriptions; /* initialize GIS environment */ G_gisinit(argv[0]); /* reads grass env, stores program name to G_program_name() */ /* initialize module */ module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("generalization")); G_add_keyword(_("simplification")); G_add_keyword(_("smoothing")); G_add_keyword(_("displacement")); G_add_keyword(_("network generalization")); module->description = _("Performs vector based generalization."); /* Define the different options as defined in gis.h */ map_in = G_define_standard_option(G_OPT_V_INPUT); field_opt = G_define_standard_option(G_OPT_V_FIELD_ALL); type_opt = G_define_standard_option(G_OPT_V_TYPE); type_opt->options = "line,boundary,area"; type_opt->answer = "line,boundary,area"; type_opt->guisection = _("Selection"); map_out = G_define_standard_option(G_OPT_V_OUTPUT); error_out = G_define_standard_option(G_OPT_V_OUTPUT); error_out->key = "error"; error_out->required = NO; error_out->description = _("Error map of all lines and boundaries not being generalized due to topology issues or over-simplification"); method_opt = G_define_option(); method_opt->key = "method"; method_opt->type = TYPE_STRING; method_opt->required = YES; method_opt->multiple = NO; method_opt->options = "douglas,douglas_reduction,lang,reduction,reumann,boyle,sliding_averaging,distance_weighting,chaiken,hermite,snakes,network,displacement"; descriptions = NULL; G_asprintf(&descriptions, "douglas;%s;" "douglas_reduction;%s;" "lang;%s;" "reduction;%s;" "reumann;%s;" "boyle;%s;" "sliding_averaging;%s;" "distance_weighting;%s;" "chaiken;%s;" "hermite;%s;" "snakes;%s;" "network;%s;" "displacement;%s;", _("Douglas-Peucker Algorithm"), _("Douglas-Peucker Algorithm with reduction parameter"), _("Lang Simplification Algorithm"), _("Vertex Reduction Algorithm eliminates points close to each other"), _("Reumann-Witkam Algorithm"), _("Boyle's Forward-Looking Algorithm"), _("McMaster's Sliding Averaging Algorithm"), _("McMaster's Distance-Weighting Algorithm"), _("Chaiken's Algorithm"), _("Interpolation by Cubic Hermite Splines"), _("Snakes method for line smoothing"), _("Network generalization"), _("Displacement of lines close to each other")); method_opt->descriptions = G_store(descriptions); method_opt->description = _("Generalization algorithm"); thresh_opt = G_define_option(); thresh_opt->key = "threshold"; thresh_opt->type = TYPE_DOUBLE; thresh_opt->required = YES; thresh_opt->options = "0-1000000000"; thresh_opt->description = _("Maximal tolerance value"); look_ahead_opt = G_define_option(); look_ahead_opt->key = "look_ahead"; look_ahead_opt->type = TYPE_INTEGER; look_ahead_opt->required = NO; look_ahead_opt->answer = "7"; look_ahead_opt->description = _("Look-ahead parameter"); reduction_opt = G_define_option(); reduction_opt->key = "reduction"; reduction_opt->type = TYPE_DOUBLE; reduction_opt->required = NO; reduction_opt->answer = "50"; reduction_opt->options = "0-100"; reduction_opt->description = _("Percentage of the points in the output of 'douglas_reduction' algorithm"); slide_opt = G_define_option(); slide_opt->key = "slide"; slide_opt->type = TYPE_DOUBLE; slide_opt->required = NO; slide_opt->answer = "0.5"; slide_opt->options = "0-1"; slide_opt->description = _("Slide of computed point toward the original point"); angle_thresh_opt = G_define_option(); angle_thresh_opt->key = "angle_thresh"; angle_thresh_opt->type = TYPE_DOUBLE; angle_thresh_opt->required = NO; angle_thresh_opt->answer = "3"; angle_thresh_opt->options = "0-180"; angle_thresh_opt->description = _("Minimum angle between two consecutive segments in Hermite method"); degree_thresh_opt = G_define_option(); degree_thresh_opt->key = "degree_thresh"; degree_thresh_opt->type = TYPE_INTEGER; degree_thresh_opt->required = NO; degree_thresh_opt->answer = "0"; degree_thresh_opt->description = _("Degree threshold in network generalization"); closeness_thresh_opt = G_define_option(); closeness_thresh_opt->key = "closeness_thresh"; closeness_thresh_opt->type = TYPE_DOUBLE; closeness_thresh_opt->required = NO; closeness_thresh_opt->answer = "0"; closeness_thresh_opt->options = "0-1"; closeness_thresh_opt->description = _("Closeness threshold in network generalization"); betweeness_thresh_opt = G_define_option(); betweeness_thresh_opt->key = "betweeness_thresh"; betweeness_thresh_opt->type = TYPE_DOUBLE; betweeness_thresh_opt->required = NO; betweeness_thresh_opt->answer = "0"; betweeness_thresh_opt->description = _("Betweeness threshold in network generalization"); alpha_opt = G_define_option(); alpha_opt->key = "alpha"; alpha_opt->type = TYPE_DOUBLE; alpha_opt->required = NO; alpha_opt->answer = "1.0"; alpha_opt->description = _("Snakes alpha parameter"); beta_opt = G_define_option(); beta_opt->key = "beta"; beta_opt->type = TYPE_DOUBLE; beta_opt->required = NO; beta_opt->answer = "1.0"; beta_opt->description = _("Snakes beta parameter"); iterations_opt = G_define_option(); iterations_opt->key = "iterations"; iterations_opt->type = TYPE_INTEGER; iterations_opt->required = NO; iterations_opt->answer = "1"; iterations_opt->description = _("Number of iterations"); cat_opt = G_define_standard_option(G_OPT_V_CATS); cat_opt->guisection = _("Selection"); where_opt = G_define_standard_option(G_OPT_DB_WHERE); where_opt->guisection = _("Selection"); loop_support_flag = G_define_flag(); loop_support_flag->key = 'l'; loop_support_flag->label = _("Disable loop support"); loop_support_flag->description = _("Do not modify end points of lines forming a closed loop"); notab_flag = G_define_standard_flag(G_FLG_V_TABLE); notab_flag->description = _("Do not copy attributes"); notab_flag->guisection = _("Attributes"); /* options and flags parser */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); thresh = atof(thresh_opt->answer); look_ahead = atoi(look_ahead_opt->answer); alpha = atof(alpha_opt->answer); beta = atof(beta_opt->answer); reduction = atof(reduction_opt->answer); iterations = atoi(iterations_opt->answer); slide = atof(slide_opt->answer); angle_thresh = atof(angle_thresh_opt->answer); degree_thresh = atof(degree_thresh_opt->answer); closeness_thresh = atof(closeness_thresh_opt->answer); betweeness_thresh = atof(betweeness_thresh_opt->answer); mask_type = type_mask(type_opt); G_debug(3, "Method: %s", method_opt->answer); s = method_opt->answer; if (strcmp(s, "douglas") == 0) method = DOUGLAS; else if (strcmp(s, "lang") == 0) method = LANG; else if (strcmp(s, "reduction") == 0) method = VERTEX_REDUCTION; else if (strcmp(s, "reumann") == 0) method = REUMANN; else if (strcmp(s, "boyle") == 0) method = BOYLE; else if (strcmp(s, "distance_weighting") == 0) method = DISTANCE_WEIGHTING; else if (strcmp(s, "chaiken") == 0) method = CHAIKEN; else if (strcmp(s, "hermite") == 0) method = HERMITE; else if (strcmp(s, "snakes") == 0) method = SNAKES; else if (strcmp(s, "douglas_reduction") == 0) method = DOUGLAS_REDUCTION; else if (strcmp(s, "sliding_averaging") == 0) method = SLIDING_AVERAGING; else if (strcmp(s, "network") == 0) method = NETWORK; else if (strcmp(s, "displacement") == 0) { method = DISPLACEMENT; /* we can displace only the lines */ mask_type = GV_LINE; } else { G_fatal_error(_("Unknown method")); exit(EXIT_FAILURE); } /* simplification or smoothing? */ switch (method) { case DOUGLAS: case DOUGLAS_REDUCTION: case LANG: case VERTEX_REDUCTION: case REUMANN: simplification = 1; break; default: simplification = 0; break; } Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); Vect_check_input_output_name(map_in->answer, map_out->answer, G_FATAL_EXIT); Vect_set_open_level(2); if (Vect_open_old2(&In, map_in->answer, "", field_opt->answer) < 1) G_fatal_error(_("Unable to open vector map <%s>"), map_in->answer); if (Vect_get_num_primitives(&In, mask_type) == 0) { G_warning(_("No lines found in input map <%s>"), map_in->answer); Vect_close(&In); exit(EXIT_SUCCESS); } with_z = Vect_is_3d(&In); if (0 > Vect_open_new(&Out, map_out->answer, with_z)) { Vect_close(&In); G_fatal_error(_("Unable to create vector map <%s>"), map_out->answer); } if (error_out->answer) { if (0 > Vect_open_new(&Error, error_out->answer, with_z)) { Vect_close(&In); G_fatal_error(_("Unable to create error vector map <%s>"), error_out->answer); } } Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); total_input = total_output = 0; layer = Vect_get_field_number(&In, field_opt->answer); /* parse filter options */ if (layer > 0) cat_list = Vect_cats_set_constraint(&In, layer, where_opt->answer, cat_opt->answer); if (method == DISPLACEMENT) { /* modifies only lines, all other features including boundaries are preserved */ /* options where, cats, and layer are respected */ G_message(_("Displacement...")); snakes_displacement(&In, &Out, thresh, alpha, beta, 1.0, 10.0, iterations, cat_list, layer); } /* TODO: rearrange code below. It's really messy */ if (method == NETWORK) { /* extracts lines of selected type, all other features are discarded */ /* options where, cats, and layer are ignored */ G_message(_("Network generalization...")); total_output = graph_generalization(&In, &Out, mask_type, degree_thresh, closeness_thresh, betweeness_thresh); } /* copy tables here because method == NETWORK is complete and * tables for Out may be needed for parse_filter_options() below */ if (!notab_flag->answer) { if (method == NETWORK) copy_tables_by_cats(&In, &Out); else Vect_copy_tables(&In, &Out, -1); } else if (where_opt->answer && method < NETWORK) { G_warning(_("Attributes are needed for 'where' option, copying table")); Vect_copy_tables(&In, &Out, -1); } /* smoothing/simplification */ if (method < NETWORK) { /* modifies only lines of selected type, all other features are preserved */ int not_modified_boundaries = 0, n_oversimplified = 0; struct line_pnts *APoints; /* original Points */ set_topo_debug(); Vect_copy_map_lines(&In, &Out); Vect_build_partial(&Out, GV_BUILD_CENTROIDS); G_message("-----------------------------------------------------"); G_message(_("Generalization (%s)..."), method_opt->answer); G_message(_("Using threshold: %g %s"), thresh, G_database_unit_name(1)); G_percent_reset(); APoints = Vect_new_line_struct(); n_lines = Vect_get_num_lines(&Out); for (i = 1; i <= n_lines; i++) { int after = 0; G_percent(i, n_lines, 1); type = Vect_read_line(&Out, APoints, Cats, i); if (!(type & GV_LINES) || !(mask_type & type)) continue; if (layer > 0) { if ((type & GV_LINE) && !Vect_cats_in_constraint(Cats, layer, cat_list)) continue; else if ((type & GV_BOUNDARY)) { int do_line = 0; int left, right; do_line = Vect_cats_in_constraint(Cats, layer, cat_list); if (!do_line) { /* check if any of the centroids is selected */ Vect_get_line_areas(&Out, i, &left, &right); if (left < 0) left = Vect_get_isle_area(&Out, abs(left)); if (right < 0) right = Vect_get_isle_area(&Out, abs(right)); if (left > 0) { Vect_get_area_cats(&Out, left, Cats); do_line = Vect_cats_in_constraint(Cats, layer, cat_list); } if (!do_line && right > 0) { Vect_get_area_cats(&Out, right, Cats); do_line = Vect_cats_in_constraint(Cats, layer, cat_list); } } if (!do_line) continue; } } Vect_line_prune(APoints); if (APoints->n_points < 2) /* Line of length zero, delete if boundary ? */ continue; total_input += APoints->n_points; /* copy points */ Vect_reset_line(Points); Vect_append_points(Points, APoints, GV_FORWARD); loop_support = 0; if (!loop_support_flag->answer) { int n1, n2; Vect_get_line_nodes(&Out, i, &n1, &n2); if (n1 == n2) { if (Vect_get_node_n_lines(&Out, n1) == 2) { if (abs(Vect_get_node_line(&Out, n1, 0)) == i && abs(Vect_get_node_line(&Out, n1, 1)) == i) loop_support = 1; } } } for (iter = 0; iter < iterations; iter++) { switch (method) { case DOUGLAS: douglas_peucker(Points, thresh, with_z); break; case DOUGLAS_REDUCTION: douglas_peucker_reduction(Points, thresh, reduction, with_z); break; case LANG: lang(Points, thresh, look_ahead, with_z); break; case VERTEX_REDUCTION: vertex_reduction(Points, thresh, with_z); break; case REUMANN: reumann_witkam(Points, thresh, with_z); break; case BOYLE: boyle(Points, look_ahead, loop_support, with_z); break; case SLIDING_AVERAGING: sliding_averaging(Points, slide, look_ahead, loop_support, with_z); break; case DISTANCE_WEIGHTING: distance_weighting(Points, slide, look_ahead, loop_support, with_z); break; case CHAIKEN: chaiken(Points, thresh, loop_support, with_z); break; case HERMITE: hermite(Points, thresh, angle_thresh, loop_support, with_z); break; case SNAKES: snakes(Points, alpha, beta, loop_support, with_z); break; } } if (loop_support == 0) { /* safety check, BUG in method if not passed */ if (APoints->x[0] != Points->x[0] || APoints->y[0] != Points->y[0] || APoints->z[0] != Points->z[0]) G_fatal_error(_("Method '%s' did not preserve first point"), method_opt->answer); if (APoints->x[APoints->n_points - 1] != Points->x[Points->n_points - 1] || APoints->y[APoints->n_points - 1] != Points->y[Points->n_points - 1] || APoints->z[APoints->n_points - 1] != Points->z[Points->n_points - 1]) G_fatal_error(_("Method '%s' did not preserve last point"), method_opt->answer); } else { /* safety check, BUG in method if not passed */ if (Points->x[0] != Points->x[Points->n_points - 1] || Points->y[0] != Points->y[Points->n_points - 1] || Points->z[0] != Points->z[Points->n_points - 1]) G_fatal_error(_("Method '%s' did not preserve loop"), method_opt->answer); } Vect_line_prune(Points); /* oversimplified line */ if (Points->n_points < 2) { after = APoints->n_points; n_oversimplified++; if (error_out->answer) Vect_write_line(&Error, type, APoints, Cats); } /* check for topology corruption */ else if (type == GV_BOUNDARY) { if (!check_topo(&Out, i, APoints, Points, Cats)) { after = APoints->n_points; not_modified_boundaries++; if (error_out->answer) Vect_write_line(&Error, type, APoints, Cats); } else after = Points->n_points; } else { /* type == GV_LINE */ Vect_rewrite_line(&Out, i, type, Points, Cats); after = Points->n_points; } total_output += after; } if (not_modified_boundaries > 0) G_warning(_("%d boundaries were not modified because modification would damage topology"), not_modified_boundaries); if (n_oversimplified > 0) G_warning(_("%d lines/boundaries were not modified due to over-simplification"), n_oversimplified); G_message("-----------------------------------------------------"); /* make sure that clean topo is built at the end */ Vect_build_partial(&Out, GV_BUILD_NONE); if (error_out->answer) Vect_build_partial(&Error, GV_BUILD_NONE); } Vect_build(&Out); if (error_out->answer) Vect_build(&Error); Vect_close(&In); Vect_close(&Out); if (error_out->answer) Vect_close(&Error); G_message("-----------------------------------------------------"); if (total_input != 0 && total_input != total_output) G_done_msg(_("Number of vertices for selected features %s from %d to %d (%d%% remaining)"), simplification ? _("reduced") : _("changed"), total_input, total_output, (total_output * 100) / total_input); else G_done_msg(" "); exit(EXIT_SUCCESS); }
int main(int argc, char **argv) { struct GModule *module; struct opts opt; struct Map_info In, Out; BOUND_BOX box; int field, type; int ret; G_gisinit(argv[0]); module = G_define_module(); module->keywords = _("vector, transformation, 3D"); module->description = _("Performs transformation of 2D vector features to 3D."); parse_args(&opt); if (G_parser(argc, argv)) exit(EXIT_FAILURE); field = atoi(opt.field->answer); type = Vect_option_to_types(opt.type); if (!opt.reverse->answer) { if ((!opt.height->answer && !opt.column->answer) || (opt.height->answer && opt.column->answer)) { G_fatal_error(_("Either '%s' or '%s' parameter have to be used"), opt.height->key, opt.column->key); } } else { if (opt.height->answer) { G_warning(_("Parameters '%s' ignored"), opt.height->key); } } if (opt.reverse->answer && opt.table->answer) { G_fatal_error(_("Attribute table required")); } Vect_check_input_output_name(opt.input->answer, opt.output->answer, GV_FATAL_EXIT); /* open input vector, topology not needed */ Vect_set_open_level(1); if (Vect_open_old(&In, opt.input->answer, "") < 1) G_fatal_error(_("Unable to open vector map <%s>"), opt.input->answer); if (opt.reverse->answer && !Vect_is_3d(&In)) { Vect_close(&In); G_fatal_error(_("Vector map <%s> is 2D"), opt.input->answer); } if (!opt.reverse->answer && Vect_is_3d(&In)) { Vect_close(&In); G_fatal_error(_("Vector map <%s> is 3D"), opt.input->answer); } /* create output vector */ Vect_set_open_level(2); if (Vect_open_new(&Out, opt.output->answer, opt.reverse->answer ? WITHOUT_Z : WITH_Z) == -1) G_fatal_error(_("Unable to create vector map <%s>"), opt.output->answer); /* copy history & header */ Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); Vect_copy_head_data(&In, &Out); if (opt.reverse->answer && !opt.table->answer) { G_message(_("Copying attributes...")); if (Vect_copy_tables(&In, &Out, 0) == -1) { G_warning(_("Unable to copy attributes")); } } G_message(_("Transforming features...")); ret = 0; if (opt.reverse->answer) { /* 3d -> 2d */ ret = trans3d(&In, &Out, type, field, opt.column->answer); } else { /* 2d -> 3d */ double height = 0.; if (opt.height->answer) { height = atof(opt.height->answer); } ret = trans2d(&In, &Out, type, height, field, opt.column->answer); } if (ret < 0) { Vect_close(&In); Vect_close(&Out); Vect_delete(opt.output->answer); G_fatal_error(_("%s failed"), G_program_name()); } if (!opt.reverse->answer && !opt.table->answer) { G_message(_("Copying attributes...")); if (Vect_copy_tables(&In, &Out, 0) == -1) { G_warning(_("Unable to copy attributes")); } } Vect_close(&In); Vect_build(&Out); if (!opt.reverse->answer) { Vect_get_map_box(&Out, &box); G_message(_("Vertical extent of vector map <%s>: B: %f T: %f"), opt.output->answer, box.B, box.T); } Vect_close(&Out); exit(EXIT_SUCCESS); }
int read_points(const char *name, const char *field_name, const char *col, std::map<Point, Coord_type, K::Less_xy_2>& function_values, std::vector<K::Point_2>& OutPoints) { int nrec, ctype = 0, npoints, field, with_z; double x, y, z; Point p; struct Map_info Map; struct field_info *Fi; struct line_pnts *Points; struct line_cats *Cats; dbDriver *Driver; dbCatValArray cvarr; Vect_set_open_level(1); /* without topology */ if (Vect_open_old2(&Map, name, "", field_name) < 0) G_fatal_error(_("Unable to open vector map <%s>"), name); field = Vect_get_field_number(&Map, field_name); with_z = col == NULL && Vect_is_3d(&Map); /* read z-coordinates only when column is not defined */ if (!col) { if (!with_z) G_important_message(_("Input vector map <%s> is 2D - using categories to interpolate"), Vect_get_full_name(&Map)); else G_important_message(_("Input vector map <%s> is 3D - using z-coordinates to interpolate"), Vect_get_full_name(&Map)); } if (col) { db_CatValArray_init(&cvarr); Fi = Vect_get_field(&Map, field); if (Fi == NULL) G_fatal_error(_("Database connection not defined for layer %s"), field_name); 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); nrec = db_select_CatValArray(Driver, Fi->table, Fi->key, col, NULL, &cvarr); G_debug(3, "nrec = %d", nrec); ctype = cvarr.ctype; if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE) G_fatal_error(_("Column type not supported")); if (nrec < 0) G_fatal_error(_("Unable to select data from table")); G_verbose_message("One record selected from table %d records selected from table", nrec); db_close_database_shutdown_driver(Driver); } Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); /* set constraints */ Vect_set_constraint_type(&Map, GV_POINTS); if (field > 0) Vect_set_constraint_field(&Map, field); /* read points */ npoints = 0; G_message(_("Reading points...")); while(TRUE) { double dval; if (Vect_read_next_line(&Map, Points, Cats) < 0) break; G_progress(npoints, 1e3); if (Points->n_points != 1) { G_warning(_("Invalid point skipped")); continue; } if (!with_z) { int cat, ival, ret; /* TODO: what to do with multiple cats */ Vect_cat_get(Cats, field, &cat); if (cat < 0) /* skip features without category */ continue; if (col) { if (ctype == DB_C_TYPE_INT) { ret = db_CatValArray_get_value_int(&cvarr, cat, &ival); dval = ival; } else { /* DB_C_TYPE_DOUBLE */ ret = db_CatValArray_get_value_double(&cvarr, cat, &dval); } if (ret != DB_OK) { G_warning(_("No record for point (cat = %d)"), cat); continue; } } else { dval = cat; } } else dval = Points->z[0]; x = Points->x[0]; y = Points->y[0]; p = Point(x,y); OutPoints.push_back(p); function_values.insert(std::make_pair(p, dval)); G_debug(3, "new point added: %f, %f, %f", x, y, dval); npoints++; } G_progress(1, 1); if (col) db_CatValArray_free(&cvarr); Vect_set_release_support(&Map); Vect_close(&Map); Vect_destroy_line_struct(Points); G_debug(1, "read_points(): %d", npoints); G_message("%d point loaded", npoints); return npoints; }
OGRGeometry *OGRGRASSLayer::GetFeatureGeometry ( long nFeatureId, int *cat ) { CPLDebug ( "GRASS", "OGRGRASSLayer::GetFeatureGeometry nFeatureId = %d", nFeatureId ); int cidx = paFeatureIndex[(int)nFeatureId]; int type, id; Vect_cidx_get_cat_by_index ( poMap, iLayerIndex, cidx, cat, &type, &id ); //CPLDebug ( "GRASS", "cat = %d type = %d id = %d", *cat, type, id ); OGRGeometry *poOGR = NULL; int bIs3D = Vect_is_3d(poMap); switch ( type ) { case GV_POINT: { Vect_read_line ( poMap, poPoints, poCats, id); if (bIs3D) poOGR = new OGRPoint( poPoints->x[0], poPoints->y[0], poPoints->z[0] ); else poOGR = new OGRPoint( poPoints->x[0], poPoints->y[0] ); } break; case GV_LINE: case GV_BOUNDARY: { Vect_read_line ( poMap, poPoints, poCats, id); OGRLineString *poOGRLine = new OGRLineString(); if (bIs3D) poOGRLine->setPoints( poPoints->n_points, poPoints->x, poPoints->y, poPoints->z ); else poOGRLine->setPoints( poPoints->n_points, poPoints->x, poPoints->y ); poOGR = poOGRLine; } break; case GV_AREA: { Vect_get_area_points ( poMap, id, poPoints ); OGRPolygon *poOGRPoly; poOGRPoly = new OGRPolygon(); OGRLinearRing *poRing; poRing = new OGRLinearRing(); if (bIs3D) poRing->setPoints( poPoints->n_points, poPoints->x, poPoints->y, poPoints->z ); else poRing->setPoints( poPoints->n_points, poPoints->x, poPoints->y ); poOGRPoly->addRingDirectly( poRing ); // Islands int nisles = Vect_get_area_num_isles ( poMap, id ); for ( int i = 0; i < nisles; i++ ) { int isle = Vect_get_area_isle ( poMap, id, i ); Vect_get_isle_points ( poMap, isle, poPoints ); poRing = new OGRLinearRing(); if (bIs3D) poRing->setPoints( poPoints->n_points, poPoints->x, poPoints->y, poPoints->z ); else poRing->setPoints( poPoints->n_points, poPoints->x, poPoints->y ); poOGRPoly->addRingDirectly( poRing ); } poOGR = poOGRPoly; } break; default: // Should not happen { CPLError( CE_Failure, CPLE_AppDefined, "Unknown GRASS feature type."); return NULL; } } return poOGR; }
OGRGRASSLayer::OGRGRASSLayer( int layerIndex, struct Map_info * map ) { CPLDebug ( "GRASS", "OGRGRASSLayer::OGRGRASSLayer layerIndex = %d", layerIndex ); iLayerIndex = layerIndex; poMap = map; poSRS = NULL; iNextId = 0; poPoints = Vect_new_line_struct(); poCats = Vect_new_cats_struct(); pszQuery = NULL; paQueryMatch = NULL; paSpatialMatch = NULL; iLayer = Vect_cidx_get_field_number ( poMap, iLayerIndex); CPLDebug ( "GRASS", "iLayer = %d", iLayer ); poLink = Vect_get_field ( poMap, iLayer ); // May be NULL if not defined // Layer name if ( poLink && poLink->name ) { pszName = CPLStrdup( poLink->name ); } else { char buf[20]; sprintf ( buf, "%d", iLayer ); pszName = CPLStrdup( buf ); } // Because we don't represent centroids as any simple feature, we have to scan // category index and create index of feature IDs pointing to category index nTotalCount = Vect_cidx_get_type_count(poMap,iLayer, GV_POINT|GV_LINES|GV_AREA); CPLDebug ( "GRASS", "nTotalCount = %d", nTotalCount ); paFeatureIndex = (int *) CPLMalloc ( nTotalCount * sizeof(int) ); int n = Vect_cidx_get_type_count(poMap,iLayer, GV_POINTS|GV_LINES|GV_AREA); int cnt = 0; for ( int i = 0; i < n; i++ ) { int cat,type, id; Vect_cidx_get_cat_by_index ( poMap, iLayerIndex, i, &cat, &type, &id ); if ( !( type & (GV_POINT|GV_LINES|GV_AREA) ) ) continue; paFeatureIndex[cnt++] = i; } poFeatureDefn = new OGRFeatureDefn( pszName ); poFeatureDefn->Reference(); // Get type definition int nTypes = Vect_cidx_get_num_types_by_index ( poMap, iLayerIndex ); int types = 0; for ( int i = 0; i < nTypes; i++ ) { int type, count; Vect_cidx_get_type_count_by_index ( poMap, iLayerIndex, i, &type, &count); if ( !(type & (GV_POINT|GV_LINES|GV_AREA) ) ) continue; types |= type; CPLDebug ( "GRASS", "type = %d types = %d", type, types ); } OGRwkbGeometryType eGeomType = wkbUnknown; if ( types == GV_LINE || types == GV_BOUNDARY || types == GV_LINES ) { eGeomType = wkbLineString; } else if ( types == GV_POINT ) { eGeomType = wkbPoint; } else if ( types == GV_AREA ) { CPLDebug ( "GRASS", "set wkbPolygon" ); eGeomType = wkbPolygon; } if (Vect_is_3d(poMap)) poFeatureDefn->SetGeomType ( (OGRwkbGeometryType)(eGeomType | wkb25DBit) ); else poFeatureDefn->SetGeomType ( eGeomType ); // Get attributes definition poDbString = (dbString*) CPLMalloc ( sizeof(dbString) ); poCursor = (dbCursor*) CPLMalloc ( sizeof(dbCursor) ); bCursorOpened = FALSE; poDriver = NULL; bHaveAttributes = false; db_init_string ( poDbString ); if ( poLink ) { if ( StartDbDriver() ) { db_set_string ( poDbString, poLink->table ); dbTable *table; if ( db_describe_table ( poDriver, poDbString, &table) == DB_OK ) { nFields = db_get_table_number_of_columns ( table ); iCatField = -1; for ( int i = 0; i < nFields; i++) { dbColumn *column = db_get_table_column ( table, i ); int ctype = db_sqltype_to_Ctype ( db_get_column_sqltype(column) ); OGRFieldType ogrFtype = OFTInteger; switch ( ctype ) { case DB_C_TYPE_INT: ogrFtype = OFTInteger; break; case DB_C_TYPE_DOUBLE: ogrFtype = OFTReal; break; case DB_C_TYPE_STRING: ogrFtype = OFTString; break; case DB_C_TYPE_DATETIME: ogrFtype = OFTDateTime; break; } CPLDebug ( "GRASS", "column = %s type = %d", db_get_column_name(column), ctype ); OGRFieldDefn oField ( db_get_column_name(column), ogrFtype ); poFeatureDefn->AddFieldDefn( &oField ); if ( G_strcasecmp(db_get_column_name(column),poLink->key) == 0 ) { iCatField = i; } } if ( iCatField >= 0 ) { bHaveAttributes = true; } else { CPLError( CE_Failure, CPLE_AppDefined, "Cannot find key field" ); db_close_database_shutdown_driver ( poDriver ); poDriver = NULL; } } else { CPLError( CE_Failure, CPLE_AppDefined, "Cannot describe table %s", poLink->table ); } db_close_database_shutdown_driver ( poDriver ); poDriver = NULL; } } if ( !bHaveAttributes && iLayer > 0 ) // Because features in layer 0 have no cats { OGRFieldDefn oField("cat", OFTInteger); poFeatureDefn->AddFieldDefn( &oField ); } if ( getenv("GISBASE") ) // We have some projection info in GISBASE { struct Key_Value *projinfo, *projunits; // Note: we dont have to reset GISDBASE and LOCATION_NAME because // OGRGRASSLayer constructor is called from OGRGRASSDataSource::Open // where those variables are set projinfo = G_get_projinfo(); projunits = G_get_projunits(); char *srsWkt = GPJ_grass_to_wkt ( projinfo, projunits, 0, 0); if ( srsWkt ) { poSRS = new OGRSpatialReference ( srsWkt ); CPLFree ( srsWkt ); } G_free_key_value(projinfo); G_free_key_value(projunits); } }
int main(int argc, char **argv) { int line; struct line_pnts *points; struct line_cats *Cats; struct Map_info map, Out; struct GModule *module; struct Option *input; struct Option *output; struct Option *cats; struct Option *type_opt; char *desc; int polyline; int *lines_visited; int points_in_polyline; int start_line; int nlines; int write_cats, copy_tables; int type, ltype; /* Initialize the GIS calls */ G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("topology")); G_add_keyword(_("geometry")); G_add_keyword(_("line")); G_add_keyword(_("node")); G_add_keyword(_("vertex")); module->description = _("Builds polylines from lines or boundaries."); /* Define the options */ input = G_define_standard_option(G_OPT_V_INPUT); output = G_define_standard_option(G_OPT_V_OUTPUT); cats = G_define_option(); cats->key = "cats"; cats->type = TYPE_STRING; cats->description = _("Category number mode"); cats->options = "no,first,multi,same"; desc = NULL; G_asprintf(&desc, "no;%s;first;%s;multi;%s;same;%s", _("Do not assign any category number to polyline"), _("Assign category number of first line to polyline"), _("Assign multiple category numbers to polyline"), _("Create polyline from lines with same categories")); cats->descriptions = desc; cats->answer = "no"; type_opt = G_define_standard_option(G_OPT_V_TYPE); type_opt->options = "line,boundary"; type_opt->answer = "line,boundary"; if (G_parser(argc, argv)) exit(EXIT_FAILURE); Vect_check_input_output_name(input->answer, output->answer, G_FATAL_EXIT); /* Open binary vector map at level 2 */ Vect_set_open_level(2); if (Vect_open_old(&map, input->answer, "") < 0) G_fatal_error(_("Unable to open vector map <%s>"), input->answer); /* Open new vector */ G_find_vector2(output->answer, ""); if (Vect_open_new(&Out, output->answer, Vect_is_3d(&map)) < 0) G_fatal_error(_("Unable to create vector map <%s>"), output->answer); /* Copy header info. */ Vect_copy_head_data(&map, &Out); /* History */ Vect_hist_copy(&map, &Out); Vect_hist_command(&Out); /* Get the number of lines in the binary map and set up record of lines visited */ lines_visited = (int *)G_calloc(Vect_get_num_lines(&map) + 1, sizeof(int)); /* Set up points structure and coordinate arrays */ points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); /* Write cats */ if (strcmp(cats->answer, "no") == 0) write_cats = NO_CATS; else if (strcmp(cats->answer, "first") == 0) write_cats = ONE_CAT; else write_cats = MULTI_CATS; if (type_opt->answer) type = Vect_option_to_types(type_opt); else type = GV_LINES; /* Step over all lines in binary map */ polyline = 0; nlines = 0; copy_tables = (write_cats != NO_CATS); for (line = 1; line <= Vect_get_num_lines(&map); line++) { Vect_reset_cats(Cats); ltype = Vect_read_line(&map, NULL, NULL, line); if ((ltype & GV_LINES) && (ltype & type)) nlines++; else { /* copy points to output as they are, with cats */ Vect_read_line(&map, points, Cats, line); Vect_write_line(&Out, ltype, points, Cats); if (Cats->n_cats > 0) copy_tables = 1; continue; } /* Skip line if already visited from another */ if (lines_visited[line]) continue; /* Only get here if line is not previously visited */ /* Find start of this polyline */ start_line = walk_back(&map, line, ltype); G_debug(1, "Polyline %d: start line = %d", polyline, start_line); /* Walk forward and pick up coordinates */ points_in_polyline = walk_forward_and_pick_up_coords(&map, start_line, ltype, points, lines_visited, Cats, write_cats); /* Write the line (type of the first line is used) */ Vect_write_line(&Out, ltype, points, Cats); polyline++; } G_verbose_message(n_("%d line or boundaries found in input vector map", "%d lines or boundaries found in input vector map", nlines), nlines, Vect_get_name(&map), Vect_get_mapset(&map)); G_verbose_message(n_("%d polyline stored in output vector map", "%d polylines stored in output vector map", polyline), polyline, Vect_get_name(&Out), Vect_get_mapset(&Out)); /* Copy (all linked) tables if needed */ if (copy_tables) { if (Vect_copy_tables(&map, &Out, 0)) G_warning(_("Failed to copy attribute table to output map")); } /* Tidy up */ Vect_destroy_line_struct(points); Vect_destroy_cats_struct(Cats); G_free(lines_visited); Vect_close(&map); Vect_build(&Out); Vect_close(&Out); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct Map_info In, Out; static struct line_pnts *Points; struct line_cats *Cats; struct field_info *Fi; struct cat_list *Clist; int i, j, ret, option, otype, type, with_z, step, id; int n_areas, centr, new_centr, nmodified; int open_level; double x, y; int cat, ocat, scat, *fields, nfields, field; struct GModule *module; struct Option *in_opt, *out_opt, *option_opt, *type_opt; struct Option *cat_opt, *field_opt, *step_opt, *id_opt; struct Flag *shell, *notab; FREPORT **freps; int nfreps, rtype, fld; char *desc; module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("category")); G_add_keyword(_("layer")); module->description = _("Attaches, deletes or reports vector categories to map geometry."); in_opt = G_define_standard_option(G_OPT_V_INPUT); field_opt = G_define_standard_option(G_OPT_V_FIELD); field_opt->multiple = YES; field_opt->guisection = _("Selection"); type_opt = G_define_standard_option(G_OPT_V3_TYPE); type_opt->answer = "point,line,centroid,face"; type_opt->guisection = _("Selection"); id_opt = G_define_standard_option(G_OPT_V_IDS); id_opt->label = _("Feature ids (by default all features are processed)"); id_opt->guisection = _("Selection"); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); out_opt->required = NO; option_opt = G_define_option(); option_opt->key = "option"; option_opt->type = TYPE_STRING; option_opt->required = YES; option_opt->multiple = NO; option_opt->options = "add,del,chlayer,sum,report,print,layers,transfer"; option_opt->description = _("Action to be done"); desc = NULL; G_asprintf(&desc, "add;%s;" "del;%s;" "chlayer;%s;" "sum;%s;" "transfer;%s;" "report;%s;" "print;%s;" "layers;%s", _("add a category to features without category in the given layer"), _("delete category (cat=-1 to delete all categories of given layer)"), _("change layer number (e.g. layer=3,1 changes layer 3 to layer 1)"), _("add the value specified by cat option to the current category value"), _("copy values from one layer to another (e.g. layer=1,2,3 copies values from layer 1 to layer 2 and 3)"), _("print report (statistics), in shell style: layer type count min max"), _("print category values, layers are separated by '|', more cats in the same layer are separated by '/'"), _("print only layer numbers")); option_opt->descriptions = desc; cat_opt = G_define_standard_option(G_OPT_V_CAT); cat_opt->answer = "1"; step_opt = G_define_option(); step_opt->key = "step"; step_opt->type = TYPE_INTEGER; step_opt->required = NO; step_opt->multiple = NO; step_opt->answer = "1"; step_opt->description = _("Category increment"); shell = G_define_flag(); shell->key = 'g'; shell->label = _("Shell script style, currently only for report"); shell->description = _("Format: layer type count min max"); notab = G_define_standard_flag(G_FLG_V_TABLE); notab->description = _("Do not copy attribute table(s)"); G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* read options */ option = 0; switch (option_opt->answer[0]) { case ('a'): option = O_ADD; break; case ('d'): option = O_DEL; break; case ('c'): option = O_CHFIELD; G_warning(_("Database connection and attribute tables for concerned layers are not changed")); break; case ('s'): option = O_SUM; break; case ('t'): option = O_TRANS; break; case ('r'): option = O_REP; break; case ('p'): option = O_PRN; break; case ('l'): option = O_LYR; break; } if (option == O_LYR) { /* print vector layer numbers */ /* open vector on level 2 head only, this is why this option * is processed here, all other options need (?) to fully open * the input vector */ Vect_set_open_level(2); if (Vect_open_old_head2(&In, in_opt->answer, "", field_opt->answer) < 2) { G_fatal_error(_("Unable to open vector map <%s> at topological level %d"), Vect_get_full_name(&In), 2); } if (In.format == GV_FORMAT_NATIVE) { nfields = Vect_cidx_get_num_fields(&In); for (i = 0; i < nfields; i++) { if ((field = Vect_cidx_get_field_number(&In, i)) > 0) fprintf(stdout, "%d\n", field); } } else fprintf(stdout, "%s\n", field_opt->answer); Vect_close(&In); exit(EXIT_SUCCESS); } cat = atoi(cat_opt->answer); step = atoi(step_opt->answer); otype = Vect_option_to_types(type_opt); if (cat < 0 && option == O_ADD) G_fatal_error(_("Invalid category number (must be equal to or greater than 0). " "Normally category number starts at 1.")); /* collect ids */ if (id_opt->answer) { Clist = Vect_new_cat_list(); Clist->field = atoi(field_opt->answer); ret = Vect_str_to_cat_list(id_opt->answer, Clist); if (ret > 0) { G_warning(n_("%d error in id option", "%d errors in id option", ret), ret); } } else { Clist = NULL; } if ((option != O_REP) && (option != O_PRN) && (option != O_LYR)) { if (out_opt->answer == NULL) G_fatal_error(_("Output vector wasn't entered")); Vect_check_input_output_name(in_opt->answer, out_opt->answer, G_FATAL_EXIT); } Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); /* do we need topology ? */ if ((option == O_ADD && (otype & GV_AREA)) || (option == O_REP && (otype & GV_AREA)) || (option == O_TRANS) || /* topo for cidx check */ (option == O_LYR)) /* topo for cidx check */ open_level = 2; else open_level = 1; /* open input vector */ if (open_level > 1) { Vect_set_open_level(open_level); if (Vect_open_old2(&In, in_opt->answer, "", field_opt->answer) < open_level) { G_warning(_("Unable to open vector map <%s> at topological level %d"), Vect_get_full_name(&In), open_level); open_level = 1; } } if (open_level == 1) { Vect_set_open_level(open_level); if (Vect_open_old2(&In, in_opt->answer, "", field_opt->answer) < open_level) { G_fatal_error(_("Unable to open vector map <%s> at topological level %d"), Vect_get_full_name(&In), open_level); } } /* read fields */ i = nfields = 0; while (field_opt->answers[i++]) nfields++; fields = (int *)G_malloc(nfields * sizeof(int)); i = 0; while (field_opt->answers[i]) { fields[i] = Vect_get_field_number(&In, field_opt->answers[i]); i++; } if (nfields > 1 && option != O_PRN && option != O_CHFIELD && option != O_TRANS) G_fatal_error(_("Too many layers for this operation")); if (nfields != 2 && option == O_CHFIELD) G_fatal_error(_("2 layers must be specified")); if (option == O_TRANS && open_level == 1 && nfields < 2) { G_fatal_error(_("2 layers must be specified")); } if (option == O_TRANS && open_level > 1) { /* check if field[>0] already exists */ if (nfields > 1) { for(i = 1; i < nfields; i++) { if (Vect_cidx_get_field_index(&In, fields[i]) != -1) G_warning(_("Categories already exist in layer %d"), fields[i]); } } /* find next free layer number */ else if (nfields == 1) { int max = -1; for (i = 0; i < Vect_cidx_get_num_fields(&In); i++) { if (max < Vect_cidx_get_field_number(&In, i)) max = Vect_cidx_get_field_number(&In, i); } max++; nfields++; fields = (int *)G_realloc(fields, nfields * sizeof(int)); fields[nfields - 1] = max; } } if (otype & GV_AREA && option == O_TRANS && !(otype & GV_CENTROID)) otype |= GV_CENTROID; /* open output vector if needed */ if (option == O_ADD || option == O_DEL || option == O_CHFIELD || option == O_SUM || option == O_TRANS) { with_z = Vect_is_3d(&In); if (0 > Vect_open_new(&Out, out_opt->answer, with_z)) { Vect_close(&In); exit(EXIT_FAILURE); } Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); } id = 0; nmodified = 0; if (option == O_ADD || option == O_DEL || option == O_CHFIELD || option == O_SUM || option == O_TRANS) { G_message(_("Processing features...")); } switch (option) { case (O_ADD): /* Lines */ while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) { id++; if (type & otype && (!Clist || (Clist && Vect_cat_in_cat_list(id, Clist) == TRUE))) { if ((Vect_cat_get(Cats, fields[0], &ocat)) == 0) { if (ocat < 0) { if (Vect_cat_set(Cats, fields[0], cat) > 0) { nmodified++; } cat += step; } } } Vect_write_line(&Out, type, Points, Cats); } /* Areas */ if ((otype & GV_AREA) && open_level > 1) { n_areas = Vect_get_num_areas(&In); new_centr = 0; for (i = 1; i <= n_areas; i++) { centr = Vect_get_area_centroid(&In, i); if (centr > 0) continue; /* Centroid exists and may be processed as line */ ret = Vect_get_point_in_area(&In, i, &x, &y); if (ret < 0) { G_warning(_("Unable to calculate area centroid")); continue; } Vect_reset_line(Points); Vect_reset_cats(Cats); Vect_append_point(Points, x, y, 0.0); if (Vect_cat_set(Cats, fields[0], cat) > 0) { nmodified++; } cat += step; Vect_write_line(&Out, GV_CENTROID, Points, Cats); new_centr++; } if (new_centr > 0) G_message(n_("%d new centroid placed in output map", "%d new centroids placed in output map", new_centr), new_centr); } break; case (O_TRANS): /* Lines */ while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) { id++; if (type & otype && (!Clist || (Clist && Vect_cat_in_cat_list(id, Clist) == TRUE))) { int n = Cats->n_cats; scat = -1; for (i = 0; i < n; i++) { if (Cats->field[i] == fields[0]) { scat = Cats->cat[i]; for (j = 1; j < nfields; j++) { if (Vect_cat_set(Cats, fields[j], scat) > 0) { G_debug(4, "Copy cat %i of field %i to field %i", scat, fields[0], fields[j]); } } } } if (scat != -1) nmodified++; } Vect_write_line(&Out, type, Points, Cats); } break; case (O_DEL): while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) { id++; if (type & otype && (!Clist || (Clist && Vect_cat_in_cat_list(id, Clist) == TRUE))) { ret = Vect_field_cat_del(Cats, fields[0], cat); if (ret > 0) { nmodified++; } } Vect_write_line(&Out, type, Points, Cats); } break; case (O_CHFIELD): while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) { id++; if (type & otype && (!Clist || (Clist && Vect_cat_in_cat_list(id, Clist) == TRUE))) { i = 0; while (i < Cats->n_cats) { if (Cats->field[i] == fields[0]) { int found = -1; /* check if cat already exists in layer fields[1] */ for (j = 0; j < Cats->n_cats; j++) { if (Cats->field[j] == fields[1] && Cats->cat[j] == Cats->cat[i]) { found = j; break; } } /* does not exist, change layer */ if (found < 0) { Cats->field[i] = fields[1]; i++; } /* exists already in fields[1], delete from fields[0] */ else Vect_field_cat_del(Cats, fields[0], Cats->cat[found]); nmodified++; } } } Vect_write_line(&Out, type, Points, Cats); } break; case (O_SUM): while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) { id++; if (type & otype && (!Clist || (Clist && Vect_cat_in_cat_list(id, Clist) == TRUE))) { for (i = 0; i < Cats->n_cats; i++) { if (Cats->field[i] == fields[0]) { Cats->cat[i] += cat; } } nmodified++; } Vect_write_line(&Out, type, Points, Cats); } break; case (O_REP): nfreps = 0; freps = NULL; while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) { id++; if (Clist && Vect_cat_in_cat_list(id, Clist) == FALSE) continue; switch (type) { case (GV_POINT): rtype = FR_POINT; break; case (GV_LINE): rtype = FR_LINE; break; case (GV_BOUNDARY): rtype = FR_BOUNDARY; break; case (GV_CENTROID): rtype = FR_CENTROID; break; case (GV_FACE): rtype = FR_FACE; break; case (GV_KERNEL): rtype = FR_KERNEL; break; default: rtype = FR_UNKNOWN; } for (i = 0; i < Cats->n_cats; i++) { field = Cats->field[i]; cat = Cats->cat[i]; ret = FALSE; for (j = 0; j < nfreps; j++) { if (freps[j]->field == field) { fld = j; ret = TRUE; break; } } if (!ret) { /* field report doesn't exist */ nfreps++; freps = (FREPORT **) G_realloc(freps, nfreps * sizeof(FREPORT *)); fld = nfreps - 1; freps[fld] = (FREPORT *) G_calloc(1, sizeof(FREPORT)); freps[fld]->field = field; for (j = 0; j < FRTYPES; j++) { /* cat '0' is valid category number */ freps[fld]->min[j] = -1; } if ((Fi = Vect_get_field(&In, field)) != NULL) { freps[fld]->table = G_store(Fi->table); } else { freps[fld]->table = '\0'; } } freps[fld]->count[rtype]++; freps[fld]->count[FR_ALL]++; if (freps[fld]->min[rtype] == -1 || freps[fld]->min[rtype] > cat) freps[fld]->min[rtype] = cat; if ((freps[fld]->max[rtype] == 0) || freps[fld]->max[rtype] < cat) freps[fld]->max[rtype] = cat; if (freps[fld]->min[FR_ALL] == -1 || freps[fld]->min[FR_ALL] > cat) freps[fld]->min[FR_ALL] = cat; if ((freps[fld]->max[FR_ALL] == 0) || freps[fld]->max[FR_ALL] < cat) freps[fld]->max[FR_ALL] = cat; } } /* Areas */ if ((otype & GV_AREA) && open_level > 1 && !Clist) { n_areas = Vect_get_num_areas(&In); for (i = 1; i <= n_areas; i++) { int k; centr = Vect_get_area_centroid(&In, i); if (centr <= 0) continue; /* Area without centroid */ Vect_read_line(&In, NULL, Cats, centr); for (j = 0; j < Cats->n_cats; j++) { field = Cats->field[j]; cat = Cats->cat[j]; ret = FALSE; for (k = 0; k < nfreps; k++) { if (freps[k]->field == field) { fld = k; ret = TRUE; break; } } if (!ret) { /* field report doesn't exist */ nfreps++; freps = (FREPORT **) G_realloc(freps, nfreps * sizeof(FREPORT *)); fld = nfreps - 1; freps[fld] = (FREPORT *) G_calloc(1, sizeof(FREPORT)); freps[fld]->field = field; for (j = 0; j < FRTYPES; j++) { /* cat '0' is valid category number */ freps[fld]->min[k] = -1; } if ((Fi = Vect_get_field(&In, field)) != NULL) { freps[fld]->table = G_store(Fi->table); } else { freps[fld]->table = '\0'; } } freps[fld]->count[FR_AREA]++; if (freps[fld]->min[FR_AREA] == -1 || freps[fld]->min[FR_AREA] > cat) freps[fld]->min[FR_AREA] = cat; if ((freps[fld]->max[FR_AREA] == 0) || freps[fld]->max[FR_AREA] < cat) freps[fld]->max[FR_AREA] = cat; } } } for (i = 0; i < nfreps; i++) { if (shell->answer) { if (freps[i]->count[FR_POINT] > 0) fprintf(stdout, "%d point %d %d %d\n", freps[i]->field, freps[i]->count[FR_POINT], (freps[i]->min[FR_POINT] < 0 ? 0 : freps[i]->min[FR_POINT]), freps[i]->max[FR_POINT]); if (freps[i]->count[FR_LINE] > 0) fprintf(stdout, "%d line %d %d %d\n", freps[i]->field, freps[i]->count[FR_LINE], (freps[i]->min[FR_LINE] < 0 ? 0 : freps[i]->min[FR_LINE]), freps[i]->max[FR_LINE]); if (freps[i]->count[FR_BOUNDARY] > 0) fprintf(stdout, "%d boundary %d %d %d\n", freps[i]->field, freps[i]->count[FR_BOUNDARY], (freps[i]->min[FR_BOUNDARY] < 0 ? 0 : freps[i]->min[FR_BOUNDARY]), freps[i]->max[FR_BOUNDARY]); if (freps[i]->count[FR_CENTROID] > 0) fprintf(stdout, "%d centroid %d %d %d\n", freps[i]->field, freps[i]->count[FR_CENTROID], (freps[i]->min[FR_BOUNDARY] < 0 ? 0 : freps[i]->min[FR_BOUNDARY]), freps[i]->max[FR_CENTROID]); if (freps[i]->count[FR_AREA] > 0) fprintf(stdout, "%d area %d %d %d\n", freps[i]->field, freps[i]->count[FR_AREA], (freps[i]->min[FR_AREA] < 0 ? 0 : freps[i]->min[FR_AREA]), freps[i]->max[FR_AREA]); if (freps[i]->count[FR_FACE] > 0) fprintf(stdout, "%d face %d %d %d\n", freps[i]->field, freps[i]->count[FR_FACE], (freps[i]->min[FR_FACE] < 0 ? 0 : freps[i]->min[FR_FACE]), freps[i]->max[FR_FACE]); if (freps[i]->count[FR_KERNEL] > 0) fprintf(stdout, "%d kernel %d %d %d\n", freps[i]->field, freps[i]->count[FR_KERNEL], (freps[i]->min[FR_KERNEL] < 0 ? 0 : freps[i]->min[FR_KERNEL]), freps[i]->max[FR_KERNEL]); if (freps[i]->count[FR_ALL] > 0) fprintf(stdout, "%d all %d %d %d\n", freps[i]->field, freps[i]->count[FR_ALL], (freps[i]->min[FR_ALL] < 0 ? 0 : freps[i]->min[FR_ALL]), freps[i]->max[FR_ALL]); } else { if (freps[i]->table != '\0') { fprintf(stdout, "%s: %d/%s\n", _("Layer/table"), freps[i]->field, freps[i]->table); } else { fprintf(stdout, "%s: %d\n", _("Layer"), freps[i]->field); } fprintf(stdout, _("type count min max\n")); fprintf(stdout, "%s %7d %10d %10d\n", _("point"), freps[i]->count[FR_POINT], (freps[i]->min[FR_POINT] < 0) ? 0 : freps[i]->min[FR_POINT], freps[i]->max[FR_POINT]); fprintf(stdout, "%s %7d %10d %10d\n", _("line"), freps[i]->count[FR_LINE], (freps[i]->min[FR_LINE] < 0) ? 0 : freps[i]->min[FR_LINE], freps[i]->max[FR_LINE]); fprintf(stdout, "%s %7d %10d %10d\n", _("boundary"), freps[i]->count[FR_BOUNDARY], (freps[i]->min[FR_BOUNDARY] < 0) ? 0 : freps[i]->min[FR_BOUNDARY], freps[i]->max[FR_BOUNDARY]); fprintf(stdout, "%s %7d %10d %10d\n", _("centroid"), freps[i]->count[FR_CENTROID], (freps[i]->min[FR_CENTROID] < 0) ? 0 : freps[i]->min[FR_CENTROID], freps[i]->max[FR_CENTROID]); fprintf(stdout, "%s %7d %10d %10d\n", _("area"), freps[i]->count[FR_AREA], (freps[i]->min[FR_AREA] < 0) ? 0 : freps[i]->min[FR_AREA], freps[i]->max[FR_AREA]); fprintf(stdout, "%s %7d %10d %10d\n", _("face"), freps[i]->count[FR_FACE], (freps[i]->min[FR_FACE] < 0) ? 0 : freps[i]->min[FR_FACE], freps[i]->max[FR_FACE]); fprintf(stdout, "%s %7d %10d %10d\n", _("kernel"), freps[i]->count[FR_KERNEL], (freps[i]->min[FR_KERNEL] < 0) ? 0 : freps[i]->min[FR_KERNEL], freps[i]->max[FR_KERNEL]); fprintf(stdout, "%s %7d %10d %10d\n", _("all"), freps[i]->count[FR_ALL], (freps[i]->min[FR_ALL] < 0) ? 0 : freps[i]->min[FR_ALL], freps[i]->max[FR_ALL]); } } break; case (O_PRN): while ((type = Vect_read_next_line(&In, Points, Cats)) > 0) { id++; int has = 0; if (!(type & otype)) continue; if (Clist && Vect_cat_in_cat_list(id, Clist) == FALSE) continue; /* Check if the line has at least one cat */ for (i = 0; i < nfields; i++) { for (j = 0; j < Cats->n_cats; j++) { if (Cats->field[j] == fields[i]) { has = 1; break; } } } if (!has) continue; for (i = 0; i < nfields; i++) { int first = 1; if (i > 0) fprintf(stdout, "|"); for (j = 0; j < Cats->n_cats; j++) { if (Cats->field[j] == fields[i]) { if (!first) fprintf(stdout, "/"); fprintf(stdout, "%d", Cats->cat[j]); first = 0; } } } fprintf(stdout, "\n"); } break; } if (option == O_ADD || option == O_DEL || option == O_CHFIELD || option == O_SUM || option == O_TRANS){ if (!notab->answer){ G_message(_("Copying attribute table(s)...")); if (Vect_copy_tables(&In, &Out, 0)) G_warning(_("Failed to copy attribute table to output map")); } Vect_build(&Out); Vect_close(&Out); } if (option == O_TRANS && nmodified > 0) for(i = 1; i < nfields; i++) G_important_message(_("Categories copied from layer %d to layer %d"), fields[0], fields[i]); if (option != O_REP && option != O_PRN) G_done_msg(n_("%d feature modified.", "%d features modified.", nmodified), nmodified); Vect_close(&In); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct Map_info In, Out; static struct line_pnts *Points; struct line_cats *Cats; struct GModule *module; /* GRASS module for parsing arguments */ struct Option *map_in, *map_out; struct Option *afield_opt, *nfield_opt, *afcol, *ncol; struct Flag *geo_f; int with_z; int afield, nfield, mask_type; dglGraph_s *graph; int i, edges, geo; struct ilist *tree_list; /* initialize GIS environment */ G_gisinit(argv[0]); /* reads grass env, stores program name to G_program_name() */ /* initialize module */ module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("network")); G_add_keyword(_("spanning tree")); module->description = _("Computes minimum spanning tree for the network."); /* Define the different options as defined in gis.h */ map_in = G_define_standard_option(G_OPT_V_INPUT); map_out = G_define_standard_option(G_OPT_V_OUTPUT); afield_opt = G_define_standard_option(G_OPT_V_FIELD); afield_opt->key = "alayer"; afield_opt->answer = "1"; afield_opt->label = _("Arc layer"); afield_opt->guisection = _("Cost"); nfield_opt = G_define_standard_option(G_OPT_V_FIELD); nfield_opt->key = "nlayer"; nfield_opt->answer = "2"; nfield_opt->label = _("Node layer"); nfield_opt->guisection = _("Cost"); afcol = G_define_standard_option(G_OPT_DB_COLUMN); afcol->key = "afcolumn"; afcol->required = NO; afcol->description = _("Arc forward/both direction(s) cost column (number)"); afcol->guisection = _("Cost"); ncol = G_define_standard_option(G_OPT_DB_COLUMN); ncol->key = "ncolumn"; ncol->required = NO; ncol->description = _("Node cost column (number)"); ncol->guisection = _("Cost"); geo_f = G_define_flag(); geo_f->key = 'g'; geo_f->description = _("Use geodesic calculation for longitude-latitude locations"); /* options and flags parser */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* TODO: make an option for this */ mask_type = GV_LINE | GV_BOUNDARY; Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); Vect_check_input_output_name(map_in->answer, map_out->answer, G_FATAL_EXIT); Vect_set_open_level(2); if (1 > Vect_open_old(&In, map_in->answer, "")) G_fatal_error(_("Unable to open vector map <%s>"), map_in->answer); with_z = Vect_is_3d(&In); if (0 > Vect_open_new(&Out, map_out->answer, with_z)) { Vect_close(&In); G_fatal_error(_("Unable to create vector map <%s>"), map_out->answer); } if (geo_f->answer) { geo = 1; if (G_projection() != PROJECTION_LL) G_warning(_("The current projection is not longitude-latitude")); } else geo = 0; /* parse filter option and select appropriate lines */ afield = Vect_get_field_number(&In, afield_opt->answer); nfield = Vect_get_field_number(&In, nfield_opt->answer); if (0 != Vect_net_build_graph(&In, mask_type, afield, nfield, afcol->answer, NULL, ncol->answer, geo, 0)) G_fatal_error(_("Unable to build graph for vector map <%s>"), Vect_get_full_name(&In)); graph = Vect_net_get_graph(&In); Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); tree_list = Vect_new_list(); edges = NetA_spanning_tree(graph, tree_list); G_debug(3, "Edges: %d", edges); for (i = 0; i < edges; i++) { int type = Vect_read_line(&In, Points, Cats, abs(tree_list->value[i])); Vect_write_line(&Out, type, Points, Cats); } Vect_destroy_list(tree_list); Vect_build(&Out); Vect_close(&In); Vect_close(&Out); exit(EXIT_SUCCESS); }
int display_shape(struct Map_info *Map, int type, struct cat_list *Clist, const struct Cell_head *window, const struct color_rgb *bcolor, const struct color_rgb *fcolor, int chcat, const char *icon, double size, const char *size_column, int sqrt_flag, const char *rot_column, /* lines only */ int id_flag, int cats_colors_flag, char *rgb_column, int default_width, char *width_column, double width_scale, char *z_style) { int open_db, field, i, stat; dbCatValArray cvarr_rgb, cvarr_width, cvarr_size, cvarr_rot; struct field_info *fi; dbDriver *driver; int nrec_rgb, nrec_width, nrec_size, nrec_rot, have_colors; struct Colors colors, zcolors; struct bound_box box; stat = 0; nrec_rgb = nrec_width = nrec_size = nrec_rot = 0; open_db = rgb_column || width_column || size_column || rot_column; if (open_db) { field = Clist->field > 0 ? Clist->field : 1; fi = Vect_get_field(Map, field); if (!fi) { G_fatal_error(_("Database connection not defined for layer %d"), field); } driver = db_start_driver_open_database(fi->driver, fi->database); if (!driver) G_fatal_error(_("Unable to open database <%s> by driver <%s>"), fi->database, fi->driver); db_set_error_handler_driver(driver); } /* fisrt search for color table */ have_colors = Vect_read_colors(Vect_get_name(Map), Vect_get_mapset(Map), &colors); if (have_colors && rgb_column) { G_warning(_("Both color table and <%s> option detected. " "Color table will ignored."), "rgb_column"); have_colors = FALSE; } if (rgb_column) { /* read RRR:GGG:BBB color strings from table */ db_CatValArray_init(&cvarr_rgb); nrec_rgb = db_select_CatValArray(driver, fi->table, fi->key, rgb_column, NULL, &cvarr_rgb); G_debug(3, "nrec_rgb (%s) = %d", rgb_column, nrec_rgb); if (cvarr_rgb.ctype != DB_C_TYPE_STRING) { G_warning(_("Color definition column ('%s') not a string. " "Column must be of form 'RRR:GGG:BBB' where RGB values range 0-255. " "You can use '%s' module to define color rules. " "Unable to colorize features."), rgb_column, "v.colors"); rgb_column = NULL; } else { if (nrec_rgb < 0) G_fatal_error(_("Unable to select data ('%s') from table"), rgb_column); G_debug(2, "\n%d records selected from table", nrec_rgb); } } if (width_column) { if (*width_column == '\0') G_fatal_error(_("Line width column not specified")); db_CatValArray_init(&cvarr_width); nrec_width = db_select_CatValArray(driver, fi->table, fi->key, width_column, NULL, &cvarr_width); G_debug(3, "nrec_width (%s) = %d", width_column, nrec_width); if (cvarr_width.ctype != DB_C_TYPE_INT && cvarr_width.ctype != DB_C_TYPE_DOUBLE) G_fatal_error(_("Line width column ('%s') not a number"), width_column); if (nrec_width < 0) G_fatal_error(_("Unable to select data ('%s') from table"), width_column); G_debug(2, "\n%d records selected from table", nrec_width); for (i = 0; i < cvarr_width.n_values; i++) { G_debug(4, "cat = %d %s = %d", cvarr_width.value[i].cat, width_column, (cvarr_width.ctype == DB_C_TYPE_INT ? cvarr_width.value[i].val. i : (int)cvarr_width.value[i].val.d)); } } if (size_column) { if (*size_column == '\0') G_fatal_error(_("Symbol size column not specified")); db_CatValArray_init(&cvarr_size); nrec_size = db_select_CatValArray(driver, fi->table, fi->key, size_column, NULL, &cvarr_size); G_debug(3, "nrec_size (%s) = %d", size_column, nrec_size); if (cvarr_size.ctype != DB_C_TYPE_INT && cvarr_size.ctype != DB_C_TYPE_DOUBLE) G_fatal_error(_("Symbol size column ('%s') is not numeric"), size_column); if (nrec_size < 0) G_fatal_error(_("Unable to select data ('%s') from table"), size_column); G_debug(2, " %d records selected from table", nrec_size); for (i = 0; i < cvarr_size.n_values; i++) { G_debug(4, "(size) cat = %d %s = %.2f", cvarr_size.value[i].cat, size_column, (cvarr_size.ctype == DB_C_TYPE_INT ? (double)cvarr_size.value[i].val.i : cvarr_size.value[i].val.d)); } } if (rot_column) { if (*rot_column == '\0') G_fatal_error(_("Symbol rotation column not specified")); db_CatValArray_init(&cvarr_rot); nrec_rot = db_select_CatValArray(driver, fi->table, fi->key, rot_column, NULL, &cvarr_rot); G_debug(3, "nrec_rot (%s) = %d", rot_column, nrec_rot); if (cvarr_rot.ctype != DB_C_TYPE_INT && cvarr_rot.ctype != DB_C_TYPE_DOUBLE) G_fatal_error(_("Symbol rotation column ('%s') is not numeric"), rot_column); if (nrec_rot < 0) G_fatal_error(_("Unable to select data ('%s') from table"), rot_column); G_debug(2, " %d records selected from table", nrec_rot); for (i = 0; i < cvarr_rot.n_values; i++) { G_debug(4, "(rot) cat = %d %s = %.2f", cvarr_rot.value[i].cat, rot_column, (cvarr_rot.ctype == DB_C_TYPE_INT ? (double)cvarr_rot.value[i].val.i : cvarr_rot.value[i].val.d)); } } if (open_db) { db_close_database_shutdown_driver(driver); } if (z_style) { if (!Vect_is_3d(Map)) { G_warning(_("Vector map is not 3D. Unable to colorize features based on z-coordinates.")); z_style = NULL; } else if (rgb_column) { G_warning(_("%s= and %s= are mutually exclusive. " "%s= will be ignored."), "zcolor", "rgb_column", "zcolor"); z_style = NULL; } else { Vect_get_map_box(Map, &box); Rast_make_fp_colors(&zcolors, z_style, box.B, box.T); } } stat = 0; if (type & GV_AREA && Vect_get_num_primitives(Map, GV_CENTROID | GV_BOUNDARY) > 0) stat += display_area(Map, Clist, window, bcolor, fcolor, chcat, id_flag, cats_colors_flag, default_width, width_scale, z_style ? &zcolors : NULL, rgb_column ? &cvarr_rgb : NULL, have_colors ? &colors : NULL, &cvarr_width, nrec_width); stat += display_lines(Map, type, Clist, bcolor, fcolor, chcat, icon, size, sqrt_flag, id_flag, cats_colors_flag, default_width, width_scale, z_style ? &zcolors : NULL, rgb_column ? &cvarr_rgb : NULL, have_colors ? &colors : NULL, &cvarr_width, nrec_width, &cvarr_size, nrec_size, &cvarr_rot, nrec_rot); return stat; }
int main(int argc, char *argv[]) { struct file_info Current, Trans, Coord; struct GModule *module; struct Option *vold, *vnew, *pointsfile, *xshift, *yshift, *zshift, *xscale, *yscale, *zscale, *zrot, *columns, *table, *field; struct Flag *quiet_flag, *tozero_flag, *shift_flag, *print_mat_flag; char *mapset, mon[4], date[40], buf[1000]; struct Map_info Old, New; int ifield; int day, yr; BOUND_BOX box; double ztozero; double trans_params[7]; /* xshift, ..., xscale, ..., zrot */ /* columns */ unsigned int i; int idx, out3d; char **tokens; char *columns_name[7]; /* xshift, yshift, zshift, xscale, yscale, zscale, zrot */ G_gisinit(argv[0]); module = G_define_module(); module->keywords = _("vector, transformation"); module->description = _("Performs an affine transformation (shift, scale and rotate, " "or GPCs) on vector map."); /* remove in GRASS7 */ quiet_flag = G_define_flag(); quiet_flag->key = 'q'; quiet_flag->description = _("Suppress display of residuals or other information"); tozero_flag = G_define_flag(); tozero_flag->key = 't'; tozero_flag->description = _("Shift all z values to bottom=0"); tozero_flag->guisection = _("Custom"); print_mat_flag = G_define_flag(); print_mat_flag->key = 'm'; print_mat_flag->description = _("Print the transformation matrix to stdout"); shift_flag = G_define_flag(); shift_flag->key = 's'; shift_flag->description = _("Instead of points use transformation parameters " "(xshift, yshift, zshift, xscale, yscale, zscale, zrot)"); shift_flag->guisection = _("Custom"); vold = G_define_standard_option(G_OPT_V_INPUT); field = G_define_standard_option(G_OPT_V_FIELD); field->answer = "-1"; vnew = G_define_standard_option(G_OPT_V_OUTPUT); pointsfile = G_define_standard_option(G_OPT_F_INPUT); pointsfile->key = "pointsfile"; pointsfile->required = NO; pointsfile->label = _("ASCII file holding transform coordinates"); pointsfile->description = _("If not given, transformation parameters " "(xshift, yshift, zshift, xscale, yscale, zscale, zrot) are used instead"); pointsfile->gisprompt = "old_file,file,points"; pointsfile->guisection = _("Points"); xshift = G_define_option(); xshift->key = "xshift"; xshift->type = TYPE_DOUBLE; xshift->required = NO; xshift->multiple = NO; xshift->description = _("Shifting value for x coordinates"); xshift->answer = "0.0"; xshift->guisection = _("Custom"); yshift = G_define_option(); yshift->key = "yshift"; yshift->type = TYPE_DOUBLE; yshift->required = NO; yshift->multiple = NO; yshift->description = _("Shifting value for y coordinates"); yshift->answer = "0.0"; yshift->guisection = _("Custom"); zshift = G_define_option(); zshift->key = "zshift"; zshift->type = TYPE_DOUBLE; zshift->required = NO; zshift->multiple = NO; zshift->description = _("Shifting value for z coordinates"); zshift->answer = "0.0"; zshift->guisection = _("Custom"); xscale = G_define_option(); xscale->key = "xscale"; xscale->type = TYPE_DOUBLE; xscale->required = NO; xscale->multiple = NO; xscale->description = _("Scaling factor for x coordinates"); xscale->answer = "1.0"; xscale->guisection = _("Custom"); yscale = G_define_option(); yscale->key = "yscale"; yscale->type = TYPE_DOUBLE; yscale->required = NO; yscale->multiple = NO; yscale->description = _("Scaling factor for y coordinates"); yscale->answer = "1.0"; yscale->guisection = _("Custom"); zscale = G_define_option(); zscale->key = "zscale"; zscale->type = TYPE_DOUBLE; zscale->required = NO; zscale->multiple = NO; zscale->description = _("Scaling factor for z coordinates"); zscale->answer = "1.0"; zscale->guisection = _("Custom"); zrot = G_define_option(); zrot->key = "zrot"; zrot->type = TYPE_DOUBLE; zrot->required = NO; zrot->multiple = NO; zrot->description = _("Rotation around z axis in degrees counterclockwise"); zrot->answer = "0.0"; zrot->guisection = _("Custom"); table = G_define_standard_option(G_OPT_TABLE); table->description = _("Name of table containing transformation parameters"); table->guisection = _("Attributes"); columns = G_define_option(); columns->key = "columns"; columns->type = TYPE_STRING; columns->required = NO; columns->multiple = NO; columns->label = _("Name of attribute column(s) used as transformation parameters"); columns->description = _("Format: parameter:column, e.g. xshift:xs,yshift:ys,zrot:zr"); columns->guisection = _("Attributes"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); G_strcpy(Current.name, vold->answer); G_strcpy(Trans.name, vnew->answer); Vect_check_input_output_name(vold->answer, vnew->answer, GV_FATAL_EXIT); out3d = WITHOUT_Z; ifield = atoi(field->answer); if (shift_flag->answer) G_warning(_("The '%c' flag is deprecated and will be removed in future. " "Transformation parameters are used automatically when no pointsfile is given."), shift_flag->key); /* please remove in GRASS7 */ if (quiet_flag->answer) { G_warning(_("The '%c' flag is deprecated and will be removed in future. " "Please use '--quiet' instead."), quiet_flag->key); G_putenv("GRASS_VERBOSE", "0"); } /* if a table is specified, require columns and layer */ /* if columns are specified, but no table, require layer > 0 and use * the table attached to that layer */ if (table->answer && !columns->answer) { G_fatal_error(_("Column names are not defined. Please use '%s' parameter."), columns->key); } if ((columns->answer || table->answer) && ifield < 1) { G_fatal_error(_("Please specify a valid layer with '%s' parameter."), field->key); } if (table->answer && strcmp(vnew->answer, table->answer) == 0) { G_fatal_error(_("Name of table and name for output vector map must be different. " "Otherwise the table is overwritten.")); } if (!columns->answer && !table->answer) ifield = -1; if (pointsfile->answer != NULL && !shift_flag->answer) { G_strcpy(Coord.name, pointsfile->answer); } else { Coord.name[0] = '\0'; } /* open coord file */ if (Coord.name[0] != '\0') { if ((Coord.fp = fopen(Coord.name, "r")) == NULL) G_fatal_error(_("Unable to open file with coordinates <%s>"), Coord.name); } /* tokenize columns names */ for (i = 0; i <= IDX_ZROT; i++) { columns_name[i] = NULL; } i = 0; if (columns->answer) { while (columns->answers[i]) { tokens = G_tokenize(columns->answers[i], ":"); if (G_number_of_tokens(tokens) == 2) { if (strcmp(tokens[0], xshift->key) == 0) idx = IDX_XSHIFT; else if (strcmp(tokens[0], yshift->key) == 0) idx = IDX_YSHIFT; else if (strcmp(tokens[0], zshift->key) == 0) idx = IDX_ZSHIFT; else if (strcmp(tokens[0], xscale->key) == 0) idx = IDX_XSCALE; else if (strcmp(tokens[0], yscale->key) == 0) idx = IDX_YSCALE; else if (strcmp(tokens[0], zscale->key) == 0) idx = IDX_ZSCALE; else if (strcmp(tokens[0], zrot->key) == 0) idx = IDX_ZROT; else idx = -1; if (idx != -1) columns_name[idx] = G_store(tokens[1]); G_free_tokens(tokens); } else { G_fatal_error(_("Unable to tokenize column string: [%s]"), columns->answers[i]); } i++; } } /* determine transformation parameters */ trans_params[IDX_XSHIFT] = atof(xshift->answer); trans_params[IDX_YSHIFT] = atof(yshift->answer); trans_params[IDX_ZSHIFT] = atof(zshift->answer); trans_params[IDX_XSCALE] = atof(xscale->answer); trans_params[IDX_YSCALE] = atof(yscale->answer); trans_params[IDX_ZSCALE] = atof(zscale->answer); trans_params[IDX_ZROT] = atof(zrot->answer); /* open vector maps */ if ((mapset = G_find_vector2(vold->answer, "")) == NULL) G_fatal_error(_("Vector map <%s> not found"), vold->answer); Vect_open_old(&Old, vold->answer, mapset); /* should output be 3D ? * note that z-scale and ztozero have no effect with input 2D */ if (Vect_is_3d(&Old) || trans_params[IDX_ZSHIFT] != 0. || columns_name[IDX_ZSHIFT]) out3d = WITH_Z; Vect_open_new(&New, vnew->answer, out3d); /* copy and set header */ Vect_copy_head_data(&Old, &New); Vect_hist_copy(&Old, &New); Vect_hist_command(&New); sprintf(date, "%s", G_date()); sscanf(date, "%*s%s%d%*s%d", mon, &day, &yr); sprintf(date, "%s %d %d", mon, day, yr); Vect_set_date(&New, date); Vect_set_person(&New, G_whoami()); sprintf(buf, "transformed from %s", vold->answer); Vect_set_map_name(&New, buf); Vect_set_scale(&New, 1); Vect_set_zone(&New, 0); Vect_set_thresh(&New, 0.0); /* points file */ if (Coord.name[0]) { create_transform_from_file(&Coord, quiet_flag->answer); if (Coord.name[0] != '\0') fclose(Coord.fp); } Vect_get_map_box(&Old, &box); /* z to zero */ if (tozero_flag->answer) ztozero = 0 - box.B; else ztozero = 0; /* do the transformation */ transform_digit_file(&Old, &New, Coord.name[0] ? 1 : 0, ztozero, trans_params, table->answer, columns_name, ifield); if (Vect_copy_tables(&Old, &New, 0)) G_warning(_("Failed to copy attribute table to output map")); Vect_close(&Old); Vect_build(&New); if (!quiet_flag->answer) { Vect_get_map_box(&New, &box); G_message(_("\nNew vector map <%s> boundary coordinates:"), vnew->answer); G_message(_(" N: %-10.3f S: %-10.3f"), box.N, box.S); G_message(_(" E: %-10.3f W: %-10.3f"), box.E, box.W); G_message(_(" B: %6.3f T: %6.3f"), box.B, box.T); /* print the transformation matrix if requested */ if (print_mat_flag->answer) print_transform_matrix(); } Vect_close(&New); G_done_msg(" "); exit(EXIT_SUCCESS); }
void print_info(const struct Map_info *Map) { int i, map_type; char line[1024]; char timebuff[256]; struct TimeStamp ts; int time_ok, first_time_ok, second_time_ok; struct bound_box box; char tmp1[1024], tmp2[1024]; time_ok = first_time_ok = second_time_ok = FALSE; map_type = Vect_maptype(Map); /* Check the Timestamp */ time_ok = G_read_vector_timestamp(Vect_get_name(Map), NULL, "", &ts); /* Check for valid entries, show none if no timestamp available */ if (time_ok == TRUE) { if (ts.count > 0) first_time_ok = TRUE; if (ts.count > 1) second_time_ok = TRUE; } divider('+'); sprintf(line, "%-17s%s", _("Name:"), Vect_get_name(Map)); printline(line); sprintf(line, "%-17s%s", _("Mapset:"), Vect_get_mapset(Map)); printline(line); sprintf(line, "%-17s%s", _("Location:"), G_location()); printline(line); sprintf(line, "%-17s%s", _("Database:"), G_gisdbase()); printline(line); sprintf(line, "%-17s%s", _("Title:"), Vect_get_map_name(Map)); printline(line); sprintf(line, "%-17s1:%d", _("Map scale:"), Vect_get_scale(Map)); printline(line); sprintf(line, "%-17s%s", _("Name of creator:"), Vect_get_person(Map)); printline(line); sprintf(line, "%-17s%s", _("Organization:"), Vect_get_organization(Map)); printline(line); sprintf(line, "%-17s%s", _("Source date:"), Vect_get_map_date(Map)); printline(line); /* This shows the TimeStamp (if present) */ if (time_ok == TRUE && (first_time_ok || second_time_ok)) { G_format_timestamp(&ts, timebuff); sprintf(line, "%-17s%s", _("Timestamp (first layer): "), timebuff); printline(line); } else { strcpy(line, _("Timestamp (first layer): none")); printline(line); } divider('|'); if (map_type == GV_FORMAT_OGR || map_type == GV_FORMAT_OGR_DIRECT) { sprintf(line, "%-17s%s (%s)", _("Map format:"), Vect_maptype_info(Map), Vect_get_finfo_format_info(Map)); printline(line); /* for OGR format print also datasource and layer */ sprintf(line, "%-17s%s", _("OGR layer:"), Vect_get_finfo_layer_name(Map)); printline(line); sprintf(line, "%-17s%s", _("OGR datasource:"), Vect_get_finfo_dsn_name(Map)); printline(line); sprintf(line, "%-17s%s", _("Feature type:"), Vect_get_finfo_geometry_type(Map)); printline(line); } else if (map_type == GV_FORMAT_POSTGIS) { int topo_format; char *toposchema_name, *topogeom_column; int topo_geo_only; const struct Format_info *finfo; finfo = Vect_get_finfo(Map); sprintf(line, "%-17s%s (%s)", _("Map format:"), Vect_maptype_info(Map), Vect_get_finfo_format_info(Map)); printline(line); /* for PostGIS format print also datasource and layer */ sprintf(line, "%-17s%s", _("DB table:"), Vect_get_finfo_layer_name(Map)); printline(line); sprintf(line, "%-17s%s", _("DB name:"), Vect_get_finfo_dsn_name(Map)); printline(line); sprintf(line, "%-17s%s", _("Geometry column:"), finfo->pg.geom_column); printline(line); sprintf(line, "%-17s%s", _("Feature type:"), Vect_get_finfo_geometry_type(Map)); printline(line); topo_format = Vect_get_finfo_topology_info(Map, &toposchema_name, &topogeom_column, &topo_geo_only); if (topo_format == GV_TOPO_POSTGIS) { sprintf(line, "%-17s%s (%s %s%s)", _("Topology:"), "PostGIS", _("schema:"), toposchema_name, topo_geo_only ? ", topo-geo-only: yes" : ""); printline(line); sprintf(line, "%-17s%s", _("Topology column:"), topogeom_column); } else sprintf(line, "%-17s%s", _("Topology:"), "pseudo (simple features)"); printline(line); } else { sprintf(line, "%-17s%s", _("Map format:"), Vect_maptype_info(Map)); printline(line); } divider('|'); sprintf(line, " %s: %s (%s: %i)", _("Type of map"), _("vector"), _("level"), Vect_level(Map)); printline(line); if (Vect_level(Map) > 0) { printline(""); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of points:"), Vect_get_num_primitives(Map, GV_POINT), _("Number of centroids:"), Vect_get_num_primitives(Map, GV_CENTROID)); printline(line); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of lines:"), Vect_get_num_primitives(Map, GV_LINE), _("Number of boundaries:"), Vect_get_num_primitives(Map, GV_BOUNDARY)); printline(line); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of areas:"), Vect_get_num_areas(Map), _("Number of islands:"), Vect_get_num_islands(Map)); printline(line); if (Vect_is_3d(Map)) { sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of faces:"), Vect_get_num_primitives(Map, GV_FACE), _("Number of kernels:"), Vect_get_num_primitives(Map, GV_KERNEL)); printline(line); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of volumes:"), Vect_get_num_volumes(Map), _("Number of holes:"), Vect_get_num_holes(Map)); printline(line); } printline(""); sprintf(line, " %-24s%s", _("Map is 3D:"), Vect_is_3d(Map) ? _("Yes") : _("No")); printline(line); sprintf(line, " %-24s%-9d", _("Number of dblinks:"), Vect_get_num_dblinks(Map)); printline(line); } printline(""); /* this differs from r.info in that proj info IS taken from the map here, not the location settings */ /* Vect_get_proj_name() and _zone() are typically unset?! */ if (G_projection() == PROJECTION_UTM) { int utm_zone; utm_zone = Vect_get_zone(Map); if (utm_zone < 0 || utm_zone > 60) strcpy(tmp1, _("invalid")); else if (utm_zone == 0) strcpy(tmp1, _("unspecified")); else sprintf(tmp1, "%d", utm_zone); sprintf(line, " %s: %s (%s %s)", _("Projection"), Vect_get_proj_name(Map), _("zone"), tmp1); } else sprintf(line, " %s: %s", _("Projection"), Vect_get_proj_name(Map)); printline(line); printline(""); Vect_get_map_box(Map, &box); G_format_northing(box.N, tmp1, G_projection()); G_format_northing(box.S, tmp2, G_projection()); sprintf(line, " %c: %17s %c: %17s", 'N', tmp1, 'S', tmp2); printline(line); G_format_easting(box.E, tmp1, G_projection()); G_format_easting(box.W, tmp2, G_projection()); sprintf(line, " %c: %17s %c: %17s", 'E', tmp1, 'W', tmp2); printline(line); if (Vect_is_3d(Map)) { format_double(box.B, tmp1); format_double(box.T, tmp2); sprintf(line, " %c: %17s %c: %17s", 'B', tmp1, 'T', tmp2); printline(line); } printline(""); format_double(Vect_get_thresh(Map), tmp1); sprintf(line, " %s: %s", _("Digitization threshold"), tmp1); printline(line); sprintf(line, " %s:", _("Comment")); printline(line); sprintf(line, " %s", Vect_get_comment(Map)); printline(line); divider('+'); fprintf(stdout, "\n"); }
int main(int argc, char *argv[]) { struct Map_info In, Out; static struct line_pnts *Points; struct line_cats *Cats; struct GModule *module; /* GRASS module for parsing arguments */ struct Option *map_in, *map_out; struct Option *method_opt, *afield_opt, *nfield_opt, *abcol, *afcol, *ncol; struct Flag *add_f; int with_z; int afield, nfield, mask_type; dglGraph_s *graph; int *component, nnodes, type, i, nlines, components, max_cat; char buf[2000], *covered; char *desc; /* Attribute table */ dbString sql; dbDriver *driver; struct field_info *Fi; /* initialize GIS environment */ G_gisinit(argv[0]); /* reads grass env, stores program name to G_program_name() */ /* initialize module */ module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("network")); G_add_keyword(_("components")); module->description = _("Computes strongly and weakly connected components in the network."); /* Define the different options as defined in gis.h */ map_in = G_define_standard_option(G_OPT_V_INPUT); afield_opt = G_define_standard_option(G_OPT_V_FIELD); afield_opt->key = "arc_layer"; afield_opt->answer = "1"; afield_opt->label = _("Arc layer"); afield_opt->guisection = _("Cost"); nfield_opt = G_define_standard_option(G_OPT_V_FIELD); nfield_opt->key = "node_layer"; nfield_opt->answer = "2"; nfield_opt->label = _("Node layer"); nfield_opt->guisection = _("Cost"); afcol = G_define_standard_option(G_OPT_DB_COLUMN); afcol->key = "arc_column"; afcol->required = NO; afcol->description = _("Arc forward/both direction(s) cost column (number)"); afcol->guisection = _("Cost"); abcol = G_define_standard_option(G_OPT_DB_COLUMN); abcol->key = "arc_backward_column"; abcol->required = NO; abcol->description = _("Arc backward direction cost column (number)"); abcol->guisection = _("Cost"); ncol = G_define_option(); ncol->key = "node_column"; ncol->type = TYPE_STRING; ncol->required = NO; ncol->description = _("Node cost column (number)"); ncol->guisection = _("Cost"); map_out = G_define_standard_option(G_OPT_V_OUTPUT); method_opt = G_define_option(); method_opt->key = "method"; method_opt->type = TYPE_STRING; method_opt->required = YES; method_opt->multiple = NO; method_opt->options = "weak,strong"; desc = NULL; G_asprintf(&desc, "weak;%s;strong;%s", _("Weakly connected components"), _("Strongly connected components")); method_opt->descriptions = desc; method_opt->description = _("Type of components"); add_f = G_define_flag(); add_f->key = 'a'; add_f->description = _("Add points on nodes"); /* options and flags parser */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* TODO: make an option for this */ mask_type = GV_LINE | GV_BOUNDARY; Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); Vect_check_input_output_name(map_in->answer, map_out->answer, G_FATAL_EXIT); Vect_set_open_level(2); if (1 > Vect_open_old(&In, map_in->answer, "")) G_fatal_error(_("Unable to open vector map <%s>"), map_in->answer); with_z = Vect_is_3d(&In); if (0 > Vect_open_new(&Out, map_out->answer, with_z)) { Vect_close(&In); G_fatal_error(_("Unable to create vector map <%s>"), map_out->answer); } /* parse filter option and select appropriate lines */ afield = Vect_get_field_number(&In, afield_opt->answer); nfield = Vect_get_field_number(&In, nfield_opt->answer); if (0 != Vect_net_build_graph(&In, mask_type, afield, nfield, afcol->answer, abcol->answer, ncol->answer, 0, 2)) G_fatal_error(_("Unable to build graph for vector map <%s>"), Vect_get_full_name(&In)); graph = Vect_net_get_graph(&In); nnodes = Vect_get_num_nodes(&In); component = (int *)G_calloc(nnodes + 1, sizeof(int)); covered = (char *)G_calloc(nnodes + 1, sizeof(char)); if (!component || !covered) { G_fatal_error(_("Out of memory")); exit(EXIT_FAILURE); } /* Create table */ Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE); Vect_map_add_dblink(&Out, 1, NULL, Fi->table, GV_KEY_COLUMN, Fi->database, Fi->driver); db_init_string(&sql); 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); sprintf(buf, "create table %s ( cat integer, comp integer)", Fi->table); db_set_string(&sql, buf); G_debug(2, "%s", db_get_string(&sql)); if (db_execute_immediate(driver, &sql) != DB_OK) { db_close_database_shutdown_driver(driver); G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&sql)); } if (db_create_index2(driver, Fi->table, GV_KEY_COLUMN) != DB_OK) G_warning(_("Cannot create index")); if (db_grant_on_table (driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK) G_fatal_error(_("Cannot grant privileges on table <%s>"), Fi->table); db_begin_transaction(driver); if (method_opt->answer[0] == 'w') { G_message(_("Computing weakly connected components...")); components = NetA_weakly_connected_components(graph, component); } else { G_message(_("Computing strongly connected components...")); components = NetA_strongly_connected_components(graph, component); } G_debug(3, "Components: %d", components); G_message(_("Writing output...")); Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); nlines = Vect_get_num_lines(&In); max_cat = 1; G_percent(0, nlines, 4); for (i = 1; i <= nlines; i++) { int comp, cat; G_percent(i, nlines, 4); type = Vect_read_line(&In, Points, Cats, i); if (!Vect_cat_get(Cats, afield, &cat)) continue; if (type == GV_LINE || type == GV_BOUNDARY) { int node1, node2; Vect_get_line_nodes(&In, i, &node1, &node2); if (component[node1] == component[node2]) { comp = component[node1]; } else { continue; } } else if (type == GV_POINT) { int node; /* Vect_get_line_nodes(&In, i, &node, NULL); */ node = Vect_find_node(&In, Points->x[0], Points->y[0], Points->z[0], 0, 0); if (!node) continue; comp = component[node]; covered[node] = 1; } else continue; cat = max_cat++; Vect_reset_cats(Cats); Vect_cat_set(Cats, 1, cat); Vect_write_line(&Out, type, Points, Cats); insert_new_record(driver, Fi, &sql, cat, comp); } /*add points on nodes not covered by any point in the network */ if (add_f->answer) { for (i = 1; i <= nnodes; i++) if (!covered[i]) { Vect_reset_cats(Cats); Vect_cat_set(Cats, 1, max_cat); NetA_add_point_on_node(&In, &Out, i, Cats); insert_new_record(driver, Fi, &sql, max_cat++, component[i]); } } db_commit_transaction(driver); db_close_database_shutdown_driver(driver); Vect_close(&In); Vect_build(&Out); Vect_close(&Out); G_done_msg(_("Found %d components."), components); exit(EXIT_SUCCESS); }
/*! \brief Load vector map to memory The other alternative may be to load to a tmp file \param grassname vector map name \param[out] number of loaded features \return pointer to geoline struct \return NULL on failure */ geoline *Gv_load_vect(const char *grassname, int *nlines) { struct Map_info map; struct line_pnts *points; struct line_cats *Cats = NULL; geoline *top, *gln, *prev; int np, i, n, nareas, nl = 0, area, type, is3d; struct Cell_head wind; float vect[2][3]; const char *mapset; mapset = G_find_vector2(grassname, ""); if (!mapset) { G_warning(_("Vector map <%s> not found"), grassname); return NULL; } Vect_set_open_level(2); if (Vect_open_old(&map, grassname, "") == -1) { G_warning(_("Unable to open vector map <%s>"), G_fully_qualified_name(grassname, mapset)); return NULL; } top = gln = (geoline *) G_malloc(sizeof(geoline)); /* G_fatal_error */ if (!top) { return NULL; } prev = top; #ifdef TRAK_MEM Tot_mem += sizeof(geoline); #endif points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); G_get_set_window(&wind); Vect_set_constraint_region(&map, wind.north, wind.south, wind.east, wind.west, PORT_DOUBLE_MAX, -PORT_DOUBLE_MAX); is3d = Vect_is_3d(&map); /* Read areas */ n = Vect_get_num_areas(&map); nareas = 0; G_debug(3, "Reading vector areas (nareas = %d)", n); for (area = 1; area <= n; area++) { G_debug(3, " area %d", area); Vect_get_area_points(&map, area, points); if (points->n_points < 3) continue; /* initialize style */ gln->highlighted = 0; gln->type = OGSF_POLYGON; gln->npts = np = points->n_points; G_debug(3, " np = %d", np); if (is3d) { gln->dims = 3; gln->p3 = (Point3 *) G_calloc(np, sizeof(Point3)); /* G_fatal_error */ if (!gln->p3) { return (NULL); } #ifdef TRAK_MEM Tot_mem += (np * sizeof(Point3)); #endif } else { gln->dims = 2; gln->p2 = (Point2 *) G_calloc(np, sizeof(Point2)); /* G_fatal_error */ if (!gln->p2) { return (NULL); } #ifdef TRAK_MEM Tot_mem += (np * sizeof(Point2)); #endif } for (i = 0; i < np; i++) { if (is3d) { gln->p3[i][X] = points->x[i]; gln->p3[i][Y] = points->y[i]; gln->p3[i][Z] = points->z[i]; } else { gln->p2[i][X] = points->x[i]; gln->p2[i][Y] = points->y[i]; } } /* Calc normal (should be average) */ if (is3d) { vect[0][X] = (float)(gln->p3[0][X] - gln->p3[1][X]); vect[0][Y] = (float)(gln->p3[0][Y] - gln->p3[1][Y]); vect[0][Z] = (float)(gln->p3[0][Z] - gln->p3[1][Z]); vect[1][X] = (float)(gln->p3[2][X] - gln->p3[1][X]); vect[1][Y] = (float)(gln->p3[2][Y] - gln->p3[1][Y]); vect[1][Z] = (float)(gln->p3[2][Z] - gln->p3[1][Z]); GS_v3cross(vect[1], vect[0], gln->norm); } gln->cats = NULL; gln->next = (geoline *) G_malloc(sizeof(geoline)); /* G_fatal_error */ if (!gln->next) { return (NULL); } #ifdef TRAK_MEM Tot_mem += sizeof(geoline); #endif prev = gln; gln = gln->next; nareas++; } G_debug(3, "%d areas loaded", nareas); /* Read all lines */ G_debug(3, "Reading vector lines ..."); while (-1 < (type = Vect_read_next_line(&map, points, Cats))) { G_debug(3, "line type = %d", type); if (type & (GV_LINES | GV_FACE)) { if (type & (GV_LINES)) { gln->type = OGSF_LINE; } else { gln->type = OGSF_POLYGON; /* Vect_append_point ( points, points->x[0], points->y[0], points->z[0] ); */ } /* initialize style */ gln->highlighted = 0; gln->npts = np = points->n_points; G_debug(3, " np = %d", np); if (is3d) { gln->dims = 3; gln->p3 = (Point3 *) G_calloc(np, sizeof(Point3)); /* G_fatal_error */ if (!gln->p3) { return (NULL); } #ifdef TRAK_MEM Tot_mem += (np * sizeof(Point3)); #endif } else { gln->dims = 2; gln->p2 = (Point2 *) G_calloc(np, sizeof(Point2)); /* G_fatal_error */ if (!gln->p2) { return (NULL); } #ifdef TRAK_MEM Tot_mem += (np * sizeof(Point2)); #endif } for (i = 0; i < np; i++) { if (is3d) { gln->p3[i][X] = points->x[i]; gln->p3[i][Y] = points->y[i]; gln->p3[i][Z] = points->z[i]; } else { gln->p2[i][X] = points->x[i]; gln->p2[i][Y] = points->y[i]; } } /* Calc normal (should be average) */ if (is3d && gln->type == OGSF_POLYGON) { vect[0][X] = (float)(gln->p3[0][X] - gln->p3[1][X]); vect[0][Y] = (float)(gln->p3[0][Y] - gln->p3[1][Y]); vect[0][Z] = (float)(gln->p3[0][Z] - gln->p3[1][Z]); vect[1][X] = (float)(gln->p3[2][X] - gln->p3[1][X]); vect[1][Y] = (float)(gln->p3[2][Y] - gln->p3[1][Y]); vect[1][Z] = (float)(gln->p3[2][Z] - gln->p3[1][Z]); GS_v3cross(vect[1], vect[0], gln->norm); G_debug(3, "norm %f %f %f", gln->norm[0], gln->norm[1], gln->norm[2]); } /* Store category info for thematic display */ if (Cats->n_cats > 0) { gln->cats = Cats; Cats = Vect_new_cats_struct(); } else { gln->cats = NULL; Vect_reset_cats(Cats); } gln->next = (geoline *) G_malloc(sizeof(geoline)); /* G_fatal_error */ if (!gln->next) { return (NULL); } #ifdef TRAK_MEM Tot_mem += sizeof(geoline); #endif prev = gln; gln = gln->next; nl++; } } G_debug(3, "%d lines loaded", nl); nl += nareas; prev->next = NULL; G_free(gln); #ifdef TRAK_MEM Tot_mem -= sizeof(geoline); #endif Vect_close(&map); if (!nl) { G_warning(_("No features from vector map <%s> fall within current region"), G_fully_qualified_name(grassname, mapset)); return (NULL); } else { G_message(_("Vector map <%s> loaded (%d features)"), G_fully_qualified_name(grassname, mapset), nl); } *nlines = nl; #ifdef TRAK_MEM G_debug(3, "Total vect memory = %d Kbytes", Tot_mem / 1000); #endif return (top); }
/*--------------------------------------------------------------------*/ int main(int argc, char *argv[]) { /* Variable declarations */ int nsply, nsplx, nrows, ncols, nsplx_adj, nsply_adj; int nsubregion_col, nsubregion_row, subregion_row, subregion_col; int subregion = 0, nsubregions = 0; int last_row, last_column, grid, bilin, ext, flag_auxiliar, cross; /* booleans */ double stepN, stepE, lambda, mean; double N_extension, E_extension, edgeE, edgeN; const char *mapset, *drv, *db, *vector, *map; char table_name[GNAME_MAX], title[64]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; int dim_vect, nparameters, BW; int *lineVect; /* Vector restoring primitive's ID */ double *TN, *Q, *parVect; /* Interpolating and least-square vectors */ double **N, **obsVect; /* Interpolation and least-square matrix */ SEGMENT out_seg, mask_seg; const char *out_file, *mask_file; int out_fd, mask_fd; double seg_size; int seg_mb, segments_in_memory; int have_mask; /* Structs declarations */ int raster; struct Map_info In, In_ext, Out; struct History history; struct GModule *module; struct Option *in_opt, *in_ext_opt, *out_opt, *out_map_opt, *stepE_opt, *stepN_opt, *lambda_f_opt, *type_opt, *dfield_opt, *col_opt, *mask_opt, *memory_opt, *solver, *error, *iter; struct Flag *cross_corr_flag, *spline_step_flag; struct Reg_dimens dims; struct Cell_head elaboration_reg, original_reg; struct bound_box general_box, overlap_box, original_box; struct Point *observ; struct line_cats *Cats; dbCatValArray cvarr; int with_z; int nrec, ctype = 0; struct field_info *Fi; dbDriver *driver, *driver_cats; /*----------------------------------------------------------------*/ /* Options declarations */ module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("surface")); G_add_keyword(_("interpolation")); G_add_keyword(_("LIDAR")); module->description = _("Performs bicubic or bilinear spline interpolation with Tykhonov regularization."); cross_corr_flag = G_define_flag(); cross_corr_flag->key = 'c'; cross_corr_flag->description = _("Find the best Tykhonov regularizing parameter using a \"leave-one-out\" cross validation method"); spline_step_flag = G_define_flag(); spline_step_flag->key = 'e'; spline_step_flag->label = _("Estimate point density and distance"); spline_step_flag->description = _("Estimate point density and distance for the input vector points within the current region extends and quit"); in_opt = G_define_standard_option(G_OPT_V_INPUT); in_opt->label = _("Name of input vector point map"); dfield_opt = G_define_standard_option(G_OPT_V_FIELD); dfield_opt->guisection = _("Settings"); col_opt = G_define_standard_option(G_OPT_DB_COLUMN); col_opt->required = NO; col_opt->label = _("Name of the attribute column with values to be used for approximation"); col_opt->description = _("If not given and input is 3D vector map then z-coordinates are used."); col_opt->guisection = _("Settings"); in_ext_opt = G_define_standard_option(G_OPT_V_INPUT); in_ext_opt->key = "sparse_input"; in_ext_opt->required = NO; in_ext_opt->label = _("Name of input vector map with sparse points"); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); out_opt->required = NO; out_opt->guisection = _("Outputs"); out_map_opt = G_define_standard_option(G_OPT_R_OUTPUT); out_map_opt->key = "raster_output"; out_map_opt->required = NO; out_map_opt->guisection = _("Outputs"); mask_opt = G_define_standard_option(G_OPT_R_INPUT); mask_opt->key = "mask"; mask_opt->label = _("Raster map to use for masking (applies to raster output only)"); mask_opt->description = _("Only cells that are not NULL and not zero are interpolated"); mask_opt->required = NO; stepE_opt = G_define_option(); stepE_opt->key = "ew_step"; stepE_opt->type = TYPE_DOUBLE; stepE_opt->required = NO; stepE_opt->answer = "4"; stepE_opt->description = _("Length of each spline step in the east-west direction"); stepE_opt->guisection = _("Settings"); stepN_opt = G_define_option(); stepN_opt->key = "ns_step"; stepN_opt->type = TYPE_DOUBLE; stepN_opt->required = NO; stepN_opt->answer = "4"; stepN_opt->description = _("Length of each spline step in the north-south direction"); stepN_opt->guisection = _("Settings"); type_opt = G_define_option(); type_opt->key = "method"; type_opt->description = _("Spline interpolation algorithm"); type_opt->type = TYPE_STRING; type_opt->options = "bilinear,bicubic"; type_opt->answer = "bilinear"; type_opt->guisection = _("Settings"); G_asprintf((char **) &(type_opt->descriptions), "bilinear;%s;bicubic;%s", _("Bilinear interpolation"), _("Bicubic interpolation")); lambda_f_opt = G_define_option(); lambda_f_opt->key = "lambda_i"; lambda_f_opt->type = TYPE_DOUBLE; lambda_f_opt->required = NO; lambda_f_opt->description = _("Tykhonov regularization parameter (affects smoothing)"); lambda_f_opt->answer = "0.01"; lambda_f_opt->guisection = _("Settings"); solver = N_define_standard_option(N_OPT_SOLVER_SYMM); solver->options = "cholesky,cg"; solver->answer = "cholesky"; iter = N_define_standard_option(N_OPT_MAX_ITERATIONS); error = N_define_standard_option(N_OPT_ITERATION_ERROR); memory_opt = G_define_option(); memory_opt->key = "memory"; memory_opt->type = TYPE_INTEGER; memory_opt->required = NO; memory_opt->answer = "300"; memory_opt->label = _("Maximum memory to be used (in MB)"); memory_opt->description = _("Cache size for raster rows"); /*----------------------------------------------------------------*/ /* Parsing */ G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); vector = out_opt->answer; map = out_map_opt->answer; if (vector && map) G_fatal_error(_("Choose either vector or raster output, not both")); if (!vector && !map && !cross_corr_flag->answer) G_fatal_error(_("No raster or vector or cross-validation output")); if (!strcmp(type_opt->answer, "linear")) bilin = P_BILINEAR; else bilin = P_BICUBIC; stepN = atof(stepN_opt->answer); stepE = atof(stepE_opt->answer); lambda = atof(lambda_f_opt->answer); flag_auxiliar = FALSE; drv = db_get_default_driver_name(); if (!drv) { if (db_set_default_connection() != DB_OK) G_fatal_error(_("Unable to set default DB connection")); drv = db_get_default_driver_name(); } db = db_get_default_database_name(); if (!db) G_fatal_error(_("No default DB defined")); /* Set auxiliary table's name */ if (vector) { if (G_name_is_fully_qualified(out_opt->answer, xname, xmapset)) { sprintf(table_name, "%s_aux", xname); } else sprintf(table_name, "%s_aux", out_opt->answer); } /* Something went wrong in a previous v.surf.bspline execution */ if (db_table_exists(drv, db, table_name)) { /* Start driver and open db */ driver = db_start_driver_open_database(drv, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), drv); db_set_error_handler_driver(driver); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_fatal_error(_("Old auxiliary table could not be dropped")); db_close_database_shutdown_driver(driver); } /* Open input vector */ if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) G_fatal_error(_("Vector map <%s> not found"), in_opt->answer); Vect_set_open_level(1); /* WITHOUT TOPOLOGY */ if (1 > Vect_open_old(&In, in_opt->answer, mapset)) G_fatal_error(_("Unable to open vector map <%s> at the topological level"), in_opt->answer); bspline_field = 0; /* assume 3D input */ bspline_column = col_opt->answer; with_z = !bspline_column && Vect_is_3d(&In); if (Vect_is_3d(&In)) { if (!with_z) G_verbose_message(_("Input is 3D: using attribute values instead of z-coordinates for approximation")); else G_verbose_message(_("Input is 3D: using z-coordinates for approximation")); } else { /* 2D */ if (!bspline_column) G_fatal_error(_("Input vector map is 2D. Parameter <%s> required."), col_opt->key); } if (!with_z) { bspline_field = Vect_get_field_number(&In, dfield_opt->answer); } /* Estimate point density and mean distance for current region */ if (spline_step_flag->answer) { double dens, dist; if (P_estimate_splinestep(&In, &dens, &dist) == 0) { fprintf(stdout, _("Estimated point density: %.4g"), dens); fprintf(stdout, _("Estimated mean distance between points: %.4g"), dist); } else { fprintf(stdout, _("No points in current region")); } Vect_close(&In); exit(EXIT_SUCCESS); } /*----------------------------------------------------------------*/ /* Cross-correlation begins */ if (cross_corr_flag->answer) { G_debug(1, "CrossCorrelation()"); cross = cross_correlation(&In, stepE, stepN); if (cross != TRUE) G_fatal_error(_("Cross validation didn't finish correctly")); else { G_debug(1, "Cross validation finished correctly"); Vect_close(&In); G_done_msg(_("Cross validation finished for ew_step = %f and ns_step = %f"), stepE, stepN); exit(EXIT_SUCCESS); } } /* Open input ext vector */ ext = FALSE; if (in_ext_opt->answer) { ext = TRUE; G_message(_("Vector map <%s> of sparse points will be interpolated"), in_ext_opt->answer); if ((mapset = G_find_vector2(in_ext_opt->answer, "")) == NULL) G_fatal_error(_("Vector map <%s> not found"), in_ext_opt->answer); Vect_set_open_level(1); /* WITHOUT TOPOLOGY */ if (1 > Vect_open_old(&In_ext, in_ext_opt->answer, mapset)) G_fatal_error(_("Unable to open vector map <%s> at the topological level"), in_opt->answer); } /* Open output map */ /* vector output */ if (vector && !map) { if (strcmp(drv, "dbf") == 0) G_fatal_error(_("Sorry, the <%s> driver is not compatible with " "the vector output of this module. " "Try with raster output or another driver."), drv); Vect_check_input_output_name(in_opt->answer, out_opt->answer, G_FATAL_EXIT); grid = FALSE; if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer); /* Copy vector Head File */ if (ext == FALSE) { Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); } else { Vect_copy_head_data(&In_ext, &Out); Vect_hist_copy(&In_ext, &Out); } Vect_hist_command(&Out); G_verbose_message(_("Points in input vector map <%s> will be interpolated"), vector); } /* read z values from attribute table */ if (bspline_field > 0) { G_message(_("Reading values from attribute table...")); db_CatValArray_init(&cvarr); Fi = Vect_get_field(&In, bspline_field); if (Fi == NULL) G_fatal_error(_("Cannot read layer info")); driver_cats = db_start_driver_open_database(Fi->driver, Fi->database); /*G_debug (0, _("driver=%s db=%s"), Fi->driver, Fi->database); */ if (driver_cats == NULL) G_fatal_error(_("Unable to open database <%s> by driver <%s>"), Fi->database, Fi->driver); db_set_error_handler_driver(driver_cats); nrec = db_select_CatValArray(driver_cats, Fi->table, Fi->key, col_opt->answer, NULL, &cvarr); G_debug(3, "nrec = %d", nrec); ctype = cvarr.ctype; if (ctype != DB_C_TYPE_INT && ctype != DB_C_TYPE_DOUBLE) G_fatal_error(_("Column type not supported")); if (nrec < 0) G_fatal_error(_("Unable to select data from table")); G_verbose_message(_("%d records selected from table"), nrec); db_close_database_shutdown_driver(driver_cats); } /*----------------------------------------------------------------*/ /* Interpolation begins */ G_debug(1, "Interpolation()"); /* Open driver and database */ driver = db_start_driver_open_database(drv, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. " "Run db.connect."), drv); db_set_error_handler_driver(driver); /* Create auxiliary table */ if (vector) { if ((flag_auxiliar = P_Create_Aux4_Table(driver, table_name)) == FALSE) { P_Drop_Aux_Table(driver, table_name); G_fatal_error(_("Interpolation: Creating table: " "It was impossible to create table <%s>."), table_name); } /* db_create_index2(driver, table_name, "ID"); */ /* sqlite likes that ??? */ db_close_database_shutdown_driver(driver); driver = db_start_driver_open_database(drv, db); } /* raster output */ raster = -1; Rast_set_fp_type(DCELL_TYPE); if (!vector && map) { grid = TRUE; raster = Rast_open_fp_new(out_map_opt->answer); G_verbose_message(_("Cells for raster map <%s> will be interpolated"), map); } /* Setting regions and boxes */ G_debug(1, "Interpolation: Setting regions and boxes"); G_get_window(&original_reg); G_get_window(&elaboration_reg); Vect_region_box(&original_reg, &original_box); Vect_region_box(&elaboration_reg, &overlap_box); Vect_region_box(&elaboration_reg, &general_box); nrows = Rast_window_rows(); ncols = Rast_window_cols(); /* Alloc raster matrix */ have_mask = 0; out_file = mask_file = NULL; out_fd = mask_fd = -1; if (grid == TRUE) { int row; DCELL *drastbuf; seg_mb = atoi(memory_opt->answer); if (seg_mb < 3) G_fatal_error(_("Memory in MB must be >= 3")); if (mask_opt->answer) seg_size = sizeof(double) + sizeof(char); else seg_size = sizeof(double); seg_size = (seg_size * SEGSIZE * SEGSIZE) / (1 << 20); segments_in_memory = seg_mb / seg_size + 0.5; G_debug(1, "%d %dx%d segments held in memory", segments_in_memory, SEGSIZE, SEGSIZE); out_file = G_tempfile(); out_fd = creat(out_file, 0666); if (Segment_format(out_fd, nrows, ncols, SEGSIZE, SEGSIZE, sizeof(double)) != 1) G_fatal_error(_("Can not create temporary file")); close(out_fd); out_fd = open(out_file, 2); if (Segment_init(&out_seg, out_fd, segments_in_memory) != 1) G_fatal_error(_("Can not initialize temporary file")); /* initialize output */ G_message(_("Initializing output...")); drastbuf = Rast_allocate_buf(DCELL_TYPE); Rast_set_d_null_value(drastbuf, ncols); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); Segment_put_row(&out_seg, drastbuf, row); } G_percent(row, nrows, 2); if (mask_opt->answer) { int row, col, maskfd; DCELL dval, *drastbuf; char mask_val; G_message(_("Load masking map")); mask_file = G_tempfile(); mask_fd = creat(mask_file, 0666); if (Segment_format(mask_fd, nrows, ncols, SEGSIZE, SEGSIZE, sizeof(char)) != 1) G_fatal_error(_("Can not create temporary file")); close(mask_fd); mask_fd = open(mask_file, 2); if (Segment_init(&mask_seg, mask_fd, segments_in_memory) != 1) G_fatal_error(_("Can not initialize temporary file")); maskfd = Rast_open_old(mask_opt->answer, ""); drastbuf = Rast_allocate_buf(DCELL_TYPE); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); Rast_get_d_row(maskfd, drastbuf, row); for (col = 0; col < ncols; col++) { dval = drastbuf[col]; if (Rast_is_d_null_value(&dval) || dval == 0) mask_val = 0; else mask_val = 1; Segment_put(&mask_seg, &mask_val, row, col); } } G_percent(row, nrows, 2); G_free(drastbuf); Rast_close(maskfd); have_mask = 1; } } /*------------------------------------------------------------------ | Subdividing and working with tiles: | Each original region will be divided into several subregions. | Each one will be overlaped by its neighbouring subregions. | The overlapping is calculated as a fixed OVERLAP_SIZE times | the largest spline step plus 2 * edge ----------------------------------------------------------------*/ /* Fixing parameters of the elaboration region */ P_zero_dim(&dims); /* Set dim struct to zero */ nsplx_adj = NSPLX_MAX; nsply_adj = NSPLY_MAX; if (stepN > stepE) dims.overlap = OVERLAP_SIZE * stepN; else dims.overlap = OVERLAP_SIZE * stepE; P_get_edge(bilin, &dims, stepE, stepN); P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj); G_verbose_message(_("Adjusted EW splines %d"), nsplx_adj); G_verbose_message(_("Adjusted NS splines %d"), nsply_adj); /* calculate number of subregions */ edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v; edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h; N_extension = original_reg.north - original_reg.south; E_extension = original_reg.east - original_reg.west; nsubregion_col = ceil(E_extension / edgeE) + 0.5; nsubregion_row = ceil(N_extension / edgeN) + 0.5; if (nsubregion_col < 0) nsubregion_col = 0; if (nsubregion_row < 0) nsubregion_row = 0; nsubregions = nsubregion_row * nsubregion_col; /* Creating line and categories structs */ Cats = Vect_new_cats_struct(); Vect_cat_set(Cats, 1, 0); subregion_row = 0; elaboration_reg.south = original_reg.north; last_row = FALSE; while (last_row == FALSE) { /* For each subregion row */ subregion_row++; P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_ROW); if (elaboration_reg.north > original_reg.north) { /* First row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_ROW); } if (elaboration_reg.south <= original_reg.south) { /* Last row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_ROW); last_row = TRUE; } nsply = ceil((elaboration_reg.north - elaboration_reg.south) / stepN) + 0.5; G_debug(1, "Interpolation: nsply = %d", nsply); /* if (nsply > NSPLY_MAX) nsply = NSPLY_MAX; */ elaboration_reg.east = original_reg.west; last_column = FALSE; subregion_col = 0; /* TODO: process each subregion using its own thread (via OpenMP or pthreads) */ /* I'm not sure about pthreads, but you can tell OpenMP to start all at the same time and it will keep num_workers supplied with the next job as free cpus become available */ while (last_column == FALSE) { /* For each subregion column */ int npoints = 0; /* needed for sparse points interpolation */ int npoints_ext, *lineVect_ext = NULL; double **obsVect_ext; /*, mean_ext = .0; */ struct Point *observ_ext; subregion_col++; subregion++; if (nsubregions > 1) G_message(_("Processing subregion %d of %d..."), subregion, nsubregions); P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_COLUMN); if (elaboration_reg.west < original_reg.west) { /* First column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_COLUMN); } if (elaboration_reg.east >= original_reg.east) { /* Last column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_COLUMN); last_column = TRUE; } nsplx = ceil((elaboration_reg.east - elaboration_reg.west) / stepE) + 0.5; G_debug(1, "Interpolation: nsplx = %d", nsplx); /* if (nsplx > NSPLX_MAX) nsplx = NSPLX_MAX; */ G_debug(1, "Interpolation: (%d,%d): subregion bounds", subregion_row, subregion_col); G_debug(1, "Interpolation: \t\tNORTH:%.2f\t", elaboration_reg.north); G_debug(1, "Interpolation: WEST:%.2f\t\tEAST:%.2f", elaboration_reg.west, elaboration_reg.east); G_debug(1, "Interpolation: \t\tSOUTH:%.2f", elaboration_reg.south); #ifdef DEBUG_SUBREGIONS fprintf(stdout, "B 5\n"); fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.north); fprintf(stdout, " %.11g %.11g\n", elaboration_reg.west, elaboration_reg.north); fprintf(stdout, " %.11g %.11g\n", elaboration_reg.west, elaboration_reg.south); fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.south); fprintf(stdout, " %.11g %.11g\n", elaboration_reg.east, elaboration_reg.north); fprintf(stdout, "C 1 1\n"); fprintf(stdout, " %.11g %.11g\n", (elaboration_reg.west + elaboration_reg.east) / 2, (elaboration_reg.south + elaboration_reg.north) / 2); fprintf(stdout, " 1 %d\n", subregion); #endif /* reading points in interpolation region */ dim_vect = nsplx * nsply; observ_ext = NULL; if (grid == FALSE && ext == TRUE) { observ_ext = P_Read_Vector_Region_Map(&In_ext, &elaboration_reg, &npoints_ext, dim_vect, 1); } else npoints_ext = 1; if (grid == TRUE && have_mask) { /* any unmasked cells in general region ? */ mean = 0; observ_ext = P_Read_Raster_Region_masked(&mask_seg, &original_reg, original_box, general_box, &npoints_ext, dim_vect, mean); } observ = NULL; if (npoints_ext > 0) { observ = P_Read_Vector_Region_Map(&In, &elaboration_reg, &npoints, dim_vect, bspline_field); } else npoints = 1; G_debug(1, "Interpolation: (%d,%d): Number of points in <elaboration_box> is %d", subregion_row, subregion_col, npoints); if (npoints > 0) G_verbose_message(_("%d points found in this subregion"), npoints); /* only interpolate if there are any points in current subregion */ if (npoints > 0 && npoints_ext > 0) { int i; nparameters = nsplx * nsply; BW = P_get_BandWidth(bilin, nsply); /* Least Squares system */ N = G_alloc_matrix(nparameters, BW); /* Normal matrix */ TN = G_alloc_vector(nparameters); /* vector */ parVect = G_alloc_vector(nparameters); /* Parameters vector */ obsVect = G_alloc_matrix(npoints, 3); /* Observation vector */ Q = G_alloc_vector(npoints); /* "a priori" var-cov matrix */ lineVect = G_alloc_ivector(npoints); /* */ for (i = 0; i < npoints; i++) { /* Setting obsVect vector & Q matrix */ double dval; Q[i] = 1; /* Q=I */ lineVect[i] = observ[i].lineID; obsVect[i][0] = observ[i].coordX; obsVect[i][1] = observ[i].coordY; /* read z coordinates from attribute table */ if (bspline_field > 0) { int cat, ival, ret; cat = observ[i].cat; if (cat < 0) continue; if (ctype == DB_C_TYPE_INT) { ret = db_CatValArray_get_value_int(&cvarr, cat, &ival); obsVect[i][2] = ival; observ[i].coordZ = ival; } else { /* DB_C_TYPE_DOUBLE */ ret = db_CatValArray_get_value_double(&cvarr, cat, &dval); obsVect[i][2] = dval; observ[i].coordZ = dval; } if (ret != DB_OK) { G_warning(_("Interpolation: (%d,%d): No record for point (cat = %d)"), subregion_row, subregion_col, cat); continue; } } /* use z coordinates of 3D vector */ else { obsVect[i][2] = observ[i].coordZ; } } /* Mean calculation for every point */ mean = P_Mean_Calc(&elaboration_reg, observ, npoints); G_debug(1, "Interpolation: (%d,%d): mean=%lf", subregion_row, subregion_col, mean); G_free(observ); for (i = 0; i < npoints; i++) obsVect[i][2] -= mean; /* Bilinear interpolation */ if (bilin) { G_debug(1, "Interpolation: (%d,%d): Bilinear interpolation...", subregion_row, subregion_col); normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx, nsply, elaboration_reg.west, elaboration_reg.south, npoints, nparameters, BW); nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN); } /* Bicubic interpolation */ else { G_debug(1, "Interpolation: (%d,%d): Bicubic interpolation...", subregion_row, subregion_col); normalDefBicubic(N, TN, Q, obsVect, stepE, stepN, nsplx, nsply, elaboration_reg.west, elaboration_reg.south, npoints, nparameters, BW); nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN); } if(G_strncasecmp(solver->answer, "cg", 2) == 0) G_math_solver_cg_sband(N, parVect, TN, nparameters, BW, atoi(iter->answer), atof(error->answer)); else G_math_solver_cholesky_sband(N, parVect, TN, nparameters, BW); G_free_matrix(N); G_free_vector(TN); G_free_vector(Q); if (grid == TRUE) { /* GRID INTERPOLATION ==> INTERPOLATION INTO A RASTER */ G_debug(1, "Interpolation: (%d,%d): Regular_Points...", subregion_row, subregion_col); if (!have_mask) { P_Regular_Points(&elaboration_reg, &original_reg, general_box, overlap_box, &out_seg, parVect, stepN, stepE, dims.overlap, mean, nsplx, nsply, nrows, ncols, bilin); } else { P_Sparse_Raster_Points(&out_seg, &elaboration_reg, &original_reg, general_box, overlap_box, observ_ext, parVect, stepE, stepN, dims.overlap, nsplx, nsply, npoints_ext, bilin, mean); } } else { /* OBSERVATION POINTS INTERPOLATION */ if (ext == FALSE) { G_debug(1, "Interpolation: (%d,%d): Sparse_Points...", subregion_row, subregion_col); P_Sparse_Points(&Out, &elaboration_reg, general_box, overlap_box, obsVect, parVect, lineVect, stepE, stepN, dims.overlap, nsplx, nsply, npoints, bilin, Cats, driver, mean, table_name); } else { /* FLAG_EXT == TRUE */ /* done that earlier */ /* int npoints_ext, *lineVect_ext = NULL; double **obsVect_ext; struct Point *observ_ext; observ_ext = P_Read_Vector_Region_Map(&In_ext, &elaboration_reg, &npoints_ext, dim_vect, 1); */ obsVect_ext = G_alloc_matrix(npoints_ext, 3); /* Observation vector_ext */ lineVect_ext = G_alloc_ivector(npoints_ext); for (i = 0; i < npoints_ext; i++) { /* Setting obsVect_ext vector & Q matrix */ obsVect_ext[i][0] = observ_ext[i].coordX; obsVect_ext[i][1] = observ_ext[i].coordY; obsVect_ext[i][2] = observ_ext[i].coordZ - mean; lineVect_ext[i] = observ_ext[i].lineID; } G_free(observ_ext); G_debug(1, "Interpolation: (%d,%d): Sparse_Points...", subregion_row, subregion_col); P_Sparse_Points(&Out, &elaboration_reg, general_box, overlap_box, obsVect_ext, parVect, lineVect_ext, stepE, stepN, dims.overlap, nsplx, nsply, npoints_ext, bilin, Cats, driver, mean, table_name); G_free_matrix(obsVect_ext); G_free_ivector(lineVect_ext); } /* END FLAG_EXT == TRUE */ } /* END GRID == FALSE */ G_free_vector(parVect); G_free_matrix(obsVect); G_free_ivector(lineVect); } else { if (observ) G_free(observ); if (observ_ext) G_free(observ_ext); if (npoints == 0) G_warning(_("No data within this subregion. " "Consider increasing spline step values.")); } } /*! END WHILE; last_column = TRUE */ } /*! END WHILE; last_row = TRUE */ G_verbose_message(_("Writing output...")); /* Writing the output raster map */ if (grid == TRUE) { int row, col; DCELL *drastbuf, dval; if (have_mask) { Segment_release(&mask_seg); /* release memory */ close(mask_fd); unlink(mask_file); } drastbuf = Rast_allocate_buf(DCELL_TYPE); for (row = 0; row < nrows; row++) { G_percent(row, nrows, 2); for (col = 0; col < ncols; col++) { Segment_get(&out_seg, &dval, row, col); drastbuf[col] = dval; } Rast_put_d_row(raster, drastbuf); } Rast_close(raster); Segment_release(&out_seg); /* release memory */ close(out_fd); unlink(out_file); /* set map title */ sprintf(title, "%s interpolation with Tykhonov regularization", type_opt->answer); Rast_put_cell_title(out_map_opt->answer, title); /* write map history */ Rast_short_history(out_map_opt->answer, "raster", &history); Rast_command_history(&history); Rast_write_history(out_map_opt->answer, &history); } /* Writing to the output vector map the points from the overlapping zones */ else if (flag_auxiliar == TRUE) { if (ext == FALSE) P_Aux_to_Vector(&In, &Out, driver, table_name); else P_Aux_to_Vector(&In_ext, &Out, driver, table_name); /* Drop auxiliary table */ G_debug(1, "%s: Dropping <%s>", argv[0], table_name); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_fatal_error(_("Auxiliary table could not be dropped")); } db_close_database_shutdown_driver(driver); Vect_close(&In); if (ext != FALSE) Vect_close(&In_ext); if (vector) Vect_close(&Out); G_done_msg(" "); exit(EXIT_SUCCESS); } /*END MAIN */
/*--------------------------------------------------------------------*/ int main(int argc, char *argv[]) { /* Variables declarations */ int nsplx_adj, nsply_adj; int nsubregion_col, nsubregion_row; int subregion = 0, nsubregions = 0; double N_extension, E_extension, edgeE, edgeN; int dim_vect, nparameters, BW, npoints; double mean, lambda; const char *dvr, *db, *mapset; char table_name[GNAME_MAX]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; int last_row, last_column, flag_auxiliar = FALSE; int filter_mode; int *lineVect; double *TN, *Q, *parVect; /* Interpolating and least-square vectors */ double **N, **obsVect; /* Interpolation and least-square matrix */ /* Structs declarations */ struct Map_info In, Out, Outlier, Qgis; struct Option *in_opt, *out_opt, *outlier_opt, *qgis_opt, *stepE_opt, *stepN_opt, *lambda_f_opt, *Thres_O_opt, *filter_opt; struct Flag *spline_step_flag; struct GModule *module; struct Reg_dimens dims; struct Cell_head elaboration_reg, original_reg; struct bound_box general_box, overlap_box; struct Point *observ; dbDriver *driver; /*----------------------------------------------------------------*/ /* Options declaration */ module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("statistics")); G_add_keyword(_("extract")); G_add_keyword(_("select")); G_add_keyword(_("filter")); module->description = _("Removes outliers from vector point data."); spline_step_flag = G_define_flag(); spline_step_flag->key = 'e'; spline_step_flag->label = _("Estimate point density and distance"); spline_step_flag->description = _("Estimate point density and distance for the input vector points within the current region extends and quit"); in_opt = G_define_standard_option(G_OPT_V_INPUT); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); outlier_opt = G_define_option(); outlier_opt->key = "outlier"; outlier_opt->type = TYPE_STRING; outlier_opt->key_desc = "name"; outlier_opt->required = YES; outlier_opt->gisprompt = "new,vector,vector"; outlier_opt->description = _("Name of output outlier vector map"); qgis_opt = G_define_option(); qgis_opt->key = "qgis"; qgis_opt->type = TYPE_STRING; qgis_opt->key_desc = "name"; qgis_opt->required = NO; qgis_opt->gisprompt = "new,vector,vector"; qgis_opt->description = _("Name of vector map for visualization in QGIS"); stepE_opt = G_define_option(); stepE_opt->key = "ew_step"; stepE_opt->type = TYPE_DOUBLE; stepE_opt->required = NO; stepE_opt->answer = "10"; stepE_opt->description = _("Length of each spline step in the east-west direction"); stepE_opt->guisection = _("Settings"); stepN_opt = G_define_option(); stepN_opt->key = "ns_step"; stepN_opt->type = TYPE_DOUBLE; stepN_opt->required = NO; stepN_opt->answer = "10"; stepN_opt->description = _("Length of each spline step in the north-south direction"); stepN_opt->guisection = _("Settings"); lambda_f_opt = G_define_option(); lambda_f_opt->key = "lambda"; lambda_f_opt->type = TYPE_DOUBLE; lambda_f_opt->required = NO; lambda_f_opt->description = _("Tykhonov regularization weight"); lambda_f_opt->answer = "0.1"; lambda_f_opt->guisection = _("Settings"); Thres_O_opt = G_define_option(); Thres_O_opt->key = "threshold"; Thres_O_opt->type = TYPE_DOUBLE; Thres_O_opt->required = NO; Thres_O_opt->description = _("Threshold for the outliers"); Thres_O_opt->answer = "50"; filter_opt = G_define_option(); filter_opt->key = "filter"; filter_opt->type = TYPE_STRING; filter_opt->required = NO; filter_opt->description = _("Filtering option"); filter_opt->options = "both,positive,negative"; filter_opt->answer = "both"; /* Parsing */ G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if (!(db = G_getenv_nofatal2("DB_DATABASE", G_VAR_MAPSET))) G_fatal_error(_("Unable to read name of database")); if (!(dvr = G_getenv_nofatal2("DB_DRIVER", G_VAR_MAPSET))) G_fatal_error(_("Unable to read name of driver")); stepN = atof(stepN_opt->answer); stepE = atof(stepE_opt->answer); lambda = atof(lambda_f_opt->answer); Thres_Outlier = atof(Thres_O_opt->answer); filter_mode = 0; if (strcmp(filter_opt->answer, "positive") == 0) filter_mode = 1; else if (strcmp(filter_opt->answer, "negative") == 0) filter_mode = -1; P_set_outlier_fn(filter_mode); flag_auxiliar = FALSE; /* Checking vector names */ Vect_check_input_output_name(in_opt->answer, out_opt->answer, G_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(out_opt->answer, xname, xmapset)) { sprintf(table_name, "%s_aux", xname); } else sprintf(table_name, "%s_aux", out_opt->answer); /* Something went wrong in a previous v.outlier execution */ if (db_table_exists(dvr, db, table_name)) { /* Start driver and open db */ driver = db_start_driver_open_database(dvr, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), dvr); db_set_error_handler_driver(driver); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_fatal_error(_("Old auxiliar table could not be dropped")); db_close_database_shutdown_driver(driver); } /* Open input vector */ Vect_set_open_level(1); /* WITHOUT TOPOLOGY */ if (1 > Vect_open_old(&In, in_opt->answer, mapset)) G_fatal_error(_("Unable to open vector map <%s> at the topological level"), in_opt->answer); /* Input vector must be 3D */ if (!Vect_is_3d(&In)) G_fatal_error(_("Input vector map <%s> is not 3D!"), in_opt->answer); /* Estimate point density and mean distance for current region */ if (spline_step_flag->answer) { double dens, dist; if (P_estimate_splinestep(&In, &dens, &dist) == 0) { G_message("Estimated point density: %.4g", dens); G_message("Estimated mean distance between points: %.4g", dist); } else G_warning(_("No points in current region!")); Vect_close(&In); exit(EXIT_SUCCESS); } /* Open output vector */ if (qgis_opt->answer) if (0 > Vect_open_new(&Qgis, qgis_opt->answer, WITHOUT_Z)) G_fatal_error(_("Unable to create vector map <%s>"), qgis_opt->answer); if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) { Vect_close(&Qgis); G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer); } if (0 > Vect_open_new(&Outlier, outlier_opt->answer, WITH_Z)) { Vect_close(&Out); Vect_close(&Qgis); G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer); } /* Copy vector Head File */ Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); Vect_copy_head_data(&In, &Outlier); Vect_hist_copy(&In, &Outlier); Vect_hist_command(&Outlier); if (qgis_opt->answer) { Vect_copy_head_data(&In, &Qgis); Vect_hist_copy(&In, &Qgis); Vect_hist_command(&Qgis); } /* Open driver and database */ driver = db_start_driver_open_database(dvr, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), dvr); db_set_error_handler_driver(driver); /* Create auxiliar table */ if ((flag_auxiliar = P_Create_Aux2_Table(driver, table_name)) == FALSE) G_fatal_error(_("It was impossible to create <%s> table."), table_name); db_create_index2(driver, table_name, "ID"); /* sqlite likes that ??? */ db_close_database_shutdown_driver(driver); driver = db_start_driver_open_database(dvr, db); /* Setting regions and boxes */ G_get_set_window(&original_reg); G_get_set_window(&elaboration_reg); Vect_region_box(&elaboration_reg, &overlap_box); Vect_region_box(&elaboration_reg, &general_box); /*------------------------------------------------------------------ | Subdividing and working with tiles: | Each original region will be divided into several subregions. | Each one will be overlaped by its neighbouring subregions. | The overlapping is calculated as a fixed OVERLAP_SIZE times | the largest spline step plus 2 * edge ----------------------------------------------------------------*/ /* Fixing parameters of the elaboration region */ P_zero_dim(&dims); /* Set dim struct to zero */ nsplx_adj = NSPLX_MAX; nsply_adj = NSPLY_MAX; if (stepN > stepE) dims.overlap = OVERLAP_SIZE * stepN; else dims.overlap = OVERLAP_SIZE * stepE; P_get_edge(P_BILINEAR, &dims, stepE, stepN); P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj); G_verbose_message(_("Adjusted EW splines %d"), nsplx_adj); G_verbose_message(_("Adjusted NS splines %d"), nsply_adj); /* calculate number of subregions */ edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v; edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h; N_extension = original_reg.north - original_reg.south; E_extension = original_reg.east - original_reg.west; nsubregion_col = ceil(E_extension / edgeE) + 0.5; nsubregion_row = ceil(N_extension / edgeN) + 0.5; if (nsubregion_col < 0) nsubregion_col = 0; if (nsubregion_row < 0) nsubregion_row = 0; nsubregions = nsubregion_row * nsubregion_col; elaboration_reg.south = original_reg.north; last_row = FALSE; while (last_row == FALSE) { /* For each row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_ROW); if (elaboration_reg.north > original_reg.north) { /* First row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_ROW); } if (elaboration_reg.south <= original_reg.south) { /* Last row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_ROW); last_row = TRUE; } nsply = ceil((elaboration_reg.north - elaboration_reg.south) / stepN) + 0.5; /* if (nsply > NSPLY_MAX) nsply = NSPLY_MAX; */ G_debug(1, "nsply = %d", nsply); elaboration_reg.east = original_reg.west; last_column = FALSE; while (last_column == FALSE) { /* For each column */ subregion++; if (nsubregions > 1) G_message(_("Processing subregion %d of %d..."), subregion, nsubregions); else /* v.outlier -e will report mean point distance: */ G_warning(_("No subregions found! Check values for 'ew_step' and 'ns_step' parameters")); P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_COLUMN); if (elaboration_reg.west < original_reg.west) { /* First column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_COLUMN); } if (elaboration_reg.east >= original_reg.east) { /* Last column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_COLUMN); last_column = TRUE; } nsplx = ceil((elaboration_reg.east - elaboration_reg.west) / stepE) + 0.5; /* if (nsplx > NSPLX_MAX) nsplx = NSPLX_MAX; */ G_debug(1, "nsplx = %d", nsplx); /*Setting the active region */ dim_vect = nsplx * nsply; observ = P_Read_Vector_Region_Map(&In, &elaboration_reg, &npoints, dim_vect, 1); if (npoints > 0) { /* If there is any point falling into elaboration_reg... */ int i; nparameters = nsplx * nsply; /* Mean calculation */ mean = P_Mean_Calc(&elaboration_reg, observ, npoints); /* Least Squares system */ G_debug(1, "Allocation memory for bilinear interpolation"); BW = P_get_BandWidth(P_BILINEAR, nsply); /* Bilinear interpolation */ N = G_alloc_matrix(nparameters, BW); /* Normal matrix */ TN = G_alloc_vector(nparameters); /* vector */ parVect = G_alloc_vector(nparameters); /* Bicubic parameters vector */ obsVect = G_alloc_matrix(npoints, 3); /* Observation vector */ Q = G_alloc_vector(npoints); /* "a priori" var-cov matrix */ lineVect = G_alloc_ivector(npoints); /* Setting obsVect vector & Q matrix */ for (i = 0; i < npoints; i++) { obsVect[i][0] = observ[i].coordX; obsVect[i][1] = observ[i].coordY; obsVect[i][2] = observ[i].coordZ - mean; lineVect[i] = observ[i].lineID; Q[i] = 1; /* Q=I */ } G_free(observ); G_verbose_message(_("Bilinear interpolation")); normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx, nsply, elaboration_reg.west, elaboration_reg.south, npoints, nparameters, BW); nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN); G_math_solver_cholesky_sband(N, parVect, TN, nparameters, BW); G_free_matrix(N); G_free_vector(TN); G_free_vector(Q); G_verbose_message(_("Outlier detection")); if (qgis_opt->answer) P_Outlier(&Out, &Outlier, &Qgis, elaboration_reg, general_box, overlap_box, obsVect, parVect, mean, dims.overlap, lineVect, npoints, driver, table_name); else P_Outlier(&Out, &Outlier, NULL, elaboration_reg, general_box, overlap_box, obsVect, parVect, mean, dims.overlap, lineVect, npoints, driver, table_name); G_free_vector(parVect); G_free_matrix(obsVect); G_free_ivector(lineVect); } /*! END IF; npoints > 0 */ else { G_free(observ); G_warning(_("No data within this subregion. " "Consider increasing spline step values.")); } } /*! END WHILE; last_column = TRUE */ } /*! END WHILE; last_row = TRUE */ /* Drop auxiliar table */ if (npoints > 0) { G_debug(1, "%s: Dropping <%s>", argv[0], table_name); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_fatal_error(_("Auxiliary table could not be dropped")); } db_close_database_shutdown_driver(driver); Vect_close(&In); Vect_close(&Out); Vect_close(&Outlier); if (qgis_opt->answer) { Vect_build(&Qgis); Vect_close(&Qgis); } G_done_msg(" "); exit(EXIT_SUCCESS); } /*END MAIN */
/*----------------------------------------------------------------------------------------------------------*/ int main(int argc, char *argv[]) { /* Declarations */ int dim_vect, nparameters, BW, npoints; int nsply, nsplx, nsplx_adj, nsply_adj; int nsubregion_col, nsubregion_row; int subregion = 0, nsubregions = 0; const char *dvr, *db, *mapset; char table_name[GNAME_MAX]; char xname[GNAME_MAX], xmapset[GMAPSET_MAX]; double lambda, mean, stepN, stepE, HighThresh, LowThresh; double N_extension, E_extension, edgeE, edgeN; int i, nterrain, count_terrain; int last_row, last_column, flag_auxiliar = FALSE; int *lineVect; double *TN, *Q, *parVect; /* Interpolating and least-square vectors */ double **N, **obsVect, **obsVect_all; /* Interpolation and least-square matrix */ struct Map_info In, Out, Terrain; struct Option *in_opt, *out_opt, *out_terrain_opt, *stepE_opt, *stepN_opt, *lambda_f_opt, *Thresh_A_opt, *Thresh_B_opt; struct Flag *spline_step_flag; struct GModule *module; struct Cell_head elaboration_reg, original_reg; struct Reg_dimens dims; struct bound_box general_box, overlap_box; struct Point *observ; struct lidar_cat *lcat; dbDriver *driver; /*----------------------------------------------------------------------------------------------------------*/ /* Options' declaration */ module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("LIDAR")); module->description = _("Corrects the v.lidar.growing output. It is the last of the three algorithms for LIDAR filtering."); spline_step_flag = G_define_flag(); spline_step_flag->key = 'e'; spline_step_flag->label = _("Estimate point density and distance"); spline_step_flag->description = _("Estimate point density and distance for the input vector points within the current region extends and quit"); in_opt = G_define_standard_option(G_OPT_V_INPUT); in_opt->description = _("Input observation vector map name (v.lidar.growing output)"); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); out_opt->description = _("Output classified vector map name"); out_terrain_opt = G_define_option(); out_terrain_opt->key = "terrain"; out_terrain_opt->type = TYPE_STRING; out_terrain_opt->key_desc = "name"; out_terrain_opt->required = YES; out_terrain_opt->gisprompt = "new,vector,vector"; out_terrain_opt->description = _("Only 'terrain' points output vector map"); stepE_opt = G_define_option(); stepE_opt->key = "ew_step"; stepE_opt->type = TYPE_DOUBLE; stepE_opt->required = NO; stepE_opt->answer = "25"; stepE_opt->description = _("Length of each spline step in the east-west direction"); stepE_opt->guisection = _("Settings"); stepN_opt = G_define_option(); stepN_opt->key = "ns_step"; stepN_opt->type = TYPE_DOUBLE; stepN_opt->required = NO; stepN_opt->answer = "25"; stepN_opt->description = _("Length of each spline step in the north-south direction"); stepN_opt->guisection = _("Settings"); lambda_f_opt = G_define_option(); lambda_f_opt->key = "lambda_c"; lambda_f_opt->type = TYPE_DOUBLE; lambda_f_opt->required = NO; lambda_f_opt->description = _("Regularization weight in reclassification evaluation"); lambda_f_opt->answer = "1"; Thresh_A_opt = G_define_option(); Thresh_A_opt->key = "tch"; Thresh_A_opt->type = TYPE_DOUBLE; Thresh_A_opt->required = NO; Thresh_A_opt->description = _("High threshold for object to terrain reclassification"); Thresh_A_opt->answer = "2"; Thresh_B_opt = G_define_option(); Thresh_B_opt->key = "tcl"; Thresh_B_opt->type = TYPE_DOUBLE; Thresh_B_opt->required = NO; Thresh_B_opt->description = _("Low threshold for terrain to object reclassification"); Thresh_B_opt->answer = "1"; /* Parsing */ G_gisinit(argv[0]); if (G_parser(argc, argv)) exit(EXIT_FAILURE); stepN = atof(stepN_opt->answer); stepE = atof(stepE_opt->answer); lambda = atof(lambda_f_opt->answer); HighThresh = atof(Thresh_A_opt->answer); LowThresh = atof(Thresh_B_opt->answer); if (!(db = G_getenv_nofatal2("DB_DATABASE", G_VAR_MAPSET))) G_fatal_error(_("Unable to read name of database")); if (!(dvr = G_getenv_nofatal2("DB_DRIVER", G_VAR_MAPSET))) G_fatal_error(_("Unable to read name of driver")); /* Setting auxiliar table's name */ if (G_name_is_fully_qualified(out_opt->answer, xname, xmapset)) { sprintf(table_name, "%s_aux", xname); } else sprintf(table_name, "%s_aux", out_opt->answer); /* Something went wrong in a previous v.lidar.correction execution */ if (db_table_exists(dvr, db, table_name)) { /* Start driver and open db */ driver = db_start_driver_open_database(dvr, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), dvr); db_set_error_handler_driver(driver); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_fatal_error(_("Old auxiliar table could not be dropped")); db_close_database_shutdown_driver(driver); } /* Checking vector names */ Vect_check_input_output_name(in_opt->answer, out_opt->answer, G_FATAL_EXIT); /* Open input vector */ if ((mapset = G_find_vector2(in_opt->answer, "")) == NULL) G_fatal_error(_("Vector map <%s> not found"), in_opt->answer); Vect_set_open_level(1); /* without topology */ if (1 > Vect_open_old(&In, in_opt->answer, mapset)) G_fatal_error(_("Unable to open vector map <%s>"), in_opt->answer); /* Input vector must be 3D */ if (!Vect_is_3d(&In)) G_fatal_error(_("Input vector map <%s> is not 3D!"), in_opt->answer); /* Estimate point density and mean distance for current region */ if (spline_step_flag->answer) { double dens, dist; if (P_estimate_splinestep(&In, &dens, &dist) == 0) { G_message("Estimated point density: %.4g", dens); G_message("Estimated mean distance between points: %.4g", dist); } else G_warning(_("No points in current region!")); Vect_close(&In); exit(EXIT_SUCCESS); } /* Open output vector */ if (0 > Vect_open_new(&Out, out_opt->answer, WITH_Z)) { Vect_close(&In); G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer); } if (0 > Vect_open_new(&Terrain, out_terrain_opt->answer, WITH_Z)) { Vect_close(&In); Vect_close(&Out); G_fatal_error(_("Unable to create vector map <%s>"), out_opt->answer); } /* Copy vector Head File */ Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); Vect_copy_head_data(&In, &Terrain); Vect_hist_copy(&In, &Terrain); Vect_hist_command(&Terrain); /* Start driver and open db */ driver = db_start_driver_open_database(dvr, db); if (driver == NULL) G_fatal_error(_("No database connection for driver <%s> is defined. Run db.connect."), dvr); db_set_error_handler_driver(driver); /* Create auxiliar table */ if ((flag_auxiliar = P_Create_Aux2_Table(driver, table_name)) == FALSE) { Vect_close(&In); Vect_close(&Out); Vect_close(&Terrain); exit(EXIT_FAILURE); } db_create_index2(driver, table_name, "ID"); /* sqlite likes that ??? */ db_close_database_shutdown_driver(driver); driver = db_start_driver_open_database(dvr, db); /* Setting regions and boxes */ G_get_set_window(&original_reg); G_get_set_window(&elaboration_reg); Vect_region_box(&elaboration_reg, &overlap_box); Vect_region_box(&elaboration_reg, &general_box); /*------------------------------------------------------------------ | Subdividing and working with tiles: | Each original region will be divided into several subregions. | Each one will be overlaped by its neighbouring subregions. | The overlapping is calculated as a fixed OVERLAP_SIZE times | the largest spline step plus 2 * edge ----------------------------------------------------------------*/ /* Fixing parameters of the elaboration region */ P_zero_dim(&dims); nsplx_adj = NSPLX_MAX; nsply_adj = NSPLY_MAX; if (stepN > stepE) dims.overlap = OVERLAP_SIZE * stepN; else dims.overlap = OVERLAP_SIZE * stepE; P_get_edge(P_BILINEAR, &dims, stepE, stepN); P_set_dim(&dims, stepE, stepN, &nsplx_adj, &nsply_adj); G_verbose_message(n_("adjusted EW spline %d", "adjusted EW splines %d", nsplx_adj), nsplx_adj); G_verbose_message(n_("adjusted NS spline %d", "adjusted NS splines %d", nsply_adj), nsply_adj); /* calculate number of subregions */ edgeE = dims.ew_size - dims.overlap - 2 * dims.edge_v; edgeN = dims.sn_size - dims.overlap - 2 * dims.edge_h; N_extension = original_reg.north - original_reg.south; E_extension = original_reg.east - original_reg.west; nsubregion_col = ceil(E_extension / edgeE) + 0.5; nsubregion_row = ceil(N_extension / edgeN) + 0.5; if (nsubregion_col < 0) nsubregion_col = 0; if (nsubregion_row < 0) nsubregion_row = 0; nsubregions = nsubregion_row * nsubregion_col; elaboration_reg.south = original_reg.north; last_row = FALSE; while (last_row == FALSE) { /* For each row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_ROW); if (elaboration_reg.north > original_reg.north) { /* First row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_ROW); } if (elaboration_reg.south <= original_reg.south) { /* Last row */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_ROW); last_row = TRUE; } nsply = ceil((elaboration_reg.north - elaboration_reg.south) / stepN) + 0.5; /* if (nsply > NSPLY_MAX) { nsply = NSPLY_MAX; } */ G_debug(1, _("nsply = %d"), nsply); elaboration_reg.east = original_reg.west; last_column = FALSE; while (last_column == FALSE) { /* For each column */ subregion++; if (nsubregions > 1) G_message(_("subregion %d of %d"), subregion, nsubregions); P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, GENERAL_COLUMN); if (elaboration_reg.west < original_reg.west) { /* First column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, FIRST_COLUMN); } if (elaboration_reg.east >= original_reg.east) { /* Last column */ P_set_regions(&elaboration_reg, &general_box, &overlap_box, dims, LAST_COLUMN); last_column = TRUE; } nsplx = ceil((elaboration_reg.east - elaboration_reg.west) / stepE) + 0.5; /* if (nsplx > NSPLX_MAX) { nsplx = NSPLX_MAX; } */ G_debug(1, _("nsplx = %d"), nsplx); dim_vect = nsplx * nsply; G_debug(1, _("read vector region map")); observ = P_Read_Vector_Correction(&In, &elaboration_reg, &npoints, &nterrain, dim_vect, &lcat); G_debug(5, _("npoints = %d, nterrain = %d"), npoints, nterrain); if (npoints > 0) { /* If there is any point falling into elaboration_reg. */ count_terrain = 0; nparameters = nsplx * nsply; /* Mean calculation */ G_debug(3, _("Mean calculation")); mean = P_Mean_Calc(&elaboration_reg, observ, npoints); /*Least Squares system */ BW = P_get_BandWidth(P_BILINEAR, nsply); /* Bilinear interpolation */ N = G_alloc_matrix(nparameters, BW); /* Normal matrix */ TN = G_alloc_vector(nparameters); /* vector */ parVect = G_alloc_vector(nparameters); /* Bilinear parameters vector */ obsVect = G_alloc_matrix(nterrain + 1, 3); /* Observation vector with terrain points */ obsVect_all = G_alloc_matrix(npoints + 1, 3); /* Observation vector with all points */ Q = G_alloc_vector(nterrain + 1); /* "a priori" var-cov matrix */ lineVect = G_alloc_ivector(npoints + 1); /* Setting obsVect vector & Q matrix */ G_debug(3, _("Only TERRAIN points")); for (i = 0; i < npoints; i++) { if (observ[i].cat == TERRAIN_SINGLE) { obsVect[count_terrain][0] = observ[i].coordX; obsVect[count_terrain][1] = observ[i].coordY; obsVect[count_terrain][2] = observ[i].coordZ - mean; Q[count_terrain] = 1; /* Q=I */ count_terrain++; } lineVect[i] = observ[i].lineID; obsVect_all[i][0] = observ[i].coordX; obsVect_all[i][1] = observ[i].coordY; obsVect_all[i][2] = observ[i].coordZ - mean; } G_free(observ); G_verbose_message(_("Bilinear interpolation")); normalDefBilin(N, TN, Q, obsVect, stepE, stepN, nsplx, nsply, elaboration_reg.west, elaboration_reg.south, nterrain, nparameters, BW); nCorrectGrad(N, lambda, nsplx, nsply, stepE, stepN); G_math_solver_cholesky_sband(N, parVect, TN, nparameters, BW); G_free_matrix(N); G_free_vector(TN); G_free_vector(Q); G_free_matrix(obsVect); G_verbose_message( _("Correction and creation of terrain vector")); P_Sparse_Correction(&In, &Out, &Terrain, &elaboration_reg, general_box, overlap_box, obsVect_all, lcat, parVect, lineVect, stepN, stepE, dims.overlap, HighThresh, LowThresh, nsplx, nsply, npoints, driver, mean, table_name); G_free_vector(parVect); G_free_matrix(obsVect_all); G_free_ivector(lineVect); } else { G_free(observ); G_warning(_("No data within this subregion. " "Consider changing the spline step.")); } G_free(lcat); } /*! END WHILE; last_column = TRUE */ } /*! END WHILE; last_row = TRUE */ /* Dropping auxiliar table */ if (npoints > 0) { G_debug(1, _("Dropping <%s>"), table_name); if (P_Drop_Aux_Table(driver, table_name) != DB_OK) G_fatal_error(_("Auxiliar table could not be dropped")); } db_close_database_shutdown_driver(driver); Vect_close(&In); Vect_close(&Out); Vect_close(&Terrain); G_done_msg(" "); exit(EXIT_SUCCESS); } /*! END MAIN */
int main(int argc, char *argv[]) { struct GModule *module; struct GParams params; struct Map_info Map; struct Map_info **BgMap; /* backgroud vector maps */ int nbgmaps; /* number of registrated background maps */ enum mode action_mode; FILE *ascii; int i; int move_first, snap; int ret, layer; double move_x, move_y, move_z, thresh[3]; struct line_pnts *coord; struct ilist *List; struct cat_list *Clist; ascii = NULL; List = NULL; BgMap = NULL; nbgmaps = 0; coord = NULL; Clist = NULL; G_gisinit(argv[0]); module = G_define_module(); module->overwrite = TRUE; G_add_keyword(_("vector")); G_add_keyword(_("editing")); G_add_keyword(_("geometry")); module->description = _("Edits a vector map, allows adding, deleting " "and modifying selected vector features."); if (!parser(argc, argv, ¶ms, &action_mode)) exit(EXIT_FAILURE); /* get list of categories */ Clist = Vect_new_cat_list(); if (params.cat->answer && Vect_str_to_cat_list(params.cat->answer, Clist)) { G_fatal_error(_("Unable to get category list <%s>"), params.cat->answer); } /* open input file */ if (params.in->answer) { if (strcmp(params.in->answer, "-") != 0) { ascii = fopen(params.in->answer, "r"); if (ascii == NULL) G_fatal_error(_("Unable to open file <%s>"), params.in->answer); } else { ascii = stdin; } } if (!ascii && action_mode == MODE_ADD) G_fatal_error(_("Required parameter <%s> not set"), params.in->key); if (action_mode == MODE_CREATE) { int overwrite; overwrite = G_check_overwrite(argc, argv); if (G_find_vector2(params.map->answer, G_mapset())) { if (!overwrite) G_fatal_error(_("Vector map <%s> already exists"), params.map->answer); } /* 3D vector maps? */ ret = Vect_open_new(&Map, params.map->answer, WITHOUT_Z); if (Vect_maptype(&Map) == GV_FORMAT_OGR_DIRECT) { int type; type = Vect_option_to_types(params.type); if (type != GV_POINT && type != GV_LINE && type != GV_BOUNDARY) G_fatal_error(_("Supported feature type for OGR layer: " "%s, %s or %s"), "point", "line", "boundary"); V2_open_new_ogr(&Map, type); } if (ret == -1) { G_fatal_error(_("Unable to create vector map <%s>"), params.map->answer); } G_debug(1, "Map created"); if (ascii) { /* also add new vector features */ action_mode = MODE_ADD; } } else { /* open selected vector file */ if (action_mode == MODE_ADD) /* write */ ret = Vect_open_update2(&Map, params.map->answer, G_mapset(), params.fld->answer); else /* read-only -- select features */ ret = Vect_open_old2(&Map, params.map->answer, G_mapset(), params.fld->answer); if (ret < 2) G_fatal_error(_("Unable to open vector map <%s> at topological level %d"), params.map->answer, 2); } G_debug(1, "Map opened"); /* open backgroud maps */ if (params.bmaps->answer) { i = 0; while (params.bmaps->answers[i]) { const char *bmap = params.bmaps->answers[i]; const char *mapset = G_find_vector2(bmap, ""); if (!mapset) G_fatal_error(_("Vector map <%s> not found"), bmap); if (strcmp( G_fully_qualified_name(params.map->answer, G_mapset()), G_fully_qualified_name(bmap, mapset)) == 0) { G_fatal_error(_("Unable to open vector map <%s> as the background map. " "It is given as vector map to be edited."), bmap); } nbgmaps++; BgMap = (struct Map_info **)G_realloc( BgMap, nbgmaps * sizeof(struct Map_info *)); BgMap[nbgmaps - 1] = (struct Map_info *)G_malloc(sizeof(struct Map_info)); if (Vect_open_old(BgMap[nbgmaps - 1], bmap, "") == -1) G_fatal_error(_("Unable to open vector map <%s>"), bmap); G_verbose_message(_("Background vector map <%s> registered"), bmap); i++; } } layer = Vect_get_field_number(&Map, params.fld->answer); i = 0; while (params.maxdist->answers[i]) { switch (i) { case THRESH_COORDS: thresh[THRESH_COORDS] = max_distance(atof(params.maxdist->answers[THRESH_COORDS])); thresh[THRESH_SNAP] = thresh[THRESH_QUERY] = thresh[THRESH_COORDS]; break; case THRESH_SNAP: thresh[THRESH_SNAP] = max_distance(atof(params.maxdist->answers[THRESH_SNAP])); break; case THRESH_QUERY: thresh[THRESH_QUERY] = atof(params.maxdist->answers[THRESH_QUERY]); break; default: break; } i++; } move_first = params.move_first->answer ? 1 : 0; snap = NO_SNAP; if (strcmp(params.snap->answer, "node") == 0) snap = SNAP; else if (strcmp(params.snap->answer, "vertex") == 0) snap = SNAPVERTEX; if (snap != NO_SNAP && thresh[THRESH_SNAP] <= 0) { G_warning(_("Threshold for snapping must be > 0. No snapping applied.")); snap = NO_SNAP; } if (action_mode != MODE_CREATE && action_mode != MODE_ADD) { /* select lines */ List = Vect_new_list(); G_message(_("Selecting features...")); if (action_mode == MODE_COPY && BgMap && BgMap[0]) { List = select_lines(BgMap[0], action_mode, ¶ms, thresh, List); } else { List = select_lines(&Map, action_mode, ¶ms, thresh, List); } } if ((action_mode != MODE_CREATE && action_mode != MODE_ADD && action_mode != MODE_SELECT)) { if (List->n_values < 1) { G_warning(_("No features selected, nothing to edit")); action_mode = MODE_NONE; ret = 0; } else { /* reopen the map for updating */ if (action_mode == MODE_ZBULK && !Vect_is_3d(&Map)) { Vect_close(&Map); G_fatal_error(_("Vector map <%s> is not 3D. Tool '%s' requires 3D vector map. " "Please convert the vector map " "to 3D using e.g. %s."), params.map->answer, params.tool->answer, "v.extrude"); } Vect_close(&Map); Vect_open_update2(&Map, params.map->answer, G_mapset(), params.fld->answer); } } /* coords option -> array */ if (params.coord->answers) { coord = Vect_new_line_struct(); int i = 0; double east, north; while (params.coord->answers[i]) { east = atof(params.coord->answers[i]); north = atof(params.coord->answers[i + 1]); Vect_append_point(coord, east, north, 0.0); i += 2; } } /* perform requested editation */ switch (action_mode) { case MODE_CREATE: break; case MODE_ADD: if (!params.header->answer) Vect_read_ascii_head(ascii, &Map); int num_lines; num_lines = Vect_get_num_lines(&Map); ret = Vect_read_ascii(ascii, &Map); G_message(_("%d features added"), ret); if (ret > 0) { int iline; struct ilist *List_added; List_added = Vect_new_list(); for (iline = num_lines + 1; iline <= Vect_get_num_lines(&Map); iline++) Vect_list_append(List_added, iline); G_verbose_message(_("Threshold value for snapping is %.2f"), thresh[THRESH_SNAP]); if (snap != NO_SNAP) { /* apply snapping */ /* snap to vertex ? */ Vedit_snap_lines(&Map, BgMap, nbgmaps, List_added, thresh[THRESH_SNAP], snap == SNAP ? FALSE : TRUE); } if (params.close->answer) { /* close boundaries */ int nclosed; nclosed = close_lines(&Map, GV_BOUNDARY, thresh[THRESH_SNAP]); G_message(_("%d boundaries closed"), nclosed); } Vect_destroy_list(List_added); } break; case MODE_DEL: ret = Vedit_delete_lines(&Map, List); G_message(_("%d features deleted"), ret); break; case MODE_MOVE: move_x = atof(params.move->answers[0]); move_y = atof(params.move->answers[1]); move_z = atof(params.move->answers[2]); G_verbose_message(_("Threshold value for snapping is %.2f"), thresh[THRESH_SNAP]); ret = Vedit_move_lines(&Map, BgMap, nbgmaps, List, move_x, move_y, move_z, snap, thresh[THRESH_SNAP]); G_message(_("%d features moved"), ret); break; case MODE_VERTEX_MOVE: move_x = atof(params.move->answers[0]); move_y = atof(params.move->answers[1]); move_z = atof(params.move->answers[2]); G_verbose_message(_("Threshold value for snapping is %.2f"), thresh[THRESH_SNAP]); ret = Vedit_move_vertex(&Map, BgMap, nbgmaps, List, coord, thresh[THRESH_COORDS], thresh[THRESH_SNAP], move_x, move_y, move_z, move_first, snap); G_message(_("%d vertices moved"), ret); break; case MODE_VERTEX_ADD: ret = Vedit_add_vertex(&Map, List, coord, thresh[THRESH_COORDS]); G_message(_("%d vertices added"), ret); break; case MODE_VERTEX_DELETE: ret = Vedit_remove_vertex(&Map, List, coord, thresh[THRESH_COORDS]); G_message(_("%d vertices removed"), ret); break; case MODE_BREAK: if (params.coord->answer) { ret = Vedit_split_lines(&Map, List, coord, thresh[THRESH_COORDS], NULL); } else { ret = Vect_break_lines_list(&Map, List, NULL, GV_LINES, NULL); } G_message(_("%d lines broken"), ret); break; case MODE_CONNECT: G_verbose_message(_("Threshold value for snapping is %.2f"), thresh[THRESH_SNAP]); ret = Vedit_connect_lines(&Map, List, thresh[THRESH_SNAP]); G_message(_("%d lines connected"), ret); break; case MODE_MERGE: ret = Vedit_merge_lines(&Map, List); G_message(_("%d lines merged"), ret); break; case MODE_SELECT: ret = print_selected(List); break; case MODE_CATADD: ret = Vedit_modify_cats(&Map, List, layer, 0, Clist); G_message(_("%d features modified"), ret); break; case MODE_CATDEL: ret = Vedit_modify_cats(&Map, List, layer, 1, Clist); G_message(_("%d features modified"), ret); break; case MODE_COPY: if (BgMap && BgMap[0]) { if (nbgmaps > 1) G_warning(_("Multiple background maps were given. " "Selected features will be copied only from " "vector map <%s>."), Vect_get_full_name(BgMap[0])); ret = Vedit_copy_lines(&Map, BgMap[0], List); } else { ret = Vedit_copy_lines(&Map, NULL, List); } G_message(_("%d features copied"), ret); break; case MODE_SNAP: G_verbose_message(_("Threshold value for snapping is %.2f"), thresh[THRESH_SNAP]); ret = snap_lines(&Map, List, thresh[THRESH_SNAP]); break; case MODE_FLIP: ret = Vedit_flip_lines(&Map, List); G_message(_("%d lines flipped"), ret); break; case MODE_NONE: break; case MODE_ZBULK:{ double start, step; double x1, y1, x2, y2; start = atof(params.zbulk->answers[0]); step = atof(params.zbulk->answers[1]); x1 = atof(params.bbox->answers[0]); y1 = atof(params.bbox->answers[1]); x2 = atof(params.bbox->answers[2]); y2 = atof(params.bbox->answers[3]); ret = Vedit_bulk_labeling(&Map, List, x1, y1, x2, y2, start, step); G_message(_("%d lines labeled"), ret); break; } case MODE_CHTYPE:{ ret = Vedit_chtype_lines(&Map, List); if (ret > 0) { G_message(_("%d features converted"), ret); } else { G_message(_("No feature modified")); } break; } default: G_warning(_("Operation not implemented")); ret = -1; break; } Vect_hist_command(&Map); /* build topology only if requested or if tool!=select */ if (!(action_mode == MODE_SELECT || params.topo->answer == 1 || !MODE_NONE)) { Vect_build_partial(&Map, GV_BUILD_NONE); Vect_build(&Map); } if (List) Vect_destroy_list(List); Vect_close(&Map); G_debug(1, "Map closed"); /* close background maps */ for (i = 0; i < nbgmaps; i++) { Vect_close(BgMap[i]); G_free((void *)BgMap[i]); } G_free((void *)BgMap); if (coord) Vect_destroy_line_struct(coord); if (Clist) Vect_destroy_cat_list(Clist); G_done_msg(" "); if (ret > -1) { exit(EXIT_SUCCESS); } else { exit(EXIT_FAILURE); } }
int main(int argc, char *argv[]) { struct Option *vector_opt, *seed_opt, *flowlines_opt, *flowacc_opt, *sampled_opt, *scalar_opt, *unit_opt, *step_opt, *limit_opt, *skip_opt, *dir_opt, *error_opt; struct Flag *table_fl; struct GModule *module; RASTER3D_Region region; RASTER3D_Map *flowacc, *sampled; struct Integration integration; struct Seed seed; struct Gradient_info gradient_info; struct Map_info seed_Map; struct line_pnts *seed_points; struct line_cats *seed_cats; struct Map_info fl_map; struct line_cats *fl_cats; /* for flowlines */ struct line_pnts *fl_points; /* for flowlines */ struct field_info *finfo; dbDriver *driver; int cat; /* cat of flowlines */ int if_table; int i, r, c, d; char *desc; int n_seeds, seed_count, ltype; int skip[3]; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("raster3d")); G_add_keyword(_("hydrology")); G_add_keyword(_("voxel")); module->description = _("Computes 3D flow lines and 3D flow accumulation."); scalar_opt = G_define_standard_option(G_OPT_R3_INPUT); scalar_opt->required = NO; scalar_opt->guisection = _("Input"); vector_opt = G_define_standard_option(G_OPT_R3_INPUTS); vector_opt->key = "vector_field"; vector_opt->required = NO; vector_opt->description = _("Names of three 3D raster maps describing " "x, y, z components of vector field"); vector_opt->guisection = _("Input"); seed_opt = G_define_standard_option(G_OPT_V_INPUT); seed_opt->required = NO; seed_opt->key = "seed_points"; seed_opt->description = _("If no map is provided, " "flow lines are generated " "from each cell of the input 3D raster"); seed_opt->label = _("Name of vector map with points " "from which flow lines are generated"); seed_opt->guisection = _("Input"); flowlines_opt = G_define_standard_option(G_OPT_V_OUTPUT); flowlines_opt->key = "flowline"; flowlines_opt->required = NO; flowlines_opt->description = _("Name for vector map of flow lines"); flowlines_opt->guisection = _("Output"); flowacc_opt = G_define_standard_option(G_OPT_R3_OUTPUT); flowacc_opt->key = "flowaccumulation"; flowacc_opt->required = NO; flowacc_opt->description = _("Name for output flowaccumulation 3D raster"); flowacc_opt->guisection = _("Output"); sampled_opt = G_define_standard_option(G_OPT_R3_INPUT); sampled_opt->key = "sampled"; sampled_opt->required = NO; sampled_opt->label = _("Name for 3D raster sampled by flowlines"); sampled_opt->description = _("Values of this 3D raster will be stored " "as attributes of flowlines segments"); unit_opt = G_define_option(); unit_opt->key = "unit"; unit_opt->type = TYPE_STRING; unit_opt->required = NO; unit_opt->answer = "cell"; unit_opt->options = "time,length,cell"; desc = NULL; G_asprintf(&desc, "time;%s;" "length;%s;" "cell;%s", _("elapsed time"), _("length in map units"), _("length in cells (voxels)")); unit_opt->descriptions = desc; unit_opt->label = _("Unit of integration step"); unit_opt->description = _("Default unit is cell"); unit_opt->guisection = _("Integration"); step_opt = G_define_option(); step_opt->key = "step"; step_opt->type = TYPE_DOUBLE; step_opt->required = NO; step_opt->answer = "0.25"; step_opt->label = _("Integration step in selected unit"); step_opt->description = _("Default step is 0.25 cell"); step_opt->guisection = _("Integration"); limit_opt = G_define_option(); limit_opt->key = "limit"; limit_opt->type = TYPE_INTEGER; limit_opt->required = NO; limit_opt->answer = "2000"; limit_opt->description = _("Maximum number of steps"); limit_opt->guisection = _("Integration"); error_opt = G_define_option(); error_opt->key = "max_error"; error_opt->type = TYPE_DOUBLE; error_opt->required = NO; error_opt->answer = "1e-5"; error_opt->label = _("Maximum error of integration"); error_opt->description = _("Influences step, increase maximum error " "to allow bigger steps"); error_opt->guisection = _("Integration"); skip_opt = G_define_option(); skip_opt->key = "skip"; skip_opt->type = TYPE_INTEGER; skip_opt->required = NO; skip_opt->multiple = YES; skip_opt->description = _("Number of cells between flow lines in x, y and z direction"); dir_opt = G_define_option(); dir_opt->key = "direction"; dir_opt->type = TYPE_STRING; dir_opt->required = NO; dir_opt->multiple = NO; dir_opt->options = "up,down,both"; dir_opt->answer = "down"; dir_opt->description = _("Compute flowlines upstream, " "downstream or in both direction."); table_fl = G_define_flag(); table_fl->key = 'a'; table_fl->description = _("Create and fill attribute table"); G_option_required(scalar_opt, vector_opt, NULL); G_option_exclusive(scalar_opt, vector_opt, NULL); G_option_required(flowlines_opt, flowacc_opt, NULL); G_option_requires(seed_opt, flowlines_opt, NULL); G_option_requires(table_fl, flowlines_opt, NULL); G_option_requires(sampled_opt, table_fl, NULL); if (G_parser(argc, argv)) exit(EXIT_FAILURE); driver = NULL; finfo = NULL; if_table = table_fl->answer ? TRUE : FALSE; check_vector_input_maps(vector_opt, seed_opt); Rast3d_init_defaults(); Rast3d_get_window(®ion); /* set up integration variables */ if (step_opt->answer) { integration.step = atof(step_opt->answer); integration.unit = unit_opt->answer; } else { integration.unit = "cell"; integration.step = 0.25; } integration.max_error = atof(error_opt->answer); integration.max_step = 5 * integration.step; integration.min_step = integration.step / 5; integration.limit = atof(limit_opt->answer); if (strcmp(dir_opt->answer, "up") == 0) integration.direction_type = FLOWDIR_UP; else if (strcmp(dir_opt->answer, "down") == 0) integration.direction_type = FLOWDIR_DOWN; else integration.direction_type = FLOWDIR_BOTH; /* cell size is the diagonal */ integration.cell_size = sqrt(region.ns_res * region.ns_res + region.ew_res * region.ew_res + region.tb_res * region.tb_res); /* set default skip if needed */ if (skip_opt->answers) { for (i = 0; i < 3; i++) { if (skip_opt->answers[i] != NULL) { skip[i] = atoi(skip_opt->answers[i]); } else { G_fatal_error(_("Please provide 3 integer values for skip option.")); } } } else { skip[0] = fmax(1, region.cols / 10); skip[1] = fmax(1, region.rows / 10); skip[2] = fmax(1, region.depths / 10); } /* open raster 3D maps of velocity components */ gradient_info.initialized = FALSE; load_input_raster3d_maps(scalar_opt, vector_opt, &gradient_info, ®ion); /* open new 3D raster map of flowacumulation */ if (flowacc_opt->answer) { flowacc = Rast3d_open_new_opt_tile_size(flowacc_opt->answer, RASTER3D_USE_CACHE_DEFAULT, ®ion, FCELL_TYPE, 32); if (!flowacc) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), flowacc_opt->answer); init_flowaccum(®ion, flowacc); } /* open 3D raster map used for sampling */ if (sampled_opt->answer) { sampled = Rast3d_open_cell_old(sampled_opt->answer, G_find_raster3d(sampled_opt->answer, ""), ®ion, RASTER3D_TILE_SAME_AS_FILE, RASTER3D_USE_CACHE_DEFAULT); if (!sampled) Rast3d_fatal_error(_("Unable to open 3D raster map <%s>"), sampled_opt->answer); } else sampled = NULL; /* open new vector map of flowlines */ if (flowlines_opt->answer) { fl_cats = Vect_new_cats_struct(); fl_points = Vect_new_line_struct(); if (Vect_open_new(&fl_map, flowlines_opt->answer, TRUE) < 0) G_fatal_error(_("Unable to create vector map <%s>"), flowlines_opt->answer); Vect_hist_command(&fl_map); if (if_table) { create_table(&fl_map, &finfo, &driver, gradient_info.compute_gradient, sampled ? 1 : 0); } } n_seeds = 0; /* open vector map of seeds */ if (seed_opt->answer) { if (Vect_open_old2(&seed_Map, seed_opt->answer, "", "1") < 0) G_fatal_error(_("Unable to open vector map <%s>"), seed_opt->answer); if (!Vect_is_3d(&seed_Map)) G_fatal_error(_("Vector map <%s> is not 3D"), seed_opt->answer); n_seeds = Vect_get_num_primitives(&seed_Map, GV_POINT); } if (flowacc_opt->answer || (!seed_opt->answer && flowlines_opt->answer)) { if (flowacc_opt->answer) n_seeds += region.cols * region.rows * region.depths; else { n_seeds += ceil(region.cols / (double)skip[0]) * ceil(region.rows / (double)skip[1]) * ceil(region.depths / (double)skip[2]); } } G_debug(1, "Number of seeds is %d", n_seeds); seed_count = 0; cat = 1; if (seed_opt->answer) { seed_points = Vect_new_line_struct(); seed_cats = Vect_new_cats_struct(); /* compute flowlines from vector seed map */ while (TRUE) { ltype = Vect_read_next_line(&seed_Map, seed_points, seed_cats); if (ltype == -1) { Vect_close(&seed_Map); G_fatal_error(_("Error during reading seed vector map")); } else if (ltype == -2) { break; } else if (ltype == GV_POINT) { seed.x = seed_points->x[0]; seed.y = seed_points->y[0]; seed.z = seed_points->z[0]; seed.flowline = TRUE; seed.flowaccum = FALSE; } G_percent(seed_count, n_seeds, 1); if (integration.direction_type == FLOWDIR_UP || integration.direction_type == FLOWDIR_BOTH) { integration.actual_direction = FLOWDIR_UP; compute_flowline(®ion, &seed, &gradient_info, flowacc, sampled, &integration, &fl_map, fl_cats, fl_points, &cat, if_table, finfo, driver); } if (integration.direction_type == FLOWDIR_DOWN || integration.direction_type == FLOWDIR_BOTH) { integration.actual_direction = FLOWDIR_DOWN; compute_flowline(®ion, &seed, &gradient_info, flowacc, sampled, &integration, &fl_map, fl_cats, fl_points, &cat, if_table, finfo, driver); } seed_count++; } Vect_destroy_line_struct(seed_points); Vect_destroy_cats_struct(seed_cats); Vect_close(&seed_Map); } if (flowacc_opt->answer || (!seed_opt->answer && flowlines_opt->answer)) { /* compute flowlines from points on grid */ for (r = region.rows; r > 0; r--) { for (c = 0; c < region.cols; c++) { for (d = 0; d < region.depths; d++) { seed.x = region.west + c * region.ew_res + region.ew_res / 2; seed.y = region.south + r * region.ns_res - region.ns_res / 2; seed.z = region.bottom + d * region.tb_res + region.tb_res / 2; seed.flowline = FALSE; seed.flowaccum = FALSE; if (flowacc_opt->answer) seed.flowaccum = TRUE; if (flowlines_opt->answer && !seed_opt->answer && (c % skip[0] == 0) && (r % skip[1] == 0) && (d % skip[2] == 0)) seed.flowline = TRUE; if (seed.flowaccum || seed.flowline) { G_percent(seed_count, n_seeds, 1); if (integration.direction_type == FLOWDIR_UP || integration.direction_type == FLOWDIR_BOTH) { integration.actual_direction = FLOWDIR_UP; compute_flowline(®ion, &seed, &gradient_info, flowacc, sampled, &integration, &fl_map, fl_cats, fl_points, &cat, if_table, finfo, driver); } if (integration.direction_type == FLOWDIR_DOWN || integration.direction_type == FLOWDIR_BOTH) { integration.actual_direction = FLOWDIR_DOWN; compute_flowline(®ion, &seed, &gradient_info, flowacc, sampled, &integration, &fl_map, fl_cats, fl_points, &cat, if_table, finfo, driver); } seed_count++; } } } } } G_percent(1, 1, 1); if (flowlines_opt->answer) { if (if_table) { db_commit_transaction(driver); db_close_database_shutdown_driver(driver); } Vect_destroy_line_struct(fl_points); Vect_destroy_cats_struct(fl_cats); Vect_build(&fl_map); Vect_close(&fl_map); } if (flowacc_opt->answer) Rast3d_close(flowacc); return EXIT_SUCCESS; }
int main(int argc, char **argv) { int i, j, ret, centre, line, centre1, centre2, tfield, tucfield; int nlines, nnodes, type, ltype, afield, nfield, geo, cat; int node, node1, node2; double cost, e1cost, e2cost, n1cost, n2cost, s1cost, s2cost, l, l1; struct Option *map, *output; struct Option *afield_opt, *nfield_opt, *afcol, *abcol, *ncol, *type_opt, *term_opt, *cost_opt, *tfield_opt, *tucfield_opt; struct Flag *geo_f, *turntable_f; struct GModule *module; struct Map_info Map, Out; struct cat_list *catlist; CENTER *Centers = NULL; int acentres = 0, ncentres = 0; NODE *Nodes; struct line_cats *Cats; struct line_pnts *Points, *SPoints; int niso, aiso; double *iso; int npnts1, apnts1 = 0, npnts2, apnts2 = 0; ISOPOINT *pnts1 = NULL, *pnts2 = NULL; int next_iso; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("network")); G_add_keyword(_("isolines")); module->label = _("Splits net by cost isolines."); module->description = _ ("Splits net to bands between cost isolines (direction from center). " "Center node must be opened (costs >= 0). " "Costs of center node are used in calculation."); map = G_define_standard_option(G_OPT_V_INPUT); output = G_define_standard_option(G_OPT_V_OUTPUT); term_opt = G_define_standard_option(G_OPT_V_CATS); term_opt->key = "ccats"; term_opt->required = YES; term_opt->description = _("Categories of centers (points on nodes) to which net " "will be allocated, " "layer for this categories is given by nlayer option"); cost_opt = G_define_option(); cost_opt->key = "costs"; cost_opt->type = TYPE_INTEGER; cost_opt->multiple = YES; cost_opt->required = YES; cost_opt->description = _("Costs for isolines"); afield_opt = G_define_standard_option(G_OPT_V_FIELD); afield_opt->key = "alayer"; afield_opt->answer = "1"; afield_opt->required = YES; afield_opt->label = _("Arc layer"); type_opt = G_define_standard_option(G_OPT_V_TYPE); type_opt->options = "line,boundary"; type_opt->answer = "line,boundary"; type_opt->required = YES; type_opt->label = _("Arc type"); nfield_opt = G_define_standard_option(G_OPT_V_FIELD); nfield_opt->key = "nlayer"; nfield_opt->answer = "2"; nfield_opt->required = YES; nfield_opt->label = _("Node layer"); afcol = G_define_standard_option(G_OPT_DB_COLUMN); afcol->key = "afcolumn"; afcol->description = _("Arc forward/both direction(s) cost column (number)"); afcol->guisection = _("Cost"); abcol = G_define_standard_option(G_OPT_DB_COLUMN); abcol->key = "abcolumn"; abcol->description = _("Arc backward direction cost column (number)"); abcol->guisection = _("Cost"); ncol = G_define_standard_option(G_OPT_DB_COLUMN); ncol->key = "ncolumn"; ncol->description = _("Node cost column (number)"); ncol->guisection = _("Cost"); turntable_f = G_define_flag(); turntable_f->key = 't'; turntable_f->description = _("Use turntable"); turntable_f->guisection = _("Turntable"); tfield_opt = G_define_standard_option(G_OPT_V_FIELD); tfield_opt->key = "tlayer"; tfield_opt->answer = "3"; tfield_opt->label = _("Layer with turntable"); tfield_opt->description = _("Relevant only with -t flag"); tfield_opt->guisection = _("Turntable"); tucfield_opt = G_define_standard_option(G_OPT_V_FIELD); tucfield_opt->key = "tuclayer"; tucfield_opt->answer = "4"; tucfield_opt->label = _("Layer with unique categories used in turntable"); tucfield_opt->description = _("Relevant only with -t flag"); tucfield_opt->guisection = _("Turntable"); geo_f = G_define_flag(); geo_f->key = 'g'; geo_f->description = _("Use geodesic calculation for longitude-latitude locations"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); Vect_check_input_output_name(map->answer, output->answer, G_FATAL_EXIT); Cats = Vect_new_cats_struct(); Points = Vect_new_line_struct(); SPoints = Vect_new_line_struct(); type = Vect_option_to_types(type_opt); catlist = Vect_new_cat_list(); Vect_str_to_cat_list(term_opt->answer, catlist); /* Iso costs */ aiso = 1; iso = (double *)G_malloc(aiso * sizeof(double)); /* Set first iso to 0 */ iso[0] = 0; niso = 1; i = 0; while (cost_opt->answers[i]) { if (niso == aiso) { aiso += 1; iso = (double *)G_realloc(iso, aiso * sizeof(double)); } iso[niso] = atof(cost_opt->answers[i]); if (iso[niso] <= 0) G_fatal_error(_("Wrong iso cost: %f"), iso[niso]); if (iso[niso] <= iso[niso - 1]) G_fatal_error(_("Iso cost: %f less than previous"), iso[niso]); G_verbose_message(_("Iso cost %d: %f"), niso, iso[niso]); niso++; i++; } /* Should not happen: */ if (niso < 2) G_warning(_ ("Not enough costs, everything reachable falls to first band")); if (geo_f->answer) geo = 1; else geo = 0; Vect_set_open_level(2); if (Vect_open_old(&Map, map->answer, "") < 0) G_fatal_error(_("Unable to open vector map <%s>"), map->answer); afield = Vect_get_field_number(&Map, afield_opt->answer); nfield = Vect_get_field_number(&Map, nfield_opt->answer); tfield = Vect_get_field_number(&Map, tfield_opt->answer); tucfield = Vect_get_field_number(&Map, tucfield_opt->answer); /* Build graph */ if (turntable_f->answer) Vect_net_ttb_build_graph(&Map, type, afield, nfield, tfield, tucfield, afcol->answer, abcol->answer, ncol->answer, geo, 0); else Vect_net_build_graph(&Map, type, afield, nfield, afcol->answer, abcol->answer, ncol->answer, geo, 0); nnodes = Vect_get_num_nodes(&Map); nlines = Vect_get_num_lines(&Map); /* Create list of centres based on list of categories */ for (i = 1; i <= nlines; i++) { ltype = Vect_get_line_type(&Map, i); if (!(ltype & GV_POINT)) continue; Vect_read_line(&Map, Points, Cats, i); node = Vect_find_node(&Map, Points->x[0], Points->y[0], Points->z[0], 0, 0); if (!node) { G_warning(_("Point is not connected to the network")); continue; } if (!(Vect_cat_get(Cats, nfield, &cat))) continue; if (Vect_cat_in_cat_list(cat, catlist)) { Vect_net_get_node_cost(&Map, node, &n1cost); if (n1cost == -1) { /* closed */ G_warning(_("Centre at closed node (costs = -1) ignored")); } else { if (acentres == ncentres) { acentres += 1; Centers = (CENTER *) G_realloc(Centers, acentres * sizeof(CENTER)); } Centers[ncentres].cat = cat; Centers[ncentres].node = node; G_debug(2, "centre = %d node = %d cat = %d", ncentres, node, cat); ncentres++; } } } G_message(_("Number of centres: %d (nlayer %d)"), ncentres, nfield); if (ncentres == 0) G_warning(_ ("Not enough centres for selected nlayer. Nothing will be allocated.")); /* alloc and reset space for all nodes */ if (turntable_f->answer) { /* if turntable is used we are looking for lines as destinations, instead of the intersections (nodes) */ Nodes = (NODE *) G_calloc((nlines * 2 + 2), sizeof(NODE)); for (i = 2; i <= (nlines * 2 + 2); i++) { Nodes[i].centre = -1;/* NOTE: first two items of Nodes are not used */ } } else { Nodes = (NODE *) G_calloc((nnodes + 1), sizeof(NODE)); for (i = 1; i <= nnodes; i++) { Nodes[i].centre = -1; } } apnts1 = 1; pnts1 = (ISOPOINT *) G_malloc(apnts1 * sizeof(ISOPOINT)); apnts2 = 1; pnts2 = (ISOPOINT *) G_malloc(apnts2 * sizeof(ISOPOINT)); /* Fill Nodes by neares centre and costs from that centre */ for (centre = 0; centre < ncentres; centre++) { node1 = Centers[centre].node; Vect_net_get_node_cost(&Map, node1, &n1cost); G_debug(2, "centre = %d node = %d cat = %d", centre, node1, Centers[centre].cat); G_message(_("Calculating costs from centre %d..."), centre + 1); if (turntable_f->answer) for (line = 1; line <= nlines; line++) { G_debug(5, " node1 = %d line = %d", node1, line); Vect_net_get_node_cost(&Map, line, &n2cost); /* closed, left it as not attached */ if (Vect_read_line(&Map, Points, Cats, line) < 0) continue; if (Vect_get_line_type(&Map, line) != GV_LINE) continue; if (!Vect_cat_get(Cats, tucfield, &cat)) continue; for (j = 0; j < 2; j++) { if (j == 1) cat *= -1; ret = Vect_net_ttb_shortest_path(&Map, node1, 0, cat, 1, tucfield, NULL, &cost); if (ret == -1) { continue; } /* node unreachable */ /* We must add centre node costs (not calculated by Vect_net_shortest_path() ), but * only if centre and node are not identical, because at the end node cost is add later */ if (ret != 1) cost += n1cost; G_debug(5, "Arc nodes: %d %d cost: %f (x old cent: %d old cost %f", node1, line, cost, Nodes[line * 2 + j].centre, Nodes[line * 2 + j].cost); if (Nodes[line * 2 + j].centre == -1 || cost < Nodes[line * 2 + j].cost) { Nodes[line * 2 + j].cost = cost; Nodes[line * 2 + j].centre = centre; } } } else for (node2 = 1; node2 <= nnodes; node2++) { G_percent(node2, nnodes, 1); G_debug(5, " node1 = %d node2 = %d", node1, node2); Vect_net_get_node_cost(&Map, node2, &n2cost); if (n2cost == -1) { continue; } /* closed, left it as not attached */ ret = Vect_net_shortest_path(&Map, node1, node2, NULL, &cost); if (ret == -1) { continue; } /* node unreachable */ /* We must add centre node costs (not calculated by Vect_net_shortest_path() ), but * only if centre and node are not identical, because at the end node cost is add later */ if (node1 != node2) cost += n1cost; G_debug(5, "Arc nodes: %d %d cost: %f (x old cent: %d old cost %f", node1, node2, cost, Nodes[node2].centre, Nodes[node2].cost); if (Nodes[node2].centre == -1 || cost < Nodes[node2].cost) { Nodes[node2].cost = cost; Nodes[node2].centre = centre; } } } /* Write arcs to new map */ if (Vect_open_new(&Out, output->answer, Vect_is_3d(&Map)) < 0) G_fatal_error(_("Unable to create vector map <%s>"), output->answer); Vect_hist_command(&Out); G_message("Generating isolines..."); nlines = Vect_get_num_lines(&Map); for (line = 1; line <= nlines; line++) { G_percent(line, nlines, 2); ltype = Vect_read_line(&Map, Points, NULL, line); if (!(ltype & type)) { continue; } l = Vect_line_length(Points); if (l == 0) continue; if (turntable_f->answer) { centre1 = Nodes[line * 2].centre; centre2 = Nodes[line * 2 + 1].centre; s1cost = Nodes[line * 2].cost; s2cost = Nodes[line * 2 + 1].cost; n1cost = n2cost = 0; } else { Vect_get_line_nodes(&Map, line, &node1, &node2); centre1 = Nodes[node1].centre; centre2 = Nodes[node2].centre; s1cost = Nodes[node1].cost; s2cost = Nodes[node2].cost; Vect_net_get_node_cost(&Map, node1, &n1cost); Vect_net_get_node_cost(&Map, node2, &n2cost); } Vect_net_get_line_cost(&Map, line, GV_FORWARD, &e1cost); Vect_net_get_line_cost(&Map, line, GV_BACKWARD, &e2cost); G_debug(3, "Line %d : length = %f", line, l); G_debug(3, "Arc centres: %d %d (nodes: %d %d)", centre1, centre2, node1, node2); G_debug(3, " s1cost = %f n1cost = %f e1cost = %f", s1cost, n1cost, e1cost); G_debug(3, " s2cost = %f n2cost = %f e2cost = %f", s2cost, n2cost, e2cost); /* First check if arc is reachable from at least one side */ if ((centre1 != -1 && n1cost != -1 && e1cost != -1) || (centre2 != -1 && n2cost != -1 && e2cost != -1)) { /* Line is reachable at least from one side */ G_debug(3, " -> arc is reachable"); /* Add costs of node to starting costs */ s1cost += n1cost; s2cost += n2cost; e1cost /= l; e2cost /= l; /* Find points on isolines along the line in both directions, add them to array, * first point is placed at the beginning/end of line */ /* Forward */ npnts1 = 0; /* in case this direction is closed */ if (centre1 != -1 && n1cost != -1 && e1cost != -1) { /* Find iso for beginning of the line */ next_iso = 0; for (i = niso - 1; i >= 0; i--) { if (iso[i] <= s1cost) { next_iso = i; break; } } /* Add first */ pnts1[0].iso = next_iso; pnts1[0].distance = 0; npnts1++; next_iso++; /* Calculate distances for points along line */ while (next_iso < niso) { if (e1cost == 0) break; /* Outside line */ l1 = (iso[next_iso] - s1cost) / e1cost; if (l1 >= l) break; /* Outside line */ if (npnts1 == apnts1) { apnts1 += 1; pnts1 = (ISOPOINT *) G_realloc(pnts1, apnts1 * sizeof(ISOPOINT)); } pnts1[npnts1].iso = next_iso; pnts1[npnts1].distance = l1; G_debug(3, " forward %d : iso %d : distance %f : cost %f", npnts1, next_iso, l1, iso[next_iso]); npnts1++; next_iso++; } } G_debug(3, " npnts1 = %d", npnts1); /* Backward */ npnts2 = 0; if (centre2 != -1 && n2cost != -1 && e2cost != -1) { /* Find iso for beginning of the line */ next_iso = 0; for (i = niso - 1; i >= 0; i--) { if (iso[i] <= s2cost) { next_iso = i; break; } } /* Add first */ pnts2[0].iso = next_iso; pnts2[0].distance = l; npnts2++; next_iso++; /* Calculate distances for points along line */ while (next_iso < niso) { if (e2cost == 0) break; /* Outside line */ l1 = (iso[next_iso] - s2cost) / e2cost; if (l1 >= l) break; /* Outside line */ if (npnts2 == apnts2) { apnts2 += 1; pnts2 = (ISOPOINT *) G_realloc(pnts2, apnts2 * sizeof(ISOPOINT)); } pnts2[npnts2].iso = next_iso; pnts2[npnts2].distance = l - l1; G_debug(3, " backward %d : iso %d : distance %f : cost %f", npnts2, next_iso, l - l1, iso[next_iso]); npnts2++; next_iso++; } } G_debug(3, " npnts2 = %d", npnts2); /* Limit number of points by maximum costs in reverse direction, this may remove * also the first point in one direction, but not in both */ /* Forward */ if (npnts2 > 0) { for (i = 0; i < npnts1; i++) { G_debug(3, " pnt1 = %d dist1 = %f iso1 = %d max iso2 = %d", i, pnts1[i].distance, pnts1[i].iso, pnts2[npnts2 - 1].iso); if (pnts2[npnts2 - 1].iso < pnts1[i].iso) { G_debug(3, " -> cut here"); npnts1 = i; break; } } } G_debug(3, " npnts1 cut = %d", npnts1); /* Backward */ if (npnts1 > 0) { for (i = 0; i < npnts2; i++) { G_debug(3, " pnt2 = %d dist2 = %f iso2 = %d max iso1 = %d", i, pnts2[i].distance, pnts2[i].iso, pnts1[npnts1 - 1].iso); if (pnts1[npnts1 - 1].iso < pnts2[i].iso) { G_debug(3, " -> cut here"); npnts2 = i; break; } } } G_debug(3, " npnts2 cut = %d", npnts2); /* Biggest cost shoud be equal if exist (npnts > 0). Cut out overlapping segments, * this can cut only points on line but not first points */ if (npnts1 > 1 && npnts2 > 1) { while (npnts1 > 1 && npnts2 > 1) { if (pnts1[npnts1 - 1].distance >= pnts2[npnts2 - 1].distance) { /* overlap */ npnts1--; npnts2--; } else { break; } } } G_debug(3, " npnts1 2. cut = %d", npnts1); G_debug(3, " npnts2 2. cut = %d", npnts2); /* Now we have points in both directions which may not overlap, npoints in one * direction may be 0 but not both */ /* Join both arrays, iso of point is for next segment (point is at the beginning) */ /* In case npnts1 == 0 add point at distance 0 */ if (npnts1 == 0) { G_debug(3, " npnts1 = 0 -> add first at distance 0, cat = %d", pnts2[npnts2 - 1].iso); pnts1[0].iso = pnts2[npnts2 - 1].iso; /* use last point iso in reverse direction */ pnts1[0].distance = 0; npnts1++; } for (i = npnts2 - 1; i >= 0; i--) { /* Check if identical */ if (pnts1[npnts1 - 1].distance == pnts2[i].distance) continue; if (npnts1 == apnts1) { apnts1 += 1; pnts1 = (ISOPOINT *) G_realloc(pnts1, apnts1 * sizeof(ISOPOINT)); } pnts1[npnts1].iso = pnts2[i].iso - 1; /* last may be -1, but it is not used */ pnts1[npnts1].distance = pnts2[i].distance; npnts1++; } /* In case npnts2 == 0 add point at the end */ if (npnts2 == 0) { pnts1[npnts1].iso = 0; /* not used */ pnts1[npnts1].distance = l; npnts1++; } /* Create line segments. */ for (i = 1; i < npnts1; i++) { cat = pnts1[i - 1].iso + 1; G_debug(3, " segment %f - %f cat %d", pnts1[i - 1].distance, pnts1[i].distance, cat); ret = Vect_line_segment(Points, pnts1[i - 1].distance, pnts1[i].distance, SPoints); if (ret == 0) { G_warning(_ ("Cannot get line segment, segment out of line")); } else { Vect_reset_cats(Cats); Vect_cat_set(Cats, 1, cat); Vect_write_line(&Out, ltype, SPoints, Cats); } } } else { /* arc is not reachable */ G_debug(3, " -> arc is not reachable"); Vect_reset_cats(Cats); Vect_write_line(&Out, ltype, Points, Cats); } } Vect_build(&Out); /* Free, ... */ G_free(Nodes); G_free(Centers); Vect_close(&Map); Vect_close(&Out); exit(EXIT_SUCCESS); }
int main(int argc, char *argv[]) { struct Map_info In, Out; static struct line_pnts *Points; struct line_cats *Cats; struct GModule *module; /* GRASS module for parsing arguments */ struct Option *map_in, *map_out; struct Option *cat_opt, *field_opt, *where_opt, *abcol, *afcol; struct Option *iter_opt, *error_opt; struct Flag *geo_f, *add_f; int chcat, with_z; int layer, mask_type; struct varray *varray; dglGraph_s *graph; int i, geo, nnodes, nlines, j, max_cat; char buf[2000], *covered; /* initialize GIS environment */ G_gisinit(argv[0]); /* reads grass env, stores program name to G_program_name() */ /* initialize module */ module = G_define_module(); module->keywords = _("vector, network, centrality measures"); module->description = _("Computes degree, centrality, betweeness, closeness and eigenvector " "centrality measures in the network."); /* Define the different options as defined in gis.h */ map_in = G_define_standard_option(G_OPT_V_INPUT); field_opt = G_define_standard_option(G_OPT_V_FIELD); map_out = G_define_standard_option(G_OPT_V_OUTPUT); cat_opt = G_define_standard_option(G_OPT_V_CATS); cat_opt->guisection = _("Selection"); where_opt = G_define_standard_option(G_OPT_WHERE); where_opt->guisection = _("Selection"); afcol = G_define_standard_option(G_OPT_COLUMN); afcol->key = "afcolumn"; afcol->required = NO; afcol->description = _("Name of arc forward/both direction(s) cost column"); afcol->guisection = _("Cost"); abcol = G_define_standard_option(G_OPT_COLUMN); abcol->key = "abcolumn"; abcol->required = NO; abcol->description = _("Name of arc backward direction cost column"); abcol->guisection = _("Cost"); deg_opt = G_define_standard_option(G_OPT_COLUMN); deg_opt->key = "degree"; deg_opt->required = NO; deg_opt->description = _("Name of degree centrality column"); deg_opt->guisection = _("Columns"); close_opt = G_define_standard_option(G_OPT_COLUMN); close_opt->key = "closeness"; close_opt->required = NO; close_opt->description = _("Name of closeness centrality column"); close_opt->guisection = _("Columns"); betw_opt = G_define_standard_option(G_OPT_COLUMN); betw_opt->key = "betweenness"; betw_opt->required = NO; betw_opt->description = _("Name of betweenness centrality column"); betw_opt->guisection = _("Columns"); eigen_opt = G_define_standard_option(G_OPT_COLUMN); eigen_opt->key = "eigenvector"; eigen_opt->required = NO; eigen_opt->description = _("Name of eigenvector centrality column"); eigen_opt->guisection = _("Columns"); iter_opt = G_define_option(); iter_opt->key = "iterations"; iter_opt->answer = "1000"; iter_opt->type = TYPE_INTEGER; iter_opt->required = NO; iter_opt->description = _("Maximum number of iterations to compute eigenvector centrality"); error_opt = G_define_option(); error_opt->key = "error"; error_opt->answer = "0.1"; error_opt->type = TYPE_DOUBLE; error_opt->required = NO; error_opt->description = _("Cummulative error tolerance for eigenvector centrality"); geo_f = G_define_flag(); geo_f->key = 'g'; geo_f->description = _("Use geodesic calculation for longitude-latitude locations"); add_f = G_define_flag(); add_f->key = 'a'; add_f->description = _("Add points on nodes"); /* options and flags parser */ if (G_parser(argc, argv)) exit(EXIT_FAILURE); /* TODO: make an option for this */ mask_type = GV_LINE | GV_BOUNDARY; Points = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); Vect_check_input_output_name(map_in->answer, map_out->answer, GV_FATAL_EXIT); Vect_set_open_level(2); if (1 > Vect_open_old(&In, map_in->answer, "")) G_fatal_error(_("Unable to open vector map <%s>"), map_in->answer); with_z = Vect_is_3d(&In); if (0 > Vect_open_new(&Out, map_out->answer, with_z)) { Vect_close(&In); G_fatal_error(_("Unable to create vector map <%s>"), map_out->answer); } if (geo_f->answer) { geo = 1; if (G_projection() != PROJECTION_LL) G_warning(_("The current projection is not longitude-latitude")); } else geo = 0; /* parse filter option and select appropriate lines */ layer = atoi(field_opt->answer); chcat = (NetA_initialise_varray (&In, layer, mask_type, where_opt->answer, cat_opt->answer, &varray) == 1); /* Create table */ Fi = Vect_default_field_info(&Out, 1, NULL, GV_1TABLE); Vect_map_add_dblink(&Out, 1, NULL, Fi->table, "cat", Fi->database, Fi->driver); db_init_string(&sql); 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); db_init_string(&tmp); if (deg_opt->answer) append_string(&tmp, deg_opt->answer); if (close_opt->answer) append_string(&tmp, close_opt->answer); if (betw_opt->answer) append_string(&tmp, betw_opt->answer); if (eigen_opt->answer) append_string(&tmp, eigen_opt->answer); sprintf(buf, "create table %s(cat integer%s)", Fi->table, db_get_string(&tmp)); db_set_string(&sql, buf); G_debug(2, db_get_string(&sql)); if (db_execute_immediate(driver, &sql) != DB_OK) { db_close_database_shutdown_driver(driver); G_fatal_error(_("Unable to create table: '%s'"), db_get_string(&sql)); } if (db_create_index2(driver, Fi->table, "cat") != DB_OK) G_warning(_("Cannot create index")); if (db_grant_on_table (driver, Fi->table, DB_PRIV_SELECT, DB_GROUP | DB_PUBLIC) != DB_OK) G_fatal_error(_("Cannot grant privileges on table <%s>"), Fi->table); db_begin_transaction(driver); Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); Vect_net_build_graph(&In, mask_type, atoi(field_opt->answer), 0, afcol->answer, abcol->answer, NULL, geo, 0); graph = &(In.graph); nnodes = dglGet_NodeCount(graph); deg = closeness = betw = eigen = NULL; covered = (char *)G_calloc(nnodes + 1, sizeof(char)); if (!covered) G_fatal_error(_("Out of memory")); if (deg_opt->answer) { deg = (double *)G_calloc(nnodes + 1, sizeof(double)); if (!deg) G_fatal_error(_("Out of memory")); } if (close_opt->answer) { closeness = (double *)G_calloc(nnodes + 1, sizeof(double)); if (!closeness) G_fatal_error(_("Out of memory")); } if (betw_opt->answer) { betw = (double *)G_calloc(nnodes + 1, sizeof(double)); if (!betw) G_fatal_error(_("Out of memory")); } if (eigen_opt->answer) { eigen = (double *)G_calloc(nnodes + 1, sizeof(double)); if (!eigen) G_fatal_error(_("Out of memory")); } if (deg_opt->answer) { G_message(_("Computing degree centrality measure")); NetA_degree_centrality(graph, deg); } if (betw_opt->answer || close_opt->answer) { G_message(_("Computing betweenness and/or closeness centrality measure")); NetA_betweenness_closeness(graph, betw, closeness); if (closeness) for (i = 1; i <= nnodes; i++) closeness[i] /= (double)In.cost_multip; } if (eigen_opt->answer) { G_message(_("Computing eigenvector centrality measure")); NetA_eigenvector_centrality(graph, atoi(iter_opt->answer), atof(error_opt->answer), eigen); } nlines = Vect_get_num_lines(&In); G_message(_("Writing data into the table...")); G_percent_reset(); for (i = 1; i <= nlines; i++) { G_percent(i, nlines, 1); int type = Vect_read_line(&In, Points, Cats, i); if (type == GV_POINT && (!chcat || varray->c[i])) { int cat, node; if (!Vect_cat_get(Cats, layer, &cat)) continue; Vect_reset_cats(Cats); Vect_cat_set(Cats, 1, cat); Vect_write_line(&Out, type, Points, Cats); Vect_get_line_nodes(&In, i, &node, NULL); process_node(node, cat); covered[node] = 1; } } if (add_f->answer && !chcat) { max_cat = 0; for (i = 1; i <= nlines; i++) { Vect_read_line(&In, NULL, Cats, i); for (j = 0; j < Cats->n_cats; j++) if (Cats->cat[j] > max_cat) max_cat = Cats->cat[j]; } max_cat++; for (i = 1; i <= nnodes; i++) if (!covered[i]) { Vect_reset_cats(Cats); Vect_cat_set(Cats, 1, max_cat); NetA_add_point_on_node(&In, &Out, i, Cats); process_node(i, max_cat); max_cat++; } } db_commit_transaction(driver); db_close_database_shutdown_driver(driver); G_free(covered); if (deg) G_free(deg); if (closeness) G_free(closeness); if (betw) G_free(betw); if (eigen) G_free(eigen); Vect_build(&Out); Vect_close(&In); Vect_close(&Out); exit(EXIT_SUCCESS); }
void print_info(const struct Map_info *Map) { int i; char line[100]; char tmp1[100], tmp2[100]; struct bound_box box; divider('+'); if (Vect_maptype(Map) & (GV_FORMAT_OGR | GV_FORMAT_OGR_DIRECT)) { /* for OGR format print also datasource and layer */ sprintf(line, "%-17s%s", _("OGR layer:"), Vect_get_ogr_layer_name(Map)); printline(line); sprintf(line, "%-17s%s", _("OGR datasource:"), Vect_get_ogr_dsn_name(Map)); printline(line); } else { sprintf(line, "%-17s%s", _("Name:"), Vect_get_name(Map)); printline(line); sprintf(line, "%-17s%s", _("Mapset:"), Vect_get_mapset(Map)); printline(line); } sprintf(line, "%-17s%s", _("Location:"), G_location()); printline(line); sprintf(line, "%-17s%s", _("Database:"), G_gisdbase()); printline(line); sprintf(line, "%-17s%s", _("Title:"), Vect_get_map_name(Map)); printline(line); sprintf(line, "%-17s1:%d", _("Map scale:"), Vect_get_scale(Map)); printline(line); if (Vect_maptype(Map) & (GV_FORMAT_OGR | GV_FORMAT_OGR_DIRECT)) { sprintf(line, "%-17s%s (%s)", _("Map format:"), Vect_maptype_info(Map), Vect_get_ogr_format_info(Map)); } else { sprintf(line, "%-17s%s", _("Map format:"), Vect_maptype_info(Map)); } printline(line); sprintf(line, "%-17s%s", _("Name of creator:"), Vect_get_person(Map)); printline(line); sprintf(line, "%-17s%s", _("Organization:"), Vect_get_organization(Map)); printline(line); sprintf(line, "%-17s%s", _("Source date:"), Vect_get_map_date(Map)); printline(line); divider('|'); sprintf(line, " %s: %s (%s: %i)", _("Type of map"), _("vector"), _("level"), Vect_level(Map)); printline(line); if (Vect_level(Map) > 0) { printline(""); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of points:"), Vect_get_num_primitives(Map, GV_POINT), _("Number of centroids:"), Vect_get_num_primitives(Map, GV_CENTROID)); printline(line); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of lines:"), Vect_get_num_primitives(Map, GV_LINE), _("Number of boundaries:"), Vect_get_num_primitives(Map, GV_BOUNDARY)); printline(line); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of areas:"), Vect_get_num_areas(Map), _("Number of islands:"), Vect_get_num_islands(Map)); printline(line); if (Vect_is_3d(Map)) { sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of faces:"), Vect_get_num_primitives(Map, GV_FACE), _("Number of kernels:"), Vect_get_num_primitives(Map, GV_KERNEL)); printline(line); sprintf(line, " %-24s%-9d %-22s%-9d", _("Number of volumes:"), Vect_get_num_volumes(Map), _("Number of holes:"), Vect_get_num_holes(Map)); printline(line); } printline(""); sprintf(line, " %-24s%s", _("Map is 3D:"), Vect_is_3d(Map) ? _("Yes") : _("No")); printline(line); sprintf(line, " %-24s%-9d", _("Number of dblinks:"), Vect_get_num_dblinks(Map)); printline(line); } printline(""); /* this differs from r.info in that proj info IS taken from the map here, not the location settings */ /* Vect_get_proj_name() and _zone() are typically unset?! */ if (G_projection() == PROJECTION_UTM) sprintf(line, " %s: %s (%s %d)", _("Projection:"), Vect_get_proj_name(Map), _("zone"), Vect_get_zone(Map)); else sprintf(line, " %s: %s", _("Projection"), Vect_get_proj_name(Map)); printline(line); printline(""); Vect_get_map_box(Map, &box); G_format_northing(box.N, tmp1, G_projection()); G_format_northing(box.S, tmp2, G_projection()); sprintf(line, " %c: %17s %c: %17s", 'N', tmp1, 'S', tmp2); printline(line); G_format_easting(box.E, tmp1, G_projection()); G_format_easting(box.W, tmp2, G_projection()); sprintf(line, " %c: %17s %c: %17s", 'E', tmp1, 'W', tmp2); printline(line); if (Vect_is_3d(Map)) { format_double(box.B, tmp1); format_double(box.T, tmp2); sprintf(line, " %c: %17s %c: %17s", 'B', tmp1, 'T', tmp2); printline(line); } printline(""); format_double(Vect_get_thresh(Map), tmp1); sprintf(line, " %s: %s", _("Digitization threshold"), tmp1); printline(line); sprintf(line, " %s:", _("Comment")); printline(line); sprintf(line, " %s", Vect_get_comment(Map)); printline(line); divider('+'); fprintf(stdout, "\n"); }
int main(int argc, char *argv[]) { struct GModule *module; struct Option *in_opt, *layer_opt, *out_opt, *length_opt, *units_opt, *vertices_opt; struct Map_info In, Out; struct line_pnts *Points, *Points2; struct line_cats *Cats; int line, nlines, layer; double length = -1; int vertices = 0; double (*line_length) (); int latlon = 0; G_gisinit(argv[0]); module = G_define_module(); G_add_keyword(_("vector")); G_add_keyword(_("geometry")); module->description = _("Splits vector lines to shorter segments."); in_opt = G_define_standard_option(G_OPT_V_INPUT); layer_opt = G_define_standard_option(G_OPT_V_FIELD_ALL); out_opt = G_define_standard_option(G_OPT_V_OUTPUT); length_opt = G_define_option(); length_opt->key = "length"; length_opt->type = TYPE_DOUBLE; length_opt->required = NO; length_opt->multiple = NO; length_opt->description = _("Maximum segment length"); units_opt = G_define_option(); units_opt->key = "units"; units_opt->type = TYPE_STRING; units_opt->required = NO; units_opt->multiple = NO; units_opt->options = "meters,kilometers,feet,miles,nautmiles"; units_opt->answer = "meters"; units_opt->description = _("Length units"); vertices_opt = G_define_option(); vertices_opt->key = "vertices"; vertices_opt->type = TYPE_INTEGER; vertices_opt->required = NO; vertices_opt->multiple = NO; vertices_opt->description = _("Maximum number of vertices in segment"); if (G_parser(argc, argv)) exit(EXIT_FAILURE); if ((length_opt->answer && vertices_opt->answer) || !(length_opt->answer || vertices_opt->answer)) G_fatal_error(_("Use either length or vertices")); line_length = NULL; if (length_opt->answer) { length = atof(length_opt->answer); if (length <= 0) G_fatal_error(_("Length must be positive but is %g"), length); /* convert length to meters */ if (strcmp(units_opt->answer, "meters") == 0) /* do nothing */ ; else if (strcmp(units_opt->answer, "kilometers") == 0) length *= FROM_KILOMETERS; else if (strcmp(units_opt->answer, "feet") == 0) length *= FROM_FEET; else if (strcmp(units_opt->answer, "miles") == 0) length *= FROM_MILES; else if (strcmp(units_opt->answer, "nautmiles") == 0) length *= FROM_NAUTMILES; else G_fatal_error(_("Unknown unit %s"), units_opt->answer); /* set line length function */ if ((latlon = (G_projection() == PROJECTION_LL)) == 1) line_length = Vect_line_geodesic_length; else { double factor; line_length = Vect_line_length; /* convert length to map units */ if ((factor = G_database_units_to_meters_factor()) == 0) G_fatal_error(_("Can not get projection units")); else { /* meters to units */ length = length / factor; } } G_verbose_message(_("length in %s: %g"), (latlon ? "meters" : "map units"), length); } if (vertices_opt->answer) { vertices = atoi(vertices_opt->answer); if (vertices < 2) G_fatal_error(_("Number of vertices must be at least 2")); } Vect_set_open_level(2); Vect_open_old2(&In, in_opt->answer, "", layer_opt->answer); layer = Vect_get_field_number(&In, layer_opt->answer); Vect_open_new(&Out, out_opt->answer, Vect_is_3d(&In)); Vect_copy_head_data(&In, &Out); Vect_hist_copy(&In, &Out); Vect_hist_command(&Out); Vect_copy_tables(&In, &Out, layer); Points = Vect_new_line_struct(); Points2 = Vect_new_line_struct(); Cats = Vect_new_cats_struct(); nlines = Vect_get_num_lines(&In); for (line = 1; line <= nlines; line++) { int ltype; G_percent(line, nlines, 1); if (!Vect_line_alive(&In, line)) continue; ltype = Vect_read_line(&In, Points, Cats, line); if (layer != -1 && !Vect_cat_get(Cats, layer, NULL)) continue; if (ltype & GV_LINES) { if (length > 0) { double l, from, to, step; l = line_length(Points); if (l <= length) { Vect_write_line(&Out, ltype, Points, Cats); } else { int n, i; n = ceil(l / length); if (latlon) l = Vect_line_length(Points); step = l / n; from = 0.; for (i = 0; i < n; i++) { int ret; double x, y, z; if (i == n - 1) { to = l; /* to be sure that it goes to end */ } else { to = from + step; } ret = Vect_line_segment(Points, from, to, Points2); if (ret == 0) { G_warning(_("Unable to make line segment: %f - %f (line length = %f)"), from, to, l); continue; } /* To be sure that the coordinates are identical */ if (i > 0) { Points2->x[0] = x; Points2->y[0] = y; Points2->z[0] = z; } if (i == n - 1) { Points2->x[Points2->n_points - 1] = Points->x[Points->n_points - 1]; Points2->y[Points2->n_points - 1] = Points->y[Points->n_points - 1]; Points2->z[Points2->n_points - 1] = Points->z[Points->n_points - 1]; } Vect_write_line(&Out, ltype, Points2, Cats); /* last point */ x = Points2->x[Points2->n_points - 1]; y = Points2->y[Points2->n_points - 1]; z = Points2->z[Points2->n_points - 1]; from += step; } } } else { int start = 0; /* number of coordinates written */ while (start < Points->n_points - 1) { int i, v; Vect_reset_line(Points2); for (i = 0; i < vertices; i++) { v = start + i; if (v == Points->n_points) break; Vect_append_point(Points2, Points->x[v], Points->y[v], Points->z[v]); } Vect_write_line(&Out, ltype, Points2, Cats); start = v; } } } else { Vect_write_line(&Out, ltype, Points, Cats); } } Vect_close(&In); Vect_build(&Out); Vect_close(&Out); exit(EXIT_SUCCESS); }
void print_topo(const struct Map_info *Map) { int with_z; long nprimitives; nprimitives = 0; with_z = Vect_is_3d(Map); nprimitives += Vect_get_num_primitives(Map, GV_POINT); nprimitives += Vect_get_num_primitives(Map, GV_LINE); nprimitives += Vect_get_num_primitives(Map, GV_BOUNDARY); nprimitives += Vect_get_num_primitives(Map, GV_CENTROID); if (with_z) { nprimitives += Vect_get_num_primitives(Map, GV_FACE); nprimitives += Vect_get_num_primitives(Map, GV_KERNEL); } fprintf(stdout, "nodes=%d\n", Vect_get_num_nodes(Map)); fflush(stdout); fprintf(stdout, "points=%d\n", Vect_get_num_primitives(Map, GV_POINT)); fflush(stdout); fprintf(stdout, "lines=%d\n", Vect_get_num_primitives(Map, GV_LINE)); fflush(stdout); fprintf(stdout, "boundaries=%d\n", Vect_get_num_primitives(Map, GV_BOUNDARY)); fflush(stdout); fprintf(stdout, "centroids=%d\n", Vect_get_num_primitives(Map, GV_CENTROID)); fflush(stdout); fprintf(stdout, "areas=%d\n", Vect_get_num_areas(Map)); fflush(stdout); fprintf(stdout, "islands=%d\n", Vect_get_num_islands(Map)); fflush(stdout); if (with_z) { fprintf(stdout, "faces=%d\n", Vect_get_num_primitives(Map, GV_FACE)); fflush(stdout); fprintf(stdout, "kernels=%d\n", Vect_get_num_primitives(Map, GV_KERNEL)); fflush(stdout); fprintf(stdout, "volumes=%d\n", Vect_get_num_primitives(Map, GV_VOLUME)); fflush(stdout); fprintf(stdout, "holes=%d\n", Vect_get_num_holes(Map)); fflush(stdout); } fprintf(stdout, "primitives=%ld\n", nprimitives); fflush(stdout); fprintf(stdout, "map3d=%d\n", Vect_is_3d(Map) ? 1 : 0); fflush(stdout); }