[GRASS-SVN] r33534 - in grass/trunk: include include/vect lib/vector/Vlib

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Sep 25 07:39:17 EDT 2008


Author: martinl
Date: 2008-09-25 07:39:17 -0400 (Thu, 25 Sep 2008)
New Revision: 33534

Modified:
   grass/trunk/include/Vect.h
   grass/trunk/include/vect/dig_externs.h
   grass/trunk/lib/vector/Vlib/read.c
   grass/trunk/lib/vector/Vlib/write.c
   grass/trunk/lib/vector/Vlib/write_nat.c
Log:
vlib: Vect_restore_line() added (initial step towards vector digitizer undo)
(merge from devbr6, r33533)


Modified: grass/trunk/include/Vect.h
===================================================================
--- grass/trunk/include/Vect.h	2008-09-25 11:33:00 UTC (rev 33533)
+++ grass/trunk/include/Vect.h	2008-09-25 11:39:17 UTC (rev 33534)
@@ -4,9 +4,11 @@
 #include <grass/vect/digit.h>
 
 /* --- ANSI prototypes for the lib/vector/Vlib functions --- */
-/* "Public" functions, for use in modules */
-    /* Basic structures */
-      /* Points (line) */
+
+/*
+ * "Public" functions, for use in modules
+ */
+/* Points (line) */
 struct line_pnts *Vect_new_line_struct(void);
 int Vect_append_point(struct line_pnts *, double, double, double);
 int Vect_append_points(struct line_pnts *, struct line_pnts *, int);
@@ -23,8 +25,8 @@
 int Vect_destroy_line_struct(struct line_pnts *);
 int Vect_point_on_line(struct line_pnts *, double, double *, double *,
 		       double *, double *, double *);
-int Vect_line_segment(struct line_pnts *InPoints, double start, double end,
-		      struct line_pnts *OutPoints);
+int Vect_line_segment(struct line_pnts *, double, double,
+		      struct line_pnts *);
 double Vect_line_length(struct line_pnts *);
 double Vect_area_perimeter(struct line_pnts *);
 double Vect_line_geodesic_length(struct line_pnts *);
@@ -36,7 +38,7 @@
 			struct line_pnts *);
 void Vect_line_buffer(struct line_pnts *, double, double, struct line_pnts *);
 
-      /* Categories */
+/* Categories */
 struct line_cats *Vect_new_cats_struct(void);
 int Vect_cat_set(struct line_cats *, int, int);
 int Vect_cat_get(struct line_cats *, int, int *);
@@ -49,14 +51,14 @@
 int Vect_get_area_cat(struct Map_info *, int, int);
 int Vect_get_line_cat(struct Map_info *, int, int);
 
-      /* List of categories */
+/* List of categories */
 struct cat_list *Vect_new_cat_list(void);
 int Vect_str_to_cat_list(const char *, struct cat_list *);
 int Vect_array_to_cat_list(int *, int, struct cat_list *);
 int Vect_cat_in_cat_list(int, struct cat_list *);
 int Vect_destroy_cat_list(struct cat_list *);
 
-      /* Vector array */
+/* Vector array */
 VARRAY *Vect_new_varray(int size);
 int Vect_set_varray_from_cat_string(struct Map_info *, int, const char *, int,
 				    int, VARRAY *);
@@ -65,30 +67,30 @@
 int Vect_set_varray_from_db(struct Map_info *, int, const char *, int, int,
 			    VARRAY *);
 
-     /* DB connection - field info */
+/* DB connection - field info */
 struct dblinks *Vect_new_dblinks_struct(void);
-void Vect_reset_dblinks(struct dblinks *p);
-int Vect_add_dblink(struct dblinks *p, int number, const char *name,
-		    const char *table, const char *key, const char *db,
-		    const char *driver);
-int Vect_check_dblink(struct dblinks *p, int field);
-int Vect_map_add_dblink(struct Map_info *, int number, const char *name,
-			const char *table, const char *key, const char *db,
-			const char *driver);
-int Vect_map_del_dblink(struct Map_info *, int number);
-int Vect_map_check_dblink(struct Map_info *, int field);
+void Vect_reset_dblinks(struct dblinks *);
+int Vect_add_dblink(struct dblinks *, int, const char *,
+		    const char *, const char *, const char *,
+		    const char *);
+int Vect_check_dblink(struct dblinks *, int);
+int Vect_map_add_dblink(struct Map_info *, int, const char *,
+			const char *, const char *, const char *,
+			const char *);
+int Vect_map_del_dblink(struct Map_info *, int);
+int Vect_map_check_dblink(struct Map_info *, int);
 int Vect_read_dblinks(struct Map_info *);
 int Vect_write_dblinks(struct Map_info *);
-struct field_info *Vect_default_field_info(struct Map_info *Map, int field,
-					   const char *field_name, int type);
-struct field_info *Vect_get_dblink(struct Map_info *Map, int link);
-struct field_info *Vect_get_field(struct Map_info *Map, int field);
-void Vect_set_db_updated(struct Map_info *Map);
-const char *Vect_get_column_names(struct Map_info *Map, int field);
-const char *Vect_get_column_types(struct Map_info *Map, int field);
-const char *Vect_get_column_names_types(struct Map_info *Map, int field);
+struct field_info *Vect_default_field_info(struct Map_info *, int,
+					   const char *, int);
+struct field_info *Vect_get_dblink(struct Map_info *, int);
+struct field_info *Vect_get_field(struct Map_info *, int );
+void Vect_set_db_updated(struct Map_info *);
+const char *Vect_get_column_names(struct Map_info *, int);
+const char *Vect_get_column_types(struct Map_info *, int);
+const char *Vect_get_column_names_types(struct Map_info *, int);
 
-      /* List of FID (feature ID) (integers) */
+/* List of FID (feature ID) (integers) */
 struct ilist *Vect_new_list(void);
 int Vect_list_append(struct ilist *, int);
 int Vect_list_append_list(struct ilist *, struct ilist *);
@@ -98,7 +100,7 @@
 int Vect_reset_list(struct ilist *);
 int Vect_destroy_list(struct ilist *);
 
