[GRASS-SVN] r29680 - in grass/trunk/vector/v.edit: . cmd lib

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Jan 12 14:31:46 EST 2008


Author: martinl
Date: 2008-01-12 14:31:46 -0500 (Sat, 12 Jan 2008)
New Revision: 29680

Added:
   grass/trunk/vector/v.edit/cmd/
   grass/trunk/vector/v.edit/cmd/Makefile
   grass/trunk/vector/v.edit/cmd/a2b.c
   grass/trunk/vector/v.edit/cmd/args.c
   grass/trunk/vector/v.edit/cmd/description.html
   grass/trunk/vector/v.edit/cmd/global.h
   grass/trunk/vector/v.edit/cmd/main.c
   grass/trunk/vector/v.edit/cmd/max_distance.c
   grass/trunk/vector/v.edit/cmd/proto.h
   grass/trunk/vector/v.edit/cmd/select.c
   grass/trunk/vector/v.edit/cmd/snap.c
   grass/trunk/vector/v.edit/lib/
   grass/trunk/vector/v.edit/lib/Makefile
   grass/trunk/vector/v.edit/lib/break.c
   grass/trunk/vector/v.edit/lib/cats.c
   grass/trunk/vector/v.edit/lib/copy.c
   grass/trunk/vector/v.edit/lib/delete.c
   grass/trunk/vector/v.edit/lib/distance.c
   grass/trunk/vector/v.edit/lib/flip.c
   grass/trunk/vector/v.edit/lib/merge.c
   grass/trunk/vector/v.edit/lib/move.c
   grass/trunk/vector/v.edit/lib/snap.c
   grass/trunk/vector/v.edit/lib/vedit.h
   grass/trunk/vector/v.edit/lib/vertex.c
   grass/trunk/vector/v.edit/lib/zbulk.c
Removed:
   grass/trunk/vector/v.edit/Makefile
   grass/trunk/vector/v.edit/a2b.c
   grass/trunk/vector/v.edit/args.c
   grass/trunk/vector/v.edit/break.c
   grass/trunk/vector/v.edit/cats.c
   grass/trunk/vector/v.edit/copy.c
   grass/trunk/vector/v.edit/del.c
   grass/trunk/vector/v.edit/description.html
   grass/trunk/vector/v.edit/flip.c
   grass/trunk/vector/v.edit/global.h
   grass/trunk/vector/v.edit/main.c
   grass/trunk/vector/v.edit/max_distance.c
   grass/trunk/vector/v.edit/merge.c
   grass/trunk/vector/v.edit/move.c
   grass/trunk/vector/v.edit/proto.h
   grass/trunk/vector/v.edit/select.c
   grass/trunk/vector/v.edit/snap.c
   grass/trunk/vector/v.edit/vertex.c
   grass/trunk/vector/v.edit/zbulk.c
Log:
Code reorganization, v.edit functionality move to the library (grass_vedit).

Deleted: grass/trunk/vector/v.edit/Makefile
===================================================================
--- grass/trunk/vector/v.edit/Makefile	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/Makefile	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,12 +0,0 @@
-MODULE_TOPDIR = ../..
-
-PGM = v.edit
-
-LIBES = $(VECTLIB) $(GISLIB)
-DEPENDENCIES= $(VECTDEP) $(GISDEP)
-EXTRA_INC = $(VECT_INC)
-EXTRA_CFLAGS = $(VECT_CFLAGS)
-
-include $(MODULE_TOPDIR)/include/Make/Module.make
-
-default: cmd

Deleted: grass/trunk/vector/v.edit/a2b.c
===================================================================
--- grass/trunk/vector/v.edit/a2b.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/a2b.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,311 +0,0 @@
-#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 do_close(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;
-}

Deleted: grass/trunk/vector/v.edit/args.c
===================================================================
--- grass/trunk/vector/v.edit/args.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/args.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,348 +0,0 @@
-#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)");
-    params -> tool->options     = "create,add,delete,copy,move,flip,catadd,catdel,"
-      "merge,break,snap,connect,"
-      "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 -> 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) snap to");
-
-    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 -> 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) { 
-        /* del requires a cats or or bbox or coords */
-	*action_mode = MODE_SELECT;
-    }
-    else if(G_strcasecmp (params -> tool -> answer, "catadd") == 0) { 
-        /* cat requires a cats or or bbox or coords */
-	*action_mode = MODE_CATADD;
-    }
-    else if(G_strcasecmp (params -> tool -> answer, "catdel") == 0) {
-        /* cat requires a cats or or bbox or coords */
-	*action_mode = MODE_CATDEL;
-    }
-    else if(G_strcasecmp(params -> tool -> answer, "copy") == 0) { 
-        /* del requires a cats or or bbox or coords */
-	*action_mode = MODE_COPY;
-    }
-    else if(G_strcasecmp (params -> tool -> answer, "snap") == 0) {
-	/* del requires a cats or or bbox or coords */ 
-	*action_mode = MODE_SNAP;
-    }
-    else if(G_strcasecmp (params -> tool -> answer, "flip") == 0) {
-	/* del requires a cats or or bbox or coords */ 
-	*action_mode = MODE_FLIP;
-    }
-    else if(G_strcasecmp (params -> tool -> answer, "zbulk") == 0) {
-	/* del requires a cats or or bbox or coords */ 
-	*action_mode = MODE_ZBULK;
-    }
-    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;
-}

Deleted: grass/trunk/vector/v.edit/break.c
===================================================================
--- grass/trunk/vector/v.edit/break.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/break.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,349 +0,0 @@
-/****************************************************************
- *
- * MODULE:     v.edit
- *
- * AUTHOR(S):  GRASS Development Team
- *             Jachym Cepicky <jachym.cepicky gmail.com>
- *             Martin Landa <martin.landa gmail.com>
- *
- * PURPOSE:    This module edits vector map. 
- *             Break / connect the line
- *
- * COPYRIGHT:  (C) 2006-2007 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.
- *
- ****************************************************************/
-
-#include <math.h>
-#include "global.h"
-
-/**
-   \brief Break selected lines
-
-   \param[in] Map vector map
-   \param[in] List list of selected lines
-
-   \return number of modified lines
-   \return -1 on error
- */
-
-int do_break (struct Map_info *Map, struct ilist *List) {
-
-    return Vect_break_lines_list(Map, List,
-				 GV_LINES, NULL, NULL);
-}
-
-/**
-   \brief Split selected lines on given position
-   
-   \param[in] Map vector map
-   \param[in] List list of selected lines
-   \param[in] coord points location
-   \param[in] List_updated list of rewritten features (if given)
-
-   \return number of modified lines
-   \return -1 on error
- */
-int do_split (struct Map_info *Map, struct ilist *List,
-	      struct line_pnts *coord, double thresh,
-	      struct ilist *List_updated)
-{
-    int i, j, l;
-    int type, line, seg, newline;
-    int nlines_modified;
-    double px, py, spdist, lpdist, dist;
-    double *x, *y, *z;
-
-    struct line_pnts *Points, *Points2;
-    struct line_cats *Cats;
-    struct ilist *List_in_box;
-
-    nlines_modified = 0;
-
-    Points = Vect_new_line_struct();
-    Points2 = Vect_new_line_struct();
-    Cats = Vect_new_cats_struct();
-    List_in_box = Vect_new_list();
-
-    for (i = 0; i < List -> n_values; i++) {
-	line = List -> value[i];
-	
-	if (!Vect_line_alive (Map, line))
-	    continue;
-
-        type = Vect_read_line(Map, Points, Cats, line);
-
-	if (!(type & GV_LINES))
-	    continue;
-
-	x = Points -> x;
-	y = Points -> y;
-	z = Points -> z;
-
-	for (j = 0; j < coord -> n_points; j++) {
-	    seg = Vect_line_distance (Points, coord->x[j], coord->y[j], coord->z[j],
-				      WITHOUT_Z,
-				      &px, &py, NULL,
-				      &dist, &spdist, &lpdist);
-
-	    if (dist > thresh) {
-		continue;
-	    }
-
-	    G_debug (3, "do_break: line=%d, x=%f, y=%f, px=%f, py=%f, seg=%d, dist=%f, spdist=%f, lpdist=%f",
-		     line, coord->x[j], coord->y[j], px, py, seg, dist, spdist, lpdist);
-
-	    if (spdist <= 0.0 ||
-		spdist >= Vect_line_length(Points))
-		continue;
-	    
-	    G_debug (3, "do_break: line=%d broken", line);
-
-	    /* copy first line part */
-	    for (l = 0; l < seg; l++) {
-		Vect_append_point(Points2,
-				  x[l], y[l], z[l]);
-	    }
-	    
-	    /* add last vertex */
-	    Vect_append_point(Points2, px, py, 0.0);
-	    
-	    /* rewrite the line */
-	    newline = Vect_rewrite_line (Map, line, type, Points2, Cats);
-   	    if (List_updated)
-		Vect_list_append (List_updated, newline);
-	    Vect_reset_line (Points2);
-	    
-	    /* add given vertex */
-	    Vect_append_point(Points2, px, py, 0.0);
-	    
-	    /* copy second line part */
-	    for (l = seg; l < Points->n_points; l++) {
-		Vect_append_point(Points2, 
-				  x[l], y[l], z[l]);
-	    }
-	    
-	    /* rewrite the line */
-	    newline = Vect_write_line (Map, type, Points2, Cats);
-   	    if (List_updated)
-		Vect_list_append (List_updated, newline);
-	    
-	    nlines_modified++;
-	} /* for each bounding box */
-    } /* for each selected line */
-
-    Vect_destroy_line_struct(Points);
-    Vect_destroy_line_struct(Points2);
-    Vect_destroy_cats_struct(Cats);
-    Vect_destroy_list (List_in_box);
-
-    return nlines_modified;
-}
-
-/**
-   \brief Connect *two* lines
- 
-   The first line from the list is connected to the second one
-   if necessary the second line is broken
- 
-   \			     \
-   id1  \           ->	      \
-                               \
-   id2 ---------           ---------
- 
-   \param[in] Map vector map
-   \param[in] List list of selected lines
-   \param[in] thresh threshold value for connect
-
-   \return  number of modified lines
-   \return -1 on error
- */
-int do_connect (struct Map_info *Map, struct ilist *List,
-		double thresh)
-{
-    int nlines_modified, newline, intersection, linep, nlines_to_modify;
-    int i, idx, pnt_idx[2];
-    int line[2], type[2], seg[2];
-    double px[2], py[2], pz[2], dist[2], spdist[2], lpdist[2];
-    double nx[2], ny[2], nz[2];
-    char   n_on_line[2], connected;
-    double angle, dseg, dist_connect;
-
-    struct ilist *List_break, *List_updated;
-
-    struct line_pnts *Points[2];
-    struct line_cats *Cats[2];
-
-    nlines_modified  = 0;
-    nlines_to_modify = 2; /* modify *two* lines at the time */
-
-    Points[0] = Points[1] = NULL;
-    Cats[0]   = Cats[1]   = NULL;
-
-    List_break = Vect_new_list ();
-    List_updated = Vect_new_list();
-
-    for (linep = 0; linep < List -> n_values; linep += 2) {
-	connected = 0;
-	/* read the lines */
-	for (i = 0; i < nlines_to_modify; i++) {
-	    line[i] = List -> value[linep + i];
-
-	    if (!Vect_line_alive (Map, line[i])) {
-		line[i] = -1;
-		break;
-	    }
-	    if (!Points[i])
-		Points[i] = Vect_new_line_struct();
-	    if (!Cats[i])
-		Cats[i] = Vect_new_cats_struct();
-
-	    type[i] = Vect_read_line(Map, Points[i], Cats[i], line[i]);
-
-	    if (!(type[i] & GV_LINES)) {
-		line[i] = -1;
-		break;
-	    }
-	}
-
-	if (line[0] == -1 || line[1] == -1)
-	    continue;
-
-	/* check lines intersection 
-	   if (Vect_line_check_intersection (Points[0], Points[1], WITHOUT_Z))
-	   return 0;
-	*/
-
-	/* find node to connect */
-	for (i = 0; i < nlines_to_modify; i++) {
-	    if (i == 0)
-		idx = 0;
-	    else
-		idx = Points[0] -> n_points - 1;
-
-	    seg[i] = Vect_line_distance (Points[1], Points[0]->x[idx], Points[0]->y[idx], Points[0]->z[idx],
-					 WITHOUT_Z,
-					 &px[i], &py[i], &pz[i],
-					 &dist[i], &spdist[i], &lpdist[i]);
-	}
-
-	idx        = (dist[0] <= dist[1]) ? 0 : 1;
-	pnt_idx[0] = (idx == 0) ? 0 : Points[0] -> n_points - 1; /* which node to connect */
-
-	angle =
-	    M_PI / 2 -
-	    acos (fabs (Points[0] -> x[0] - Points[0] -> x[Points[0] -> n_points - 1]) /
-		  Vect_line_length (Points[0])) -
-	    asin (fabs (Points[1] -> y[seg[idx] - 1] - py[idx]) / spdist[idx]);
-	
-	dseg = dist[idx] * tan (angle);
-
-	/* compute connect points */
-	for (i = 0; i < nlines_to_modify; i++) {
-	    if (0 == Vect_point_on_line (Points[1], lpdist[idx] + dseg, &nx[i], &ny[i], &nz[i], NULL, NULL)) {
-		n_on_line[i] = 0;
-	    }
-	    else {
-		n_on_line[i] = 1;
-	    }
-	    dseg *= -1.0;
-	}
-    
-	if (!n_on_line[0] || !n_on_line[1]) {
-	    G_warning (_("Unable to connect line id %d to line %d"), line[0], line[1]);
-	    continue;
-	}
-
-	/* choose connect point */
-	if (idx == 0)
-	    pnt_idx[1] = Points[0] -> n_points - 1;
-	else
-	    pnt_idx[1] = 0;
-	
-	if (Vect_points_distance (nx[0], ny[0], nz[0],
-				  Points[0] -> x[pnt_idx[1]], Points[0] -> y[pnt_idx[1]],
-				  Points[0] -> z[pnt_idx[1]],
-				  WITHOUT_Z) >
-	    Vect_points_distance (nx[1], ny[1], nz[1],
-				  Points[0] -> x[pnt_idx[1]], Points[0] -> y[pnt_idx[1]],
-				  Points[0] -> z[pnt_idx[1]],
-				  WITHOUT_Z))
-	    pnt_idx[1] = 0;
-	else
-	    pnt_idx[1] = 1;
-	
-	dist_connect = Vect_points_distance (nx[pnt_idx[1]], ny[pnt_idx[1]], nz[pnt_idx[1]],
-					     Points[0] -> x[pnt_idx[0]], Points[0] -> y[pnt_idx[0]],
-					     Points[0] -> z[pnt_idx[0]],
-					     WITHOUT_Z);
-
-	G_debug (3, "do_connect: dist=%f/%f -> pnt_idx=%d -> x=%f, y=%f / dist_connect=%f (thresh=%f)",
-		 dist[0], dist[1], pnt_idx[0], nx[pnt_idx[1]], ny[pnt_idx[1]], dist_connect, thresh);
-
-	if (thresh >= 0.0 && dist_connect > thresh) {
-	    G_warning (_("Unable to connect line id %d to line %d because of threshold distance. "
-			 "Run v.edit with other threshold distance value."),
-		       line[0], line[1]);
-	    continue;
-	}
-    
-	/* modify the first line */
-	Vect_reset_list (List_updated);
-	intersection = Vect_line_check_intersection (Points[0], Points[1], WITHOUT_Z);
-
-	if (!intersection) {
-	    if (pnt_idx[0] == 0)
-		Vect_line_insert_point (Points[0], 0, nx[pnt_idx[1]], ny[pnt_idx[1]], 0.0);
-	    else
-		Vect_append_point (Points[0], nx[pnt_idx[1]], ny[pnt_idx[1]], 0.0);
-	    
-	    /* rewrite the first line */
-	    newline = Vect_rewrite_line (Map, line[0], type[0], Points[0], Cats[0]);
-	    Vect_list_append (List_updated, newline);
-	    connected = 1;
-	}
-	else
-	    Vect_list_append (List_updated, line[0]);
-	
-	/* break the second line */
-	Vect_reset_list (List_break);
-	if (!intersection ||
-	    (intersection &&
-	     Vect_points_distance (nx[pnt_idx[1]], ny[pnt_idx[1]], nz[pnt_idx[1]],
-				   Points[0] -> x[pnt_idx[0]], Points[0] -> y[pnt_idx[0]],
-				   Points[0] -> z[pnt_idx[0]],
-				   WITHOUT_Z) <= 0.0)) {
-	    Vect_list_append (List_break, line[1]);
-	    struct line_pnts *coord = Vect_new_line_struct();
-	    Vect_append_point(coord, nx[pnt_idx[1]], ny[pnt_idx[1]], nz[pnt_idx[1]]);
-	    do_split (Map, List_break, 
-		      coord, 1e-1, 
-		      List_updated);
-	    Vect_destroy_line_struct(coord);
-	    /* snap lines */
-	    Vect_snap_lines_list (Map, List_updated, 1e-1, NULL, NULL);
-	    connected = 1;
-	}
-	
-	if (connected)
-	    nlines_modified += 2;
-	else
-	    G_warning (_("Unable to connect line id %d to line %d"), line[0], line[1]);
-    } /* for each line pair */
-
-    /* destroy structures */
-    for (i = 0; i < nlines_to_modify; i++) {
-	if (Points[i])
-	    Vect_destroy_line_struct(Points[i]);
-	if (Cats[i])
-	    Vect_destroy_cats_struct(Cats[i]);
-    }
-    Vect_destroy_list (List_break);
-    Vect_destroy_list (List_updated);
-
-    return nlines_modified;
-}

