Sfoglia il codice sorgente

vlib: allow to optionally maintain list of updated lines/nodes

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@50294 15284696-431f-4ddb-bdfa-cd5b030d7da7
Martin Landa 13 anni fa
parent
commit
65f72a5848

+ 3 - 0
include/defs/vector.h

@@ -282,8 +282,11 @@ int Vect_get_centroid_area(const struct Map_info *, int);
 /* Level 2 update only */
 int Vect_get_num_updated_lines(const struct Map_info *);
 int Vect_get_updated_line(const struct Map_info *, int);
+off_t Vect_get_updated_line_offset(const struct Map_info *, int);
 int Vect_get_num_updated_nodes(const struct Map_info *);
 int Vect_get_updated_node(const struct Map_info *, int);
+void Vect_set_updated(struct Map_info *, int);
+void Vect_reset_updated(struct Map_info *);
 
 /* History */
 int Vect_hist_command(struct Map_info *);

+ 44 - 31
include/vect/dig_structs.h

@@ -1008,39 +1008,52 @@ struct Plus_head
 
     /*** level 2 ***/
     /*!
-      \brief Used internaly in diglib to know if list is maintained
-    */
-    int do_uplist;
-
-    /*!
-      \brief Array of updated lines
+      \brief List of updated lines/nodes
 
-      List of lines and nodes updated (topo info for the line was
-      changed) by last write/rewrite/delete operation.  Lines/nodes in
-      the list may be deleted (e.g. delete boundary: first added for
-      delete area and then delete
-    */
-    int *uplines;
-    /*!
-      \brief Allocated array (level 2)
-    */
-    int alloc_uplines;
-    /*!
-      \brief Number of updated lines (level 2)
-    */
-    int n_uplines;
-    /*!
-      \brief Array of updated nodes (level 2)
-    */
-    int *upnodes;
-    /*!
-      \brief Allocated array (level 2)
-    */
-    int alloc_upnodes;
-    /*!
-      \brief number of updated nodes (level 2)
+      Note: Vect_set_updated() must be called to maintain this list
     */
-    int n_upnodes;
+    struct {
+	/*!
+	  \brief Used internaly in diglib to know if list is maintained
+	*/
+	int do_uplist;
+	
+	/*!
+	  \brief Array of updated lines
+	  
+	  List of lines and nodes updated (topo info for the line was
+	  changed) by last write/rewrite/delete operation.
+	  Lines/nodes in the list may be deleted (e.g. delete
+	  boundary: first added for delete area and then delete
+	*/
+	int *uplines;
+	/*!
+	  \brief Array of updated lines - offset
+
+	  Negative value for dead (deleted) lines - used by Vect_restore_line()
+	*/
+	off_t *uplines_offset;
+	/*!
+	  \brief Allocated array of lines
+	*/
+	int alloc_uplines;
+	/*!
+	  \brief Number of updated lines
+	*/
+	int n_uplines;
+	/*!
+	  \brief Array of updated nodes 
+	*/
+	int *upnodes;
+	/*!
+	  \brief Allocated array of nodes
+	*/
+	int alloc_upnodes;
+	/*!
+	  \brief number of updated nodes
+	*/
+	int n_upnodes;
+    } uplist;
 };
 
 /*! \brief

+ 2 - 2
lib/vector/Vlib/build.c

@@ -455,7 +455,7 @@ int Vect_attach_centroids(struct Map_info *Map, const struct bound_box * box)
 		Area->centroid = centr;
 		topo->area = sel_area;
 
-		if (sel_area != orig_area && plus->do_uplist)
+		if (sel_area != orig_area && plus->uplist.do_uplist)
 		    dig_line_add_updated(plus, centr);
 	    }
 	    else if (Area->centroid != centr) {	/* duplicate centroid */
@@ -464,7 +464,7 @@ int Vect_attach_centroids(struct Map_info *Map, const struct bound_box * box)
 		G_debug(3, "\tduplicate centroid -> do not attach to area");
 		topo->area = -sel_area;
 
-		if (-sel_area != orig_area && plus->do_uplist)
+		if (-sel_area != orig_area && plus->uplist.do_uplist)
 		    dig_line_add_updated(plus, centr);
 	    }
 	}

+ 105 - 57
lib/vector/Vlib/level_two.c

@@ -3,23 +3,31 @@
 
    \brief Vector library - topology level functions
 
