[GRASS-SVN] r40204 - in grass/trunk: include lib/vector/Vlib vector/v.edit

svn_grass at osgeo.org svn_grass at osgeo.org
Sun Jan 3 05:36:36 EST 2010


Author: martinl
Date: 2010-01-03 05:36:35 -0500 (Sun, 03 Jan 2010)
New Revision: 40204

Modified:
   grass/trunk/include/vector.h
   grass/trunk/lib/vector/Vlib/build.c
   grass/trunk/lib/vector/Vlib/build_ogr.c
   grass/trunk/lib/vector/Vlib/hist.c
   grass/trunk/lib/vector/Vlib/open.c
   grass/trunk/lib/vector/Vlib/write.c
   grass/trunk/lib/vector/Vlib/write_nat.c
   grass/trunk/lib/vector/Vlib/write_ogr.c
   grass/trunk/vector/v.edit/args.c
   grass/trunk/vector/v.edit/main.c
   grass/trunk/vector/v.edit/select.c
Log:
libvect: implement V1/2_delete_line_ogr()
	 v.edit updated to delete features


Modified: grass/trunk/include/vector.h
===================================================================
--- grass/trunk/include/vector.h	2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/include/vector.h	2010-01-03 10:36:35 UTC (rev 40204)
@@ -222,6 +222,7 @@
 int Vect_open_old_head2(struct Map_info *, const char *, const char *, const char *);
 int Vect_open_new(struct Map_info *, const char *, int);
 int Vect_open_update(struct Map_info *, const char *, const char *);
+int Vect_open_update2(struct Map_info *, const char *, const char *, const char *);
 int Vect_open_update_head(struct Map_info *, const char *, const char *);
 int Vect_copy_head_data(const struct Map_info *, struct Map_info *);
 int Vect_build(struct Map_info *);
@@ -435,6 +436,9 @@
  */
 int Vect_print_header(const struct Map_info *);
 void Vect__init_head(struct Map_info *);
+void Vect__delete_area_cats_from_cidx(struct Map_info *, int);
+void Vect__add_area_cats_to_cidx(struct Map_info *, int);
+int V2__delete_line(struct Map_info *, int, int (*fn) (struct Map_info *, off_t));
 
 /* Open/close/rewind map */
 int Vect_coor_info(const struct Map_info *, struct Coor_info *);
@@ -478,7 +482,9 @@
 int V2_read_next_line_ogr(struct Map_info *, struct line_pnts *,
 			  struct line_cats *);
 int V1_delete_line_nat(struct Map_info *, off_t);
+int V1_delete_line_ogr(struct Map_info *, off_t);
 int V2_delete_line_nat(struct Map_info *, int);
+int V2_delete_line_ogr(struct Map_info *, int);
 int V1_restore_line_nat(struct Map_info *, off_t);
 int V2_restore_line_nat(struct Map_info *, int, off_t);
 off_t V1_write_line_nat(struct Map_info *, int, const struct line_pnts *,

Modified: grass/trunk/lib/vector/Vlib/build.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build.c	2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/build.c	2010-01-03 10:36:35 UTC (rev 40204)
@@ -127,7 +127,7 @@
     plus = &(Map->plus);
     if (build > GV_BUILD_NONE) {
 	G_message(_("Building topology for vector map <%s>..."),
-		  Vect_get_name(Map));
+		  Vect_get_full_name(Map));
     }
     plus->with_z = Map->head.with_z;
     plus->spidx_with_z = Map->head.with_z;

Modified: grass/trunk/lib/vector/Vlib/build_ogr.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_ogr.c	2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/build_ogr.c	2010-01-03 10:36:35 UTC (rev 40204)
@@ -62,7 +62,7 @@
 /* Free parts */
 static void free_parts(GEOM_PARTS * parts)
 {
-    free(parts->part);
+    G_free(parts->part);
     parts->a_parts = parts->n_parts = 0;
 }
 
@@ -317,7 +317,7 @@
    \brief Build pseudo-topology for OGR layer
 
    \param Map pointer to Map_info structure
-   \param build build level (only GV_BUILD_ALL currently supported)
+   \param build build level (GV_BUILD_NONE and GV_BUILD_ALL currently supported)
 
    \return 1 on success
    \return 0 on error