Deleted: grass/trunk/vector/v.edit/cats.c
===================================================================
--- grass/trunk/vector/v.edit/cats.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/cats.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,109 +0,0 @@
-/***************************************************************
- *
- * MODULE:     v.edit
- * 
- * AUTHOR(S):  GRASS Development Team
- *             Jachym Cepicky <jachym  les-ejk cz>
- *             Radim Blazek, Martin Landa
- *               
- * PURPOSE:    This module edits vector maps.
- *
- * COPYRIGHT:  (C) 2001-2007 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.
- *
- **************************************************************/
-
-#include "global.h"
-
-/**
-   \brief Edit category numbers of selected vector features
-
-   \param[in] Map vector map
-   \param[in] List list of selected features
-   \param[in] layer layer number
-   \param[in] del action (add/delete)
-   \param[in] cats_list list of category numbers
-
-   \return number of modified features
-   \return -1 on error
-*/
-int cats (struct Map_info *Map, struct ilist *List,
-	  int layer, int del, char *cats_list)
-{
-    int i, j;
-    struct line_cats *Cats;
-    struct line_pnts *Points;
-    struct cat_list *Clist;
-    int line, type, cat;
-    int nlines_modified, rewrite;
-    
-    nlines_modified = 0;
-
-    /* get list of categories */
-    Clist = Vect_new_cat_list();
-    if (Vect_str_to_cat_list(cats_list, Clist)) {
-	G_warning (_("Unable to get category list <%s>, editing terminated"), cats_list);
-	return -1;
-    }
-    
-    /* features defined by cats */
-    if(Clist->n_ranges > 0) {
-	Cats   = Vect_new_cats_struct (); 
-	Points = Vect_new_line_struct();
-
-	/* for each line, set new category */
-	for (i = 0; i < List->n_values; i++) {
-	    line = List->value[i];
-            type = Vect_read_line(Map, Points, Cats, line);
-
-	    if (!Vect_line_alive (Map, line))
-		continue;
-
-	    rewrite = 0;
-	    for (j = 0; j < Clist -> n_ranges; j++) {
-		for (cat = Clist -> min[j]; cat <= Clist -> max[j]; cat++) {
-		    /* add new category */
-		    if (!del) {
-			if(Vect_cat_set (Cats, layer, cat) < 1) {
-			    G_warning (_("Unable to set category %d line %d"),
-				       cat, line);
-			}
-			else {
-			    rewrite = 1;
-			}
-		    }
-		    else { /* delete old category */
-			if(Vect_field_cat_del (Cats, layer, cat) == 0) {
-			    G_warning (_("Unable to delete layer/category [%d/%d] line %d"), 
-				       layer, cat, line);
-			}
-			else {
-			    rewrite = 1;
-			}
-		    }
-		}
-	    }
-
-	    if (rewrite == 0)
-		continue;
-
-	    if (Vect_rewrite_line (Map, line, type, Points, Cats) < 0)  {
-		G_warning (_("Unable to rewrite line %d"), line);
-		return -1;
-	    }
-
-	    nlines_modified++;
-
-	}
-
-	/* destroy structures */
-	Vect_destroy_line_struct(Points);
-	Vect_destroy_cats_struct(Cats);
-    }
-
-    return nlines_modified;
-}

Copied: grass/trunk/vector/v.edit/cmd/Makefile (from rev 29679, grass/trunk/vector/v.edit/Makefile)
===================================================================
--- grass/trunk/vector/v.edit/cmd/Makefile	                        (rev 0)
+++ grass/trunk/vector/v.edit/cmd/Makefile	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,12 @@
+MODULE_TOPDIR = ../../..
+
+PGM = v.edit
+
+LIBES = $(VEDITLIB) $(VECTLIB) $(GISLIB)
+DEPENDENCIES= $(VEDITDEP) $(VECTDEP) $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+
+include $(MODULE_TOPDIR)/include/Make/Module.make
+
+default: cmd

Copied: grass/trunk/vector/v.edit/cmd/a2b.c (from rev 29679, grass/trunk/vector/v.edit/a2b.c)
===================================================================
--- grass/trunk/vector/v.edit/cmd/a2b.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/cmd/a2b.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -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/trunk/vector/v.edit/cmd/args.c (from rev 29679, grass/trunk/vector/v.edit/args.c)
===================================================================
--- grass/trunk/vector/v.edit/cmd/args.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/cmd/args.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -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)");
+    params -> tool->options     = "create,add,delete,copy,move,flip,catadd,catdel,"
+      "merge,break,snap,connect,"
+      "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 -> 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) snap to");
+
+    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 -> 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) { 
+        /* del requires a cats or or bbox or coords */
+	*action_mode = MODE_SELECT;
+    }
+    else if(G_strcasecmp (params -> tool -> answer, "catadd") == 0) { 
+        /* cat requires a cats or or bbox or coords */
+	*action_mode = MODE_CATADD;
+    }
+    else if(G_strcasecmp (params -> tool -> answer, "catdel") == 0) {
+        /* cat requires a cats or or bbox or coords */
+	*action_mode = MODE_CATDEL;
+    }
+    else if(G_strcasecmp(params -> tool -> answer, "copy") == 0) { 
+        /* del requires a cats or or bbox or coords */
+	*action_mode = MODE_COPY;
+    }
+    else if(G_strcasecmp (params -> tool -> answer, "snap") == 0) {
+	/* del requires a cats or or bbox or coords */ 
+	*action_mode = MODE_SNAP;
+    }
+    else if(G_strcasecmp (params -> tool -> answer, "flip") == 0) {
+	/* del requires a cats or or bbox or coords */ 
+	*action_mode = MODE_FLIP;
+    }
+    else if(G_strcasecmp (params -> tool -> answer, "zbulk") == 0) {
+	/* del requires a cats or or bbox or coords */ 
+	*action_mode = MODE_ZBULK;
+    }
+    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/trunk/vector/v.edit/cmd/description.html (from rev 29679, grass/trunk/vector/v.edit/description.html)
===================================================================
--- grass/trunk/vector/v.edit/cmd/description.html	                        (rev 0)
+++ grass/trunk/vector/v.edit/cmd/description.html	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,448 @@
+<h2>DESCRIPTION</h2>
+
+<p>
+The module <em>v.edit</em> allows the user to edit a vector map
+via command line interface. 
+</p>
+
+<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>
+
+<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:
+</p>
+
+<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>
+<p>
+If no vector features are selected or the flag <b>-t</b> is
+used, topology is not build at the end.
+</p>
+
+<h2>USAGE</h2>
+
+<h3>Feature selection</h3>
+
+<p>
+Vector features can be selected in several ways:
+</p>
+<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>
+
+<p>
+Additional parameters for vector feature specification are:
+</p>
+<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 <a href="v.in.ascii.html">v.in.ascii</a>). 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 <a href="v.build.polylines.html">v.build.polylines</a>.</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 <a href="v.clean.html">v.clean</a>, tool=break).</li>
+    
+    <li><b>snap</b> - Snap vector features in given threshold. See
+    also module <a href="v.clean.html">v.clean</a>.</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>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>
+<p>
+Create new (empty) vector map:
+</p>
+<div class="code"><pre>
+v.edit tool=create map=vectmap
+</pre></div>
+
+<p>
+Create new vector map and read data from file 'roads.txt':
+</p>
+<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>
+
+<p>
+Add point to the vector map (without header):
+</p>
+<div class="code"><pre>
+echo "P 1 1
+ 640794 214874
+ 1 1" | v.edit -n tool=add map=vectmap
+</pre></div>
+
+<p>
+Add new features read from standard input:
+</p>
+<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>
+
+<p>
+Remove all vector features with category number 1 or 2:
+</p>
+<div class="code"><pre>
+v.edit tool=delete map=roads cats=1,2
+</pre></div>
+
+<p>
+Remove all vector features except of those with category number 1 or 2
+(reverse selection):
+</p>
+<div class="code"><pre>
+v.edit -r tool=delete map=roads cats=1,2
+</pre></div>
+
+<p>
+Remove features with category 1 or 2 located on coordinates
+600952.625,4926107 (bounding box based on the current 2D resolution):
+</p>
+<div class="code"><pre>
+g.region -d;
+v.edit tool=delete map=roads cats=1,2 coords=600952.625,4926107
+</pre></div>
+
+<p>
+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):
+</p>
+<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>
+
+<p>
+Move feature (vector point) located on coordinates 602580,4918480 to
+coordinates 603580,4919480:
+</p>
+
+<div class="code"><pre>
+v.edit tool=move map=archsites coord=602580,4918480 th=1e-2 move=1000,1000
+</pre></div>
+
+<p>
+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:
+</p>
+
+<div class="code"><pre>
+v.edit tool=move map=roads cat=1 move=1000,-1000 snap=node thresh=10
+</pre></div>
+
+<p>
+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:
+</p>
+
+<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>
+
+<p>
+Flip direction of all vector lines:
+</p>
+
+<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>
+
+<p>
+Print id's of selected features, e.g.:
+</p>
+
+<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>d.vect</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><br><br>
+<a HREF="http://freegis.org/cgi-bin/viewcvs.cgi/~checkout~/grass6/doc/vector/vector.html#ascii">Vector ASCII Format Specification</a>
+
+<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/trunk/vector/v.edit/cmd/global.h (from rev 29679, grass/trunk/vector/v.edit/global.h)
===================================================================
--- grass/trunk/vector/v.edit/cmd/global.h	                        (rev 0)
+++ grass/trunk/vector/v.edit/cmd/global.h	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,49 @@
+#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>
+
+# 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,
+};
+
+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"
+# include "../lib/vedit.h"
+
+#endif

Copied: grass/trunk/vector/v.edit/cmd/main.c (from rev 29679, grass/trunk/vector/v.edit/main.c)
===================================================================
--- grass/trunk/vector/v.edit/cmd/main.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/cmd/main.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,406 @@
+/****************************************************************
+ *
+ * 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, &params, &action_mode))
+	exit(EXIT_FAILURE);
+
+    /* get list of categories */
+    Clist = Vect_new_cat_list();
+    if (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,
+				&params,
+				List);
+	}
+	else {
+	    List = select_lines(&Map, action_mode,
+				&params,
+				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, 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;
+    }
+    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/trunk/vector/v.edit/cmd/max_distance.c (from rev 29679, grass/trunk/vector/v.edit/max_distance.c)
===================================================================
--- grass/trunk/vector/v.edit/cmd/max_distance.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/cmd/max_distance.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -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/trunk/vector/v.edit/cmd/proto.h (from rev 29679, grass/trunk/vector/v.edit/proto.h)
===================================================================
--- grass/trunk/vector/v.edit/cmd/proto.h	                        (rev 0)
+++ grass/trunk/vector/v.edit/cmd/proto.h	2008-01-12 19:31:46 UTC (rev 29680)
@@ -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 *,
+	      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/trunk/vector/v.edit/cmd/select.c (from rev 29679, grass/trunk/vector/v.edit/select.c)
===================================================================
--- grass/trunk/vector/v.edit/cmd/select.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/cmd/select.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,745 @@
+/****************************************************************
+ *
+ * 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,
+		  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) {
+	sel_by_query(Map,
+		     type, layer, thresh, params -> query -> answer,
+		     List);
+    }
+
+    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] ids ids list
+   \param[in,out] List list of selected features
+ 
+   \return number of selected lines
+*/
+int sel_by_id(struct Map_info *Map,
+	      char *ids,
+	      struct ilist* List)
+{
+    int i, j;
+    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 = il -> min[i]; id <= il -> max[i]; id++) {
+	    for (j = 1; j <= num; j++) {
+		if (id == j) {
+		    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;
+}
+
+/**
+   \brief Select features by query (based on geometry)
+
+   \param[in] Map vector map
+   \param[in] type feature type
+   \param[in] layer layer number
+   \param[in] thresh threshold value (< 0 for 'shorter', > 0 for 'longer')
+   \param[in] query query (length, dangle, ...)
+   \param[in,out] List list of selected features
+ 
+   \return number of selected lines
+*/
+int sel_by_query(struct Map_info *Map,
+		 int type, int layer, double thresh, const char *query,
+		 struct ilist* List)
+{
+    int num, line, ltype, cat;
+    double length;
+    struct ilist *List_tmp;
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+
+    if (first_selection) {
+	List_tmp = List;
+	first_selection = 0;
+    }
+    else {
+	List_tmp = Vect_new_list();
+    }
+
+    Points = Vect_new_line_struct();
+    Cats   = Vect_new_cats_struct();
+
+    num = Vect_get_num_lines (Map);
+
+    for (line = 1; line <= num; line++) {
+	if (!Vect_line_alive(Map, line))
+	    continue;
+	
+	ltype = Vect_read_line(Map, Points, Cats, line);
+	Vect_cat_get(Cats, layer, &cat); /* get first category from layer */
+
+	if (!(ltype & type))
+	    continue;
+
+	if (strcmp(query, "length") == 0) {
+	    length = Vect_line_length(Points);
+	    if (thresh <= 0.0) { /* shorter then */
+		if (length <= fabs(thresh))
+		    Vect_list_append(List_tmp, line);
+	    }
+	    else { /* longer then */
+		if (length > thresh)
+		    Vect_list_append(List_tmp, line);
+	    }
+	}
+	else if (strcmp(query, "dangle") == 0) {
+	    if (!(type & GV_LINES))
+		continue;
+	    /* check if line is dangle */
+
+	    int i, cat_curr;
+	    int node1, node2, node;        /* nodes */
+	    int nnode1, nnode2;            /* number of line in node */
+	    double nx, ny, nz;             /* node coordinates */
+	    struct ilist *exclude, *found; /* line id of nearest lines */
+	    struct line_cats *Cats_curr;   
+
+	    Vect_get_line_nodes(Map, line, &node1, &node2);
+	    
+	    node = -1;
+	    nnode1 = Vect_get_node_n_lines(Map, node1);
+	    nnode2 = Vect_get_node_n_lines(Map, node2);
+
+	    if ((nnode1 == 4 && nnode2 == 1) ||
+		(nnode1 == 1 && nnode2 == 4)) {
+		if (nnode1 == 4)
+		    node = node1;
+		else
+		    node = node2;
+	    }
+
+	    /* no dangle ? */
+	    if (node == -1)
+		continue;
+
+	    length = Vect_line_length(Points);
+	    if (thresh <= 0.0) { /* shorter then */
+		if (length > fabs(thresh))
+		    continue;
+	    }
+	    else { /* longer then */
+		if (length <= thresh)
+		    continue;
+	    }
+	    
+	    /* at least one of the lines need to have same category number */
+	    exclude = Vect_new_list();
+	    found   = Vect_new_list();
+
+	    Vect_get_node_coor(Map, node, &nx, &ny, &nz);
+
+	    Vect_list_append(exclude, line);
+	    Vect_find_line_list(Map, nx, ny, nz,
+				GV_LINES, 0.0, WITHOUT_Z,
+				exclude, found);
+
+	    Cats_curr = Vect_new_cats_struct();
+
+	    for (i = 0; i < found->n_values; i++) {
+		Vect_read_line(Map, NULL, Cats_curr, found->value[i]);
+		if (Vect_cat_get(Cats_curr, layer, &cat_curr) > -1) {
+		    if (cat == cat_curr)
+			Vect_list_append(List_tmp, line);
+		}
+	    }
+
+	    Vect_destroy_cats_struct(Cats_curr);
+	    Vect_destroy_list(exclude);
+	    Vect_destroy_list(found);
+	}
+	else {
+	    /* this shouldn't happen */
+	    G_fatal_error (_("Unknown query tool '%s'"), query);
+	}
+    }
+
+    G_debug (1, "  %d lines selected (by query '%s')", List_tmp -> n_values, query);
+
+    /* merge lists (only duplicate items) */
+    if (List_tmp != List) {
+	merge_lists (List, List_tmp);
+	Vect_destroy_list (List_tmp);
+    }
+
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_cats_struct(Cats);
+
+    return List -> n_values; 
+}

Added: grass/trunk/vector/v.edit/cmd/snap.c
===================================================================
--- grass/trunk/vector/v.edit/cmd/snap.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/cmd/snap.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -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;
+}

Deleted: grass/trunk/vector/v.edit/copy.c
===================================================================
--- grass/trunk/vector/v.edit/copy.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/copy.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,73 +0,0 @@
-/***************************************************************
- *
- * MODULE:     v.edit
- * 
- * AUTHOR(S):  GRASS Development Team
- *             Jachym Cepicky <jachym  les-ejk cz>
- *             Martin Landa <landa.martin gmail.com>
- *               
- * PURPOSE:    This module edits vector map.
- *             Copy selected features.
- *
- * COPYRIGHT:  (C) 2007 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.
- *
- **************************************************************/
-
-#include "global.h"
-
-/**
-   \brief Copy selected features
-
-   \param[in] Map vector map copy to
-   \param[in] FromMap vector map copy from (if not given use Map)
-   \param[in] List list of selected features (to be copied)
-
-   \return number of copied features
-   \return -1 on error 
- */
-int do_copy (struct Map_info *Map, struct Map_info *FromMap, struct ilist *List)
-{
-    struct line_cats *Cats;
-    struct line_pnts *Points;
-    int i;
-    int type, line;
-    int nlines_copied;
-
-    nlines_copied = 0;
-    Cats = Vect_new_cats_struct(); 
-    Points = Vect_new_line_struct();
-
-    if (!FromMap) {
-	FromMap = Map;
-    }
-
-    /* for each line, make a copy */
-    for (i = 0; i < List->n_values; i++) {
-	line = List -> value[i];
-
-	if (!Vect_line_alive(FromMap, line))
-	    continue;
-
-        type = Vect_read_line(FromMap, Points, Cats, line);
-
-        G_debug(3, "Copying line type %d number %d", type, line);
-
-        /* copy */
-        if (Vect_write_line (Map, type, Points, Cats) < 0) {
-            G_warning (_("Unable to write line %d"), line);
-	    return -1;
-	}
-        
-	nlines_copied++;
-    }
-
-    Vect_destroy_line_struct (Points);
-    Vect_destroy_cats_struct (Cats);
-
-    return nlines_copied;
-}

Deleted: grass/trunk/vector/v.edit/del.c
===================================================================
--- grass/trunk/vector/v.edit/del.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/del.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,55 +0,0 @@
-/***************************************************************
- *
- * MODULE:     v.edit
- * 
- * AUTHOR(S):  GRASS Development Team
- *             Jachym Cepicky <jachym  les-ejk cz>
- *             Martin Landa <landa.martin gmail.com>
- *               
- * PURPOSE:    This module edits vector map.
- *             Delete selected features.
- *
- * COPYRIGHT:  (C) 2007 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.
- *
- **************************************************************/
-
-#include "global.h"
-
-/**
-   \brief Delete selected features
-
-   \param[in] Map vector map
-   \param[in] List list of features to be deleted
-
-   \return number of deleted features
-   \return -1 on on error
- */
-int do_delete(struct Map_info *Map, struct ilist *List)
-{
-    int i, line;
-    int nlines_removed;
-
-    nlines_removed = 0;
-
-    /* delete */
-    for (i = 0; i < List->n_values; i++) {
-	line = List -> value[i];
-
-	if (Vect_line_alive(Map, line)) {
-	    if (-1 == Vect_delete_line(Map, line)) { 
-		G_warning (_("Unable to delete line %d"), line);
-		return -1;
-	    }
-
-	    G_debug (3, "Line %d deleted", line);
-	    nlines_removed++;
-	}
-    }
-
-    return nlines_removed;
-}

Deleted: grass/trunk/vector/v.edit/description.html
===================================================================
--- grass/trunk/vector/v.edit/description.html	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/description.html	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,448 +0,0 @@
-<h2>DESCRIPTION</h2>
-
-<p>
-The module <em>v.edit</em> allows the user to edit a vector map
-via command line interface. 
-</p>
-
-<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>
-
-<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:
-</p>
-
-<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>
-<p>
-If no vector features are selected or the flag <b>-t</b> is
-used, topology is not build at the end.
-</p>
-
-<h2>USAGE</h2>
-
-<h3>Feature selection</h3>
-
-<p>
-Vector features can be selected in several ways:
-</p>
-<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>
-
-<p>
-Additional parameters for vector feature specification are:
-</p>
-<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 <a href="v.in.ascii.html">v.in.ascii</a>). 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 <a href="v.build.polylines.html">v.build.polylines</a>.</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 <a href="v.clean.html">v.clean</a>, tool=break).</li>
-    
-    <li><b>snap</b> - Snap vector features in given threshold. See
-    also module <a href="v.clean.html">v.clean</a>.</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>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>
-<p>
-Create new (empty) vector map:
-</p>
-<div class="code"><pre>
-v.edit tool=create map=vectmap
-</pre></div>
-
-<p>
-Create new vector map and read data from file 'roads.txt':
-</p>
-<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>
-
-<p>
-Add point to the vector map (without header):
-</p>
-<div class="code"><pre>
-echo "P 1 1
- 640794 214874
- 1 1" | v.edit -n tool=add map=vectmap
-</pre></div>
-
-<p>
-Add new features read from standard input:
-</p>
-<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>
-
-<p>
-Remove all vector features with category number 1 or 2:
-</p>
-<div class="code"><pre>
-v.edit tool=delete map=roads cats=1,2
-</pre></div>
-
-<p>
-Remove all vector features except of those with category number 1 or 2
-(reverse selection):
-</p>
-<div class="code"><pre>
-v.edit -r tool=delete map=roads cats=1,2
-</pre></div>
-
-<p>
-Remove features with category 1 or 2 located on coordinates
-600952.625,4926107 (bounding box based on the current 2D resolution):
-</p>
-<div class="code"><pre>
-g.region -d;
-v.edit tool=delete map=roads cats=1,2 coords=600952.625,4926107
-</pre></div>
-
-<p>
-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):
-</p>
-<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>
-
-<p>
-Move feature (vector point) located on coordinates 602580,4918480 to
-coordinates 603580,4919480:
-</p>
-
-<div class="code"><pre>
-v.edit tool=move map=archsites coord=602580,4918480 th=1e-2 move=1000,1000
-</pre></div>
-
-<p>
-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:
-</p>
-
-<div class="code"><pre>
-v.edit tool=move map=roads cat=1 move=1000,-1000 snap=node thresh=10
-</pre></div>
-
-<p>
-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:
-</p>
-
-<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>
-
-<p>
-Flip direction of all vector lines:
-</p>
-
-<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>
-
-<p>
-Print id's of selected features, e.g.:
-</p>
-
-<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>d.vect</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><br><br>
-<a HREF="http://freegis.org/cgi-bin/viewcvs.cgi/~checkout~/grass6/doc/vector/vector.html#ascii">Vector ASCII Format Specification</a>
-
-<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>

