Browse Source

vlib: add V2__delete_line_topo_nat()
update V2__add_line_topo_nat()
add extra checks (invalid line id) + update doxygen (note required build level)
various minor issue


git-svn-id: https://svn.osgeo.org/grass/grass/trunk@55582 15284696-431f-4ddb-bdfa-cd5b030d7da7

Martin Landa 12 năm trước cách đây
mục cha
commit
955ec9ab4c

+ 12 - 21
lib/vector/Vlib/bridges.c

@@ -28,9 +28,8 @@ static int cmp_int(const void *a, const void *b)
     return (*ai < *bi ? -1 : (*ai > *bi));
     return (*ai < *bi ? -1 : (*ai > *bi));
 }
 }
 
 
-static void
-remove_bridges(struct Map_info *Map, int chtype, struct Map_info *Err, 
-               int *lrm, int *brm);
+static void remove_bridges(struct Map_info *Map, int chtype, struct Map_info *Err, 
+                           int *lrm, int *brm);
 
 
 /*!
 /*!
    \brief Remove bridges from vector map.
    \brief Remove bridges from vector map.
@@ -45,12 +44,9 @@ remove_bridges(struct Map_info *Map, int chtype, struct Map_info *Err,
    \param Err vector map where deleted bridges are written or NULL
    \param Err vector map where deleted bridges are written or NULL
    \param lines_removed number of lines removed
    \param lines_removed number of lines removed
    \param bridges_removed Err number of bridges removed
    \param bridges_removed Err number of bridges removed
-
-   \return
- */
-void
-Vect_remove_bridges(struct Map_info *Map, struct Map_info *Err,
-                    int *lines_removed, int *bridges_removed)
+*/
+void Vect_remove_bridges(struct Map_info *Map, struct Map_info *Err,
+                         int *lines_removed, int *bridges_removed)
 {
 {
     remove_bridges(Map, 0, Err, lines_removed, bridges_removed);
     remove_bridges(Map, 0, Err, lines_removed, bridges_removed);
 }
 }