@@ -325,17 +325,26 @@
 int Vect_build_ogr(struct Map_info *Map, int build)
 {
     int iFeature, count, FID;
+    struct Plus_head *plus;
+    
     GEOM_PARTS parts;
     OGRFeatureH hFeature;
     OGRGeometryH hGeom;
 
-    G_debug(1, "Vect_build_ogr(): dsn=%s layer=%s",
-	    Map->fInfo.ogr.dsn, Map->fInfo.ogr.layer_name);
+    G_debug(1, "Vect_build_ogr(): dsn=%s layer=%s, build=%d",
+	    Map->fInfo.ogr.dsn, Map->fInfo.ogr.layer_name, build);
     
-    if (build != GV_BUILD_ALL)
-	G_fatal_error(_("Partial build for OGR is not supported"));
+    if (build != GV_BUILD_ALL && build != GV_BUILD_NONE) {
+	G_warning(_("Partial build for OGR is not supported"));
+	return 0;
+    }
 
+    plus = &(Map->plus);
+    if (build == plus->built)
+	return 1;		/* do nothing */
+    
     /* TODO move this init to better place (Vect_open_ ?), because in theory build may be reused on level2 */
+    G_free((void *) Map->fInfo.ogr.offset);
     Map->fInfo.ogr.offset = NULL;
     Map->fInfo.ogr.offset_num = 0;
     Map->fInfo.ogr.offset_alloc = 0;
@@ -349,40 +358,56 @@
 
     /* initialize data structures */
     init_parts(&parts);
-    
-    /* Note: Do not use OGR_L_GetFeatureCount (it may scan all features) */
-    OGR_L_ResetReading(Map->fInfo.ogr.layer);
-    count = iFeature = 0;
-    while ((hFeature = OGR_L_GetNextFeature(Map->fInfo.ogr.layer)) != NULL) {
-	iFeature++;
-	count++;
 
-	G_debug(3, "   Feature %d", iFeature);
-
-	hGeom = OGR_F_GetGeometryRef(hFeature);
-	if (hGeom == NULL) {
-	    G_warning(_("Feature %d without geometry ignored"), iFeature);
-	    OGR_F_Destroy(hFeature);
-	    continue;
-	}
+    /* Check if upgrade or downgrade */
+    if (build < plus->built) {	/* lower level request, currently only GV_BUILD_NONE */
+	dig_free_plus_areas(plus);
+	dig_spidx_free_areas(plus);
+	dig_free_plus_isles(plus);
+	dig_spidx_free_isles(plus);
 	
-	FID = (int)OGR_F_GetFID(hFeature);
-	if (FID == OGRNullFID) {
-	    G_warning(_("OGR feature %d without ID ignored"), iFeature);
+	dig_free_plus_nodes(plus);
+	dig_spidx_free_nodes(plus);
+	dig_free_plus_lines(plus);
+	dig_spidx_free_lines(plus);
+    }
+    else {
+	/* Note: Do not use OGR_L_GetFeatureCount (it may scan all features) */
+	OGR_L_ResetReading(Map->fInfo.ogr.layer);
+	count = iFeature = 0;
+	while ((hFeature = OGR_L_GetNextFeature(Map->fInfo.ogr.layer)) != NULL) {
+	    iFeature++;
+	    count++;
+	    
+	    G_debug(3, "   Feature %d", iFeature);
+	    
+	    hGeom = OGR_F_GetGeometryRef(hFeature);
+	    if (hGeom == NULL) {
+		G_warning(_("Feature %d without geometry ignored"), iFeature);
+		OGR_F_Destroy(hFeature);
+		continue;
+	    }
+	    
+	    FID = (int)OGR_F_GetFID(hFeature);
+	    if (FID == OGRNullFID) {
+		G_warning(_("OGR feature %d without ID ignored"), iFeature);
+		OGR_F_Destroy(hFeature);
+		continue;
+	    }
+	    G_debug(4, "    FID = %d", FID);
+	    
+	    reset_parts(&parts);
+	    add_part(&parts, FID);
+	    add_geometry(Map, hGeom, FID, &parts);
+	    
 	    OGR_F_Destroy(hFeature);
-	    continue;
-	}
-	G_debug(4, "    FID = %d", FID);
-	
-	reset_parts(&parts);
-	add_part(&parts, FID);
-	add_geometry(Map, hGeom, FID, &parts);
-	
-	OGR_F_Destroy(hFeature);
-    }				/* while */
+	}				/* while */
+    }
+
     free_parts(&parts);
     
-    Map->plus.built = GV_BUILD_ALL;
+    Map->plus.built = build;
+    
     return 1;
 }
 #endif

Modified: grass/trunk/lib/vector/Vlib/hist.c
===================================================================
--- grass/trunk/lib/vector/Vlib/hist.c	2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/hist.c	2010-01-03 10:36:35 UTC (rev 40204)
@@ -52,6 +52,8 @@
 /*!
    \brief Write string to history file
 
+   Only native format supported.
+   
    \param Map pointer to Map_info structure
    \param str string to write
 
@@ -61,9 +63,12 @@
 {
     int ret;
 
-    G_debug(5, "Vect_hist_write()");
-    ret = fprintf(Map->hist_fp, str);
-    fflush(Map->hist_fp);
+    G_debug(5, "Vect_hist_write(): %s", str);
+    ret = 0;
+    if (Map->hist_fp) {
+	ret = fprintf(Map->hist_fp, str);
+	fflush(Map->hist_fp);
+    }
 
     return (ret);
 }

Modified: grass/trunk/lib/vector/Vlib/open.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open.c	2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/open.c	2010-01-03 10:36:35 UTC (rev 40204)
@@ -120,6 +120,7 @@
  * \param[out] Map pointer to Map_info structure
  * \param name name of vector map to open
  * \param mapset mapset name ("" for search path)
+ * \param layer layer name (OGR format only)
  * \param update non-zero to open for update otherwise read-only mode
  * \param head_only read only header info from 'head', 'dbln', 'topo',
  * 'cidx' is not opened. The header may be opened on level 2 only.
@@ -138,8 +139,8 @@
     int ogr_mapset;
     const char *fmapset;
 
-    G_debug(1, "Vect__open_old(): name = %s mapset= %s update = %d", name,
-	    mapset, update);
+    G_debug(1, "Vect__open_old(): name = %s mapset = %s layer= %s update = %d", name,
+	    mapset, layer, update);
 
     /* zero Map_info structure */
     G_zero(Map, sizeof(struct Map_info));
@@ -200,17 +201,11 @@
 	}
 	Map->mapset = G_store(fmapset);
     }
-    else { /* OGR mapset */
-	if (update) {
-	    sprintf(errmsg, _("OGR layer cannot be opened for update"));
-	    fatal_error(ferror, errmsg);
-	    return -1;
-	}
-    }
+    
     Map->location = G_store(G_location());
     Map->gisdbase = G_store(G_gisdbase());
     