Deleted: grass/trunk/vector/v.edit/flip.c
===================================================================
--- grass/trunk/vector/v.edit/flip.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/flip.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,71 +0,0 @@
-/***************************************************************
- *
- * MODULE:     v.edit
- * 
- * AUTHOR(S):  GRASS Development Team
- *             Martin Landa <landa.martin gmail.com>
- *               
- * PURPOSE:    This module edits vector maps.
- *             Flip direction of selected vector lines.
- *             Inspired by v.flip script by Maciej Sieczka
- *
- * COPYRIGHT:  (C) 2007 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.
- *
- **************************************************************/
-
-#include "global.h"
-
-/**
-   \brief Flip direction of selected vector lines
-
-   \param[in] Map vector map
-   \param[in] List list of selected lines
-
-   \return number of modified lines
-   \return -1 on error
- */
-int do_flip (struct Map_info *Map, struct ilist *List)
-{
-    struct line_cats *Cats;
-    struct line_pnts *Points;
-    int i, line, type;
-    int nlines_flipped;
-
-    nlines_flipped = 0;
-
-    Points = Vect_new_line_struct();
-    Cats   = Vect_new_cats_struct();
-
-    for (i = 0; i < List -> n_values; i++) {
-	line = List -> value[i];
-
-	if (!Vect_line_alive (Map, line))
-	    continue;
-	
-	type = Vect_read_line (Map, Points, Cats, line);
-
-	if (!(type & GV_LINES))
-	    continue;
-
-	Vect_line_reverse (Points);
-
-	if (Vect_rewrite_line (Map, line, type, Points, Cats) < 0) {
-	    G_warning (_("Unable to rewrite line %d"),
-		       line);
-	    return -1;
-	}
-
-	nlines_flipped++;
-    }
-
-    /* destroy structures */
-    Vect_destroy_line_struct(Points);
-    Vect_destroy_cats_struct(Cats);
-
-    return nlines_flipped;
-}

Deleted: grass/trunk/vector/v.edit/global.h
===================================================================
--- grass/trunk/vector/v.edit/global.h	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/global.h	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,52 +0,0 @@
-#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>
-
-# 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,
-};
-
-#define NO_SNAP    0 /* snapping disabled */
-#define SNAP       1 /* snapping enabled for nodes */
-#define SNAPVERTEX 2 /* snapping enabled for vertex also */
-
-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

Added: grass/trunk/vector/v.edit/lib/Makefile
===================================================================
--- grass/trunk/vector/v.edit/lib/Makefile	                        (rev 0)
+++ grass/trunk/vector/v.edit/lib/Makefile	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,16 @@
+MODULE_TOPDIR = ../../..
+
+LIB_NAME = $(VEDIT_LIBNAME)
+DEPENDENCIES = $(GISDEP)
+EXTRA_INC = $(VECT_INC)
+EXTRA_CFLAGS = $(VECT_CFLAGS)
+EXTRA_LIBS = $(VECTLIB) $(DBMILIB) $(GISLIB)
+
+include $(MODULE_TOPDIR)/include/Make/Lib.make
+
+default: lib $(ARCH_INCDIR)/vedit.h
+
+$(ARCH_INCDIR)/vedit.h: vedit.h
+	$(INSTALL_DATA) vedit.h $(ARCH_INCDIR)/vedit.h
+
+

Copied: grass/trunk/vector/v.edit/lib/break.c (from rev 29679, grass/trunk/vector/v.edit/break.c)
===================================================================
--- grass/trunk/vector/v.edit/lib/break.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/lib/break.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,328 @@
+/**
+   \brief Vedit library - split/break line
+
+   This program is free software under the
+   GNU General Public License (>=v2).
+   Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) 2007-2008 by the GRASS Development Team
+   Martin Landa <landa.martin gmail.com>
+
+   \date 2007-2008
+*/
+
+#include <math.h>
+#include "vedit.h"
+
+/**
+   \brief Split selected lines on given position
+   
+   \param[in] Map vector map
+   \param[in] List list of selected lines
+   \param[in] coord points location
+   \param[in] List_updated list of rewritten features (if given)
+
+   \return number of modified lines
+   \return -1 on error
+ */
+int Vedit_split_lines(struct Map_info *Map, struct ilist *List,
+		      struct line_pnts *coord, double thresh,
+		      struct ilist *List_updated)
+{
+    int i, j, l;
+    int type, line, seg, newline;
+    int nlines_modified;
+    double px, py, spdist, lpdist, dist;
+    double *x, *y, *z;
+
+    struct line_pnts *Points, *Points2;
+    struct line_cats *Cats;
+    struct ilist *List_in_box;
+
+    nlines_modified = 0;
+
+    Points = Vect_new_line_struct();
+    Points2 = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+    List_in_box = Vect_new_list();
+
+    for (i = 0; i < List -> n_values; i++) {
+	line = List -> value[i];
+	
+	if (!Vect_line_alive (Map, line))
+	    continue;
+
+        type = Vect_read_line(Map, Points, Cats, line);
+
+	if (!(type & GV_LINES))
+	    continue;
+
+	x = Points -> x;
+	y = Points -> y;
+	z = Points -> z;
+
+	for (j = 0; j < coord -> n_points; j++) {
+	    seg = Vect_line_distance (Points, coord->x[j], coord->y[j], coord->z[j],
+				      WITHOUT_Z,
+				      &px, &py, NULL,
+				      &dist, &spdist, &lpdist);
+
+	    if (dist > thresh) {
+		continue;
+	    }
+
+	    G_debug (3, "do_break: line=%d, x=%f, y=%f, px=%f, py=%f, seg=%d, dist=%f, spdist=%f, lpdist=%f",
+		     line, coord->x[j], coord->y[j], px, py, seg, dist, spdist, lpdist);
+
+	    if (spdist <= 0.0 ||
+		spdist >= Vect_line_length(Points))
+		continue;
+	    
+	    G_debug (3, "do_break: line=%d broken", line);
+
+	    /* copy first line part */
+	    for (l = 0; l < seg; l++) {
+		Vect_append_point(Points2,
+				  x[l], y[l], z[l]);
+	    }
+	    
+	    /* add last vertex */
+	    Vect_append_point(Points2, px, py, 0.0);
+	    
+	    /* rewrite the line */
+	    newline = Vect_rewrite_line (Map, line, type, Points2, Cats);
+   	    if (List_updated)
+		Vect_list_append (List_updated, newline);
+	    Vect_reset_line (Points2);
+	    
+	    /* add given vertex */
+	    Vect_append_point(Points2, px, py, 0.0);
+	    
+	    /* copy second line part */
+	    for (l = seg; l < Points->n_points; l++) {
+		Vect_append_point(Points2, 
+				  x[l], y[l], z[l]);
+	    }
+	    
+	    /* rewrite the line */
+	    newline = Vect_write_line (Map, type, Points2, Cats);
+   	    if (List_updated)
+		Vect_list_append (List_updated, newline);
+	    
+	    nlines_modified++;
+	} /* for each bounding box */
+    } /* for each selected line */
+
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_line_struct(Points2);
+    Vect_destroy_cats_struct(Cats);
+    Vect_destroy_list (List_in_box);
+
+    return nlines_modified;
+}
+
+/**
+   \brief Connect *two* lines
+ 
+   The first line from the list is connected to the second one
+   if necessary the second line is broken
+ 
+   \			     \
+   id1  \           ->	      \
+                               \
+   id2 ---------           ---------
+ 
+   \param[in] Map vector map
+   \param[in] List list of selected lines
+   \param[in] thresh threshold value for connect
+
+   \return  1 lines connected
+   \return  0 lines not connected
+   \return -1 on error
+ */
+int Vedit_connect_lines (struct Map_info *Map, struct ilist *List,
+			 double thresh)
+{
+    int nlines_modified, newline, intersection, linep, nlines_to_modify;
+    int i, idx, pnt_idx[2];
+    int line[2], type[2], seg[2];
+    double px[2], py[2], pz[2], dist[2], spdist[2], lpdist[2];
+    double nx[2], ny[2], nz[2];
+    char   n_on_line[2], connected;
+    double angle, dseg, dist_connect;
+
+    struct ilist *List_break, *List_updated;
+
+    struct line_pnts *Points[2];
+    struct line_cats *Cats[2];
+
+    nlines_modified  = 0;
+    nlines_to_modify = 2; /* modify *two* lines at the time */
+
+    Points[0] = Points[1] = NULL;
+    Cats[0]   = Cats[1]   = NULL;
+
+    List_break = Vect_new_list ();
+    List_updated = Vect_new_list();
+
+    for (linep = 0; linep < List -> n_values; linep += 2) {
+	connected = 0;
+	/* read the lines */
+	for (i = 0; i < nlines_to_modify; i++) {
+	    line[i] = List -> value[linep + i];
+
+	    if (!Vect_line_alive (Map, line[i])) {
+		line[i] = -1;
+		break;
+	    }
+	    if (!Points[i])
+		Points[i] = Vect_new_line_struct();
+	    if (!Cats[i])
+		Cats[i] = Vect_new_cats_struct();
+
+	    type[i] = Vect_read_line(Map, Points[i], Cats[i], line[i]);
+
+	    if (!(type[i] & GV_LINES)) {
+		line[i] = -1;
+		break;
+	    }
+	}
+
+	if (line[0] == -1 || line[1] == -1)
+	    continue;
+
+	/* check lines intersection 
+	   if (Vect_line_check_intersection (Points[0], Points[1], WITHOUT_Z))
+	   return 0;
+	*/
+
+	/* find node to connect */
+	for (i = 0; i < nlines_to_modify; i++) {
+	    if (i == 0)
+		idx = 0;
+	    else
+		idx = Points[0] -> n_points - 1;
+
+	    seg[i] = Vect_line_distance (Points[1], Points[0]->x[idx], Points[0]->y[idx], Points[0]->z[idx],
+					 WITHOUT_Z,
+					 &px[i], &py[i], &pz[i],
+					 &dist[i], &spdist[i], &lpdist[i]);
+	}
+
+	idx        = (dist[0] <= dist[1]) ? 0 : 1;
+	pnt_idx[0] = (idx == 0) ? 0 : Points[0] -> n_points - 1; /* which node to connect */
+
+	angle =
+	    M_PI / 2 -
+	    acos (fabs (Points[0] -> x[0] - Points[0] -> x[Points[0] -> n_points - 1]) /
+		  Vect_line_length (Points[0])) -
+	    asin (fabs (Points[1] -> y[seg[idx] - 1] - py[idx]) / spdist[idx]);
+	
+	dseg = dist[idx] * tan (angle);
+
+	/* compute connect points */
+	for (i = 0; i < nlines_to_modify; i++) {
+	    if (0 == Vect_point_on_line (Points[1], lpdist[idx] + dseg, &nx[i], &ny[i], &nz[i], NULL, NULL)) {
+		n_on_line[i] = 0;
+	    }
+	    else {
+		n_on_line[i] = 1;
+	    }
+	    dseg *= -1.0;
+	}
+    
+	if (!n_on_line[0] || !n_on_line[1]) {
+	    G_warning (_("Unable to connect line id %d to line %d"), line[0], line[1]);
+	    continue;
+	}
+
+	/* choose connect point */
+	if (idx == 0)
+	    pnt_idx[1] = Points[0] -> n_points - 1;
+	else
+	    pnt_idx[1] = 0;
+	
+	if (Vect_points_distance (nx[0], ny[0], nz[0],
+				  Points[0] -> x[pnt_idx[1]], Points[0] -> y[pnt_idx[1]],
+				  Points[0] -> z[pnt_idx[1]],
+				  WITHOUT_Z) >
+	    Vect_points_distance (nx[1], ny[1], nz[1],
+				  Points[0] -> x[pnt_idx[1]], Points[0] -> y[pnt_idx[1]],
+				  Points[0] -> z[pnt_idx[1]],
+				  WITHOUT_Z))
+	    pnt_idx[1] = 0;
+	else
+	    pnt_idx[1] = 1;
+	
+	dist_connect = Vect_points_distance (nx[pnt_idx[1]], ny[pnt_idx[1]], nz[pnt_idx[1]],
+					     Points[0] -> x[pnt_idx[0]], Points[0] -> y[pnt_idx[0]],
+					     Points[0] -> z[pnt_idx[0]],
+					     WITHOUT_Z);
+
+	G_debug (3, "do_connect: dist=%f/%f -> pnt_idx=%d -> x=%f, y=%f / dist_connect=%f (thresh=%f)",
+		 dist[0], dist[1], pnt_idx[0], nx[pnt_idx[1]], ny[pnt_idx[1]], dist_connect, thresh);
+
+	if (thresh >= 0.0 && dist_connect > thresh) {
+	    G_warning (_("Unable to connect line id %d to line %d because of threshold distance. "
+			 "Run v.edit with other threshold distance value."),
+		       line[0], line[1]);
+	    continue;
+	}
+    
+	/* modify the first line */
+	Vect_reset_list (List_updated);
+	intersection = Vect_line_check_intersection (Points[0], Points[1], WITHOUT_Z);
+
+	if (!intersection) {
+	    if (pnt_idx[0] == 0)
+		Vect_line_insert_point (Points[0], 0, nx[pnt_idx[1]], ny[pnt_idx[1]], 0.0);
+	    else
+		Vect_append_point (Points[0], nx[pnt_idx[1]], ny[pnt_idx[1]], 0.0);
+	    
+	    /* rewrite the first line */
+	    newline = Vect_rewrite_line (Map, line[0], type[0], Points[0], Cats[0]);
+	    Vect_list_append (List_updated, newline);
+	    connected = 1;
+	}
+	else
+	    Vect_list_append (List_updated, line[0]);
+	
+	/* break the second line */
+	Vect_reset_list (List_break);
+	if (!intersection ||
+	    (intersection &&
+	     Vect_points_distance (nx[pnt_idx[1]], ny[pnt_idx[1]], nz[pnt_idx[1]],
+				   Points[0] -> x[pnt_idx[0]], Points[0] -> y[pnt_idx[0]],
+				   Points[0] -> z[pnt_idx[0]],
+				   WITHOUT_Z) <= 0.0)) {
+	    Vect_list_append (List_break, line[1]);
+	    struct line_pnts *coord = Vect_new_line_struct();
+	    Vect_append_point(coord, nx[pnt_idx[1]], ny[pnt_idx[1]], nz[pnt_idx[1]]);
+	    Vedit_split_lines(Map, List_break, 
+			      coord, 1e-1, 
+			      List_updated);
+	    Vect_destroy_line_struct(coord);
+	    /* snap lines */
+	    Vect_snap_lines_list (Map, List_updated, 1e-1, NULL, NULL);
+	    connected = 1;
+	}
+	
+	if (connected)
+	    nlines_modified += 2;
+	else
+	    G_warning (_("Unable to connect line id %d to line %d"), line[0], line[1]);
+    } /* for each line pair */
+
+    /* destroy structures */
+    for (i = 0; i < nlines_to_modify; i++) {
+	if (Points[i])
+	    Vect_destroy_line_struct(Points[i]);
+	if (Cats[i])
+	    Vect_destroy_cats_struct(Cats[i]);
+    }
+    Vect_destroy_list (List_break);
+    Vect_destroy_list (List_updated);
+
+    return nlines_modified == 2 ? 1 : 0;
+}