-   (C) 2001-2009, 2011 by the GRASS Development Team
+   (C) 2001-2009, 2011-2012 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.
+   (>=v2). Read the file COPYING that comes with GRASS for details.
 
    \author Original author CERL, probably Dave Gerdes or Mike Higgins.
    \author Update to GRASS 5.7 Radim Blazek and David D. Gray.
+   \author Update to GRASS 7 by Martin Landa <landa.martin gmail.com>
  */
 
 #include <stdlib.h>
 #include <grass/vector.h>
 #include <grass/glocale.h>
 
+static void check_level(const struct Map_info *Map)
+{
+    if (Map->level < 2)
+	G_fatal_error(_("Vector map <%s> is not open at topological level"),
+		      Vect_get_full_name(Map));
+}
+
 /*!
    \brief Get number of nodes in vector map
 
-   \param Map vector map
+   \param Map pointer to Map_info struct
 
    \return number of nodes
  */
@@ -31,7 +39,7 @@ plus_t Vect_get_num_nodes(const struct Map_info *Map)
 /*!
    \brief Get number of primitives in vector map
 
-   \param map vector map
+   \param map pointer to Map_info struct
    \patam type feature type
 
    \return number of primitives
@@ -59,7 +67,7 @@ plus_t Vect_get_num_primitives(const struct Map_info *Map, int type)
 /*!
    \brief Fetch number of features (points, lines, boundaries, centroids) in vector map
 
-   \param map vector map
+   \param map pointer to Map_info struct
 
    \return number of features
  */
@@ -71,7 +79,7 @@ plus_t Vect_get_num_lines(const struct Map_info *Map)
 /*!
    \brief Get number of areas in vector map
 
-   \param map vector map
+   \param map pointer to Map_info struct
 
    \return number of areas
  */
@@ -83,7 +91,7 @@ plus_t Vect_get_num_areas(const struct Map_info *Map)
 /*!
    \brief Fetch number of kernels in vector map
 
-   \param map vector map
+   \param map pointer to Map_info struct
 
    \return number of kernels
  */
@@ -96,7 +104,7 @@ plus_t Vect_get_num_kernels(const struct Map_info *Map)
 /*!
    \brief Get number of faces in vector map
 
-   \param map vector map
+   \param map pointer to Map_info struct
 
    \return number of faces
  */
@@ -109,7 +117,7 @@ plus_t Vect_get_num_faces(const struct Map_info *Map)
 /*!
    \brief Fetch number of volumes in vector map
 
-   \param map vector map
+   \param map pointer to Map_info struct
 
    \return number of volumes
  */
@@ -122,7 +130,7 @@ plus_t Vect_get_num_volumes(const struct Map_info *Map)
 /*!
    \brief Get number of islands in vector map
 
-   \param map vector map
+   \param map pointer to Map_info struct
 
    \return number of islands
  */
@@ -135,7 +143,7 @@ plus_t Vect_get_num_islands(const struct Map_info *Map)
 /*!
    \brief Fetch number of holes in vector map
 
-   \param map vector map
+   \param map pointer to Map_info struct
 
    \return number of holes
  */
@@ -148,7 +156,7 @@ plus_t Vect_get_num_holes(const struct Map_info *Map)
 /*!
    \brief Get number of defined dblinks
 
-   \param map vector map
+   \param map pointer to Map_info struct
 
    \return number of dblinks
  */
