[GRASS-SVN] r48474 - grass/branches/releasebranch_6_4/vector/v.voronoi

svn_grass at osgeo.org svn_grass at osgeo.org
Mon Sep 26 05:30:19 EDT 2011


Author: mmetz
Date: 2011-09-26 02:30:19 -0700 (Mon, 26 Sep 2011)
New Revision: 48474

Modified:
   grass/branches/releasebranch_6_4/vector/v.voronoi/vo_extend.c
   grass/branches/releasebranch_6_4/vector/v.voronoi/vo_main.c
Log:
v.voronoi: fix #957 (backport from trunk)

Modified: grass/branches/releasebranch_6_4/vector/v.voronoi/vo_extend.c
===================================================================
--- grass/branches/releasebranch_6_4/vector/v.voronoi/vo_extend.c	2011-09-26 09:30:05 UTC (rev 48473)
+++ grass/branches/releasebranch_6_4/vector/v.voronoi/vo_extend.c	2011-09-26 09:30:19 UTC (rev 48474)
@@ -31,19 +31,21 @@
 		double a, double b, double c, double x, double y,
 		double *c_x, double *c_y, int knownPointAtLeft)
 {
-    double nx, ny;		/* intesection coordinates */
+    double nx, ny;		/* intersection coordinates */
 
     if (x > w && x < e && y > s && y < n) {
 	/* vertical line? */
 	if (a == 0) {
-	    *c_y = c / b;
-	    *c_x = knownPointAtLeft ? s : n;
+	    *c_x = knownPointAtLeft ? e : w;
+	    *c_y =  y;
+	    return 1;
 	}
 
 	/* horizontal line? */
 	if (b == 0) {
-	    *c_x = c / a;
-	    *c_y = knownPointAtLeft ? e : w;
+	    *c_x = x;
+	    *c_y = knownPointAtLeft ? s : n;
+	    return 1;
 	}
 
 	/* south */

Modified: grass/branches/releasebranch_6_4/vector/v.voronoi/vo_main.c
===================================================================
--- grass/branches/releasebranch_6_4/vector/v.voronoi/vo_main.c	2011-09-26 09:30:05 UTC (rev 48473)
+++ grass/branches/releasebranch_6_4/vector/v.voronoi/vo_main.c	2011-09-26 09:30:19 UTC (rev 48474)
@@ -111,6 +111,8 @@
     int node, nnodes;
     COOR *coor;
     int ncoor, acoor;
+    int line, nlines, type, ctype, area, nareas;
+    int err_boundaries, err_centr_out, err_centr_dupl, err_nocentr;
 
     G_gisinit(argv[0]);
 
@@ -169,6 +171,8 @@
     /* initialize working region */
     G_get_window(&Window);
     Vect_region_box(&Window, &Box);
+    Box.T = 0.5;
+    Box.B = -0.5;
 
     freeinit(&sfl, sizeof(struct Site));
 
@@ -257,46 +261,44 @@
 	fields[i] = Vect_cidx_get_field_number(&In, i);
     }
 
-    if (1) {
-	int line, nlines, type, ctype;
+    if (line_flag->answer)
+	ctype = GV_POINT;
+    else
+	ctype = GV_CENTROID;
 
-	if (line_flag->answer)
-	    ctype = GV_POINT;
-	else
-	    ctype = GV_CENTROID;
+    nlines = Vect_get_num_lines(&In);
 
-	nlines = Vect_get_num_lines(&In);
+    G_message(_("Writing sites to output..."));
 
-	G_message(_("Writing sites to output..."));
+    for (line = 1; line <= nlines; line++) {
 
-	for (line = 1; line <= nlines; line++) {
+	G_percent(line, nlines, 2);
 
-	    G_percent(line, nlines, 2);
+	type = Vect_read_line(&In, Points, Cats, line);
+	if (!(type & GV_POINTS))
+	    continue;
 
-	    type = Vect_read_line(&In, Points, Cats, line);
-	    if (!(type & GV_POINTS))
-		continue;
+	if (!Vect_point_in_box(Points->x[0], Points->y[0], 0.0, &Box))
+	    continue;
 
-	    if (!Vect_point_in_box(Points->x[0], Points->y[0], 0.0, &Box))
-		continue;
+	Vect_write_line(&Out, ctype, Points, Cats);
 
-	    Vect_write_line(&Out, ctype, Points, Cats);
 
+	for (i = 0; i < Cats->n_cats; i++) {
+	    int f, j;
 
-	    for (i = 0; i < Cats->n_cats; i++) {
-		int f, j;
-
-		for (j = 0; j < nfields; j++) {	/* find field */
-		    if (fields[j] == Cats->field[i]) {
-			f = j;
-			break;
-		    }
+	    f = -1;
+	    for (j = 0; j < nfields; j++) {	/* find field */
+		if (fields[j] == Cats->field[i]) {
+		    f = j;
+		    break;
 		}
+	    }
+	    if (f > -1) {
 		cats[f][ncats[f]] = Cats->cat[i];
 		ncats[f]++;
 	    }
 	}
-
     }
 
     /* Copy tables */
@@ -310,14 +312,17 @@
 
 	    IFi = Vect_get_dblink(&In, i);
 
+	    f = -1;
 	    for (j = 0; j < nfields; j++) {	/* find field */
 		if (fields[j] == IFi->number) {
 		    f = j;
 		    break;
 		}
 	    }
-	    if (ncats[f] > 0)
-		ntabs++;
+	    if (f > -1) {
+		if (ncats[f] > 0)
+		    ntabs++;
+	    }
 	}
 
 	if (ntabs > 1)
@@ -363,6 +368,106 @@
 
     Vect_close(&In);
 
+    /* cleaning part 1: count errors */
+    Vect_build_partial(&Out, GV_BUILD_CENTROIDS);
+    err_boundaries = err_centr_out = err_centr_dupl = err_nocentr = 0;
+    nlines = Vect_get_num_lines(&Out);
+    for (line = 1; line <= nlines; line++) {
+
+	if (!Vect_line_alive(&Out, line))
+	    continue;
+
+	type = Vect_read_line(&Out, NULL, NULL, line);
+	if (type == GV_BOUNDARY) {
+	    int left, right;
+
+	    Vect_get_line_areas(&Out, line, &left, &right);
+
+	    if (left == 0 || right == 0) {
+		G_debug(3, "line = %d left = %d right = %d", line, 
+			left, right);
+		err_boundaries++;
+	    }
+	}
+	if (type == GV_CENTROID) {
+	    area = Vect_get_centroid_area(&Out, line);
+	    if (area == 0)
+		err_centr_out++;
+	    else if (area < 0)
+		err_centr_dupl++;
+	}
+    }
+
+    err_nocentr = 0;
+    nareas = Vect_get_num_areas(&Out);
+    for (area = 1; area <= nareas; area++) {
+	if (!Vect_area_alive(&Out, area))
+	    continue;
+	line = Vect_get_area_centroid(&Out, area);
+	if (line == 0)
+	    err_nocentr++;
+    }
+
+    /* cleaning part 2: snap */
+    if (err_nocentr || err_centr_dupl || err_centr_out) {
+	int nmod;
+
+	G_important_message(_("Output needs topological cleaning"));
+	Vect_snap_lines(&Out, GV_BOUNDARY, 1e-7, NULL);
+	do {
+	    Vect_break_lines(&Out, GV_BOUNDARY, NULL);
+	    Vect_remove_duplicates(&Out, GV_BOUNDARY, NULL);
+	    nmod =
+		Vect_clean_small_angles_at_nodes(&Out, GV_BOUNDARY, NULL);
+	} while (nmod > 0);
+
+	err_boundaries = 0;
+	nlines = Vect_get_num_lines(&Out);
+	for (line = 1; line <= nlines; line++) {
+
+	    if (!Vect_line_alive(&Out, line))
+		continue;
+
+	    type = Vect_read_line(&Out, NULL, NULL, line);
+	    if (type == GV_BOUNDARY) {
+		int left, right;
+
+		Vect_get_line_areas(&Out, line, &left, &right);
+
+		if (left == 0 || right == 0) {
+		    G_debug(3, "line = %d left = %d right = %d", line, 
+			    left, right);
+		    err_boundaries++;
+		}
+	    }
+	}
+    }
+    /* cleaning part 3: remove remaining incorrect boundaries */
+    if (err_boundaries) {
+	G_important_message(_("Removing incorrect boundaries from output"));
+	nlines = Vect_get_num_lines(&Out);
+	for (line = 1; line <= nlines; line++) {
+
+	    if (!Vect_line_alive(&Out, line))
+		continue;
+
+	    type = Vect_read_line(&Out, NULL, NULL, line);
+	    if (type == GV_BOUNDARY) {
+		int left, right;
+
+		Vect_get_line_areas(&Out, line, &left, &right);
+
+		/* &&, not ||, no typo */
+		if (left == 0 && right == 0) {
+		    G_debug(3, "line = %d left = %d right = %d", line, 
+			    left, right);
+		    Vect_delete_line(&Out, line);
+		}
+	    }
+	}
+    }
+
+    /* build clean topology */
     Vect_build_partial(&Out, GV_BUILD_NONE);
     Vect_build(&Out);
     Vect_close(&Out);



More information about the grass-commit mailing list