浏览代码

digitizer crashes, leaves vector broken (https://trac.osgeo.org/grass/ticket/2814)
fix restore logic broken by https://trac.osgeo.org/grass/changeset/64214
(merge https://trac.osgeo.org/grass/changeset/67508 from trunk)


git-svn-id: https://svn.osgeo.org/grass/grass/branches/releasebranch_7_0@67517 15284696-431f-4ddb-bdfa-cd5b030d7da7

Martin Landa 9 年之前
父节点
当前提交
ac812b1892
共有 5 个文件被更改,包括 30 次插入28 次删除
  1. 4 2
      gui/wxpython/vdigit/wxdigit.py
  2. 3 3
      include/defs/vector.h
  3. 2 2
      lib/python/pygrass/vector/__init__.py
  4. 8 8
      lib/vector/Vlib/write.c
  5. 13 13
      lib/vector/Vlib/write_nat.c

+ 4 - 2
gui/wxpython/vdigit/wxdigit.py

@@ -419,6 +419,7 @@ class IVDigit:
             action = actions[i]
             action = actions[i]
             line = action['line']
             line = action['line']
             if action['offset'] > 0:
             if action['offset'] > 0:
+                # feature previously added -> to be deleted
                 if Vect_line_alive(self.poMapInfo, line):
                 if Vect_line_alive(self.poMapInfo, line):
                     Debug.msg(3, "IVDigit._applyChangeset(): changeset=%d, action=add, line=%d -> deleted",
                     Debug.msg(3, "IVDigit._applyChangeset(): changeset=%d, action=add, line=%d -> deleted",
                               changeset, line)
                               changeset, line)
@@ -428,14 +429,15 @@ class IVDigit:
                 else:
                 else:
                     Debug.msg(3, "Digit.ApplyChangeset(): changeset=%d, action=add, line=%d dead",
                     Debug.msg(3, "Digit.ApplyChangeset(): changeset=%d, action=add, line=%d dead",
                               changeset, line)
                               changeset, line)
-            else: # delete
+            else:
+                # feature previously deleted -> to be added
                 offset = abs(action['offset'])
                 offset = abs(action['offset'])
                 
                 
                 if not Vect_line_alive(self.poMapInfo, line):
                 if not Vect_line_alive(self.poMapInfo, line):
                     Debug.msg(3, "Digit.ApplyChangeset(): changeset=%d, action=delete, line=%d -> added",
                     Debug.msg(3, "Digit.ApplyChangeset(): changeset=%d, action=delete, line=%d -> added",
                               changeset, line)
                               changeset, line)
                     
                     
-                    if Vect_restore_line(self.poMapInfo, line, offset) < 0:
+                    if Vect_restore_line(self.poMapInfo, offset, line) < 0:
                         return -1
                         return -1
                     ret = 1
                     ret = 1
                 else:
                 else:

+ 3 - 3
include/defs/vector.h

@@ -256,7 +256,7 @@ off_t Vect_write_line(struct Map_info *, int, const struct line_pnts *,
 off_t Vect_rewrite_line(struct Map_info *, off_t, int, const struct line_pnts *,
 off_t Vect_rewrite_line(struct Map_info *, off_t, int, const struct line_pnts *,
                       const struct line_cats *);
                       const struct line_cats *);
 int Vect_delete_line(struct Map_info *, off_t);
 int Vect_delete_line(struct Map_info *, off_t);
-int Vect_restore_line(struct Map_info *, off_t);
+int Vect_restore_line(struct Map_info *, off_t, off_t);
 
 
 int Vect_get_num_dblinks(const struct Map_info *);
 int Vect_get_num_dblinks(const struct Map_info *);
 
 
@@ -549,8 +549,8 @@ int V1_delete_line_pg(struct Map_info *, off_t);
 int V2_delete_line_nat(struct Map_info *, off_t);
 int V2_delete_line_nat(struct Map_info *, off_t);
 int V2_delete_line_sfa(struct Map_info *, off_t);
 int V2_delete_line_sfa(struct Map_info *, off_t);
 int V2_delete_line_pg(struct Map_info *, off_t);
 int V2_delete_line_pg(struct Map_info *, off_t);
-int V1_restore_line_nat(struct Map_info *, off_t);
-int V2_restore_line_nat(struct Map_info *, off_t);
+int V1_restore_line_nat(struct Map_info *, off_t, off_t);
+int V2_restore_line_nat(struct Map_info *, off_t, off_t);
 off_t V1_write_line_nat(struct Map_info *, int, const struct line_pnts *,
 off_t V1_write_line_nat(struct Map_info *, int, const struct line_pnts *,
                         const struct line_cats *);
                         const struct line_cats *);
 off_t V1_write_line_ogr(struct Map_info *, int, const struct line_pnts *,
 off_t V1_write_line_ogr(struct Map_info *, int, const struct line_pnts *,

+ 2 - 2
lib/python/pygrass/vector/__init__.py

@@ -543,8 +543,8 @@ class VectorTopo(Vector):
     @must_be_open
     @must_be_open
     def restore(self, geo_obj):
     def restore(self, geo_obj):
         if hasattr(geo_obj, 'offset'):
         if hasattr(geo_obj, 'offset'):
-            if libvect.Vect_restore_line(self.c_mapinfo, geo_obj.id,
-                                         geo_obj.offset) == -1:
+            if libvect.Vect_restore_line(self.c_mapinfo, geo_obj.offset,
+                                         geo_obj.id) == -1:
                 raise GrassError("C funtion: Vect_restore_line.")
                 raise GrassError("C funtion: Vect_restore_line.")
         else:
         else:
             raise ValueError("The value have not an offset attribute.")
             raise ValueError("The value have not an offset attribute.")

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

@@ -277,27 +277,27 @@ int Vect_delete_line(struct Map_info *Map, off_t line)
    A warning is printed on error.
    A warning is printed on error.
 
 
    \param Map pointer to Map_info structure
    \param Map pointer to Map_info structure
-   \param line feature id to be restored
-   \param offset feature offset
+   \param offset feature offset to be restored
+   \param line feature id to be restored (used only on level 2)
 
 
    \return 0 on success
    \return 0 on success
    \return -1 on error
    \return -1 on error
  */
  */
-int Vect_restore_line(struct Map_info *Map, off_t line)
+int Vect_restore_line(struct Map_info *Map, off_t offset, off_t line)
 {
 {
     int ret;
     int ret;
 
 
-    G_debug(3, "Vect_restore_line(): name = %s,level = %d, line/offset = %"PRI_OFF_T,
-            Map->name, Map->level, line);
+    G_debug(3, "Vect_restore_line(): name = %s, level = %d, offset = %"PRI_OFF_T", line = %"PRI_OFF_T,
+            Map->name, Map->level, offset, line);
 
 
     if (!check_map(Map))
     if (!check_map(Map))
         return -1;
         return -1;
 
 
-    ret = (*Vect_restore_line_array[Map->format][Map->level]) (Map, line);
+    ret = (*Vect_restore_line_array[Map->format][Map->level]) (Map, offset, line);
 
 
     if (ret == -1)
     if (ret == -1)
-	G_warning(_("Unable to restore feature/offset %lu in vector map <%s>"),
-                  line, Vect_get_name(Map));
+	G_warning(_("Unable to restore feature/offset %"PRI_OFF_T" in vector map <%s>"),
+                  offset, Vect_get_name(Map));
 
 
     return ret;
     return ret;
 }
 }

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

@@ -332,16 +332,17 @@ int V2_delete_line_nat(struct Map_info *Map, off_t line)
   
   
   \param Map pointer to Map_info structure
   \param Map pointer to Map_info structure
   \param offset feature offset
   \param offset feature offset
-  
+  \param line feature id (not used)
+
   \return  0 on success
   \return  0 on success
   \return -1 on error
   \return -1 on error
 */
 */
-int V1_restore_line_nat(struct Map_info *Map, off_t offset)
+int V1_restore_line_nat(struct Map_info *Map, off_t offset, off_t line)
 {
 {
     char rhead;
     char rhead;
     struct gvfile *dig_fp;
     struct gvfile *dig_fp;
     
     
-    G_debug(3, "V1_restore_line_nat(), offset = %"PRI_OFF_T, offset);
+    G_debug(3, "V1_restore_line_nat(): offset = %"PRI_OFF_T", line (not used) = %"PRI_OFF_T, offset, line);
     
     
     dig_set_cur_port(&(Map->head.port));
     dig_set_cur_port(&(Map->head.port));
     dig_fp = &(Map->dig_fp);
     dig_fp = &(Map->dig_fp);
@@ -375,15 +376,15 @@ int V1_restore_line_nat(struct Map_info *Map, off_t offset)
   Note: requires topology level >= GV_BUILD_BASE.
   Note: requires topology level >= GV_BUILD_BASE.
   
   
   \param Map pointer to Map_info structure
   \param Map pointer to Map_info structure
-  \param line feature id
+  \param offset feature offset to be restored
+  \param line feature id to be restored
   
   
   \return 0 on success
   \return 0 on success
   \return -1 on error
   \return -1 on error
 */
 */
-int V2_restore_line_nat(struct Map_info *Map, off_t line)
+int V2_restore_line_nat(struct Map_info *Map, off_t offset, off_t line)
 {
 {
     int type;
     int type;
-    off_t offset;
     struct Plus_head *plus;
     struct Plus_head *plus;
     struct P_line *Line;
     struct P_line *Line;
     static struct line_cats *Cats = NULL;
     static struct line_cats *Cats = NULL;
@@ -391,14 +392,14 @@ int V2_restore_line_nat(struct Map_info *Map, off_t line)
     
     
     plus = &(Map->plus);
     plus = &(Map->plus);
 
 
-    G_debug(3, "V2_restore_line_nat(), line = %d", (int)line);
+    G_debug(3, "V2_restore_line_nat(): offset = %"PRI_OFF_T", line = %"PRI_OFF_T, offset, line);
 
 
     if (line < 1 || line > plus->n_lines) {
     if (line < 1 || line > plus->n_lines) {
-        G_warning(_("Attempt to access feature with invalid id (%d)"), (int)line);
+        G_warning(_("Attempt to access feature with invalid id (%"PRI_OFF_T")"), line);
         return -1;
         return -1;
     }
     }
     
     
-    Line = Map->plus.Line[line];
+    Line = Map->plus.Line[line]; /* we expect Line to be NULL, so offset is needed */
     if (Line != NULL) {
     if (Line != NULL) {
         G_warning(_("Attempt to access alive feature %d"), (int)line);
         G_warning(_("Attempt to access alive feature %d"), (int)line);
         return -1;
         return -1;
@@ -408,10 +409,8 @@ int V2_restore_line_nat(struct Map_info *Map, off_t line)
 	plus->cidx_up_to_date = 0;
 	plus->cidx_up_to_date = 0;
     }
     }
 
 
-    offset = Line->offset;
-    
     /* restore feature in 'coor' file */
     /* restore feature in 'coor' file */
-    if (0 != V1_restore_line_nat(Map, offset))
+    if (0 != V1_restore_line_nat(Map, offset, line))
 	return -1;
 	return -1;
 
 
     /* read feature geometry */    
     /* read feature geometry */    
@@ -859,9 +858,10 @@ int V2__delete_line_from_topo_nat(struct Map_info *Map, int line, int type,
     Note that 1) and 2) is done by the same code.
     Note that 1) and 2) is done by the same code.
 
 
     \param Map pointer to Map_info structure
     \param Map pointer to Map_info structure
-    \param line feature id to be added
+    \param offset feature offset to be added
     \param points pointer to line_pnts structure (feature's geometry)
     \param points pointer to line_pnts structure (feature's geometry)
     \param cats pointer to line_cats structure (feature's categories)
     \param cats pointer to line_cats structure (feature's categories)
+    \param restore_line feature id to be restored (>0) or added (<=0)
     \param external_routine pointer to external routine (used by PostGIS Topology)
     \param external_routine pointer to external routine (used by PostGIS Topology)
 
 
     \return feature id to be added
     \return feature id to be added