@@ -161,68 +169,90 @@ int Vect_get_num_dblinks(const struct Map_info *Map)
 /*!
    \brief Get number of updated features
 
-   \param map vector map
+   Note: Vect_set_updated() must be called to maintain list of updated
+   features
+
+   \param map pointer to Map_info struct
 
    \return number of updated features
  */
 int Vect_get_num_updated_lines(const struct Map_info *Map)
 {
-    return (Map->plus.n_uplines);
+    return (Map->plus.uplist.n_uplines);
 }
 
 /*!
    \brief Get updated line by index
 
-   \param map vector map
+   Note: Vect_set_updated() must be called to maintain list of updated
+   features
+
+   \param map pointer to Map_info struct
    \param idx index
 
    \return updated line
  */
 int Vect_get_updated_line(const struct Map_info *Map, int idx)
 {
-    return (Map->plus.uplines[idx]);
+    return (Map->plus.uplist.uplines[idx]);
+}
+
+/*!
+   \brief Get updated line offset by index
+
+   Note: Vect_set_updated() must be called to maintain list of updated
+   features
+
+   \param map pointer to Map_info struct
+   \param idx index
+
+   \return updated line
+ */
+off_t Vect_get_updated_line_offset(const struct Map_info *Map, int idx)
+{
+    return (Map->plus.uplist.uplines_offset[idx]);
 }
 
 /*!
    \brief Get number of updated nodes
 
-   \param map vector map
+   \param map pointer to Map_info struct
 
    \return number of updated nodes
  */
 int Vect_get_num_updated_nodes(const struct Map_info *Map)
 {
-    return (Map->plus.n_upnodes);
+    return (Map->plus.uplist.n_upnodes);
 }
 
 /*!
    \brief Get updated node by index
 
-   \param map vector map
+   Note: Vect_set_updated() must be called to maintain list of updated
+   features
+
+   \param map pointer to Map_info struct
    \param idx index
 
    \return updated node
  */
 int Vect_get_updated_node(const struct Map_info *Map, int idx)
 {
-    return (Map->plus.upnodes[idx]);
+    return (Map->plus.uplist.upnodes[idx]);
 }
 
 /*!
    \brief Get line type
 
-   \param map vector map
+   \param map pointer to Map_info struct
    \param line line id
 
    \return line type
  */