-      /* Bounding box (MBR) */
+/* Bounding box (MBR) */
 int Vect_point_in_box(double, double, double, BOUND_BOX *);
 int Vect_box_overlap(BOUND_BOX *, BOUND_BOX *);
 int Vect_box_copy(BOUND_BOX *, BOUND_BOX *);
@@ -106,14 +108,14 @@
 int Vect_box_clip(double *, double *, double *, double *, BOUND_BOX *);
 int Vect_region_box(struct Cell_head *, BOUND_BOX *);
 
-    /* Spatial index */
+/* Spatial index */
 void Vect_spatial_index_init(SPATIAL_INDEX *);
 void Vect_spatial_index_destroy(SPATIAL_INDEX *);
 void Vect_spatial_index_add_item(SPATIAL_INDEX *, int, BOUND_BOX *);
 void Vect_spatial_index_del_item(SPATIAL_INDEX *, int);
 int Vect_spatial_index_select(SPATIAL_INDEX *, BOUND_BOX *, struct ilist *);
 
-    /* Category index */
+/* Category index */
 int Vect_cidx_get_num_fields(struct Map_info *);
 int Vect_cidx_get_field_number(struct Map_info *, int);
 int Vect_cidx_get_field_index(struct Map_info *, int);
@@ -132,7 +134,7 @@
 int Vect_cidx_open(struct Map_info *, int);
 
 
-    /* Set/get Map header info */
+/* Set/get map header info */
 int Vect_read_header(struct Map_info *);
 int Vect_write_header(struct Map_info *);
 const char *Vect_get_name(struct Map_info *);
@@ -162,7 +164,7 @@
 int Vect_get_constraint_box(struct Map_info *, BOUND_BOX *);
 
 
-    /* Get map level 2 informations */
+/* Get map level 2 informations */
 int Vect_level(struct Map_info *);
 int Vect_get_num_nodes(struct Map_info *);
 int Vect_get_num_primitives(struct Map_info *, int);
@@ -175,15 +177,14 @@
 int Vect_get_isle_box(struct Map_info *, int, BOUND_BOX *);
 int Vect_get_map_box(struct Map_info *, BOUND_BOX *);
 int V__map_overlap(struct Map_info *, double, double, double, double);
-
 void Vect_set_release_support(struct Map_info *);
 void Vect_set_category_index_update(struct Map_info *);
 
-    /* Set/get fatal error behaviour */
+/* Set/get fatal error behaviour */
 int Vect_set_fatal_error(int);
 int Vect_get_fatal_error();
 
-    /* Open/close/rewind/set_constraints for map */
+/* Open/close/rewind/set_constraints for map */
 int Vect_check_input_output_name(const char *, const char *, int);
 int Vect_legal_filename(const char *);
 int Vect_set_open_level(int);
@@ -194,7 +195,7 @@
 int Vect_open_update_head(struct Map_info *, const char *, const char *);
 int Vect_copy_head_data(struct Map_info *, struct Map_info *);
 int Vect_build(struct Map_info *, FILE *);
-int Vect_get_built(struct Map_info *Map);
+int Vect_get_built(struct Map_info *);
 int Vect_build_partial(struct Map_info *, int, FILE *);
 int Vect_set_constraint_region(struct Map_info *, double, double, double,
 			       double, double, double);
@@ -203,21 +204,22 @@
 int Vect_rewind(struct Map_info *);
 int Vect_close(struct Map_info *);
 
-    /* Read/write lines, nodes, areas */
-      /* Level 1 and 2 */
+/* Read/write lines, nodes, areas */
+/* Level 1 and 2 */
 int Vect_read_next_line(struct Map_info *, struct line_pnts *,
 			struct line_cats *);