-    if (update && (0 != strcmp(Map->mapset, G_mapset()))) {
+    if (update && !ogr_mapset && (0 != strcmp(Map->mapset, G_mapset()))) {
 	G_warning(_("Vector map which is not in the current mapset cannot be opened for update"));
 	return -1;
     }
@@ -427,7 +422,7 @@
 
     /* open history file */
     sprintf(buf, "%s/%s", GV_DIRECTORY, Map->name);
-    if (update) {		/* native only */
+    if (update && !ogr_mapset) {		/* native only */
 	Map->hist_fp = G_fopen_modify(buf, GV_HIST_ELEMENT);
 	if (Map->hist_fp == NULL) {
 	    sprintf(errmsg,
@@ -480,8 +475,12 @@
 }
 
 /*!
- * \brief Open existing vector for reading
+ * \brief Open existing vector map for reading (native or OGR format
+ * via v.external)
  *
+ * This function is replaced by Vect_open_old2() to handle also direct
+ * OGR support.
+ * 
  * In case of error, the functions respect fatal error settings.
  *
  * \param[out] Map pointer to Map_info structure
@@ -496,14 +495,31 @@
     return (Vect__open_old(Map, name, mapset, NULL, 0, 0));
 }
 
+/*!
+ * \brief Open existing vector map for reading (native and OGR format)
+ *
+ * In case of error, the functions respect fatal error settings.
+ *
+ * \param[out] Map pointer to Map_info structure
+ * \param name name of vector map to open
+ * \param mapset mapset name
+ * \param layer layer name (OGR format)
+ *
+ * \return level of openness [1, 2, (3)]
+ * \return -1 on error
+ */
 int Vect_open_old2(struct Map_info *Map, const char *name, const char *mapset, const char *layer)
 {
     return (Vect__open_old(Map, name, mapset, layer, 0, 0));
 }
 
 /*!
- * \brief Open existing vector for reading/writing
+ * \brief Open existing vector map for reading/writing (native or OGR
+ * format via v.external)
  *
+ * This function is replaced by Vect_open_update2() to handle also
+ * direct OGR support.
+ *
  * In case of error, the functions respect fatal error settings.
  *
  * \param[out] Map pointer to Map_info structure
@@ -536,16 +552,42 @@
     return ret;
 }
 
+/*!
+ * \brief Open existing vector map for reading/writing (native or OGR
+ * format)
+ *
+ * In case of error, the functions respect fatal error settings.
+ *
+ * \param[out] Map pointer to Map_info structure
+ * \param name name of vector map to update
+ * \param mapset mapset name
+ * \param layer layer name (OGR format)
+ *
+ * \return level of openness [1, 2, (3)]
+ * \return -1 on error
+ */
+int Vect_open_update2(struct Map_info *Map, const char *name, const char *mapset, const char *layer)
+{
+    int ret;
+    
+    ret = Vect__open_old(Map, name, mapset, layer, 1, 0);
+    
+    return ret;
+}
+
 /*! 
  * \brief Reads only info about vector map from headers of 'head',
- * 'dbln', 'topo' and 'cidx' file.
+ * 'dbln', 'topo' and 'cidx' file (native or OGR format via
+ * v.external)
  *
+ * This function is replaced by Vect_open_old_head2() to handle also
+ * direct OGR support.
+ *
  * In case of error, the functions respect fatal error settings.
  * 
  * \param[out] Map pointer to Map_info structure
  * \param name name of vector map to read (dsn for OGR)
  * \param mapset mapset name ("" for search path)
- * \param layer layer name (only for OGR)
  *
  * \return level of openness [1, 2, (3)]
  * \return -1 on error
@@ -555,6 +597,20 @@
     return (Vect__open_old(Map, name, mapset, NULL, 0, 1));
 }
 
+/*! 
+ * \brief Reads only info about vector map from headers of 'head',
+ * 'dbln', 'topo' and 'cidx' file (native or OGR format)
+ *
+ * In case of error, the functions respect fatal error settings.
+ * 
+ * \param[out] Map pointer to Map_info structure
+ * \param name name of vector map to read (dsn for OGR)
+ * \param mapset mapset name ("" for search path)
+ * \param layer layer name (OGR format)
+ *
+ * \return level of openness [1, 2, (3)]
+ * \return -1 on error
+ */
 int Vect_open_old_head2(struct Map_info *Map, const char *name, const char *mapset, const char *layer)
 {
     return (Vect__open_old(Map, name, mapset, layer, 0, 1));

Modified: grass/trunk/lib/vector/Vlib/write.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write.c	2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/write.c	2010-01-03 10:36:35 UTC (rev 40204)
@@ -67,9 +67,13 @@
 #ifdef HAVE_OGR
     , {
     write_dummy, V1_write_line_ogr, write_dummy}
+    , {
+    write_dummy, V1_write_line_ogr, write_dummy}
 #else
     , {
     write_dummy, format_l, format_l}
+    , {
+    write_dummy, format_l, format_l}
 #endif
 };
 
@@ -79,21 +83,29 @@
 #ifdef HAVE_OGR
     , {
     rewrite_dummy, rewrite_dummy, rewrite_dummy}
+    , {
+    rewrite_dummy, rewrite_dummy, rewrite_dummy}
 #else
     , {
     rewrite_dummy, format, format}
+    , {
+    rewrite_dummy, format, format}
 #endif
 };
 
 static int (*Vect_delete_line_array[][3]) () = {
     {
-    delete_dummy, delete_dummy, V2_delete_line_nat}
+    delete_dummy, V1_delete_line_nat, V2_delete_line_nat}
 #ifdef HAVE_OGR
     , {
-    delete_dummy, delete_dummy, delete_dummy}
+    delete_dummy, V1_delete_line_ogr, V2_delete_line_ogr}
+    , {
+    delete_dummy, V1_delete_line_ogr, V2_delete_line_ogr}
 #else
     , {
     delete_dummy, format, format}
+    , {
+    delete_dummy, format, format}
 #endif
 };
 
@@ -103,13 +115,287 @@
 #ifdef HAVE_OGR
     , {
     restore_dummy, restore_dummy, restore_dummy}
+    , {
+    restore_dummy, restore_dummy, restore_dummy}
 #else
     , {
     restore_dummy, format, format}
+    , {
+    restore_dummy, format, format}
 #endif
 };
 
