[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