[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