Copied: grass/trunk/vector/v.edit/lib/cats.c (from rev 29679, grass/trunk/vector/v.edit/cats.c)
===================================================================
--- grass/trunk/vector/v.edit/lib/cats.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/lib/cats.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,97 @@
+/**
+   \brief Vedit library - category manipulation
+
+   This program is free software under the
+   GNU General Public License (>=v2).
+   Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) 2006-2008 by the GRASS Development Team
+   Jachym Cepicky <jachym.cepicky gmail.com>
+   Martin Landa <landa.martin gmail.com>
+
+   \date 2006-2008
+*/
+
+#include "vedit.h"
+
+/**
+   \brief Edit category numbers of selected vector features
+
+   \param[in] Map vector map
+   \param[in] List list of selected features
+   \param[in] layer layer number
+   \param[in] del action (add/delete)
+   \param[in] cats_list list of category numbers
+
+   \return number of modified features
+   \return -1 on error
+*/
+int Vedit_modify_cats (struct Map_info *Map, struct ilist *List,
+		       int layer, int del, struct cat_list *Clist)
+{
+    int i, j;
+    struct line_cats *Cats;
+    struct line_pnts *Points;
+    int line, type, cat;
+    int nlines_modified, rewrite;
+    
+    nlines_modified = 0;
+
+    /* features defined by cats */
+    if(Clist->n_ranges > 0) {
+	Cats   = Vect_new_cats_struct (); 
+	Points = Vect_new_line_struct();
+
+	/* for each line, set new category */
+	for (i = 0; i < List->n_values; i++) {
+	    line = List->value[i];
+            type = Vect_read_line(Map, Points, Cats, line);
+
+	    if (!Vect_line_alive (Map, line))
+		continue;
+
+	    rewrite = 0;
+	    for (j = 0; j < Clist -> n_ranges; j++) {
+		for (cat = Clist -> min[j]; cat <= Clist -> max[j]; cat++) {
+		    /* add new category */
+		    if (!del) {
+			if(Vect_cat_set (Cats, layer, cat) < 1) {
+			    G_warning (_("Unable to set category %d line %d"),
+				       cat, line);
+			}
+			else {
+			    rewrite = 1;
+			}
+		    }
+		    else { /* delete old category */
+			if(Vect_field_cat_del (Cats, layer, cat) == 0) {
+			    G_warning (_("Unable to delete layer/category [%d/%d] line %d"), 
+				       layer, cat, line);
+			}
+			else {
+			    rewrite = 1;
+			}
+		    }
+		}
+	    }
+
+	    if (rewrite == 0)
+		continue;
+
+	    if (Vect_rewrite_line (Map, line, type, Points, Cats) < 0)  {
+		G_warning (_("Unable to rewrite line %d"), line);
+		return -1;
+	    }
+
+	    nlines_modified++;
+
+	}
+
+	/* destroy structures */
+	Vect_destroy_line_struct(Points);
+	Vect_destroy_cats_struct(Cats);
+    }
+
+    return nlines_modified;
+}

Copied: grass/trunk/vector/v.edit/lib/copy.c (from rev 29679, grass/trunk/vector/v.edit/copy.c)
===================================================================
--- grass/trunk/vector/v.edit/lib/copy.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/lib/copy.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,69 @@
+/**
+   \brief Vedit library - copy features
+
+   This program is free software under the
+   GNU General Public License (>=v2).
+   Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) 2007-2008 by the GRASS Development Team
+   Jachym Cepicky <jachym.cepicky gmail.com>
+   Martin Landa <landa.martin gmail.com>
+
+   \date 2007-2008
+*/
+
+#include "vedit.h"
+
+/**
+   \brief Copy selected features
+
+   \param[in] Map vector map copy to
+   \param[in] FromMap vector map copy from (if not given use Map)
+   \param[in] List list of selected features (to be copied)
+
+   \return number of copied features
+   \return -1 on error 
+ */
+int Vedit_copy_lines (struct Map_info *Map, struct Map_info *FromMap,
+		      struct ilist *List)
+{
+    struct line_cats *Cats;
+    struct line_pnts *Points;
+    int i;
+    int type, line;
+    int nlines_copied;
+
+    nlines_copied = 0;
+    Cats = Vect_new_cats_struct(); 
+    Points = Vect_new_line_struct();
+
+    if (!FromMap) {
+	FromMap = Map;
+    }
+
+    /* for each line, make a copy */
+    for (i = 0; i < List->n_values; i++) {
+	line = List -> value[i];
+
+	if (!Vect_line_alive(FromMap, line))
+	    continue;
+
+        type = Vect_read_line(FromMap, Points, Cats, line);
+
+        G_debug(3, "Copying line type %d number %d", type, line);
+
+        /* copy */
+        if (Vect_write_line (Map, type, Points, Cats) < 0) {
+            G_warning (_("Unable to write line %d"), line);
+	    return -1;
+	}
+        
+	nlines_copied++;
+    }
+
+    Vect_destroy_line_struct (Points);
+    Vect_destroy_cats_struct (Cats);
+
+    return nlines_copied;
+}

Copied: grass/trunk/vector/v.edit/lib/delete.c (from rev 29679, grass/trunk/vector/v.edit/del.c)
===================================================================
--- grass/trunk/vector/v.edit/lib/delete.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/lib/delete.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,49 @@
+/**
+   \brief Vedit library - delete features
+
+   This program is free software under the
+   GNU General Public License (>=v2).
+   Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) 2007-2008 by the GRASS Development Team
+   Martin Landa <landa.martin gmail.com>
+
+   \date 2007-2008
+*/
+
+#include "vedit.h"
+
+/**
+   \brief Delete selected features
+
+   \param[in] Map vector map
+   \param[in] List list of features to be deleted
+
+   \return number of deleted features
+   \return -1 on on error
+ */
+int Vedit_delete_lines(struct Map_info *Map, struct ilist *List)
+{
+    int i, line;
+    int nlines_removed;
+
+    nlines_removed = 0;
+
+    /* delete */
+    for (i = 0; i < List->n_values; i++) {
+	line = List -> value[i];
+
+	if (Vect_line_alive(Map, line)) {
+	    if (-1 == Vect_delete_line(Map, line)) { 
+		G_warning (_("Unable to delete line %d"), line);
+		return -1;
+	    }
+
+	    G_debug (3, "Vedit_delete_lines(): line=%d", line);
+	    nlines_removed++;
+	}
+    }
+
+    return nlines_removed;
+}

Added: grass/trunk/vector/v.edit/lib/distance.c
===================================================================
--- grass/trunk/vector/v.edit/lib/distance.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/lib/distance.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,70 @@
+/**
+   \brief Vedit library - distance calculation
+
+   This program is free software under the
+   GNU General Public License (>=v2).
+   Read the file COPYING that comes with GRASS
+   for details.
+
+   (C) 2007-2008 by the GRASS Development Team
+
+   \author Martin Landa <landa.martin gmail.com>
+
+   \date 2007-2008
+*/
+
+#include "vedit.h"
+
+/**
+   \brief Calculate distances between two lines
+ 
+   TODO: LL projection
+
+   \param[in] Points1 first line
+   \param[in] Points2 second line
+   \param[out] index of minimal distance
+
+   \return minimal distance betwen two lines (their nodes)
+*/
+double Vedit_get_min_distance(struct line_pnts *Points1, struct line_pnts *Points2,
+			      int with_z, int* mindistidx)
+{
+    unsigned int i;
+    double distances [4];
+
+    /*
+      distances[0] = first-first
+      distances[1] = first-last
+      distances[2] = last-first
+      distances[3] = last-last
+    */
+
+    distances[0] = Vect_points_distance(Points1->x[0], Points1->y[0], Points1->z[0],
+					Points2->x[0], Points2->y[0], Points2->z[0], with_z);
+    
+    distances[1] = Vect_points_distance(Points1->x[0], Points1->y[0], Points1->z[0],
+					Points2->x[Points2->n_points-1],
+					Points2->y[Points2->n_points-1],
+					Points2->z[Points2->n_points-1], with_z);
+    
+    distances[2] = Vect_points_distance(Points1->x[Points1->n_points-1],
+					Points1->y[Points1->n_points-1],
+					Points1->z[Points1->n_points-1],
+					Points2->x[0], Points2->y[0], Points2->z[0], with_z);
+    
+    distances[3] = Vect_points_distance(Points1->x[Points1->n_points-1],
+					Points1->y[Points1->n_points-1],
+					Points1->z[Points1->n_points-1],
+					Points2->x[Points2->n_points-1],
+					Points2->y[Points2->n_points-1],
+					Points2->z[Points2->n_points-1], with_z);
+    
+    /* find the minimal distance between first or last point of both lines */
+    *mindistidx = 0;
+    for (i = 0; i < sizeof (distances) / sizeof (double); i++) {
+	if (distances[i] >= 0.0 && distances[i] < distances[*mindistidx])
+	    *mindistidx = i;
+    }
+
+    return distances [*mindistidx];
+}

Copied: grass/trunk/vector/v.edit/lib/flip.c (from rev 29679, grass/trunk/vector/v.edit/flip.c)
===================================================================
--- grass/trunk/vector/v.edit/lib/flip.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/lib/flip.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,65 @@
+/**
+   \brief Vedit library - lines flipping
+
+   This program is free software under the
+   GNU General Public License (>=v2).
+   Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) 2007-2008 by the GRASS Development Team
+   Martin Landa <landa.martin gmail.com>
+
+   \date 2007-2008
+*/
+
+#include "vedit.h"
+
+/**
+   \brief Flip direction of selected vector lines
+
+   \param[in] Map vector map
+   \param[in] List list of selected lines
+
+   \return number of modified lines
+   \return -1 on error
+ */
+int Vedit_flip_lines(struct Map_info *Map, struct ilist *List)
+{
+    struct line_cats *Cats;
+    struct line_pnts *Points;
+    int i, line, type;
+    int nlines_flipped;
+
+    nlines_flipped = 0;
+
+    Points = Vect_new_line_struct();
+    Cats   = Vect_new_cats_struct();
+
+    for (i = 0; i < List -> n_values; i++) {
+	line = List -> value[i];
+
+	if (!Vect_line_alive (Map, line))
+	    continue;
+	
+	type = Vect_read_line (Map, Points, Cats, line);
+
+	if (!(type & GV_LINES))
+	    continue;
+
+	Vect_line_reverse (Points);
+
+	if (Vect_rewrite_line (Map, line, type, Points, Cats) < 0) {
+	    G_warning (_("Unable to rewrite line %d"),
+		       line);
+	    return -1;
+	}
+
+	nlines_flipped++;
+    }
+
+    /* destroy structures */
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_cats_struct(Cats);
+
+    return nlines_flipped;
+}

Copied: grass/trunk/vector/v.edit/lib/merge.c (from rev 29679, grass/trunk/vector/v.edit/merge.c)
===================================================================
--- grass/trunk/vector/v.edit/lib/merge.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/lib/merge.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,248 @@
+/**
+   \brief Vedit library - merge lines
+
+   This program is free software under the
+   GNU General Public License (>=v2).
+   Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) 2006-2008 by the GRASS Development Team
+   Jachym Cepicky <jachym.cepicky gmail.com>
+   Martin Landa <landa.martin gmail.com>
+
+   \date 2006-2008
+*/
+
+#include "vedit.h"
+
+/**
+   \brief Merge two given lines a, b
+   
+   a : Points1/Cats1
+   b : Points2/Cats2
+   merged line : Points/Cats
+   
+   \param[in] Points1,Cats1 first line
+   \param[in] Points2,Cats2 second line
+   \param[in] thresh threshold value
+   \param[out] Points result line
+
+   \return 1 on success
+   \return 0 on error
+*/
+static int merge_lines (struct line_pnts *Points1, struct line_cats *Cats1, 
+			struct line_pnts *Points2, struct line_cats *Cats2,
+			double thresh, struct line_pnts **Points);
+
+/**
+   \brief Merge lines/boundaries
+ 
+   At least two lines need to be given.
+
+   \param[in] Map vector map
+   \param[in] List list of selected features
+
+   \return number of merged lines
+   \return -1 on error
+*/
+int Vedit_merge_lines(struct Map_info *Map, struct ilist *List)
+{
+    struct ilist *List_in_box;
+    
+    struct line_pnts *Points1, *Points2, *Points;
+    struct line_cats *Cats1, *Cats2;
+    
+    int line_i, i, j;    
+    int line, line1, type1, line2, type2;
+    int do_merge;
+    /* number of lines (original, selected, merged) */
+    int nlines, nlines_selected, nlines_merged;
+    
+    nlines_merged = 0;
+    
+    if (List->n_values < 2) {
+	G_warning (_("Only %d lines found, at least two needed"),
+		   List->n_values);
+	return 0;
+    }
+    
+    Points1 = Vect_new_line_struct();
+    Cats1   = Vect_new_cats_struct();
+    Points2 = Vect_new_line_struct();
+    Cats2   = Vect_new_cats_struct();
+    Points  = Vect_new_line_struct();
+    
+    List_in_box = Vect_new_list();
+    
+    nlines          = Vect_get_num_lines (Map);
+    nlines_selected = List -> n_values;
+    
+    /* merge lines */
+    for (line_i = 0; line_i < List -> n_values; line_i++) {
+	G_percent (line_i, List -> n_values, 2);
+	
+	line1 = List -> value[line_i];
+	
+	if (!Vect_line_alive (Map, line1))
+	    continue;
+	
+	type1 = Vect_read_line (Map, Points1, Cats1, line1);
+	
+	if (!(type1 & GV_LINES))
+	    continue;
+	
+	Vect_reset_line (Points);
+	
+	for (i = 0; i < Points1 -> n_points; i += Points1 -> n_points - 1) {
+	    Vect_reset_list (List_in_box);
+	    
+	    /* define searching region */
+	    Vect_reset_line (Points2);
+	    /*
+	      Vect_append_point (Points2, Points1 -> x[i] - thresh,
+	      Points1 -> y[i] + thresh, Points1 -> z[i]);
+	      Vect_append_point (Points2, Points1 -> x[i] + thresh,
+	      Points1 -> y[i] + thresh, Points1 -> z[i]);
+	      Vect_append_point (Points2, Points1 -> x[i] + thresh,
+	      Points1 -> y[i] - thresh, Points1 -> z[i]);
+	      Vect_append_point (Points2, Points1 -> x[i] - thresh,
+	      Points1 -> y[i] - thresh, Points1 -> z[i]);
+	    */
+	    Vect_append_point (Points2, Points1 -> x[i],
+			       Points1 -> y[i], Points1 -> z[i]);
+	    
+	    /* 
+	     * merge lines only if two lines found in the region
+	     * i.e. the current line and an adjacent line
+	     */
+	    if (1 < Vect_select_lines_by_polygon (Map, Points2, 0, NULL,
+						  GV_LINES, List_in_box)) {
+		do_merge = 1;
+		line2 = -1;
+		for (j = 0; do_merge && j < List -> n_values; j++) {
+		    if (List -> value[j] == line1 ||
+			!Vect_line_alive(Map, List -> value[j]))
+			continue;
+		    
+		    if (Vect_val_in_list (List_in_box, List -> value[j])) {
+			if (line2 > 0) {
+			    /* three lines found
+			     * selected lines will be not merged
+			     */
+			    do_merge = 0;
+			}
+			else {
+			    line2 = List -> value[j];
+			}
+		    }
+		}
+		
+		if (!do_merge || line2 < 0)
+		    continue;
+		
+		type2 = Vect_read_line (Map, Points2, Cats2, line2);
+		
+		merge_lines (Points1, Cats1,
+			     Points2, Cats2,
+			     -1.0,  &Points); /* do not use threshold value */
+		
+		G_debug (3, "merge lines: %d, %d", line1, line2);
+		
+		if (Points -> n_points > 0) {
+		    if (Vect_delete_line(Map, line2) == -1) {
+			G_warning (_("Unable to delete line %d"),
+				   line2);
+			return -1;
+		    }
+		    
+		    if (line2 <= nlines)
+			nlines_merged++;
+		}
+	    }
+	} /* for each node */
+	
+	if (Points -> n_points > 0) {
+	    line = Vect_rewrite_line (Map, line1, type1, Points, Cats1);
+	    if (line < 0) {
+		G_warning (_("Unable to rewrite line %d"),
+			   line1);
+		return -1;
+	    }
+	    
+	    if (line1 <= nlines)
+		nlines_merged++;
+	    
+	    /* update number of lines */
+	    Vect_list_append (List, line);
+	}
+    } /* for each line */
+    
+    /* destroy stuctures */
+    Vect_destroy_line_struct(Points1);
+    Vect_destroy_line_struct(Points2);
+    Vect_destroy_line_struct(Points);
+    
+    Vect_destroy_cats_struct(Cats1);
+    Vect_destroy_cats_struct(Cats2);
+    
+    return nlines_merged;
+}
+
+static int merge_lines (struct line_pnts *Points1, struct line_cats *Cats1, 
+			struct line_pnts *Points2, struct line_cats *Cats2,
+			double thresh, struct line_pnts **Points)
+{
+    struct line_pnts *ps = *Points;
+    struct line_cats *cs = Cats1;
+
+    int i, mindistidx;
+    double mindist;
+    
+    /* find mininal distance and its index */
+    mindist = Vedit_get_min_distance(Points1, Points2, 0, /* TODO 3D */
+				     &mindistidx);
+
+    G_debug (3, "merge line ? index: %d, mindist: %g, thresh: %g",
+	     mindistidx, mindist, thresh);
+    
+    if (thresh > 0 && mindist > thresh) {
+	return 0;
+    }
+    
+    /* set index and other things */
+    switch(mindistidx) {
+	/* for each mindistidx create new line */
+    case 0: 
+	Vect_append_points (ps, Points2, GV_BACKWARD);
+	if (ps -> n_points == Points2 -> n_points)
+	    Vect_append_points (ps, Points1, GV_FORWARD);
+	break;
+    case 1: 
+	Vect_append_points (ps, Points2, GV_FORWARD);
+	if (ps -> n_points == Points2 -> n_points)
+	    Vect_append_points (ps, Points1, GV_FORWARD);
+	break;
+    case 2: 
+	if (ps -> n_points == 0)
+	    Vect_append_points (ps, Points1, GV_FORWARD);
+	Vect_append_points (ps, Points2, GV_FORWARD);
+	break;
+    case 3: 
+	if (ps -> n_points == 0)
+	    Vect_append_points (ps, Points1, GV_FORWARD);
+	Vect_append_points (ps, Points2, GV_BACKWARD);
+	break;
+    default:
+	break;
+    }
+    
+    /* remove duplicate points */
+    Vect_line_prune (ps);
+
+    /* copy categories if needed */
+    for (i = 0; i < Cats2 -> n_cats; i++) {
+	Vect_cat_set (cs, Cats2 -> field[i], Cats2 -> cat[i]);
+    }
+
+    return 1;
+}

