[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