[GRASS-SVN] r30374 - grass/branches/releasebranch_6_3/vector/v.edit
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Feb 27 10:10:07 EST 2008
Author: martinl
Date: 2008-02-27 10:10:07 -0500 (Wed, 27 Feb 2008)
New Revision: 30374
Added:
grass/branches/releasebranch_6_3/vector/v.edit/a2b.c
grass/branches/releasebranch_6_3/vector/v.edit/args.c
grass/branches/releasebranch_6_3/vector/v.edit/description.html
grass/branches/releasebranch_6_3/vector/v.edit/global.h
grass/branches/releasebranch_6_3/vector/v.edit/main.c
grass/branches/releasebranch_6_3/vector/v.edit/max_distance.c
grass/branches/releasebranch_6_3/vector/v.edit/proto.h
grass/branches/releasebranch_6_3/vector/v.edit/select.c
grass/branches/releasebranch_6_3/vector/v.edit/snap.c
Removed:
grass/branches/releasebranch_6_3/vector/v.edit/cmd/
grass/branches/releasebranch_6_3/vector/v.edit/lib/
Modified:
grass/branches/releasebranch_6_3/vector/v.edit/Makefile
Log:
v.edit backported from trunk (lib moved to lib/vector/vedit)
Modified: grass/branches/releasebranch_6_3/vector/v.edit/Makefile
===================================================================
--- grass/branches/releasebranch_6_3/vector/v.edit/Makefile 2008-02-27 08:45:08 UTC (rev 30373)
+++ grass/branches/releasebranch_6_3/vector/v.edit/Makefile 2008-02-27 15:10:07 UTC (rev 30374)
@@ -1,13 +1,12 @@
MODULE_TOPDIR = ../..
-SUBDIRS1 = cmd
+PGM = v.edit
-SUBDIRS = lib $(SUBDIRS1)
+LIBES = $(VEDITLIB) $(VECTLIB) $(GISLIB)
+DEPENDENCIES= $(VEDITDEP) $(VECTDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
-include $(MODULE_TOPDIR)/include/Make/Dir.make
+include $(MODULE_TOPDIR)/include/Make/Module.make
-default: parsubdirs
-
-clean: cleansubdirs
-
-$(SUBDIRS1): lib
+default: cmd
Copied: grass/branches/releasebranch_6_3/vector/v.edit/a2b.c (from rev 30279, grass/branches/releasebranch_6_3/vector/v.edit/cmd/a2b.c)
===================================================================
--- grass/branches/releasebranch_6_3/vector/v.edit/a2b.c (rev 0)
+++ grass/branches/releasebranch_6_3/vector/v.edit/a2b.c 2008-02-27 15:10:07 UTC (rev 30374)
@@ -0,0 +1,330 @@
+/****************************************************************
+ *
+ * MODULE: v.edit
+ *
+ * PURPOSE: Editing vector map.
+ *
+ * AUTHOR(S): GRASS Development Team
+ * Wolf Bergenheim, Jachym Cepicky, Martin Landa
+ *
+ * COPYRIGHT: (C) 2006-2008 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
+ ****************************************************************/
+
+#include <string.h>
+#include "global.h"
+
+#define BUFFSIZE 128
+
+/**
+ \brief Add new vector features to the vector map
+
+ Input format is GRASS ASCII vector, the code adopted from v.in.ascii
+
+ \param[in] ascii file containing definition of new vector features
+ \param[in] Map vector map
+ \param[out] List list of added features (if given)
+
+ \return number of added features
+*/
+int asc_to_bin(FILE *ascii , struct Map_info *Map, struct ilist *List)
+{
+ char ctype;
+ char buff[BUFFSIZE];
+ double *xarray;
+ double *yarray;
+ double *zarray;
+ double *x, *y, *z;
+ int i, n_points, n_coors, n_cats;
+ int type, newline;
+ int alloc_points;
+ int end_of_file;
+ int catn;
+ int cat;
+ int nlines;
+
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+
+ nlines = 0;
+
+ Points = Vect_new_line_struct ();
+ Cats = Vect_new_cats_struct ();
+
+ if (List) {
+ Vect_reset_list(List);
+ }
+
+ end_of_file = 0 ;
+ /*alloc_points = 1000 ; */
+ alloc_points = 1;
+ xarray = (double *) G_calloc(alloc_points, sizeof(double)) ;
+ yarray = (double *) G_calloc(alloc_points, sizeof(double)) ;
+ zarray = (double *) G_calloc(alloc_points, sizeof(double)) ;
+
+ while( G_getl2(buff,BUFFSIZE-1,ascii) != 0 )
+ {
+ n_cats=0;
+ if (buff[0] == '\0') {
+ G_debug(3, "a2b: skipping blank line");
+ continue;
+ }
+
+ if ( sscanf(buff, "%1c%d%d", &ctype, &n_coors, &n_cats) < 2 || n_coors < 0 || n_cats < 0 ) {
+ if (ctype == '#') {
+ G_debug(2, "a2b: skipping commented line");
+ continue;
+ }
+ G_warning (_("Error reading ASCII file: '%s'"), buff);
+ return -1;
+ }
+ if (ctype == '#') {
+ G_debug(2, "a2b: Skipping commented line");
+ continue;
+ }
+
+ switch(ctype){
+ case 'A':
+ type = GV_BOUNDARY ;
+ break ;
+ case 'B':
+ type = GV_BOUNDARY ;
+ break ;
+ case 'C':
+ type = GV_CENTROID ;
+ break ;
+ case 'L':
+ type = GV_LINE ;
+ break ;
+ case 'P':
+ type = GV_POINT ;
+ break ;
+ case 'F':
+ type = GV_FACE ;
+ break ;
+ case 'K':
+ type = GV_KERNEL ;
+ break ;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'l':
+ case 'p':
+ type = 0; /* dead -> ignore */
+ break;
+ default:
+ G_warning (_("Error reading ASCII file: '%s'"), buff) ;
+ return -1;
+ }
+ G_debug(5, "feature type = %d", type);
+
+ n_points = 0 ;
+ x = xarray ;
+ y = yarray ;
+ z = zarray ;
+
+ /* Collect the points */
+ for(i = 0; i < n_coors; i++)
+ {
+ if ( G_getl2 (buff, BUFFSIZE-1, ascii) == 0 ) {
+ G_warning (_("End of ASCII file reached before end of coordinates")) ;
+ return -1;
+ }
+ if (buff[0] == '\0') {
+ G_debug(3, "a2b: skipping blank line while reading vertices");
+ i--;
+ continue;
+ }
+
+ *z=0;
+ if ( sscanf(buff, "%lf%lf%lf", x, y, z) < 2 ) {
+ G_warning (_("Error reading ASCII file: '%s'"), buff) ;
+ return -1;
+ }
+ G_debug( 5, "coor in: %s -> x = %f y = %f z = %f", G_chop(buff), *x, *y, *z);
+
+ n_points++;
+ x++;
+ y++;
+ z++;
+
+ if (n_points >= alloc_points)
+ {
+ alloc_points = n_points + 1000 ;
+ xarray = (double *) G_realloc((void *)xarray, alloc_points * sizeof(double) );
+ yarray = (double *) G_realloc((void *)yarray, alloc_points * sizeof(double) );
+ zarray = (double *) G_realloc((void *)zarray, alloc_points * sizeof(double) );
+ x = xarray + n_points ;
+ y = yarray + n_points ;
+ z = zarray + n_points ;
+ }
+ }
+
+ /* Collect the cats */
+ for( i=0; i<n_cats; i++)
+ {
+ if ( G_getl2(buff,BUFFSIZE-1,ascii) == 0 ) {
+ G_warning (_("End of ascii file reached before end of categories")) ;
+ return -1;
+ }
+ if (buff[0] == '\0') {
+ G_debug(3, "a2b: skipping blank line while reading category info");
+ i--;
+ continue;
+ }
+
+ if ( sscanf(buff, "%u%u", &catn, &cat) != 2 ) {
+ G_warning (_("Error reading categories: '%s'"), buff) ;
+ return -1;
+ }
+ Vect_cat_set ( Cats, catn, cat );
+ }
+
+ /* Allocation is handled for line_pnts */
+ if (0 > Vect_copy_xyz_to_pnts (Points, xarray, yarray, zarray, n_points))
+ G_fatal_error(_("Out of memory"));
+
+ if ( type > 0 ) {
+ newline = Vect_write_line ( Map, type, Points, Cats );
+ if (List) {
+ Vect_list_append(List, newline);
+ }
+ nlines++;
+
+ Vect_reset_cats ( Cats );
+ }
+ }
+
+ return nlines;
+}
+
+/**
+ \brief Read header of input file
+
+ \param[in] dascii file containing definition of vector features to be added
+ \param[in] Map vector map
+
+ \return 0
+*/
+int
+read_head ( FILE * dascii, struct Map_info *Map )
+{
+ char buff[1024];
+ char *ptr;
+
+ for (;;)
+ {
+ if (0 == G_getl2(buff, sizeof(buff) -1, dascii))
+ return 0;
+
+ /* Last line of header */
+ if (strncmp (buff, "VERTI:", 6) == 0)
+ return 0;
+
+ if (!(ptr = G_index (buff, ':')))
+ G_fatal_error(_("Unexpected data in vector head: '%s'"), buff);
+
+ ptr++; /* Search for the start of text */
+ while (*ptr == ' ')
+ ptr++;
+
+ if (strncmp (buff, "ORGANIZATION:", 12) == 0)
+ Vect_set_organization ( Map, ptr );
+ else if (strncmp (buff, "DIGIT DATE:", 11) == 0)
+ Vect_set_date ( Map, ptr );
+ else if (strncmp (buff, "DIGIT NAME:", 11) == 0)
+ Vect_set_person ( Map, ptr );
+ else if (strncmp (buff, "MAP NAME:", 9) == 0)
+ Vect_set_map_name ( Map, ptr );
+ else if (strncmp (buff, "MAP DATE:", 9) == 0)
+ Vect_set_map_date ( Map, ptr );
+ else if (strncmp (buff, "MAP SCALE:", 10) == 0)
+ Vect_set_scale ( Map, atoi (ptr) );
+ else if (strncmp (buff, "OTHER INFO:", 11) == 0)
+ Vect_set_comment ( Map, ptr );
+ else if (strncmp (buff, "ZONE:", 5) == 0 || strncmp (buff, "UTM ZONE:", 9) == 0)
+ Vect_set_zone ( Map, atoi (ptr) );
+ else if (strncmp (buff, "WEST EDGE:", 10) == 0) {}
+ else if (strncmp (buff, "EAST EDGE:", 10) == 0) {}
+ else if (strncmp (buff, "SOUTH EDGE:", 11) == 0) {}
+ else if (strncmp (buff, "NORTH EDGE:", 11) == 0) {}
+ else if (strncmp (buff, "MAP THRESH:", 11) == 0)
+ Vect_set_thresh ( Map, atof (ptr) );
+ else
+ {
+ G_warning(_("Unknown keyword '%s' in vector head"), buff);
+ }
+ }
+ /* NOTREACHED */
+}
+
+/**
+ \brief Close lines (boudaries)
+
+ Using threshold distance (-1 for no limit)
+
+ \param[in] Map vector map
+ \param[in] ltype vector feature type (line | boundary)
+ \param[in] thresh threshold distance
+
+ \return number of modified features
+*/
+int close_lines(struct Map_info *Map, int ltype, double thresh)
+{
+ int nlines, line, type, nlines_modified, newline;
+ int npoints;
+ double *x, *y, *z;
+ double dist;
+
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+
+ nlines_modified = 0;
+
+ Vect_build_partial (Map, GV_BUILD_BASE, NULL);
+ nlines = Vect_get_num_lines (Map);
+
+ for (line = 1; line <= nlines; line++) {
+ if (!Vect_line_alive (Map, line))
+ continue;
+
+ type = Vect_read_line(Map, Points, Cats, line);
+
+ if (!(type & ltype))
+ continue;
+
+ npoints = Points -> n_points - 1;
+ x = Points -> x;
+ y = Points -> y;
+ z = Points -> z;
+
+ dist = Vect_points_distance (x[npoints], y[npoints], z[npoints],
+ x[0], y[0], z[0], WITHOUT_Z);
+
+ if (dist > 0 && (thresh < 0.0 || dist <= thresh)) {
+ Vect_line_delete_point (Points, npoints);
+ Vect_append_point (Points, x[0], y[0], z[0]);
+
+ newline = Vect_rewrite_line (Map, line, type, Points, Cats);
+ if (newline < 0) {
+ G_warning(_("Unable to rewrite line %d"), line);
+ return -1;
+ }
+ nlines_modified++;
+ }
+ }
+
+ Vect_destroy_line_struct(Points);
+ Vect_destroy_cats_struct(Cats);
+
+ return nlines_modified;
+}
Copied: grass/branches/releasebranch_6_3/vector/v.edit/args.c (from rev 30279, grass/branches/releasebranch_6_3/vector/v.edit/cmd/args.c)
===================================================================
--- grass/branches/releasebranch_6_3/vector/v.edit/args.c (rev 0)
+++ grass/branches/releasebranch_6_3/vector/v.edit/args.c 2008-02-27 15:10:07 UTC (rev 30374)
@@ -0,0 +1,367 @@
+/****************************************************************
+ *
+ * MODULE: v.edit
+ *
+ * PURPOSE: Editing vector map.
+ *
+ * AUTHOR(S): GRASS Development Team
+ * Wolf Bergenheim, Jachym Cepicky, Martin Landa
+ *
+ * COPYRIGHT: (C) 2006-2008 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
+ ****************************************************************/
+
+#include "global.h"
+
+/**
+ \brief Parser stuff
+
+ \param[in] argc number of arguments
+ \param[in] argv arguments array
+ \param[in] params GRASS paramenters
+ \param[out] action mode selected tool
+
+ \return 1
+*/
+int parser(int argc, char* argv[], struct GParams *params,
+ enum mode *action_mode)
+{
+ /* parameters */
+ params -> map = G_define_standard_option(G_OPT_V_MAP);
+ params -> map -> description = _("Name of vector map to edit");
+
+ params -> fld = G_define_standard_option(G_OPT_V_FIELD);
+ params -> fld->guisection = _("Query");
+
+ params -> type = G_define_standard_option(G_OPT_V_TYPE);
+ params -> type->answer = "point,line,boundary,centroid";
+ params -> type->options = "point,line,boundary,centroid";
+ params -> type->guisection = _("Query");
+
+ params -> tool = G_define_option();
+ params -> tool->key = "tool";
+ params -> tool->type = TYPE_STRING;
+ params -> tool->required = YES;
+ params -> tool->multiple = NO;
+ params -> tool->description = _("Tool");
+ params -> tool->descriptions = _("create;"
+ "Create new (empty) vector map;"
+ "add;"
+ "Add new features to existing vector map;"
+ "delete;"
+ "Delete selected features from vector map;"
+ "move;"
+ "Move selected features in vector map;"
+ "vertexmove;"
+ "Move vertex of selected vector lines;"
+ "vertexdel;"
+ "Remove vertex from selected vector lines;"
+ "vertexadd;"
+ "Add new vertex to selected vector lines;"
+ "merge;"
+ "Merge selected vector lines;"
+ "break;"
+ "Break/split vector lines;"
+ "select;"
+ "Select lines and print their ID's;"
+ "catadd;"
+ "Set new categories to selected vector features "
+ "for defined layer;"
+ "catdel;"
+ "Delete categories from selected vector features "
+ "for defined layer;"
+ "copy;"
+ "Copy selected features;"
+ "snap;"
+ "Snap vector features in given threshold;"
+ "flip;"
+ "Flip direction of selected vector lines;"
+ "connect;"
+ "Connect two lines;"
+ "zbulk;"
+ "Z bulk-labeling (automated assignment of z coordinate to "
+ "vector lines);"
+ "chtype;"
+ "Change feature type (point<->centroid, line<->boundary)");
+ params -> tool->options = "create,add,delete,copy,move,flip,catadd,catdel,"
+ "merge,break,snap,connect,chtype,"
+ "vertexadd,vertexdel,vertexmove,zbulk,select";
+
+ params -> in = G_define_standard_option (G_OPT_F_INPUT);
+ params -> in -> required = NO;
+ params -> in -> label = _("ASCII file to be converted to binary vector map");
+ params -> in -> description = _("If not given (or \"-\") reads from standard input");
+ params -> in -> guisection = _("Input");
+
+ params -> move = G_define_option();
+ params -> move->key = "move";
+ params -> move->key_desc = "x,y";
+ params -> move->type = TYPE_DOUBLE;
+ params -> move->required = NO;
+ params -> move->multiple = NO;
+ params -> move->description = _("Difference in x,y direction for moving feature or vertex");
+
+ params -> maxdist = G_define_option();
+ params -> maxdist->key = "thresh";
+ params -> maxdist->type = TYPE_DOUBLE;
+ params -> maxdist->required = NO;
+ params -> maxdist->multiple = NO;
+ params -> maxdist->label = _("Threshold distance");
+ params -> maxdist->description = _("'-1' for threshold based on the current resolution settings");
+ params -> maxdist->answer = "-1";
+
+ params -> id = G_define_standard_option(G_OPT_V_CATS);
+ params -> id->required = NO;
+ params -> id->key = "ids";
+ params -> id->label = _("ID values");
+ params -> id->guisection = _("Query");
+
+
+ params -> cat = G_define_standard_option(G_OPT_V_CATS);
+ params -> cat->required = NO;
+ params -> cat->guisection = _("Query");
+
+ params -> coord = G_define_option();
+ params -> coord->key = "coords";
+ params -> coord->key_desc = "x,y";
+ params -> coord->type = TYPE_DOUBLE;
+ params -> coord->required = NO;
+ params -> coord->multiple = YES;
+ params -> coord->description = _("List of point coordinates");
+ params -> coord->guisection = _("Query");
+
+ params -> bbox = G_define_option();
+ params -> bbox->key = "bbox";
+ params -> bbox->key_desc = "x1,y1,x2,y2";
+ params -> bbox->type = TYPE_DOUBLE;
+ params -> bbox->required = NO;
+ params -> bbox->multiple = NO;
+ params -> bbox->description = _("Bounding box for selecting features");
+ params -> bbox->guisection = _("Query");
+
+ params -> poly = G_define_option();
+ params -> poly->key = "polygon";
+ params -> poly->key_desc = "x,y";
+ params -> poly->type = TYPE_DOUBLE;
+ params -> poly->required = NO;
+ params -> poly->multiple = YES;
+ params -> poly->description = _("Polygon for selecting features");
+ params -> poly->guisection = _("Query");
+
+ params -> where = G_define_standard_option(G_OPT_WHERE);
+ params -> where->guisection = _("Query");
+
+ params -> query = G_define_option();
+ params -> query -> key = "query";
+ params -> query ->type = TYPE_STRING;
+ params -> query -> options = "length,dangle";
+ params -> query -> label = _("Query tool");
+ params -> query -> description = _("For 'shorter' use negative threshold value, "
+ "positive value for 'longer'");
+ params -> query -> descriptions = _("length;Select only lines or boudaries shorter"
+ "/longer than threshold distance;"
+ "dangle;Select dangles shorter/longer than "
+ "threshold distance");
+ params -> query->guisection = _("Query");
+
+ params -> bmaps = G_define_standard_option(G_OPT_V_MAPS);
+ params -> bmaps -> key = "bgmap";
+ params -> bmaps -> required = NO;
+ params -> bmaps -> description = _("Name of background vector map(s)");
+
+ params -> snap = G_define_option();
+ params -> snap -> key = "snap";
+ params -> snap ->type = TYPE_STRING;
+ params -> snap -> options = "no,node,vertex";
+ params -> snap -> description = _("Snap added or modified features in the given threshold to the nearest existing feature");
+ params -> snap -> descriptions = _("no;Not apply snapping;"
+ "node;Snap only to node;"
+ "vertex;Allow snapping also to vertex");
+ params -> snap -> answer = "no";
+
+ params -> zbulk = G_define_option();
+ params -> zbulk -> key = "zbulk";
+ params -> zbulk ->type = TYPE_DOUBLE;
+ params -> zbulk -> key_desc = "value,step";
+ params -> zbulk -> label = _("Starting value and step for z bulk-labeling");
+ params -> zbulk -> description = _("Pair: value,step (e.g. 1100,10)");
+
+ /* flags */
+ params -> reverse = G_define_flag();
+ params -> reverse -> key = 'r';
+ params -> reverse -> description = _("Reverse selection");
+
+ /*
+ params -> print = G_define_flag();
+ params -> print -> key = 'i';
+ params -> print -> description = _("Print ID's of edited features");
+ */
+
+ params -> close = G_define_flag();
+ params -> close -> key = 'c';
+ params -> close -> description = _("Close added boundaries (using threshold distance)");
+
+ params -> header = G_define_flag();
+ params -> header -> key = 'n';
+ params -> header -> description = _("Do not expect header of input data");
+ params -> header -> guisection = _("Input");
+
+ params -> topo = G_define_flag();
+ params -> topo -> key = 't';
+ params -> topo -> description = _("Do not build topology");
+
+ params -> move_first = G_define_flag();
+ params -> move_first -> key = '1';
+ params -> move_first -> description = _("Modify only first found feature in bounding box");
+
+ /*
+ params -> boundary = G_define_flag();
+ params -> boundary -> key = 'b';
+ params -> boundary -> description = _("Assign cats to boundaries too");
+
+ params -> print_cat = G_define_flag();
+ params -> print_cat -> key = 'c';
+ params -> print_cat -> description = _("Print category numbers instead of ID's");
+ */
+
+ if(G_parser(argc, argv))
+ exit (EXIT_FAILURE);
+
+ /* check for polygon param */
+ if (params -> poly -> answers != NULL) {
+ int i = 0;
+ while (params -> poly -> answers[i++])
+ ;
+
+ if (i < 6)
+ G_fatal_error (_("Polygon must have at least 3 coordinate pairs"));
+ }
+
+ /*
+ check that the given arguments makes sense together
+ */
+ if(G_strcasecmp (params -> tool -> answer, "create") == 0) {
+ *action_mode = MODE_CREATE;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "add") == 0) {
+ *action_mode = MODE_ADD;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "delete")==0) {
+ *action_mode = MODE_DEL;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "move") == 0) {
+ *action_mode = MODE_MOVE;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "merge") == 0) {
+ *action_mode = MODE_MERGE;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "break") == 0) {
+ *action_mode = MODE_BREAK;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "connect") == 0) {
+ *action_mode = MODE_CONNECT;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "vertexadd") == 0) {
+ *action_mode = MODE_VERTEX_ADD;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "vertexdel") ==0 ) {
+ *action_mode = MODE_VERTEX_DELETE;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "vertexmove") == 0) {
+ *action_mode = MODE_VERTEX_MOVE;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "select") == 0) {
+ *action_mode = MODE_SELECT;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "catadd") == 0) {
+ *action_mode = MODE_CATADD;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "catdel") == 0) {
+ *action_mode = MODE_CATDEL;
+ }
+ else if(G_strcasecmp(params -> tool -> answer, "copy") == 0) {
+ *action_mode = MODE_COPY;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "snap") == 0) {
+ *action_mode = MODE_SNAP;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "flip") == 0) {
+ *action_mode = MODE_FLIP;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "zbulk") == 0) {
+ *action_mode = MODE_ZBULK;
+ }
+ else if(G_strcasecmp (params -> tool -> answer, "chtype") == 0) {
+ *action_mode = MODE_CHTYPE;
+ }
+ else
+ {
+ G_fatal_error (_("Operation '%s' not implemented"),
+ params -> tool -> answer);
+ }
+
+ if((*action_mode != MODE_CREATE && *action_mode != MODE_ADD && *action_mode != MODE_ZBULK) &&
+ (params -> cat -> answers == NULL) &&
+ (params -> coord -> answers == NULL) &&
+ (params -> poly -> answers == NULL) &&
+ (params -> id -> answers == NULL) &&
+ (params -> bbox -> answers == NULL) &&
+ (params -> where -> answer == NULL) &&
+ (params -> query -> answer == NULL)) {
+ G_fatal_error (_("At least one option from %s must be specified"),
+ "cats, ids, coords, bbox, polygon, where, query");
+ }
+
+ if (*action_mode == MODE_MOVE ||
+ *action_mode == MODE_VERTEX_MOVE)
+ {
+ if(params -> move -> answers == NULL) {
+ G_fatal_error (_("Tool %s requires option %s"),
+ params -> tool -> answer,
+ params -> move -> key);
+ }
+ }
+
+ if (*action_mode == MODE_VERTEX_ADD ||
+ *action_mode == MODE_VERTEX_DELETE ||
+ *action_mode == MODE_VERTEX_MOVE)
+ {
+ if(params -> coord -> answers == NULL) {
+ G_fatal_error (_("Tool %s requires option %s"),
+ params -> tool -> answer,
+ params -> coord -> key);
+ }
+ }
+
+ if (*action_mode == MODE_CATADD ||
+ *action_mode == MODE_CATDEL)
+ {
+ if (params -> cat -> answers == NULL)
+ {
+ G_fatal_error (_("Tool %s requires option %s"),
+ params -> tool -> answer,
+ params -> cat -> key);
+ }
+ }
+
+ if (*action_mode == MODE_ZBULK) {
+ if (params -> bbox -> answers == NULL) {
+ G_fatal_error (_("Tool %s requires option %s"),
+ params -> tool -> answer,
+ params -> bbox -> key);
+ }
+ if (params -> zbulk -> answers == NULL) {
+ G_fatal_error (_("Tool %s requires option %s"),
+ params -> tool -> answer,
+ params -> zbulk -> key);
+ }
+ }
+
+ return 1;
+}
Copied: grass/branches/releasebranch_6_3/vector/v.edit/description.html (from rev 30279, grass/branches/releasebranch_6_3/vector/v.edit/cmd/description.html)
===================================================================
--- grass/branches/releasebranch_6_3/vector/v.edit/description.html (rev 0)
+++ grass/branches/releasebranch_6_3/vector/v.edit/description.html 2008-02-27 15:10:07 UTC (rev 30374)
@@ -0,0 +1,430 @@
+<h2>DESCRIPTION</h2>
+
+The module <em>v.edit</em> allows the user to edit a vector map
+via command line interface.
+
+<p>
+<em>v.edit</em> supports only "simple" vector features: points,
+centroids, lines and boundaries. Currently, only 2D vector features
+(except of tool <b>zbulk</b>) are supported.
+
+<p>
+Provides editing features' geometry. Attribute data connected to the
+vector map are not modified at all.
+
+<p>
+Vector features can be selected either by internal <b>id</b>,
+category number <b>cats</b>, coordinates <b>coords</b>, bounding
+box <b>bbox</b>, <b>polygon</b>, <b>where</b> statement (attribute
+data) or by <b>query</b>. Selecting features by
+coordinates is affected by the current 2D resolution. It can be
+changed using threshold distance <b>thresh</b>. The options
+are <em>orthogonal</em>, i.e. can be used in various combinations. For
+example:
+
+<div class="code"><pre>
+v.edit map=roads tool=select \
+ coord=599505,4921010,603389.0625,4918292.1875 \
+ thresh=10000 where="label='interstate'"
+</pre></div>
+
+selects all features (and prints their id's to standard output)
+covered by two bounding boxes (center at 599505,4921010 and
+603389.0625,4918292.1875, size 2*10000) with attribute
+label='interstate'.
+
+<h2>NOTES</h2>
+
+If no vector features are selected or the flag <b>-t</b> is
+used, topology is not build at the end.
+
+<h2>USAGE</h2>
+
+<h3>Feature selection</h3>
+
+Vector features can be selected in several ways:
+<ul>
+ <li><b>ids</b> - using internal (unique) feature id's</li>
+ <li><b>cats</b> - using category numbers</li>
+ <li><b>coords</b> - using x,y coordinate pairs (center of bounding
+ box, size defined by <b>thresh</b>)</li>
+ <li><b>bbox</b> - using bounding box</li>
+ <li><b>polygon</b> - using polygon (at least 3 coordinate pairs have to be set)</li>
+ <li><b>where</b> - using where statement (attribute data)
+ <li><b>query</b> - special query (e.g. minimal vector line length)
+</ul>
+
+Additional parameters for vector feature specification are:
+<ul>
+ <li><b>layer</b> - layer number (currently used only
+ with <b>cats</b> or <b>where</b> option)</li>
+ <li><b>thresh</b> - threshold distance used for selecting vector
+ features by coordinates</li>
+</ul>
+
+<h3>Tool description</h3>
+
+<ul>
+ <li><b>create</b> - Create new (empty) vector map
+ (see <em><a href="v.in.ascii.html">v.in.ascii</a></em>). Optionally vector
+ features (in GRASS ASCII standard format) can be read from
+ standard input (<b>input=-</b>) or from the text file given by
+ the <b>input</b> option.</li>
+
+ <li><b>add</b> - Add new vector features (defined in GRASS ASCII
+ standard format) to existing vector map. Features can be read from
+ standard input or from the given text file (<b>input</b>
+ option). If no header is given, the <b>-n</b> flag must be
+ used. Added features can be snapped (based on <b>snap</b>
+ parameter) using threshold distance <b>thresh</b>.</li>
+
+ <li><b>delete</b> - Delete selected vector features from existing
+ vector map.</li>
+
+ <li><b>copy</b> - Make identical copy of selected vector
+ features. If background map <b>bgmap</b> is given copy features
+ from background map, not from currently modified vector map.</li>
+
+ <li><b>move</b> - Move selected features of existing vector map
+ relatively to their current location. This tool requires
+ <b>move</b> option. The option defines coordinates of the movement
+ direction. Moved features can be snapped (based on <b>snap</b>
+ parameter) using threshold distance <b>thresh</b>.</li>
+
+ <li><b>flip</b> - Flip direction of selected vector lines
+ (lines or boundaries).</li>
+
+ <li><b>catadd</b> - Add new layer category(ies) to selected vector
+ feature(s). Category can be later used for new database
+ entry.</li>
+
+ <li><b>catdel</b> - Delete layer category(ies) of selected vector
+ feature(s).</li>
+
+ <li><b>merge</b> - Merge (at least two) selected vector lines or
+ boundaries. The geometry of the merged vector lines can be
+ changed. If the second line from two selected lines is in opposite
+ direction to the first, it will be flipped. See also
+ module <em><a href="v.build.polylines.html">v.build.polylines</a></em>.</li>
+
+ <li><b>break</b> - Split given vector line or boundary into two
+ lines on location given by <b>coords</b>. If <b>coords</b> not
+ given, breaks all selected lines at each intersection (based
+ on <em><a href="v.clean.html">v.clean</a></em>, tool=break).</li>
+
+ <li><b>snap</b> - Snap vector features in given threshold. See
+ also module <em><a href="v.clean.html">v.clean</a></em>. Note that this
+ tool supports only snapping to nodes. Parameters <b>snap</b> and
+ <b>bgmap</b> are ignored.</li>
+
+ <li><b>connect</b> - Connect selected lines or boundaries, the
+ first given line is connected to the second one. The second line
+ is broken if necessary. The lines are connected regarding
+ threshold distance <b>thresh</b>.</li>
+
+ <li><b>chtype</b> - Change feature type of selected geometry
+ objects. Points are converted to centroids, centroids to points,
+ lines to boundaries and boundaries to lines.
+
+ <li><b>vertexadd</b> - Add vertex(ces) to the given vector lines
+ or boundaries. Location of the new vertex is given by <b>coord</b>
+ option. If <b>-1</b> is given only first found line or boundary in bounding
+ box is modified.</li>
+
+ <li><b>vertexdel</b> - Remove vertex(ces) specified by
+ <b>coords</b> option. If <b>-1</b> is given only first found line or
+ boundary in bounding box is modified.</li>
+
+ <li><b>vertexmove</b> - Move vertex(ces) specified
+ by <b>coords</b> option. Direction of the movement is specified by
+ the <b>move</b> option. If <b>-1</b> is given only first found line or
+ boundary in bounding box is modified. Moved vertex can be snapped
+ (based on <b>snap</b> parameter) using threshold
+ distance <b>thresh</b>.</li>
+
+ <li><b>zbulk</b> - Assign z coordinate to 3D vector lines in given
+ bounding box. The first found line will get z coordinate based on
+ value given by <b>zbulk</b> parameter. Z coordinate of other
+ selected lines will be increased by step given by <b>zbulk</b>
+ parameter. This tool strictly requires <b>bbox</b>
+ and <b>zbulk</b> parameter. Also input vector map must be 3D.</li>
+
+ <li><b>select</b> - Print comma separated list of selected line
+ id's. No editing is done.
+</ul>
+
+<h2>EXAMPLES</h2>
+
+<h3>Create new vector map</h3>
+
+Create new (empty) vector map:
+
+<div class="code"><pre>
+v.edit tool=create map=vectmap
+</pre></div>
+
+Create new vector map and read data from file 'roads.txt':
+
+<div class="code"><pre>
+v.out.ascii in=roads format=standard > roads.txt;
+v.edit tool=create map=vectmap input=roads.txt
+</pre></div>
+
+or alternatively
+
+<div class="code"><pre>
+cat roads.txt | v.edit tool=create map=vectmap input=-
+</pre></div>
+
+<h3>Add new features to existing vector map</h3>
+
+Add point to the vector map (without header):
+
+<div class="code"><pre>
+echo "P 1 1
+ 640794 214874
+ 1 1" | v.edit -n tool=add map=vectmap
+</pre></div>
+
+Add new features read from standard input:
+
+<div class="code"><pre>
+v.out.ascii in=railroads format=standard | v.edit tool=add map=vectmap
+</pre></div>
+
+<h3>Delete selected features from vector map layer</h3>
+
+Remove all vector features with category number 1 or 2:
+
+<div class="code"><pre>
+v.edit tool=delete map=roads cats=1,2
+</pre></div>
+
+Remove all vector features except of those with category number 1 or 2
+(reverse selection):
+
+<div class="code"><pre>
+v.edit -r tool=delete map=roads cats=1,2
+</pre></div>
+
+Remove features with category 1 or 2 located on coordinates
+600952.625,4926107 (bounding box based on the current 2D resolution):
+
+<div class="code"><pre>
+g.region -d;
+v.edit tool=delete map=roads cats=1,2 coords=600952.625,4926107
+</pre></div>
+
+Remove all features with category 1 and 2 covered by two bounding boxes
+(center coordinates 592542.892,4924766.996 and 603389.062,4918292.187,
+size 2000 map units):
+
+<div class="code"><pre>
+v.edit map=roads tool=delete \
+ coord=592542.892,4924766.996,603389.062,4918292.187 \
+ thresh=1000 cat=1,2
+</pre></div>
+
+<h3>Copy selected features from background map</h3>
+
+Copy all features with category number 1 from background map:
+
+<div class="code"><pre>
+v.edit map=roads tool=copy bgmap=archsites cat=1
+</pre></div>
+
+<h3>Move features</h3>
+
+Move feature (vector point) located on coordinates 602580,4918480 to
+coordinates 603580,4919480:
+
+<div class="code"><pre>
+v.edit tool=move map=archsites coord=602580,4918480 th=1e-2 move=1000,1000
+</pre></div>
+
+Move all features with category 1 1000 map units to the west and 1000
+map units to the south. Moved features snap to nodes in threshold
+distance 10 map units:
+
+<div class="code"><pre>
+v.edit tool=move map=roads cat=1 move=1000,-1000 snap=node thresh=10
+</pre></div>
+
+Move all features defined by bounding box
+601530,4921560,602520,4922310 (W,S,E,N) 1000 map units to the
+east and 1000 map units to the north:
+
+<div class="code"><pre>
+v.edit tool=move map=roads bbox=601530,4921560,602520,4922310 move=-1000,1000
+</pre></div>
+
+<h3>Flip direction of vector lines</h3>
+
+Flip direction of all vector lines:
+
+<div class="code"><pre>
+v.edit tool=flip map=streams cats=1-9999 type=line
+</pre></div>
+
+<h3>Add / delete layer category number</h3>
+
+Add new layer/category 2/1, 2/3, 2/4, 2/5 to features covered by given polygon:
+
+<div class="code"><pre>
+v.edit tool=catadd map=roads \
+ polygon=599877.75,4925088.375,597164.812,4922524.5,601338.562,4920914.625 \
+ layer=2 cat=1,3-5
+</pre></div>
+
+Delete layer/category 1/1, line id 1:
+
+<div class="code"><pre>
+v.edit tool=catdel map=roads id=1 cats=5
+</pre></div>
+
+<h3>Merge lines</h3>
+
+Merge two lines with given category number:
+
+<div class="code"><pre>
+v.edit map=roads tool=merge cat=4
+</pre></div>
+
+<h3>Split line on given point</h3>
+
+Split line id 810 on coordinates 604268,4923570 in threshold 50 map units:
+
+<div class="code"><pre>
+v.edit map=roads tool=break coords=604268,4923570 id=810 thresh=50
+</pre></div>
+
+<h3>Break selected lines at each intersection</h3>
+
+Break selected lines (with category number 1) at each intersection:
+
+<div class="code"><pre>
+v.edit map=roads tool=break cat=1
+</pre></div>
+
+<h3>Snap lines</h3>
+
+Snap all lines using threshold distance 20 map units:
+
+<div class="code"><pre>
+v.edit map=roads id=1-9999 tool=snap thresh=20 type=line
+</pre></div>
+
+<h3>Connect lines</h3>
+
+Connect line id 48 to line id 565:
+
+<div class="code"><pre>
+v.edit map=roads tool=connect id=48,565
+</pre></div>
+
+Connect line id 48 to line id 565; line id 60 to line id
+50. Maximum threshold distance is 700 map units:
+
+<div class="code"><pre>
+v.edit map=roads tool=connect id=48,565,60,50 thresh=1000
+</pre></div>
+
+<h3>Add vertex</h3>
+
+Add new vertex to the line located at 600952,4926107, threshold is
+set to 1 map unit:
+
+<div class="code"><pre>
+v.edit tool=vertexadd map=roads coords=600952,4926107 thresh=1
+</pre></div>
+
+<h3>Delete vertices</h3>
+
+Delete vertex located at 593191.608,4925684.849 (threshold set to 0.1 map units).
+Modify only lines with category 1:
+
+<div class="code"><pre>
+v.edit tool=vertexdel map=roads coord=593191.608,4925684.849 \
+ thresh=1-e1 cats=1
+</pre></div>
+
+<h3>Move vertices</h3>
+
+Move vertices located at 604441,4921088 (threshold set to 100 map units).
+Modify only lines with categories 1-10:
+
+<div class="code"><pre>
+v.edit tool=vertexmove map=roads cats=1-10 coord=604441,4921088 \
+ thresh=100 move=1000,1000
+</pre></div>
+
+<h3>Select features and print their id's</h3>
+
+Print id's of selected features, e.g.:
+
+<div class="code"><pre>
+v.edit map=soils at PERMANENT tool=select \
+ bbox=595733.8125,4919781.75,598536.1875,4917396.75 --q
+</pre></div>
+
+Example with <em><a href="d.vect.html">d.vect</a></em>:
+
+<div class="code"><pre>
+d.erase;
+d.vect roads;
+d.vect -i map=roads cats=`v.edit map=roads tool=select \
+ coord=592542.89243878,4924766.99622811,603389.0625,4918292.1875 \
+ thresh=1000 --q` col=red
+</pre></div>
+
+Select all lines shorter (or equal) than 10 map units:
+
+<div class="code"><pre>
+v.edit map=roads tool=select query=length thresh=-10
+</pre></div>
+
+Select from given bounding box all lines longer then 200 map units:
+
+<div class="code"><pre>
+v.edit map=roads tool=select bbox=598260,4919730,605100,4926240 query=length thresh=1000
+</pre></div>
+
+<h3>Fix height of contours</h3>
+
+Intput vector map contains 2D lines representing contours. Height can
+be assign to the contours using tool <b>zbulk</b>. First of all 2D
+lines need to be converted to 3D lines:
+
+<div class="code"><pre>
+v.extrude input=line2 output=line3 height=0 type=line
+</pre></div>
+
+All lines which intersect with the line given by coordinates will be
+modified. First found line will get height 1000 map units, height of
+other selected lines will be increased by 10 map units.
+
+<div class="code"><pre>
+v.edit a2 tool=zbulk bbox=586121.25049368,4911970.21547109,603092.60466035,4927071.25713776 \
+ zbulk=1000,10
+</pre></div>
+
+
+<h2>SEE ALSO</h2>
+
+<em>
+<a HREF="v.in.ascii.html">v.in.ascii</a>,
+<a HREF="v.info.html">v.info</a>,
+<a HREF="v.build.html">v.build</a>,
+<a HREF="v.clean.html">v.clean</a>,
+<a HREF="v.digit.html">v.digit</a>,
+<a HREF="v.extrude.html">v.extrude</a>
+</em>
+
+<h2>AUTHOR</h2>
+
+Original author: Wolf Bergenheim - independent developer<br>
+Various updates: Jachym Cepicky, Mendel University of Agriculture and Forestry in Brno, Czech Republic<br>
+Martin Landa, FBK-irst (formerly ITC-irst), Trento, Italy
+
+<p>
+<i>Last changed: $Date$</i>
Copied: grass/branches/releasebranch_6_3/vector/v.edit/global.h (from rev 30279, grass/branches/releasebranch_6_3/vector/v.edit/cmd/global.h)
===================================================================
--- grass/branches/releasebranch_6_3/vector/v.edit/global.h (rev 0)
+++ grass/branches/releasebranch_6_3/vector/v.edit/global.h 2008-02-27 15:10:07 UTC (rev 30374)
@@ -0,0 +1,51 @@
+#ifndef _V_EDIT_GLOBAL
+# define _V_EDIT_GLOBAL
+
+# include <stdio.h>
+# include <stdlib.h>
+# include <grass/gis.h>
+# include <grass/Vect.h>
+# include <grass/glocale.h>
+# include <grass/vedit.h>
+
+# define SEP "----------------------------------"
+
+enum mode {
+ /* geometry of features is not changed */
+ MODE_CREATE, /* create new vector map */
+ MODE_ADD, /* add new vector features */
+ MODE_DEL, /* delete new vector features */
+ MODE_COPY, /* copy vector features */
+ MODE_MOVE, /* move vector features */
+ MODE_FLIP, /* flip direction of vector lines */
+ MODE_CATADD, /* add layer category */
+ MODE_CATDEL, /* delete layer category */
+ /* geometry of features changed */
+ MODE_MERGE, /* merge vector lines */
+ MODE_BREAK, /* break (split) vector lines */
+ MODE_CONNECT, /* connect *two* lines */
+ MODE_SNAP, /* snap vector lines */
+ /* geometry of feature changed */
+ MODE_VERTEX_ADD, /* add vertex */
+ MODE_VERTEX_DELETE, /* delete vertex(ces) */
+ MODE_VERTEX_MOVE, /* move vertex(ces) */
+ /* only print selected features */
+ MODE_SELECT,
+ /* */
+ MODE_NONE,
+ /* z bulk-labeling */
+ MODE_ZBULK,
+ /* change feature type (point<->centroid, line<->boundary) */
+ MODE_CHTYPE,
+};
+
+struct GParams {
+ struct Option *map, *in, *maxdist, *tool,
+ *coord, *cat, *move, *bbox, *fld,
+ *poly, *type, *id, *where, *bmaps, *snap, *query, *zbulk;
+ struct Flag *header, *topo, *close, *reverse, *move_first;
+};
+
+# include "proto.h"
+
+#endif
Copied: grass/branches/releasebranch_6_3/vector/v.edit/main.c (from rev 30279, grass/branches/releasebranch_6_3/vector/v.edit/cmd/main.c)
===================================================================
--- grass/branches/releasebranch_6_3/vector/v.edit/main.c (rev 0)
+++ grass/branches/releasebranch_6_3/vector/v.edit/main.c 2008-02-27 15:10:07 UTC (rev 30374)
@@ -0,0 +1,436 @@
+/****************************************************************
+ *
+ * MODULE: v.edit
+ *
+ * PURPOSE: Editing vector map.
+ *
+ * AUTHOR(S): GRASS Development Team
+ * Wolf Bergenheim, Jachym Cepicky, Martin Landa
+ *
+ * COPYRIGHT: (C) 2006-2008 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
+ ****************************************************************/
+
+#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 */
+ char *mapset;
+ enum mode action_mode;
+ FILE *ascii;
+
+ int i;
+ int move_first, snap;
+ int ret, print, layer;
+ double move_x, move_y, thresh;
+
+ 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->keywords = _("vector, editing, 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) {
+ /* 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 */
+ mapset = G_find_vector2 (params.map -> answer, G_mapset());
+ if ( mapset == NULL ) {
+ G_fatal_error (_("Vector map <%s> not found in the current mapset"),
+ params.map -> answer);
+ }
+ else if (action_mode == MODE_ADD) { /* write */
+ ret = Vect_open_update (&Map, params.map -> answer, mapset);
+ }
+ else { /* read-only -- select features */
+ ret = Vect_open_old (&Map, params.map -> answer, mapset);
+ }
+
+ 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;
+ char *bmap;
+ while (params.bmaps->answers[i]) {
+ bmap = params.bmaps->answers[i];
+ mapset = G_find_vector2 (bmap, "");
+ if (mapset == NULL) {
+ G_fatal_error (_("Vector map <%s> not found"),
+ bmap);
+ }
+
+ if (strcmp(G_fully_qualified_name((const char*) params.map -> answer, (const char*) G_mapset()),
+ G_fully_qualified_name((const char*) bmap, (const char*) mapset)) == 0) {
+ G_fatal_error (_("Unable to open vector map <%s> as the backround map. "
+ "It is given as vector map to be edited."),
+ bmap);
+ }
+ nbgmaps++;
+ BgMap = (struct Map_info**) G_realloc ((void *) 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, mapset) == -1) {
+ G_fatal_error (_("Unable to open vector map <%s>"),
+ G_fully_qualified_name(bmap, mapset));
+ }
+ G_verbose_message(_("Background vector map <%s> registered"),
+ G_fully_qualified_name(bmap, mapset));
+ i++;
+ }
+ }
+
+ layer = atoi (params.fld -> answer);
+ if (params.query->answer) { /* allow negative threshold value (shorter / longer) */
+ thresh = atof (params.maxdist -> answer);
+ }
+ else {
+ thresh = max_distance(atof (params.maxdist -> answer));
+ }
+ 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();
+ if (action_mode == MODE_COPY && BgMap && BgMap[0]) {
+ List = select_lines(BgMap[0], action_mode,
+ ¶ms,
+ List);
+ }
+ else {
+ List = select_lines(&Map, action_mode,
+ ¶ms,
+ 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_update (&Map, params.map -> answer, G_mapset());
+ }
+ }
+
+ /* 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)
+ read_head(ascii, &Map);
+ struct ilist *List_added;
+ List_added = Vect_new_list();
+ ret = asc_to_bin(ascii, &Map, List_added);
+ G_message(_("%d features added"), ret);
+ if (ret > 0) {
+ if (snap != NO_SNAP) { /* apply snapping */
+ Vedit_snap_lines(&Map, BgMap, nbgmaps,
+ List_added,
+ thresh,
+ snap == SNAP ? 0 : 1); /* snap to vertex ? */
+ }
+ if (params.close -> answer) { /* close boundaries */
+ int nclosed;
+ nclosed = close_lines(&Map, GV_BOUNDARY, thresh);
+ G_message (_("%d lines 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]);
+ ret = Vedit_move_lines(&Map, BgMap, nbgmaps,
+ List,
+ move_x, move_y, 0.0, snap, thresh); /* TODO: 3D */
+ 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]);
+ ret = Vedit_move_vertex(&Map, BgMap, nbgmaps,
+ List,
+ coord, thresh,
+ move_x, move_y, 0.0, /* TODO: 3D */
+ move_first, snap);
+ G_message(_("%d vertices moved"), ret);
+ break;
+ case MODE_VERTEX_ADD:
+ ret = Vedit_add_vertex(&Map, List,
+ coord, thresh);
+ G_message(_("%d vertices added"), ret);
+ break;
+ case MODE_VERTEX_DELETE:
+ ret = Vedit_remove_vertex(&Map, List,
+ coord, thresh);
+ G_message(_("%d vertices removed"), ret);
+ break;
+ case MODE_BREAK:
+ if (params.coord->answer) {
+ ret = Vedit_split_lines(&Map, List,
+ coord, thresh, NULL);
+ }
+ else {
+ ret = Vect_break_lines_list(&Map, List,
+ GV_LINES, NULL, NULL);
+ }
+ G_message(_("%d lines broken"), ret);
+ break;
+ case MODE_CONNECT:
+ ret = Vedit_connect_lines(&Map, List,
+ thresh);
+ 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:
+ ret = snap_lines(&Map, List, thresh);
+ 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: {
+ int npoints, nlines, ncentroids, nboundaries;
+ ret = Vedit_chtype_lines(&Map, List,
+ &npoints, &ncentroids,
+ &nlines, &nboundaries);
+
+ if (ret > 0) {
+ if (npoints > 0) {
+ G_message(_("%d points converted to centroids"),
+ npoints);
+ }
+ if (ncentroids > 0) {
+ G_message(_("%d centroids converted to points"),
+ ncentroids);
+ }
+ if (nlines > 0) {
+ G_message(_("%d lines converted to boundaries"),
+ nlines);
+ }
+ if (nboundaries > 0) {
+ G_message(_("%d boundaries converted to lines"),
+ nboundaries);
+ }
+ }
+ else {
+ G_message(_("No feature modified"));
+ }
+ break;
+ }
+ default:
+ G_warning(_("Operation not implemented"));
+ ret = -1;
+ break;
+ }
+
+ /*
+ if (print && ret > 0) {
+ for (i = 0; i < Vect_get_num_updated_lines(&Map); i++) {
+ if (i > 0)
+ fprintf (stdout, ",");
+ fprintf (stdout, "%d", Vect_get_updated_line(&Map, i));
+ }
+ if (Vect_get_num_updated_lines(&Map) > 0)
+ fprintf (stdout, "\n");
+ fflush (stdout);
+ }
+ */
+
+ 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, NULL);
+ if (G_verbose() > G_verbose_min())
+ Vect_build (&Map, stderr);
+ else
+ Vect_build (&Map, NULL);
+ }
+
+ 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);
+ }
+}
Copied: grass/branches/releasebranch_6_3/vector/v.edit/max_distance.c (from rev 30279, grass/branches/releasebranch_6_3/vector/v.edit/cmd/max_distance.c)
===================================================================
--- grass/branches/releasebranch_6_3/vector/v.edit/max_distance.c (rev 0)
+++ grass/branches/releasebranch_6_3/vector/v.edit/max_distance.c 2008-02-27 15:10:07 UTC (rev 30374)
@@ -0,0 +1,92 @@
+/****************************************************************
+ *
+ * MODULE: v.edit
+ *
+ * PURPOSE: Editing vector map.
+ *
+ * AUTHOR(S): GRASS Development Team
+ * Wolf Bergenheim, Jachym Cepicky, Martin Landa
+ *
+ * COPYRIGHT: (C) 2006-2008 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
+ ****************************************************************/
+
+#include "global.h"
+
+/**
+ \brief Set distance based on the current resolution
+
+ This code comes from v.what/main.c
+
+ \param[in] maxdistance max distance
+
+ \return result max distance
+*/
+double max_distance(double maxdistance)
+{
+ struct Cell_head window;
+
+ double ew_dist1, ew_dist2, ns_dist1, ns_dist2;
+ double xres, yres, maxd;
+
+ if (maxdistance < 0.0) {
+ G_get_window (&window);
+
+ ew_dist1 = G_distance(window.east, window.north, window.west, window.north);
+ /* EW Dist at South Edge */
+ ew_dist2 = G_distance(window.east, window.south, window.west, window.south);
+ /* NS Dist at East edge */
+ ns_dist1 = G_distance(window.east, window.north, window.east, window.south);
+ /* NS Dist at West edge */
+ ns_dist2 = G_distance(window.west, window.north, window.west, window.south);
+
+ xres = ((ew_dist1 + ew_dist2) / 2) / window.cols;
+ yres = ((ns_dist1 + ns_dist2) / 2) / window.rows;
+
+ if (xres > yres)
+ maxd = xres;
+ else
+ maxd = yres;
+
+ G_important_message (_("Threshold distance set to %g map units (based on 2D resolution)"), maxd);
+ }
+ else {
+ maxd = maxdistance;
+ }
+
+ G_debug (3, "max_distance(): threshold is %g", maxd);
+
+ return maxd;
+}
+
+/**
+ \brief Creates bounding box (polygon)
+
+ Based on center point; size (2 * maxdist)
+
+ \param[in] east,north coordinates of center
+ \param[in] maxdist size of bounding box
+ \param[out] result bounding box
+
+ \return
+*/
+void coord2bbox (double east, double north, double maxdist,
+ struct line_pnts *box)
+{
+ /* TODO: 3D */
+ Vect_reset_line(box);
+
+ Vect_append_point(box, east - maxdist, north - maxdist, 0);
+ Vect_append_point(box, east + maxdist, north - maxdist, 0);
+ Vect_append_point(box, east + maxdist, north + maxdist, 0);
+ Vect_append_point(box, east - maxdist, north + maxdist, 0);
+ Vect_append_point(box, box->x[0], box->y[0], box->z[0]);
+
+ return;
+}
Copied: grass/branches/releasebranch_6_3/vector/v.edit/proto.h (from rev 30279, grass/branches/releasebranch_6_3/vector/v.edit/cmd/proto.h)
===================================================================
--- grass/branches/releasebranch_6_3/vector/v.edit/proto.h (rev 0)
+++ grass/branches/releasebranch_6_3/vector/v.edit/proto.h 2008-02-27 15:10:07 UTC (rev 30374)
@@ -0,0 +1,51 @@
+#ifndef _V_EDIT_PROTO
+# define _V_EDIT_PROTO
+
+/* args.c */
+int parser(int, char* [], struct GParams *, enum mode *);
+
+/* a2b.c */
+int asc_to_bin(FILE *, struct Map_info *, struct ilist *);
+int read_head ( FILE *, struct Map_info *);
+int close_lines(struct Map_info *, int, double);
+
+/* select.c */
+int print_selected(struct ilist *);
+struct ilist* select_lines(struct Map_info *, enum mode,
+ struct GParams *,
+ struct ilist *);
+int sel_by_cat(struct Map_info *, struct cat_list*,
+ int, int, char *,
+ struct ilist *);
+int sel_by_coordinates(struct Map_info *,
+ int, struct line_pnts *, double,
+ struct ilist *);
+int sel_by_bbox(struct Map_info *,
+ int, double, double, double, double,
+ struct ilist *);
+int sel_by_polygon(struct Map_info *,
+ int, struct line_pnts *,
+ struct ilist *);
+int sel_by_id(struct Map_info *,
+ int, char *,
+ struct ilist *);
+int sel_by_where(struct Map_info *,
+ int, int, char *,
+ struct ilist *);
+int reverse_selection(struct Map_info *, int, struct ilist **);
+int sel_by_query(struct Map_info *,
+ int, int, double, const char *,
+ struct ilist*);
+
+/* snap.c */
+int snap_lines(struct Map_info *,
+ struct ilist *, double);
+int snap_line(struct Map_info *,
+ int, int, double);
+
+/* max_distance.c */
+double max_distance (double);
+void coord2bbox (double, double, double,
+ struct line_pnts *);
+
+#endif /* _V_EDIT_PROTO */
Copied: grass/branches/releasebranch_6_3/vector/v.edit/select.c (from rev 30279, grass/branches/releasebranch_6_3/vector/v.edit/cmd/select.c)
===================================================================
--- grass/branches/releasebranch_6_3/vector/v.edit/select.c (rev 0)
+++ grass/branches/releasebranch_6_3/vector/v.edit/select.c 2008-02-27 15:10:07 UTC (rev 30374)
@@ -0,0 +1,630 @@
+/****************************************************************
+ *
+ * MODULE: v.edit
+ *
+ * PURPOSE: Editing vector map.
+ *
+ * AUTHOR(S): GRASS Development Team
+ * Wolf Bergenheim, Jachym Cepicky, Martin Landa
+ *
+ * COPYRIGHT: (C) 2006-2008 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
+ ****************************************************************/
+
+#include <grass/dbmi.h>
+#include "global.h"
+
+static char first_selection = 1;
+static int merge_lists (struct ilist*, struct ilist*);
+
+/**
+ \brief Select vector features
+
+ \param[in] Map vector map
+ \param[in] action_mode tool
+ \param[in] params GRASS parameters
+ \param[in] List list of selected features
+
+ \return list of newly selected features
+*/
+struct ilist *select_lines(struct Map_info *Map, enum mode action_mode,
+ struct GParams *params,
+ struct ilist *List)
+{
+ int layer, type;
+ double thresh;
+
+ layer = atoi (params -> fld -> answer);
+ type = Vect_option_to_types (params -> type);
+ thresh = atof (params -> maxdist -> answer);
+
+ /* select by id's */
+ if (params -> id -> answer != NULL) {
+ sel_by_id(Map,
+ type, params -> id -> answer,
+ List);
+ }
+
+ /* select by category (ignore tools catdel and catadd) */
+ if((action_mode != MODE_CATADD && action_mode != MODE_CATDEL) &&
+ params -> cat -> answer != NULL) {
+ sel_by_cat(Map, NULL,
+ layer, type, params -> cat -> answer,
+ List);
+ }
+
+ /* select by coordinates (+threshold) */
+ if (params -> coord -> answer != NULL) {
+ int i;
+ double east, north;
+ struct line_pnts *coords;
+
+ coords = Vect_new_line_struct();
+ i = 0;
+ while (params->coord->answers[i]) {
+ east = atof(params->coord->answers[i]);
+ north = atof(params->coord->answers[i+1]);
+ Vect_append_point(coords, east, north, 0.0);
+ i += 2;
+ }
+
+ sel_by_coordinates(Map,
+ type, coords, thresh,
+ List);
+
+ Vect_destroy_line_struct(coords);
+ }
+
+ /* select by bbox */
+ if (params -> bbox -> answer != NULL) {
+ struct line_pnts *bbox;
+ double x1, y1, x2, y2;
+
+ bbox = Vect_new_line_struct();
+
+ x1 = atof(params->bbox->answers[0]);
+ y1 = atof(params->bbox->answers[1]);
+ x2 = atof(params->bbox->answers[2]);
+ y2 = atof(params->bbox->answers[3]);
+
+ Vect_append_point(bbox, x1, y1, -PORT_DOUBLE_MAX);
+ Vect_append_point(bbox, x2, y1, PORT_DOUBLE_MAX);
+ Vect_append_point(bbox, x2, y2, -PORT_DOUBLE_MAX);
+ Vect_append_point(bbox, x1, y2, PORT_DOUBLE_MAX);
+ Vect_append_point(bbox, x1, y1, -PORT_DOUBLE_MAX);
+
+ /* sel_by_bbox not used */
+ /*
+ sel_by_bbox(Map,
+ type, x1, y1, x2, y2,
+ List);
+ */
+ sel_by_polygon(Map,
+ type, bbox,
+ List);
+
+ Vect_destroy_line_struct(bbox);
+ }
+
+ /* select by polygon */
+ if (params -> poly -> answer != NULL) {
+ int i;
+ struct line_pnts *Polygon;
+
+ Polygon = Vect_new_line_struct();
+
+ for (i = 0; params -> poly -> answers[i]; i+=2){
+ Vect_append_point(Polygon,
+ atof(params -> poly -> answers[i]),
+ atof(params -> poly -> answers[i+1]),
+ 0.0);
+ }
+
+ /* if first and last point of polygon does not match */
+ if (atof(params -> poly -> answers[i-1]) != atof(params -> poly -> answers[0])) {
+ Vect_append_point(Polygon,
+ atof(params -> poly -> answers[0]),
+ atof(params -> poly -> answers[1]),
+ 0.0);
+ }
+
+ sel_by_polygon(Map,
+ type, Polygon,
+ List);
+
+ Vect_destroy_line_struct(Polygon);
+ }
+
+ /* select by where statement */
+ if (params -> where -> answer != NULL) {
+ sel_by_where(Map,
+ layer, type, params -> where -> answer,
+ List);
+ }
+
+ /* selecy by query */
+ if (params -> query -> answer != NULL) {
+ int query_type;
+ struct ilist *List_tmp;
+ if (first_selection) {
+ List_tmp = List;
+ first_selection = 0;
+ }
+ else {
+ List_tmp = Vect_new_list();
+ }
+
+ query_type = QUERY_UNKNOWN;
+ if (strcmp(params->query->answer, "length") == 0) {
+ query_type = QUERY_LENGTH;
+ }
+ else if (strcmp(params->query->answer, "dangle") == 0) {
+ query_type = QUERY_DANGLE;
+ }
+
+ Vedit_select_by_query(Map,
+ type, layer, thresh, query_type,
+ List_tmp);
+
+ /* merge lists (only duplicate items) */
+ if (List_tmp != List) {
+ merge_lists (List, List_tmp);
+ Vect_destroy_list (List_tmp);
+ }
+ }
+
+ if (params -> reverse -> answer) {
+ reverse_selection(Map, type, &List);
+ }
+
+ G_message (_("%d of %d features selected from vector map <%s>"),
+ List -> n_values,
+ Vect_get_num_lines (Map),
+ Vect_get_full_name(Map));
+
+ return List;
+}
+
+/**
+ \brief Print selected vector features
+
+ \param[in] List list of selected features
+
+ \return number of selected features
+ \return -1 on error
+*/
+int print_selected(struct ilist *List)
+{
+ int i;
+
+ /* print the result */
+ for (i = 0; i < List->n_values; i++) {
+ fprintf(stdout, "%d%s",
+ List -> value[i],
+ i < List->n_values -1 ? "," : "");
+ }
+ if (List->n_values > 0) {
+ fprintf(stdout, "\n");
+ }
+ fflush(stdout);
+
+ return List -> n_values;
+}
+
+/**
+ \brief Select features by category
+
+ \param[in] Map vector map
+ \param[in] cl_orig original list of categories (previously selected)
+ \param[in] layer layer number
+ \param[in] type feature type
+ \param[in] cat category string
+ \param[in,out] List list of selected features
+
+ \return number of selected lines
+*/
+int sel_by_cat(struct Map_info *Map, struct cat_list *cl_orig,
+ int layer, int type, char *cats,
+ struct ilist* List)
+{
+ struct ilist *List_tmp, *List_tmp1;
+ struct cat_list *cl;
+
+ int i, cat;
+
+ if (first_selection || cl_orig) {
+ List_tmp = List;
+ first_selection = 0;
+ }
+ else {
+ List_tmp = Vect_new_list();
+ }
+
+ List_tmp1 = Vect_new_list();
+
+ if (cl_orig == NULL) {
+ cl = Vect_new_cat_list();
+
+ Vect_str_to_cat_list (cats, cl);
+ }
+ else {
+ cl = cl_orig;
+ }
+
+ for(i = 0; i < cl -> n_ranges; i++) {
+ for(cat = cl->min[i]; cat <= cl->max[i]; cat++) {
+ Vect_cidx_find_all (Map, layer, type, cat, List_tmp1);
+ Vect_list_append_list (List_tmp, List_tmp1);
+ }
+ }
+
+ G_debug (1, " %d lines selected (by category)", List_tmp -> n_values);
+
+ /* merge lists (only duplicate items) */
+ if (List_tmp != List) {
+ merge_lists (List, List_tmp);
+ Vect_destroy_list (List_tmp);
+ }
+
+ Vect_destroy_list (List_tmp1);
+
+ return List -> n_values;
+}
+
+/**
+ \brief Select features by coordinates
+
+ \param[in] Map vector map
+ \param[in] type feature type
+ \param[in] coords coordinates GRASS parameters
+ \param[in] thresh threshold value for searching
+ \param[in,out] List list of selected features
+
+ \return number of selected lines
+*/
+int sel_by_coordinates(struct Map_info *Map,
+ int type, struct line_pnts *coords, double thresh,
+ struct ilist* List)
+{
+ int i;
+ double east, north, maxdist;
+
+ struct ilist* List_tmp, *List_in_box;
+ struct line_pnts *box;
+
+ if (first_selection) {
+ List_tmp = List;
+ first_selection = 0;
+ }
+ else {
+ List_tmp = Vect_new_list();
+ }
+
+ box = Vect_new_line_struct();
+ List_in_box = Vect_new_list();
+
+ if (thresh < 0)
+ maxdist = max_distance (thresh);
+ else
+ maxdist = thresh;
+
+ for (i = 0; i < coords -> n_points; i++) {
+ east = coords->x[i];
+ north = coords->y[i];
+
+ coord2bbox (east, north, maxdist, box);
+
+ Vect_select_lines_by_polygon(Map, box, 0, NULL, type, List_in_box);
+
+ if (List_in_box -> n_values > 0)
+ Vect_list_append_list (List_tmp, List_in_box);
+ }
+
+ G_debug (1, " %d lines selected (by coordinates)", List_tmp -> n_values);
+
+ /* merge lists (only duplicate items) */
+ if (List_tmp != List) {
+ merge_lists (List, List_tmp);
+ Vect_destroy_list (List_tmp);
+ }
+
+ Vect_destroy_line_struct (box);
+ Vect_destroy_list (List_in_box);
+
+ return List -> n_values;
+}
+
+/**
+ \brief Select features by bbox
+
+ \param[in] Map vector map
+ \param[in] type feature type
+ \param[in] bbox_opt bounding boxes
+ \param[in,out] List list of selected features
+
+ \return number of selected lines
+*/
+int sel_by_bbox(struct Map_info *Map,
+ int type, double x1, double y1, double x2, double y2,
+ struct ilist* List)
+{
+ BOUND_BOX bbox;
+
+ struct ilist* List_tmp;
+
+ if (first_selection) {
+ List_tmp = List;
+ first_selection = 0;
+ }
+ else {
+ List_tmp = Vect_new_list();
+ }
+
+ /* bounding box */
+ bbox.N = y1 < y2 ? y2 : y1;
+ bbox.S = y1 < y2 ? y1 : y2;
+ bbox.W = x1 < x2 ? x1 : x2;
+ bbox.E = x1 < x2 ? x2 : x1;
+ bbox.T = PORT_DOUBLE_MAX;
+ bbox.B = -PORT_DOUBLE_MAX;
+
+ Vect_select_lines_by_box (Map, &bbox, type, List_tmp);
+
+ G_debug (1, " %d lines selected (by bbox)", List_tmp -> n_values);
+
+ /* merge lists (only duplicate items) */
+ if (List_tmp != List) {
+ merge_lists (List, List_tmp);
+ Vect_destroy_list (List_tmp);
+ }
+
+ return List -> n_values;
+}
+
+/**
+ \brief Select features by polygon
+
+ \param[in] Map vector map
+ \param[in] type feature type
+ \param[in] poly polygon coordinates
+ \param[in,out] List list of selected features
+
+ \return number of selected lines
+*/
+int sel_by_polygon(struct Map_info *Map,
+ int type, struct line_pnts *Polygon,
+ struct ilist* List)
+{
+ struct ilist *List_tmp;
+
+ if (first_selection) {
+ List_tmp = List;
+ first_selection = 0;
+ }
+ else {
+ List_tmp = Vect_new_list();
+ }
+
+ /* no isles */
+ Vect_select_lines_by_polygon (Map, Polygon, 0, NULL, type, List_tmp);
+
+ G_debug (1, " %d lines selected (by polygon)", List_tmp -> n_values);
+
+ /* merge lists (only duplicate items) */
+ if (List_tmp != List) {
+ merge_lists (List, List_tmp);
+ Vect_destroy_list (List_tmp);
+ }
+
+ return List -> n_values;
+}
+
+/**
+ \brief Select features by id
+
+ \param[in] Map vector map
+ \param[in] type feature type
+ \param[in] ids ids list
+ \param[in,out] List list of selected features
+
+ \return number of selected lines
+*/
+int sel_by_id(struct Map_info *Map,
+ int type, char *ids,
+ struct ilist* List)
+{
+ int i;
+ int num, id;
+ struct cat_list *il; /* NOTE: this is not cat list, but list of id's */
+ struct ilist *List_tmp;
+
+ if (first_selection) {
+ List_tmp = List;
+ first_selection = 0;
+ }
+ else {
+ List_tmp = Vect_new_list();
+ }
+
+ il = Vect_new_cat_list();
+ Vect_str_to_cat_list (ids, il);
+
+ num = Vect_get_num_lines (Map);
+
+ for(i = 0; i < il -> n_ranges; i++) {
+ for (id = 1; id <= num; id++) {
+ if (!(Vect_read_line(Map, NULL, NULL, id) & type)) {
+ continue;
+ }
+ if (id >= il -> min[i] && id <= il -> max[i]) {
+ Vect_list_append (List_tmp, id);
+ }
+ }
+ }
+
+ G_debug (1, " %d lines selected (by id)", List_tmp -> n_values);
+
+ /* merge lists (only duplicate items) */
+ if (List_tmp != List) {
+ merge_lists (List, List_tmp);
+ Vect_destroy_list (List_tmp);
+ }
+
+ Vect_destroy_cat_list (il);
+
+ return List -> n_values;
+}
+
+/**
+ \brief Select features according to SQL where statement
+
+ \param[in] Map vector map
+ \param[in] layer layer number
+ \param[in] type feature type
+ \param[in] where 'where' statement
+ \param[in,out] List list of selected features
+
+ \return number of selected lines
+*/
+int sel_by_where (struct Map_info *Map,
+ int layer, int type, char *where,
+ struct ilist* List)
+{
+ struct cat_list *cat_list;
+ struct ilist *List_tmp;
+ struct field_info* Fi;
+ dbDriver* driver;
+ dbHandle handle;
+
+ int *cats, ncats;
+
+ if (first_selection) {
+ List_tmp = List;
+ first_selection = 0;
+ }
+ else {
+ List_tmp = Vect_new_list();
+ }
+
+ cat_list = Vect_new_cat_list();
+
+ if (layer < 1) {
+ G_fatal_error (_("Layer must be > 0 for 'where'"));
+ }
+
+ Fi = Vect_get_field (Map, layer);
+
+ if (!Fi) {
+ G_fatal_error (_("Database connection not defined for layer %d"),
+ layer);
+ }
+
+ driver = db_start_driver (Fi -> driver);
+
+ if (!driver)
+ G_fatal_error(_("Unable to start driver <%s>"),
+ Fi->driver) ;
+
+ db_init_handle (&handle);
+
+ db_set_handle (&handle, Fi -> database, NULL);
+
+ if (db_open_database(driver, &handle) != DB_OK)
+ G_fatal_error(_("Unable to open database <%s> by driver <%s>"),
+ Fi->database, Fi->driver);
+
+ ncats = db_select_int (driver, Fi -> table, Fi -> key,
+ where, &cats);
+
+ db_close_database(driver);
+ db_shutdown_driver(driver);
+
+ Vect_array_to_cat_list (cats, ncats, cat_list);
+
+ /* free array of cats */
+ if (ncats >= 0)
+ G_free (cats);
+
+ sel_by_cat (Map, cat_list,
+ layer, type, NULL,
+ List_tmp);
+
+ G_debug (1, " %d lines selected (by where)", List_tmp -> n_values);
+
+ /* merge lists (only duplicate items) */
+ if (List_tmp != List) {
+ merge_lists (List, List_tmp);
+ Vect_destroy_list (List_tmp);
+ }
+
+ Vect_destroy_cat_list (cat_list);
+
+ return List -> n_values;
+}
+
+/**
+ \brief merge two list, i.e. store only duplicate items
+
+ \param[in] alist,blist list to be merged
+
+ \return result number of items
+*/
+static int merge_lists (struct ilist* alist, struct ilist* blist)
+{
+ int i;
+
+ struct ilist* list_del;
+
+ list_del = Vect_new_list();
+
+ for (i = 0; i < alist -> n_values; i++) {
+ if (!Vect_val_in_list (blist, alist -> value[i]))
+ Vect_list_append (list_del, alist -> value[i]);
+ }
+
+ Vect_list_delete_list (alist, list_del);
+
+ Vect_destroy_list (list_del);
+
+ return alist -> n_values;
+}
+
+/**
+ \brief Reverse list selection
+
+ \param[in] Map vector map
+ \param[in] type feature type
+ \param[in,out] reversed list
+
+ \return 1
+*/
+int reverse_selection (struct Map_info *Map, int type, struct ilist** List) {
+
+ struct ilist* list_reverse;
+ int line, nlines, ltype;
+
+ list_reverse = Vect_new_list();
+
+ nlines = Vect_get_num_lines(Map);
+
+ for (line = 1; line <= nlines; line++) {
+ ltype = Vect_read_line(Map, NULL, NULL, line);
+
+ if (!(ltype & type))
+ continue;
+
+ if (!Vect_val_in_list (*List, line))
+ Vect_list_append (list_reverse, line);
+ }
+
+ Vect_destroy_list (*List);
+ *List = list_reverse;
+
+ return 1;
+}
Copied: grass/branches/releasebranch_6_3/vector/v.edit/snap.c (from rev 30279, grass/branches/releasebranch_6_3/vector/v.edit/cmd/snap.c)
===================================================================
--- grass/branches/releasebranch_6_3/vector/v.edit/snap.c (rev 0)
+++ grass/branches/releasebranch_6_3/vector/v.edit/snap.c 2008-02-27 15:10:07 UTC (rev 30374)
@@ -0,0 +1,132 @@
+/****************************************************************
+ *
+ * MODULE: v.edit
+ *
+ * PURPOSE: Editing vector map.
+ *
+ * AUTHOR(S): GRASS Development Team
+ * Wolf Bergenheim, Jachym Cepicky, Martin Landa
+ *
+ * COPYRIGHT: (C) 2006-2008 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
+ ****************************************************************/
+
+#include "global.h"
+
+/**
+ \brief Global snapping function based on snapping library function.
+
+ \param[in] Map vector map
+ \param[in] List list of lines to be snapped
+ \param[in] thresh threshold distance for snapping
+
+ \return 1
+ */
+int snap_lines(struct Map_info *Map,
+ struct ilist *List, double thresh) {
+
+ FILE * output;
+
+ if (G_verbose() > G_verbose_min()) {
+ G_important_message (SEP);
+ output = stderr;
+ }
+ else
+ output = NULL;
+
+ Vect_snap_lines_list (Map, List, thresh, NULL, output);
+
+ if (G_verbose() > G_verbose_min()) {
+ G_important_message (SEP);
+ }
+
+ return 1;
+}
+
+/**
+ \brief Snap two selected lines
+
+ \param[in] Map vector map
+ \param[in] line1 reference line
+ \param[in] line2 line to be snapped (to be modified)
+ \param[in] thresh threshold distance for snapping (-1 for no limit)
+
+ \return id of snapped line
+ \return 0 lines not snapped
+ \return -1 on error
+*/
+int snap_line2(struct Map_info *Map,
+ int line1, int line2, double thresh)
+{
+ struct line_pnts *Points1, *Points2;
+ struct line_cats *Cats2;
+ int type1, type2;
+ int newline;
+ double mindist;
+ int mindistidx;
+
+ Points1 = Vect_new_line_struct();
+ Points2 = Vect_new_line_struct();
+ Cats2 = Vect_new_cats_struct();
+
+ type1 = Vect_read_line(Map, Points1, NULL, line1);
+ type2 = Vect_read_line(Map, Points2, Cats2, line2);
+
+ /* find mininal distance and its indexes */
+ mindist = Vedit_get_min_distance(Points1, Points2, 0, /* TODO 3D */
+ &mindistidx);
+
+ if (thresh > 0.0 && mindist > thresh) {
+ Vect_destroy_line_struct(Points1);
+ Vect_destroy_line_struct(Points2);
+ Vect_destroy_cats_struct(Cats2);
+ return 0;
+ }
+
+ switch(mindistidx) {
+ case 0:
+ Points2->x[0] = Points1->x[0];
+ Points2->y[0] = Points1->y[0];
+ Points2->z[0] = Points1->z[0];
+ break;
+ case 1:
+ Points2->x[Points2->n_points-1] = Points1->x[0];
+ Points2->y[Points2->n_points-1] = Points1->y[0];
+ Points2->z[Points2->n_points-1] = Points1->z[0];
+ break;
+ case 2:
+ Points2->x[0] = Points1->x[Points1->n_points-1];
+ Points2->y[0] = Points1->y[Points1->n_points-1];
+ Points2->z[0] = Points1->z[Points1->n_points-1];
+ break;
+ case 3:
+ Points2->x[Points2->n_points-1] = Points1->x[Points1->n_points-1];
+ Points2->y[Points2->n_points-1] = Points1->y[Points1->n_points-1];
+ Points2->z[Points2->n_points-1] = Points1->z[Points1->n_points-1];
+ break;
+ default:
+ break;
+ }
+
+ newline = Vect_rewrite_line (Map, line2, type2, Points2, Cats2);
+ if (newline < 0) {
+ G_warning(_("Unable to rewrite line %d"), line2);
+ return -1;
+ }
+
+ /*
+ G_message(_("Line %d snapped to line %d"),
+ line2, line1);
+ */
+ Vect_destroy_line_struct(Points1);
+ Vect_destroy_line_struct(Points2);
+ Vect_destroy_cats_struct(Cats2);
+
+ return newline;
+}
More information about the grass-commit
mailing list