Copied: grass/trunk/vector/v.edit/lib/move.c (from rev 29679, grass/trunk/vector/v.edit/move.c)
===================================================================
--- grass/trunk/vector/v.edit/lib/move.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/lib/move.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,89 @@
+/**
+   \brief Vedit library - snapping
+
+   This program is free software under the
+   GNU General Public License (>=v2).
+   Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) 2007-2008 by the GRASS Development Team
+   Martin Landa <landa.martin gmail.com>
+   Jachym Cepicky <jachym.cepicky gmail.com>
+
+   \date 2007-2008
+*/
+
+#include "vedit.h"
+
+/**
+   \brief Move selected features
+   
+   \param[in] Map vector map
+   \param[in] List list of features to be moved
+   \param[in] move_x,move_y,move_z direction (move_z used only if map is 3D)
+   \param[in] snap enable snapping (see globals.h)
+
+   \return number of modified features
+   \return -1 on error
+*/
+int Vedit_move_lines(struct Map_info *Map, struct ilist *List, 
+		     double move_x, double move_y, double move_z,
+		     int snap, double thresh)
+{
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+    int i, j;
+    int type, newline, line;
+    int nlines_moved;
+    double *x, *y, *z;
+
+    nlines_moved = 0;
+
+    Points = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+
+    for (i = 0; i < List->n_values; i++) {
+	line = List -> value[i];
+
+	if (!Vect_line_alive (Map, line))
+	    continue;
+
+        type = Vect_read_line(Map, Points, Cats, line);
+
+        G_debug(3, "Vedit_move_lines(): type=%d, id=%d", type, line);
+
+	x = Points->x;
+	y = Points->y;
+	z = Points->z;
+
+        /* move */
+        for (j = 0; j < Points -> n_points; j++) {
+	    x[j] += move_x;
+            y[j] += move_y;
+	    if (Vect_is_3d(Map))
+		z[j] += move_z;
+
+	    if (snap != NO_SNAP) {
+		if (Vedit_snap_point(Map, line, &x[j], &y[j], &z[j], thresh,
+				     (snap == SNAPVERTEX) ? 1 : 0) == 0) {
+		    /* check also background maps */
+		}
+	    }
+        } /* for each point at line */
+
+	newline = Vect_rewrite_line (Map, line, type, Points, Cats);
+
+        if (newline < 0)  {
+	    G_warning(_("Unable to rewrite line %d"),
+		      line);
+            return -1;
+        }
+
+        nlines_moved++;
+    }
+        
+    Vect_destroy_line_struct (Points);
+    Vect_destroy_cats_struct (Cats);
+
+    return nlines_moved;
+}

Copied: grass/trunk/vector/v.edit/lib/snap.c (from rev 29679, grass/trunk/vector/v.edit/snap.c)
===================================================================
--- grass/trunk/vector/v.edit/lib/snap.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/lib/snap.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,195 @@
+/**
+   \brief Vedit library - snapping
+
+   This program is free software under the
+   GNU General Public License (>=v2).
+   Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) 2007-2008 by the GRASS Development Team
+   Martin Landa <landa.martin gmail.com>
+
+   \date 2007-2008
+*/
+
+#include "vedit.h"
+
+/**
+   \brief Snap given point to the nearest feature
+   
+   \param[in] Map vector map
+   \param[in] line line id to be snapped
+   \param[in] x,y,z point on line to be snapped
+   \param[in] thresh snapping threshold (>0)
+   \param[in] vertex snap also to vertex
+
+   \return 1 snapped
+   \return 0 not snapped
+*/
+int Vedit_snap_point(struct Map_info *Map,
+		     int line, double *x, double *y, double *z, double thresh,
+		     int vertex)
+{
+    struct line_pnts *Points;
+    
+    int i, snapped;
+    int line2snap, mindist_idx;
+    double dist, mindist;
+    
+    snapped = 0;
+    mindist_idx = -1;
+    mindist = thresh;
+    
+    Points = Vect_new_line_struct();
+
+    line2snap = Vect_find_line(Map, *x, *y, *z,
+			       -1, thresh, WITHOUT_Z, line);
+    
+    if (line2snap > 0) {
+	Vect_read_line(Map, Points, NULL, line2snap);
+	
+	if (!Vect_line_alive(Map, line2snap)) {
+	    Vect_destroy_line_struct(Points);
+	    return snapped;
+	}
+
+	for (i = 0; i < Points->n_points; i++) {
+	    if (i > 0 && i < Points->n_points-1)
+	      if (!vertex)
+		continue;
+	    dist = Vect_points_distance(*x, *y, *z,
+					Points->x[i], Points->y[i], Points->z[i],
+					WITHOUT_Z);
+
+	    if (mindist >= dist) {
+		mindist = dist;
+		mindist_idx = i;
+	    }
+	}
+				
+	if(mindist_idx > -1) {
+	    *x = Points->x[mindist_idx];
+	    *y = Points->y[mindist_idx];
+	    *z = Points->z[mindist_idx];
+	    snapped = 1;
+	}
+    }
+
+    Vect_destroy_line_struct(Points);
+
+    return snapped;
+}
+
+/**
+   \brief Snap lines/boudaries to the nearest feature
+   
+   \param[in] Map vector map
+   \param[in] BgMap,nbgmaps List of background maps
+   \param[in] line line to be snapped
+   \param[in] layer layer number
+   \param[in] thresh threshold value used for snapping (>0)
+   \param[in] to_vertex allow snapping also to vertex
+
+   \return 1 line snapped
+   \return 0 line not snapped
+   \return -1 line is dead
+*/
+int Vedit_snap_line(struct Map_info *Map, struct Map_info **BgMap, int nbgmaps,
+		    int line,
+		    double thresh, int to_vertex)
+{
+    int i, type, npoints, node, rewrite;
+    double *x, *y, *z;
+
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+
+    Points = Vect_new_line_struct();
+    Cats   = Vect_new_cats_struct();
+
+    if (!Vect_line_alive (Map, line))
+	return -1;
+
+    type = Vect_read_line(Map, Points, Cats, line);
+    npoints = Points -> n_points;
+    x = Points->x;
+    y = Points->y;
+    z = Points->z;
+    
+    rewrite = 0;
+    for (node = 0; node < npoints; node++) {
+	if ((node > 0  && node < npoints -1) &&
+	    !to_vertex)
+	    continue;
+	
+	if (Vedit_snap_point(Map, line, &x[node], &y[node], &z[node], thresh,
+			     to_vertex)) {
+	    rewrite = 1;
+	}
+	else {
+	    /* check also background maps */
+	    int bgi;
+	    for (bgi = 0; bgi < nbgmaps; bgi++) {
+		if (Vedit_snap_point(BgMap[i], line, &x[node], &y[node], &z[node], thresh,
+				     to_vertex)) {
+		    rewrite = 1;
+		    break; /* snapped, don't continue */
+		}
+	    }
+	}
+    } /* for each line vertex */
+    
+    /* close boundaries or lines */
+    if (!rewrite && (type & GV_LINES) &&
+	Vect_points_distance(x[0], y[0], z[0],
+			     x[npoints-1], y[npoints-1], z[npoints-1],
+			     WITHOUT_Z) <= thresh) {
+	x[npoints-1] = x[0];
+	y[npoints-1] = y[0];
+	z[npoints-1] = z[0];
+	
+	rewrite = 1;
+    }
+
+    if (rewrite) {
+	if (Vect_rewrite_line (Map, line, type, Points, Cats) < 0) {
+	    G_warning(_("Unable to rewrite line %d"), line);
+	    return -1;
+	}
+    }
+    
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_cats_struct(Cats);
+
+    return rewrite;
+}
+
+/**
+   \brief Snap lines/boudaries to the nearest feature
+   
+   \param[in] Map vector map
+   \param[in] BgMap,nbgmaps List of background maps
+   \param[in] List list of lines to be snapped
+   \param[in] layer layer number
+   \param[in] thresh threshold value used for snapping (>0)
+   \param[in] to_vertex allow snapping also to vertex
+
+   \return number of snapped lines
+*/
+int Vedit_snap_lines(struct Map_info *Map, struct Map_info **BgMap, int nbgmaps,
+		     struct ilist* List,
+		     double thresh, int to_vertex)
+{
+    int i, line;
+    int nlines_modified;
+
+    for(i = 0; i < List -> n_values; i++) {
+	line = List -> value[i];
+	if (Vedit_snap_line(Map, BgMap, nbgmaps,
+			    line, thresh, to_vertex) == 1) {
+	    nlines_modified++;
+	}
+    }
+
+    return nlines_modified;
+}

Added: grass/trunk/vector/v.edit/lib/vedit.h
===================================================================
--- grass/trunk/vector/v.edit/lib/vedit.h	                        (rev 0)
+++ grass/trunk/vector/v.edit/lib/vedit.h	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,72 @@
+#ifndef __VEDIT_H__
+#define __VEDIT_H__
+
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+
+#define NO_SNAP    0 /* snapping disabled */
+#define SNAP       1 /* snapping enabled for nodes */
+#define SNAPVERTEX 2 /* snapping enabled for vertex also */
+
+/* break.c */
+int Vedit_split_lines(struct Map_info *, struct ilist *,
+		      struct line_pnts *, double,
+		      struct ilist *);
+int Vedit_connect_lines (struct Map_info *, struct ilist *,
+			 double);
+
+/* cats.c */
+int Vedit_modify_cats (struct Map_info *, struct ilist *,
+		       int, int, struct cat_list *);
+
+/* copy.c */
+int Vedit_copy_lines (struct Map_info *, struct Map_info *,
+		      struct ilist *);
+
+/* delete.c */
+
+int Vedit_delete_lines(struct Map_info *, struct ilist *);
+
+/* distance.c */
+double Vedit_get_min_distance(struct line_pnts *, struct line_pnts *,
+			      int, int *);
+
+/* flip.c */
+int Vedit_flip_lines(struct Map_info *, struct ilist *);
+
+/* merge.c */
+int Vedit_merge_lines(struct Map_info *, struct ilist *);
+
+/* move.c */
+int Vedit_move_lines(struct Map_info *, struct ilist *, 
+		     double, double, double, int, double);
+
+/* snap.c */
+int Vedit_snap_point(struct Map_info *,
+		     int, double *, double *, double *, double,
+		     int);
+int Vedit_snap_line(struct Map_info *, struct Map_info **, int,
+		    int,
+		    double, int);
+int Vedit_snap_lines(struct Map_info *, struct Map_info **, int,
+		     struct ilist*,
+		     double, int);
+
+/* vertex.c */
+int Vedit_move_vertex(struct Map_info *, struct Map_info **, int,
+		      struct ilist *,
+		      struct line_pnts*, double,
+		      double, double, double,
+		      int, int);
+int Vedit_add_vertex(struct Map_info *Map, struct ilist *,
+		     struct line_pnts*, double);
+int Vedit_remove_vertex(struct Map_info *, struct ilist *,
+			struct line_pnts *, double);
+
+/* zbulk.c */
+int Vedit_bulk_labeling (struct Map_info *, struct ilist *,
+			 double, double, double, double,
+			 double, double);
+
+#endif /* __VEDIT_H__ */

Copied: grass/trunk/vector/v.edit/lib/vertex.c (from rev 29679, grass/trunk/vector/v.edit/vertex.c)
===================================================================
--- grass/trunk/vector/v.edit/lib/vertex.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/lib/vertex.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,342 @@
+/**
+   \brief Vedit library - vertex manipulation
+
+   This program is free software under the
+   GNU General Public License (>=v2).
+   Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) 2006-2008 by the GRASS Development Team
+   Jachym Cepicky <jachym.cepicky gmail.com>
+   Martin Landa <landa.martin gmail.com>
+
+   \date 2006-2008
+*/
+
+#include "vedit.h"
+
+/**
+   \brief Move all vertices in bounding box(es)
+
+   \param[in] Map vector map
+   \param[in] BgMap, nbgmaps list of background vector maps for snapping
+   \param[in] List list of selected features
+   \param[in] coord points location
+   \param[in] thresh threshold value (also size of bounding boxes) (>0)
+   \param[in] move_x,move_y,move_z direction (move_z is used when map is 3D)
+   \param[in] move_first move only first vertex found in the bounding box
+   \param[in] snap snapping mode (see vedit.h)
+
+   \return number of moved verteces
+   \return -1 on error
+ */
+int Vedit_move_vertex(struct Map_info *Map, struct Map_info **BgMap, int nbgmaps,
+		      struct ilist *List,
+		      struct line_pnts* coord, double thresh,
+		      double move_x, double move_y, double move_z,
+		      int move_first, int snap)
+{
+    int nvertices_moved, nlines_modified, nvertices_snapped;
+
+    int i, j, k;
+    int line, type, rewrite;
+    int npoints;
+    double east, north, dist;
+    double *x, *y, *z;
+    char *moved;
+
+    struct line_pnts *Points, *Points_snap;
+    struct line_cats *Cats;
+    
+    nlines_modified = 0;
+    nvertices_moved = nvertices_snapped = 0;
+    moved = NULL;
+
+    Points = Vect_new_line_struct();
+    Points_snap = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+
+    for (i = 0; i < List -> n_values; i++) {
+	line = List -> value[i];
+	
+	if (!Vect_line_alive (Map, line))
+	    continue;
+	
+	type = Vect_read_line(Map, Points, Cats, line);
+
+	if (!(type & GV_LINES))
+	    continue;
+
+	npoints = Points -> n_points;
+	x = Points -> x;
+	y = Points -> y;
+	z = Points -> z;
+
+	/* vertex moved 
+	   0 not moved
+	   1 moved
+	   2 moved and snapped
+	 */
+	moved = (char *) G_realloc ((void *) moved, Points -> n_points * sizeof (char));
+	G_zero ((void *) moved, Points -> n_points * sizeof (char));
+	
+	rewrite = 0;
+	for (j = 0; j < coord -> n_points; j++) {
+	    east  = coord->x[j];
+	    north = coord->y[j];
+	    
+	    /* move all vertices in the bounding box */
+	    for (k = 0; k < Points -> n_points; k++) {
+		if (moved[k] == 0) {
+		    dist = Vect_points_distance (east, north, 0.0,
+						 x[k], y[k], z[k],
+						 WITHOUT_Z);
+		    if (dist <= thresh) {
+			G_debug (3, "Vedit_move_vertex(): line=%d; x=%f, y=%f -> x=%f, y=%f",
+				 line, x[k], y[k], x[k] + move_x, y[k] + move_y);
+			x[k] += move_x;
+			y[k] += move_y;
+			if (Vect_is_3d(Map))
+			  z[k] += move_z;
+
+			moved[k] = 1;
+
+			G_debug (3, "Vedit_move_vertex(): line=%d, point=%d", line, k);
+			
+			if (snap != NO_SNAP) {
+			    if (Vedit_snap_point(Map, line, &x[k], &y[k], &z[k], thresh,
+						(snap == SNAPVERTEX) ? 1 : 0) == 0) {
+				/* check also background maps */
+				int bgi;
+				for (bgi = 0; bgi < nbgmaps; bgi++) {
+				    if (Vedit_snap_point(BgMap[i], line, &x[k], &y[k], &z[k], thresh,
+							 (snap == SNAPVERTEX) ? 1 : 0))
+					moved[k] = 2;
+					break; /* snapped, don't continue */
+				}
+			    }
+			    else {
+				moved[k] = 2;
+			    }
+			}
+			
+			rewrite = 1;
+			nvertices_moved++;
+
+			if (move_first)
+			    break;
+		    }
+		}
+	    } /* for each line vertex */
+
+	    /* close line or boundary */
+	    if ((type & GV_LINES) &&
+		Vect_points_distance(x[0], y[0], z[0],
+				     x[npoints-1], y[npoints-1], z[npoints-1],
+				     WITHOUT_Z) <= thresh) {
+
+		if (moved[0] == 1) { /* first node moved */
+		    x[0] = x[npoints-1];
+		    y[0] = y[npoints-1];
+		    if (Vect_is_3d(Map))
+			z[0] = z[npoints-1];
+		}
+		else if (moved[npoints-1] == 1) { /* last node moved */
+		    x[npoints-1] = x[0];
+		    y[npoints-1] = y[0];
+		    if (Vect_is_3d(Map))
+			z[npoints-1] = z[0];
+		}
+	    }
+	} /* for each coord */
+	
+	if (rewrite) {
+	    if (Vect_rewrite_line (Map, line, type, Points, Cats) < 0)  {
+		G_warning(_("Unable to rewrite line %d"), line);
+		return -1;
+	    }
+	    
+	    nlines_modified++;
+	}
+    } /* for each selected line */
+
+    /* destroy structures */
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_line_struct(Points_snap);
+    Vect_destroy_cats_struct(Cats);
+/*     G_free ((void *) moved); */
+
+    return nvertices_moved;
+}
+
+/**
+   \brief Add new vertex to line.
+
+   Shape of line is not changed.
+
+   TODO: 3D
+
+   \param[in] Map vector map
+   \param[in] List list of features
+   \param[in] coord points location
+   \param[in] thresh find line in given threshold
+
+   \return number of add verteces
+   \return -1 on error
+*/
+int Vedit_add_vertex(struct Map_info *Map, struct ilist *List,
+		     struct line_pnts* coord, double thresh)
+{
+    int i, j;
+    int type, line, seg;
+    int nlines_modified, nvertices_added, rewrite;
+    double east, north, dist;
+    double *x, *y, *z;
+    double px, py;
+
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+
+    nlines_modified = 0;
+    nvertices_added = 0;
+    Points  = Vect_new_line_struct();
+    Cats    = Vect_new_cats_struct();
+
+    for (i = 0; i < List -> n_values; i++) {
+	line = List -> value[i];
+
+	if (!Vect_line_alive (Map, line))
+	    continue;
+
+        type = Vect_read_line(Map, Points, Cats, line);
+
+	if (!(type & GV_LINES))
+	    continue;
+
+	x = Points -> x;
+	y = Points -> y;
+	z = Points -> z;
+	rewrite = 0;
+	for (j = 0; j < coord -> n_points; j++) {
+	    east  = coord->x[j];
+	    north = coord->y[j];
+
+	    seg = Vect_line_distance (Points,
+				      east, north, 0.0,    /* standpoint */
+				      WITHOUT_Z,
+				      &px, &py, NULL,      /* point on line */
+				      &dist,               /* distance to line */
+				      NULL, NULL);
+	    
+	    if (dist <= thresh &&
+		Vect_points_distance (px, py, 0.0, x[seg], y[seg], z[seg], WITHOUT_Z) > 0 &&
+		Vect_points_distance (px, py, 0.0, x[seg-1], y[seg-1], z[seg-1], WITHOUT_Z) > 0) {
+		/* add new vertex */
+		Vect_line_insert_point (Points, seg, px, py, 0.0);
+		G_debug (3, "Vedit_add_vertex(): line=%d; x=%f, y=%f, index=%d", line, px, py, seg);
+		rewrite = 1;
+		nvertices_added++;
+	    }
+	} /* for each point */
+
+	/* rewrite the line */
+	if (rewrite) {
+	    Vect_line_prune (Points);
+	    if (Vect_rewrite_line (Map, line, type, Points, Cats) < 0) {
+		G_warning(_("Unable to rewrite line %d"), line);
+		return -1;
+	    }
+		
+	    nlines_modified++;
+	}
+    } /* for each line */
+
+    /* destroy structures */
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_cats_struct(Cats);
+
+    return nvertices_added;
+}
+
+/**
+   \brief Remove vertex from line
+
+   TODO: 3D
+
+   \param[in] Map vector map
+   \param[in] List list of selected features
+   \param[in] coord points location
+   \param[in] thresh threshold value to find a line
+
+   \return number of removed vertices
+   \return -1 on error
+*/
+int Vedit_remove_vertex(struct Map_info *Map, struct ilist *List,
+			struct line_pnts *coord, double thresh)
+{
+    int i, j, k;
+    int type, line;
+    int nvertices_removed, rewrite, nlines_modified;
+    double east, north;
+    double dist;
+    double *x, *y, *z;
+
+    struct line_pnts *Points;
+    struct line_cats *Cats;
+
+    nvertices_removed = nlines_modified = 0;
+
+    Points = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+    
+    for (i = 0; i < List -> n_values; i++) {
+	line = List -> value[i];
+	
+	if (!Vect_line_alive (Map, line))
+	    continue;
+	
+        type = Vect_read_line(Map, Points, Cats, line);
+
+	if (!(type & GV_LINES))
+	    continue;
+
+	x = Points -> x;
+	y = Points -> y;
+	z = Points -> z;
+	rewrite = 0;
+	for (j = 0; j < coord -> n_points; j++) {
+	    east  = coord->x[j];
+	    north = coord->y[j];
+	    
+	    for (k = 0; k < Points -> n_points; k++) {
+		dist = Vect_points_distance (east, north, 0.0,
+					     x[k], y[k], z[k],
+					     WITHOUT_Z);
+		if (dist <= thresh) {
+		    /* remove vertex */
+		    Vect_line_delete_point (Points, k);
+		    G_debug (3, "Vedit_remove_vertex(): line=%d; x=%f, y=%f, index=%d", line, x[k], y[k], k);
+		    k--;
+		    nvertices_removed++;
+		    rewrite = 1;
+		}
+	    } /* for each point */
+	} /* for each bounding box */
+	
+	if (rewrite) {
+	    /* rewrite the line */
+	    if (Vect_rewrite_line (Map, line, type, Points, Cats) < 0) {
+		G_warning (_("Unable to rewrite line %d"), line);
+		return -1;
+	    }
+	    
+	    nlines_modified++;
+	}
+    } /* for each line */
+
+    /* destroy structures */
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_cats_struct(Cats);
+    
+    return nvertices_removed;
+}