-int
-Vect_get_line_type(const struct Map_info *Map, int line)
+int Vect_get_line_type(const struct Map_info *Map, int line)
 {
-    if (Map->level < 2)
-	G_fatal_error(_("Vector map <%s> is not open on level >= 2"),
-		      Vect_get_full_name(Map));
-
+    check_level(Map);
+    
     if (!Vect_line_alive(Map, line))
 	return 0;
 	
@@ -232,7 +262,7 @@ Vect_get_line_type(const struct Map_info *Map, int line)
 /*!
    \brief Get node coordinates
 
-   \param map vector map
+   \param map pointer to Map_info struct
    \param num node id
    \param x,y,z coordinates values (for 2D coordinates z is NULL)
 
@@ -257,7 +287,7 @@ Vect_get_node_coor(const struct Map_info *Map, int num, double *x, double *y,
 /*!
    \brief Get line nodes
 
-   \param Map vector map
+   \param Map pointer to Map_info struct
    \param line line id
    \param n1, n2 ids of line nodes (or NULL)
 
@@ -267,9 +297,7 @@ int Vect_get_line_nodes(const struct Map_info *Map, int line, int *n1, int *n2)
 {
     char type;
 
-    if (Map->level < 2)
-	G_fatal_error(_("Vector map <%s> is not open on level >= 2"),
-		      Vect_get_full_name(Map));
+    check_level(Map);
 
     type = Vect_get_line_type(Map, line);
 
@@ -299,7 +327,7 @@ int Vect_get_line_nodes(const struct Map_info *Map, int line, int *n1, int *n2)
 /*!
    \brief Get area/isle ids on the left and right
 
-   \param Map vector map
+   \param Map pointer to Map_info struct
    \param line line id
    \param[out] left,right area/isle id on the left and right
 
@@ -309,10 +337,8 @@ int Vect_get_line_areas(const struct Map_info *Map, int line, int *left, int *ri
 {
     struct P_topo_b *topo;
 
-    if (Map->level < 2)
-	G_fatal_error(_("Vector map <%s> is not open on level >= 2"),
-		      Vect_get_full_name(Map));
-
+    check_level(Map);
+    
     if (!Map->plus.Line[line]->topo)
 	G_fatal_error(_("Areas not available for line %d"), line);
 
@@ -332,18 +358,15 @@ int Vect_get_line_areas(const struct Map_info *Map, int line, int *left, int *ri
 /*!
    \brief Get number of lines for node
 
-   \param Map vector map
+   \param Map pointer to Map_info struct
    \param node node id
 
    \return numbers of lines
  */
 int Vect_get_node_n_lines(const struct Map_info *Map, int node)
 {
-
-    if (Map->level < 2)
-	G_fatal_error(_("Vector map <%s> is not open on level >= 2"),
-		      Vect_get_full_name(Map));
-
+    check_level(Map);
+    
     return (Map->plus.Node[node]->n_lines);
 
 }
@@ -351,7 +374,7 @@ int Vect_get_node_n_lines(const struct Map_info *Map, int node)
 /*!
    \brief Get line id for node line index
 
-   \param Map vector map
+   \param Map pointer to Map_info struct
    \param node node id
    \param line line index (range: 0 - Vect_get_node_n_lines())
 
@@ -359,17 +382,15 @@ int Vect_get_node_n_lines(const struct Map_info *Map, int node)
  */
 int Vect_get_node_line(const struct Map_info *Map, int node, int line)
 {
-    if (Map->level < 2)
-	G_fatal_error(_("Vector map <%s> is not open on level >= 2"),
-		      Vect_get_full_name(Map));
-
+    check_level(Map);
+    
     return (Map->plus.Node[node]->lines[line]);
 }
 
 /*!
    \brief Angle of segment of the line connected to the node
 
-   \param Map vector map
+   \param Map pointer to Map_info struct
    \param node node number
    \param line line index (range: 0 - Vect_get_node_n_lines())
 
@@ -377,9 +398,7 @@ int Vect_get_node_line(const struct Map_info *Map, int node, int line)
  */
 float Vect_get_node_line_angle(const struct Map_info *Map, int node, int line)
 {
-    if (Map->level < 2)
-	G_fatal_error(_("Vector map <%s> is not open on level >= 2"),
-		      Vect_get_full_name(Map));
+    check_level(Map);
 
     return (Map->plus.Node[node]->angles[line]);
 }
@@ -387,7 +406,7 @@ float Vect_get_node_line_angle(const struct Map_info *Map, int node, int line)
 /*!
    \brief Get area id the centroid is within
 
-   \param Map vector map
+   \param Map pointer to Map_info struct
    \param centroid centroid id
 
    \return area id the centroid is within
@@ -398,10 +417,8 @@ int Vect_get_centroid_area(const struct Map_info *Map, int centroid)
 {
     struct P_topo_c *topo;
 
-    if (Map->level < 2)
-	G_fatal_error(_("Vector map <%s> is not open on level >= 2"),
-		      Vect_get_full_name(Map));
-
+    check_level(Map);
+    
     if (Map->plus.Line[centroid]->type != GV_CENTROID)
 	return 0;
     
@@ -411,3 +428,34 @@ int Vect_get_centroid_area(const struct Map_info *Map, int centroid)
     
     return (topo->area);
 }
+
+/*!
+  \brief Enable/disable maintanance of list of updated lines/nodes
+
+  See Plus_head.uplist for details.
+  
+  \param Map pointer to Map_info struct
+  \param enable TRUE/FALSE to enable/disable
+*/
+void Vect_set_updated(struct Map_info *Map, int enable)
+{
+    check_level(Map);
+    
+    Map->plus.uplist.do_uplist = enable != 0 ? TRUE : FALSE;
+}
+
+/*!
+  \brief Reset list of updated lines/nodes
+
+  \param Map pointer to Map_info struct
+*/
+void Vect_reset_updated(struct Map_info *Map)
+{
+    struct Plus_head *Plus;
+
+    check_level(Map);
+    
+    Plus = &(Map->plus);
+    dig_line_reset_updated(Plus);
+    dig_node_reset_updated(Plus);
+}

+ 13 - 56
lib/vector/Vlib/open.c

@@ -5,7 +5,7 @@
  *
  * Higher level functions for reading/writing/manipulating vectors.
  *
- * (C) 2001-2009 by the GRASS Development Team
+ * (C) 2001-2009, 2012 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.
@@ -120,8 +120,6 @@ int Vect_set_open_level(int level)
 /*! 
  * \brief Open existing vector map for reading (internal use only)
  *
- * 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 ("" for search path)
@@ -412,7 +410,7 @@ int Vect__open_old(struct Map_info *Map, const char *name, const char *mapset, c
 	Map->plus.built = GV_BUILD_ALL;	/* highest level of topology for level 2 */
     }
 
-    Map->plus.do_uplist = 0;
+    Map->plus.uplist.do_uplist = FALSE;
 
     /* read db links */
     Map->dblnk = Vect_new_dblinks_struct();