-long Vect_write_line(struct Map_info *, int type, struct line_pnts *,
+long Vect_write_line(struct Map_info *, int, struct line_pnts *,
 		     struct line_cats *);
 
-int Vect_get_num_dblinks(struct Map_info *map);
+int Vect_get_num_dblinks(struct Map_info *);
 
-      /* Level 2 only */
+/* Level 2 only */
 int Vect_read_line(struct Map_info *, struct line_pnts *, struct line_cats *,
 		   int);
 int Vect_rewrite_line(struct Map_info *, int, int, struct line_pnts *,
 		      struct line_cats *);
 int Vect_delete_line(struct Map_info *, int);
+int Vect_restore_line(struct Map_info *, int, long);
 
 int Vect_line_alive(struct Map_info *, int);
 int Vect_node_alive(struct Map_info *, int);
@@ -225,6 +227,7 @@
 int Vect_isle_alive(struct Map_info *, int);
 int Vect_get_line_nodes(struct Map_info *, int, int *, int *);
 int Vect_get_line_areas(struct Map_info *, int, int *, int *);
+long Vect_get_line_offset(const struct Map_info *, int);
 
 int Vect_get_node_coor(struct Map_info *, int, double *, double *, double *);
 int Vect_get_node_n_lines(struct Map_info *, int);
@@ -244,20 +247,20 @@
 
 int Vect_get_centroid_area(struct Map_info *, int);
 
-      /* Level 2 update only */
-int Vect_get_num_updated_lines(struct Map_info *map);
-int Vect_get_updated_line(struct Map_info *map, int idx);
-int Vect_get_num_updated_nodes(struct Map_info *map);
-int Vect_get_updated_node(struct Map_info *map, int idx);
+/* Level 2 update only */
+int Vect_get_num_updated_lines(struct Map_info *);
+int Vect_get_updated_line(struct Map_info *, int);
+int Vect_get_num_updated_nodes(struct Map_info *);
+int Vect_get_updated_node(struct Map_info *, int);
 
-      /* History */
-int Vect_hist_command(struct Map_info *Map);
-int Vect_hist_write(struct Map_info *Map, const char *str);
-int Vect_hist_copy(struct Map_info *In, struct Map_info *Out);
-void Vect_hist_rewind(struct Map_info *Map);
-char *Vect_hist_read(char *s, int size, struct Map_info *Map);
+/* History */
+int Vect_hist_command(struct Map_info *);
+int Vect_hist_write(struct Map_info *, const char *);
+int Vect_hist_copy(struct Map_info *, struct Map_info *);
+void Vect_hist_rewind(struct Map_info *);
+char *Vect_hist_read(char *, int, struct Map_info *);
 
-      /* Selecting features */
+/* Selecting features */
 int Vect_select_lines_by_box(struct Map_info *, BOUND_BOX *, int,
 			     struct ilist *);
 int Vect_select_areas_by_box(struct Map_info *, BOUND_BOX *, struct ilist *);
@@ -275,7 +278,7 @@
 int Vect_select_areas_by_polygon(struct Map_info *, struct line_pnts *, int,
 				 struct line_pnts **, struct ilist *);
 
-      /* Analysis */
+/* Analysis */
 int Vect_point_in_area(struct Map_info *, int, double, double);
 int Vect_tin_get_z(struct Map_info *, double, double, double *, double *,
 		   double *);
@@ -292,7 +295,7 @@
 int Vect_point_in_area_outer_ring(double, double, struct Map_info *, int);
 int Vect_point_in_island(double, double, struct Map_info *, int);
 
-    /* Cleaning */
+/* Cleaning */
 void Vect_break_lines(struct Map_info *, int, struct Map_info *, FILE *);
 int Vect_break_lines_list(struct Map_info *, struct ilist *, struct ilist *,
 			  int, struct Map_info *, FILE *);
@@ -318,7 +321,7 @@
 int Vect_clean_small_angles_at_nodes(struct Map_info *, int,
 				     struct Map_info *, FILE *);
 
-    /* Overlay */
+/* Overlay */
 int Vect_overlay_str_to_operator(const char *);
 int Vect_overlay(struct Map_info *, int, struct ilist *, struct ilist *,
 		 struct Map_info *, int, struct ilist *, struct ilist *,
@@ -328,14 +331,14 @@
 		     struct ilist *, struct ilist *,
 		     struct Map_info *);
 
-    /* Graph */
+/* Graph */
 void Vect_graph_init(GRAPH *, int);
 void Vect_graph_build(GRAPH *);
 void Vect_graph_add_edge(GRAPH *, int, int, double, int);
 void Vect_graph_set_node_costs(GRAPH *, int, double);
 int Vect_graph_shortest_path(GRAPH *, int, int, struct ilist *, double *);
 
-    /* Network (graph) */
+/* Network (graph) */
 int Vect_net_build_graph(struct Map_info *, int, int, int, const char *,
 			 const char *, const char *, int, int);
 int Vect_net_shortest_path(struct Map_info *, int, int, struct ilist *,
@@ -351,7 +354,7 @@
 				struct line_pnts *, struct line_pnts *,
 				double *, double *);
 
-    /* Miscellaneous */
+/* Miscellaneous */
 int Vect_topo_dump(struct Map_info *, FILE *);
 double Vect_points_distance(double, double, double, double, double, double,
 			    int);
@@ -364,7 +367,7 @@
 int Vect_copy_table_by_cats(struct Map_info *, struct Map_info *, int, int,
 			    const char *, int, int *, int);
 int Vect_copy_tables(struct Map_info *, struct Map_info *, int);
-int Vect_delete(const char *map);
+int Vect_delete(const char *);
 int Vect_segment_intersection(double, double, double, double, double, double,
 			      double, double, double, double, double, double,
 			      double *, double *, double *, double *,
@@ -375,11 +378,13 @@
 int Vect_line_check_intersection(struct line_pnts *, struct line_pnts *, int);
 char *Vect_subst_var(const char *str, struct Map_info *Map);
 
-/* Internal functions, MUST NOT be used in modules */
+/*
+ * Internal functions, MUST NOT be used in modules
+ */
 int Vect_print_header(struct Map_info *);
 int Vect__init_head(struct Map_info *);
 
-    /* Open/close/rewind map */
+/* Open/close/rewind map */
 int Vect_coor_info(struct Map_info *, struct Coor_info *);
 const char *Vect_maptype_info(struct Map_info *);
 int Vect_open_topo(struct Map_info *, int);
@@ -404,7 +409,7 @@
 int V1_close_ogr(struct Map_info *);
 int V2_close_ogr(struct Map_info *);
 
-    /* Read/write lines */
+/* Read/write lines */
 int V1_read_line_nat(struct Map_info *, struct line_pnts *,
 		     struct line_cats *, long);
 int V1_read_next_line_nat(struct Map_info *, struct line_pnts *,
@@ -421,6 +426,8 @@
 			  struct line_cats *);
 int V1_delete_line_nat(struct Map_info *, long);
 int V2_delete_line_nat(struct Map_info *, int);
+int V1_restore_line_nat(struct Map_info *, long);
+int V2_restore_line_nat(struct Map_info *, int, long);
 long V1_write_line_nat(struct Map_info *, int type, struct line_pnts *,
 		       struct line_cats *);
 long V2_write_line_nat(struct Map_info *, int type, struct line_pnts *,
@@ -447,4 +454,4 @@
 int Vect_attach_isles(struct Map_info *, BOUND_BOX *);
 int Vect_attach_centroids(struct Map_info *, BOUND_BOX *);
 
-#endif
+#endif /* GRASS_VECT_H */

Modified: grass/trunk/include/vect/dig_externs.h
===================================================================
--- grass/trunk/include/vect/dig_externs.h	2008-09-25 11:33:00 UTC (rev 33533)
+++ grass/trunk/include/vect/dig_externs.h	2008-09-25 11:39:17 UTC (rev 33534)
@@ -124,8 +124,10 @@
 
 int dig_add_node(struct Plus_head *, double, double, double);
 int dig_which_node(struct Plus_head *, double, double, double);
-int dig_add_line(struct Plus_head *plus, int type, struct line_pnts *points,
-		 long offset);
+int dig_add_line(struct Plus_head *, int, struct line_pnts *,
+		 long);
+int dig_restore_line(struct Plus_head *, int, int, struct line_pnts *,
+		     long);
 int dig_del_line(struct Plus_head *, int);
 int dig_node_add_line(struct Plus_head *, int, int, struct line_pnts *, int);
 float dig_node_line_angle(struct Plus_head *, int, int);

Modified: grass/trunk/lib/vector/Vlib/read.c
===================================================================
--- grass/trunk/lib/vector/Vlib/read.c	2008-09-25 11:33:00 UTC (rev 33533)
+++ grass/trunk/lib/vector/Vlib/read.c	2008-09-25 11:39:17 UTC (rev 33534)
@@ -1,21 +1,19 @@
 /*!
    \file read.c
 
-   \brief Vector library - reading data
+   \brief Vector library - read vector features
 
    Higher level functions for reading/writing/manipulating vectors.
 
    (C) 2001-2008 by the GRASS Development Team
 
-   This program is free software under the 
-   GNU General Public License (>=v2). 
-   Read the file COPYING that comes with GRASS
-   for details.
+   This program is free software under the GNU General Public License
+   (>=v2).  Read the file COPYING that comes with GRASS for details.
 
    \author Original author CERL, probably Dave Gerdes or Mike Higgins.
-   Update to GRASS 5.7 Radim Blazek and David D. Gray.
+   \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
 
-   \date 2001
+   \date 2001-2008
  */
 
 #include <grass/Vect.h>
@@ -56,20 +54,18 @@
 };
 
 /*!
-   \brief Get next vector line
+   \brief Read next vector feature (level 1 and 2)
 
-   \param Map vector map
-   \param[out] line_p line geometry
-   \param[out] line_c line categories
+   \param Map pointer vector map
+   \param[out] line_p feature geometry
+   \param[out] line_c feature categories
 
-   \return line type,
-   \return -1 on Out of memory,
-   \return -2 on EOF   
-
+   \return feature type,
+   \return -1 out of memory
+   \return -2 EOF   
  */
-int
-Vect_read_next_line(struct Map_info *Map,
-		    struct line_pnts *line_p, struct line_cats *line_c)
+int Vect_read_next_line(struct Map_info *Map,
+			struct line_pnts *line_p, struct line_cats *line_c)
 {
 
     G_debug(3, "Vect_read_next_line()");
@@ -82,19 +78,19 @@
 }
 
 /*!
-   \brief Get vector line
+   \brief Read vector feature
 
-   \param Map vector map
-   \param[out] line_p line geometry
-   \param[out] line_c line categories
-   \param line line id 
-   \return line type,
-   \return -1 on Out of memory,
-   \return -2 on EOF   
+   \param Map pointer to vector map
+   \param[out] line_p feature geometry
+   \param[out] line_c feature categories
+   \param line feature id 
+   
+   \return feature type
+   \return -1 out of memory,
+   \return -2 EOF   
  */
-int
-Vect_read_line(struct Map_info *Map,
-	       struct line_pnts *line_p, struct line_cats *line_c, int line)
+int Vect_read_line(struct Map_info *Map,
+		   struct line_pnts *line_p, struct line_cats *line_c, int line)
 {
 
     G_debug(3, "Vect_read_line()");
@@ -103,33 +99,34 @@
 	G_fatal_error("Vect_read_line(): %s", _("vector map is not opened"));
 
     if (line < 1 || line > Map->plus.n_lines)
-	G_fatal_error(_("Vect_read_line(): line %d is not reasonable (max line in vector map: %d)"),
-		      line, Map->plus.n_lines);
+	G_fatal_error(_("Vect_read_line(): feature id %d is not reasonable "
+			"(max features in vector map <%s>: %d)"),
+		      line, Vect_get_full_name(Map), Map->plus.n_lines);
 
     return (*V2_read_line_array[Map->format]) (Map, line_p, line_c, line);
 }
 
 /*!
-   \brief Check if line is alive or dead
+   \brief Check if feature is alive or dead
 
-   \param Map vector map
-   \param line line id
+   \param Map pointer to vector map
+   \param line feature id
 
-   \return 1 if line alive
-   \return 0 if line is dead
+   \return 1 if feature alive
+   \return 0 if feature is dead
  */
 int Vect_line_alive(struct Map_info *Map, int line)
 {
     if (Map->plus.Line[line] != NULL)
 	return 1;
-
+    
     return 0;
 }
 
 /*!
    \brief Check if node is alive or dead
 
-   \param Map vector map
+   \param Map pointer to vector map
    \param node node id
 
    \return 1 if node alive
@@ -146,7 +143,7 @@
 /*!
    \brief Check if area is alive or dead
 
-   \param Map vector map
+   \param Map pointer to vector map
    \param area area id
 
    \return 1 if area alive
@@ -163,7 +160,7 @@
 /*!
    \brief Check if isle is alive or dead
 
-   \param Map vector map
+   \param Map pointer to vector map
    \param isle isle id
 
    \return 1 if isle alive
@@ -176,3 +173,26 @@
 
     return 0;
 }
+
+/*!
+  \brief Get feature offset
+
+  Can be used for Vect_restore_line().
+
+  \param Map pointer to vector map
+  \param line feature id
+
+  \return feature offset
+  \return -1 on error
+*/
+long Vect_get_line_offset(const struct Map_info *Map, int line)
+{
+    if (line < 1 || line > Map->plus.n_lines)
+	return -1;
+    
+    if (Map->plus.Line[line] != NULL) {
+	return Map->plus.Line[line]->offset;
+    }
+    
+    return -1;
+}

Modified: grass/trunk/lib/vector/Vlib/write.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write.c	2008-09-25 11:33:00 UTC (rev 33533)
+++ grass/trunk/lib/vector/Vlib/write.c	2008-09-25 11:39:17 UTC (rev 33534)
@@ -1,7 +1,7 @@
 /*!
    \file write.c
 
-   \brief Vector library - write data
+   \brief Vector library - write vector features
 
    Higher level functions for reading/writing/manipulating vectors.
 
@@ -40,6 +40,13 @@
     return -1;
 }
 
+static int restore_dummy()
+{
+    G_warning("Vect_restore_line() %s",
+	      _("for this format/level not supported"));
+    return -1;
+}
+
 #ifndef HAVE_OGR
 static int format()
 {
@@ -91,17 +98,29 @@
 #endif
 };
 
+static int (*Vect_restore_line_array[][3]) () = {
+    {
+    restore_dummy, restore_dummy, V2_restore_line_nat}
+#ifdef HAVE_OGR
+    , {
+    restore_dummy, restore_dummy, restore_dummy}
+#else
+    , {
+    restore_dummy, format, format}
+#endif
+};
+
 /*!
-   \brief Writes new line to the end of file (table)
+   \brief Writes new feature to the end of file (table)
 
    The function calls G_fatal_error() on error.
 
    \param Map pointer to vector map
-   \param type vector type
-   \param points line geometry
-   \param cats line categories
+   \param type feature type
+   \param points feature geometry
+   \param cats feature categories
 
-   \return offset into file where the line starts
+   \return offset into file where the feature starts
  */
 long
 Vect_write_line(struct Map_info *Map,
@@ -113,7 +132,7 @@
 	    Map->name, Map->format, Map->level);
 
     if (!VECT_OPEN(Map))
-	G_fatal_error(_("Unable to write line, vector map is not opened"));
+	G_fatal_error(_("Unable to write feature, vector map is not opened"));
 
     dig_line_reset_updated(&(Map->plus));
     dig_node_reset_updated(&(Map->plus));
@@ -126,27 +145,27 @@
 						      cats);
 
     if (offset == -1)
-	G_fatal_error(_("Unable to write line (negative offset)"));
+	G_fatal_error(_("Unable to write feature (negative offset)"));
 
     return offset;
 }
 
 
 /*!
-   \brief Rewrites line info at the given offset.
+   \brief Rewrites feature info at the given offset.
 
    The number of points or cats or type may change. If necessary, the
-   old line is deleted and new is written.
+   old feature is deleted and new is written.
 
    This function calls G_fatal_error() on error.
 
    \param Map pointer to vector map
-   \param line line id
-   \param type vector type
-   \param points line geometry
-   \param cats line categories
+   \param line feature id
+   \param type feature type
+   \param points feature geometry
+   \param cats feature categories
 
-   \return number of new line
+   \return new feature id
    \return -1 on error
  */
 int