Copied: grass/trunk/vector/v.edit/lib/zbulk.c (from rev 29679, grass/trunk/vector/v.edit/zbulk.c)
===================================================================
--- grass/trunk/vector/v.edit/lib/zbulk.c	                        (rev 0)
+++ grass/trunk/vector/v.edit/lib/zbulk.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -0,0 +1,127 @@
+/**
+   \brief Vedit library - Bulk labeling (automated labeling of vector features)
+
+   This program is free software under the
+   GNU General Public License (>=v2).
+   Read the file COPYING that comes with GRASS
+   for details.
+
+   \author (C) 2007-2008 by the GRASS Development Team
+   Martin Landa <landa.martin gmail.com>
+
+   \date 2007-2008
+*/
+
+#include <grass/dbmi.h>
+#include "vedit.h"
+
+/**
+   \brief Z bulk-labeling.
+
+   Automated labeling (z coordinate assignment) of vector lines (contours).
+
+   \param[in] Map vector map
+   \param[in] List list of selected features
+   \param[in] point_start_end staring and ending point
+   \param[in] start starting value
+   \param[in] step step
+
+   \return number of modified features
+   \return -1 on error
+*/
+int Vedit_bulk_labeling (struct Map_info *Map, struct ilist *List,
+			 double x1, double y1, double x2, double y2,
+			 double start, double step)
+{
+    int i, cv_i, p_i;
+    int line, type, temp_line;
+    int nlines_modified;
+    double value, dist;
+
+    struct line_cats *Cats;
+    struct line_pnts *Points, *Points_se; /* start - end */
+    /* for intersection */
+    struct line_pnts **Points_a, **Points_b;
+    int nlines_a, nlines_b;
+
+    dbCatValArray cv; /* line_id / dist */
+
+    nlines_modified = 0;
+
+    value = start;
+
+    Points = Vect_new_line_struct();
+    Points_se = Vect_new_line_struct();
+    Cats = Vect_new_cats_struct();
+
+    //cv = (dbCatValArray *) G_malloc (sizeof (dbCatValArray));
+    db_CatValArray_alloc(&cv, List->n_values);
+    cv.ctype    = DB_C_TYPE_DOUBLE;
+    cv.n_values = 0;
+
+    Vect_append_point(Points_se, x1, y1, -PORT_DOUBLE_MAX);
+    Vect_append_point(Points_se, x2, y2, PORT_DOUBLE_MAX);
+
+    /* write temporaly line */
+    temp_line = Vect_write_line(Map, GV_LINE, Points_se, Cats);
+
+    /* determine order of lines */
+    cv_i = 0;
+    for (i = 0; i < List->n_values; i++) {
+	line = List->value[i];
+
+	if (!Vect_line_alive(Map, line))
+	    continue;
+
+	type = Vect_read_line(Map, Points, NULL, line);
+
+	if (!(type & GV_LINE))
+	    continue;
+
+	if (Vect_line_check_intersection(Points_se, Points, WITH_Z)) {
+	    Vect_line_intersection (Points_se, Points,
+				    &Points_a, &Points_b, &nlines_a, &nlines_b,
+				    WITHOUT_Z);
+
+	    if (nlines_a < 2 || nlines_b < 1) /* should not happen */
+		continue;
+
+	    /* calculate distance start point -> point of intersection */
+	    for (p_i = 0; p_i < Points_a[0]->n_points; p_i++) {
+		Points_a[0]->z[p_i] = 0;
+	    }
+	    dist = Vect_line_length(Points_a[0]); /* always first line in array? */
+
+	    cv.value[cv_i].cat     = line;
+	    cv.value[cv_i++].val.d = dist;
+	    cv.n_values++;
+	}
+    }
+
+    /* sort array by distance */
+    db_CatValArray_sort_by_value(&cv);
+
+    /* z bulk-labeling */
+    for (cv_i = 0; cv_i < cv.n_values; cv_i++) {
+	line = cv.value[cv_i].cat;
+	Vect_read_line(Map, Points, Cats, line);
+
+	for(p_i = 0; p_i < Points->n_points; p_i++) {
+	    Points->z[p_i] = value;
+	}
+	
+	Vect_rewrite_line(Map, line, type, Points, Cats);
+	nlines_modified++;
+
+	value += step;
+    }
+
+    Vect_delete_line(Map, temp_line);
+
+    db_CatValArray_free(&cv);
+    Vect_destroy_line_struct(Points);
+    Vect_destroy_line_struct(Points_se);
+    Vect_destroy_cats_struct(Cats);
+
+    return nlines_modified;
+}

Deleted: grass/trunk/vector/v.edit/main.c
===================================================================
--- grass/trunk/vector/v.edit/main.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/main.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,392 +0,0 @@
-/****************************************************************
- *
- * MODULE:     v.edit
- *
- * AUTHOR(S):  GRASS Development Team
- *             Wolf Bergenheim, Jachym Cepicky, Martin Landa
- *
- * PURPOSE:    This module edits vector map.
- *
- * COPYRIGHT:  (C) 2002-2007 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;
-
-    ascii  = NULL;
-    List   = NULL;
-    BgMap  = NULL;
-    nbgmaps = 0;
-    coord  = 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, &params, &action_mode))
-	exit(EXIT_FAILURE);
-
-    /* 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,
-				&params,
-				List);
-	}
-	else {
-	    List = select_lines(&Map, action_mode,
-				&params,
-				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 */
-		do_snapping (&Map, BgMap, nbgmaps,
-			     List_added,
-			     thresh,
-			     snap == SNAP ? 0 : 1); /* snap to vertex ? */
-	    }
-	    if (params.close -> answer) { /* close boundaries */
-		int nclosed;
-		nclosed = do_close (&Map, GV_BOUNDARY, thresh);
-		G_message (_("%d lines closed"), nclosed);
-	    }
-	}
-	Vect_destroy_list (List_added);
-	break;
-    case MODE_DEL:
-	ret = do_delete(&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 = do_move(&Map, List,
-		      move_x, move_y, snap, thresh);
-	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 = do_move_vertex (&Map, BgMap, nbgmaps,
-			      List,
-			      coord, thresh,
-			      move_x, move_y,
-			      move_first, snap);
-	G_message(_("%d vertices moved"), ret);
-	break;
-    case MODE_VERTEX_ADD:
-	ret = do_add_vertex (&Map, List,
-			     coord, thresh);
-	G_message(_("%d vertices added"), ret);    
-	break;
-    case MODE_VERTEX_DELETE:
-	ret = do_remove_vertex(&Map, List,
-			       coord, thresh);
-	G_message(_("%d vertices removed"), ret);
-	break;
-    case MODE_BREAK:
-	if (params.coord->answer) {
-	    ret = do_split(&Map, List,
-			   coord, thresh, NULL);
-	}
-	else {
-	    ret = do_break(&Map, List);
-	}
-	G_message(_("%d lines broken"), ret);
-	break;
-    case MODE_CONNECT:
-	ret = do_connect(&Map, List,
-			 thresh);
-	G_message(_("%d lines connected"), ret);
-      	break;
-    case MODE_MERGE:
-	ret = do_merge(&Map, List);
-	G_message (_("%d lines merged"), ret);
-    	break;
-    case MODE_SELECT:
-	print = 1;
-	ret = do_print_selected(List);
-	break;
-    case MODE_CATADD:
-	ret = cats(&Map, List,
-		   layer, 0, params.cat -> answer);
-	G_message(_("%d features modified"), ret);
-    	break;
-    case MODE_CATDEL:
-	ret = cats(&Map, List,
-		   layer, 1, params.cat -> answer);
-	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 = do_copy(&Map, BgMap[0], List);
-	}
-	else {
-	    ret = do_copy(&Map, NULL, List);
-	}
-	G_message (_("%d features copied"), ret);
-	break;
-    case MODE_SNAP:
-	ret = do_snap(&Map, List, thresh);
-	break;
-    case MODE_FLIP:
-	ret = do_flip(&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 = bulk_labeling (&Map, List,
-			     x1, y1, x2, y2,
-			     start, step);
-
-	G_message(_("%d lines labeled"), ret);
-	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);
-
-    G_done_msg (" ");
-
-    if (ret > -1) {
-	exit (EXIT_SUCCESS);
-    }
-    else {
-	exit (EXIT_FAILURE);
-    }
-}

Deleted: grass/trunk/vector/v.edit/max_distance.c
===================================================================
--- grass/trunk/vector/v.edit/max_distance.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/max_distance.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,143 +0,0 @@
-/****************************************************************
- *
- * MODULE:     v.edit
- *
- * AUTHOR(S):  GRASS Development Team
- *             Jachym Cepicky <jachym  les-ejk cz>
- *             Martin Landa <landa.martin gmail.com>
- *
- * PURPOSE:    This module edits vector map.
- *
- * COPYRIGHT:  (C) 2002-2007 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.
- *
- ****************************************************************/
-
-#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 Calculate distances between two lines
- 
-   array distances hold distances between first and last point of both lines:
-   distances[0] = first-first
-   distances[1] = first-last
-   distances[2] = last-first
-   distances[3] = last-last
-   
-   \param[in] Points1 first line
-   \param[in] Points2 second line
-   \param[out] index of minimal distance
-
-   \return minimal distance 
-*/
-double min_distance_line (struct line_pnts *Points1, struct line_pnts *Points2,
-			  int* mindistidx)
-{
-    unsigned int i;
-    double distances [4];
-
-    distances[0] = Vect_points_distance(Points1->x[0], Points1->y[0], Points1->z[0],
-					Points2->x[0], Points2->y[0], Points2->z[0], 0);
-    
-    distances[1] = Vect_points_distance(Points1->x[0], Points1->y[0], Points1->z[0],
-					Points2->x[Points2->n_points-1],
-					Points2->y[Points2->n_points-1],
-					Points2->z[Points2->n_points-1], 0);
-    
-    distances[2] = Vect_points_distance(Points1->x[Points1->n_points-1],
-					Points1->y[Points1->n_points-1],
-					Points1->z[Points1->n_points-1],
-					Points2->x[0], Points2->y[0], Points2->z[0], 0);
-    
-    distances[3] = Vect_points_distance(Points1->x[Points1->n_points-1],
-					Points1->y[Points1->n_points-1],
-					Points1->z[Points1->n_points-1],
-					Points2->x[Points2->n_points-1],
-					Points2->y[Points2->n_points-1],
-					Points2->z[Points2->n_points-1], 0);
-    
-    /* find the minimal distance between first or last point of both lines */
-    *mindistidx = 0;
-    for (i = 0; i < sizeof (distances) / sizeof (double); i++) {
-	if (distances[i] >= 0.0 && distances[i] < distances[*mindistidx])
-	    *mindistidx = i;
-    }
-
-    return distances [*mindistidx];
-}
-
-/**
-   \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;
-}

Deleted: grass/trunk/vector/v.edit/merge.c
===================================================================
--- grass/trunk/vector/v.edit/merge.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/merge.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,251 +0,0 @@
-/****************************************************************
- *
- * MODULE:     v.edit
- *
- * AUTHOR(S):  GRASS Development Team
- *             Original author Jachym Cepicky <jachym  les-ejk cz>
- *             Updated by Martin Landa <landa.martin gmail.com> (2007/03)
- *
- * PURPOSE:    This module edits vector map.
- *             Merge lines.
- *
- * COPYRIGHT:  (C) 2002-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.
- *
- ****************************************************************/
-
-#include "global.h"
-
-/**
-   \brief Merge two given lines a, b
-   
-   a : Points1/Cats1
-   b : Points2/Cats2
-   merged line : Points/Cats
-   
-   \param[in] Points1,Cats1 first line
-   \param[in] Points2,Cats2 second line
-   \param[in] thresh threshold value
-   \param[out] Points result line
-
-   \return 1 on success
-   \return 0 on error
-*/
-static int merge_lines (struct line_pnts *Points1, struct line_cats *Cats1, 
-			struct line_pnts *Points2, struct line_cats *Cats2,
-			double thresh, struct line_pnts **Points);
-
-/**
-   \brief Merge lines/boundaries
- 
-   \param[in] Map vector map
-   \param[in] List list of selected features
-
-   \return number of merged lines
-   \return -1 on error
-*/
-int do_merge(struct Map_info *Map, struct ilist *List)
-{
-    struct ilist *List_in_box;
-    
-    struct line_pnts *Points1, *Points2, *Points;
-    struct line_cats *Cats1, *Cats2;
-    
-    int line_i, i, j;    
-    int line, line1, type1, line2, type2;
-    int do_merge;
-    /* number of lines (original, selected, merged) */
-    int nlines, nlines_selected, nlines_merged;
-    
-    nlines_merged = 0;
-    
-    if (List->n_values < 2) {
-	G_warning (_("Only %d lines found, at least two needed"),
-		   List->n_values);
-	return -1;
-    }
-    
-    Points1 = Vect_new_line_struct();
-    Cats1   = Vect_new_cats_struct();
-    Points2 = Vect_new_line_struct();
-    Cats2   = Vect_new_cats_struct();
-    Points  = Vect_new_line_struct();
-    
-    List_in_box = Vect_new_list();
-    
-    nlines          = Vect_get_num_lines (Map);
-    nlines_selected = List -> n_values;
-    
-    /* merge lines */
-    for (line_i = 0; line_i < List -> n_values; line_i++) {
-	G_percent (line_i, List -> n_values, 2);
-	
-	line1 = List -> value[line_i];
-	
-	if (!Vect_line_alive (Map, line1))
-	    continue;
-	
-	type1 = Vect_read_line (Map, Points1, Cats1, line1);
-	
-	if (!(type1 & GV_LINES))
-	    continue;
-	
-	Vect_reset_line (Points);
-	
-	for (i = 0; i < Points1 -> n_points; i += Points1 -> n_points - 1) {
-	    Vect_reset_list (List_in_box);
-	    
-	    /* define searching region */
-	    Vect_reset_line (Points2);
-	    /*
-	      Vect_append_point (Points2, Points1 -> x[i] - thresh,
-	      Points1 -> y[i] + thresh, Points1 -> z[i]);
-	      Vect_append_point (Points2, Points1 -> x[i] + thresh,
-	      Points1 -> y[i] + thresh, Points1 -> z[i]);
-	      Vect_append_point (Points2, Points1 -> x[i] + thresh,
-	      Points1 -> y[i] - thresh, Points1 -> z[i]);
-	      Vect_append_point (Points2, Points1 -> x[i] - thresh,
-	      Points1 -> y[i] - thresh, Points1 -> z[i]);
-	    */
-	    Vect_append_point (Points2, Points1 -> x[i],
-			       Points1 -> y[i], Points1 -> z[i]);
-	    
-	    /* 
-	     * merge lines only if two lines found in the region
-	     * i.e. the current line and an adjacent line
-	     */
-	    if (1 < Vect_select_lines_by_polygon (Map, Points2, 0, NULL,
-						  GV_LINES, List_in_box)) {
-		do_merge = 1;
-		line2 = -1;
-		for (j = 0; do_merge && j < List -> n_values; j++) {
-		    if (List -> value[j] == line1 ||
-			!Vect_line_alive(Map, List -> value[j]))
-			continue;
-		    
-		    if (Vect_val_in_list (List_in_box, List -> value[j])) {
-			if (line2 > 0) {
-			    /* three lines found
-			     * selected lines will be not merged
-			     */
-			    do_merge = 0;
-			}
-			else {
-			    line2 = List -> value[j];
-			}
-		    }
-		}
-		
-		if (!do_merge || line2 < 0)
-		    continue;
-		
-		type2 = Vect_read_line (Map, Points2, Cats2, line2);
-		
-		merge_lines (Points1, Cats1,
-			     Points2, Cats2,
-			     -1.0,  &Points); /* do not use threshold value */
-		
-		G_debug (3, "merge lines: %d, %d", line1, line2);
-		
-		if (Points -> n_points > 0) {
-		    if (Vect_delete_line(Map, line2) == -1) {
-			G_warning (_("Unable to delete line %d"),
-				   line2);
-			return -1;
-		    }
-		    
-		    if (line2 <= nlines)
-			nlines_merged++;
-		}
-	    }
-	} /* for each node */
-	
-	if (Points -> n_points > 0) {
-	    line = Vect_rewrite_line (Map, line1, type1, Points, Cats1);
-	    if (line < 0) {
-		G_warning (_("Unable to rewrite line %d"),
-			   line1);
-		return -1;
-	    }
-	    
-	    if (line1 <= nlines)
-		nlines_merged++;
-	    
-	    /* update number of lines */
-	    Vect_list_append (List, line);
-	}
-    } /* for each line */
-    
-    /* destroy stuctures */
-    Vect_destroy_line_struct(Points1);
-    Vect_destroy_line_struct(Points2);
-    Vect_destroy_line_struct(Points);
-    
-    Vect_destroy_cats_struct(Cats1);
-    Vect_destroy_cats_struct(Cats2);
-    
-    return nlines_merged;
-}
-
-static int merge_lines (struct line_pnts *Points1, struct line_cats *Cats1, 
-			struct line_pnts *Points2, struct line_cats *Cats2,
-			double thresh, struct line_pnts **Points)
-{
-    struct line_pnts *ps = *Points;
-    struct line_cats *cs = Cats1;
-
-    int i, mindistidx;
-    double mindist;
-    
-    /* find mininal distance and its index */
-    mindist = min_distance_line (Points1, Points2,
-				 &mindistidx);
-
-    G_debug (3, "merge line ? index: %d, mindist: %g, thresh: %g",
-	     mindistidx, mindist, thresh);
-    
-    if (thresh > 0 && mindist > thresh) {
-	return 0;
-    }
-    
-    /* set index and other things */
-    switch(mindistidx) {
-	/* for each mindistidx create new line */
-    case 0: 
-	Vect_append_points (ps, Points2, GV_BACKWARD);
-	if (ps -> n_points == Points2 -> n_points)
-	    Vect_append_points (ps, Points1, GV_FORWARD);
-	break;
-    case 1: 
-	Vect_append_points (ps, Points2, GV_FORWARD);
-	if (ps -> n_points == Points2 -> n_points)
-	    Vect_append_points (ps, Points1, GV_FORWARD);
-	break;
-    case 2: 
-	if (ps -> n_points == 0)
-	    Vect_append_points (ps, Points1, GV_FORWARD);
-	Vect_append_points (ps, Points2, GV_FORWARD);
-	break;
-    case 3: 
-	if (ps -> n_points == 0)
-	    Vect_append_points (ps, Points1, GV_FORWARD);
-	Vect_append_points (ps, Points2, GV_BACKWARD);
-	break;
-    default:
-	break;
-    }
-    
-    /* remove duplicate points */
-    Vect_line_prune (ps);
-
-    /* copy categories if needed */
-    for (i = 0; i < Cats2 -> n_cats; i++) {
-	Vect_cat_set (cs, Cats2 -> field[i], Cats2 -> cat[i]);
-    }
-
-    return 1;
-}