@@ -476,8 +474,6 @@ int Vect__open_old(struct Map_info *Map, const char *name, const char *mapset, c
  * 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
  * \param name name of vector map to open
  * \param mapset mapset name
@@ -493,8 +489,6 @@ int Vect_open_old(struct Map_info *Map, const char *name, const char *mapset)
 /*!
  * \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
@@ -515,7 +509,8 @@ int Vect_open_old2(struct Map_info *Map, const char *name, const char *mapset, c
  * This function is replaced by Vect_open_update2() to handle also
  * direct OGR support.
  *
- * In case of error, the functions respect fatal error settings.
+ * By default list of updated features is not maintained, see
+ * Vect_set_updated() for details.
  *
  * \param[out] Map pointer to Map_info structure
  * \param name name of vector map to update
@@ -526,32 +521,15 @@ int Vect_open_old2(struct Map_info *Map, const char *name, const char *mapset, c
  */
 int Vect_open_update(struct Map_info *Map, const char *name, const char *mapset)
 {
-    int ret;
-    
-    ret = Vect__open_old(Map, name, mapset, NULL, 1, 0);
-    
-    /* the update lists are unused, a waste of time and memory */
-    /*
-    if (ret > 0) {
-	Map->plus.do_uplist = 1;
-
-	Map->plus.uplines = NULL;
-	Map->plus.n_uplines = 0;
-	Map->plus.alloc_uplines = 0;
-	Map->plus.upnodes = NULL;
-	Map->plus.n_upnodes = 0;
-	Map->plus.alloc_upnodes = 0;
-    }
-    */
-
-    return ret;
+    return Vect__open_old(Map, name, mapset, NULL, 1, 0);
 }
 
 /*!
  * \brief Open existing vector map for reading/writing (native or OGR
  * format)
  *
- * In case of error, the functions respect fatal error settings.
+ * By default list of updated features is not maintained, see
+ * Vect_set_updated() for details.
  *
  * \param[out] Map pointer to Map_info structure
  * \param name name of vector map to update
@@ -563,11 +541,7 @@ int Vect_open_update(struct Map_info *Map, const char *name, const char *mapset)
  */
 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;
+    return Vect__open_old(Map, name, mapset, layer, 1, 0);
 }
 
 /*! 
@@ -578,8 +552,6 @@ int Vect_open_update2(struct Map_info *Map, const char *name, const char *mapset
  * 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)
@@ -596,8 +568,6 @@ int Vect_open_old_head(struct Map_info *Map, const char *name, const char *mapse
  * \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)
@@ -615,8 +585,6 @@ int Vect_open_old_head2(struct Map_info *Map, const char *name, const char *maps
  * \brief Open header file of existing vector map for updating (mostly
  * for database link updates)
  *
- * 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
@@ -630,27 +598,16 @@ int Vect_open_update_head(struct Map_info *Map, const char *name,
     int ret;
 
     ret = Vect__open_old(Map, name, mapset, NULL, 1, 1);
-
-    /* the update lists are unused, a waste of time and memory */
-    /*
-    if (ret > 0) {
-	Map->plus.do_uplist = 1;
-
-	Map->plus.uplines = NULL;
-	Map->plus.n_uplines = 0;
-	Map->plus.alloc_uplines = 0;
-	Map->plus.upnodes = NULL;
-	Map->plus.n_upnodes = 0;
-	Map->plus.alloc_upnodes = 0;
-    }
-    */
-
+    
     return ret;
 }
 
 /*!
  * \brief Create new vector map for reading/writing
  *
+ * By default list of updated features is not maintained, see
+ * Vect_set_updated() for details.
+ *
  * \param[in,out] Map pointer to Map_info structure
  * \param name name of vector map
  * \param with_z non-zero value for 3D vector data
@@ -769,7 +726,7 @@ int Vect_open_new(struct Map_info *Map, const char *name, int with_z)
     Map->support_updated = 0;
     Map->plus.built = GV_BUILD_NONE;
     Map->mode = GV_MODE_RW;
-    Map->plus.do_uplist = 0;
+    Map->plus.uplist.do_uplist = FALSE;
 
     Vect_set_proj(Map, G_projection());
     Vect_set_zone(Map, G_zone());

+ 1 - 1
lib/vector/Vlib/read.c

@@ -215,7 +215,7 @@ int Vect_isle_alive(const struct Map_info *Map, int isle)
   \return feature offset
   \return -1 on error
 */
