123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425 |
- /****************************************************************
- *
- * MODULE: v.edit
- *
- * PURPOSE: Editing vector map.
- *
- * AUTHOR(S): GRASS Development Team
- * Wolf Bergenheim, Jachym Cepicky, Martin Landa
- *
- * COPYRIGHT: (C) 2006-2010 by the GRASS Development Team
- *
- * This program is free software under the GNU General
- * Public License (>=v2). Read the file COPYING that
- * comes with GRASS for details.
- *
- * TODO: 3D support (done for move and vertexmove)
- ****************************************************************/
- #include "global.h"
- 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, print, 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();
- 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 (G_strcasecmp(params.in->answer, "-") == 0 ||
- (action_mode != MODE_CREATE && params.in->answer == NULL)) {
- ascii = stdin;
- }
- else if (params.in->answer) {
- ascii = fopen(params.in->answer, "r");
- if (ascii == NULL) {
- G_fatal_error(_("Unable to open ASCII file <%s>"),
- params.in->answer);
- }
- }
- 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 (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 (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:
- print = 0; /* do not print id's */
- break;
- case MODE_ADD:
- print = 0;
- 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 */
- Vedit_snap_lines(&Map, BgMap, nbgmaps, List_added, thresh[THRESH_SNAP], snap == SNAP ? 0 : 1); /* snap to vertex ? */
- }
- 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:
- print = 1;
- 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:
- print = 0;
- 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);
- }
- }
|