@@ -159,7 +178,7 @@
     G_debug(3, "Vect_rewrite_line(): name = %s, line = %d", Map->name, line);
 
     if (!VECT_OPEN(Map))
-	G_fatal_error(_("Unable to rewrite line, vector map is not opened"));
+	G_fatal_error(_("Unable to rewrite feature, vector map is not opened"));
 
     dig_line_reset_updated(&(Map->plus));
     dig_node_reset_updated(&(Map->plus));
@@ -172,39 +191,20 @@
 							     points, cats);
 
     if (ret == -1)
-	G_fatal_error(_("Unable to rewrite line %d"), line);
+	G_fatal_error(_("Unable to rewrite feature %d"), line);
 
     return ret;
 }
 
-/*
- *  Deletes line at the given offset. Map must be opened on level 2.
- *  
- *  Returns: 0 ok
- *          -1 on error 
- */
-/*
-   int
-   V1_delete_line (
-   struct Map_info *Map,
-   long offset)
-   {
-   #ifdef GDEBUG
-   G_debug (3, "V1_delete_line(): name = %s", Map->name);
-   #endif
-   return (*V1_delete_line_array[Map->format][Map->level]) (Map, offset);
-   }
- */
-
 /*!
-   \brief Deletes line of given number.
+   \brief Delete feature
 
    Vector map must be opened on topo level 2.
 
    This function calls G_fatal_error() on error.
 
    \param Map pointer to vector map
-   \param line line id
+   \param line feature id
 
    \return 0 on success
    \return -1 on error
@@ -216,13 +216,13 @@
     G_debug(3, "Vect_delete_line(): name = %s, line = %d", Map->name, line);
 
     if (Map->level < 2) {
-	G_fatal_error(_("Unable to delete line %d, "
-			"vector map <%s> is not opened on topo level 2"),
+	G_fatal_error(_("Unable to delete feature %d, "
+			"vector map <%s> is not opened on topology level"),
 		      line, Map->name);
     }
 
     if (Map->mode != GV_MODE_RW && Map->mode != GV_MODE_WRITE) {
-	G_fatal_error(_("Unable to delete line %d, "
+	G_fatal_error(_("Unable to delete feature %d, "
 			"vector map <%s> is not opened in 'write' mode"),
 		      line, Map->name);
     }
@@ -236,8 +236,54 @@
     ret = (*Vect_delete_line_array[Map->format][Map->level]) (Map, line);
 
     if (ret == -1)
-	G_fatal_error(_("Unable to delete line %d from vector map <%s>"),
+	G_fatal_error(_("Unable to feature %d from vector map <%s>"),
 		      line, Map->name);
 
     return ret;
 }
+
+/*!
+   \brief Restore previously deleted feature
+
+   Vector map must be opened on topo level 2.
+
+   This function calls G_fatal_error() on error.
+
+   \param Map pointer to vector map
+   \param line feature id to be deleted
+
+   \return 0 on success
+   \return -1 on error
+ */
+int Vect_restore_line(struct Map_info *Map, int line, long offset)
+{
+    int ret;
+
+    G_debug(3, "Vect_restore_line(): name = %s, line = %d", Map->name, line);
+
+    if (Map->level < 2) {
+	G_fatal_error(_("Unable to restore feature %d, "
+			"vector map <%s> is not opened on topology level"),
+		      line, Map->name);
+    }
+
+    if (Map->mode != GV_MODE_RW && Map->mode != GV_MODE_WRITE) {
+	G_fatal_error(_("Unable to restore feature %d, "
+			"vector map <%s> is not opened in 'write' mode"),
+		      line, Map->name);
+    }
+
+    dig_line_reset_updated(&(Map->plus));
+    dig_node_reset_updated(&(Map->plus));
+    if (!(Map->plus.update_cidx)) {
+	Map->plus.cidx_up_to_date = 0;
+    }
+
+    ret = (*Vect_restore_line_array[Map->format][Map->level]) (Map, line, offset);
+
+    if (ret == -1)
+	G_fatal_error(_("Unable to restore feature %d from vector map <%s>"),
+		      line, Map->name);
+    
+    return ret;
+}