-off_t Vect_get_line_offset(const const struct Map_info *Map, int line)
+off_t Vect_get_line_offset(const struct Map_info *Map, int line)
 {
     if (line < 1 || line > Map->plus.n_lines)
 	return -1;

+ 0 - 8
lib/vector/Vlib/write.c

@@ -149,8 +149,6 @@ off_t Vect_write_line(struct Map_info *Map, int type,
     if (!VECT_OPEN(Map))
 	G_fatal_error(_("Unable to write feature, vector map is not opened"));
 
-    dig_line_reset_updated(&(Map->plus));
-    dig_node_reset_updated(&(Map->plus));
     if (!(Map->plus.update_cidx)) {
 	Map->plus.cidx_up_to_date = 0;
     }
@@ -195,8 +193,6 @@ off_t Vect_rewrite_line(struct Map_info *Map, int line, int type,
     if (!VECT_OPEN(Map))
 	G_fatal_error(_("Unable to rewrite feature, vector map is not opened"));
 
-    dig_line_reset_updated(&(Map->plus));
-    dig_node_reset_updated(&(Map->plus));
     if (!(Map->plus.update_cidx)) {
 	Map->plus.cidx_up_to_date = 0;
     }
@@ -244,8 +240,6 @@ int Vect_delete_line(struct Map_info *Map, int line)
 		      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;
     }
@@ -290,8 +284,6 @@ int Vect_restore_line(struct Map_info *Map, int line, off_t offset)
 		      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;
     }

+ 9 - 9
lib/vector/Vlib/write_nat.c

@@ -375,8 +375,8 @@ off_t V2_write_line_nat(struct Map_info *Map, int type,
 
     V2__add_line_to_topo_nat(Map, line, points, cats);
 
-    G_debug(3, "updated lines : %d , updated nodes : %d", plus->n_uplines,
-	    plus->n_upnodes);
+    G_debug(3, "updated lines : %d , updated nodes : %d", plus->uplist.n_uplines,
+	    plus->uplist.n_upnodes);
 
     /* returns int line, but is defined as off_t for compatibility with
      * Vect_write_line_array in write.c */
@@ -496,8 +496,8 @@ off_t V2_rewrite_line_nat(struct Map_info *Map, int line, int type, off_t old_of
 
     V2__add_line_to_topo_nat(Map, line, points, cats);
 
-    G_debug(3, "updated lines : %d , updated nodes : %d", plus->n_uplines,
-	    plus->n_upnodes);
+    G_debug(3, "updated lines : %d , updated nodes : %d", plus->uplist.n_uplines,
+	    plus->uplist.n_upnodes);
 
     /* returns int line, but is defined as off_t for compatibility with
      * Vect_rewrite_line_array in write.c */
@@ -690,7 +690,6 @@ int V2_delete_line_nat(struct Map_info *Map, int line)
 
     /* Update category index */
     if (plus->update_cidx) {
-
 	for (i = 0; i < Cats->n_cats; i++) {
 	    dig_cidx_del_cat(plus, Cats->field[i], Cats->cat[i], line, type);
 	}
@@ -848,8 +847,9 @@ int V2_delete_line_nat(struct Map_info *Map, int line)
 	}
     }
 
-    G_debug(3, "updated lines : %d , updated nodes : %d", plus->n_uplines,
-	    plus->n_upnodes);
+    G_debug(3, "updated lines : %d , updated nodes : %d", plus->uplist.n_uplines,
+	    plus->uplist.n_upnodes);
+    
     return ret;
 }
 
@@ -968,8 +968,8 @@ int V2_restore_line_nat(struct Map_info *Map, int line, off_t offset)
     V2__add_line_to_topo_nat(Map,
 		     line, points, cats);
 
-    G_debug(3, "updated lines : %d , updated nodes : %d", plus->n_uplines,
-	    plus->n_upnodes);
+    G_debug(3, "updated lines : %d , updated nodes : %d", plus->uplist.n_uplines,
+	    plus->uplist.n_upnodes);
 
     return ret;
 }

+ 2 - 2
lib/vector/Vlib/write_ogr.c

@@ -341,8 +341,8 @@ off_t V2_write_line_ogr(struct Map_info *Map, int type,
     }
 
 
-    G_debug(3, "updated lines : %d , updated nodes : %d", plus->n_uplines,
-	    plus->n_upnodes);
+    G_debug(3, "updated lines : %d , updated nodes : %d", plus->uplist.n_uplines,
+	    plus->uplist.n_upnodes);
 
     /* returns int line, but is defined as off_t for compatibility with
      * Write_line_array in write.c */

+ 5 - 5
lib/vector/diglib/plus_area.c