+/*! 
+  \brief Deletes area (i.e. centroid) categories from category
+  index (internal use only)
+
+  \param Map pointer to Map_info structure
+  \param area area id
+*/
+void Vect__delete_area_cats_from_cidx(struct Map_info *Map, int area)
+{
+    int i;
+    struct P_area *Area;
+    static struct line_cats *Cats = NULL;
+
+    G_debug(3, "Vect__delete_area_cats_from_cidx() area = %d", area);
+
+    Area = Map->plus.Area[area];
+    if (!Area)
+	G_fatal_error(_("%s: Area %d does not exist"),
+		      "delete_area_cats_from_cidx()", area);
+    
+    if (Area->centroid == 0) /* no centroid found */
+	return;
+
+    if (!Cats)
+	Cats = Vect_new_cats_struct();
+
+    V2_read_line_nat(Map, NULL, Cats, Area->centroid);
+
+    for (i = 0; i < Cats->n_cats; i++) {
+	dig_cidx_del_cat(&(Map->plus), Cats->field[i], Cats->cat[i], area,
+			 GV_AREA);
+    }
+}
+
+/*! 
+  \brief Adds area (i.e. centroid) categories from category index
+  (internal use only)
+
+  \param Map pointer to Map_info structure
+  \param area area id
+*/
+void Vect__add_area_cats_to_cidx(struct Map_info *Map, int area)
+{
+    int i;
+    struct P_area *Area;
+    static struct line_cats *Cats = NULL;
+
+    G_debug(3, "Vect__add_area_cats_to_cidx() area = %d", area);
+
+    Area = Map->plus.Area[area];
+    if (!Area)
+	G_fatal_error(_("%s: Area %d does not exist"),
+		      "add_area_cats_to_cidx():", area);
+
+    if (Area->centroid == 0) /* no centroid found */
+	return;
+
+    if (!Cats)
+	Cats = Vect_new_cats_struct();
+
+    V2_read_line_nat(Map, NULL, Cats, Area->centroid);
+
+    for (i = 0; i < Cats->n_cats; i++) {
+	dig_cidx_add_cat_sorted(&(Map->plus), Cats->field[i], Cats->cat[i],
+				area, GV_AREA);
+    }
+}
+
 /*!
+  \brief Deletes feature (topology level) -- internal use only
+  
+  \param pointer to Map_info structure
+  \param line feature id
+  \param fn function to delete feature (native or ogr)
+  
+  \return 0 on success
+  \return -1 on error
+*/
+int V2__delete_line(struct Map_info *Map, int line, int (*fn_delete) (struct Map_info *, off_t))
+{
+    int ret, i, side, type, first, next_line, area;
+    struct P_line *Line;
+    struct P_area *Area;
+    struct Plus_head *plus;
+    struct bound_box box, abox;
+    int adjacent[4], n_adjacent;
+    static struct line_cats *Cats = NULL;
+
+    G_debug(3, "V2__delete_line(), line = %d", line);
+
+    type = first = n_adjacent = 0;
+    Line = NULL;
+    plus = &(Map->plus);
+
+    if (plus->built >= GV_BUILD_BASE) {
+	Line = Map->plus.Line[line];
+
+	if (Line == NULL)
+	    G_fatal_error(_("Attempt to delete dead feature"));
+	type = Line->type;
+    }
+
+    if (!Cats) {
+	Cats = Vect_new_cats_struct();
+    }
+
+    /* Update category index */
+    if (plus->update_cidx) {
+	type = V2_read_line_nat(Map, NULL, Cats, line);
+
+	for (i = 0; i < Cats->n_cats; i++) {
+	    dig_cidx_del_cat(plus, Cats->field[i], Cats->cat[i], line, type);
+	}
+    }
+
+    /* delete the line from coor */
+    ret = fn_delete(Map, Line->offset);
+
+    if (ret == -1) {
+	return ret;
+    }
+
+    /* Update topology */
+    if (plus->built >= GV_BUILD_AREAS && type == GV_BOUNDARY) {
+	/* Store adjacent boundaries at nodes (will be used to rebuild area/isle) */
+	/* Adjacent are stored: > 0 - we want right side; < 0 - we want left side */
+	n_adjacent = 0;
+
+	next_line = dig_angle_next_line(plus, line, GV_RIGHT, GV_BOUNDARY);
+	if (next_line != 0 && abs(next_line) != line) {
+	    /* N1, to the right -> we want the right side for > 0  and left for < 0 */
+	    adjacent[n_adjacent] = next_line;
+	    n_adjacent++;
+	}
+	next_line = dig_angle_next_line(plus, line, GV_LEFT, GV_BOUNDARY);
+	if (next_line != 0 && abs(next_line) != line) {
+	    /* N1, to the left -> we want the left side for > 0  and right for < 0 */
+	    adjacent[n_adjacent] = -next_line;
+	    n_adjacent++;
+	}
+	next_line = dig_angle_next_line(plus, -line, GV_RIGHT, GV_BOUNDARY);
+	if (next_line != 0 && abs(next_line) != line) {
+	    /* N2, to the right -> we want the right side for > 0  and left for < 0 */
+	    adjacent[n_adjacent] = next_line;
+	    n_adjacent++;
+	}
+	next_line = dig_angle_next_line(plus, -line, GV_LEFT, GV_BOUNDARY);
+	if (next_line != 0 && abs(next_line) != line) {
+	    /* N2, to the left -> we want the left side for > 0  and right for < 0 */
+	    adjacent[n_adjacent] = -next_line;
+	    n_adjacent++;
+	}
+
+	/* Delete area(s) and islands this line forms */
+	first = 1;
+	if (Line->left > 0) {	/* delete area */
+	    Vect_get_area_box(Map, Line->left, &box);
+	    if (first) {
+		Vect_box_copy(&abox, &box);
+		first = 0;
+	    }
+	    else
+		Vect_box_extend(&abox, &box);
+
+	    if (plus->update_cidx) {
+		Vect__delete_area_cats_from_cidx(Map, Line->left);
+	    }
+	    dig_del_area(plus, Line->left);
+	}
+	else if (Line->left < 0) {	/* delete isle */
+	    dig_del_isle(plus, -Line->left);
+	}
+	if (Line->right > 0) {	/* delete area */
+	    Vect_get_area_box(Map, Line->right, &box);
+	    if (first) {
+		Vect_box_copy(&abox, &box);
+		first = 0;
+	    }
+	    else
+		Vect_box_extend(&abox, &box);
+
+	    if (plus->update_cidx) {
+		Vect__delete_area_cats_from_cidx(Map, Line->right);
+	    }
+	    dig_del_area(plus, Line->right);
+	}
+	else if (Line->right < 0) {	/* delete isle */
+	    dig_del_isle(plus, -Line->right);
+	}
+    }
+
+    /* Delete reference from area */
+    if (plus->built >= GV_BUILD_CENTROIDS && type == GV_CENTROID) {
+	if (Line->left > 0) {
+	    G_debug(3, "Remove centroid %d from area %d", line, Line->left);
+	    if (plus->update_cidx) {
+		Vect__delete_area_cats_from_cidx(Map, Line->left);
+	    }
+	    Area = Map->plus.Area[Line->left];
+	    Area->centroid = 0;
+	}
+    }
+
+    /* delete the line from topo */
+    dig_del_line(plus, line);
+
+    /* Rebuild areas/isles and attach centroids and isles */
+    if (plus->built >= GV_BUILD_AREAS && type == GV_BOUNDARY) {
+	int *new_areas, nnew_areas;
+
+	nnew_areas = 0;
+	new_areas = (int *)G_malloc(2 * n_adjacent * sizeof(int));
+	/* Rebuild areas/isles */
+	for (i = 0; i < n_adjacent; i++) {
+	    if (adjacent[i] > 0)
+		side = GV_RIGHT;
+	    else
+		side = GV_LEFT;
+
+	    G_debug(3, "Build area for line = %d, side = %d", adjacent[i],
+		    side);
+
+	    area = Vect_build_line_area(Map, abs(adjacent[i]), side);
+	    if (area > 0) {	/* area */
+		Vect_get_area_box(Map, area, &box);
+		if (first) {
+		    Vect_box_copy(&abox, &box);
+		    first = 0;
+		}
+		else
+		    Vect_box_extend(&abox, &box);
+
+		new_areas[nnew_areas] = area;
+		nnew_areas++;
+	    }
+	    else if (area < 0) {
+		/* isle -> must be attached -> add to abox */
+		Vect_get_isle_box(Map, -area, &box);
+		if (first) {
+		    Vect_box_copy(&abox, &box);
+		    first = 0;
+		}
+		else
+		    Vect_box_extend(&abox, &box);
+	    }
+	}
+	/* Reattach all centroids/isles in deleted areas + new area.
+	 *  Because isles are selected by box it covers also possible new isle created above */
+	if (!first) {		/* i.e. old area/isle was deleted or new one created */
+	    /* Reattache isles */
+	    if (plus->built >= GV_BUILD_ATTACH_ISLES)
+		Vect_attach_isles(Map, &abox);
+
+	    /* Reattach centroids */
+	    if (plus->built >= GV_BUILD_CENTROIDS)
+		Vect_attach_centroids(Map, &abox);
+	}
+
+	if (plus->update_cidx) {
+	    for (i = 0; i < nnew_areas; i++) {
+		Vect__add_area_cats_to_cidx(Map, new_areas[i]);
+	    }
+	}
+    }
+
+    G_debug(3, "updated lines : %d , updated nodes : %d", plus->n_uplines,
+	    plus->n_upnodes);
+    return ret;
+}
+
+/*!
    \brief Writes new feature to the end of file
 
    The function calls G_fatal_error() on error.
@@ -237,8 +523,8 @@
     ret = (*Vect_delete_line_array[Map->format][Map->level]) (Map, line);
 
     if (ret == -1)
-	G_fatal_error(_("Unable to feature %d from vector map <%s>"),
-		      line, Map->name);
+	G_fatal_error(_("Unable to delete feature id %d from vector map <%s>"),
+		      line, Vect_get_full_name(Map));
 
     return ret;
 }

Modified: grass/trunk/lib/vector/Vlib/write_nat.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_nat.c	2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/write_nat.c	2010-01-03 10:36:35 UTC (rev 40204)
@@ -1,7 +1,7 @@
 /*!
-   \file write_nat.c
+   \file lib/vector/Vlib/write_nat.c
 
-   \brief Vector library - write vector feature (native format)
+   \brief Vector library - write/modify vector feature (native format)
 
    Higher level functions for reading/writing/manipulating vectors.
 
@@ -11,7 +11,7 @@
     - Delete feature
     - Restore feature
 
-   (C) 2001-2009 by the GRASS Development Team
+   (C) 2001-2010 by the GRASS Development Team
 
    This program is free software under the GNU General Public License
    (>=v2). Read the file COPYING that comes with GRASS for details.
@@ -31,72 +31,6 @@
 #include <grass/glocale.h>
 
 /*!
-  \brief Deletes area (i.e. centroid) categories from category index
-
-  \param Map pointer to vector map
-  \param area area id
-*/
-static void delete_area_cats_from_cidx(struct Map_info *Map, int area)
-{
-    int i;
-    struct P_area *Area;
-    static struct line_cats *Cats = NULL;
-
-    G_debug(3, "delete_area_cats_from_cidx() area = %d", area);
-
-    Area = Map->plus.Area[area];
-    if (!Area)
-	G_fatal_error(_("%s: Area %d does not exist"),
-		      "delete_area_cats_from_cidx()", area);
-    
-    if (Area->centroid == 0) /* no centroid found */
-	return;
-
-    if (!Cats)
-	Cats = Vect_new_cats_struct();
-
-    V2_read_line_nat(Map, NULL, Cats, Area->centroid);
-
-    for (i = 0; i < Cats->n_cats; i++) {
-	dig_cidx_del_cat(&(Map->plus), Cats->field[i], Cats->cat[i], area,
-			 GV_AREA);
-    }
-}
-
-/*!
-  \brief Adds area (i.e. centroid) categories from category index
-
-  \param Map pointer to vector map
-  \param area area id
-*/
-static void add_area_cats_to_cidx(struct Map_info *Map, int area)
-{
-    int i;
-    struct P_area *Area;
-    static struct line_cats *Cats = NULL;
-
-    G_debug(3, "add_area_cats_to_cidx() area = %d", area);
-
-    Area = Map->plus.Area[area];
-    if (!Area)
-	G_fatal_error(_("%s: Area %d does not exist"),
-		      "add_area_cats_to_cidx():", area);
-
-    if (Area->centroid == 0) /* no centroid found */
-	return;
-
-    if (!Cats)
-	Cats = Vect_new_cats_struct();
-
-    V2_read_line_nat(Map, NULL, Cats, Area->centroid);
-
-    for (i = 0; i < Cats->n_cats; i++) {
-	dig_cidx_add_cat_sorted(&(Map->plus), Cats->field[i], Cats->cat[i],
-				area, GV_AREA);
-    }
-}
-
-/*!
   \brief Add line to topo file
 
   Update areas. Areas are modified if: 
@@ -196,7 +130,7 @@
 				Vect_box_extend(&abox, &box);
 
 			    if (plus->update_cidx) {
-				delete_area_cats_from_cidx(Map, area);
+				Vect__delete_area_cats_from_cidx(Map, area);
 			    }
 			    dig_del_area(plus, area);
 			}
@@ -255,7 +189,7 @@
 	    if (plus->update_cidx) {
 		for (s = 1; s < 3; s++) {
 		    if (new_area[s - 1] > 0) {
-			add_area_cats_to_cidx(Map, new_area[s - 1]);
+			Vect__add_area_cats_to_cidx(Map, new_area[s - 1]);
 		    }
 		}
 	    }
@@ -275,7 +209,7 @@
 		    Area->centroid = line;
 		    Line->left = sel_area;
 		    if (plus->update_cidx) {
-			add_area_cats_to_cidx(Map, sel_area);
+			Vect__add_area_cats_to_cidx(Map, sel_area);
 		    }
 		}
 		else {		/* duplicate centroid */