Modified: grass/trunk/lib/vector/Vlib/write_nat.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_nat.c	2008-09-25 11:33:00 UTC (rev 33533)
+++ grass/trunk/lib/vector/Vlib/write_nat.c	2008-09-25 11:39:17 UTC (rev 33534)
@@ -1,19 +1,24 @@
 /*!
    \file write_nat.c
 
-   \brief Vector library - write data
+   \brief Vector library - write vector feature (native format)
 
    Higher level functions for reading/writing/manipulating vectors.
 
+   Operations:
+    - Add feature
+    - Rewrite feature
+    - Delete feature
+    - Restore feature
+
    (C) 2001-2008 by the GRASS Development Team
 
-   This program is free software under the 
-   GNU General Public License (>=v2). 
-   Read the file COPYING that comes with GRASS
-   for details.
+   This program is free software under the GNU General Public License
+   (>=v2). Read the file COPYING that comes with GRASS for details.
 
    \author Original author CERL, probably Dave Gerdes or Mike Higgins.
-   Update to GRASS 5.7 Radim Blazek and David D. Gray.
+   \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
+   \author V*_restore_line() by Martin Landa <landa.martin gmail.com> (2008)
 
    \date 2001
  */
@@ -26,6 +31,12 @@
 #include <grass/Vect.h>
 #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;
