[GRASS-SVN] r40204 - in grass/trunk: include lib/vector/Vlib
vector/v.edit
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Jan 3 05:36:36 EST 2010
Author: martinl
Date: 2010-01-03 05:36:35 -0500 (Sun, 03 Jan 2010)
New Revision: 40204
Modified:
grass/trunk/include/vector.h
grass/trunk/lib/vector/Vlib/build.c
grass/trunk/lib/vector/Vlib/build_ogr.c
grass/trunk/lib/vector/Vlib/hist.c
grass/trunk/lib/vector/Vlib/open.c
grass/trunk/lib/vector/Vlib/write.c
grass/trunk/lib/vector/Vlib/write_nat.c
grass/trunk/lib/vector/Vlib/write_ogr.c
grass/trunk/vector/v.edit/args.c
grass/trunk/vector/v.edit/main.c
grass/trunk/vector/v.edit/select.c
Log:
libvect: implement V1/2_delete_line_ogr()
v.edit updated to delete features
Modified: grass/trunk/include/vector.h
===================================================================
--- grass/trunk/include/vector.h 2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/include/vector.h 2010-01-03 10:36:35 UTC (rev 40204)
@@ -222,6 +222,7 @@
int Vect_open_old_head2(struct Map_info *, const char *, const char *, const char *);
int Vect_open_new(struct Map_info *, const char *, int);
int Vect_open_update(struct Map_info *, const char *, const char *);
+int Vect_open_update2(struct Map_info *, const char *, const char *, const char *);
int Vect_open_update_head(struct Map_info *, const char *, const char *);
int Vect_copy_head_data(const struct Map_info *, struct Map_info *);
int Vect_build(struct Map_info *);
@@ -435,6 +436,9 @@
*/
int Vect_print_header(const struct Map_info *);
void Vect__init_head(struct Map_info *);
+void Vect__delete_area_cats_from_cidx(struct Map_info *, int);
+void Vect__add_area_cats_to_cidx(struct Map_info *, int);
+int V2__delete_line(struct Map_info *, int, int (*fn) (struct Map_info *, off_t));
/* Open/close/rewind map */
int Vect_coor_info(const struct Map_info *, struct Coor_info *);
@@ -478,7 +482,9 @@
int V2_read_next_line_ogr(struct Map_info *, struct line_pnts *,
struct line_cats *);
int V1_delete_line_nat(struct Map_info *, off_t);
+int V1_delete_line_ogr(struct Map_info *, off_t);
int V2_delete_line_nat(struct Map_info *, int);
+int V2_delete_line_ogr(struct Map_info *, int);
int V1_restore_line_nat(struct Map_info *, off_t);
int V2_restore_line_nat(struct Map_info *, int, off_t);
off_t V1_write_line_nat(struct Map_info *, int, const struct line_pnts *,
Modified: grass/trunk/lib/vector/Vlib/build.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build.c 2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/build.c 2010-01-03 10:36:35 UTC (rev 40204)
@@ -127,7 +127,7 @@
plus = &(Map->plus);
if (build > GV_BUILD_NONE) {
G_message(_("Building topology for vector map <%s>..."),
- Vect_get_name(Map));
+ Vect_get_full_name(Map));
}
plus->with_z = Map->head.with_z;
plus->spidx_with_z = Map->head.with_z;
Modified: grass/trunk/lib/vector/Vlib/build_ogr.c
===================================================================
--- grass/trunk/lib/vector/Vlib/build_ogr.c 2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/build_ogr.c 2010-01-03 10:36:35 UTC (rev 40204)
@@ -62,7 +62,7 @@
/* Free parts */
static void free_parts(GEOM_PARTS * parts)
{
- free(parts->part);
+ G_free(parts->part);
parts->a_parts = parts->n_parts = 0;
}
@@ -317,7 +317,7 @@
\brief Build pseudo-topology for OGR layer
\param Map pointer to Map_info structure
- \param build build level (only GV_BUILD_ALL currently supported)
+ \param build build level (GV_BUILD_NONE and GV_BUILD_ALL currently supported)
\return 1 on success
\return 0 on error
@@ -325,17 +325,26 @@
int Vect_build_ogr(struct Map_info *Map, int build)
{
int iFeature, count, FID;
+ struct Plus_head *plus;
+
GEOM_PARTS parts;
OGRFeatureH hFeature;
OGRGeometryH hGeom;
- G_debug(1, "Vect_build_ogr(): dsn=%s layer=%s",
- Map->fInfo.ogr.dsn, Map->fInfo.ogr.layer_name);
+ G_debug(1, "Vect_build_ogr(): dsn=%s layer=%s, build=%d",
+ Map->fInfo.ogr.dsn, Map->fInfo.ogr.layer_name, build);
- if (build != GV_BUILD_ALL)
- G_fatal_error(_("Partial build for OGR is not supported"));
+ if (build != GV_BUILD_ALL && build != GV_BUILD_NONE) {
+ G_warning(_("Partial build for OGR is not supported"));
+ return 0;
+ }
+ plus = &(Map->plus);
+ if (build == plus->built)
+ return 1; /* do nothing */
+
/* TODO move this init to better place (Vect_open_ ?), because in theory build may be reused on level2 */
+ G_free((void *) Map->fInfo.ogr.offset);
Map->fInfo.ogr.offset = NULL;
Map->fInfo.ogr.offset_num = 0;
Map->fInfo.ogr.offset_alloc = 0;
@@ -349,40 +358,56 @@
/* initialize data structures */
init_parts(&parts);
-
- /* Note: Do not use OGR_L_GetFeatureCount (it may scan all features) */
- OGR_L_ResetReading(Map->fInfo.ogr.layer);
- count = iFeature = 0;
- while ((hFeature = OGR_L_GetNextFeature(Map->fInfo.ogr.layer)) != NULL) {
- iFeature++;
- count++;
- G_debug(3, " Feature %d", iFeature);
-
- hGeom = OGR_F_GetGeometryRef(hFeature);
- if (hGeom == NULL) {
- G_warning(_("Feature %d without geometry ignored"), iFeature);
- OGR_F_Destroy(hFeature);
- continue;
- }
+ /* Check if upgrade or downgrade */
+ if (build < plus->built) { /* lower level request, currently only GV_BUILD_NONE */
+ dig_free_plus_areas(plus);
+ dig_spidx_free_areas(plus);
+ dig_free_plus_isles(plus);
+ dig_spidx_free_isles(plus);
- FID = (int)OGR_F_GetFID(hFeature);
- if (FID == OGRNullFID) {
- G_warning(_("OGR feature %d without ID ignored"), iFeature);
+ dig_free_plus_nodes(plus);
+ dig_spidx_free_nodes(plus);
+ dig_free_plus_lines(plus);
+ dig_spidx_free_lines(plus);
+ }
+ else {
+ /* Note: Do not use OGR_L_GetFeatureCount (it may scan all features) */
+ OGR_L_ResetReading(Map->fInfo.ogr.layer);
+ count = iFeature = 0;
+ while ((hFeature = OGR_L_GetNextFeature(Map->fInfo.ogr.layer)) != NULL) {
+ iFeature++;
+ count++;
+
+ G_debug(3, " Feature %d", iFeature);
+
+ hGeom = OGR_F_GetGeometryRef(hFeature);
+ if (hGeom == NULL) {
+ G_warning(_("Feature %d without geometry ignored"), iFeature);
+ OGR_F_Destroy(hFeature);
+ continue;
+ }
+
+ FID = (int)OGR_F_GetFID(hFeature);
+ if (FID == OGRNullFID) {
+ G_warning(_("OGR feature %d without ID ignored"), iFeature);
+ OGR_F_Destroy(hFeature);
+ continue;
+ }
+ G_debug(4, " FID = %d", FID);
+
+ reset_parts(&parts);
+ add_part(&parts, FID);
+ add_geometry(Map, hGeom, FID, &parts);
+
OGR_F_Destroy(hFeature);
- continue;
- }
- G_debug(4, " FID = %d", FID);
-
- reset_parts(&parts);
- add_part(&parts, FID);
- add_geometry(Map, hGeom, FID, &parts);
-
- OGR_F_Destroy(hFeature);
- } /* while */
+ } /* while */
+ }
+
free_parts(&parts);
- Map->plus.built = GV_BUILD_ALL;
+ Map->plus.built = build;
+
return 1;
}
#endif
Modified: grass/trunk/lib/vector/Vlib/hist.c
===================================================================
--- grass/trunk/lib/vector/Vlib/hist.c 2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/hist.c 2010-01-03 10:36:35 UTC (rev 40204)
@@ -52,6 +52,8 @@
/*!
\brief Write string to history file
+ Only native format supported.
+
\param Map pointer to Map_info structure
\param str string to write
@@ -61,9 +63,12 @@
{
int ret;
- G_debug(5, "Vect_hist_write()");
- ret = fprintf(Map->hist_fp, str);
- fflush(Map->hist_fp);
+ G_debug(5, "Vect_hist_write(): %s", str);
+ ret = 0;
+ if (Map->hist_fp) {
+ ret = fprintf(Map->hist_fp, str);
+ fflush(Map->hist_fp);
+ }
return (ret);
}
Modified: grass/trunk/lib/vector/Vlib/open.c
===================================================================
--- grass/trunk/lib/vector/Vlib/open.c 2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/open.c 2010-01-03 10:36:35 UTC (rev 40204)
@@ -120,6 +120,7 @@
* \param[out] Map pointer to Map_info structure
* \param name name of vector map to open
* \param mapset mapset name ("" for search path)
+ * \param layer layer name (OGR format only)
* \param update non-zero to open for update otherwise read-only mode
* \param head_only read only header info from 'head', 'dbln', 'topo',
* 'cidx' is not opened. The header may be opened on level 2 only.
@@ -138,8 +139,8 @@
int ogr_mapset;
const char *fmapset;
- G_debug(1, "Vect__open_old(): name = %s mapset= %s update = %d", name,
- mapset, update);
+ G_debug(1, "Vect__open_old(): name = %s mapset = %s layer= %s update = %d", name,
+ mapset, layer, update);
/* zero Map_info structure */
G_zero(Map, sizeof(struct Map_info));
@@ -200,17 +201,11 @@
}
Map->mapset = G_store(fmapset);
}
- else { /* OGR mapset */
- if (update) {
- sprintf(errmsg, _("OGR layer cannot be opened for update"));
- fatal_error(ferror, errmsg);
- return -1;
- }
- }
+
Map->location = G_store(G_location());
Map->gisdbase = G_store(G_gisdbase());
- if (update && (0 != strcmp(Map->mapset, G_mapset()))) {
+ if (update && !ogr_mapset && (0 != strcmp(Map->mapset, G_mapset()))) {
G_warning(_("Vector map which is not in the current mapset cannot be opened for update"));
return -1;
}
@@ -427,7 +422,7 @@
/* open history file */
sprintf(buf, "%s/%s", GV_DIRECTORY, Map->name);
- if (update) { /* native only */
+ if (update && !ogr_mapset) { /* native only */
Map->hist_fp = G_fopen_modify(buf, GV_HIST_ELEMENT);
if (Map->hist_fp == NULL) {
sprintf(errmsg,
@@ -480,8 +475,12 @@
}
/*!
- * \brief Open existing vector for reading
+ * \brief Open existing vector map for reading (native or OGR format
+ * via v.external)
*
+ * 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
@@ -496,14 +495,31 @@
return (Vect__open_old(Map, name, mapset, NULL, 0, 0));
}
+/*!
+ * \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
+ * \param layer layer name (OGR format)
+ *
+ * \return level of openness [1, 2, (3)]
+ * \return -1 on error
+ */
int Vect_open_old2(struct Map_info *Map, const char *name, const char *mapset, const char *layer)
{
return (Vect__open_old(Map, name, mapset, layer, 0, 0));
}
/*!
- * \brief Open existing vector for reading/writing
+ * \brief Open existing vector map for reading/writing (native or OGR
+ * format via v.external)
*
+ * This function is replaced by Vect_open_update2() to handle also
+ * direct OGR support.
+ *
* In case of error, the functions respect fatal error settings.
*
* \param[out] Map pointer to Map_info structure
@@ -536,16 +552,42 @@
return ret;
}
+/*!
+ * \brief Open existing vector map for reading/writing (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 update
+ * \param mapset mapset name
+ * \param layer layer name (OGR format)
+ *
+ * \return level of openness [1, 2, (3)]
+ * \return -1 on error
+ */
+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;
+}
+
/*!
* \brief Reads only info about vector map from headers of 'head',
- * 'dbln', 'topo' and 'cidx' file.
+ * 'dbln', 'topo' and 'cidx' file (native or OGR format via
+ * v.external)
*
+ * 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)
- * \param layer layer name (only for OGR)
*
* \return level of openness [1, 2, (3)]
* \return -1 on error
@@ -555,6 +597,20 @@
return (Vect__open_old(Map, name, mapset, NULL, 0, 1));
}
+/*!
+ * \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)
+ * \param layer layer name (OGR format)
+ *
+ * \return level of openness [1, 2, (3)]
+ * \return -1 on error
+ */
int Vect_open_old_head2(struct Map_info *Map, const char *name, const char *mapset, const char *layer)
{
return (Vect__open_old(Map, name, mapset, layer, 0, 1));
Modified: grass/trunk/lib/vector/Vlib/write.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write.c 2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/write.c 2010-01-03 10:36:35 UTC (rev 40204)
@@ -67,9 +67,13 @@
#ifdef HAVE_OGR
, {
write_dummy, V1_write_line_ogr, write_dummy}
+ , {
+ write_dummy, V1_write_line_ogr, write_dummy}
#else
, {
write_dummy, format_l, format_l}
+ , {
+ write_dummy, format_l, format_l}
#endif
};
@@ -79,21 +83,29 @@
#ifdef HAVE_OGR
, {
rewrite_dummy, rewrite_dummy, rewrite_dummy}
+ , {
+ rewrite_dummy, rewrite_dummy, rewrite_dummy}
#else
, {
rewrite_dummy, format, format}
+ , {
+ rewrite_dummy, format, format}
#endif
};
static int (*Vect_delete_line_array[][3]) () = {
{
- delete_dummy, delete_dummy, V2_delete_line_nat}
+ delete_dummy, V1_delete_line_nat, V2_delete_line_nat}
#ifdef HAVE_OGR
, {
- delete_dummy, delete_dummy, delete_dummy}
+ delete_dummy, V1_delete_line_ogr, V2_delete_line_ogr}
+ , {
+ delete_dummy, V1_delete_line_ogr, V2_delete_line_ogr}
#else
, {
delete_dummy, format, format}
+ , {
+ delete_dummy, format, format}
#endif
};
@@ -103,13 +115,287 @@
#ifdef HAVE_OGR
, {
restore_dummy, restore_dummy, restore_dummy}
+ , {
+ restore_dummy, restore_dummy, restore_dummy}
#else
, {
restore_dummy, format, format}
+ , {
+ restore_dummy, format, format}
#endif
};
+/*!
+ \brief Deletes area (i.e. centroid) categories from category
+ index (internal use only)
+
+ \param Map pointer to Map_info structure
+ \param area area id
+*/
+void Vect__delete_area_cats_from_cidx(struct Map_info *Map, int area)
+{
+ int i;
+ struct P_area *Area;
+ static struct line_cats *Cats = NULL;
+
+ G_debug(3, "Vect__delete_area_cats_from_cidx() area = %d", area);
+
+ Area = Map->plus.Area[area];
+ if (!Area)
+ 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)
+ Cats = Vect_new_cats_struct();
+
+ V2_read_line_nat(Map, NULL, Cats, Area->centroid);
+
+ for (i = 0; i < Cats->n_cats; i++) {
+ dig_cidx_del_cat(&(Map->plus), Cats->field[i], Cats->cat[i], area,
+ GV_AREA);
+ }
+}
+
+/*!
+ \brief Adds area (i.e. centroid) categories from category index
+ (internal use only)
+
+ \param Map pointer to Map_info structure
+ \param area area id
+*/
+void Vect__add_area_cats_to_cidx(struct Map_info *Map, int area)
+{
+ int i;
+ struct P_area *Area;
+ static struct line_cats *Cats = NULL;
+
+ G_debug(3, "Vect__add_area_cats_to_cidx() area = %d", area);
+
+ Area = Map->plus.Area[area];
+ if (!Area)
+ G_fatal_error(_("%s: Area %d does not exist"),
+ "add_area_cats_to_cidx():", area);
+
+ if (Area->centroid == 0) /* no centroid found */
+ return;
+
+ if (!Cats)
+ Cats = Vect_new_cats_struct();
+
+ V2_read_line_nat(Map, NULL, Cats, Area->centroid);
+
+ for (i = 0; i < Cats->n_cats; i++) {
+ dig_cidx_add_cat_sorted(&(Map->plus), Cats->field[i], Cats->cat[i],
+ area, GV_AREA);
+ }
+}
+
/*!
+ \brief Deletes feature (topology level) -- internal use only
+
+ \param pointer to Map_info structure
+ \param line feature id
+ \param fn function to delete feature (native or ogr)
+
+ \return 0 on success
+ \return -1 on error
+*/
+int V2__delete_line(struct Map_info *Map, int line, int (*fn_delete) (struct Map_info *, off_t))
+{
+ int ret, i, side, type, first, next_line, area;
+ struct P_line *Line;
+ struct P_area *Area;
+ struct Plus_head *plus;
+ struct bound_box box, abox;
+ int adjacent[4], n_adjacent;
+ static struct line_cats *Cats = NULL;
+
+ G_debug(3, "V2__delete_line(), line = %d", line);
+
+ type = first = n_adjacent = 0;
+ Line = NULL;
+ plus = &(Map->plus);
+
+ if (plus->built >= GV_BUILD_BASE) {
+ Line = Map->plus.Line[line];
+
+ if (Line == NULL)
+ G_fatal_error(_("Attempt to delete dead feature"));
+ type = Line->type;
+ }
+
+ if (!Cats) {
+ Cats = Vect_new_cats_struct();
+ }
+
+ /* Update category index */
+ if (plus->update_cidx) {
+ type = V2_read_line_nat(Map, NULL, Cats, line);
+
+ for (i = 0; i < Cats->n_cats; i++) {
+ dig_cidx_del_cat(plus, Cats->field[i], Cats->cat[i], line, type);
+ }
+ }
+
+ /* delete the line from coor */
+ ret = fn_delete(Map, Line->offset);
+
+ if (ret == -1) {
+ return ret;
+ }
+
+ /* Update topology */
+ if (plus->built >= GV_BUILD_AREAS && type == GV_BOUNDARY) {
+ /* Store adjacent boundaries at nodes (will be used to rebuild area/isle) */
+ /* Adjacent are stored: > 0 - we want right side; < 0 - we want left side */
+ n_adjacent = 0;
+
+ next_line = dig_angle_next_line(plus, line, GV_RIGHT, GV_BOUNDARY);
+ if (next_line != 0 && abs(next_line) != line) {
+ /* N1, to the right -> we want the right side for > 0 and left for < 0 */
+ adjacent[n_adjacent] = next_line;
+ n_adjacent++;
+ }
+ next_line = dig_angle_next_line(plus, line, GV_LEFT, GV_BOUNDARY);
+ if (next_line != 0 && abs(next_line) != line) {
+ /* N1, to the left -> we want the left side for > 0 and right for < 0 */
+ adjacent[n_adjacent] = -next_line;
+ n_adjacent++;
+ }
+ next_line = dig_angle_next_line(plus, -line, GV_RIGHT, GV_BOUNDARY);
+ if (next_line != 0 && abs(next_line) != line) {
+ /* N2, to the right -> we want the right side for > 0 and left for < 0 */
+ adjacent[n_adjacent] = next_line;
+ n_adjacent++;
+ }
+ next_line = dig_angle_next_line(plus, -line, GV_LEFT, GV_BOUNDARY);
+ if (next_line != 0 && abs(next_line) != line) {
+ /* N2, to the left -> we want the left side for > 0 and right for < 0 */
+ adjacent[n_adjacent] = -next_line;
+ n_adjacent++;
+ }
+
+ /* Delete area(s) and islands this line forms */
+ first = 1;
+ if (Line->left > 0) { /* delete area */
+ Vect_get_area_box(Map, Line->left, &box);
+ if (first) {
+ Vect_box_copy(&abox, &box);
+ first = 0;
+ }
+ else
+ Vect_box_extend(&abox, &box);
+
+ if (plus->update_cidx) {
+ Vect__delete_area_cats_from_cidx(Map, Line->left);
+ }
+ dig_del_area(plus, Line->left);
+ }
+ else if (Line->left < 0) { /* delete isle */
+ dig_del_isle(plus, -Line->left);
+ }
+ if (Line->right > 0) { /* delete area */
+ Vect_get_area_box(Map, Line->right, &box);
+ if (first) {
+ Vect_box_copy(&abox, &box);
+ first = 0;
+ }
+ else
+ Vect_box_extend(&abox, &box);
+
+ if (plus->update_cidx) {
+ Vect__delete_area_cats_from_cidx(Map, Line->right);
+ }
+ dig_del_area(plus, Line->right);
+ }
+ else if (Line->right < 0) { /* delete isle */
+ dig_del_isle(plus, -Line->right);
+ }
+ }
+
+ /* Delete reference from area */
+ if (plus->built >= GV_BUILD_CENTROIDS && type == GV_CENTROID) {
+ if (Line->left > 0) {
+ G_debug(3, "Remove centroid %d from area %d", line, Line->left);
+ if (plus->update_cidx) {
+ Vect__delete_area_cats_from_cidx(Map, Line->left);
+ }
+ Area = Map->plus.Area[Line->left];
+ Area->centroid = 0;
+ }
+ }
+
+ /* delete the line from topo */
+ dig_del_line(plus, line);
+
+ /* Rebuild areas/isles and attach centroids and isles */
+ if (plus->built >= GV_BUILD_AREAS && type == GV_BOUNDARY) {
+ int *new_areas, nnew_areas;
+
+ nnew_areas = 0;
+ new_areas = (int *)G_malloc(2 * n_adjacent * sizeof(int));
+ /* Rebuild areas/isles */
+ for (i = 0; i < n_adjacent; i++) {
+ if (adjacent[i] > 0)
+ side = GV_RIGHT;
+ else
+ side = GV_LEFT;
+
+ G_debug(3, "Build area for line = %d, side = %d", adjacent[i],
+ side);
+
+ area = Vect_build_line_area(Map, abs(adjacent[i]), side);
+ if (area > 0) { /* area */
+ Vect_get_area_box(Map, area, &box);
+ if (first) {
+ Vect_box_copy(&abox, &box);
+ first = 0;
+ }
+ else
+ Vect_box_extend(&abox, &box);
+
+ new_areas[nnew_areas] = area;
+ nnew_areas++;
+ }
+ else if (area < 0) {
+ /* isle -> must be attached -> add to abox */
+ Vect_get_isle_box(Map, -area, &box);
+ if (first) {
+ Vect_box_copy(&abox, &box);
+ first = 0;
+ }
+ else
+ Vect_box_extend(&abox, &box);
+ }
+ }
+ /* Reattach all centroids/isles in deleted areas + new area.
+ * Because isles are selected by box it covers also possible new isle created above */
+ if (!first) { /* i.e. old area/isle was deleted or new one created */
+ /* Reattache isles */
+ if (plus->built >= GV_BUILD_ATTACH_ISLES)
+ Vect_attach_isles(Map, &abox);
+
+ /* Reattach centroids */
+ if (plus->built >= GV_BUILD_CENTROIDS)
+ Vect_attach_centroids(Map, &abox);
+ }
+
+ if (plus->update_cidx) {
+ for (i = 0; i < nnew_areas; i++) {
+ Vect__add_area_cats_to_cidx(Map, new_areas[i]);
+ }
+ }
+ }
+
+ G_debug(3, "updated lines : %d , updated nodes : %d", plus->n_uplines,
+ plus->n_upnodes);
+ return ret;
+}
+
+/*!
\brief Writes new feature to the end of file
The function calls G_fatal_error() on error.
@@ -237,8 +523,8 @@
ret = (*Vect_delete_line_array[Map->format][Map->level]) (Map, line);
if (ret == -1)
- G_fatal_error(_("Unable to feature %d from vector map <%s>"),
- line, Map->name);
+ G_fatal_error(_("Unable to delete feature id %d from vector map <%s>"),
+ line, Vect_get_full_name(Map));
return ret;
}
Modified: grass/trunk/lib/vector/Vlib/write_nat.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_nat.c 2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/write_nat.c 2010-01-03 10:36:35 UTC (rev 40204)
@@ -1,7 +1,7 @@
/*!
- \file write_nat.c
+ \file lib/vector/Vlib/write_nat.c
- \brief Vector library - write vector feature (native format)
+ \brief Vector library - write/modify vector feature (native format)
Higher level functions for reading/writing/manipulating vectors.
@@ -11,7 +11,7 @@
- Delete feature
- Restore feature
- (C) 2001-2009 by the GRASS Development Team
+ (C) 2001-2010 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.
@@ -31,72 +31,6 @@
#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;
- struct P_area *Area;
- static struct line_cats *Cats = NULL;
-
- G_debug(3, "delete_area_cats_from_cidx() area = %d", area);
-
- Area = Map->plus.Area[area];
- if (!Area)
- 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)
- Cats = Vect_new_cats_struct();
-
- V2_read_line_nat(Map, NULL, Cats, Area->centroid);
-
- for (i = 0; i < Cats->n_cats; i++) {
- dig_cidx_del_cat(&(Map->plus), Cats->field[i], Cats->cat[i], area,
- GV_AREA);
- }
-}
-
-/*!
- \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;
- struct P_area *Area;
- static struct line_cats *Cats = NULL;
-
- G_debug(3, "add_area_cats_to_cidx() area = %d", area);
-
- Area = Map->plus.Area[area];
- if (!Area)
- G_fatal_error(_("%s: Area %d does not exist"),
- "add_area_cats_to_cidx():", area);
-
- if (Area->centroid == 0) /* no centroid found */
- return;
-
- if (!Cats)
- Cats = Vect_new_cats_struct();
-
- V2_read_line_nat(Map, NULL, Cats, Area->centroid);
-
- for (i = 0; i < Cats->n_cats; i++) {
- dig_cidx_add_cat_sorted(&(Map->plus), Cats->field[i], Cats->cat[i],
- area, GV_AREA);
- }
-}
-
-/*!
\brief Add line to topo file
Update areas. Areas are modified if:
@@ -196,7 +130,7 @@
Vect_box_extend(&abox, &box);
if (plus->update_cidx) {
- delete_area_cats_from_cidx(Map, area);
+ Vect__delete_area_cats_from_cidx(Map, area);
}
dig_del_area(plus, area);
}
@@ -255,7 +189,7 @@
if (plus->update_cidx) {
for (s = 1; s < 3; s++) {
if (new_area[s - 1] > 0) {
- add_area_cats_to_cidx(Map, new_area[s - 1]);
+ Vect__add_area_cats_to_cidx(Map, new_area[s - 1]);
}
}
}
@@ -275,7 +209,7 @@
Area->centroid = line;
Line->left = sel_area;
if (plus->update_cidx) {
- add_area_cats_to_cidx(Map, sel_area);
+ Vect__add_area_cats_to_cidx(Map, sel_area);
}
}
else { /* duplicate centroid */
@@ -302,7 +236,7 @@
/*!
\brief Writes feature to 'coor' file
- \param Map pointer to vector map
+ \param Map pointer to Map_info structure
\param type feature type
\param points feature geometry
\param cats feature categories
@@ -328,7 +262,7 @@
/*!
\brief Writes feature to 'coor' file (topology level)
- \param Map pointer to vector map
+ \param Map pointer to Map_info structure
\param type feature type
\param points feature geometry
\param cats feature categories
@@ -386,7 +320,7 @@
Old feature is deleted (marked as dead), new feature written.
- \param Map pointer to vector map
+ \param Map pointer to Map_info structure
\param offset feature offset
\param type feature type
\param points feature geometry
@@ -446,7 +380,7 @@
Old feature is deleted (marked as dead), new feature written.
- \param Map pointer to vector map
+ \param Map pointer to Map_info structure
\param line feature id
\param type feature type
\param points feature geometry
@@ -474,7 +408,7 @@
/*!
\brief Rewrites feature at the given offset.
- \param Map pointer to vector map
+ \param Map pointer to Map_info structure
\param offset feature offset
\param type feature type
\param points feature geometry
@@ -572,9 +506,9 @@
}
/*!
- \brief Deletes feature at the given offset.
+ \brief Deletes feature at the given offset (level 1)
- \param Map pointer to vector map
+ \param Map pointer Map_info structure
\param offset feature offset
\return 0 on success
@@ -614,7 +548,7 @@
/*!
\brief Deletes feature (topology level).
- \param pointer to vector map
+ \param pointer to Map_info structure
\param line feature id
\return 0 on success
@@ -622,198 +556,13 @@
*/
int V2_delete_line_nat(struct Map_info *Map, int line)
{
- int ret, i, side, type = 0, first = 0, next_line, area;
- struct P_line *Line = NULL;
- struct P_area *Area;
- struct Plus_head *plus;
- struct bound_box box, abox;
- int adjacent[4], n_adjacent = 0;
- static struct line_cats *Cats = NULL;
-
- G_debug(3, "V2_delete_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 delete dead feature"));
- type = Line->type;
- }
-
- if (!Cats) {
- Cats = Vect_new_cats_struct();
- }
-
- /* Update category index */
- if (plus->update_cidx) {
- type = V2_read_line_nat(Map, NULL, Cats, line);
-
- for (i = 0; i < Cats->n_cats; i++) {
- dig_cidx_del_cat(plus, Cats->field[i], Cats->cat[i], line, type);
- }
- }
-
- /* delete the line from coor */
- ret = V1_delete_line_nat(Map, Line->offset);
-
- if (ret == -1) {
- return ret;
- }
-
- /* Update topology */
- if (plus->built >= GV_BUILD_AREAS && type == GV_BOUNDARY) {
- /* Store adjacent boundaries at nodes (will be used to rebuild area/isle) */
- /* Adjacent are stored: > 0 - we want right side; < 0 - we want left side */
- n_adjacent = 0;
-
- next_line = dig_angle_next_line(plus, line, GV_RIGHT, GV_BOUNDARY);
- if (next_line != 0 && abs(next_line) != line) {
- /* N1, to the right -> we want the right side for > 0 and left for < 0 */
- adjacent[n_adjacent] = next_line;
- n_adjacent++;
- }
- next_line = dig_angle_next_line(plus, line, GV_LEFT, GV_BOUNDARY);
- if (next_line != 0 && abs(next_line) != line) {
- /* N1, to the left -> we want the left side for > 0 and right for < 0 */
- adjacent[n_adjacent] = -next_line;
- n_adjacent++;
- }
- next_line = dig_angle_next_line(plus, -line, GV_RIGHT, GV_BOUNDARY);
- if (next_line != 0 && abs(next_line) != line) {
- /* N2, to the right -> we want the right side for > 0 and left for < 0 */
- adjacent[n_adjacent] = next_line;
- n_adjacent++;
- }
- next_line = dig_angle_next_line(plus, -line, GV_LEFT, GV_BOUNDARY);
- if (next_line != 0 && abs(next_line) != line) {
- /* N2, to the left -> we want the left side for > 0 and right for < 0 */
- adjacent[n_adjacent] = -next_line;
- n_adjacent++;
- }
-
- /* Delete area(s) and islands this line forms */
- first = 1;
- if (Line->left > 0) { /* delete area */
- Vect_get_area_box(Map, Line->left, &box);
- if (first) {
- Vect_box_copy(&abox, &box);
- first = 0;
- }
- else
- Vect_box_extend(&abox, &box);
-
- if (plus->update_cidx) {
- delete_area_cats_from_cidx(Map, Line->left);
- }
- dig_del_area(plus, Line->left);
- }
- else if (Line->left < 0) { /* delete isle */
- dig_del_isle(plus, -Line->left);
- }
- if (Line->right > 0) { /* delete area */
- Vect_get_area_box(Map, Line->right, &box);
- if (first) {
- Vect_box_copy(&abox, &box);
- first = 0;
- }
- else
- Vect_box_extend(&abox, &box);
-
- if (plus->update_cidx) {
- delete_area_cats_from_cidx(Map, Line->right);
- }
- dig_del_area(plus, Line->right);
- }
- else if (Line->right < 0) { /* delete isle */
- dig_del_isle(plus, -Line->right);
- }
- }
-
- /* Delete reference from area */
- if (plus->built >= GV_BUILD_CENTROIDS && type == GV_CENTROID) {
- if (Line->left > 0) {
- G_debug(3, "Remove centroid %d from area %d", line, Line->left);
- if (plus->update_cidx) {
- delete_area_cats_from_cidx(Map, Line->left);
- }
- Area = Map->plus.Area[Line->left];
- Area->centroid = 0;
- }
- }
-
- /* delete the line from topo */
- dig_del_line(plus, line);
-
- /* Rebuild areas/isles and attach centroids and isles */
- if (plus->built >= GV_BUILD_AREAS && type == GV_BOUNDARY) {
- int *new_areas, nnew_areas;
-
- nnew_areas = 0;
- new_areas = (int *)G_malloc(2 * n_adjacent * sizeof(int));
- /* Rebuild areas/isles */
- for (i = 0; i < n_adjacent; i++) {
- if (adjacent[i] > 0)
- side = GV_RIGHT;
- else
- side = GV_LEFT;
-
- G_debug(3, "Build area for line = %d, side = %d", adjacent[i],
- side);
-
- area = Vect_build_line_area(Map, abs(adjacent[i]), side);
- if (area > 0) { /* area */
- Vect_get_area_box(Map, area, &box);
- if (first) {
- Vect_box_copy(&abox, &box);
- first = 0;
- }
- else
- Vect_box_extend(&abox, &box);
-
- new_areas[nnew_areas] = area;
- nnew_areas++;
- }
- else if (area < 0) {
- /* isle -> must be attached -> add to abox */
- Vect_get_isle_box(Map, -area, &box);
- if (first) {
- Vect_box_copy(&abox, &box);
- first = 0;
- }
- else
- Vect_box_extend(&abox, &box);
- }
- }
- /* Reattach all centroids/isles in deleted areas + new area.
- * Because isles are selected by box it covers also possible new isle created above */
- if (!first) { /* i.e. old area/isle was deleted or new one created */
- /* Reattache isles */
- if (plus->built >= GV_BUILD_ATTACH_ISLES)
- Vect_attach_isles(Map, &abox);
-
- /* Reattach centroids */
- if (plus->built >= GV_BUILD_CENTROIDS)
- Vect_attach_centroids(Map, &abox);
- }
-
- if (plus->update_cidx) {
- for (i = 0; i < nnew_areas; i++) {
- add_area_cats_to_cidx(Map, new_areas[i]);
- }
- }
- }
-
- G_debug(3, "updated lines : %d , updated nodes : %d", plus->n_uplines,
- plus->n_upnodes);
- return ret;
+ return V2__delete_line(Map, line, V1_delete_line_nat);
}
/*!
\brief Restores feature at the given offset.
- \param Map pointer to vector map
+ \param Map pointer to Map_info structure
\param offset feature offset
\return 0 on success
@@ -855,7 +604,7 @@
/*!
\brief Restores feature (topology level)
- \param Map pointer to vector map
+ \param Map pointer to Map_info structure
\param line feature id
\param offset feature offset
Modified: grass/trunk/lib/vector/Vlib/write_ogr.c
===================================================================
--- grass/trunk/lib/vector/Vlib/write_ogr.c 2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/lib/vector/Vlib/write_ogr.c 2010-01-03 10:36:35 UTC (rev 40204)
@@ -7,12 +7,12 @@
Inspired by v.out.ogr's code.
- (C) 2009 by the GRASS Development Team
+ (C) 2009-2010 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.
- \author Martin Landa <landa.martin gmail.com> (2009)
+ \author Martin Landa <landa.martin gmail.com>
*/
#include <grass/config.h>
@@ -49,7 +49,7 @@
OGRFeatureDefnH Ogr_featuredefn;
if (!Map->fInfo.ogr.layer) {
- G_warning(_("Unable to write feature, OGR layer not defined"));
+ G_warning(_("OGR layer not defined"));
return -1;
}
@@ -212,4 +212,45 @@
return 1;
}
+/*!
+ \brief Deletes feature at the given offset (level 1)
+
+ \param Map pointer Map_info structure
+ \param offset feature offset
+
+ \return 0 on success
+ \return -1 on error
+*/
+int V1_delete_line_ogr(struct Map_info *Map, off_t offset)
+{
+ G_debug(3, "V1_delete_line_ogr(), offset = %lu", (unsigned long) offset);
+
+ if (!Map->fInfo.ogr.layer) {
+ G_warning(_("OGR layer not defined"));
+ return -1;
+ }
+
+ if (offset >= Map->fInfo.ogr.offset_num)
+ return -1;
+
+ if (OGR_L_DeleteFeature(Map->fInfo.ogr.layer, Map->fInfo.ogr.offset[offset]) != OGRERR_NONE)
+ return -1;
+
+ return 0;
+}
+
+/*!
+ \brief Deletes feature (topology level).
+
+ \param Map pointer to Map_info structure
+ \param line feature id
+
+ \return 0 on success
+ \return -1 on error
+*/
+int V2_delete_line_ogr(struct Map_info *Map, int line)
+{
+ return V2__delete_line(Map, line, V1_delete_line_ogr);
+}
+
#endif /* HAVE_OGR */
Modified: grass/trunk/vector/v.edit/args.c
===================================================================
--- grass/trunk/vector/v.edit/args.c 2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/vector/v.edit/args.c 2010-01-03 10:36:35 UTC (rev 40204)
@@ -35,7 +35,7 @@
{
/* parameters */
params->map = G_define_standard_option(G_OPT_V_MAP);
- params->map->description = _("Name of vector map to edit");
+ params->map->label = _("Name of vector map to edit");
params->fld = G_define_standard_option(G_OPT_V_FIELD);
params->fld->gisprompt = "new_layer,layer,layer";
Modified: grass/trunk/vector/v.edit/main.c
===================================================================
--- grass/trunk/vector/v.edit/main.c 2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/vector/v.edit/main.c 2010-01-03 10:36:35 UTC (rev 40204)
@@ -8,12 +8,11 @@
* AUTHOR(S): GRASS Development Team
* Wolf Bergenheim, Jachym Cepicky, Martin Landa
*
- * COPYRIGHT: (C) 2006-2008 by the GRASS Development Team
+ * COPYRIGHT: (C) 2006-2010 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.
*
* TODO: 3D support (done for move and vertexmove)
****************************************************************/
@@ -108,7 +107,7 @@
if (action_mode == MODE_ADD) /* write */
ret = Vect_open_update(&Map, params.map->answer, G_mapset());
else /* read-only -- select features */
- ret = Vect_open_old(&Map, params.map->answer, G_mapset());
+ ret = Vect_open_old2(&Map, params.map->answer, G_mapset(), params.fld->answer);
if (ret < 2)
G_fatal_error(_("Unable to open vector map <%s> at topological level %d"),
@@ -146,7 +145,7 @@
}
}
- layer = atoi(params.fld->answer);
+ layer = Vect_get_field_number(&Map, params.fld->answer);
i = 0;
while (params.maxdist->answers[i]) {
switch (i) {
@@ -207,7 +206,7 @@
}
Vect_close(&Map);
- Vect_open_update(&Map, params.map->answer, G_mapset());
+ Vect_open_update2(&Map, params.map->answer, G_mapset(), params.fld->answer);
}
}
Modified: grass/trunk/vector/v.edit/select.c
===================================================================
--- grass/trunk/vector/v.edit/select.c 2010-01-03 09:20:16 UTC (rev 40203)
+++ grass/trunk/vector/v.edit/select.c 2010-01-03 10:36:35 UTC (rev 40204)
@@ -40,7 +40,7 @@
{
int layer, type;
- layer = atoi(params->fld->answer);
+ layer = Vect_get_field_number(Map, params->fld->answer);
type = Vect_option_to_types(params->type);
/* select by id's */
More information about the grass-commit
mailing list