@@ -209,7 +209,7 @@ int dig_add_area(struct Plus_head *plus, int n_lines, plus_t * lines,
 	Area->lines[i] = line;
 	Line = plus->Line[abs(line)];
 	topo = (struct P_topo_b *)Line->topo;
-	if (plus->do_uplist)
+	if (plus->uplist.do_uplist)
 	    dig_line_add_updated(plus, abs(line));
 	if (line < 0) {		/* revers direction -> area on left */
 	    if (topo->left != 0) {
@@ -368,7 +368,7 @@ int dig_del_area(struct Plus_head *plus, int area)
 	line = Area->lines[i];	/* >0 = clockwise -> right, <0 = counterclockwise ->left */
 	Line = plus->Line[abs(line)];
 	btopo = (struct P_topo_b *)Line->topo;
-	if (plus->do_uplist)
+	if (plus->uplist.do_uplist)
 	    dig_line_add_updated(plus, abs(line));
 	if (line > 0) {
 	    G_debug(3, "  Set line %d right side to 0", line);
@@ -403,7 +403,7 @@ int dig_del_area(struct Plus_head *plus, int area)
 	else {
 	    ctopo = (struct P_topo_c *)Line->topo;
 	    ctopo->area = 0;
-	    if (plus->do_uplist)
+	    if (plus->uplist.do_uplist)
 		dig_line_add_updated(plus, line);
 	}
     }
@@ -687,7 +687,7 @@ int dig_add_isle(struct Plus_head *plus, int n_lines, plus_t * lines,
 	Isle->lines[i] = line;
 	Line = plus->Line[abs(line)];
 	topo = (struct P_topo_b *)Line->topo;
-	if (plus->do_uplist)
+	if (plus->uplist.do_uplist)
 	    dig_line_add_updated(plus, abs(line));
 	if (line < 0) {		/* revers direction -> isle on left */
 	    if (topo->left != 0) {
@@ -747,7 +747,7 @@ int dig_del_isle(struct Plus_head *plus, int isle)
 	line = Isle->lines[i];	/* >0 = clockwise -> right, <0 = counterclockwise ->left */
 	Line = plus->Line[abs(line)];
 	topo = (struct P_topo_b *)Line->topo;
-	if (plus->do_uplist)
+	if (plus->uplist.do_uplist)
 	    dig_line_add_updated(plus, abs(line));
 	if (line > 0)
 	    topo->right = 0;

+ 13 - 7
lib/vector/diglib/plus_line.c

@@ -31,9 +31,11 @@ static int add_line(struct Plus_head *plus, int lineid, int type, const struct l
     line->offset = offset;
 
     dig_spidx_add_line(plus, lineid, box);
-    if (plus->do_uplist)
+    if (plus->uplist.do_uplist) {
 	dig_line_add_updated(plus, lineid);
-
+	plus->uplist.uplines_offset[plus->uplist.n_uplines - 1] = line->offset;
+    }
+    
     if (type & GV_POINT) {
 	line->topo = NULL;
 	return (lineid);
@@ -77,7 +79,7 @@ static int add_line(struct Plus_head *plus, int lineid, int type, const struct l
     }
 
     dig_node_add_line(plus, node, lineid, Points, type);
-    if (plus->do_uplist)
+    if (plus->uplist.do_uplist)
 	dig_node_add_updated(plus, node);
 
     lp = Points->n_points - 1;
@@ -105,7 +107,7 @@ static int add_line(struct Plus_head *plus, int lineid, int type, const struct l
     }
 
     dig_node_add_line(plus, node, -lineid, Points, type);
-    if (plus->do_uplist)
+    if (plus->uplist.do_uplist)
 	dig_node_add_updated(plus, node);
 
     return (lineid);
@@ -216,6 +218,11 @@ int dig_del_line(struct Plus_head *plus, int line, double x, double y, double z)
     Line = plus->Line[line];
     dig_spidx_del_line(plus, line, x, y, z);
 
+    if (plus->uplist.do_uplist) {
+	dig_line_add_updated(plus, line);
+	plus->uplist.uplines_offset[plus->uplist.n_uplines - 1] = -1 * Line->offset;
+    }
+    
     if (!(Line->type & GV_LINES)) {
 	/* Delete line */
 	dig_free_line(Line);
@@ -252,7 +259,6 @@ int dig_del_line(struct Plus_head *plus, int line, double x, double y, double z)
     Node->n_lines--;
 
     if (Node->n_lines == 0) {
-
 	G_debug(3, "    node %d has 0 lines -> delete", N1);
 	dig_spidx_del_node(plus, N1);
 	/* free structures */
@@ -260,7 +266,7 @@ int dig_del_line(struct Plus_head *plus, int line, double x, double y, double z)
 	plus->Node[N1] = NULL;
     }
     else {
-	if (plus->do_uplist)
+	if (plus->uplist.do_uplist)
 	    dig_node_add_updated(plus, N1);
     }
 
@@ -296,7 +302,7 @@ int dig_del_line(struct Plus_head *plus, int line, double x, double y, double z)
 	plus->Node[N2] = NULL;
     }
     else {
-	if (plus->do_uplist)
+	if (plus->uplist.do_uplist)
 	    dig_node_add_updated(plus, N2);
     }
 

+ 25 - 22
lib/vector/diglib/update.c

@@ -24,7 +24,7 @@
  */
 void dig_line_reset_updated(struct Plus_head *Plus)
 {
-    Plus->n_uplines = 0;
+    Plus->uplist.n_uplines = 0;
 }
 
 /*!
@@ -39,21 +39,24 @@ void dig_line_add_updated(struct Plus_head *Plus, int line)
 
     G_debug(3, "dig_line_add_updated(): line = %d", line);
 
-    /* Check if already in list */
-    for (i = 0; i < Plus->n_uplines; i++)
-	if (Plus->uplines[i] == line)
+    /* Check if already in list
+    for (i = 0; i < Plus->uplist.n_uplines; i++)
+	if (Plus->uplist.uplines[i] == line)
 	    return;
-
+    */
     /* Alloc space if needed */
-    if (Plus->n_uplines == Plus->alloc_uplines) {
-	Plus->alloc_uplines += 1000;
-	Plus->uplines =
-	    (int *)G_realloc(Plus->uplines,
-			     Plus->alloc_uplines * sizeof(int));
+    if (Plus->uplist.n_uplines == Plus->uplist.alloc_uplines) {
+	Plus->uplist.alloc_uplines += 1000;
+	Plus->uplist.uplines =
+	    (int *)G_realloc(Plus->uplist.uplines,
+			     Plus->uplist.alloc_uplines * sizeof(int));
+	Plus->uplist.uplines_offset =
+	    (off_t *)G_realloc(Plus->uplist.uplines_offset,
+			     Plus->uplist.alloc_uplines * sizeof(off_t));
     }
 
-    Plus->uplines[Plus->n_uplines] = line;
-    Plus->n_uplines++;
+    Plus->uplist.uplines[Plus->uplist.n_uplines] = line;
+    Plus->uplist.n_uplines++;
 }
 
 /*!
@@ -63,7 +66,7 @@ void dig_line_add_updated(struct Plus_head *Plus, int line)
  */
 void dig_node_reset_updated(struct Plus_head *Plus)
 {
-    Plus->n_upnodes = 0;
+    Plus->uplist.n_upnodes = 0;
 }
 
 /*!
@@ -79,18 +82,18 @@ void dig_node_add_updated(struct Plus_head *Plus, int node)
     G_debug(3, "dig_node_add_updated(): node = %d", node);
 
     /* Check if already in list */
-    for (i = 0; i < Plus->n_upnodes; i++)
-	if (Plus->upnodes[i] == node)
+    for (i = 0; i < Plus->uplist.n_upnodes; i++)
+	if (Plus->uplist.upnodes[i] == node)
 	    return;
 
     /* Alloc space if needed */
-    if (Plus->n_upnodes == Plus->alloc_upnodes) {
-	Plus->alloc_upnodes += 1000;
-	Plus->upnodes =
-	    (int *)G_realloc(Plus->upnodes,
-			     Plus->alloc_upnodes * sizeof(int));
+    if (Plus->uplist.n_upnodes == Plus->uplist.alloc_upnodes) {
+	Plus->uplist.alloc_upnodes += 1000;
+	Plus->uplist.upnodes =
+	    (int *)G_realloc(Plus->uplist.upnodes,
+			     Plus->uplist.alloc_upnodes * sizeof(int));
     }
 
-    Plus->upnodes[Plus->n_upnodes] = node;
-    Plus->n_upnodes++;
+    Plus->uplist.upnodes[Plus->uplist.n_upnodes] = node;
+    Plus->uplist.n_upnodes++;
 }