@@ -302,7 +236,7 @@
 /*!
   \brief Writes feature to 'coor' file
   
-  \param Map pointer to vector map
+  \param Map pointer to Map_info structure
   \param type feature type
   \param points feature geometry
   \param cats feature categories
@@ -328,7 +262,7 @@
 /*!
   \brief Writes feature to 'coor' file (topology level)
   
-  \param Map pointer to vector map
+  \param Map pointer to Map_info structure
   \param type feature type
   \param points feature geometry
   \param cats feature categories
@@ -386,7 +320,7 @@
   
   Old feature is deleted (marked as dead), new feature written.
   
-  \param Map pointer to vector map
+  \param Map pointer to Map_info structure
   \param offset feature offset
   \param type feature type
   \param points feature geometry
@@ -446,7 +380,7 @@
    
   Old feature is deleted (marked as dead), new feature written.
   
-  \param Map pointer to vector map
+  \param Map pointer to Map_info structure
   \param line feature id
   \param type feature type
   \param points feature geometry
@@ -474,7 +408,7 @@
 /*!
   \brief Rewrites feature at the given offset.
   
-  \param Map pointer to vector map
+  \param Map pointer to Map_info structure
   \param offset feature offset
   \param type feature type
   \param points feature geometry
@@ -572,9 +506,9 @@
 }
 
 /*!
-  \brief Deletes feature at the given offset.
+  \brief Deletes feature at the given offset (level 1)
   
-  \param Map pointer to vector map
+  \param Map pointer Map_info structure
   \param offset feature offset
   
   \return  0 on success
@@ -614,7 +548,7 @@
 /*!
   \brief Deletes feature (topology level).
   
-  \param pointer to vector map
+  \param pointer to Map_info structure
   \param line feature id
   
   \return 0 on success
@@ -622,198 +556,13 @@
 */
 int V2_delete_line_nat(struct Map_info *Map, int line)
 {
-    int ret, i, side, type = 0, first = 0, next_line, area;
-    struct P_line *Line = NULL;
-    struct P_area *Area;
-    struct Plus_head *plus;
-    struct bound_box box, abox;
-    int adjacent[4], n_adjacent = 0;
-    static struct line_cats *Cats = NULL;
-
-    G_debug(3, "V2_delete_line_nat(), line = %d", line);
-
-    plus = &(Map->plus);
-
-    if (plus->built >= GV_BUILD_BASE) {
-	Line = Map->plus.Line[line];
-
-	if (Line == NULL)
-	    G_fatal_error(_("Attempt to delete dead feature"));
-	type = Line->type;
-    }
-
-    if (!Cats) {
-	Cats = Vect_new_cats_struct();
-    }
-
-    /* Update category index */
-    if (plus->update_cidx) {
-	type = V2_read_line_nat(Map, NULL, Cats, line);
-
-	for (i = 0; i < Cats->n_cats; i++) {
-	    dig_cidx_del_cat(plus, Cats->field[i], Cats->cat[i], line, type);
-	}
-    }
-
-    /* delete the line from coor */
-    ret = V1_delete_line_nat(Map, Line->offset);
-
-    if (ret == -1) {
-	return ret;
-    }
-
-    /* Update topology */
-    if (plus->built >= GV_BUILD_AREAS && type == GV_BOUNDARY) {
-	/* Store adjacent boundaries at nodes (will be used to rebuild area/isle) */
-	/* Adjacent are stored: > 0 - we want right side; < 0 - we want left side */
-	n_adjacent = 0;
-
-	next_line = dig_angle_next_line(plus, line, GV_RIGHT, GV_BOUNDARY);
-	if (next_line != 0 && abs(next_line) != line) {
-	    /* N1, to the right -> we want the right side for > 0  and left for < 0 */
-	    adjacent[n_adjacent] = next_line;
-	    n_adjacent++;
-	}
-	next_line = dig_angle_next_line(plus, line, GV_LEFT, GV_BOUNDARY);
-	if (next_line != 0 && abs(next_line) != line) {
-	    /* N1, to the left -> we want the left side for > 0  and right for < 0 */
-	    adjacent[n_adjacent] = -next_line;
-	    n_adjacent++;
-	}
-	next_line = dig_angle_next_line(plus, -line, GV_RIGHT, GV_BOUNDARY);
-	if (next_line != 0 && abs(next_line) != line) {
-	    /* N2, to the right -> we want the right side for > 0  and left for < 0 */
-	    adjacent[n_adjacent] = next_line;
-	    n_adjacent++;
-	}
-	next_line = dig_angle_next_line(plus, -line, GV_LEFT, GV_BOUNDARY);
-	if (next_line != 0 && abs(next_line) != line) {
-	    /* N2, to the left -> we want the left side for > 0  and right for < 0 */
-	    adjacent[n_adjacent] = -next_line;
-	    n_adjacent++;
-	}
-
-	/* Delete area(s) and islands this line forms */
-	first = 1;
-	if (Line->left > 0) {	/* delete area */
-	    Vect_get_area_box(Map, Line->left, &box);
-	    if (first) {
-		Vect_box_copy(&abox, &box);
-		first = 0;
-	    }
-	    else
-		Vect_box_extend(&abox, &box);
-
-	    if (plus->update_cidx) {
-		delete_area_cats_from_cidx(Map, Line->left);
-	    }
-	    dig_del_area(plus, Line->left);
-	}
-	else if (Line->left < 0) {	/* delete isle */
-	    dig_del_isle(plus, -Line->left);
-	}
-	if (Line->right > 0) {	/* delete area */
-	    Vect_get_area_box(Map, Line->right, &box);
-	    if (first) {
-		Vect_box_copy(&abox, &box);
-		first = 0;
-	    }
-	    else
-		Vect_box_extend(&abox, &box);
-
-	    if (plus->update_cidx) {
-		delete_area_cats_from_cidx(Map, Line->right);
-	    }
-	    dig_del_area(plus, Line->right);
-	}
-	else if (Line->right < 0) {	/* delete isle */
-	    dig_del_isle(plus, -Line->right);
-	}
-    }
-
-    /* Delete reference from area */
-    if (plus->built >= GV_BUILD_CENTROIDS && type == GV_CENTROID) {
-	if (Line->left > 0) {
-	    G_debug(3, "Remove centroid %d from area %d", line, Line->left);
-	    if (plus->update_cidx) {
-		delete_area_cats_from_cidx(Map, Line->left);
-	    }
-	    Area = Map->plus.Area[Line->left];
-	    Area->centroid = 0;
-	}
-    }
-
-    /* delete the line from topo */
-    dig_del_line(plus, line);
-
-    /* Rebuild areas/isles and attach centroids and isles */
-    if (plus->built >= GV_BUILD_AREAS && type == GV_BOUNDARY) {
-	int *new_areas, nnew_areas;
-
-	nnew_areas = 0;
-	new_areas = (int *)G_malloc(2 * n_adjacent * sizeof(int));
-	/* Rebuild areas/isles */
-	for (i = 0; i < n_adjacent; i++) {
-	    if (adjacent[i] > 0)
-		side = GV_RIGHT;
-	    else
-		side = GV_LEFT;
-
-	    G_debug(3, "Build area for line = %d, side = %d", adjacent[i],
-		    side);
-
-	    area = Vect_build_line_area(Map, abs(adjacent[i]), side);
-	    if (area > 0) {	/* area */
-		Vect_get_area_box(Map, area, &box);
-		if (first) {
-		    Vect_box_copy(&abox, &box);
-		    first = 0;
-		}
-		else
-		    Vect_box_extend(&abox, &box);
-
-		new_areas[nnew_areas] = area;
-		nnew_areas++;
-	    }
-	    else if (area < 0) {
-		/* isle -> must be attached -> add to abox */
-		Vect_get_isle_box(Map, -area, &box);
-		if (first) {
-		    Vect_box_copy(&abox, &box);
-		    first = 0;
-		}
-		else
-		    Vect_box_extend(&abox, &box);
-	    }
-	}
-	/* Reattach all centroids/isles in deleted areas + new area.
-	 *  Because isles are selected by box it covers also possible new isle created above */
-	if (!first) {		/* i.e. old area/isle was deleted or new one created */
-	    /* Reattache isles */
-	    if (plus->built >= GV_BUILD_ATTACH_ISLES)
-		Vect_attach_isles(Map, &abox);
-
-	    /* Reattach centroids */
-	    if (plus->built >= GV_BUILD_CENTROIDS)
-		Vect_attach_centroids(Map, &abox);
-	}
-
-	if (plus->update_cidx) {
-	    for (i = 0; i < nnew_areas; i++) {
-		add_area_cats_to_cidx(Map, new_areas[i]);
-	    }
-	}
-    }
-
-    G_debug(3, "updated lines : %d , updated nodes : %d", plus->n_uplines,
-	    plus->n_upnodes);
-    return ret;
+    return V2__delete_line(Map, line, V1_delete_line_nat);
 }
 
 /*!
   \brief Restores feature at the given offset.
   
-  \param Map pointer to vector map
+  \param Map pointer to Map_info structure
   \param offset feature offset
   
   \return  0 on success
@@ -855,7 +604,7 @@
 /*!
   \brief Restores feature (topology level)
   
-  \param Map pointer to vector map
+  \param Map pointer to Map_info structure
   \param line feature id
   \param offset feature offset
   

Modified: grass/trunk/lib/vector/Vlib/write_ogr.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_ogr.c	2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/write_ogr.c	2010-01-03 10:36:35 UTC (rev 40204)
@@ -7,12 +7,12 @@
 
    Inspired by v.out.ogr's code.
 
-   (C) 2009 by the GRASS Development Team
+   (C) 2009-2010 by the GRASS Development Team
 
    This program is free software under the GNU General Public License
    (>=v2). Read the file COPYING that comes with GRASS for details.
 
-   \author Martin Landa <landa.martin gmail.com> (2009)
+   \author Martin Landa <landa.martin gmail.com>
  */
 
 #include <grass/config.h>
