[GRASS-SVN] r45857 - grass/branches/develbranch_6/vector/v.buffer2

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Apr 6 13:07:25 EDT 2011


Author: mmetz
Date: 2011-04-06 10:07:25 -0700 (Wed, 06 Apr 2011)
New Revision: 45857

Modified:
   grass/branches/develbranch_6/vector/v.buffer2/main.c
Log:
use spatial index for speed, TODO done

Modified: grass/branches/develbranch_6/vector/v.buffer2/main.c
===================================================================
--- grass/branches/develbranch_6/vector/v.buffer2/main.c	2011-04-06 17:06:46 UTC (rev 45856)
+++ grass/branches/develbranch_6/vector/v.buffer2/main.c	2011-04-06 17:07:25 UTC (rev 45857)
@@ -74,19 +74,32 @@
     struct line_pnts **iPoints;
 };
 
-int point_in_buffer(struct buf_contours *arr_bc, int buffers_count,
+int point_in_buffer(struct buf_contours *arr_bc, SPATIAL_INDEX *si,
 		    double x, double y)
 {
     int i, j, ret, flag;
+    BOUND_BOX bbox;
+    static struct ilist *List = NULL;
 
-    for (i = 0; i < buffers_count; i++) {
-	ret = Vect_point_in_poly(x, y, arr_bc[i].oPoints);
+    if (List == NULL)
+	List = Vect_new_list();
+
+    /* select outer contours overlapping with centroid (x, y) */
+    bbox.W = bbox.E = x;
+    bbox.N = bbox.S = y;
+    bbox.T = PORT_DOUBLE_MAX;
+    bbox.B = -PORT_DOUBLE_MAX;
+
+    Vect_spatial_index_select(si, &bbox, List);
+
+    for (i = 0; i < List->n_values; i++) {
+	ret = Vect_point_in_poly(x, y, arr_bc[List->value[i]].oPoints);
 	if (ret == 0)
 	    continue;
 
 	flag = 1;
-	for (j = 0; j < arr_bc[i].inner_count; j++) {
-	    ret = Vect_point_in_poly(x, y, arr_bc[i].iPoints[j]);
+	for (j = 0; j < arr_bc[List->value[i]].inner_count; j++) {
+	    ret = Vect_point_in_poly(x, y, arr_bc[List->value[i]].iPoints[j]);
 	    if (ret != 0) {	/* inside inner contour */
 		flag = 0;
 		break;
@@ -121,6 +134,8 @@
     int field;
     struct buf_contours *arr_bc;
     int buffers_count;
+    SPATIAL_INDEX si;
+    BOUND_BOX bbox;
 
     /* Attributes if sizecol is used */
     int nrec, ctype;
@@ -354,12 +369,23 @@
 
 
     /* Create buffers' boundaries */
-    nlines = Vect_get_num_lines(&In);
-    nareas = Vect_get_num_areas(&In);
-    /* TODO: don't allocate so much space */
-    buffers_count = 0;
-    arr_bc = G_malloc((nlines + nareas) * sizeof(struct buf_contours));
+    nlines = nareas = 0;
+    if ((type & GV_POINTS) || (type & GV_LINES))
+	nlines += Vect_get_num_primitives(&In, type);
+    if (type & GV_AREA)
+	nareas = Vect_get_num_areas(&In);
+    
+    if (nlines + nareas == 0) {
+	G_warning(_("No features available for buffering. "
+	            "Check type option and features available in the input vector."));
+	exit(EXIT_SUCCESS);
+    }
 
+    buffers_count = 1;
+    arr_bc = G_malloc((nlines + nareas + 1) * sizeof(struct buf_contours));
+
+    Vect_spatial_index_init(&si);
+
     /* Lines (and Points) */
     if ((type & GV_POINTS) || (type & GV_LINES)) {
 	int ltype;
@@ -408,7 +434,8 @@
 		G_debug(2, _("The tolerance in map units: %g"),
 			unit_tolerance);
 	    }
-
+	    
+	    Vect_line_prune(Points);
 	    if (ltype & GV_POINTS || Points->n_points == 1) {
 		Vect_point_buffer2(Points->x[0], Points->y[0], da, db, dalpha,
 				   !(straight_flag->answer), unit_tolerance,
@@ -491,14 +518,26 @@
 
     /* write all buffer contours */
     G_message(_("Writting buffers..."));
-    for (i = 0; i < buffers_count; i++) {
+    for (i = 1; i < buffers_count; i++) {
 	G_percent(i, buffers_count, 2);
 	Vect_write_line(&Out, GV_BOUNDARY, arr_bc[i].oPoints, BCats);
+
+	dig_line_box(arr_bc[i].oPoints, &bbox);
+	Vect_spatial_index_add_item(&si, i, &bbox);
+	
 	for (j = 0; j < arr_bc[i].inner_count; j++)
 	    Vect_write_line(&Out, GV_BOUNDARY, arr_bc[i].iPoints[j], BCats);
+	    
     }
     G_percent(1, 1, 1);
 
+/*
+    Vect_close(&In);
+
+    Vect_build_partial(&Out, GV_BUILD_NONE);
+    Vect_build(&Out);
+    Vect_close(&Out);
+*/
     /* Create areas */
 
     /* Break lines */
@@ -514,20 +553,27 @@
     G_message(_("Removing duplicates..."));
     Vect_remove_duplicates(&Out, GV_BOUNDARY, NULL);
 
-    G_message(_("Breaking boundaries..."));
-    Vect_break_lines(&Out, GV_BOUNDARY, NULL);
+    do {
+	G_message(_("Breaking boundaries..."));
+	Vect_break_lines(&Out, GV_BOUNDARY, NULL);
 
-    G_message(_("Removing duplicates..."));
-    Vect_remove_duplicates(&Out, GV_BOUNDARY, NULL);
+	G_message(_("Removing duplicates..."));
+	Vect_remove_duplicates(&Out, GV_BOUNDARY, NULL);
 
+	G_message(_("Cleaning boundaries at nodes"));
+
+    } while (Vect_clean_small_angles_at_nodes(&Out, GV_BOUNDARY, NULL) > 0);
+
     /* Dangles and bridges don't seem to be necessary if snapping is small enough. */
+    /* Still needed for larger buffer distances ? */
+
     /*
-       G_message (  "Removing dangles..." );
-       Vect_remove_dangles ( &Out, GV_BOUNDARY, -1, NULL, stderr );
+    G_message(_("Removing dangles..."));
+    Vect_remove_dangles(&Out, GV_BOUNDARY, -1, NULL);
 
-       G_message (  "Removing bridges..." );
-       Vect_remove_bridges ( &Out, NULL, stderr );
-     */
+    G_message (_("Removing bridges..."));
+    Vect_remove_bridges(&Out, NULL);
+    */
 
     G_message(_("Attaching islands..."));
     Vect_build_partial(&Out, GV_BUILD_ATTACH_ISLES);
@@ -553,7 +599,7 @@
 	    continue;
 	}
 
-	ret = point_in_buffer(arr_bc, buffers_count, x, y);
+	ret = point_in_buffer(arr_bc, &si, x, y);
 
 	if (ret) {
 	    G_debug(3, "  -> in buffer");
@@ -602,10 +648,23 @@
     G_message(_("Deleting boundaries..."));
     for (line = 1; line <= nlines; line++) {
 	G_percent(line, nlines, 2);
+	
+	if (!Vect_line_alive(&Out, line))
+	    continue;
+
 	if (Lines[line]) {
 	    G_debug(3, " delete line %d", line);
 	    Vect_delete_line(&Out, line);
 	}
+	else {
+	    /* delete incorrect boundaries */
+	    int side[2];
+
+	    Vect_get_line_areas(&Out, line, &side[0], &side[1]);
+	    
+	    if (!side[0] && !side[1])
+		Vect_delete_line(&Out, line);
+	}
     }
 
     G_free(Lines);
@@ -632,7 +691,7 @@
 	    continue;
 	}
 
-	ret = point_in_buffer(arr_bc, buffers_count, x, y);
+	ret = point_in_buffer(arr_bc, &si, x, y);
 
 	if (ret) {
 	    Vect_reset_line(Points);
@@ -650,6 +709,8 @@
        G_free(arr_bc[i].iPoints);
        } */
 
+    Vect_spatial_index_destroy(&si);
+
     Vect_close(&In);
 
     Vect_build_partial(&Out, GV_BUILD_NONE);



More information about the grass-commit mailing list