@@ -69,12 +65,8 @@ Vect_remove_bridges(struct Map_info *Map, struct Map_info *Err,
    \param Err vector map where changed bridges are written or NULL
    \param Err vector map where changed bridges are written or NULL
    \param lines_changed number of lines changed
    \param lines_changed number of lines changed
    \param bridges_changed Err number of bridges changed
    \param bridges_changed Err number of bridges changed
-
-   \return
- */
-
-void
-Vect_chtype_bridges(struct Map_info *Map, struct Map_info *Err,
+*/
+void Vect_chtype_bridges(struct Map_info *Map, struct Map_info *Err,
                     int *lines_changed, int *bridges_changed)
                     int *lines_changed, int *bridges_changed)
 {
 {
     remove_bridges(Map, 1, Err, lines_changed, bridges_changed);
     remove_bridges(Map, 1, Err, lines_changed, bridges_changed);
@@ -93,11 +85,10 @@ Vect_chtype_bridges(struct Map_info *Map, struct Map_info *Err,
 
 
    List of all lines in chain is created during the cycle.
    List of all lines in chain is created during the cycle.
  */
  */
-void
-remove_bridges(struct Map_info *Map, int chtype, struct Map_info *Err,
-               int *lrm, int *brm)
+void remove_bridges(struct Map_info *Map, int chtype, struct Map_info *Err,
+                    int *lrm, int *brm)
 {
 {
-    int i, type, nlines, line, *bline;
+    int type, nlines, line, *bline;
     int left, right, node1, node2, current_line, next_line, abs_line;
     int left, right, node1, node2, current_line, next_line, abs_line;
     int bridges_removed = 0;	/* number of removed bridges */
     int bridges_removed = 0;	/* number of removed bridges */
     int lines_removed = 0;	/* number of lines removed */
     int lines_removed = 0;	/* number of lines removed */
@@ -219,6 +210,6 @@ remove_bridges(struct Map_info *Map, int chtype, struct Map_info *Err,
     if (brm)
     if (brm)
 	*brm = bridges_removed;
 	*brm = bridges_removed;
 
 
-    G_verbose_message("Removed lines: %d", lines_removed);
-    G_verbose_message("Removed bridges: %d", bridges_removed);
+    G_verbose_message(_("Removed lines: %d"), lines_removed);
+    G_verbose_message(_("Removed bridges: %d"), bridges_removed);
 }
 }

+ 9 - 3
lib/vector/Vlib/local_proto.h

@@ -3,9 +3,8 @@
 
 
 #include <grass/vector.h>
 #include <grass/vector.h>
 
 
-void V2__add_line_to_topo_nat(struct Map_info *, int ,
-                              const struct line_pnts *, const struct line_cats *,
-                              int (*external_routine) (const struct Map_info *, int));
+/* Internal vector library subroutines which are not part of public
+   API*/
 
 
 /* map.c */
 /* map.c */
 int Vect__delete(const char *, int);
 int Vect__delete(const char *, int);
@@ -16,4 +15,11 @@ int Vect__open_old(struct Map_info *, const char *, const char *,
 char *Vect__get_path(const struct Map_info *);
 char *Vect__get_path(const struct Map_info *);
 char *Vect__get_element_path(const struct Map_info *, const char *);
 char *Vect__get_element_path(const struct Map_info *, const char *);
 
 
+/* write_nat.c */
+int V2__add_line_to_topo_nat(struct Map_info *, off_t, int,
+                             const struct line_pnts *, const struct line_cats *, int,
+                             int (*external_routine) (const struct Map_info *, int));
+int V2__delete_line_from_topo_nat(struct Map_info *, int, int,
+                                  const struct line_pnts *, const struct line_cats *);
+
 #endif /* PG_LOCAL_PROTO_H__ */
 #endif /* PG_LOCAL_PROTO_H__ */

+ 2 - 1
lib/vector/Vlib/open.c

@@ -782,6 +782,8 @@ int open_new(struct Map_info *Map, const char *name, int with_z, int is_tmp)
     /* set 2D/3D */
     /* set 2D/3D */
     Map->plus.spidx_with_z = Map->plus.with_z = Map->head.with_z = (with_z != 0);
     Map->plus.spidx_with_z = Map->plus.with_z = Map->head.with_z = (with_z != 0);
 
 
+    Map->level = LEVEL_1;
+    
     if ((*Open_new_array[Map->format][1]) (Map, name, with_z) < 0) {
     if ((*Open_new_array[Map->format][1]) (Map, name, with_z) < 0) {
         if (getenv("GRASS_VECTOR_PGFILE") == NULL)  /* GRASS_VECTOR_PGFILE defined by v.out.postgis */
         if (getenv("GRASS_VECTOR_PGFILE") == NULL)  /* GRASS_VECTOR_PGFILE defined by v.out.postgis */
             Vect_delete(name); /* clean up */
             Vect_delete(name); /* clean up */
@@ -798,7 +800,6 @@ int open_new(struct Map_info *Map, const char *name, int with_z, int is_tmp)
     Vect_open_sidx(Map, 2);
     Vect_open_sidx(Map, 2);
 
 
     Map->open = VECT_OPEN_CODE;
     Map->open = VECT_OPEN_CODE;
-    Map->level = 1;
     Map->head_only = FALSE;
     Map->head_only = FALSE;
     Map->support_updated = FALSE;
     Map->support_updated = FALSE;
     Map->plus.built = GV_BUILD_NONE;
     Map->plus.built = GV_BUILD_NONE;

+ 73 - 42
lib/vector/Vlib/read.c

@@ -5,7 +5,7 @@
 
 
    Higher level functions for reading/writing/manipulating vectors.
    Higher level functions for reading/writing/manipulating vectors.
 
 
-   (C) 2001-2009, 2011 by the GRASS Development Team
+   (C) 2001-2009, 2011-2013 by the GRASS Development Team
 
 
    This program is free software under the GNU General Public License
    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.
@@ -83,13 +83,16 @@ static int (*Read_line_array[]) () = {
   \param Map pointer to Map_info struct
   \param Map pointer to Map_info struct
 
 
   \return feature id
   \return feature id
+  \return -1 on error
 */
 */
 int Vect_get_next_line_id(const struct Map_info *Map)
 int Vect_get_next_line_id(const struct Map_info *Map)
 {
 {
     G_debug(3, "Vect_get_next_line()");
     G_debug(3, "Vect_get_next_line()");
 
 
-    if (!VECT_OPEN(Map))
-	G_fatal_error(_("Vector map is not open for reading"));
+    if (!VECT_OPEN(Map)) {
+	G_warning(_("Vector map is not open for reading"));
+        return -1;
+    }
     
     
     return Map->next_line - 1;
     return Map->next_line - 1;
 }
 }
@@ -99,17 +102,17 @@ int Vect_get_next_line_id(const struct Map_info *Map)
 
 
    This function implements sequential access, constraints are
    This function implements sequential access, constraints are
    reflected, see Vect_set_constraint_region(),
    reflected, see Vect_set_constraint_region(),
-   Vect_set_constraint_type(), or Vect_set_constraint_field().
+   Vect_set_constraint_type(), or Vect_set_constraint_field() for
+   details.
      
      
-   Use Vect_rewind() to reset reading.
+   Use Vect_rewind() to reset reading. Topological level is not
+   required.
 
 
-   G_fatal_error() is called on failure.
+   A warning is printed on failure.
    
    
    \param Map pointer Map_info struct
    \param Map pointer Map_info struct
-   \param[out] line_p feature geometry
-   (pointer to line_pnts struct)
-   \param[out] line_c feature categories
-   (pointer to line_cats struct)
+   \param[out] line_p feature geometry (pointer to line_pnts struct)
+   \param[out] line_c feature categories (pointer to line_cats struct)
 
 
    \return feature type (GV_POINT, GV_LINE, ...)
    \return feature type (GV_POINT, GV_LINE, ...)
    \return -1 on error
    \return -1 on error
@@ -122,32 +125,32 @@ int Vect_read_next_line(const struct Map_info *Map,
     
     
     G_debug(3, "Vect_read_next_line(): next_line = %d", Map->next_line);
     G_debug(3, "Vect_read_next_line(): next_line = %d", Map->next_line);
 
 
-    if (!VECT_OPEN(Map))
-	G_fatal_error(_("Vector map is not open for reading"));
+    if (!VECT_OPEN(Map)) {
+	G_warning(_("Vector map is not open for reading"));
+        return -1;
+    }
     
     
     ret = (*Read_next_line_array[Map->format][Map->level]) (Map, line_p,
     ret = (*Read_next_line_array[Map->format][Map->level]) (Map, line_p,
 							    line_c);
 							    line_c);
-    /* 
     if (ret == -1)
     if (ret == -1)
-	G_fatal_error(_("Unable to read feature %d vector map <%s>"),
-		      Map->next_line, Vect_get_full_name(Map));
-    */
+        G_warning(_("Unable to read feature %d from vector map <%s>"),
+                  Map->next_line, Vect_get_full_name(Map));
+    
     return ret;
     return ret;
 }
 }
 
 
 /*!
 /*!
-   \brief Read vector feature
+   \brief Read vector feature (topological level required)
 
 
-   This function implements random access. Note that constraits are
-   ignored!
+   This function implements random access. Constraits are ignored.
 
 
-   G_fatal_error() is called on failure.
+   Note: Topology must be built at level >= GV_BUILD_BASE
+
+   A warning is printed on failure.
    
    
    \param Map pointer to vector map
    \param Map pointer to vector map
-   \param[out] line_p feature geometry
-   (pointer to line_pnts struct)
-   \param[out] line_c feature categories
-   (pointer to line_cats struct)
+   \param[out] line_p feature geometry (pointer to line_pnts struct)
+   \param[out] line_c feature categories (pointer to line_cats struct)
    \param line feature id (starts at 1)
    \param line feature id (starts at 1)
    
    
    \return feature type
    \return feature type
@@ -161,35 +164,43 @@ int Vect_read_line(const struct Map_info *Map,
     
     
     G_debug(3, "Vect_read_line(): line = %d", line);
     G_debug(3, "Vect_read_line(): line = %d", line);
 
 
-    if (!VECT_OPEN(Map))
-	G_fatal_error(_("Vector map is not open for reading"));
-
-    if (line < 1 || line > Map->plus.n_lines)
-	G_fatal_error(_("Requested feature id %d is not reasonable"
-			"(max features in vector map <%s>: %d)"),
-		      line, Vect_get_full_name(Map), Map->plus.n_lines);
-
+    if (!VECT_OPEN(Map)) {
+	G_warning(_("Vector map is not open for reading"));
+        return -1;
+    }
+    
+    if (line < 1 || line > Map->plus.n_lines) {
+        G_warning(_("Attempt to access feature with invalid id (%d)"), line);
+        return -1;
+    }
+    
     ret = (*Read_line_array[Map->format]) (Map, line_p, line_c, line);
     ret = (*Read_line_array[Map->format]) (Map, line_p, line_c, line);
 
 
-    /*
     if (ret == -1)
     if (ret == -1)
-	G_fatal_error(_("Unable to read feature %d from vector map <%s>"),
-		      line, Vect_get_full_name(Map));
-    */
+	G_warning(_("Unable to read feature %d from vector map <%s>"),
+                  line, Vect_get_full_name(Map));
+    
     return ret;
     return ret;
 }
 }
 
 
 /*!
 /*!
-  \brief Check if feature is alive or dead (level 2 required)
+  \brief Check if feature is alive or dead (topological level required)
   
   
+  Note: Topology must be built at level >= GV_BUILD_BASE
+
   \param Map pointer to Map_info structure
   \param Map pointer to Map_info structure
   \param line feature id
   \param line feature id
   
   
   \return 1 feature alive
   \return 1 feature alive
   \return 0 feature is dead
   \return 0 feature is dead
+  \return -1 on error
  */
  */
 int Vect_line_alive(const struct Map_info *Map, int line)
 int Vect_line_alive(const struct Map_info *Map, int line)
 {
 {
+    if (line < 1 || line > Map->plus.n_lines) {
+        return -1;
+    }
+
     if (Map->plus.Line[line] != NULL)
     if (Map->plus.Line[line] != NULL)
 	return 1;
 	return 1;
     
     
@@ -197,8 +208,10 @@ int Vect_line_alive(const struct Map_info *Map, int line)
 }
 }
 
 
 /*!
 /*!
-  \brief Check if node is alive or dead (level 2 required)
+  \brief Check if node is alive or dead (topological level required)
   
   
+  Note: Topology must be built at level >= GV_BUILD_BASE
+
   \param Map pointer to Map_info structure
   \param Map pointer to Map_info structure
   \param node node id
   \param node node id
   
   
@@ -207,6 +220,10 @@ int Vect_line_alive(const struct Map_info *Map, int line)
  */
  */
 int Vect_node_alive(const struct Map_info *Map, int node)
 int Vect_node_alive(const struct Map_info *Map, int node)
 {
 {
+    if (node < 1 || node > Map->plus.n_nodes) {
+        return -1;
+    }
+
     if (Map->plus.Node[node] != NULL)
     if (Map->plus.Node[node] != NULL)
 	return 1;
 	return 1;
 
 
@@ -214,16 +231,22 @@ int Vect_node_alive(const struct Map_info *Map, int node)
 }
 }
 
 
 /*!
 /*!
-  \brief Check if area is alive or dead (level 2 required)
+  \brief Check if area is alive or dead (topological level required)
   
   
+  Note: Topology must be built at level >= GV_BUILD_AREAS
+
   \param Map pointer to Map_info structure
   \param Map pointer to Map_info structure
   \param area area id
   \param area area id
   
   
   \return 1 area alive
   \return 1 area alive
   \return 0 area is dead
   \return 0 area is dead
+  \return -1 on error
 */
 */
 int Vect_area_alive(const struct Map_info *Map, int area)
 int Vect_area_alive(const struct Map_info *Map, int area)
 {
 {
+    if (area < 1 || area > Map->plus.n_areas)
+        return -1;
+    
     if (Map->plus.Area[area] != NULL)
     if (Map->plus.Area[area] != NULL)
 	return 1;
 	return 1;
 
 
@@ -231,8 +254,10 @@ int Vect_area_alive(const struct Map_info *Map, int area)
 }
 }
 
 
 /*!
 /*!
-  \brief Check if isle is alive or dead (level 2 required)
+  \brief Check if isle is alive or dead (topological level required)
 
 
+  Note: Topology must be built at level >= GV_BUILD_AREAS
+  
   \param Map pointer to Map_info structure
   \param Map pointer to Map_info structure
   \param isle isle id
   \param isle isle id
   
   
@@ -241,6 +266,9 @@ int Vect_area_alive(const struct Map_info *Map, int area)
 */
 */
 int Vect_isle_alive(const struct Map_info *Map, int isle)
 int Vect_isle_alive(const struct Map_info *Map, int isle)
 {
 {
+    if (isle < 1 || isle > Map->plus.n_isles)
+        return -1;
+
     if (Map->plus.Isle[isle] != NULL)
     if (Map->plus.Isle[isle] != NULL)
 	return 1;
 	return 1;
 
 
@@ -248,7 +276,9 @@ int Vect_isle_alive(const struct Map_info *Map, int isle)
 }
 }
 
 
 /*!
 /*!
-  \brief Get feature offset
+  \brief Get feature offset (topological level required)
+  
+  Note: Topology must be built at level >= GV_BUILD_BASE
   
   
   Used for Vect_restore_line().
   Used for Vect_restore_line().
   
   
@@ -260,8 +290,9 @@ int Vect_isle_alive(const struct Map_info *Map, int isle)
 */
 */
 off_t Vect_get_line_offset(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)
+    if (line < 1 || line > Map->plus.n_lines) {
 	return -1;
 	return -1;
+    }
     
     
     if (Map->plus.Line[line] != NULL) {
     if (Map->plus.Line[line] != NULL) {
 	return Map->plus.Line[line]->offset;
 	return Map->plus.Line[line]->offset;

+ 10 - 6
lib/vector/Vlib/read_nat.c

@@ -122,11 +122,11 @@ int V1_read_next_line_nat(struct Map_info *Map,
   This function implements random access for native format,
   This function implements random access for native format,
   constraints are ignored!
   constraints are ignored!
   
   
+  Note: Topology must be built at level >= GV_BUILD_BASE
+  
   \param Map pointer to Map_info struct 
   \param Map pointer to Map_info struct 
-  \param[out] Points container used to store line points within
-  (pointer to line_pnts struct)
-  \param[out] Cats container used to store line categories within
-  (pointer to line_cats struct)
+  \param[out] Points container used to store line points within (pointer to line_pnts struct)
+  \param[out] Cats container used to store line categories within (pointer to line_cats struct)
   \param line feature id to read (starts at 1)
   \param line feature id to read (starts at 1)
   
   
   \return feature type (GV_POINT, GV_LINE, ...)
   \return feature type (GV_POINT, GV_LINE, ...)
@@ -140,10 +140,14 @@ int V2_read_line_nat(struct Map_info *Map,
 
 
     G_debug(3, "V2_read_line_nat(): line = %d", line);
     G_debug(3, "V2_read_line_nat(): line = %d", line);
 
 
+    if (line < 1 || line > Map->plus.n_lines) {
+        G_warning(_("Attempt to access feature with invalid id (%d)"), line);
+        return -1;
+    }
+    
     Line = Map->plus.Line[line];
     Line = Map->plus.Line[line];
-
     if (Line == NULL) {
     if (Line == NULL) {
-	G_warning(_("Attempt to read dead feature %d"), line);
+	G_warning(_("Attempt to access dead feature %d"), line);
 	return -1;
 	return -1;
     }
     }
 
 

+ 13 - 4
lib/vector/Vlib/read_sfa.c

@@ -24,6 +24,8 @@
  
  
   This function implements random access on level 2.
   This function implements random access on level 2.
   
   
+  Note: Topology must be built at level >= GV_BUILD_BASE
+  
   \param Map pointer to Map_info structure
   \param Map pointer to Map_info structure
   \param[out] line_p container used to store line points within
   \param[out] line_p container used to store line points within
   (pointer to line_pnts struct)
   (pointer to line_pnts struct)
@@ -44,9 +46,14 @@ int V2_read_line_sfa(struct Map_info *Map, struct line_pnts *line_p,
     
     
     G_debug(4, "V2_read_line_sfa() line = %d", line);
     G_debug(4, "V2_read_line_sfa() line = %d", line);
     
     
+    if (line < 1 || line > Map->plus.n_lines) {
+        G_warning(_("Attempt to access feature with invalid id (%d)"), line);
+        return -1;
+    }
+
     Line = Map->plus.Line[line];
     Line = Map->plus.Line[line];
     if (Line == NULL) {
     if (Line == NULL) {
-        G_warning(_("Attempt to read dead feature %d"), line);
+        G_warning(_("Attempt to access dead feature %d"), line);
         return -1;
         return -1;
     }
     }
     
     
@@ -106,9 +113,11 @@ int V2_read_line_sfa(struct Map_info *Map, struct line_pnts *line_p,
     else
     else
         type = V1_read_line_ogr(Map, line_p, line_c, Line->offset);
         type = V1_read_line_ogr(Map, line_p, line_c, Line->offset);
 
 
-    if (type != Line->type)
-        G_fatal_error(_("Unexpected feature type (%d) - should be (%d)"),
-                      type, Line->type);
+    if (type != Line->type) {
+        G_warning(_("Unexpected feature type (%d) - should be (%d)"),
+                  type, Line->type);
+        return -1;
+    }
 
 
     return type;
     return type;
 #else
 #else

+ 90 - 72
lib/vector/Vlib/write.c

@@ -5,20 +5,19 @@
 
 
    Higher level functions for reading/writing/manipulating vectors.
    Higher level functions for reading/writing/manipulating vectors.
 
 
-   Operations:
-    - Write new feature
-    - Rewrite feature
-    - Delete feature
+   Supported operations:
+    - Write a new feature
+    - Rewrite existing feature
+    - Delete existing feature
     - Restore deleted feature
     - Restore deleted feature
 
 
-   (C) 2001-2010, 2012 by the GRASS Development Team
+   (C) 2001-2010, 2012-2013 by the GRASS Development Team
 
 
    This program is free software under the GNU General Public License
    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 Radim Blazek
    \author Radim Blazek
-   \author Updated by Martin Landa <landa.martin gmail.com>
-   (restore lines, OGR & PostGIS support)
+   \author Updated by Martin Landa <landa.martin gmail.com> (restore lines, OGR & PostGIS support)
  */
  */
 
 
 #include <sys/types.h>
 #include <sys/types.h>
@@ -104,7 +103,7 @@ static off_t (*Vect_rewrite_line_array[][3]) () = {
 #endif
 #endif
 #ifdef HAVE_POSTGRES
 #ifdef HAVE_POSTGRES
     , {
     , {
-	rewrite_dummy, V1_rewrite_line_pg, V2_rewrite_line_sfa}
+	rewrite_dummy, V1_rewrite_line_pg, V2_rewrite_line_pg}
 #else
 #else
     , {
     , {
 	rewrite_dummy, format_l, format_l}
 	rewrite_dummy, format_l, format_l}
@@ -127,7 +126,7 @@ static int (*Vect_delete_line_array[][3]) () = {
 #endif
 #endif
 #ifdef HAVE_POSTGRES
 #ifdef HAVE_POSTGRES
     , {
     , {
-	delete_dummy, V1_delete_line_pg, V2_delete_line_sfa}
+	delete_dummy, V1_delete_line_pg, V2_delete_line_pg}
 #else
 #else
     , {
     , {
 	delete_dummy, format, format}
 	delete_dummy, format, format}
@@ -157,20 +156,22 @@ static int (*Vect_restore_line_array[][3]) () = {
 #endif
 #endif
 };
 };
 
 
+static int check_map(const struct Map_info *);
+
 /*!
 /*!
-   \brief Writes new feature
+   \brief Writes a new feature
 
 
    New feature is written to the end of file (in the case of native
    New feature is written to the end of file (in the case of native
-   format). Vector map topology is not required.
+   format). Topological level is not required.
 
 
-   Calls G_fatal_error() when vector map is not opened.
+   A warning is printed on error.
    
    
    \param Map pointer to Map_info structure
    \param Map pointer to Map_info structure
    \param type feature type (see dig_defines.h for supported types)
    \param type feature type (see dig_defines.h for supported types)
-   \param points ointer to line_pnts structure (feature geometry)
+   \param points pointer to line_pnts structure (feature geometry)
    \param cats pointer to line_cats structure (feature categories)
    \param cats pointer to line_cats structure (feature categories)
 
 
-   \return new feature id (on level 2)
+   \return new feature id (on level 2) (or 0 when build level < GV_BUILD_BASE)
    \return offset into file where the feature starts (on level 1)
    \return offset into file where the feature starts (on level 1)
    \return -1 on error
    \return -1 on error
  */
  */
@@ -182,44 +183,42 @@ off_t Vect_write_line(struct Map_info *Map, int type,
     G_debug(3, "Vect_write_line(): name = %s, format = %d, level = %d",
     G_debug(3, "Vect_write_line(): name = %s, format = %d, level = %d",
 	    Map->name, Map->format, Map->level);
 	    Map->name, Map->format, Map->level);
 
 
-    if (!VECT_OPEN(Map))
-	G_fatal_error(_("Unable to write feature, vector map is not opened"));
-
+    if (!VECT_OPEN(Map)) {
+	G_warning(_("Vector map <%s> is not opened"), Vect_get_name(Map));
+        return -1;
+    }
+    
     if (!(Map->plus.update_cidx)) {
     if (!(Map->plus.update_cidx)) {
-	Map->plus.cidx_up_to_date = FALSE;
+	Map->plus.cidx_up_to_date = FALSE; /* category index will be outdated */
     }
     }
 
 
     offset = 
     offset = 
 	(*Vect_write_line_array[Map->format][Map->level]) (Map, type, points,
 	(*Vect_write_line_array[Map->format][Map->level]) (Map, type, points,
 							   cats);
 							   cats);
     
     
-    /*
-    if (offset == -1)
-	G_fatal_error(_("Unable to write feature (negative offset)"));
-    */
+    if (offset < 0)
+	G_warning(_("Unable to write feature in vector map <%s>"), Vect_get_name(Map));
     
     
-    /* note: returns new feature id on level 2 and file offset on
-       level 1 */
     return offset;
     return offset;
 }
 }
 
 
 /*!
 /*!
-   \brief Rewrites feature info at the given offset.
+   \brief Rewrites existing feature (topological level required)
 
 
-   Vector map must be opened with full topology (level 2).
+   Note: Topology must be built at level >= GV_BUILD_BASE
+   
+   A warning is printed on error.
 
 
    The number of points or cats or type may change. If necessary, the
    The number of points or cats or type may change. If necessary, the
    old feature 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 Map_info structure
    \param Map pointer to Map_info structure
    \param line feature id
    \param line feature id
    \param type feature type (GV_POINT, GV_LINE, ...)
    \param type feature type (GV_POINT, GV_LINE, ...)
    \param points feature geometry
    \param points feature geometry
    \param cats feature categories
    \param cats feature categories
 
 
-   \return feature offset
+   \return new feature offset
    \return -1 on error
    \return -1 on error
  */
  */
 off_t Vect_rewrite_line(struct Map_info *Map, int line, int type,
 off_t Vect_rewrite_line(struct Map_info *Map, int line, int type,
@@ -227,32 +226,38 @@ off_t Vect_rewrite_line(struct Map_info *Map, int line, int type,
 {
 {
     off_t ret, offset;
     off_t ret, offset;
     
     
-    if (!VECT_OPEN(Map))
-	G_fatal_error(_("Unable to rewrite feature, vector map is not opened"));
+    if (!check_map(Map))
+        return -1;
 
 
+    if (line < 1 || line > Map->plus.n_lines) {
+        G_warning(_("Attempt to access feature with invalid id (%d)"), line);
+        return -1;
+    }
+    
     if (!(Map->plus.update_cidx)) {
     if (!(Map->plus.update_cidx)) {
-	Map->plus.cidx_up_to_date = FALSE;
+	Map->plus.cidx_up_to_date = FALSE; /* category index will be outdated */
     }
     }
 
 
     offset = Map->plus.Line[line]->offset;
     offset = Map->plus.Line[line]->offset;
-    G_debug(3, "Vect_rewrite_line(): name = %s, line = %d offset = %lu",
+    
+    G_debug(3, "Vect_rewrite_line(): name = %s, line = %d, offset = %lu",
 	    Map->name, line, offset);
 	    Map->name, line, offset);
+    
     ret = (*Vect_rewrite_line_array[Map->format][Map->level]) (Map, line, type,
     ret = (*Vect_rewrite_line_array[Map->format][Map->level]) (Map, line, type,
 							       offset,
 							       offset,
 							       points, cats);
 							       points, cats);
-    /*
     if (ret == -1)
     if (ret == -1)
-	G_fatal_error(_("Unable to rewrite feature %d"), line);
-    */
+        G_warning(_("Unable to rewrite feature %d in vector map <%s>"), line, Vect_get_name(Map));
+
     return ret;
     return ret;
 }
 }
 
 
 /*!
 /*!
-   \brief Delete feature
-
-   Vector map must be opened with full topology (level 2).
+   \brief Delete existing feature (topological level required)
 
 
-   This function calls G_fatal_error() on error.
+   Note: Topology must be built at level >= GV_BUILD_BASE
+   
+   A warning is printed on error.
 
 
    \param Map pointer to Map_info structure
    \param Map pointer to Map_info structure
    \param line feature id
    \param line feature id
@@ -266,41 +271,37 @@ int Vect_delete_line(struct Map_info *Map, int line)
 
 
     G_debug(3, "Vect_delete_line(): name = %s, line = %d", Map->name, line);
     G_debug(3, "Vect_delete_line(): name = %s, line = %d", Map->name, line);
 
 
-    if (Map->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 feature %d, "
-			"vector map <%s> is not opened in 'write' mode"),
-		      line, Map->name);
+    if (!check_map(Map))
+        return -1;
+    
+    if (line < 1 || line > Map->plus.n_lines) {
+        G_warning(_("Attempt to access feature with invalid id (%d)"), line);
+        return -1;
     }
     }
 
 
     if (!(Map->plus.update_cidx)) {
     if (!(Map->plus.update_cidx)) {
-	Map->plus.cidx_up_to_date = FALSE;
+	Map->plus.cidx_up_to_date = FALSE; /* category index will be outdated */
     }
     }
 
 
     ret = (*Vect_delete_line_array[Map->format][Map->level]) (Map, line);
     ret = (*Vect_delete_line_array[Map->format][Map->level]) (Map, line);
 
 
-    /*
     if (ret == -1)
     if (ret == -1)
-	G_fatal_error(_("Unable to delete feature id %d from vector map <%s>"),
-		      line, Vect_get_full_name(Map));
-    */
+	G_warning(_("Unable to delete feature %d from vector map <%s>"),
+                  line, Vect_get_name(Map));
+
     return ret;
     return ret;
 }
 }
 
 
 /*!
 /*!
-   \brief Restore previously deleted feature
-
-   Vector map must be opened with full topology (level 2).
+   \brief Restore previously deleted feature (topological level required)
 
 
-   This function calls G_fatal_error() on error.
+   Note: Topology must be built at level >= GV_BUILD_BASE
+   
+   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 line feature id to be restored
+   \param offset feature offset
 
 
    \return 0 on success
    \return 0 on success
    \return -1 on error
    \return -1 on error
@@ -311,16 +312,12 @@ int Vect_restore_line(struct Map_info *Map, int line, off_t offset)
 
 
     G_debug(3, "Vect_restore_line(): name = %s, line = %d", Map->name, line);
     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 (!check_map(Map))
+        return -1;
 
 
-    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);
+    if (line < 1 || line > Map->plus.n_lines) {
+        G_warning(_("Attempt to access feature with invalid id (%d)"), line);
+        return -1;
     }
     }
 
 
     if (!(Map->plus.update_cidx)) {
     if (!(Map->plus.update_cidx)) {
@@ -329,10 +326,31 @@ int Vect_restore_line(struct Map_info *Map, int line, off_t offset)
 
 
     ret = (*Vect_restore_line_array[Map->format][Map->level]) (Map, line, offset);
     ret = (*Vect_restore_line_array[Map->format][Map->level]) (Map, line, offset);
 
 
-    /*
     if (ret == -1)
     if (ret == -1)
-	G_fatal_error(_("Unable to restore feature %d from vector map <%s>"),
-		      line, Map->name);
-    */
+	G_warning(_("Unable to restore feature %d in vector map <%s>"),
+                  line, Vect_get_name(Map));
+
     return ret;
     return ret;
 }
 }
+
+int check_map(const struct Map_info *Map)
+{
+    if (!VECT_OPEN(Map)) {
+	G_warning(_("Vector map <%s> is not opened"), Vect_get_name(Map));
+        return 0;
+    }
+    
+    if (Map->level < 2) {
+	G_warning(_("Vector map <%s> is not opened on topology level"),
+                  Vect_get_name(Map));
+        return 0;
+    }
+
+    if (Map->mode != GV_MODE_RW && Map->mode != GV_MODE_WRITE) {
+	G_warning(_("Vector map <%s> is not opened in write mode"),
+                  Vect_get_name(Map));
+        return 0;
+    }
+    
+    return 1;
+}

Những thai đổi đã bị hủy bỏ vì nó quá lớn
+ 617 - 581
lib/vector/Vlib/write_nat.c


+ 21 - 4
lib/vector/Vlib/write_sfa.c

@@ -126,7 +126,9 @@ off_t V2_write_line_sfa(struct Map_info *Map, int type,
 /*!
 /*!
   \brief Rewrites feature at the given offset on level 2 (OGR/PostGIS
   \brief Rewrites feature at the given offset on level 2 (OGR/PostGIS
   interface, pseudo-topological level)
   interface, pseudo-topological level)
-  
+
+  Note: Topology must be built at level >= GV_BUILD_BASE
+
   \param Map pointer to Map_info structure
   \param Map pointer to Map_info structure
   \param line feature id to be rewritten
   \param line feature id to be rewritten
   \param type feature type (see V1_write_line_ogr() for supported types)
   \param type feature type (see V1_write_line_ogr() for supported types)
@@ -143,13 +145,19 @@ off_t V2_rewrite_line_sfa(struct Map_info *Map, int line, int type, off_t offset
     G_debug(3, "V2_rewrite_line_sfa(): line=%d type=%d offset=%lu",
     G_debug(3, "V2_rewrite_line_sfa(): line=%d type=%d offset=%lu",
 	    line, type, offset);
 	    line, type, offset);
 
 
+    if (line < 1 || line > Map->plus.n_lines) {
+        G_warning(_("Attempt to access feature with invalid id (%d)"), line);
+        return -1;
+    }
+
 #if defined HAVE_OGR || defined HAVE_POSTGRES
 #if defined HAVE_OGR || defined HAVE_POSTGRES
     if (type != V2_read_line_sfa(Map, NULL, NULL, line)) {
     if (type != V2_read_line_sfa(Map, NULL, NULL, line)) {
 	G_warning(_("Unable to rewrite feature (incompatible feature types)"));
 	G_warning(_("Unable to rewrite feature (incompatible feature types)"));
 	return -1;
 	return -1;
     }
     }
 
 
-    V2_delete_line_sfa(Map, line);
+    if (V2_delete_line_sfa(Map, line) != 0)
+        return -1;
 
 
     return V2_write_line_sfa(Map, type, points, cats);
     return V2_write_line_sfa(Map, type, points, cats);
 #else
 #else
@@ -160,6 +168,8 @@ off_t V2_rewrite_line_sfa(struct Map_info *Map, int line, int type, off_t offset
 
 
 /*!
 /*!
   \brief Deletes feature on level 2 (OGR/PostGIS interface)
   \brief Deletes feature on level 2 (OGR/PostGIS interface)
+
+  Note: Topology must be built at level >= GV_BUILD_BASE
   
   
   \todo Update fidx
   \todo Update fidx
   
   
@@ -178,12 +188,17 @@ int V2_delete_line_sfa(struct Map_info *Map, int line)
     static struct line_cats *Cats = NULL;
     static struct line_cats *Cats = NULL;
     static struct line_pnts *Points = NULL;
     static struct line_pnts *Points = NULL;
 
 
-    G_debug(3, "V2_delete_line_sfa(), line = %d", line);
+    G_debug(3, "V2_delete_line_sfa(): line = %d", line);
 
 
     type = first = 0;
     type = first = 0;
     Line = NULL;
     Line = NULL;
     plus = &(Map->plus);
     plus = &(Map->plus);
 
 
+    if (line < 1 || line > Map->plus.n_lines) {
+        G_warning(_("Attempt to access feature with invalid id (%d)"), line);
+        return -1;
+    }
+
     if (plus->built >= GV_BUILD_BASE) {
     if (plus->built >= GV_BUILD_BASE) {
 	Line = Map->plus.Line[line];
 	Line = Map->plus.Line[line];
 
 
@@ -200,7 +215,9 @@ int V2_delete_line_sfa(struct Map_info *Map, int line)
     }
     }
 
 
     type = V2_read_line_sfa(Map, Points, Cats, line);
     type = V2_read_line_sfa(Map, Points, Cats, line);
-
+    if (type < 0)
+        return -1;
+    
     /* Update category index */
     /* Update category index */
     if (plus->update_cidx) {
     if (plus->update_cidx) {
       for (i = 0; i < Cats->n_cats; i++) {
       for (i = 0; i < Cats->n_cats; i++) {