Deleted: grass/trunk/vector/v.edit/move.c
===================================================================
--- grass/trunk/vector/v.edit/move.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/move.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,91 +0,0 @@
-/****************************************************************
- *
- * MODULE:     v.edit
- *
- * AUTHOR(S):  GRASS Development Team
- *             Jachym Cepicky <jachym  les-ejk cz>
- *             Martin Landa
- *
- * PURPOSE:    This module edits vector maps. 
- *             Deletes selected features.
- *
- * COPYRIGHT:  (C) 2002-2007 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.
- *
- ****************************************************************/
-
-#include "global.h"
-
-/**
-   \brief Move selected features
-   
-   \param[in] Map vector map
-   \param[in] List list of features to be moved
-   \param[in] move_x,move_y X,Y values
-   \param[in] snap enable snapping (see globals.h)
-
-   \return number of modified features
-   \return -1 on error
-*/
-int do_move(struct Map_info *Map, struct ilist *List, 
-	    double move_x, double move_y, int snap, double thresh)
-{
-    struct line_pnts *Points;
-    struct line_cats *Cats;
-    int i, j;
-    int type, newline, line;
-    int nlines_moved;
-    double *x, *y, *z;
-
-    nlines_moved = 0;
-
-    Points = Vect_new_line_struct();
-    Cats = Vect_new_cats_struct();
-
-    for (i = 0; i < List->n_values; i++) {
-	line = List -> value[i];
-
-	if (!Vect_line_alive (Map, line))
-	    continue;
-
-        type = Vect_read_line(Map, Points, Cats, line);
-
-        G_debug(3, "Moving type %d number %d", type, line);
-
-	x = Points->x;
-	y = Points->y;
-	z = Points->z;
-
-        /* move */
-        for (j = 0; j < Points -> n_points; j++) {
-	    x[j] += move_x;
-            y[j] += move_y;
-
-	    if (snap != NO_SNAP) {
-		if (do_snap_point(Map, line, &x[j], &y[j], &z[j], thresh,
-				  (snap == SNAPVERTEX) ? 1 : 0) == 0) {
-		    /* check also background maps */
-		}
-	    }
-        } /* for each point at line */
-
-	newline = Vect_rewrite_line (Map, line, type, Points, Cats);
-
-        if (newline < 0)  {
-	    G_warning(_("Unable to rewrite line %d"),
-		      line);
-            return -1;
-        }
-
-        nlines_moved++;
-    }
-        
-    Vect_destroy_line_struct (Points);
-    Vect_destroy_cats_struct (Cats);
-
-    return nlines_moved;
-}

Deleted: grass/trunk/vector/v.edit/proto.h
===================================================================
--- grass/trunk/vector/v.edit/proto.h	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/proto.h	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,103 +0,0 @@
-#ifndef _V_EDIT_PROTO
-# define _V_EDIT_PROTO
-
-/* args.c */
-int parser(int, char* [], struct GParams *, enum mode *);
-
-/* delete.c */
-int do_delete(struct Map_info *, struct ilist *);
-
-/* a2b.c */
-int asc_to_bin(FILE *, struct Map_info *, struct ilist *);
-int read_head ( FILE *, struct Map_info *);
-int do_close(struct Map_info *, int, double);
-
-/* move.c */
-int do_move(struct Map_info *, struct ilist *,
-	    double, double, int, double);
-
-/* vertex.c */
-int do_move_vertex(struct Map_info *, struct Map_info **, int,
-		   struct ilist *,
-		   struct line_pnts *, double ,
-		   double, double,
-		   int, int);
-int do_remove_vertex(struct Map_info *, struct ilist *,
-		     struct line_pnts *, double);
-int do_add_vertex(struct Map_info *, struct ilist *,
-		  struct line_pnts *, double);
-
-/* break.c */
-int do_break (struct Map_info *, struct ilist *);
-int do_split (struct Map_info *, struct ilist *,
-	      struct line_pnts *, double,
-	      struct ilist *);
-int do_connect (struct Map_info *, struct ilist *,
-		double);
-
-/* merge.c */
-int do_merge(struct Map_info *, struct ilist *);
-
-/* snap.c */
-int do_snap(struct Map_info *,
-	    struct ilist *, double);
-int do_snap_line(struct Map_info *,
-	     int, int, double);
-int do_snap_point(struct Map_info *,
-		  int, double *, double *, double *, double,
-		  int);
-int do_snapping(struct Map_info *, struct Map_info **, int,
-		struct ilist*,
-		double, int);
-
-/* select.c */
-int do_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 *,
-	      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*);
-
-/* max_distance.c */
-double max_distance (double);
-double min_distance_line (struct line_pnts *, struct line_pnts *,
-			  int *);
-void coord2bbox (double, double, double,
-		 struct line_pnts *);
-
-/* cats.c */
-int cats (struct Map_info *, struct ilist *,
-	  int, int, char *);
-
-/* copy.c */
-int do_copy (struct Map_info *, struct Map_info *, struct ilist *);
-
-/* flip.c */
-int do_flip (struct Map_info *, struct ilist *);
-
-/* bulk.c */
-int bulk_labeling (struct Map_info *, struct ilist *,
-		   double, double, double, double,
-		   double, double);
-
-#endif

