[GRASS-SVN] r53629 - in grass/trunk: include/defs lib/vector/Vlib vector/v.clean vector/v.in.ogr
svn_grass at osgeo.org
svn_grass at osgeo.org
Wed Oct 31 14:01:41 PDT 2012
Author: mmetz
Date: 2012-10-31 14:01:41 -0700 (Wed, 31 Oct 2012)
New Revision: 53629
Modified:
grass/trunk/include/defs/vector.h
grass/trunk/lib/vector/Vlib/bridges.c
grass/trunk/vector/v.clean/main.c
grass/trunk/vector/v.in.ogr/geom.c
grass/trunk/vector/v.in.ogr/main.c
Log:
vector cleaning: adjustment for pathological cases
Modified: grass/trunk/include/defs/vector.h
===================================================================
--- grass/trunk/include/defs/vector.h 2012-10-31 20:02:43 UTC (rev 53628)
+++ grass/trunk/include/defs/vector.h 2012-10-31 21:01:41 UTC (rev 53629)
@@ -26,11 +26,13 @@
double *, double *, double *);
int Vect_line_segment(const struct line_pnts *, double, double, struct line_pnts *);
double Vect_line_length(const struct line_pnts *);
-double Vect_area_perimeter(const struct line_pnts *);
double Vect_line_geodesic_length(const struct line_pnts *);
int Vect_line_distance(const struct line_pnts *, double, double, double, int,
double *, double *, double *, double *, double *,
double *);
+int Vect_line_geodesic_distance(const struct line_pnts *, double, double, double, int,
+ double *, double *, double *, double *, double *,
+ double *);
void Vect_line_box(const struct line_pnts *, struct bound_box *);
void Vect_line_parallel(struct line_pnts *, double, double, int,
struct line_pnts *);
@@ -267,6 +269,7 @@
int Vect_get_node_line(const struct Map_info *, int, int);
float Vect_get_node_line_angle(const struct Map_info *, int, int);
+double Vect_area_perimeter(const struct line_pnts *);
int Vect_get_area_points(const struct Map_info *, int, struct line_pnts *);
int Vect_get_area_centroid(const struct Map_info *, int);
int Vect_get_area_num_isles(const struct Map_info *, int);
@@ -352,8 +355,8 @@
void Vect_remove_dangles(struct Map_info *, int, double, struct Map_info *);
void Vect_chtype_dangles(struct Map_info *, double, struct Map_info *);
void Vect_select_dangles(struct Map_info *, int, double, struct ilist *);
-void Vect_remove_bridges(struct Map_info *, struct Map_info *);
-void Vect_chtype_bridges(struct Map_info *, struct Map_info *);
+void Vect_remove_bridges(struct Map_info *, struct Map_info *, int *, int *);
+void Vect_chtype_bridges(struct Map_info *, struct Map_info *, int *, int *);
int Vect_remove_small_areas(struct Map_info *, double, struct Map_info *,
double *);
int Vect_clean_small_angles_at_nodes(struct Map_info *, int,
Modified: grass/trunk/lib/vector/Vlib/bridges.c
===================================================================
--- grass/trunk/lib/vector/Vlib/bridges.c 2012-10-31 20:02:43 UTC (rev 53628)
+++ grass/trunk/lib/vector/Vlib/bridges.c 2012-10-31 21:01:41 UTC (rev 53629)
@@ -17,10 +17,20 @@
#include <stdlib.h>
#include <grass/vector.h>
+#include <grass/rbtree.h>
#include <grass/glocale.h>
+static int cmp_int(const void *a, const void *b)
+{
+ const int *ai = a;
+ const int *bi = b;
+
+ return (*ai < *bi ? -1 : (*ai > *bi));
+}
+
static void
-remove_bridges(struct Map_info *Map, int chtype, struct Map_info *Err);
+remove_bridges(struct Map_info *Map, int chtype, struct Map_info *Err,
+ int *lrm, int *brm);
/*!
\brief Remove bridges from vector map.
@@ -33,13 +43,16 @@
\param Map input map where bridges are deleted
\param Err vector map where deleted bridges are written or NULL
+ \param lines_removed number of lines removed
+ \param bridges_removed Err number of bridges removed
\return
*/
void
-Vect_remove_bridges(struct Map_info *Map, struct Map_info *Err)
+Vect_remove_bridges(struct Map_info *Map, struct Map_info *Err,
+ int *lines_removed, int *bridges_removed)
{
- remove_bridges(Map, 0, Err);
+ remove_bridges(Map, 0, Err, lines_removed, bridges_removed);
}
/*!
@@ -54,14 +67,17 @@
\param Map input map where bridges are changed
\param Err vector map where changed bridges are written or NULL
+ \param lines_changed number of lines changed
+ \param bridges_changed Err number of bridges changed
\return
*/
void
-Vect_chtype_bridges(struct Map_info *Map, struct Map_info *Err)
+Vect_chtype_bridges(struct Map_info *Map, struct Map_info *Err,
+ int *lines_changed, int *bridges_changed)
{
- remove_bridges(Map, 1, Err);
+ remove_bridges(Map, 1, Err, lines_changed, bridges_changed);
}
/*
@@ -78,17 +94,18 @@
List of all lines in chain is created during the cycle.
*/
void
-remove_bridges(struct Map_info *Map, int chtype, struct Map_info *Err)
+remove_bridges(struct Map_info *Map, int chtype, struct Map_info *Err,
+ int *lrm, int *brm)
{
- int i, type, nlines, line;
- int left, right, node1, node2, current_line, next_line;
+ int i, type, nlines, line, *bline;
+ int left, right, node1, node2, current_line, next_line, abs_line;
int bridges_removed = 0; /* number of removed bridges */
int lines_removed = 0; /* number of lines removed */
struct Plus_head *Plus;
struct line_pnts *Points;
struct line_cats *Cats;
- struct ilist *CycleList;
- struct ilist *BridgeList;
+ struct RB_TREE *CycleTree, *BridgeTree;
+ struct RB_TRAV trav;
int dangle, other_side;
@@ -96,9 +113,10 @@
Points = Vect_new_line_struct();
Cats = Vect_new_cats_struct();
- CycleList = Vect_new_list();
- BridgeList = Vect_new_list();
+ CycleTree = rbtree_create(cmp_int, sizeof(int));
+ BridgeTree = rbtree_create(cmp_int, sizeof(int));
+
nlines = Vect_get_num_lines(Map);
G_debug(1, "nlines = %d", nlines);
@@ -126,22 +144,27 @@
current_line = -line; /* we start with negative (go forward, node2 ) */
+ G_debug(3, "current line: %d", line);
dangle = 0;
other_side = 0;
- Vect_reset_list(CycleList);
- Vect_reset_list(BridgeList);
+ rbtree_clear(CycleTree);
+ rbtree_clear(BridgeTree);
+
while (1) {
next_line =
dig_angle_next_line(Plus, current_line, GV_RIGHT,
GV_BOUNDARY, NULL);
+ abs_line = abs(next_line);
/* Add this line to the list */
- /* TODO: Vect_val_in_list() and Vect_list_append() behave O(n)
- * change to O(log n) */
- if (Vect_val_in_list(CycleList, abs(next_line))) /* other side -> bridge chain */
- Vect_list_append(BridgeList, abs(next_line));
- else
- G_ilist_add(CycleList, abs(next_line)); /* not in list, can add new line fast */
+ if (rbtree_find(CycleTree, (void *)&abs_line)) {
+ if (!rbtree_find(BridgeTree, (void *)&abs_line)) {
+ rbtree_insert(BridgeTree, (void *)&abs_line);
+ }
+ }
+ else {
+ rbtree_insert(CycleTree, (void *)&abs_line);
+ }
if (abs(next_line) == abs(current_line)) {
G_debug(4, " dangle -> no bridge");
@@ -165,17 +188,19 @@
if (!dangle && other_side) {
G_debug(3, " line %d is part of bridge chain", line);
- for (i = 0; i < BridgeList->n_values; i++) {
- Vect_read_line(Map, Points, Cats, BridgeList->value[i]);
+ rbtree_init_trav(&trav, BridgeTree);
+ /* for (i = 0; i < BridgeList->n_values; i++) { */
+ while ((bline = rbtree_traverse(&trav))) {
+ Vect_read_line(Map, Points, Cats, *bline);
if (Err) {
Vect_write_line(Err, GV_BOUNDARY, Points, Cats);
}
if (!chtype)
- Vect_delete_line(Map, BridgeList->value[i]);
+ Vect_delete_line(Map, *bline);
else
- Vect_rewrite_line(Map, BridgeList->value[i], GV_LINE,
+ Vect_rewrite_line(Map, *bline, GV_LINE,
Points, Cats);
lines_removed++;
@@ -183,6 +208,17 @@
bridges_removed++;
}
}
+
+ Vect_destroy_line_struct(Points);
+ Vect_destroy_cats_struct(Cats);
+ rbtree_destroy(CycleTree);
+ rbtree_destroy(BridgeTree);
+
+ if (lrm)
+ *lrm = lines_removed;
+ if (brm)
+ *brm = bridges_removed;
+
G_verbose_message("Removed lines: %d", lines_removed);
G_verbose_message("Removed bridges: %d", bridges_removed);
}
Modified: grass/trunk/vector/v.clean/main.c
===================================================================
--- grass/trunk/vector/v.clean/main.c 2012-10-31 20:02:43 UTC (rev 53628)
+++ grass/trunk/vector/v.clean/main.c 2012-10-31 21:01:41 UTC (rev 53629)
@@ -375,11 +375,11 @@
break;
case TOOL_RMBRIDGE:
G_message(_("Tool: Remove bridges"));
- Vect_remove_bridges(&Out, pErr);
+ Vect_remove_bridges(&Out, pErr, NULL, NULL);
break;
case TOOL_CHBRIDGE:
G_message(_("Tool: Change type of boundary bridges"));
- Vect_chtype_bridges(&Out, pErr);
+ Vect_chtype_bridges(&Out, pErr, NULL, NULL);
break;
case TOOL_RMDAC:
G_message(_("Tool: Remove duplicate area centroids"));
Modified: grass/trunk/vector/v.in.ogr/geom.c
===================================================================
--- grass/trunk/vector/v.in.ogr/geom.c 2012-10-31 20:02:43 UTC (rev 53628)
+++ grass/trunk/vector/v.in.ogr/geom.c 2012-10-31 21:01:41 UTC (rev 53629)
@@ -466,6 +466,10 @@
/* can't split boundaries with only 2 vertices */
if (Points->n_points == 2) {
+ Vect_line_prune(Points);
+
+ if (Points->n_points < 2)
+ return 0;
Vect_write_line(Map, otype, Points, Cats);
return 0;
}
@@ -494,7 +498,10 @@
Vect_append_point(OutPoints, Points->x[i], Points->y[i],
Points->z[i]);
}
- Vect_write_line(Map, otype, OutPoints, Cats);
+ Vect_line_prune(OutPoints);
+
+ if (OutPoints->n_points > 1)
+ Vect_write_line(Map, otype, OutPoints, Cats);
Vect_destroy_line_struct(OutPoints);
Modified: grass/trunk/vector/v.in.ogr/main.c
===================================================================
--- grass/trunk/vector/v.in.ogr/main.c 2012-10-31 20:02:43 UTC (rev 53628)
+++ grass/trunk/vector/v.in.ogr/main.c 2012-10-31 21:01:41 UTC (rev 53629)
@@ -743,7 +743,7 @@
split_distance =
area_size / log(n_polygon_boundaries);
/* divisor is the handle: increase divisor to decrease split_distance */
- split_distance = split_distance / 5.;
+ split_distance = split_distance / 16.;
G_debug(1, "root of area size: %f", area_size);
G_verbose_message(_("Boundary splitting distance in map units: %G"),
split_distance);
@@ -1132,13 +1132,20 @@
}
G_message("%s", separator);
+ Vect_build_partial(&Tmp, GV_BUILD_AREAS);
+
+ G_message("%s", separator);
if (type & GV_BOUNDARY) {
G_message(_("Changing boundary bridges to lines..."));
- Vect_chtype_bridges(&Tmp, NULL);
+ Vect_chtype_bridges(&Tmp, NULL, &nmodif, NULL);
+ if (nmodif)
+ Vect_build_partial(&Tmp, GV_BUILD_NONE);
}
else {
G_message(_("Removing bridges..."));
- Vect_remove_bridges(&Tmp, NULL);
+ Vect_remove_bridges(&Tmp, NULL, &nmodif, NULL);
+ if (nmodif)
+ Vect_build_partial(&Tmp, GV_BUILD_NONE);
}
/* Boundaries are hopefully clean, build areas */
More information about the grass-commit
mailing list