@@ -36,10 +47,10 @@
 
     Area = Map->plus.Area[area];
     if (!Area)
-	G_fatal_error(_("BUG (delete_area_cats_from_cidx): Area %d does not exist"),
-		      area);
-
-    if (Area->centroid == 0)
+	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)
@@ -53,6 +64,12 @@
     }
 }
 
+/*!
+  \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;
@@ -63,10 +80,10 @@
 
     Area = Map->plus.Area[area];
     if (!Area)
-	G_fatal_error(_("BUG (add_area_cats_to_cidx): Area %d does not exist"),
-		      area);
+	G_fatal_error(_("%s: Area %d does not exist"),
+		      "add_area_cats_to_cidx():", area);
 
-    if (Area->centroid == 0)
+    if (Area->centroid == 0) /* no centroid found */
 	return;
 
     if (!Cats)
@@ -80,105 +97,56 @@
     }
 }
 
-long V1__rewrite_line_nat(struct Map_info *Map, long offset, int type,
-			  struct line_pnts *points, struct line_cats *cats);
+/*!
+  \brief Add line to topo file
 
-/**
-   \brief Writes line to 'coor' file
+  Update areas. Areas are modified if: 
+   
+  1) first or/and last point are existing nodes ->
+   - drop areas/islands whose boundaries are neighbour to this boundary at these nodes
+   - try build areas and islands for this boundary and neighbour boundaries going through these nodes
 
-   \param Map pointer to vector map
-   \param type feature type
-   \param points line geometry
-   \param cats line cats
+   Question: may be by adding line created new area/isle which doesn't go through nodes of this line
 
-   \return offset into file
-   \return -1 on error
+   <pre>
+             old         new line 
+         +----+----+                    +----+----+                 +----+----+ 
+         | A1 | A2 |  +      /      ->  | A1 |   /|   or +   \   -> | A1 | A2 | \
+         |    |    |                    |    |    |                 |    |    |
+         +----+----+                    +----+----+                 +----+----+
+           I1   I1                        I1   I1                      
+   </pre>        
+ 
+   - reattache all centroids/isles inside new area(s)
+   - attach new isle to area outside
+
+  2) line is closed ring (node at the end is new, so it is not case above)
+    - build new area/isle
+    - check if it is island or contains island(s)
+    - re-attach all centroids/isles inside new area(s)
+    - attach new isle to area outside
+    
+    Note that 1) and 2) is done by the same code.
 */
