[GRASS-SVN] r55999 - grass/trunk/lib/vector/Vlib

svn_grass at osgeo.org svn_grass at osgeo.org
Thu Apr 25 16:29:30 PDT 2013


Author: mmetz
Date: 2013-04-25 16:29:30 -0700 (Thu, 25 Apr 2013)
New Revision: 55999

Modified:
   grass/trunk/lib/vector/Vlib/remove_duplicates.c
Log:
Vlib: speed up Vect_remove_duplicates)

Modified: grass/trunk/lib/vector/Vlib/remove_duplicates.c
===================================================================
--- grass/trunk/lib/vector/Vlib/remove_duplicates.c	2013-04-25 23:07:37 UTC (rev 55998)
+++ grass/trunk/lib/vector/Vlib/remove_duplicates.c	2013-04-25 23:29:30 UTC (rev 55999)
@@ -17,6 +17,41 @@
 #include <grass/vector.h>
 #include <grass/glocale.h>
 
+static int cmp_int(const void *a, const void *b)
+{
+    return (*(int *)a - *(int *)b);
+}
+
+static int boxlist_add_sorted(struct boxlist *list, int id)
+{
+    int i;
+
+    if (list->n_values > 0) {
+	if (bsearch(&id, list->id, list->n_values, sizeof(int), cmp_int))
+	    return 0;
+    }
+
+    if (list->n_values == list->alloc_values) {
+	size_t size = (list->n_values + 100) * sizeof(int);
+
+	list->id = (int *)G_realloc((void *)list->id, size);
+	list->alloc_values = list->n_values + 100;
+    }
+    
+    i = 0;
+    if (list->n_values > 0) {
+	for (i = list->n_values; i > 0; i--) {
+	    if (list->id[i - 1] < id)
+		break;
+	    list->id[i] = list->id[i - 1];
+	}
+    }
+    list->id[i] = id;
+    list->n_values++;
+    
+    return 1;
+}
+
 /*!
    \brief Remove duplicate features from vector map.
 
@@ -37,6 +72,7 @@
     struct line_cats *ACats, *BCats;
     int i, c, atype, btype, aline, bline;
     int nlines, nacats_orig, npoints;
+    int na1, na2, nb1, nb2, nodelines, nline;
     struct bound_box ABox;
     struct boxlist *List;
     int ndupl, is_dupl;
@@ -73,17 +109,38 @@
 	Vect_line_prune(APoints);
 	
 	if (npoints != APoints->n_points) {
+	    G_debug(3, "Line %d pruned, %d vertices removed", aline, npoints - APoints->n_points);
 	    Vect_rewrite_line(Map, aline, atype, APoints, ACats);
 	    nlines = Vect_get_num_lines(Map);
 	    continue;
 	}
 
-	/* select potential duplicates */
-	ABox.E = ABox.W = APoints->x[0];
-	ABox.N = ABox.S = APoints->y[0];
-	ABox.T = ABox.B = APoints->z[0];
-	Vect_select_lines_by_box(Map, &ABox, type, List);
-	G_debug(3, "  %d lines selected by box", List->n_values);
+	na1 = na2 = -1;
+	if (atype & GV_LINES) {
+	    /* faster than Vect_select_lines_by_box() */
+	    Vect_reset_boxlist(List);
+	    Vect_get_line_nodes(Map, aline, &na1, &na2);
+	    nodelines = Vect_get_node_n_lines(Map, na1);
+
+	    for (i = 0; i < nodelines; i++) {
+		nline = abs(Vect_get_node_line(Map, na1, i));
+		
+		if (nline == aline)
+		    continue;
+		if (Vect_get_line_type(Map, nline) != atype)
+		    continue;
+		
+		boxlist_add_sorted(List, nline);
+	    }
+	}
+	else {
+	    /* select potential duplicates */
+	    ABox.E = ABox.W = APoints->x[0];
+	    ABox.N = ABox.S = APoints->y[0];
+	    ABox.T = ABox.B = APoints->z[0];
+	    Vect_select_lines_by_box(Map, &ABox, atype, List);
+	    G_debug(3, "  %d lines selected by box", List->n_values);
+	}
 	
 	is_dupl = 0;
 
@@ -95,6 +152,15 @@
 	    if (aline <= bline)
 		continue;
 
+	    nb1 = nb2 = -1;
+
+	    if (atype & GV_LINES) {
+		Vect_get_line_nodes(Map, bline, &nb1, &nb2);
+		if ((na1 == nb1 && na2 != nb2) ||
+		    (na1 == nb2 && na2 != nb1))
+		    continue;
+	    }
+
 	    btype = Vect_read_line(Map, BPoints, BCats, bline);
 	    Vect_line_prune(BPoints);
 



More information about the grass-commit mailing list