@@ -49,7 +49,7 @@
     OGRFeatureDefnH Ogr_featuredefn;
     
     if (!Map->fInfo.ogr.layer) {
-	G_warning(_("Unable to write feature, OGR layer not defined"));
+	G_warning(_("OGR layer not defined"));
 	return -1;
     }
 
@@ -212,4 +212,45 @@
     return 1;
 }
 
+/*!
+  \brief Deletes feature at the given offset (level 1)
+  
+  \param Map pointer Map_info structure
+  \param offset feature offset
+  
+  \return  0 on success
+  \return -1 on error
+*/
+int V1_delete_line_ogr(struct Map_info *Map, off_t offset)
+{
+    G_debug(3, "V1_delete_line_ogr(), offset = %lu", (unsigned long) offset);
+
+    if (!Map->fInfo.ogr.layer) {
+	G_warning(_("OGR layer not defined"));
+	return -1;
+    }
+    
+    if (offset >= Map->fInfo.ogr.offset_num)
+	return -1;
+    
+    if (OGR_L_DeleteFeature(Map->fInfo.ogr.layer, Map->fInfo.ogr.offset[offset]) != OGRERR_NONE)
+	return -1;
+    
+    return 0;
+}
+
+/*!
+  \brief Deletes feature (topology level).
+  
+  \param Map pointer to Map_info structure
+  \param line feature id
+  
+  \return 0 on success
+  \return -1 on error
+*/
+int V2_delete_line_ogr(struct Map_info *Map, int line)
+{
+    return V2__delete_line(Map, line, V1_delete_line_ogr);
+}
+
 #endif /* HAVE_OGR */