Deleted: grass/trunk/vector/v.edit/select.c
===================================================================
--- grass/trunk/vector/v.edit/select.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/select.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,746 +0,0 @@
-/****************************************************************
- *
- * MODULE:     v.edit
- *
- * AUTHOR(S):  GRASS Development Team
- *             Jachym Cepicky <jachym  les-ejk cz>
- *             Martin Landa <landa.martin gmail.com>
- *
- * PURPOSE:    This module edits vector map.
- *             Select vector features.
- *
- * COPYRIGHT:  (C) 2006-2007 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.
- *
- ****************************************************************/
-
-#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,
-		  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) {
-	sel_by_query(Map,
-		     type, layer, thresh, params -> query -> answer,
-		     List);
-    }
-
-    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 do_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] ids ids list
-   \param[in,out] List list of selected features
- 
-   \return number of selected lines
-*/
-int sel_by_id(struct Map_info *Map,
-	      char *ids,
-	      struct ilist* List)
-{
-    int i, j;
-    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 = il -> min[i]; id <= il -> max[i]; id++) {
-	    for (j = 1; j <= num; j++) {
-		if (id == j) {
-		    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;
-}
-
-/**
-   \brief Select features by query (based on geometry)
-
-   \param[in] Map vector map
-   \param[in] type feature type
-   \param[in] layer layer number
-   \param[in] thresh threshold value (< 0 for 'shorter', > 0 for 'longer')
-   \param[in] query query (length, dangle, ...)
-   \param[in,out] List list of selected features
- 
-   \return number of selected lines
-*/
-int sel_by_query(struct Map_info *Map,
-		 int type, int layer, double thresh, const char *query,
-		 struct ilist* List)
-{
-    int num, line, ltype, cat;
-    double length;
-    struct ilist *List_tmp;
-    struct line_pnts *Points;
-    struct line_cats *Cats;
-
-    if (first_selection) {
-	List_tmp = List;
-	first_selection = 0;
-    }
-    else {
-	List_tmp = Vect_new_list();
-    }
-
-    Points = Vect_new_line_struct();
-    Cats   = Vect_new_cats_struct();
-
-    num = Vect_get_num_lines (Map);
-
-    for (line = 1; line <= num; line++) {
-	if (!Vect_line_alive(Map, line))
-	    continue;
-	
-	ltype = Vect_read_line(Map, Points, Cats, line);
-	Vect_cat_get(Cats, layer, &cat); /* get first category from layer */
-
-	if (!(ltype & type))
-	    continue;
-
-	if (strcmp(query, "length") == 0) {
-	    length = Vect_line_length(Points);
-	    if (thresh <= 0.0) { /* shorter then */
-		if (length <= fabs(thresh))
-		    Vect_list_append(List_tmp, line);
-	    }
-	    else { /* longer then */
-		if (length > thresh)
-		    Vect_list_append(List_tmp, line);
-	    }
-	}
-	else if (strcmp(query, "dangle") == 0) {
-	    if (!(type & GV_LINES))
-		continue;
-	    /* check if line is dangle */
-
-	    int i, cat_curr;
-	    int node1, node2, node;        /* nodes */
-	    int nnode1, nnode2;            /* number of line in node */
-	    double nx, ny, nz;             /* node coordinates */
-	    struct ilist *exclude, *found; /* line id of nearest lines */
-	    struct line_cats *Cats_curr;   
-
-	    Vect_get_line_nodes(Map, line, &node1, &node2);
-	    
-	    node = -1;
-	    nnode1 = Vect_get_node_n_lines(Map, node1);
-	    nnode2 = Vect_get_node_n_lines(Map, node2);
-
-	    if ((nnode1 == 4 && nnode2 == 1) ||
-		(nnode1 == 1 && nnode2 == 4)) {
-		if (nnode1 == 4)
-		    node = node1;
-		else
-		    node = node2;
-	    }
-
-	    /* no dangle ? */
-	    if (node == -1)
-		continue;
-
-	    length = Vect_line_length(Points);
-	    if (thresh <= 0.0) { /* shorter then */
-		if (length > fabs(thresh))
-		    continue;
-	    }
-	    else { /* longer then */
-		if (length <= thresh)
-		    continue;
-	    }
-	    
-	    /* at least one of the lines need to have same category number */
-	    exclude = Vect_new_list();
-	    found   = Vect_new_list();
-
-	    Vect_get_node_coor(Map, node, &nx, &ny, &nz);
-
-	    Vect_list_append(exclude, line);
-	    Vect_find_line_list(Map, nx, ny, nz,
-				GV_LINES, 0.0, WITHOUT_Z,
-				exclude, found);
-
-	    Cats_curr = Vect_new_cats_struct();
-
-	    for (i = 0; i < found->n_values; i++) {
-		Vect_read_line(Map, NULL, Cats_curr, found->value[i]);
-		if (Vect_cat_get(Cats_curr, layer, &cat_curr) > -1) {
-		    if (cat == cat_curr)
-			Vect_list_append(List_tmp, line);
-		}
-	    }
-
-	    Vect_destroy_cats_struct(Cats_curr);
-	    Vect_destroy_list(exclude);
-	    Vect_destroy_list(found);
-	}
-	else {
-	    /* this shouldn't happen */
-	    G_fatal_error (_("Unknown query tool '%s'"), query);
-	}
-    }
-
-    G_debug (1, "  %d lines selected (by query '%s')", List_tmp -> n_values, query);
-
-    /* merge lists (only duplicate items) */
-    if (List_tmp != List) {
-	merge_lists (List, List_tmp);
-	Vect_destroy_list (List_tmp);
-    }
-
-    Vect_destroy_line_struct(Points);
-    Vect_destroy_cats_struct(Cats);
-
-    return List -> n_values; 
-}

Deleted: grass/trunk/vector/v.edit/snap.c
===================================================================
--- grass/trunk/vector/v.edit/snap.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/snap.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,288 +0,0 @@
-/****************************************************************
- *
- * MODULE:     v.edit
- *
- * AUTHOR(S):  GRASS Development Team
- *             Jachym Cepicky <jachym  les-ejk cz>
- *             Martin Landa <landa.martin gmail.com>
- *
- * PURPOSE:    This module edits vector map, snapping section.
- *
- * COPYRIGHT:  (C) 2007 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.
- *
- ****************************************************************/
-
-#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 do_snap(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 do_snap_line(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 = min_distance_line (Points1, Points2,
-				 &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;
-}
-
-/**
-   \brief Snap given point to the nearest feature
-   
-   \param[in] Map vector map
-   \param[in] line line id to be snapped
-   \param[in] x,y,z point on line to be snapped
-   \param[in] thresh snapping threshold (>0)
-   \param[in] vertex snap also to vertex
-
-   \return 1 snapped
-   \return 0 not snapped
-*/
-int do_snap_point(struct Map_info *Map,
-		  int line, double *x, double *y, double *z, double thresh,
-		  int vertex)
-{
-    struct line_pnts *Points;
-    
-    int i, snapped;
-    int line2snap, mindist_idx;
-    double dist, mindist;
-    
-    snapped = 0;
-    mindist_idx = -1;
-    mindist = thresh;
-    
-    Points = Vect_new_line_struct();
-
-    line2snap = Vect_find_line(Map, *x, *y, *z,
-			       -1, thresh, WITHOUT_Z, line);
-    
-    if (line2snap > 0) {
-	Vect_read_line(Map, Points, NULL, line2snap);
-	
-	if (!Vect_line_alive(Map, line2snap)) {
-	    Vect_destroy_line_struct(Points);
-	    return snapped;
-	}
-
-	for (i = 0; i < Points->n_points; i++) {
-	    if (i > 0 && i < Points->n_points-1)
-	      if (!vertex)
-		continue;
-	    dist = Vect_points_distance(*x, *y, *z,
-					Points->x[i], Points->y[i], Points->z[i],
-					WITHOUT_Z);
-
-	    if (mindist >= dist) {
-		mindist = dist;
-		mindist_idx = i;
-	    }
-	}
-				
-	if(mindist_idx > -1) {
-	    *x = Points->x[mindist_idx];
-	    *y = Points->y[mindist_idx];
-	    *z = Points->z[mindist_idx];
-	    snapped = 1;
-	}
-    }
-
-    Vect_destroy_line_struct(Points);
-
-    return snapped;
-}
-
-/**
-   \brief Snap lines/boudaries to the nearest feature
-   
-   \param[in] Map vector map
-   \param[in] BgMap,nbgmaps List of background maps
-   \param[in] List list of lines to be snapped
-   \param[in] layer layer number
-   \param[in] thresh threshold value used for snapping (>0)
-   \param[in] to_vertex allow snapping also to vertex
-
-   \return number of snapped lines
-*/
-int do_snapping(struct Map_info *Map, struct Map_info **BgMap, int nbgmaps,
-		struct ilist* List,
-		double thresh, int to_vertex)
-{
-    int i, line, type, npoints, node, rewrite;
-    int nlines_modified;
-    double *x, *y, *z;
-
-    struct line_pnts *Points;
-    struct line_cats *Cats;
-
-    nlines_modified = 0;
-
-    Points = Vect_new_line_struct();
-    Cats   = Vect_new_cats_struct();
-
-    for(i = 0; i < List -> n_values; i++) {
-	line = List -> value[i];
-
-	if (!Vect_line_alive (Map, line))
-	    continue;
-
-        type = Vect_read_line(Map, Points, Cats, line);
-	npoints = Points -> n_points;
-	x = Points->x;
-	y = Points->y;
-	z = Points->z;
-
-	rewrite = 0;
-	for (node = 0; node < npoints; node++) {
-	    if ((node > 0  && node < npoints -1) &&
-		!to_vertex)
-		continue;
-
-	    if (do_snap_point(Map, line, &x[node], &y[node], &z[node], thresh,
-			      to_vertex)) {
-		rewrite = 1;
-	    }
-	    else {
-	      /* check also background maps */
-	      int bgi;
-	      for (bgi = 0; bgi < nbgmaps; bgi++) {
-		if (do_snap_point(BgMap[i], line, &x[node], &y[node], &z[node], thresh,
-				  to_vertex)) {
-		  rewrite = 1;
-		  break; /* snapped, don't continue */
-		}
-	      }
-	    }
-	} /* for each line vertex */
-
-	/* close boundaries or lines */
-	if (!rewrite && (type & GV_LINES) &&
-	    Vect_points_distance(x[0], y[0], z[0],
-				 x[npoints-1], y[npoints-1], z[npoints-1],
-				 WITHOUT_Z) <= thresh) {
-	    x[npoints-1] = x[0];
-	    y[npoints-1] = y[0];
-	    z[npoints-1] = z[0];
-
-	    rewrite = 1;
-	}
-
-	if (rewrite) {
-	    if (Vect_rewrite_line (Map, line, type, Points, Cats) < 0) {
-		G_warning(_("Unable to rewrite line %d"), line);
-		return -1;
-	    }
-	    nlines_modified++;
-	}
-    } /* for each line */
-
-    Vect_destroy_line_struct(Points);
-    Vect_destroy_cats_struct(Cats);
-
-    return nlines_modified;
-}

Deleted: grass/trunk/vector/v.edit/vertex.c
===================================================================
--- grass/trunk/vector/v.edit/vertex.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/vertex.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,338 +0,0 @@
-/****************************************************************
- *
- * MODULE:     v.edit
- *
- * AUTHOR(S):  GRASS Development Team
- *             Jachym Cepicky <jachym  les-ejk cz>
- *             Martin Landa
- *
- * PURPOSE:    This module edits vector maps. 
- *             Vertex operations.
- *
- * COPYRIGHT:  (C) 2006-2007 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.
- *
- ****************************************************************/
-
-#include "global.h"
-
-/**
-   \brief Move all vertices in bounding box(es)
-
-   \param[in] Map vector map
-   \param[in] BgMap, nbgmaps list of background vector maps for snapping
-   \param[in] List list of selected features
-   \param[in] coord points location
-   \param[in] thresh threshold value (also size of bounding boxes) (>0)
-   \param[in] move_x,move_y X,Y direction for moving
-   \param[in] move_first move only first vertex found in the bounding box
-   \param[in] snap allow snapping (see global.h)
-
-   \return number of moved verteces
-   \return -1 on error
- */
-int do_move_vertex(struct Map_info *Map, struct Map_info **BgMap, int nbgmaps,
-		   struct ilist *List,
-		   struct line_pnts* coord, double thresh,
-		   double move_x, double move_y,
-		   int move_first, int snap)
-{
-    int nvertices_moved, nlines_modified, nvertices_snapped;
-
-    int i, j, k;
-    int line, type, rewrite;
-    int npoints;
-    double east, north, dist;
-    double *x, *y, *z;
-    char *moved;
-
-    struct line_pnts *Points, *Points_snap;
-    struct line_cats *Cats;
-    
-    nlines_modified = 0;
-    nvertices_moved = nvertices_snapped = 0;
-    moved = NULL;
-
-    Points = Vect_new_line_struct();
-    Points_snap = Vect_new_line_struct();
-    Cats = Vect_new_cats_struct();
-
-    for (i = 0; i < List -> n_values; i++) {
-	line = List -> value[i];
-	
-	if (!Vect_line_alive (Map, line))
-	    continue;
-	
-	type = Vect_read_line(Map, Points, Cats, line);
-
-	if (!(type & GV_LINES))
-	    continue;
-
-	npoints = Points -> n_points;
-	x = Points -> x;
-	y = Points -> y;
-	z = Points -> z;
-
-	/* vertex moved 
-	   0 not moved
-	   1 moved
-	   2 moved and snapped
-	 */
-	moved = (char *) G_realloc ((void *) moved, Points -> n_points * sizeof (char));
-	G_zero ((void *) moved, Points -> n_points * sizeof (char));
-	
-	rewrite = 0;
-	for (j = 0; j < coord -> n_points; j++) {
-	    east  = coord->x[j];
-	    north = coord->y[j];
-	    
-	    /* move all vertices in the bounding box */
-	    for (k = 0; k < Points -> n_points; k++) {
-		if (moved[k] == 0) {
-		    dist = Vect_points_distance (east, north, 0.0,
-						 x[k], y[k], z[k],
-						 WITHOUT_Z);
-		    if (dist <= thresh) {
-			G_debug (3, "do_move_vertex(): line=%d; x=%f, y=%f -> x=%f, y=%f",
-				 line, x[k], y[k], x[k] + move_x, y[k] + move_y);
-			x[k] += move_x;
-			y[k] += move_y;
-			moved[k] = 1;
-
-			G_debug (3, "line=%d, point=%d moved", line, k);
-			
-			if (snap != NO_SNAP) {
-			    if (do_snap_point(Map, line, &x[k], &y[k], &z[k], thresh,
-					      (snap == SNAPVERTEX) ? 1 : 0) == 0) {
-				/* check also background maps */
-				int bgi;
-				for (bgi = 0; bgi < nbgmaps; bgi++) {
-				    if (do_snap_point(BgMap[i], line, &x[k], &y[k], &z[k], thresh,
-						      (snap == SNAPVERTEX) ? 1 : 0))
-					moved[k] = 2;
-					break; /* snapped, don't continue */
-				}
-			    }
-			    else {
-				moved[k] = 2;
-			    }
-			}
-			
-			rewrite = 1;
-			nvertices_moved++;
-
-			if (move_first)
-			    break;
-		    }
-		}
-	    } /* for each line vertex */
-
-	    /* close line or boundary */
-	    if ((type & GV_LINES) &&
-		Vect_points_distance(x[0], y[0], z[0],
-				     x[npoints-1], y[npoints-1], z[npoints-1],
-				     WITHOUT_Z) <= thresh) {
-
-		if (moved[0] == 1) { /* first node moved */
-		    x[0] = x[npoints-1];
-		    y[0] = y[npoints-1];
-		    z[0] = z[npoints-1];
-		}
-		else if (moved[npoints-1] == 1) { /* last node moved */
-		    x[npoints-1] = x[0];
-		    y[npoints-1] = y[0];
-		    z[npoints-1] = z[0];
-		}
-	    }
-	} /* for each coord */
-	
-	if (rewrite) {
-	    if (Vect_rewrite_line (Map, line, type, Points, Cats) < 0)  {
-		G_warning(_("Unable to rewrite line %d"), line);
-		return -1;
-	    }
-	    
-	    nlines_modified++;
-	}
-    } /* for each selected line */
-
-    /* destroy structures */
-    Vect_destroy_line_struct(Points);
-    Vect_destroy_line_struct(Points_snap);
-    Vect_destroy_cats_struct(Cats);
-/*     G_free ((void *) moved); */
-
-    return nvertices_moved;
-}
-
-/**
-   \brief Add new vertex to line.
-
-   Shape of line is not changed.
- 
-   \param[in] Map vector map
-   \param[in] List list of features
-   \param[in] coord points location
-   \param[in] thresh find line in given threshold
-
-   \return number of add verteces
-   \return -1 on error
-*/
-int do_add_vertex (struct Map_info *Map, struct ilist *List,
-		   struct line_pnts* coord, double thresh)
-{
-    int i, j;
-    int type, line, seg;
-    int nlines_modified, nvertices_added, rewrite;
-    double east, north, dist;
-    double *x, *y, *z;
-    double px, py;
-
-    struct line_pnts *Points;
-    struct line_cats *Cats;
-
-    nlines_modified = 0;
-    nvertices_added = 0;
-    Points  = Vect_new_line_struct();
-    Cats    = Vect_new_cats_struct();
-
-    for (i = 0; i < List -> n_values; i++) {
-	line = List -> value[i];
-
-	if (!Vect_line_alive (Map, line))
-	    continue;
-
-        type = Vect_read_line(Map, Points, Cats, line);
-
-	if (!(type & GV_LINES))
-	    continue;
-
-	x = Points -> x;
-	y = Points -> y;
-	z = Points -> z;
-	rewrite = 0;
-	for (j = 0; j < coord -> n_points; j++) {
-	    east  = coord->x[j];
-	    north = coord->y[j];
-
-	    seg = Vect_line_distance (Points,
-				      east, north, 0.0,    /* standpoint */
-				      WITHOUT_Z,
-				      &px, &py, NULL,      /* point on line */
-				      &dist,               /* distance to line */
-				      NULL, NULL);
-	    
-	    if (dist <= thresh &&
-		Vect_points_distance (px, py, 0.0, x[seg], y[seg], z[seg], WITHOUT_Z) > 0 &&
-		Vect_points_distance (px, py, 0.0, x[seg-1], y[seg-1], z[seg-1], WITHOUT_Z) > 0) {
-		/* add new vertex */
-		Vect_line_insert_point (Points, seg, px, py, 0.0);
-		G_debug (3, "do_add_vertex(): line=%d; x=%f, y=%f, index=%d", line, px, py, seg);
-		rewrite = 1;
-		nvertices_added++;
-	    }
-	} /* for each point */
-
-	/* rewrite the line */
-	if (rewrite) {
-	    Vect_line_prune (Points);
-	    if (Vect_rewrite_line (Map, line, type, Points, Cats) < 0) {
-		G_warning(_("Unable to rewrite line %d"), line);
-		return -1;
-	    }
-		
-	    nlines_modified++;
-	}
-    } /* for each line */
-
-    /* destroy structures */
-    Vect_destroy_line_struct(Points);
-    Vect_destroy_cats_struct(Cats);
-
-    return nvertices_added;
-}
-
-/**
-   \brief Remove vertex from line
-   
-   \param[in] Map vector map
-   \param[in] List list of selected features
-   \param[in] coord points location
-   \param[in] thresh threshold value to find a line
-
-   \return number of removed vertices
-   \return -1 on error
-*/
-int do_remove_vertex(struct Map_info *Map, struct ilist *List,
-		     struct line_pnts *coord, double thresh)
-{
-    int i, j, k;
-    int type, line;
-    int nvertices_removed, rewrite, nlines_modified;
-    double east, north;
-    double dist;
-    double *x, *y, *z;
-
-    struct line_pnts *Points;
-    struct line_cats *Cats;
-
-    nvertices_removed = nlines_modified = 0;
-
-    Points = Vect_new_line_struct();
-    Cats = Vect_new_cats_struct();
-    
-    for (i = 0; i < List -> n_values; i++) {
-	line = List -> value[i];
-	
-	if (!Vect_line_alive (Map, line))
-	    continue;
-	
-        type = Vect_read_line(Map, Points, Cats, line);
-
-	if (!(type & GV_LINES))
-	    continue;
-
-	x = Points -> x;
-	y = Points -> y;
-	z = Points -> z;
-	rewrite = 0;
-	for (j = 0; j < coord -> n_points; j++) {
-	    east  = coord->x[j];
-	    north = coord->y[j];
-	    
-	    for (k = 0; k < Points -> n_points; k++) {
-		dist = Vect_points_distance (east, north, 0.0,
-					     x[k], y[k], z[k],
-					     WITHOUT_Z);
-		if (dist <= thresh) {
-		    /* remove vertex */
-		    Vect_line_delete_point (Points, k);
-		    G_debug (3, "do_remove_vertex(): line=%d; x=%f, y=%f, index=%d", line, x[k], y[k], k);
-		    k--;
-		    nvertices_removed++;
-		    rewrite = 1;
-		}
-	    } /* for each point */
-	} /* for each bounding box */
-	
-	if (rewrite) {
-	    /* rewrite the line */
-	    if (Vect_rewrite_line (Map, line, type, Points, Cats) < 0) {
-		G_warning (_("Unable to rewrite line %d"), line);
-		return -1;
-	    }
-	    
-	    nlines_modified++;
-	}
-    } /* for each line */
-
-    /* destroy structures */
-    Vect_destroy_line_struct(Points);
-    Vect_destroy_cats_struct(Cats);
-    
-    return nvertices_removed;
-}

Deleted: grass/trunk/vector/v.edit/zbulk.c
===================================================================
--- grass/trunk/vector/v.edit/zbulk.c	2008-01-12 18:45:21 UTC (rev 29679)
+++ grass/trunk/vector/v.edit/zbulk.c	2008-01-12 19:31:46 UTC (rev 29680)
@@ -1,132 +0,0 @@
-/***************************************************************
- *
- * MODULE:     v.edit
- * 
- * AUTHOR(S):  GRASS Development Team
- *             Martin Landa <landa.martin gmail.com>
- *               
- * PURPOSE:    This module edits vector maps.
- *             Bulk labeling (automated labeling of vector features)
- *
- * COPYRIGHT:  (C) 2007 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.
- *
- **************************************************************/
-
-#include <grass/dbmi.h>
-#include "global.h"
-
-/**
-   \brief Z bulk-labeling.
-
-   Automated labeling (z coordinate assignment) of vector lines (contours).
-
-   \param[in] Map vector map
-   \param[in] List list of selected features
-   \param[in] point_start_end staring and ending point
-   \param[in] start starting value
-   \param[in] step step
-
-   \return number of modified features
-   \return -1 on error
-*/
-int bulk_labeling (struct Map_info *Map, struct ilist *List,
-		   double x1, double y1, double x2, double y2,
-		   double start, double step)
-{
-    int i, cv_i, p_i;
-    int line, type, temp_line;
-    int nlines_modified;
-    double value, dist;
-
-    struct line_cats *Cats;
-    struct line_pnts *Points, *Points_se; /* start - end */
-    /* for intersection */
-    struct line_pnts **Points_a, **Points_b;
-    int nlines_a, nlines_b;
-
-    dbCatValArray cv; /* line_id / dist */
-
-    nlines_modified = 0;
-
-    value = start;
-
-    Points = Vect_new_line_struct();
-    Points_se = Vect_new_line_struct();
-    Cats = Vect_new_cats_struct();
-
-    //cv = (dbCatValArray *) G_malloc (sizeof (dbCatValArray));
-    db_CatValArray_alloc(&cv, List->n_values);
-    cv.ctype    = DB_C_TYPE_DOUBLE;
-    cv.n_values = 0;
-
-    Vect_append_point(Points_se, x1, y1, -PORT_DOUBLE_MAX);
-    Vect_append_point(Points_se, x2, y2, PORT_DOUBLE_MAX);
-
-    /* write temporaly line */
-    temp_line = Vect_write_line(Map, GV_LINE, Points_se, Cats);
-
-    /* determine order of lines */
-    cv_i = 0;
-    for (i = 0; i < List->n_values; i++) {
-	line = List->value[i];
-
-	if (!Vect_line_alive(Map, line))
-	    continue;
-
-	type = Vect_read_line(Map, Points, NULL, line);
-
-	if (!(type & GV_LINE))
-	    continue;
-
-	if (Vect_line_check_intersection(Points_se, Points, WITH_Z)) {
-	    Vect_line_intersection (Points_se, Points,
-				    &Points_a, &Points_b, &nlines_a, &nlines_b,
-				    WITHOUT_Z);
-
-	    if (nlines_a < 2 || nlines_b < 1) /* should not happen */
-		continue;
-
-	    /* calculate distance start point -> point of intersection */
-	    for (p_i = 0; p_i < Points_a[0]->n_points; p_i++) {
-		Points_a[0]->z[p_i] = 0;
-	    }
-	    dist = Vect_line_length(Points_a[0]); /* always first line in array? */
-
-	    cv.value[cv_i].cat     = line;
-	    cv.value[cv_i++].val.d = dist;
-	    cv.n_values++;
-	}
-    }
-
-    /* sort array by distance */
-    db_CatValArray_sort_by_value(&cv);
-
-    /* z bulk-labeling */
-    for (cv_i = 0; cv_i < cv.n_values; cv_i++) {
-	line = cv.value[cv_i].cat;
-	Vect_read_line(Map, Points, Cats, line);
-
-	for(p_i = 0; p_i < Points->n_points; p_i++) {
-	    Points->z[p_i] = value;
-	}
-	
-	Vect_rewrite_line(Map, line, type, Points, Cats);
-	nlines_modified++;
-
-	value += step;
-    }
-
-    Vect_delete_line(Map, temp_line);
-
-    db_CatValArray_free(&cv);
-    Vect_destroy_line_struct(Points);
-    Vect_destroy_line_struct(Points_se);
-    Vect_destroy_cats_struct(Cats);
-
-    return nlines_modified;
-}



More information about the grass-commit mailing list