-long
-V1_write_line_nat(struct Map_info *Map,
-		  int type, struct line_pnts *points, struct line_cats *cats)
+static void add_line_to_topo(struct Map_info *Map, int line,
+			     struct line_pnts *points, struct line_cats *cats)
 {
-    long offset;
+    int first, s, n, i;
+    int type, node, next_line, area, side, sel_area, new_area[2];
 
-    if (dig_fseek(&(Map->dig_fp), 0L, SEEK_END) == -1)	/* set to  end of file */
-	return -1;
-
-    offset = dig_ftell(&(Map->dig_fp));
-    if (offset == -1)
-	return -1;
-
-    return V1__rewrite_line_nat(Map, offset, type, points, cats);
-}
-
-/**
-   \brief Writes line to 'coor' file.
-
-   \param Map pointer to vector map
-   \param type feature type
-   \param points line geometry
-   \param cats line cats
-
-   \return  number of new line
-   \return -1 on error
-*/
-long
-V2_write_line_nat(struct Map_info *Map,
-		  int type, struct line_pnts *points, struct line_cats *cats)
-{
-    int i, s, n, line = 0, next_line, area = 0, node, side, first, sel_area;
-    int new_area[2];
-    long offset;
     struct Plus_head *plus;
-    BOUND_BOX box, abox;
     P_LINE *Line, *NLine;
+    P_NODE *Node;
     P_AREA *Area;
-    P_NODE *Node;
-
-    G_debug(3, "V2_write_line_nat()");
-    offset = V1_write_line_nat(Map, type, points, cats);
-    if (offset < 0)
-	return -1;
-
-    /* Update topology */
+    
+    BOUND_BOX box, abox;
+    
     plus = &(Map->plus);
-    /* Add line */
-    if (plus->built >= GV_BUILD_BASE) {
-	line = dig_add_line(plus, type, points, offset);
-	G_debug(3, "  line added to topo with id = %d", line);
-	dig_line_box(points, &box);
-	dig_line_set_box(plus, line, &box);
-	if (line == 1)
-	    Vect_box_copy(&(plus->box), &box);
-	else
-	    Vect_box_extend(&(plus->box), &box);
-    }
+    Line = plus->Line[line];
+    type = Line->type;
 
-    /* Update areas. Areas are modified if: 
-     *  1) first or/and last point are existing nodes ->
-     *     - drop areas/islands whose boundaries are neighbour to this boundary at these nodes
-     *     - try build areas and islands for this boundary and neighbour boundaries going through these nodes
-     *       Question: may be by adding line created new area/isle which doesn't go through nodes of this line
-     *            old         new line 
-     *        +----+----+                    +----+----+                 +----+----+ 
-     *        | A1 | A2 |  +      /      ->  | A1 |   /|   or +   \   -> | A1 | A2 |\
-     *        |    |    |                    |    |    |                 |    |    |
-     *        +----+----+                    +----+----+                 +----+----+
-     *          I1   I1                        I1   I1                      
-     *        
-     *     - reattache all centroids/isles inside new area(s)
-     *     - attach new isle to area outside
-     *  2) line is closed ring (node at the end is new, so it is not case above)
-     *     - build new area/isle
-     *     - check if it is island or contains island(s)
-     *     - reattache all centroids/isles inside new area(s)
-     *     - attach new isle to area outside
-     *
-     *  Note that 1) and 2) is done by the same code.
-     */
-
     if (plus->built >= GV_BUILD_AREAS) {
 	if (type == GV_BOUNDARY) {
-	    Line = plus->Line[line];
 	    /* Delete neighbour areas/isles */
 	    first = 1;
 	    for (s = 1; s < 3; s++) {	/* for each node */
@@ -326,42 +294,116 @@
 				type);
     }
 
-    G_debug(3, "updated lines : %d , updated nodes : %d", plus->n_uplines,
-	    plus->n_upnodes);
-    return line;
+    return;
 }
 
-/**
-   \brief Rewrites line at the given offset.
-   
-   If the number of points or cats differs from
-   the original one or the type is changed:
-   GV_POINTS -> GV_LINES or GV_LINES -> GV_POINTS,
-   the old one is deleted and the
-   new is appended to the end of the file.
+long V1__rewrite_line_nat(struct Map_info *Map, long offset, int type,
+			  struct line_pnts *points, struct line_cats *cats);
 
-   Old line is deleted (marked as dead), new line written.
+/*!
+  \brief Writes feature to 'coor' file
+  
+  \param Map pointer to vector map
+  \param type feature type
+  \param points feature geometry
+  \param cats feature categories
+  
+  \return feature offset into file
+  \return -1 on error
+*/
+long V1_write_line_nat(struct Map_info *Map,
+		       int type, struct line_pnts *points, struct line_cats *cats)
+{
+    long offset;
 
-   \param Map pointer to vector map
-   \param offset line offset
-   \param type feature type
-   \param points line geometry
-   \param cats line cats
+    if (dig_fseek(&(Map->dig_fp), 0L, SEEK_END) == -1)	/* set to  end of file */
+	return -1;
 
-   \return line offset (rewriten line)
-   \return -1 on error
+    offset = dig_ftell(&(Map->dig_fp));
+    if (offset == -1)
+	return -1;
+
+    return V1__rewrite_line_nat(Map, offset, type, points, cats);
+}
+
+/*!
+  \brief Writes feature to 'coor' file (topology level)
+  
+  \param Map pointer to vector map
+  \param type feature type
+  \param points feature geometry
+  \param cats feature categories
+  
+  \return new feature id
+  \return -1 on error
 */
-long
-V1_rewrite_line_nat(struct Map_info *Map,
-		    long offset,
-		    int type,
-		    struct line_pnts *points, struct line_cats *cats)
+long V2_write_line_nat(struct Map_info *Map,
+		       int type, struct line_pnts *points, struct line_cats *cats)
 {
+    int line;
+    long offset;
+    struct Plus_head *plus;
+    BOUND_BOX box;
+
+    line = 0;
+    
+    G_debug(3, "V2_write_line_nat()");
+    offset = V1_write_line_nat(Map, type, points, cats);
+    if (offset < 0)
+	return -1;
+
+    /* Update topology */
+    plus = &(Map->plus);
+    /* Add line */
+    if (plus->built >= GV_BUILD_BASE) {
+	line = dig_add_line(plus, type, points, offset);
+	G_debug(3, "  line added to topo with id = %d", line);
+	dig_line_box(points, &box);
+	dig_line_set_box(plus, line, &box);
+	if (line == 1)
+	    Vect_box_copy(&(plus->box), &box);
+	else
+	    Vect_box_extend(&(plus->box), &box);
+    }
+
+    add_line_to_topo(Map,
+		     line, points, cats);
+
+    G_debug(3, "updated lines : %d , updated nodes : %d", plus->n_uplines,
+	    plus->n_upnodes);
+    
+    return line;
+}
+
+/*!
+  \brief Rewrites feature at the given offset.
+  
+  If the number of points or cats differs from the original one or
+  the type is changed: GV_POINTS -> GV_LINES or GV_LINES ->
+  GV_POINTS, the old one is deleted and the new is appended to the
+  end of the file.
+  
+  Old feature is deleted (marked as dead), new feature written.
+  
+  \param Map pointer to vector map
+  \param offset feature offset
+  \param type feature type
+  \param points feature geometry
+  \param cats feature categories
+  
+  \return feature offset (rewriten feature)
+  \return -1 on error
+*/
+long V1_rewrite_line_nat(struct Map_info *Map,
+			 long offset,
+			 int type,
+			 struct line_pnts *points, struct line_cats *cats)
+{
     int old_type;
     struct line_pnts *old_points;
     struct line_cats *old_cats;
     long new_offset;
-
+    
     /* TODO: enable points and cats == NULL  */
 
     /* First compare numbers of points and cats with tha old one */
@@ -398,25 +440,24 @@
     }
 }
 
-/**
-   \brief Rewrites line of given number.
-
-   Old line is deleted (marked as dead), new line written.
-
-   \param Map pointer to vector map
-   \param line line id
-   \param type feature type
-   \param points line geometry
-   \param cats line cats
-
-   \return number of new line
-   \return -1 on error
+/*!
+  \brief Rewrites feature (topology level)
+   
+  Old feature is deleted (marked as dead), new feature written.
+  
+  \param Map pointer to vector map
+  \param line feature id
+  \param type feature type
+  \param points feature geometry
+  \param cats feature category
+  
+  \return new feature id
+  \return -1 on error
 */
