[GRASS-dev] v.edit updates

Hallo,
according to suggested funtion of v.edit [1], I started to work on
v.edit module.

I prepared patch for this and it would be great, if anybody could look
at it and say, if it is worth to commit to cvs.

Currently, only tools "delete" and "add" are supported. But they cand be
used on slightly different way:

With this patch, v.edit no longer accepts input in form of comma
separated list of coordinates, but it reads input (tools "create" and
"add") from stdin or from ASCII file. I used a2b.c file from v.in.ascii
for this purpose. Currently, it does not accept header of the vector
file, so v.out.ascii vect|v.edit tool=add would not work.

For "tool=remove", new ways for feature definition are defined:

coords=x,y - remove feature, which can be found on coordinates x,y

cats=3,4 - remove reature with category 3 or 4

bbox=x1,y1,x2,y2 - remove features in bounding box

If everything will be all right, I'll continue on v.edit with moving and
spliting tools

Looking forward to your feedback

Jachym

[1] http://grass.gdf-hannover.de/wiki/GRASS_Digitizing_tool#v.edit
--
Jachym Cepicky
e-mail: jachym.cepicky@centrum.cz
URL: http://les-ejk.cz
GPG: http://www.les-ejk.cz/pgp/jachym_cepicky-gpg.pub
-----------------------------------------
OFFICE:
Department of Geoinformation Technologies
Zemedelska 3
613 00, Brno
Czech Republick
e-mail: xcepicky@node.mendelu.cz
URL: http://mapserver.mendelu.cz
Tel.: +420 545 134 514

(attachments)

v.edit.patch (21.1 KB)

Hallo,
since nobody answared, I suppose there nobody had enough time to check
the patches.

Before I move with further development, I would like to hear from the
GRASS-core developers, that this changes are all right and worth to be
committed to cvs.
I did not commit this changes yet, because of they are changing behavior
and features of v.edit significantly.

Removed options:
    type - there is no need to define type of the vector input feature,
            this can be done using other methods (grass ascii format)
    values - all database updates should be done via db.* commands

Changes options:
    coords - coords were used for data inputs. But it could come to
            maximum length of a line limit.
            coords option is used for feature identification, not for
            data input
    action->tool - IMHO "tool" does fit idea of the option better, than
            action

    tools: merge - removed
            new tools introduced

Added options:
    to - moving to coordinates
    at - breaking/spliting at this coordinates
    bbox - for bounding box feature selection
    about - (not added yet) for moving features +- map units
    
How to test this:
This commands should give you impression about how v.edit currently
works:

# copy soils map
g.copy vect=soils,tmp --o
d.mon x0
d.vect tmp

# add new line the soils map
echo "L 2 1
593229.5625 4917307.3125
606824.0625 4926102
1 60" | v.edit map=tmp tool=add

v.build tmp
echo "insert into tmp (cat, label) values (60,'road');"|db.execute
d.redraw

# remove feature defined by coordinates
v.edit map=tmp tool=delete coords=593229.5625,4917307.3125
d.redraw # line should be removed

# remove feature defined by category
v.edit map=tmp tool=delete cat=13
d.redraw # big soil area on south should be removed

# remove featuers defined by bounding box
d.graph -m color=0:255:0 << EOF
width 4
polyline
602203.125 4918112.25
602203.125 4924402.6875
604319.8125 4924402.6875
604319.8125 4918112.25
602203.125 4918112.25
EOF

v.edit map=tmp tool=delete bbox=602203.125,4918112.25,604319.8125,4924402.6875
d.redraw

I prepared new patch (attached). If there will be no provisos, I would
like to add this to cvs soon and continue with the development.

Thank you

Jachym

On Tue, Dec 12, 2006 at 02:41:42PM +0100, Jachym Cepicky wrote:

Hallo,
according to suggested funtion of v.edit [1], I started to work on
v.edit module.

I prepared patch for this and it would be great, if anybody could look
at it and say, if it is worth to commit to cvs.

Currently, only tools "delete" and "add" are supported. But they cand be
used on slightly different way:

With this patch, v.edit no longer accepts input in form of comma
separated list of coordinates, but it reads input (tools "create" and
"add") from stdin or from ASCII file. I used a2b.c file from v.in.ascii
for this purpose. Currently, it does not accept header of the vector
file, so v.out.ascii vect|v.edit tool=add would not work.

For "tool=remove", new ways for feature definition are defined:

coords=x,y - remove feature, which can be found on coordinates x,y

cats=3,4 - remove reature with category 3 or 4

bbox=x1,y1,x2,y2 - remove features in bounding box

If everything will be all right, I'll continue on v.edit with moving and
spliting tools

Looking forward to your feedback

Jachym

[1] http://grass.gdf-hannover.de/wiki/GRASS_Digitizing_tool#v.edit
--
Jachym Cepicky
e-mail: jachym.cepicky@centrum.cz
URL: http://les-ejk.cz
GPG: http://www.les-ejk.cz/pgp/jachym_cepicky-gpg.pub
-----------------------------------------
OFFICE:
Department of Geoinformation Technologies
Zemedelska 3
613 00, Brno
Czech Republick
e-mail: xcepicky@node.mendelu.cz
URL: http://mapserver.mendelu.cz
Tel.: +420 545 134 514

Index: vector/v.edit/a2b.c

RCS file: vector/v.edit/a2b.c
diff -N vector/v.edit/a2b.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ vector/v.edit/a2b.c 12 Dec 2006 13:29:22 -0000
@@ -0,0 +1,171 @@
+/*
+ * This file has been adopted from v.in.ascii code
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include "global.h"
+
+#define BUFFSIZE 128
+
+int asc_to_bin(FILE *ascii , struct Map_info *Map)
+{
+ 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;
+ int alloc_points ;
+ int end_of_file ;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int catn;
+ int cat;
+
+ /* Must always use this to create an initialized line_pnts structure */
+ Points = Vect_new_line_struct ();
+ Cats = Vect_new_cats_struct ();
+
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 )
+ Vect_write_line ( Map, type, Points, Cats );
+
+ Vect_reset_cats ( Cats );
+ }
+ return 0;
+}
+
Index: vector/v.edit/args.c