Modified: grass/trunk/vector/v.edit/args.c
===================================================================
--- grass/trunk/vector/v.edit/args.c	2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/vector/v.edit/args.c	2010-01-03 10:36:35 UTC (rev 40204)
@@ -35,7 +35,7 @@
 {
     /* parameters */
     params->map = G_define_standard_option(G_OPT_V_MAP);
-    params->map->description = _("Name of vector map to edit");
+    params->map->label = _("Name of vector map to edit");
 
     params->fld = G_define_standard_option(G_OPT_V_FIELD);
     params->fld->gisprompt = "new_layer,layer,layer";

Modified: grass/trunk/vector/v.edit/main.c
===================================================================
--- grass/trunk/vector/v.edit/main.c	2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/vector/v.edit/main.c	2010-01-03 10:36:35 UTC (rev 40204)
@@ -8,12 +8,11 @@
  * AUTHOR(S):  GRASS Development Team
  *             Wolf Bergenheim, Jachym Cepicky, Martin Landa
  *
- * COPYRIGHT:  (C) 2006-2008 by the GRASS Development Team
+ * COPYRIGHT:  (C) 2006-2010 by the GRASS Development Team
  *
- *             This program is free software under the
- *             GNU General Public License (>=v2).
- *             Read the file COPYING that comes with GRASS
- *             for details.
+ *             This program is free software under the GNU General
+ *             Public License (>=v2).  Read the file COPYING that
+ *             comes with GRASS for details.
  *
  * TODO:       3D support (done for move and vertexmove)
  ****************************************************************/
@@ -108,7 +107,7 @@
 	if (action_mode == MODE_ADD)	/* write */
 	    ret = Vect_open_update(&Map, params.map->answer, G_mapset());
 	else			/* read-only -- select features */
-	    ret = Vect_open_old(&Map, params.map->answer, G_mapset());
+	    ret = Vect_open_old2(&Map, params.map->answer, G_mapset(), params.fld->answer);
 
 	if (ret < 2)
 	    G_fatal_error(_("Unable to open vector map <%s> at topological level %d"),
@@ -146,7 +145,7 @@
 	}
     }
 
-    layer = atoi(params.fld->answer);
+    layer = Vect_get_field_number(&Map, params.fld->answer);
     i = 0;
     while (params.maxdist->answers[i]) {
 	switch (i) {
@@ -207,7 +206,7 @@
 	    }
 	    Vect_close(&Map);
 
-	    Vect_open_update(&Map, params.map->answer, G_mapset());
+	    Vect_open_update2(&Map, params.map->answer, G_mapset(), params.fld->answer);
 	}
     }
 

Modified: grass/trunk/vector/v.edit/select.c
===================================================================
--- grass/trunk/vector/v.edit/select.c	2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/vector/v.edit/select.c	2010-01-03 10:36:35 UTC (rev 40204)
@@ -40,7 +40,7 @@
 {
     int layer, type;
 
-    layer = atoi(params->fld->answer);
+    layer = Vect_get_field_number(Map, params->fld->answer);
     type = Vect_option_to_types(params->type);
 
     /* select by id's */



More information about the grass-commit mailing list