-int
-V2_rewrite_line_nat(struct Map_info *Map,
-		    int line,
-		    int type,
-		    struct line_pnts *points, struct line_cats *cats)
+int V2_rewrite_line_nat(struct Map_info *Map,
+			int line,
+			int type,
+			struct line_pnts *points, struct line_cats *cats)
 {
     /* TODO: this is just quick shortcut because we have already V2_delete_nat()
      *        and V2_write_nat() this function first deletes old line
@@ -429,23 +470,22 @@
     return (V2_write_line_nat(Map, type, points, cats));
 }
 
-/**
-   \brief Rewrites line at the given offset.
-
-   \param Map pointer to vector map
-   \param offset line offset
-   \param type feature type
-   \param points line geometry
-   \param cats line cats
-
-   \return line offset
-   \return -1 on error
+/*!
+  \brief Rewrites feature at the given offset.
+  
+  \param Map pointer to vector map
+  \param offset feature offset
+  \param type feature type
+  \param points feature geometry
+  \param cats feature categories
+  
+  \return feature offset
+  \return -1 on error
 */
-long
-V1__rewrite_line_nat(struct Map_info *Map,
-		     long offset,
-		     int type,
-		     struct line_pnts *points, struct line_cats *cats)
+long V1__rewrite_line_nat(struct Map_info *Map,
+			  long offset,
+			  int type,
+			  struct line_pnts *points, struct line_cats *cats)
 {
     int i, n_points;
     char rhead, nc;
@@ -530,14 +570,14 @@
     return offset;
 }
 
-/**
-   \brief Deletes line at the given offset.
-
-   \param Map pointer to vector map
-   \param offset line offset
-
-   \return  0 ok
-   \return -1 on error
+/*!
+  \brief Deletes feature at the given offset.
+  
+  \param Map pointer to vector map
+  \param offset feature offset
+  
+  \return  0 on success
+  \return -1 on error
 */
 int V1_delete_line_nat(struct Map_info *Map, long offset)
 {
@@ -570,14 +610,14 @@
     return 0;
 }
 
-/**
-   \brief Deletes line of given number.
-
-   \param pointer to vector map
-   \param line line id
-
-   \return 0 ok
-   \return -1 on error
+/*!
+  \brief Deletes feature (topology level).
+  
+  \param pointer to vector map
+  \param line feature id
+  
+  \return 0 on success
+  \return -1 on error
 */
 int V2_delete_line_nat(struct Map_info *Map, int line)
 {
@@ -597,7 +637,7 @@
 	Line = Map->plus.Line[line];
 
 	if (Line == NULL)
-	    G_fatal_error(_("Attempt to delete dead line"));
+	    G_fatal_error(_("Attempt to delete dead feature"));
 	type = Line->type;
     }
 
@@ -768,3 +808,126 @@
 	    plus->n_upnodes);
     return ret;
 }
+
+/*!
+  \brief Restores feature at the given offset.
+  
+  \param Map pointer to vector map
+  \param offset feature offset
+  
+  \return  0 on success
+  \return -1 on error
+*/
+int V1_restore_line_nat(struct Map_info *Map, long offset)
+{
+    char rhead;
+    GVFILE *dig_fp;
+    
+    G_debug(3, "V1_restore_line_nat(), offset = %ld", offset);
+    
+    dig_set_cur_port(&(Map->head.port));
+    dig_fp = &(Map->dig_fp);
+    
+    if (dig_fseek(dig_fp, offset, 0) == -1)
+	return -1;
+    
+    /* read old */
+    if (0 >= dig__fread_port_C(&rhead, 1, dig_fp))
+	return (-1);
+
+    /* mark as alive */
+    rhead |= 1;
+    
+    /* write new */
+    if (dig_fseek(dig_fp, offset, 0) == -1)
+	return -1;
+
+    if (0 >= dig__fwrite_port_C(&rhead, 1, dig_fp))
+	return -1;
+    
+    if (0 != dig_fflush(dig_fp))
+	return -1;
+    
+    return 0;
+}
+
+/*!
+  \brief Restores feature (topology level)
+  
+  \param Map pointer to vector map
+  \param line feature id
+  \param offset feature offset
+  
+  \return 0 on success
+  \return -1 on error
+*/
+int V2_restore_line_nat(struct Map_info *Map, int line, long offset)
+{
+    int i, ret, type;
+    P_LINE *Line;
+    struct Plus_head *plus;
+    BOUND_BOX box;
+    
+    static struct line_pnts *points = NULL;
+    static struct line_cats *cats = NULL;
+    
+    Line = NULL;
+    type = 0;
+    
+    G_debug(3, "V2_restore_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 restore alive feature"));
+    }
+
+    if (!points) {
+	points = Vect_new_line_struct();
+    }
+
+    if (!cats) {
+	cats = Vect_new_cats_struct();
+    }
+
+    /* restore the line in coor */
+    ret = V1_restore_line_nat(Map, offset);
+
+    if (ret == -1) {
+	return ret;
+    }
+    
+    /* read feature geometry */
+    type = V1_read_line_nat(Map, points, cats, offset);
+    if (type < 0) {
+	return -1;
+    }
+
+    /* update category index */
+    if (plus->update_cidx) {
+	for (i = 0; i < cats->n_cats; i++) {
+	    dig_cidx_add_cat(plus, cats->field[i], cats->cat[i], line, type);
+	}
+    }
+    
+    /* restore the line from topo */		   
+    if (plus->built >= GV_BUILD_BASE) {
+	dig_restore_line(plus, line, type, points, offset);
+	G_debug(3, "  line restored in topo with id = %d", line);
+	dig_line_box(points, &box);
+	dig_line_set_box(plus, line, &box);
+	Vect_box_extend(&(plus->box), &box);
+    }
+    
+    add_line_to_topo(Map,
+		     line, points, cats);
+
+    G_debug(3, "updated lines : %d , updated nodes : %d", plus->n_uplines,
+	    plus->n_upnodes);
+    
+
+    return ret;
+}



More information about the grass-commit mailing list