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.
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);