RCS file: /grassrepository/grass6/vector/v.edit/args.c,v
retrieving revision 1.6
diff -u -r1.6 args.c
--- vector/v.edit/args.c 7 Jun 2006 19:16:16 -0000 1.6
+++ vector/v.edit/args.c 12 Dec 2006 13:29:22 -0000
@@ -4,48 +4,74 @@
{
     map_opt = G_define_standard_option(G_OPT_V_MAP);

- act_opt = G_define_option();
- act_opt->key = "action";
- act_opt->type = TYPE_STRING;
- act_opt->required = YES;
- act_opt->multiple = NO;
- act_opt->description = _("The edit action to take.");
- act_opt->options = "create,add,delete,move,merge";
-
- typ_opt = G_define_standard_option(G_OPT_V_TYPE);
- typ_opt->required = NO;
- typ_opt->description = _("Select type. Required for add action.");
- typ_opt->options = "point,line,area,centroid,boundary";
- typ_opt->answer = "point";
-
+ tool_opt = G_define_option();
+ tool_opt->key = "tool";
+ tool_opt->type = TYPE_STRING;
+ tool_opt->required = YES;
+ tool_opt->multiple = NO;
+ tool_opt->description = _("The edit tool to take.\n"
+ "\t\tcreate - Create new vector file\n"
+ "\t\tadd - Add new vector feature to existing vector file\n"
+ "\t\tdelete - Delete feature from vector file\n"
+ "\t\tmove - Move feature in vector file\n"
+ "\t\tvertex - Move just only vertex\n"
+ "\t\tbreak - Add new vertex to existing vector line\n"
+ "\t\tsplit - Split line into two separate lines");
+ tool_opt->options = "create,add,delete,move,vertex,break,split";
+
+ input_opt = G_define_option();
+ input_opt->key = "input";
+ input_opt->type = TYPE_STRING;
+ input_opt->required = NO;
+ input_opt->multiple = NO;
+ input_opt->description = _("ASCII file to be converted to binary vector file, if not given reads from standard input");
+
     cat_opt = G_define_standard_option(G_OPT_V_CATS);
     cat_opt->required = NO;
     
- pnt_opt = G_define_option();
- pnt_opt->key = "coords";
- pnt_opt->key_desc = "x,y";
- pnt_opt->type = TYPE_DOUBLE;
- pnt_opt->required = NO;
- pnt_opt->multiple = YES;
- pnt_opt->description = _("An x,y list of points. Required for add and move actions.");
-
- val_opt = G_define_option();
- val_opt->key = "values";
- val_opt->type = TYPE_STRING;
- val_opt->required = NO;
- val_opt->multiple = NO;
- val_opt->description = _("A comma-separated list of attr=val pairs.");
-
+ coord_opt = G_define_option();
+ coord_opt->key = "coords";
+ coord_opt->key_desc = "x,y";
+ coord_opt->type = TYPE_DOUBLE;
+ coord_opt->required = NO;
+ coord_opt->multiple = YES;
+ coord_opt->description = _("An x,y list of points. Required for add and move actions.");
+
+ to_opt = G_define_option();
+ to_opt->key = "to";
+ to_opt->key_desc = "x,y";
+ to_opt->type = TYPE_DOUBLE;
+ to_opt->required = NO;
+ to_opt->multiple = NO;
+ to_opt->description = _("An x,y location of selected feature");
+
+ at_opt = G_define_option();
+ at_opt->key = "at";
+ at_opt->key_desc = "x,y";
+ at_opt->type = TYPE_DOUBLE;
+ at_opt->required = NO;
+ at_opt->multiple = NO;
+ at_opt->description = _("An x,y location of breaking feature");
+
+ bbox_opt = G_define_option();
+ bbox_opt->key = "bbox";
+ bbox_opt->key_desc = "x1,y1,x2,y2";
+ bbox_opt->type = TYPE_DOUBLE;
+ bbox_opt->required = NO;
+ bbox_opt->multiple = NO;
+ bbox_opt->description = _("Bounding box of selected feature");
+
+ snap_opt = G_define_option();
+ snap_opt->key = "snap";
+ snap_opt->type = TYPE_DOUBLE;
+ snap_opt->required = NO;
+ snap_opt->multiple = NO;
+ snap_opt->description = _("Object points will snap to existing points within snap units.");
+ snap_opt->answer = "5.0";
+
+
     fld_opt = G_define_standard_option(G_OPT_V_FIELD);

- snp_opt = G_define_option();
- snp_opt->key = "snap";
- snp_opt->type = TYPE_DOUBLE;
- snp_opt->required = NO;
- snp_opt->multiple = NO;
- snp_opt->description = _("Object points will snap to existing points within snap units.");
- snp_opt->answer = "5.0";
-
     t_flg = G_define_flag();
     t_flg->key = 't';
     t_flg->description = _("Do not use topology.");
@@ -62,59 +88,136 @@
     c_flg->key = 'c';
     c_flg->description = _("Do not close boundaries");

+ n_flg = G_define_flag();
+ n_flg->key = 'n';
+ n_flg->description = _("Don't expect a header");
+
     if(G_parser(argc, argv))
   return 0;

     /* check that the given arguments makes sense together*/
/** @todo check for incorrect extra parameters */

- if(strcmp(act_opt->answer, "create")==0) { /* create requires nothing extra*/
+ if ( input_opt->answer != NULL ) {
+ if ( (ascii = fopen ( input_opt->answer, "r" ) ) == NULL )
+ {
+ G_warning(_("Could not open ascii file <%s>"), input_opt->answer);
+ G_usage();
+ }
+ } else {
+ ascii = stdin;
+ }
+
+ /* check for coordinate param */
+ if (coord_opt->answers != NULL) {
+ int i = 0;
+ for (i = 0; coord_opt->answers[i]; i ++)
+ ;
+ if (i%2 != 0) {
+ G_warning(_("Number of coordinates must be odd number"));
+ G_usage();
+ return 0;
+ }
+
+ }
+
+ /* check for bbox param */
+ if (bbox_opt->answers != NULL) {
+ int i = 0;
+ for (i = 0; bbox_opt->answers[i]; i ++)
+ ;
+ if (i%2 != 0) {
+ G_warning(_("Number of coordinates must be odd number"));
+ G_usage();
+ return 0;
+ }
+
+ }
+
+ if(strcmp(tool_opt->answer, "create")==0) { /* create requires nothing extra*/
   action_mode = MODE_CREATE;
   return 1;
     }
     
- snap = atof(snp_opt->answer);
-
- if(strcmp(act_opt->answer, "add")==0) { /* add requires a points argument */
+ if(strcmp(tool_opt->answer, "add")==0) { /* add requires a points argument */
   action_mode = MODE_ADD;
- if(pnt_opt->answers == NULL) {
- help(_("Required parameter <points> not set"));
+ return 1;
+ }
+ else if(strcmp(tool_opt->answer, "delete")==0) { /* del requires a cats or or bbox or coords*/
+ action_mode = MODE_DEL;
+ if((cat_opt->answers == NULL) &&
+ (coord_opt->answers == NULL) &&
+ (bbox_opt->answers == NULL)) {
+ G_warning(_("At least one from <%s> must be specified"),"cats, coords, bbox");
+ G_usage();
       return 0;
   };
   return 1;
     }
- else if(strcmp(act_opt->answer, "delete")==0) { /* del requires a cats */
- action_mode = MODE_DEL;
- if(cat_opt->answers == NULL) {
- help(_("Required parameter <cats> not set"));
+ else if(strcmp(tool_opt->answer, "move")==0) { /* move requires coords or cats arguments */
+ action_mode = MODE_MOVE;
+ if(to_opt->answers == NULL) {
+ G_warning(_("For <%s> operation, option <%s> must be set"),"move","to");
+ G_usage();
+ return 0;
+ }
+ if((coord_opt->answers == NULL) &&
+ (cat_opt->answers == NULL) &&
+ (bbox_opt->answers == NULL)) {
+ G_warning(_("At least one from <%s> must be specified"),"cats, coords, bbox");
+ G_usage();
       return 0;
   };
   return 1;
     }
- else if(strcmp(act_opt->answer, "move")==0) { /* move requires points and cats arguments */
- action_mode = MODE_ADD;
- if((pnt_opt->answers == NULL)||(cat_opt->answers == NULL)) {
- help(_("Both parameters <points> and <cats> are required."));
+
+ else if(strcmp(tool_opt->answer, "vertex")==0) { /* move vertex requires a coord and to options */
+ action_mode = MODE_VERTEX;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(to_opt->answers == NULL) {
+ G_warning(_("Required parameter <to> not set"));
+ G_usage();
       return 0;
   };
   return 1;
     }
- else if(strcmp(act_opt->answer, "merge")==0) { /* merge requires a cats argument */
- action_mode = MODE_ADD;
- if(cat_opt->answers == NULL) {
- help(_("Required parameter <cats> not set"));
+ else if(strcmp(tool_opt->answer, "break")==0) { /* break line requires a coord and at options */
+ action_mode = MODE_BREAK;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(at_opt->answers == NULL) {
+ G_warning(_("Required parameter <at> not set"));
+ G_usage();
       return 0;
   };
   return 1;
     }
+ else if(strcmp(tool_opt->answer, "split")==0) { /* split line requires a coord and at options */
+ action_mode = MODE_SPLIT;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(at_opt->answers == NULL) {
+ G_warning(_("Required parameter <at> not set"));
+ G_usage();
+ return 0;
+ };
+ return 1;
+ }
+
     else {
- help(_("This should never happen."));
+ G_warning(_("Operation <%s> not implemented."),tool_opt->answer);
+ G_usage();
   return 0;
     }
}

-void help(const char *msg)
-{
- G_message("\nERROR: %s\n\n", msg);
- G_usage();
-}
Index: vector/v.edit/del.c

RCS file: /grassrepository/grass6/vector/v.edit/del.c,v
retrieving revision 1.2
diff -u -r1.2 del.c
--- vector/v.edit/del.c 6 Oct 2006 06:47:56 -0000 1.2
+++ vector/v.edit/del.c 12 Dec 2006 13:29:23 -0000
@@ -2,45 +2,151 @@

int do_del(struct Map_info *Map)
{
- int i;
+ int res = 0;
+
+
+ /* cats or coord or bbox */
+ if(cat_opt->answer != NULL) {
+
+ res = delete_categories(Map);
+ }
+ else if (coord_opt->answer != NULL) {
+
+ res = delete_coordinates(Map);
+ }
+ else if (bbox_opt->answer != NULL) {
+
+ res = delete_bbox(Map);
+ }
+ else {
+ /* this case should not happen, see args.c for details */
+ G_warning("cats, coord or bbox must be specified");
+ }
+
+}
+
+int delete_bbox(struct Map_info *Map)
+{
+ double x1,y1,x2,y2;
+ BOUND_BOX bbox;
+ BOUND_BOX feature_bbox;
+ int cat, ret, type, i;
+ struct ilist *List;
+ SPATIAL_INDEX si;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int removed = 0;
+
+
+ /* bounding box */
+ x1 = atof(bbox_opt->answers[0]);
+ y1 = atof(bbox_opt->answers[1]);
+ x2 = atof(bbox_opt->answers[2]);
+ y2 = atof(bbox_opt->answers[3]);
+ 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 = 0.0;
+ bbox.B = 0.0;
+
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+ List = Vect_new_list ();
+
+ /* get lines number */
+ Vect_select_lines_by_box ( Map, &bbox, GV_POINTS | GV_LINES | GV_BOUNDARY | GV_CENTROID, List );
+ G_debug ( 1, " %d lines selected by box", List->n_values );
+
+ for ( i = 0; i < List->n_values; i++) {
+
+ type = Vect_read_line(Map, Points, Cats, List->value[i]);
+ G_debug(2, "Deleting type [%d] number [%d]", type, List->value[i]);
+ Vect_delete_line(Map, List->value[i]);
+ removed++;
+ /* attr_del(Map, layer, cat);*/
+ }
+ G_message(_("%d features deleted"), removed);
+ return 1;
+}
+
+int delete_coordinates(struct Map_info *Map)
+{
+ double east, north;
+ int line;
+ double maxdist = 0.5;
+ char buff[16] = "";
+
+ int type;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int cat;
+ int field=atoi(fld_opt->answer);
+ int removed = 0;
+
+ east = atof(coord_opt->answers[0]);
+ north = atof(coord_opt->answers[1]);
+
+ line = Vect_find_line(Map, east, north, 0.0, GV_POINT | GV_CENTROID, maxdist, 0, 0);
+
+ if (line == 0)
+ line = Vect_find_line(Map, east, north, 0.0, GV_LINE | GV_BOUNDARY | GV_FACE, maxdist, 0, 0);
+
+
+ G_debug (2, "line = %d", line);
+
+ if (line == 0) {
+ G_warning(_("Nothing Found."));
+ return 0;
+
+ }
+ else {
+ type = Vect_read_line(Map, Points, Cats, line);
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+ if ((cat = Vect_get_line_cat(Map, line, field )) > 0)
+ sprintf(buff,_("category [%d]"),cat);
+
+ G_debug(2, "Deleting type [%d] number [%d] %s", type, line, buff);
+ Vect_delete_line(Map, line);
+ removed++;
+
+ /* attr_del(Map, layer, cat);*/
+ }
+
+ G_message(_("%d features deleted"), removed);
+ return 1;
+}
+
+
+int delete_categories(struct Map_info *Map)
+{
+
     struct cat_list * cl;
     int layer=atoi(fld_opt->answer);
+ int i, removed=0;

- G_debug(1,"layer = %d",layer);
-/*
- if(cat_opt->answer=NULL) {
- cats = coords_catlist(Map);
- }
- */
     cl = Vect_new_cat_list();
     Vect_str_to_cat_list(cat_opt->answer, cl);
-
+
+ G_debug(1,"layer = %d",layer);
+
     for(i=0;i<cl->n_ranges;i++) {
   int cat, type, id, ret;
   G_debug(1, "cl->min[%d]=%d, cl->max[%d]=%d, layer=%d",
     i, cl->min[i], i, cl->max[i], cl->field);
   for(cat=cl->min[i]; cat <= cl->max[i]; cat++) {
- ret = Vect_cidx_find_next(Map, layer, cat, GV_POINTS|GV_LINES,
+ ret = Vect_cidx_find_next(Map, layer, cat, GV_POINTS|GV_LINES | GV_BOUNDARY | GV_CENTROID,
               0, &type, &id);
       G_debug(1, "ret=%d", ret);
       if(ret<0) continue;
- G_debug(1, "Found something to delete: id=%d, type=%d",id,type);
- if(type==GV_CENTROID) {
- int area;
- double x,y;
- Vect_get_node_coor(Map, id, &x, &y, NULL);
- area = Vect_find_area(Map, x, y);
- G_debug(1, "Deleteing area %d: id=%d, area=%d",cat,id,area);
-/* Vect_delete_line(Map, id); */
-/* Vect_delete_line(Map, area); */
- attr_del(Map, layer, cat);
- }
- else {
-/* Vect_delete_line(Map, id); */
- attr_del(Map, layer, cat);
- }
+ G_debug(2,"Deleting type [%d] number [%d] cat [%d]", type, id, cat);
+ Vect_delete_line(Map, id);
+ /* attr_del(Map, layer, cat);*/
+ removed ++;
   }
     }
+ G_message(_("%d features deleted"), removed);

     return 1;
}
Index: vector/v.edit/global.h

RCS file: /grassrepository/grass6/vector/v.edit/global.h,v
retrieving revision 1.6
diff -u -r1.6 global.h
--- vector/v.edit/global.h 7 Jun 2006 19:16:16 -0000 1.6
+++ vector/v.edit/global.h 12 Dec 2006 13:29:23 -0000
@@ -18,15 +18,18 @@
     MODE_ADD,
     MODE_DEL,
     MODE_MOVE,
- MODE_MERGE
+ MODE_VERTEX,
+ MODE_SPLIT,
+ MODE_BREAK
};

-void help(const char *msg);
int parser(int argc, char*argv);

-int do_add(struct Map_info *Map);
+int asc_to_bin(FILE *, struct Map_info *);
int do_del(struct Map_info *Map);
-
+int delete_categories(struct Map_info *Map);
+int delete_coordinates(struct Map_info *Map);
+int delete_bbox(struct Map_info *Map);

void cat_max_set ( int field, int cat);
int cat_max_get ( int field );
@@ -37,11 +40,12 @@
int attr_edit(struct Map_info *Map, int field, int cat, const char *vals);
int attr_del(struct Map_info *Map, int field, int cat);

-global struct Option *map_opt, *act_opt, *typ_opt, *cat_opt, *pnt_opt, *fld_opt, *val_opt, *snp_opt;
-global struct Flag *n_flg, *t_flg, *d_flg, *b_flg, *c_flg;
+global struct Option *input_opt, *map_opt, *tool_opt, *coord_opt, *cat_opt, *to_opt, *at_opt, *bbox_opt, *snap_opt, *fld_opt;
+global struct Flag *n_flg, *t_flg, *d_flg, *b_flg, *c_flg, *n_flg;
global struct GModule *module;
global struct Map_info Map;
global enum mode action_mode;
global char *mapset;
-global double snap;
+
+global FILE *ascii;
#endif
Index: vector/v.edit/main.c

RCS file: /grassrepository/grass6/vector/v.edit/main.c,v
retrieving revision 1.9
diff -u -r1.9 main.c
--- vector/v.edit/main.c 6 Oct 2006 06:47:56 -0000 1.9
+++ vector/v.edit/main.c 12 Dec 2006 13:29:23 -0000
@@ -21,6 +21,7 @@

#define MAIN
#include "global.h"
+
/* static int error_routine(const char*msg, int fatal); */

int main (int argc, char *argv)
@@ -56,7 +57,6 @@
     }
     else {
/* Vect_set_open_level(2); */
- G_message(_("Reading vector file ..."));
   Vect_open_update (&Map, map_opt->answer, mapset);
     }
/* Vect_set_category_index_update ( &Map ); */
@@ -66,7 +66,8 @@

     switch(action_mode) {
       case MODE_ADD:
- ret = do_add(&Map);
+ G_message(_("Adding new features to vector file ..."));
+ ret = asc_to_bin(ascii, &Map) ;
   break;
       case MODE_DEL:
   ret = do_del(&Map);

_______________________________________________
grass-dev mailing list
grass-dev@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass-dev

--
Jachym Cepicky
e-mail: jachym.cepicky@centrum.cz
URL: http://les-ejk.cz
GPG: http://www.les-ejk.cz/pgp/jachym_cepicky-gpg.pub
-----------------------------------------
OFFICE:
Department of Geoinformation Technologies
Zemedelska 3
613 00, Brno
Czech Republick
e-mail: xcepicky@node.mendelu.cz
URL: http://mapserver.mendelu.cz
Tel.: +420 545 134 514

(attachments)

v.edit.patch (21.1 KB)

Jachym,

Because we need to have a digitizing tool that works without x11, I'm in
favor of moving ahead with v.edit since it is by far the most advanced
attempt to get this rolling so far.

I haven't had time to review and test it however.

Michael

On 12/13/06 3:17 AM, "Jachym Cepicky" <jachym.cepicky@centrum.cz> wrote:

Hallo,
since nobody answared, I suppose there nobody had enough time to check
the patches.

Before I move with further development, I would like to hear from the
GRASS-core developers, that this changes are all right and worth to be
committed to cvs.
I did not commit this changes yet, because of they are changing behavior
and features of v.edit significantly.

Removed options:
    type - there is no need to define type of the vector input feature,
            this can be done using other methods (grass ascii format)
    values - all database updates should be done via db.* commands

Changes options:
    coords - coords were used for data inputs. But it could come to
            maximum length of a line limit.
            coords option is used for feature identification, not for
            data input
    action->tool - IMHO "tool" does fit idea of the option better, than
            action

    tools: merge - removed
            new tools introduced

Added options:
    to - moving to coordinates
    at - breaking/spliting at this coordinates
    bbox - for bounding box feature selection
    about - (not added yet) for moving features +- map units
    
How to test this:
This commands should give you impression about how v.edit currently
works:

# copy soils map
g.copy vect=soils,tmp --o
d.mon x0
d.vect tmp

# add new line the soils map
echo "L 2 1
593229.5625 4917307.3125
606824.0625 4926102
1 60" | v.edit map=tmp tool=add

v.build tmp
echo "insert into tmp (cat, label) values (60,'road');"|db.execute
d.redraw

# remove feature defined by coordinates
v.edit map=tmp tool=delete coords=593229.5625,4917307.3125
d.redraw # line should be removed

# remove feature defined by category
v.edit map=tmp tool=delete cat=13
d.redraw # big soil area on south should be removed

# remove featuers defined by bounding box
d.graph -m color=0:255:0 << EOF
width 4
polyline
602203.125 4918112.25
602203.125 4924402.6875
604319.8125 4924402.6875
604319.8125 4918112.25
602203.125 4918112.25
EOF

v.edit map=tmp tool=delete bbox=602203.125,4918112.25,604319.8125,4924402.6875
d.redraw

I prepared new patch (attached). If there will be no provisos, I would
like to add this to cvs soon and continue with the development.

Thank you

Jachym

On Tue, Dec 12, 2006 at 02:41:42PM +0100, Jachym Cepicky wrote:

Hallo,
according to suggested funtion of v.edit [1], I started to work on
v.edit module.

I prepared patch for this and it would be great, if anybody could look
at it and say, if it is worth to commit to cvs.

Currently, only tools "delete" and "add" are supported. But they cand be
used on slightly different way:

With this patch, v.edit no longer accepts input in form of comma
separated list of coordinates, but it reads input (tools "create" and
"add") from stdin or from ASCII file. I used a2b.c file from v.in.ascii
for this purpose. Currently, it does not accept header of the vector
file, so v.out.ascii vect|v.edit tool=add would not work.

For "tool=remove", new ways for feature definition are defined:

coords=x,y - remove feature, which can be found on coordinates x,y

cats=3,4 - remove reature with category 3 or 4

bbox=x1,y1,x2,y2 - remove features in bounding box

If everything will be all right, I'll continue on v.edit with moving and
spliting tools

Looking forward to your feedback

Jachym

[1] http://grass.gdf-hannover.de/wiki/GRASS_Digitizing_tool#v.edit
--
Jachym Cepicky
e-mail: jachym.cepicky@centrum.cz
URL: http://les-ejk.cz
GPG: http://www.les-ejk.cz/pgp/jachym_cepicky-gpg.pub
-----------------------------------------
OFFICE:
Department of Geoinformation Technologies
Zemedelska 3
613 00, Brno
Czech Republick
e-mail: xcepicky@node.mendelu.cz
URL: http://mapserver.mendelu.cz
Tel.: +420 545 134 514

Index: vector/v.edit/a2b.c

RCS file: vector/v.edit/a2b.c
diff -N vector/v.edit/a2b.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ vector/v.edit/a2b.c 12 Dec 2006 13:29:22 -0000
@@ -0,0 +1,171 @@
+/*
+ * This file has been adopted from v.in.ascii code
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include "global.h"
+
+#define BUFFSIZE 128
+
+int asc_to_bin(FILE *ascii , struct Map_info *Map)
+{
+ 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;
+ int alloc_points ;
+ int end_of_file ;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int catn;
+ int cat;
+
+ /* Must always use this to create an initialized line_pnts structure */
+ Points = Vect_new_line_struct ();
+ Cats = Vect_new_cats_struct ();
+
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 )
+ Vect_write_line ( Map, type, Points, Cats );
+
+ Vect_reset_cats ( Cats );
+ }
+ return 0;
+}
+
Index: vector/v.edit/args.c

RCS file: /grassrepository/grass6/vector/v.edit/args.c,v
retrieving revision 1.6
diff -u -r1.6 args.c
--- vector/v.edit/args.c 7 Jun 2006 19:16:16 -0000 1.6
+++ vector/v.edit/args.c 12 Dec 2006 13:29:22 -0000
@@ -4,48 +4,74 @@
{
     map_opt = G_define_standard_option(G_OPT_V_MAP);

- act_opt = G_define_option();
- act_opt->key = "action";
- act_opt->type = TYPE_STRING;
- act_opt->required = YES;
- act_opt->multiple = NO;
- act_opt->description = _("The edit action to take.");
- act_opt->options = "create,add,delete,move,merge";
-
- typ_opt = G_define_standard_option(G_OPT_V_TYPE);
- typ_opt->required = NO;
- typ_opt->description = _("Select type. Required for add action.");
- typ_opt->options = "point,line,area,centroid,boundary";
- typ_opt->answer = "point";
-
+ tool_opt = G_define_option();
+ tool_opt->key = "tool";
+ tool_opt->type = TYPE_STRING;
+ tool_opt->required = YES;
+ tool_opt->multiple = NO;
+ tool_opt->description = _("The edit tool to take.\n"
+ "\t\tcreate - Create new vector file\n"
+ "\t\tadd - Add new vector feature to
existing vector file\n"
+ "\t\tdelete - Delete feature from vector
file\n"
+ "\t\tmove - Move feature in vector file\n"
+ "\t\tvertex - Move just only vertex\n"
+ "\t\tbreak - Add new vertex to existing vector
line\n"
+ "\t\tsplit - Split line into two separate
lines");
+ tool_opt->options = "create,add,delete,move,vertex,break,split";
+
+ input_opt = G_define_option();
+ input_opt->key = "input";
+ input_opt->type = TYPE_STRING;
+ input_opt->required = NO;
+ input_opt->multiple = NO;
+ input_opt->description = _("ASCII file to be converted to binary vector
file, if not given reads from standard input");
+
     cat_opt = G_define_standard_option(G_OPT_V_CATS);
     cat_opt->required = NO;
     
- pnt_opt = G_define_option();
- pnt_opt->key = "coords";
- pnt_opt->key_desc = "x,y";
- pnt_opt->type = TYPE_DOUBLE;
- pnt_opt->required = NO;
- pnt_opt->multiple = YES;
- pnt_opt->description = _("An x,y list of points. Required for add and
move actions.");
-
- val_opt = G_define_option();
- val_opt->key = "values";
- val_opt->type = TYPE_STRING;
- val_opt->required = NO;
- val_opt->multiple = NO;
- val_opt->description = _("A comma-separated list of attr=val pairs.");
-
+ coord_opt = G_define_option();
+ coord_opt->key = "coords";
+ coord_opt->key_desc = "x,y";
+ coord_opt->type = TYPE_DOUBLE;
+ coord_opt->required = NO;
+ coord_opt->multiple = YES;
+ coord_opt->description = _("An x,y list of points. Required for add and
move actions.");
+
+ to_opt = G_define_option();
+ to_opt->key = "to";
+ to_opt->key_desc = "x,y";
+ to_opt->type = TYPE_DOUBLE;
+ to_opt->required = NO;
+ to_opt->multiple = NO;
+ to_opt->description = _("An x,y location of selected feature");
+
+ at_opt = G_define_option();
+ at_opt->key = "at";
+ at_opt->key_desc = "x,y";
+ at_opt->type = TYPE_DOUBLE;
+ at_opt->required = NO;
+ at_opt->multiple = NO;
+ at_opt->description = _("An x,y location of breaking feature");
+
+ bbox_opt = G_define_option();
+ bbox_opt->key = "bbox";
+ bbox_opt->key_desc = "x1,y1,x2,y2";
+ bbox_opt->type = TYPE_DOUBLE;
+ bbox_opt->required = NO;
+ bbox_opt->multiple = NO;
+ bbox_opt->description = _("Bounding box of selected feature");
+
+ snap_opt = G_define_option();
+ snap_opt->key = "snap";
+ snap_opt->type = TYPE_DOUBLE;
+ snap_opt->required = NO;
+ snap_opt->multiple = NO;
+ snap_opt->description = _("Object points will snap to existing points
within snap units.");
+ snap_opt->answer = "5.0";
+
+
     fld_opt = G_define_standard_option(G_OPT_V_FIELD);

- snp_opt = G_define_option();
- snp_opt->key = "snap";
- snp_opt->type = TYPE_DOUBLE;
- snp_opt->required = NO;
- snp_opt->multiple = NO;
- snp_opt->description = _("Object points will snap to existing points
within snap units.");
- snp_opt->answer = "5.0";
-
     t_flg = G_define_flag();
     t_flg->key = 't';
     t_flg->description = _("Do not use topology.");
@@ -62,59 +88,136 @@
     c_flg->key = 'c';
     c_flg->description = _("Do not close boundaries");

+ n_flg = G_define_flag();
+ n_flg->key = 'n';
+ n_flg->description = _("Don't expect a header");
+
     if(G_parser(argc, argv))
return 0;

     /* check that the given arguments makes sense together*/
/** @todo check for incorrect extra parameters */

- if(strcmp(act_opt->answer, "create")==0) { /* create requires nothing
extra*/
+ if ( input_opt->answer != NULL ) {
+ if ( (ascii = fopen ( input_opt->answer, "r" ) ) == NULL )
+ {
+ G_warning(_("Could not open ascii file <%s>"),
input_opt->answer);
+ G_usage();
+ }
+ } else {
+ ascii = stdin;
+ }
+
+ /* check for coordinate param */
+ if (coord_opt->answers != NULL) {
+ int i = 0;
+ for (i = 0; coord_opt->answers[i]; i ++)
+ ;
+ if (i%2 != 0) {
+ G_warning(_("Number of coordinates must be odd number"));
+ G_usage();
+ return 0;
+ }
+
+ }
+
+ /* check for bbox param */
+ if (bbox_opt->answers != NULL) {
+ int i = 0;
+ for (i = 0; bbox_opt->answers[i]; i ++)
+ ;
+ if (i%2 != 0) {
+ G_warning(_("Number of coordinates must be odd number"));
+ G_usage();
+ return 0;
+ }
+
+ }
+
+ if(strcmp(tool_opt->answer, "create")==0) { /* create requires nothing
extra*/
action_mode = MODE_CREATE;
return 1;
     }
     
- snap = atof(snp_opt->answer);
-
- if(strcmp(act_opt->answer, "add")==0) { /* add requires a points
argument */
+ if(strcmp(tool_opt->answer, "add")==0) { /* add requires a points
argument */
action_mode = MODE_ADD;
- if(pnt_opt->answers == NULL) {
- help(_("Required parameter <points> not set"));
+ return 1;
+ }
+ else if(strcmp(tool_opt->answer, "delete")==0) { /* del requires a cats
or or bbox or coords*/
+ action_mode = MODE_DEL;
+ if((cat_opt->answers == NULL) &&
+ (coord_opt->answers == NULL) &&
+ (bbox_opt->answers == NULL)) {
+ G_warning(_("At least one from <%s> must be specified"),"cats, coords,
bbox");
+ G_usage();
   return 0;
};
return 1;
     }
- else if(strcmp(act_opt->answer, "delete")==0) { /* del requires a cats
*/
- action_mode = MODE_DEL;
- if(cat_opt->answers == NULL) {
- help(_("Required parameter <cats> not set"));
+ else if(strcmp(tool_opt->answer, "move")==0) { /* move requires coords
or cats arguments */
+ action_mode = MODE_MOVE;
+ if(to_opt->answers == NULL) {
+ G_warning(_("For <%s> operation, option <%s> must be
set"),"move","to");
+ G_usage();
+ return 0;
+ }
+ if((coord_opt->answers == NULL) &&
+ (cat_opt->answers == NULL) &&
+ (bbox_opt->answers == NULL)) {
+ G_warning(_("At least one from <%s> must be specified"),"cats, coords,
bbox");
+ G_usage();
   return 0;
};
return 1;
     }
- else if(strcmp(act_opt->answer, "move")==0) { /* move requires points
and cats arguments */
- action_mode = MODE_ADD;
- if((pnt_opt->answers == NULL)||(cat_opt->answers == NULL)) {
- help(_("Both parameters <points> and <cats> are required."));
+
+ else if(strcmp(tool_opt->answer, "vertex")==0) { /* move vertex requires
a coord and to options */
+ action_mode = MODE_VERTEX;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(to_opt->answers == NULL) {
+ G_warning(_("Required parameter <to> not set"));
+ G_usage();
   return 0;
};
return 1;
     }
- else if(strcmp(act_opt->answer, "merge")==0) { /* merge requires a cats
argument */
- action_mode = MODE_ADD;
- if(cat_opt->answers == NULL) {
- help(_("Required parameter <cats> not set"));
+ else if(strcmp(tool_opt->answer, "break")==0) { /* break line requires a
coord and at options */
+ action_mode = MODE_BREAK;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(at_opt->answers == NULL) {
+ G_warning(_("Required parameter <at> not set"));
+ G_usage();
   return 0;
};
return 1;
     }
+ else if(strcmp(tool_opt->answer, "split")==0) { /* split line requires a
coord and at options */
+ action_mode = MODE_SPLIT;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(at_opt->answers == NULL) {
+ G_warning(_("Required parameter <at> not set"));
+ G_usage();
+ return 0;
+ };
+ return 1;
+ }
+
     else {
- help(_("This should never happen."));
+ G_warning(_("Operation <%s> not implemented."),tool_opt->answer);
+ G_usage();
return 0;
     }
}

-void help(const char *msg)
-{
- G_message("\nERROR: %s\n\n", msg);
- G_usage();
-}
Index: vector/v.edit/del.c

RCS file: /grassrepository/grass6/vector/v.edit/del.c,v
retrieving revision 1.2
diff -u -r1.2 del.c
--- vector/v.edit/del.c 6 Oct 2006 06:47:56 -0000 1.2
+++ vector/v.edit/del.c 12 Dec 2006 13:29:23 -0000
@@ -2,45 +2,151 @@

int do_del(struct Map_info *Map)
{
- int i;
+ int res = 0;
+
+
+ /* cats or coord or bbox */
+ if(cat_opt->answer != NULL) {
+
+ res = delete_categories(Map);
+ }
+ else if (coord_opt->answer != NULL) {
+
+ res = delete_coordinates(Map);
+ }
+ else if (bbox_opt->answer != NULL) {
+
+ res = delete_bbox(Map);
+ }
+ else {
+ /* this case should not happen, see args.c for details */
+ G_warning("cats, coord or bbox must be specified");
+ }
+
+}
+
+int delete_bbox(struct Map_info *Map)
+{
+ double x1,y1,x2,y2;
+ BOUND_BOX bbox;
+ BOUND_BOX feature_bbox;
+ int cat, ret, type, i;
+ struct ilist *List;
+ SPATIAL_INDEX si;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int removed = 0;
+
+
+ /* bounding box */
+ x1 = atof(bbox_opt->answers[0]);
+ y1 = atof(bbox_opt->answers[1]);
+ x2 = atof(bbox_opt->answers[2]);
+ y2 = atof(bbox_opt->answers[3]);
+ 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 = 0.0;
+ bbox.B = 0.0;
+
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+ List = Vect_new_list ();
+
+ /* get lines number */
+ Vect_select_lines_by_box ( Map, &bbox, GV_POINTS | GV_LINES |
GV_BOUNDARY | GV_CENTROID, List );
+ G_debug ( 1, " %d lines selected by box", List->n_values );
+
+ for ( i = 0; i < List->n_values; i++) {
+
+ type = Vect_read_line(Map, Points, Cats, List->value[i]);
+ G_debug(2, "Deleting type [%d] number [%d]", type, List->value[i]);
+ Vect_delete_line(Map, List->value[i]);
+ removed++;
+ /* attr_del(Map, layer, cat);*/
+ }
+ G_message(_("%d features deleted"), removed);
+ return 1;
+}
+
+int delete_coordinates(struct Map_info *Map)
+{
+ double east, north;
+ int line;
+ double maxdist = 0.5;
+ char buff[16] = "";
+
+ int type;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int cat;
+ int field=atoi(fld_opt->answer);
+ int removed = 0;
+
+ east = atof(coord_opt->answers[0]);
+ north = atof(coord_opt->answers[1]);
+
+ line = Vect_find_line(Map, east, north, 0.0, GV_POINT | GV_CENTROID,
maxdist, 0, 0);
+
+ if (line == 0)
+ line = Vect_find_line(Map, east, north, 0.0, GV_LINE | GV_BOUNDARY |
GV_FACE, maxdist, 0, 0);
+
+
+ G_debug (2, "line = %d", line);
+
+ if (line == 0) {
+ G_warning(_("Nothing Found."));
+ return 0;
+
+ }
+ else {
+ type = Vect_read_line(Map, Points, Cats, line);
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+ if ((cat = Vect_get_line_cat(Map, line, field )) > 0)
+ sprintf(buff,_("category [%d]"),cat);
+
+ G_debug(2, "Deleting type [%d] number [%d] %s", type, line, buff);
+ Vect_delete_line(Map, line);
+ removed++;
+
+ /* attr_del(Map, layer, cat);*/
+ }
+
+ G_message(_("%d features deleted"), removed);
+ return 1;
+}
+
+
+int delete_categories(struct Map_info *Map)
+{
+
     struct cat_list * cl;
     int layer=atoi(fld_opt->answer);
+ int i, removed=0;

- G_debug(1,"layer = %d",layer);
-/*
- if(cat_opt->answer=NULL) {
- cats = coords_catlist(Map);
- }
- */
     cl = Vect_new_cat_list();
     Vect_str_to_cat_list(cat_opt->answer, cl);
-
+
+ G_debug(1,"layer = %d",layer);
+
     for(i=0;i<cl->n_ranges;i++) {
int cat, type, id, ret;
G_debug(1, "cl->min[%d]=%d, cl->max[%d]=%d, layer=%d",
i, cl->min[i], i, cl->max[i], cl->field);
for(cat=cl->min[i]; cat <= cl->max[i]; cat++) {
- ret = Vect_cidx_find_next(Map, layer, cat, GV_POINTS|GV_LINES,
+ ret = Vect_cidx_find_next(Map, layer, cat, GV_POINTS|GV_LINES |
GV_BOUNDARY | GV_CENTROID,
     0, &type, &id);
   G_debug(1, "ret=%d", ret);
   if(ret<0) continue;
- G_debug(1, "Found something to delete: id=%d, type=%d",id,type);
- if(type==GV_CENTROID) {
- int area;
- double x,y;
- Vect_get_node_coor(Map, id, &x, &y, NULL);
- area = Vect_find_area(Map, x, y);
- G_debug(1, "Deleteing area %d: id=%d, area=%d",cat,id,area);
-/* Vect_delete_line(Map, id); */
-/* Vect_delete_line(Map, area); */
- attr_del(Map, layer, cat);
- }
- else {
-/* Vect_delete_line(Map, id); */
- attr_del(Map, layer, cat);
- }
+ G_debug(2,"Deleting type [%d] number [%d] cat [%d]", type, id,
cat);
+ Vect_delete_line(Map, id);
+ /* attr_del(Map, layer, cat);*/
+ removed ++;
}
     }
+ G_message(_("%d features deleted"), removed);

     return 1;
}
Index: vector/v.edit/global.h

RCS file: /grassrepository/grass6/vector/v.edit/global.h,v
retrieving revision 1.6
diff -u -r1.6 global.h
--- vector/v.edit/global.h 7 Jun 2006 19:16:16 -0000 1.6
+++ vector/v.edit/global.h 12 Dec 2006 13:29:23 -0000
@@ -18,15 +18,18 @@
     MODE_ADD,
     MODE_DEL,
     MODE_MOVE,
- MODE_MERGE
+ MODE_VERTEX,
+ MODE_SPLIT,
+ MODE_BREAK
};

-void help(const char *msg);
int parser(int argc, char*argv);

-int do_add(struct Map_info *Map);
+int asc_to_bin(FILE *, struct Map_info *);
int do_del(struct Map_info *Map);
-
+int delete_categories(struct Map_info *Map);
+int delete_coordinates(struct Map_info *Map);
+int delete_bbox(struct Map_info *Map);

void cat_max_set ( int field, int cat);
int cat_max_get ( int field );
@@ -37,11 +40,12 @@
int attr_edit(struct Map_info *Map, int field, int cat, const char *vals);
int attr_del(struct Map_info *Map, int field, int cat);

-global struct Option *map_opt, *act_opt, *typ_opt, *cat_opt, *pnt_opt,
*fld_opt, *val_opt, *snp_opt;
-global struct Flag *n_flg, *t_flg, *d_flg, *b_flg, *c_flg;
+global struct Option *input_opt, *map_opt, *tool_opt, *coord_opt, *cat_opt,
*to_opt, *at_opt, *bbox_opt, *snap_opt, *fld_opt;
+global struct Flag *n_flg, *t_flg, *d_flg, *b_flg, *c_flg, *n_flg;
global struct GModule *module;
global struct Map_info Map;
global enum mode action_mode;
global char *mapset;
-global double snap;
+
+global FILE *ascii;
#endif
Index: vector/v.edit/main.c

RCS file: /grassrepository/grass6/vector/v.edit/main.c,v
retrieving revision 1.9
diff -u -r1.9 main.c
--- vector/v.edit/main.c 6 Oct 2006 06:47:56 -0000 1.9
+++ vector/v.edit/main.c 12 Dec 2006 13:29:23 -0000
@@ -21,6 +21,7 @@

#define MAIN
#include "global.h"
+
/* static int error_routine(const char*msg, int fatal); */

int main (int argc, char *argv)
@@ -56,7 +57,6 @@
     }
     else {
/* Vect_set_open_level(2); */
- G_message(_("Reading vector file ..."));
Vect_open_update (&Map, map_opt->answer, mapset);
     }
/* Vect_set_category_index_update ( &Map ); */
@@ -66,7 +66,8 @@

     switch(action_mode) {
       case MODE_ADD:
- ret = do_add(&Map);
+ G_message(_("Adding new features to vector file ..."));
+ ret = asc_to_bin(ascii, &Map) ;
break;
       case MODE_DEL:
ret = do_del(&Map);

_______________________________________________
grass-dev mailing list
grass-dev@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass-dev

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics and Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton

On Wed, 13 Dec 2006, Jachym Cepicky wrote:

Hallo,
since nobody answared, I suppose there nobody had enough time to check
the patches.

Before I move with further development, I would like to hear from the
GRASS-core developers, that this changes are all right and worth to be
committed to cvs.

I have now looked at the patches, but only briefly. It's good to hear that someone has picked up the little v.edit, while I've been busy elsewhere. (:
So far I like what I'm seeing. Good work. I think that this should be committed to the cvs.

Comments below:

I did not commit this changes yet, because of they are changing behavior
and features of v.edit significantly.

Removed options:
   type - there is no need to define type of the vector input feature,
           this can be done using other methods (grass ascii format)

OK, this will enable you to input many things in one command.

   values - all database updates should be done via db.* commands

Changes options:
   coords - coords were used for data inputs. But it could come to
           maximum length of a line limit.
           coords option is used for feature identification, not for
           data input

This is good, and this was my idea in the end, but I never got so far. I made coords into input to be able to test things.

   action->tool - IMHO "tool" does fit idea of the option better, than
           action

Yes. I like this. It is a lot nicer then option, but option is standard. I would go with tool.

   tools: merge - removed
           new tools introduced

Is merge not needed? Or do you think other modules should do this? Could you briefly describe the other tools? I noticed that they are in the wiki, but I'd like to hear your thoughts and ideas behind the other tools.

How to test this:
This commands should give you impression about how v.edit currently
works:

# copy soils map
g.copy vect=soils,tmp --o
d.mon x0
d.vect tmp

# add new line the soils map
echo "L 2 1
593229.5625 4917307.3125
606824.0625 4926102
1 60" | v.edit map=tmp tool=add

v.build tmp

I think that maybe v.edit should rebuild the topology, there shouldn't be any need to use v.build. Does anybody else have an opinion about this?

echo "insert into tmp (cat, label) values (60,'road');"|db.execute
d.redraw

# remove feature defined by coordinates
v.edit map=tmp tool=delete coords=593229.5625,4917307.3125
d.redraw # line should be removed

:slight_smile: nice

# remove feature defined by category
v.edit map=tmp tool=delete cat=13
d.redraw # big soil area on south should be removed

does this also remove the attributes from the DB?

# remove featuers defined by bounding box
d.graph -m color=0:255:0 << EOF
width 4
polyline
602203.125 4918112.25
602203.125 4924402.6875
604319.8125 4924402.6875
604319.8125 4918112.25
602203.125 4918112.25
EOF

v.edit map=tmp tool=delete bbox=602203.125,4918112.25,604319.8125,4924402.6875
d.redraw

I prepared new patch (attached). If there will be no provisos, I would
like to add this to cvs soon and continue with the development.

I think you should keep up the good work! Sorry I've had to disappear into the background...

--Wolf

--

<:3 )---- Wolf Bergenheim ----( 8:>

Hi Wolf, thanks your your comments,

see my below :wink:

On Thu, Dec 14, 2006 at 03:58:58PM +0200, Wolf Bergenheim wrote:

Yes. I like this. It is a lot nicer then option, but option is standard. I
would go with tool.

I just think, when other modules (v.clean) use this name of option,
v.edit should use it too :wink:

>
> tools: merge - removed
> new tools introduced

Is merge not needed? Or do you think other modules should do this? Could
you briefly describe the other tools? I noticed that they are in the wiki,
but I'd like to hear your thoughts and ideas behind the other tools.

no, sorry, I understood it wrong, I'll put it back.

> [...]
>v.build tmp

I think that maybe v.edit should rebuild the topology, there shouldn't be
any need to use v.build. Does anybody else have an opinion about this?

absolutely truth, this was not working only for "add" tool. it should be
all right now

>
># remove feature defined by category
>v.edit map=tmp tool=delete cat=13
>d.redraw # big soil area on south should be removed
>

does this also remove the attributes from the DB?

not yet. IMHO it should do so (accoring to -d flag)

>I prepared new patch (attached). If there will be no provisos, I would
>like to add this to cvs soon and continue with the development.
>

I think you should keep up the good work! Sorry I've had to disappear
into the background...

--Wolf

Thanks for your suggestions and for v.edit design!

Jachym
--
Jachym Cepicky
e-mail: jachym.cepicky@centrum.cz
URL: http://les-ejk.cz
GPG: http://www.les-ejk.cz/pgp/jachym_cepicky-gpg.pub
-----------------------------------------
OFFICE:
Department of Geoinformation Technologies
Zemedelska 3
613 00, Brno
Czech Republick
e-mail: xcepicky@node.mendelu.cz
URL: http://mapserver.mendelu.cz
Tel.: +420 545 134 514

Dear all,

all changes are in CVS now.

New tool=move implemented.

Documentation [1] updated.

Jachym

[1] http://grass.gdf-hannover.de/wiki/GRASS_Digitizing_tool#v.edit

On Tue, Dec 12, 2006 at 02:41:42PM +0100, Jachym Cepicky wrote:

Hallo,
according to suggested funtion of v.edit [1], I started to work on
v.edit module.

I prepared patch for this and it would be great, if anybody could look
at it and say, if it is worth to commit to cvs.

Currently, only tools "delete" and "add" are supported. But they cand be
used on slightly different way:

With this patch, v.edit no longer accepts input in form of comma
separated list of coordinates, but it reads input (tools "create" and
"add") from stdin or from ASCII file. I used a2b.c file from v.in.ascii
for this purpose. Currently, it does not accept header of the vector
file, so v.out.ascii vect|v.edit tool=add would not work.

For "tool=remove", new ways for feature definition are defined:

coords=x,y - remove feature, which can be found on coordinates x,y

cats=3,4 - remove reature with category 3 or 4

bbox=x1,y1,x2,y2 - remove features in bounding box

If everything will be all right, I'll continue on v.edit with moving and
spliting tools

Looking forward to your feedback

Jachym

[1] http://grass.gdf-hannover.de/wiki/GRASS_Digitizing_tool#v.edit
--
Jachym Cepicky
e-mail: jachym.cepicky@centrum.cz
URL: http://les-ejk.cz
GPG: http://www.les-ejk.cz/pgp/jachym_cepicky-gpg.pub
-----------------------------------------
OFFICE:
Department of Geoinformation Technologies
Zemedelska 3
613 00, Brno
Czech Republick
e-mail: xcepicky@node.mendelu.cz
URL: http://mapserver.mendelu.cz
Tel.: +420 545 134 514

Index: vector/v.edit/a2b.c

RCS file: vector/v.edit/a2b.c
diff -N vector/v.edit/a2b.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ vector/v.edit/a2b.c 12 Dec 2006 13:29:22 -0000
@@ -0,0 +1,171 @@
+/*
+ * This file has been adopted from v.in.ascii code
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include "global.h"
+
+#define BUFFSIZE 128
+
+int asc_to_bin(FILE *ascii , struct Map_info *Map)
+{
+ 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;
+ int alloc_points ;
+ int end_of_file ;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int catn;
+ int cat;
+
+ /* Must always use this to create an initialized line_pnts structure */
+ Points = Vect_new_line_struct ();
+ Cats = Vect_new_cats_struct ();
+
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 )
+ Vect_write_line ( Map, type, Points, Cats );
+
+ Vect_reset_cats ( Cats );
+ }
+ return 0;
+}
+
Index: vector/v.edit/args.c

RCS file: /grassrepository/grass6/vector/v.edit/args.c,v
retrieving revision 1.6
diff -u -r1.6 args.c
--- vector/v.edit/args.c 7 Jun 2006 19:16:16 -0000 1.6
+++ vector/v.edit/args.c 12 Dec 2006 13:29:22 -0000
@@ -4,48 +4,74 @@
{
     map_opt = G_define_standard_option(G_OPT_V_MAP);

- act_opt = G_define_option();
- act_opt->key = "action";
- act_opt->type = TYPE_STRING;
- act_opt->required = YES;
- act_opt->multiple = NO;
- act_opt->description = _("The edit action to take.");
- act_opt->options = "create,add,delete,move,merge";
-
- typ_opt = G_define_standard_option(G_OPT_V_TYPE);
- typ_opt->required = NO;
- typ_opt->description = _("Select type. Required for add action.");
- typ_opt->options = "point,line,area,centroid,boundary";
- typ_opt->answer = "point";
-
+ tool_opt = G_define_option();
+ tool_opt->key = "tool";
+ tool_opt->type = TYPE_STRING;
+ tool_opt->required = YES;
+ tool_opt->multiple = NO;
+ tool_opt->description = _("The edit tool to take.\n"
+ "\t\tcreate - Create new vector file\n"
+ "\t\tadd - Add new vector feature to existing vector file\n"
+ "\t\tdelete - Delete feature from vector file\n"
+ "\t\tmove - Move feature in vector file\n"
+ "\t\tvertex - Move just only vertex\n"
+ "\t\tbreak - Add new vertex to existing vector line\n"
+ "\t\tsplit - Split line into two separate lines");
+ tool_opt->options = "create,add,delete,move,vertex,break,split";
+
+ input_opt = G_define_option();
+ input_opt->key = "input";
+ input_opt->type = TYPE_STRING;
+ input_opt->required = NO;
+ input_opt->multiple = NO;
+ input_opt->description = _("ASCII file to be converted to binary vector file, if not given reads from standard input");
+
     cat_opt = G_define_standard_option(G_OPT_V_CATS);
     cat_opt->required = NO;
     
- pnt_opt = G_define_option();
- pnt_opt->key = "coords";
- pnt_opt->key_desc = "x,y";
- pnt_opt->type = TYPE_DOUBLE;
- pnt_opt->required = NO;
- pnt_opt->multiple = YES;
- pnt_opt->description = _("An x,y list of points. Required for add and move actions.");
-
- val_opt = G_define_option();
- val_opt->key = "values";
- val_opt->type = TYPE_STRING;
- val_opt->required = NO;
- val_opt->multiple = NO;
- val_opt->description = _("A comma-separated list of attr=val pairs.");
-
+ coord_opt = G_define_option();
+ coord_opt->key = "coords";
+ coord_opt->key_desc = "x,y";
+ coord_opt->type = TYPE_DOUBLE;
+ coord_opt->required = NO;
+ coord_opt->multiple = YES;
+ coord_opt->description = _("An x,y list of points. Required for add and move actions.");
+
+ to_opt = G_define_option();
+ to_opt->key = "to";
+ to_opt->key_desc = "x,y";
+ to_opt->type = TYPE_DOUBLE;
+ to_opt->required = NO;
+ to_opt->multiple = NO;
+ to_opt->description = _("An x,y location of selected feature");
+
+ at_opt = G_define_option();
+ at_opt->key = "at";
+ at_opt->key_desc = "x,y";
+ at_opt->type = TYPE_DOUBLE;
+ at_opt->required = NO;
+ at_opt->multiple = NO;
+ at_opt->description = _("An x,y location of breaking feature");
+
+ bbox_opt = G_define_option();
+ bbox_opt->key = "bbox";
+ bbox_opt->key_desc = "x1,y1,x2,y2";
+ bbox_opt->type = TYPE_DOUBLE;
+ bbox_opt->required = NO;
+ bbox_opt->multiple = NO;
+ bbox_opt->description = _("Bounding box of selected feature");
+
+ snap_opt = G_define_option();
+ snap_opt->key = "snap";
+ snap_opt->type = TYPE_DOUBLE;
+ snap_opt->required = NO;
+ snap_opt->multiple = NO;
+ snap_opt->description = _("Object points will snap to existing points within snap units.");
+ snap_opt->answer = "5.0";
+
+
     fld_opt = G_define_standard_option(G_OPT_V_FIELD);

- snp_opt = G_define_option();
- snp_opt->key = "snap";
- snp_opt->type = TYPE_DOUBLE;
- snp_opt->required = NO;
- snp_opt->multiple = NO;
- snp_opt->description = _("Object points will snap to existing points within snap units.");
- snp_opt->answer = "5.0";
-
     t_flg = G_define_flag();
     t_flg->key = 't';
     t_flg->description = _("Do not use topology.");
@@ -62,59 +88,136 @@
     c_flg->key = 'c';
     c_flg->description = _("Do not close boundaries");

+ n_flg = G_define_flag();
+ n_flg->key = 'n';
+ n_flg->description = _("Don't expect a header");
+
     if(G_parser(argc, argv))
   return 0;

     /* check that the given arguments makes sense together*/
/** @todo check for incorrect extra parameters */

- if(strcmp(act_opt->answer, "create")==0) { /* create requires nothing extra*/
+ if ( input_opt->answer != NULL ) {
+ if ( (ascii = fopen ( input_opt->answer, "r" ) ) == NULL )
+ {
+ G_warning(_("Could not open ascii file <%s>"), input_opt->answer);
+ G_usage();
+ }
+ } else {
+ ascii = stdin;
+ }
+
+ /* check for coordinate param */
+ if (coord_opt->answers != NULL) {
+ int i = 0;
+ for (i = 0; coord_opt->answers[i]; i ++)
+ ;
+ if (i%2 != 0) {
+ G_warning(_("Number of coordinates must be odd number"));
+ G_usage();
+ return 0;
+ }
+
+ }
+
+ /* check for bbox param */
+ if (bbox_opt->answers != NULL) {
+ int i = 0;
+ for (i = 0; bbox_opt->answers[i]; i ++)
+ ;
+ if (i%2 != 0) {
+ G_warning(_("Number of coordinates must be odd number"));
+ G_usage();
+ return 0;
+ }
+
+ }
+
+ if(strcmp(tool_opt->answer, "create")==0) { /* create requires nothing extra*/
   action_mode = MODE_CREATE;
   return 1;
     }
     
- snap = atof(snp_opt->answer);
-
- if(strcmp(act_opt->answer, "add")==0) { /* add requires a points argument */
+ if(strcmp(tool_opt->answer, "add")==0) { /* add requires a points argument */
   action_mode = MODE_ADD;
- if(pnt_opt->answers == NULL) {
- help(_("Required parameter <points> not set"));
+ return 1;
+ }
+ else if(strcmp(tool_opt->answer, "delete")==0) { /* del requires a cats or or bbox or coords*/
+ action_mode = MODE_DEL;
+ if((cat_opt->answers == NULL) &&
+ (coord_opt->answers == NULL) &&
+ (bbox_opt->answers == NULL)) {
+ G_warning(_("At least one from <%s> must be specified"),"cats, coords, bbox");
+ G_usage();
       return 0;
   };
   return 1;
     }
- else if(strcmp(act_opt->answer, "delete")==0) { /* del requires a cats */
- action_mode = MODE_DEL;
- if(cat_opt->answers == NULL) {
- help(_("Required parameter <cats> not set"));
+ else if(strcmp(tool_opt->answer, "move")==0) { /* move requires coords or cats arguments */
+ action_mode = MODE_MOVE;
+ if(to_opt->answers == NULL) {
+ G_warning(_("For <%s> operation, option <%s> must be set"),"move","to");
+ G_usage();
+ return 0;
+ }
+ if((coord_opt->answers == NULL) &&
+ (cat_opt->answers == NULL) &&
+ (bbox_opt->answers == NULL)) {
+ G_warning(_("At least one from <%s> must be specified"),"cats, coords, bbox");
+ G_usage();
       return 0;
   };
   return 1;
     }
- else if(strcmp(act_opt->answer, "move")==0) { /* move requires points and cats arguments */
- action_mode = MODE_ADD;
- if((pnt_opt->answers == NULL)||(cat_opt->answers == NULL)) {
- help(_("Both parameters <points> and <cats> are required."));
+
+ else if(strcmp(tool_opt->answer, "vertex")==0) { /* move vertex requires a coord and to options */
+ action_mode = MODE_VERTEX;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(to_opt->answers == NULL) {
+ G_warning(_("Required parameter <to> not set"));
+ G_usage();
       return 0;
   };
   return 1;
     }
- else if(strcmp(act_opt->answer, "merge")==0) { /* merge requires a cats argument */
- action_mode = MODE_ADD;
- if(cat_opt->answers == NULL) {
- help(_("Required parameter <cats> not set"));
+ else if(strcmp(tool_opt->answer, "break")==0) { /* break line requires a coord and at options */
+ action_mode = MODE_BREAK;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(at_opt->answers == NULL) {
+ G_warning(_("Required parameter <at> not set"));
+ G_usage();
       return 0;
   };
   return 1;
     }
+ else if(strcmp(tool_opt->answer, "split")==0) { /* split line requires a coord and at options */
+ action_mode = MODE_SPLIT;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(at_opt->answers == NULL) {
+ G_warning(_("Required parameter <at> not set"));
+ G_usage();
+ return 0;
+ };
+ return 1;
+ }
+
     else {
- help(_("This should never happen."));
+ G_warning(_("Operation <%s> not implemented."),tool_opt->answer);
+ G_usage();
   return 0;
     }
}

-void help(const char *msg)
-{
- G_message("\nERROR: %s\n\n", msg);
- G_usage();
-}
Index: vector/v.edit/del.c

RCS file: /grassrepository/grass6/vector/v.edit/del.c,v
retrieving revision 1.2
diff -u -r1.2 del.c
--- vector/v.edit/del.c 6 Oct 2006 06:47:56 -0000 1.2
+++ vector/v.edit/del.c 12 Dec 2006 13:29:23 -0000
@@ -2,45 +2,151 @@

int do_del(struct Map_info *Map)
{
- int i;
+ int res = 0;
+
+
+ /* cats or coord or bbox */
+ if(cat_opt->answer != NULL) {
+
+ res = delete_categories(Map);
+ }
+ else if (coord_opt->answer != NULL) {
+
+ res = delete_coordinates(Map);
+ }
+ else if (bbox_opt->answer != NULL) {
+
+ res = delete_bbox(Map);
+ }
+ else {
+ /* this case should not happen, see args.c for details */
+ G_warning("cats, coord or bbox must be specified");
+ }
+
+}
+
+int delete_bbox(struct Map_info *Map)
+{
+ double x1,y1,x2,y2;
+ BOUND_BOX bbox;
+ BOUND_BOX feature_bbox;
+ int cat, ret, type, i;
+ struct ilist *List;
+ SPATIAL_INDEX si;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int removed = 0;
+
+
+ /* bounding box */
+ x1 = atof(bbox_opt->answers[0]);
+ y1 = atof(bbox_opt->answers[1]);
+ x2 = atof(bbox_opt->answers[2]);
+ y2 = atof(bbox_opt->answers[3]);
+ 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 = 0.0;
+ bbox.B = 0.0;
+
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+ List = Vect_new_list ();
+
+ /* get lines number */
+ Vect_select_lines_by_box ( Map, &bbox, GV_POINTS | GV_LINES | GV_BOUNDARY | GV_CENTROID, List );
+ G_debug ( 1, " %d lines selected by box", List->n_values );
+
+ for ( i = 0; i < List->n_values; i++) {
+
+ type = Vect_read_line(Map, Points, Cats, List->value[i]);
+ G_debug(2, "Deleting type [%d] number [%d]", type, List->value[i]);
+ Vect_delete_line(Map, List->value[i]);
+ removed++;
+ /* attr_del(Map, layer, cat);*/
+ }
+ G_message(_("%d features deleted"), removed);
+ return 1;
+}
+
+int delete_coordinates(struct Map_info *Map)
+{
+ double east, north;
+ int line;
+ double maxdist = 0.5;
+ char buff[16] = "";
+
+ int type;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int cat;
+ int field=atoi(fld_opt->answer);
+ int removed = 0;
+
+ east = atof(coord_opt->answers[0]);
+ north = atof(coord_opt->answers[1]);
+
+ line = Vect_find_line(Map, east, north, 0.0, GV_POINT | GV_CENTROID, maxdist, 0, 0);
+
+ if (line == 0)
+ line = Vect_find_line(Map, east, north, 0.0, GV_LINE | GV_BOUNDARY | GV_FACE, maxdist, 0, 0);
+
+
+ G_debug (2, "line = %d", line);
+
+ if (line == 0) {
+ G_warning(_("Nothing Found."));
+ return 0;
+
+ }
+ else {
+ type = Vect_read_line(Map, Points, Cats, line);
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+ if ((cat = Vect_get_line_cat(Map, line, field )) > 0)
+ sprintf(buff,_("category [%d]"),cat);
+
+ G_debug(2, "Deleting type [%d] number [%d] %s", type, line, buff);
+ Vect_delete_line(Map, line);
+ removed++;
+
+ /* attr_del(Map, layer, cat);*/
+ }
+
+ G_message(_("%d features deleted"), removed);
+ return 1;
+}
+
+
+int delete_categories(struct Map_info *Map)
+{
+
     struct cat_list * cl;
     int layer=atoi(fld_opt->answer);
+ int i, removed=0;

- G_debug(1,"layer = %d",layer);
-/*
- if(cat_opt->answer=NULL) {
- cats = coords_catlist(Map);
- }
- */
     cl = Vect_new_cat_list();
     Vect_str_to_cat_list(cat_opt->answer, cl);
-
+
+ G_debug(1,"layer = %d",layer);
+
     for(i=0;i<cl->n_ranges;i++) {
   int cat, type, id, ret;
   G_debug(1, "cl->min[%d]=%d, cl->max[%d]=%d, layer=%d",
     i, cl->min[i], i, cl->max[i], cl->field);
   for(cat=cl->min[i]; cat <= cl->max[i]; cat++) {
- ret = Vect_cidx_find_next(Map, layer, cat, GV_POINTS|GV_LINES,
+ ret = Vect_cidx_find_next(Map, layer, cat, GV_POINTS|GV_LINES | GV_BOUNDARY | GV_CENTROID,
               0, &type, &id);
       G_debug(1, "ret=%d", ret);
       if(ret<0) continue;
- G_debug(1, "Found something to delete: id=%d, type=%d",id,type);
- if(type==GV_CENTROID) {
- int area;
- double x,y;
- Vect_get_node_coor(Map, id, &x, &y, NULL);
- area = Vect_find_area(Map, x, y);
- G_debug(1, "Deleteing area %d: id=%d, area=%d",cat,id,area);
-/* Vect_delete_line(Map, id); */
-/* Vect_delete_line(Map, area); */
- attr_del(Map, layer, cat);
- }
- else {
-/* Vect_delete_line(Map, id); */
- attr_del(Map, layer, cat);
- }
+ G_debug(2,"Deleting type [%d] number [%d] cat [%d]", type, id, cat);
+ Vect_delete_line(Map, id);
+ /* attr_del(Map, layer, cat);*/
+ removed ++;
   }
     }
+ G_message(_("%d features deleted"), removed);

     return 1;
}
Index: vector/v.edit/global.h

RCS file: /grassrepository/grass6/vector/v.edit/global.h,v
retrieving revision 1.6
diff -u -r1.6 global.h
--- vector/v.edit/global.h 7 Jun 2006 19:16:16 -0000 1.6
+++ vector/v.edit/global.h 12 Dec 2006 13:29:23 -0000
@@ -18,15 +18,18 @@
     MODE_ADD,
     MODE_DEL,
     MODE_MOVE,
- MODE_MERGE
+ MODE_VERTEX,
+ MODE_SPLIT,
+ MODE_BREAK
};

-void help(const char *msg);
int parser(int argc, char*argv);

-int do_add(struct Map_info *Map);
+int asc_to_bin(FILE *, struct Map_info *);
int do_del(struct Map_info *Map);
-
+int delete_categories(struct Map_info *Map);
+int delete_coordinates(struct Map_info *Map);
+int delete_bbox(struct Map_info *Map);

void cat_max_set ( int field, int cat);
int cat_max_get ( int field );
@@ -37,11 +40,12 @@
int attr_edit(struct Map_info *Map, int field, int cat, const char *vals);
int attr_del(struct Map_info *Map, int field, int cat);

-global struct Option *map_opt, *act_opt, *typ_opt, *cat_opt, *pnt_opt, *fld_opt, *val_opt, *snp_opt;
-global struct Flag *n_flg, *t_flg, *d_flg, *b_flg, *c_flg;
+global struct Option *input_opt, *map_opt, *tool_opt, *coord_opt, *cat_opt, *to_opt, *at_opt, *bbox_opt, *snap_opt, *fld_opt;
+global struct Flag *n_flg, *t_flg, *d_flg, *b_flg, *c_flg, *n_flg;
global struct GModule *module;
global struct Map_info Map;
global enum mode action_mode;
global char *mapset;
-global double snap;
+
+global FILE *ascii;
#endif
Index: vector/v.edit/main.c

RCS file: /grassrepository/grass6/vector/v.edit/main.c,v
retrieving revision 1.9
diff -u -r1.9 main.c
--- vector/v.edit/main.c 6 Oct 2006 06:47:56 -0000 1.9
+++ vector/v.edit/main.c 12 Dec 2006 13:29:23 -0000
@@ -21,6 +21,7 @@

#define MAIN
#include "global.h"
+
/* static int error_routine(const char*msg, int fatal); */

int main (int argc, char *argv)
@@ -56,7 +57,6 @@
     }
     else {
/* Vect_set_open_level(2); */
- G_message(_("Reading vector file ..."));
   Vect_open_update (&Map, map_opt->answer, mapset);
     }
/* Vect_set_category_index_update ( &Map ); */
@@ -66,7 +66,8 @@

     switch(action_mode) {
       case MODE_ADD:
- ret = do_add(&Map);
+ G_message(_("Adding new features to vector file ..."));
+ ret = asc_to_bin(ascii, &Map) ;
   break;
       case MODE_DEL:
   ret = do_del(&Map);

_______________________________________________
grass-dev mailing list
grass-dev@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass-dev

--
Jachym Cepicky
e-mail: jachym.cepicky@centrum.cz
URL: http://les-ejk.cz
GPG: http://www.les-ejk.cz/pgp/jachym_cepicky-gpg.pub
-----------------------------------------
OFFICE:
Department of Geoinformation Technologies
Zemedelska 3
613 00, Brno
Czech Republick
e-mail: xcepicky@node.mendelu.cz
URL: http://mapserver.mendelu.cz
Tel.: +420 545 134 514

hi,

new tool, "vertex" implemented. You can move vertexes defined by
coordinates (for better fitting, "snap" option can be used) or bounding
box (first line is choosed)

hope, everything works

jachym

On Tue, Dec 12, 2006 at 02:41:42PM +0100, Jachym Cepicky wrote:

Hallo,
according to suggested funtion of v.edit [1], I started to work on
v.edit module.

I prepared patch for this and it would be great, if anybody could look
at it and say, if it is worth to commit to cvs.

Currently, only tools "delete" and "add" are supported. But they cand be
used on slightly different way:

With this patch, v.edit no longer accepts input in form of comma
separated list of coordinates, but it reads input (tools "create" and
"add") from stdin or from ASCII file. I used a2b.c file from v.in.ascii
for this purpose. Currently, it does not accept header of the vector
file, so v.out.ascii vect|v.edit tool=add would not work.

For "tool=remove", new ways for feature definition are defined:

coords=x,y - remove feature, which can be found on coordinates x,y

cats=3,4 - remove reature with category 3 or 4

bbox=x1,y1,x2,y2 - remove features in bounding box

If everything will be all right, I'll continue on v.edit with moving and
spliting tools

Looking forward to your feedback

Jachym

[1] http://grass.gdf-hannover.de/wiki/GRASS_Digitizing_tool#v.edit
--
Jachym Cepicky
e-mail: jachym.cepicky@centrum.cz
URL: http://les-ejk.cz
GPG: http://www.les-ejk.cz/pgp/jachym_cepicky-gpg.pub
-----------------------------------------
OFFICE:
Department of Geoinformation Technologies
Zemedelska 3
613 00, Brno
Czech Republick
e-mail: xcepicky@node.mendelu.cz
URL: http://mapserver.mendelu.cz
Tel.: +420 545 134 514

Index: vector/v.edit/a2b.c

RCS file: vector/v.edit/a2b.c
diff -N vector/v.edit/a2b.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ vector/v.edit/a2b.c 12 Dec 2006 13:29:22 -0000
@@ -0,0 +1,171 @@
+/*
+ * This file has been adopted from v.in.ascii code
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include "global.h"
+
+#define BUFFSIZE 128
+
+int asc_to_bin(FILE *ascii , struct Map_info *Map)
+{
+ 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;
+ int alloc_points ;
+ int end_of_file ;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int catn;
+ int cat;
+
+ /* Must always use this to create an initialized line_pnts structure */
+ Points = Vect_new_line_struct ();
+ Cats = Vect_new_cats_struct ();
+
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 )
+ Vect_write_line ( Map, type, Points, Cats );
+
+ Vect_reset_cats ( Cats );
+ }
+ return 0;
+}
+
Index: vector/v.edit/args.c

RCS file: /grassrepository/grass6/vector/v.edit/args.c,v
retrieving revision 1.6
diff -u -r1.6 args.c
--- vector/v.edit/args.c 7 Jun 2006 19:16:16 -0000 1.6
+++ vector/v.edit/args.c 12 Dec 2006 13:29:22 -0000
@@ -4,48 +4,74 @@
{
     map_opt = G_define_standard_option(G_OPT_V_MAP);

- act_opt = G_define_option();
- act_opt->key = "action";
- act_opt->type = TYPE_STRING;
- act_opt->required = YES;
- act_opt->multiple = NO;
- act_opt->description = _("The edit action to take.");
- act_opt->options = "create,add,delete,move,merge";
-
- typ_opt = G_define_standard_option(G_OPT_V_TYPE);
- typ_opt->required = NO;
- typ_opt->description = _("Select type. Required for add action.");
- typ_opt->options = "point,line,area,centroid,boundary";
- typ_opt->answer = "point";
-
+ tool_opt = G_define_option();
+ tool_opt->key = "tool";
+ tool_opt->type = TYPE_STRING;
+ tool_opt->required = YES;
+ tool_opt->multiple = NO;
+ tool_opt->description = _("The edit tool to take.\n"
+ "\t\tcreate - Create new vector file\n"
+ "\t\tadd - Add new vector feature to existing vector file\n"
+ "\t\tdelete - Delete feature from vector file\n"
+ "\t\tmove - Move feature in vector file\n"
+ "\t\tvertex - Move just only vertex\n"
+ "\t\tbreak - Add new vertex to existing vector line\n"
+ "\t\tsplit - Split line into two separate lines");
+ tool_opt->options = "create,add,delete,move,vertex,break,split";
+
+ input_opt = G_define_option();
+ input_opt->key = "input";
+ input_opt->type = TYPE_STRING;
+ input_opt->required = NO;
+ input_opt->multiple = NO;
+ input_opt->description = _("ASCII file to be converted to binary vector file, if not given reads from standard input");
+
     cat_opt = G_define_standard_option(G_OPT_V_CATS);
     cat_opt->required = NO;
     
- pnt_opt = G_define_option();
- pnt_opt->key = "coords";
- pnt_opt->key_desc = "x,y";
- pnt_opt->type = TYPE_DOUBLE;
- pnt_opt->required = NO;
- pnt_opt->multiple = YES;
- pnt_opt->description = _("An x,y list of points. Required for add and move actions.");
-
- val_opt = G_define_option();
- val_opt->key = "values";
- val_opt->type = TYPE_STRING;
- val_opt->required = NO;
- val_opt->multiple = NO;
- val_opt->description = _("A comma-separated list of attr=val pairs.");
-
+ coord_opt = G_define_option();
+ coord_opt->key = "coords";
+ coord_opt->key_desc = "x,y";
+ coord_opt->type = TYPE_DOUBLE;
+ coord_opt->required = NO;
+ coord_opt->multiple = YES;
+ coord_opt->description = _("An x,y list of points. Required for add and move actions.");
+
+ to_opt = G_define_option();
+ to_opt->key = "to";
+ to_opt->key_desc = "x,y";
+ to_opt->type = TYPE_DOUBLE;
+ to_opt->required = NO;
+ to_opt->multiple = NO;
+ to_opt->description = _("An x,y location of selected feature");
+
+ at_opt = G_define_option();
+ at_opt->key = "at";
+ at_opt->key_desc = "x,y";
+ at_opt->type = TYPE_DOUBLE;
+ at_opt->required = NO;
+ at_opt->multiple = NO;
+ at_opt->description = _("An x,y location of breaking feature");
+
+ bbox_opt = G_define_option();
+ bbox_opt->key = "bbox";
+ bbox_opt->key_desc = "x1,y1,x2,y2";
+ bbox_opt->type = TYPE_DOUBLE;
+ bbox_opt->required = NO;
+ bbox_opt->multiple = NO;
+ bbox_opt->description = _("Bounding box of selected feature");
+
+ snap_opt = G_define_option();
+ snap_opt->key = "snap";
+ snap_opt->type = TYPE_DOUBLE;
+ snap_opt->required = NO;
+ snap_opt->multiple = NO;
+ snap_opt->description = _("Object points will snap to existing points within snap units.");
+ snap_opt->answer = "5.0";
+
+
     fld_opt = G_define_standard_option(G_OPT_V_FIELD);

- snp_opt = G_define_option();
- snp_opt->key = "snap";
- snp_opt->type = TYPE_DOUBLE;
- snp_opt->required = NO;
- snp_opt->multiple = NO;
- snp_opt->description = _("Object points will snap to existing points within snap units.");
- snp_opt->answer = "5.0";
-
     t_flg = G_define_flag();
     t_flg->key = 't';
     t_flg->description = _("Do not use topology.");
@@ -62,59 +88,136 @@
     c_flg->key = 'c';
     c_flg->description = _("Do not close boundaries");

+ n_flg = G_define_flag();
+ n_flg->key = 'n';
+ n_flg->description = _("Don't expect a header");
+
     if(G_parser(argc, argv))
   return 0;

     /* check that the given arguments makes sense together*/
/** @todo check for incorrect extra parameters */

- if(strcmp(act_opt->answer, "create")==0) { /* create requires nothing extra*/
+ if ( input_opt->answer != NULL ) {
+ if ( (ascii = fopen ( input_opt->answer, "r" ) ) == NULL )
+ {
+ G_warning(_("Could not open ascii file <%s>"), input_opt->answer);
+ G_usage();
+ }
+ } else {
+ ascii = stdin;
+ }
+
+ /* check for coordinate param */
+ if (coord_opt->answers != NULL) {
+ int i = 0;
+ for (i = 0; coord_opt->answers[i]; i ++)
+ ;
+ if (i%2 != 0) {
+ G_warning(_("Number of coordinates must be odd number"));
+ G_usage();
+ return 0;
+ }
+
+ }
+
+ /* check for bbox param */
+ if (bbox_opt->answers != NULL) {
+ int i = 0;
+ for (i = 0; bbox_opt->answers[i]; i ++)
+ ;
+ if (i%2 != 0) {
+ G_warning(_("Number of coordinates must be odd number"));
+ G_usage();
+ return 0;
+ }
+
+ }
+
+ if(strcmp(tool_opt->answer, "create")==0) { /* create requires nothing extra*/
   action_mode = MODE_CREATE;
   return 1;
     }
     
- snap = atof(snp_opt->answer);
-
- if(strcmp(act_opt->answer, "add")==0) { /* add requires a points argument */
+ if(strcmp(tool_opt->answer, "add")==0) { /* add requires a points argument */
   action_mode = MODE_ADD;
- if(pnt_opt->answers == NULL) {
- help(_("Required parameter <points> not set"));
+ return 1;
+ }
+ else if(strcmp(tool_opt->answer, "delete")==0) { /* del requires a cats or or bbox or coords*/
+ action_mode = MODE_DEL;
+ if((cat_opt->answers == NULL) &&
+ (coord_opt->answers == NULL) &&
+ (bbox_opt->answers == NULL)) {
+ G_warning(_("At least one from <%s> must be specified"),"cats, coords, bbox");
+ G_usage();
       return 0;
   };
   return 1;
     }
- else if(strcmp(act_opt->answer, "delete")==0) { /* del requires a cats */
- action_mode = MODE_DEL;
- if(cat_opt->answers == NULL) {
- help(_("Required parameter <cats> not set"));
+ else if(strcmp(tool_opt->answer, "move")==0) { /* move requires coords or cats arguments */
+ action_mode = MODE_MOVE;
+ if(to_opt->answers == NULL) {
+ G_warning(_("For <%s> operation, option <%s> must be set"),"move","to");
+ G_usage();
+ return 0;
+ }
+ if((coord_opt->answers == NULL) &&
+ (cat_opt->answers == NULL) &&
+ (bbox_opt->answers == NULL)) {
+ G_warning(_("At least one from <%s> must be specified"),"cats, coords, bbox");
+ G_usage();
       return 0;
   };
   return 1;
     }
- else if(strcmp(act_opt->answer, "move")==0) { /* move requires points and cats arguments */
- action_mode = MODE_ADD;
- if((pnt_opt->answers == NULL)||(cat_opt->answers == NULL)) {
- help(_("Both parameters <points> and <cats> are required."));
+
+ else if(strcmp(tool_opt->answer, "vertex")==0) { /* move vertex requires a coord and to options */
+ action_mode = MODE_VERTEX;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(to_opt->answers == NULL) {
+ G_warning(_("Required parameter <to> not set"));
+ G_usage();
       return 0;
   };
   return 1;
     }
- else if(strcmp(act_opt->answer, "merge")==0) { /* merge requires a cats argument */
- action_mode = MODE_ADD;
- if(cat_opt->answers == NULL) {
- help(_("Required parameter <cats> not set"));
+ else if(strcmp(tool_opt->answer, "break")==0) { /* break line requires a coord and at options */
+ action_mode = MODE_BREAK;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(at_opt->answers == NULL) {
+ G_warning(_("Required parameter <at> not set"));
+ G_usage();
       return 0;
   };
   return 1;
     }
+ else if(strcmp(tool_opt->answer, "split")==0) { /* split line requires a coord and at options */
+ action_mode = MODE_SPLIT;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(at_opt->answers == NULL) {
+ G_warning(_("Required parameter <at> not set"));
+ G_usage();
+ return 0;
+ };
+ return 1;
+ }
+
     else {
- help(_("This should never happen."));
+ G_warning(_("Operation <%s> not implemented."),tool_opt->answer);
+ G_usage();
   return 0;
     }
}

-void help(const char *msg)
-{
- G_message("\nERROR: %s\n\n", msg);
- G_usage();
-}
Index: vector/v.edit/del.c

RCS file: /grassrepository/grass6/vector/v.edit/del.c,v
retrieving revision 1.2
diff -u -r1.2 del.c
--- vector/v.edit/del.c 6 Oct 2006 06:47:56 -0000 1.2
+++ vector/v.edit/del.c 12 Dec 2006 13:29:23 -0000
@@ -2,45 +2,151 @@

int do_del(struct Map_info *Map)
{
- int i;
+ int res = 0;
+
+
+ /* cats or coord or bbox */
+ if(cat_opt->answer != NULL) {
+
+ res = delete_categories(Map);
+ }
+ else if (coord_opt->answer != NULL) {
+
+ res = delete_coordinates(Map);
+ }
+ else if (bbox_opt->answer != NULL) {
+
+ res = delete_bbox(Map);
+ }
+ else {
+ /* this case should not happen, see args.c for details */
+ G_warning("cats, coord or bbox must be specified");
+ }
+
+}
+
+int delete_bbox(struct Map_info *Map)
+{
+ double x1,y1,x2,y2;
+ BOUND_BOX bbox;
+ BOUND_BOX feature_bbox;
+ int cat, ret, type, i;
+ struct ilist *List;
+ SPATIAL_INDEX si;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int removed = 0;
+
+
+ /* bounding box */
+ x1 = atof(bbox_opt->answers[0]);
+ y1 = atof(bbox_opt->answers[1]);
+ x2 = atof(bbox_opt->answers[2]);
+ y2 = atof(bbox_opt->answers[3]);
+ 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 = 0.0;
+ bbox.B = 0.0;
+
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+ List = Vect_new_list ();
+
+ /* get lines number */
+ Vect_select_lines_by_box ( Map, &bbox, GV_POINTS | GV_LINES | GV_BOUNDARY | GV_CENTROID, List );
+ G_debug ( 1, " %d lines selected by box", List->n_values );
+
+ for ( i = 0; i < List->n_values; i++) {
+
+ type = Vect_read_line(Map, Points, Cats, List->value[i]);
+ G_debug(2, "Deleting type [%d] number [%d]", type, List->value[i]);
+ Vect_delete_line(Map, List->value[i]);
+ removed++;
+ /* attr_del(Map, layer, cat);*/
+ }
+ G_message(_("%d features deleted"), removed);
+ return 1;
+}
+
+int delete_coordinates(struct Map_info *Map)
+{
+ double east, north;
+ int line;
+ double maxdist = 0.5;
+ char buff[16] = "";
+
+ int type;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int cat;
+ int field=atoi(fld_opt->answer);
+ int removed = 0;
+
+ east = atof(coord_opt->answers[0]);
+ north = atof(coord_opt->answers[1]);
+
+ line = Vect_find_line(Map, east, north, 0.0, GV_POINT | GV_CENTROID, maxdist, 0, 0);
+
+ if (line == 0)
+ line = Vect_find_line(Map, east, north, 0.0, GV_LINE | GV_BOUNDARY | GV_FACE, maxdist, 0, 0);
+
+
+ G_debug (2, "line = %d", line);
+
+ if (line == 0) {
+ G_warning(_("Nothing Found."));
+ return 0;
+
+ }
+ else {
+ type = Vect_read_line(Map, Points, Cats, line);
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+ if ((cat = Vect_get_line_cat(Map, line, field )) > 0)
+ sprintf(buff,_("category [%d]"),cat);
+
+ G_debug(2, "Deleting type [%d] number [%d] %s", type, line, buff);
+ Vect_delete_line(Map, line);
+ removed++;
+
+ /* attr_del(Map, layer, cat);*/
+ }
+
+ G_message(_("%d features deleted"), removed);
+ return 1;
+}
+
+
+int delete_categories(struct Map_info *Map)
+{
+
     struct cat_list * cl;
     int layer=atoi(fld_opt->answer);
+ int i, removed=0;

- G_debug(1,"layer = %d",layer);
-/*
- if(cat_opt->answer=NULL) {
- cats = coords_catlist(Map);
- }
- */
     cl = Vect_new_cat_list();
     Vect_str_to_cat_list(cat_opt->answer, cl);
-
+
+ G_debug(1,"layer = %d",layer);
+
     for(i=0;i<cl->n_ranges;i++) {
   int cat, type, id, ret;
   G_debug(1, "cl->min[%d]=%d, cl->max[%d]=%d, layer=%d",
     i, cl->min[i], i, cl->max[i], cl->field);
   for(cat=cl->min[i]; cat <= cl->max[i]; cat++) {
- ret = Vect_cidx_find_next(Map, layer, cat, GV_POINTS|GV_LINES,
+ ret = Vect_cidx_find_next(Map, layer, cat, GV_POINTS|GV_LINES | GV_BOUNDARY | GV_CENTROID,
               0, &type, &id);
       G_debug(1, "ret=%d", ret);
       if(ret<0) continue;
- G_debug(1, "Found something to delete: id=%d, type=%d",id,type);
- if(type==GV_CENTROID) {
- int area;
- double x,y;
- Vect_get_node_coor(Map, id, &x, &y, NULL);
- area = Vect_find_area(Map, x, y);
- G_debug(1, "Deleteing area %d: id=%d, area=%d",cat,id,area);
-/* Vect_delete_line(Map, id); */
-/* Vect_delete_line(Map, area); */
- attr_del(Map, layer, cat);
- }
- else {
-/* Vect_delete_line(Map, id); */
- attr_del(Map, layer, cat);
- }
+ G_debug(2,"Deleting type [%d] number [%d] cat [%d]", type, id, cat);
+ Vect_delete_line(Map, id);
+ /* attr_del(Map, layer, cat);*/
+ removed ++;
   }
     }
+ G_message(_("%d features deleted"), removed);

     return 1;
}
Index: vector/v.edit/global.h

RCS file: /grassrepository/grass6/vector/v.edit/global.h,v
retrieving revision 1.6
diff -u -r1.6 global.h
--- vector/v.edit/global.h 7 Jun 2006 19:16:16 -0000 1.6
+++ vector/v.edit/global.h 12 Dec 2006 13:29:23 -0000
@@ -18,15 +18,18 @@
     MODE_ADD,
     MODE_DEL,
     MODE_MOVE,
- MODE_MERGE
+ MODE_VERTEX,
+ MODE_SPLIT,
+ MODE_BREAK
};

-void help(const char *msg);
int parser(int argc, char*argv);

-int do_add(struct Map_info *Map);
+int asc_to_bin(FILE *, struct Map_info *);
int do_del(struct Map_info *Map);
-
+int delete_categories(struct Map_info *Map);
+int delete_coordinates(struct Map_info *Map);
+int delete_bbox(struct Map_info *Map);

void cat_max_set ( int field, int cat);
int cat_max_get ( int field );
@@ -37,11 +40,12 @@
int attr_edit(struct Map_info *Map, int field, int cat, const char *vals);
int attr_del(struct Map_info *Map, int field, int cat);

-global struct Option *map_opt, *act_opt, *typ_opt, *cat_opt, *pnt_opt, *fld_opt, *val_opt, *snp_opt;
-global struct Flag *n_flg, *t_flg, *d_flg, *b_flg, *c_flg;
+global struct Option *input_opt, *map_opt, *tool_opt, *coord_opt, *cat_opt, *to_opt, *at_opt, *bbox_opt, *snap_opt, *fld_opt;
+global struct Flag *n_flg, *t_flg, *d_flg, *b_flg, *c_flg, *n_flg;
global struct GModule *module;
global struct Map_info Map;
global enum mode action_mode;
global char *mapset;
-global double snap;
+
+global FILE *ascii;
#endif
Index: vector/v.edit/main.c

RCS file: /grassrepository/grass6/vector/v.edit/main.c,v
retrieving revision 1.9
diff -u -r1.9 main.c
--- vector/v.edit/main.c 6 Oct 2006 06:47:56 -0000 1.9
+++ vector/v.edit/main.c 12 Dec 2006 13:29:23 -0000
@@ -21,6 +21,7 @@

#define MAIN
#include "global.h"
+
/* static int error_routine(const char*msg, int fatal); */

int main (int argc, char *argv)
@@ -56,7 +57,6 @@
     }
     else {
/* Vect_set_open_level(2); */
- G_message(_("Reading vector file ..."));
   Vect_open_update (&Map, map_opt->answer, mapset);
     }
/* Vect_set_category_index_update ( &Map ); */
@@ -66,7 +66,8 @@

     switch(action_mode) {
       case MODE_ADD:
- ret = do_add(&Map);
+ G_message(_("Adding new features to vector file ..."));
+ ret = asc_to_bin(ascii, &Map) ;
   break;
       case MODE_DEL:
   ret = do_del(&Map);

_______________________________________________
grass-dev mailing list
grass-dev@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass-dev

--
Jachym Cepicky
e-mail: jachym.cepicky@centrum.cz
URL: http://les-ejk.cz
GPG: http://www.les-ejk.cz/pgp/jachym_cepicky-gpg.pub
-----------------------------------------
OFFICE:
Department of Geoinformation Technologies
Zemedelska 3
613 00, Brno
Czech Republick
e-mail: xcepicky@node.mendelu.cz
URL: http://mapserver.mendelu.cz
Tel.: +420 545 134 514

Hi,
I just wanted to note, that v.edit supports now all tools defined in the
wiki [1]:

create - Create new vector file
add - Add new vector feature to existing vector file
delete - Delete feature from vector file
move - Move feature in vector file
vertex - Move just vertex
straight - Remove vertex
merge - Merge two vector lines togher
break - Add new vertex to existing vector line
split - Split line into two separate lines

Would be good, if anybody could test it and drop some notes about the user interface
and how clear the tool names are.

Next target is to add support for database updates too, current version of v.edit works
only for vector geometry

Jachym

[1] http://grass.gdf-hannover.de/wiki/GRASS_Digitizing_tool
On Tue, Dec 12, 2006 at 02:41:42PM +0100, Jachym Cepicky wrote:

Hallo,
according to suggested funtion of v.edit [1], I started to work on
v.edit module.

I prepared patch for this and it would be great, if anybody could look
at it and say, if it is worth to commit to cvs.

Currently, only tools "delete" and "add" are supported. But they cand be
used on slightly different way:

With this patch, v.edit no longer accepts input in form of comma
separated list of coordinates, but it reads input (tools "create" and
"add") from stdin or from ASCII file. I used a2b.c file from v.in.ascii
for this purpose. Currently, it does not accept header of the vector
file, so v.out.ascii vect|v.edit tool=add would not work.

For "tool=remove", new ways for feature definition are defined:

coords=x,y - remove feature, which can be found on coordinates x,y

cats=3,4 - remove reature with category 3 or 4

bbox=x1,y1,x2,y2 - remove features in bounding box

If everything will be all right, I'll continue on v.edit with moving and
spliting tools

Looking forward to your feedback

Jachym

[1] http://grass.gdf-hannover.de/wiki/GRASS_Digitizing_tool#v.edit
--
Jachym Cepicky
e-mail: jachym.cepicky@centrum.cz
URL: http://les-ejk.cz
GPG: http://www.les-ejk.cz/pgp/jachym_cepicky-gpg.pub
-----------------------------------------
OFFICE:
Department of Geoinformation Technologies
Zemedelska 3
613 00, Brno
Czech Republick
e-mail: xcepicky@node.mendelu.cz
URL: http://mapserver.mendelu.cz
Tel.: +420 545 134 514

Index: vector/v.edit/a2b.c

RCS file: vector/v.edit/a2b.c
diff -N vector/v.edit/a2b.c
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ vector/v.edit/a2b.c 12 Dec 2006 13:29:22 -0000
@@ -0,0 +1,171 @@
+/*
+ * This file has been adopted from v.in.ascii code
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <grass/gis.h>
+#include <grass/Vect.h>
+#include <grass/glocale.h>
+#include "global.h"
+
+#define BUFFSIZE 128
+
+int asc_to_bin(FILE *ascii , struct Map_info *Map)
+{
+ 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;
+ int alloc_points ;
+ int end_of_file ;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int catn;
+ int cat;
+
+ /* Must always use this to create an initialized line_pnts structure */
+ Points = Vect_new_line_struct ();
+ Cats = Vect_new_cats_struct ();
+
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 0;
+ }
+ 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 )
+ Vect_write_line ( Map, type, Points, Cats );
+
+ Vect_reset_cats ( Cats );
+ }
+ return 0;
+}
+
Index: vector/v.edit/args.c

RCS file: /grassrepository/grass6/vector/v.edit/args.c,v
retrieving revision 1.6
diff -u -r1.6 args.c
--- vector/v.edit/args.c 7 Jun 2006 19:16:16 -0000 1.6
+++ vector/v.edit/args.c 12 Dec 2006 13:29:22 -0000
@@ -4,48 +4,74 @@
{
     map_opt = G_define_standard_option(G_OPT_V_MAP);

- act_opt = G_define_option();
- act_opt->key = "action";
- act_opt->type = TYPE_STRING;
- act_opt->required = YES;
- act_opt->multiple = NO;
- act_opt->description = _("The edit action to take.");
- act_opt->options = "create,add,delete,move,merge";
-
- typ_opt = G_define_standard_option(G_OPT_V_TYPE);
- typ_opt->required = NO;
- typ_opt->description = _("Select type. Required for add action.");
- typ_opt->options = "point,line,area,centroid,boundary";
- typ_opt->answer = "point";
-
+ tool_opt = G_define_option();
+ tool_opt->key = "tool";
+ tool_opt->type = TYPE_STRING;
+ tool_opt->required = YES;
+ tool_opt->multiple = NO;
+ tool_opt->description = _("The edit tool to take.\n"
+ "\t\tcreate - Create new vector file\n"
+ "\t\tadd - Add new vector feature to existing vector file\n"
+ "\t\tdelete - Delete feature from vector file\n"
+ "\t\tmove - Move feature in vector file\n"
+ "\t\tvertex - Move just only vertex\n"
+ "\t\tbreak - Add new vertex to existing vector line\n"
+ "\t\tsplit - Split line into two separate lines");
+ tool_opt->options = "create,add,delete,move,vertex,break,split";
+
+ input_opt = G_define_option();
+ input_opt->key = "input";
+ input_opt->type = TYPE_STRING;
+ input_opt->required = NO;
+ input_opt->multiple = NO;
+ input_opt->description = _("ASCII file to be converted to binary vector file, if not given reads from standard input");
+
     cat_opt = G_define_standard_option(G_OPT_V_CATS);
     cat_opt->required = NO;
     
- pnt_opt = G_define_option();
- pnt_opt->key = "coords";
- pnt_opt->key_desc = "x,y";
- pnt_opt->type = TYPE_DOUBLE;
- pnt_opt->required = NO;
- pnt_opt->multiple = YES;
- pnt_opt->description = _("An x,y list of points. Required for add and move actions.");
-
- val_opt = G_define_option();
- val_opt->key = "values";
- val_opt->type = TYPE_STRING;
- val_opt->required = NO;
- val_opt->multiple = NO;
- val_opt->description = _("A comma-separated list of attr=val pairs.");
-
+ coord_opt = G_define_option();
+ coord_opt->key = "coords";
+ coord_opt->key_desc = "x,y";
+ coord_opt->type = TYPE_DOUBLE;
+ coord_opt->required = NO;
+ coord_opt->multiple = YES;
+ coord_opt->description = _("An x,y list of points. Required for add and move actions.");
+
+ to_opt = G_define_option();
+ to_opt->key = "to";
+ to_opt->key_desc = "x,y";
+ to_opt->type = TYPE_DOUBLE;
+ to_opt->required = NO;
+ to_opt->multiple = NO;
+ to_opt->description = _("An x,y location of selected feature");
+
+ at_opt = G_define_option();
+ at_opt->key = "at";
+ at_opt->key_desc = "x,y";
+ at_opt->type = TYPE_DOUBLE;
+ at_opt->required = NO;
+ at_opt->multiple = NO;
+ at_opt->description = _("An x,y location of breaking feature");
+
+ bbox_opt = G_define_option();
+ bbox_opt->key = "bbox";
+ bbox_opt->key_desc = "x1,y1,x2,y2";
+ bbox_opt->type = TYPE_DOUBLE;
+ bbox_opt->required = NO;
+ bbox_opt->multiple = NO;
+ bbox_opt->description = _("Bounding box of selected feature");
+
+ snap_opt = G_define_option();
+ snap_opt->key = "snap";
+ snap_opt->type = TYPE_DOUBLE;
+ snap_opt->required = NO;
+ snap_opt->multiple = NO;
+ snap_opt->description = _("Object points will snap to existing points within snap units.");
+ snap_opt->answer = "5.0";
+
+
     fld_opt = G_define_standard_option(G_OPT_V_FIELD);

- snp_opt = G_define_option();
- snp_opt->key = "snap";
- snp_opt->type = TYPE_DOUBLE;
- snp_opt->required = NO;
- snp_opt->multiple = NO;
- snp_opt->description = _("Object points will snap to existing points within snap units.");
- snp_opt->answer = "5.0";
-
     t_flg = G_define_flag();
     t_flg->key = 't';
     t_flg->description = _("Do not use topology.");
@@ -62,59 +88,136 @@
     c_flg->key = 'c';
     c_flg->description = _("Do not close boundaries");

+ n_flg = G_define_flag();
+ n_flg->key = 'n';
+ n_flg->description = _("Don't expect a header");
+
     if(G_parser(argc, argv))
   return 0;

     /* check that the given arguments makes sense together*/
/** @todo check for incorrect extra parameters */

- if(strcmp(act_opt->answer, "create")==0) { /* create requires nothing extra*/
+ if ( input_opt->answer != NULL ) {
+ if ( (ascii = fopen ( input_opt->answer, "r" ) ) == NULL )
+ {
+ G_warning(_("Could not open ascii file <%s>"), input_opt->answer);
+ G_usage();
+ }
+ } else {
+ ascii = stdin;
+ }
+
+ /* check for coordinate param */
+ if (coord_opt->answers != NULL) {
+ int i = 0;
+ for (i = 0; coord_opt->answers[i]; i ++)
+ ;
+ if (i%2 != 0) {
+ G_warning(_("Number of coordinates must be odd number"));
+ G_usage();
+ return 0;
+ }
+
+ }
+
+ /* check for bbox param */
+ if (bbox_opt->answers != NULL) {
+ int i = 0;
+ for (i = 0; bbox_opt->answers[i]; i ++)
+ ;
+ if (i%2 != 0) {
+ G_warning(_("Number of coordinates must be odd number"));
+ G_usage();
+ return 0;
+ }
+
+ }
+
+ if(strcmp(tool_opt->answer, "create")==0) { /* create requires nothing extra*/
   action_mode = MODE_CREATE;
   return 1;
     }
     
- snap = atof(snp_opt->answer);
-
- if(strcmp(act_opt->answer, "add")==0) { /* add requires a points argument */
+ if(strcmp(tool_opt->answer, "add")==0) { /* add requires a points argument */
   action_mode = MODE_ADD;
- if(pnt_opt->answers == NULL) {
- help(_("Required parameter <points> not set"));
+ return 1;
+ }
+ else if(strcmp(tool_opt->answer, "delete")==0) { /* del requires a cats or or bbox or coords*/
+ action_mode = MODE_DEL;
+ if((cat_opt->answers == NULL) &&
+ (coord_opt->answers == NULL) &&
+ (bbox_opt->answers == NULL)) {
+ G_warning(_("At least one from <%s> must be specified"),"cats, coords, bbox");
+ G_usage();
       return 0;
   };
   return 1;
     }
- else if(strcmp(act_opt->answer, "delete")==0) { /* del requires a cats */
- action_mode = MODE_DEL;
- if(cat_opt->answers == NULL) {
- help(_("Required parameter <cats> not set"));
+ else if(strcmp(tool_opt->answer, "move")==0) { /* move requires coords or cats arguments */
+ action_mode = MODE_MOVE;
+ if(to_opt->answers == NULL) {
+ G_warning(_("For <%s> operation, option <%s> must be set"),"move","to");
+ G_usage();
+ return 0;
+ }
+ if((coord_opt->answers == NULL) &&
+ (cat_opt->answers == NULL) &&
+ (bbox_opt->answers == NULL)) {
+ G_warning(_("At least one from <%s> must be specified"),"cats, coords, bbox");
+ G_usage();
       return 0;
   };
   return 1;
     }
- else if(strcmp(act_opt->answer, "move")==0) { /* move requires points and cats arguments */
- action_mode = MODE_ADD;
- if((pnt_opt->answers == NULL)||(cat_opt->answers == NULL)) {
- help(_("Both parameters <points> and <cats> are required."));
+
+ else if(strcmp(tool_opt->answer, "vertex")==0) { /* move vertex requires a coord and to options */
+ action_mode = MODE_VERTEX;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(to_opt->answers == NULL) {
+ G_warning(_("Required parameter <to> not set"));
+ G_usage();
       return 0;
   };
   return 1;
     }
- else if(strcmp(act_opt->answer, "merge")==0) { /* merge requires a cats argument */
- action_mode = MODE_ADD;
- if(cat_opt->answers == NULL) {
- help(_("Required parameter <cats> not set"));
+ else if(strcmp(tool_opt->answer, "break")==0) { /* break line requires a coord and at options */
+ action_mode = MODE_BREAK;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(at_opt->answers == NULL) {
+ G_warning(_("Required parameter <at> not set"));
+ G_usage();
       return 0;
   };
   return 1;
     }
+ else if(strcmp(tool_opt->answer, "split")==0) { /* split line requires a coord and at options */
+ action_mode = MODE_SPLIT;
+ if(coord_opt->answers == NULL) {
+ G_warning(_("Required parameter <coords> not set"));
+ G_usage();
+ return 0;
+ };
+ if(at_opt->answers == NULL) {
+ G_warning(_("Required parameter <at> not set"));
+ G_usage();
+ return 0;
+ };
+ return 1;
+ }
+
     else {
- help(_("This should never happen."));
+ G_warning(_("Operation <%s> not implemented."),tool_opt->answer);
+ G_usage();
   return 0;
     }
}

-void help(const char *msg)
-{
- G_message("\nERROR: %s\n\n", msg);
- G_usage();
-}
Index: vector/v.edit/del.c

RCS file: /grassrepository/grass6/vector/v.edit/del.c,v
retrieving revision 1.2
diff -u -r1.2 del.c
--- vector/v.edit/del.c 6 Oct 2006 06:47:56 -0000 1.2
+++ vector/v.edit/del.c 12 Dec 2006 13:29:23 -0000
@@ -2,45 +2,151 @@

int do_del(struct Map_info *Map)
{
- int i;
+ int res = 0;
+
+
+ /* cats or coord or bbox */
+ if(cat_opt->answer != NULL) {
+
+ res = delete_categories(Map);
+ }
+ else if (coord_opt->answer != NULL) {
+
+ res = delete_coordinates(Map);
+ }
+ else if (bbox_opt->answer != NULL) {
+
+ res = delete_bbox(Map);
+ }
+ else {
+ /* this case should not happen, see args.c for details */
+ G_warning("cats, coord or bbox must be specified");
+ }
+
+}
+
+int delete_bbox(struct Map_info *Map)
+{
+ double x1,y1,x2,y2;
+ BOUND_BOX bbox;
+ BOUND_BOX feature_bbox;
+ int cat, ret, type, i;
+ struct ilist *List;
+ SPATIAL_INDEX si;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int removed = 0;
+
+
+ /* bounding box */
+ x1 = atof(bbox_opt->answers[0]);
+ y1 = atof(bbox_opt->answers[1]);
+ x2 = atof(bbox_opt->answers[2]);
+ y2 = atof(bbox_opt->answers[3]);
+ 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 = 0.0;
+ bbox.B = 0.0;
+
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+ List = Vect_new_list ();
+
+ /* get lines number */
+ Vect_select_lines_by_box ( Map, &bbox, GV_POINTS | GV_LINES | GV_BOUNDARY | GV_CENTROID, List );
+ G_debug ( 1, " %d lines selected by box", List->n_values );
+
+ for ( i = 0; i < List->n_values; i++) {
+
+ type = Vect_read_line(Map, Points, Cats, List->value[i]);
+ G_debug(2, "Deleting type [%d] number [%d]", type, List->value[i]);
+ Vect_delete_line(Map, List->value[i]);
+ removed++;
+ /* attr_del(Map, layer, cat);*/
+ }
+ G_message(_("%d features deleted"), removed);
+ return 1;
+}
+
+int delete_coordinates(struct Map_info *Map)
+{
+ double east, north;
+ int line;
+ double maxdist = 0.5;
+ char buff[16] = "";
+
+ int type;
+ struct line_pnts *Points;
+ struct line_cats *Cats;
+ int cat;
+ int field=atoi(fld_opt->answer);
+ int removed = 0;
+
+ east = atof(coord_opt->answers[0]);
+ north = atof(coord_opt->answers[1]);
+
+ line = Vect_find_line(Map, east, north, 0.0, GV_POINT | GV_CENTROID, maxdist, 0, 0);
+
+ if (line == 0)
+ line = Vect_find_line(Map, east, north, 0.0, GV_LINE | GV_BOUNDARY | GV_FACE, maxdist, 0, 0);
+
+
+ G_debug (2, "line = %d", line);
+
+ if (line == 0) {
+ G_warning(_("Nothing Found."));
+ return 0;
+
+ }
+ else {
+ type = Vect_read_line(Map, Points, Cats, line);
+ Points = Vect_new_line_struct();
+ Cats = Vect_new_cats_struct();
+ if ((cat = Vect_get_line_cat(Map, line, field )) > 0)
+ sprintf(buff,_("category [%d]"),cat);
+
+ G_debug(2, "Deleting type [%d] number [%d] %s", type, line, buff);
+ Vect_delete_line(Map, line);
+ removed++;
+
+ /* attr_del(Map, layer, cat);*/
+ }
+
+ G_message(_("%d features deleted"), removed);
+ return 1;
+}
+
+
+int delete_categories(struct Map_info *Map)
+{
+
     struct cat_list * cl;
     int layer=atoi(fld_opt->answer);
+ int i, removed=0;

- G_debug(1,"layer = %d",layer);
-/*
- if(cat_opt->answer=NULL) {
- cats = coords_catlist(Map);
- }
- */
     cl = Vect_new_cat_list();
     Vect_str_to_cat_list(cat_opt->answer, cl);
-
+
+ G_debug(1,"layer = %d",layer);
+
     for(i=0;i<cl->n_ranges;i++) {
   int cat, type, id, ret;
   G_debug(1, "cl->min[%d]=%d, cl->max[%d]=%d, layer=%d",
     i, cl->min[i], i, cl->max[i], cl->field);
   for(cat=cl->min[i]; cat <= cl->max[i]; cat++) {
- ret = Vect_cidx_find_next(Map, layer, cat, GV_POINTS|GV_LINES,
+ ret = Vect_cidx_find_next(Map, layer, cat, GV_POINTS|GV_LINES | GV_BOUNDARY | GV_CENTROID,
               0, &type, &id);
       G_debug(1, "ret=%d", ret);
       if(ret<0) continue;
- G_debug(1, "Found something to delete: id=%d, type=%d",id,type);
- if(type==GV_CENTROID) {
- int area;
- double x,y;
- Vect_get_node_coor(Map, id, &x, &y, NULL);
- area = Vect_find_area(Map, x, y);
- G_debug(1, "Deleteing area %d: id=%d, area=%d",cat,id,area);
-/* Vect_delete_line(Map, id); */
-/* Vect_delete_line(Map, area); */
- attr_del(Map, layer, cat);
- }
- else {
-/* Vect_delete_line(Map, id); */
- attr_del(Map, layer, cat);
- }
+ G_debug(2,"Deleting type [%d] number [%d] cat [%d]", type, id, cat);
+ Vect_delete_line(Map, id);
+ /* attr_del(Map, layer, cat);*/
+ removed ++;
   }
     }
+ G_message(_("%d features deleted"), removed);

     return 1;
}
Index: vector/v.edit/global.h

RCS file: /grassrepository/grass6/vector/v.edit/global.h,v
retrieving revision 1.6
diff -u -r1.6 global.h
--- vector/v.edit/global.h 7 Jun 2006 19:16:16 -0000 1.6
+++ vector/v.edit/global.h 12 Dec 2006 13:29:23 -0000
@@ -18,15 +18,18 @@
     MODE_ADD,
     MODE_DEL,
     MODE_MOVE,
- MODE_MERGE
+ MODE_VERTEX,
+ MODE_SPLIT,
+ MODE_BREAK
};

-void help(const char *msg);
int parser(int argc, char*argv);

-int do_add(struct Map_info *Map);
+int asc_to_bin(FILE *, struct Map_info *);
int do_del(struct Map_info *Map);
-
+int delete_categories(struct Map_info *Map);
+int delete_coordinates(struct Map_info *Map);
+int delete_bbox(struct Map_info *Map);

void cat_max_set ( int field, int cat);
int cat_max_get ( int field );
@@ -37,11 +40,12 @@
int attr_edit(struct Map_info *Map, int field, int cat, const char *vals);
int attr_del(struct Map_info *Map, int field, int cat);

-global struct Option *map_opt, *act_opt, *typ_opt, *cat_opt, *pnt_opt, *fld_opt, *val_opt, *snp_opt;
-global struct Flag *n_flg, *t_flg, *d_flg, *b_flg, *c_flg;
+global struct Option *input_opt, *map_opt, *tool_opt, *coord_opt, *cat_opt, *to_opt, *at_opt, *bbox_opt, *snap_opt, *fld_opt;
+global struct Flag *n_flg, *t_flg, *d_flg, *b_flg, *c_flg, *n_flg;
global struct GModule *module;
global struct Map_info Map;
global enum mode action_mode;
global char *mapset;
-global double snap;
+
+global FILE *ascii;
#endif
Index: vector/v.edit/main.c

RCS file: /grassrepository/grass6/vector/v.edit/main.c,v
retrieving revision 1.9
diff -u -r1.9 main.c
--- vector/v.edit/main.c 6 Oct 2006 06:47:56 -0000 1.9
+++ vector/v.edit/main.c 12 Dec 2006 13:29:23 -0000
@@ -21,6 +21,7 @@

#define MAIN
#include "global.h"
+
/* static int error_routine(const char*msg, int fatal); */

int main (int argc, char *argv)
@@ -56,7 +57,6 @@
     }
     else {
/* Vect_set_open_level(2); */
- G_message(_("Reading vector file ..."));
   Vect_open_update (&Map, map_opt->answer, mapset);
     }
/* Vect_set_category_index_update ( &Map ); */
@@ -66,7 +66,8 @@

     switch(action_mode) {
       case MODE_ADD:
- ret = do_add(&Map);
+ G_message(_("Adding new features to vector file ..."));
+ ret = asc_to_bin(ascii, &Map) ;
   break;
       case MODE_DEL:
   ret = do_del(&Map);

_______________________________________________
grass-dev mailing list
grass-dev@grass.itc.it
http://grass.itc.it/mailman/listinfo/grass-dev

--
Jachym Cepicky
e-mail: jachym.cepicky@centrum.cz
URL: http://les-ejk.cz
GPG: http://www.les-ejk.cz/pgp/jachym_cepicky-gpg.pub
-----------------------------------------
OFFICE:
Department of Geoinformation Technologies
Zemedelska 3
613 00, Brno
Czech Republick
e-mail: xcepicky@node.mendelu.cz
URL: http://mapserver.mendelu.cz
Tel.: +420 545 134 514

Jachym,

This is really nice. Thanks for doing it. It should be able to form the core
of an excellent digitizer.

Michael

On 12/22/06 2:45 PM, "Jachym Cepicky" <jachym.cepicky@centrum.cz> wrote:

Hi,
I just wanted to note, that v.edit supports now all tools defined in the
wiki [1]:

create - Create new vector file
add - Add new vector feature to existing vector file
delete - Delete feature from vector file
move - Move feature in vector file
vertex - Move just vertex
straight - Remove vertex
merge - Merge two vector lines togher
break - Add new vertex to existing vector line
split - Split line into two separate lines

Would be good, if anybody could test it and drop some notes about the user
interface
and how clear the tool names are.

Next target is to add support for database updates too, current version of
v.edit works
only for vector geometry

Jachym

__________________________________________
Michael Barton, Professor of Anthropology
School of Human Evolution & Social Change
Center for Social Dynamics & Complexity
Arizona State University

phone: 480-965-6213
fax: 480-965-7671
www: http://www.public.asu.edu/~cmbarton