[GRASS-SVN] r54132 - grass/trunk/vector/v.overlay

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Dec 1 11:46:15 PST 2012


Author: mmetz
Date: 2012-12-01 11:46:15 -0800 (Sat, 01 Dec 2012)
New Revision: 54132

Modified:
   grass/trunk/vector/v.overlay/area_area.c
   grass/trunk/vector/v.overlay/main.c
   grass/trunk/vector/v.overlay/v.overlay.html
Log:
v.overlay: use Vect_snap_line()

Modified: grass/trunk/vector/v.overlay/area_area.c
===================================================================
--- grass/trunk/vector/v.overlay/area_area.c	2012-12-01 19:45:13 UTC (rev 54131)
+++ grass/trunk/vector/v.overlay/area_area.c	2012-12-01 19:46:15 UTC (rev 54132)
@@ -15,6 +15,15 @@
 #include <grass/glocale.h>
 #include "local.h"
 
+/* for ilist qsort'ing and bsearch'ing */
+static int cmp_int(const void *a, const void *b)
+{
+    int ai = *(int *)a;
+    int bi = *(int *)b;
+    
+    return (ai < bi ? -1 : (ai > bi));
+}
+
 int area_area(struct Map_info *In, int *field, struct Map_info *Out,
 	      struct field_info *Fi, dbDriver * driver, int operator,
 	      int *ofield, ATTRIBUTES * attr, struct ilist *BList, double snap)
@@ -34,13 +43,63 @@
 
     Points = Vect_new_line_struct();
     Cats = Vect_new_cats_struct();
-    
+
     /* optional snap */
     if (snap > 0) {
-	G_message(_("Snapping lines..."));
+	int i, j, snapped_lines = 0;
+	struct bound_box box;
+	struct boxlist *boxlist = Vect_new_boxlist(0);
+	struct ilist *reflist = Vect_new_list();
+	
+	G_message(_("Snapping boundaries with %g ..."), snap);
+
 	/* snap boundaries in B to boundaries in A
 	 * not modifying boundaries in A */
-	Vect_snap_lines_list2(Out, BList, GV_BOUNDARY, snap, NULL);
+
+	if (BList->n_values > 1)
+	    qsort(BList->value, BList->n_values, sizeof(int), cmp_int);
+
+	snapped_lines = 0;
+	nlines = BList->n_values;
+	for (i = 0; i < nlines; i++) {
+	    line = BList->value[i];
+	    Vect_read_line(Out, Points, Cats, line);
+	    /* select lines by box */
+	    Vect_get_line_box(Out, line, &box);
+	    box.E += snap;
+	    box.W -= snap;
+	    box.N += snap;
+	    box.S -= snap;
+	    box.T = 0.0;
+	    box.B = 0.0;
+	    Vect_select_lines_by_box(Out, &box, GV_BOUNDARY, boxlist);
+	    
+	    if (boxlist->n_values > 0) {
+		Vect_reset_list(reflist);
+		for (j = 0; j < boxlist->n_values; j++) {
+		    int aline = boxlist->id[j];
+
+		    if (!bsearch(&aline, BList->value, BList->n_values,
+			sizeof(int), cmp_int)) {
+			G_ilist_add(reflist, aline);
+		    }
+		}
+		
+		/* snap bline to alines */
+		if (Vect_snap_line(Out, reflist, Points, snap, 0, NULL, NULL)) {
+		    /* rewrite bline*/
+		    Vect_delete_line(Out, line);
+		    ret = Vect_write_line(Out, GV_BOUNDARY, Points, Cats);
+		    G_ilist_add(BList, ret);
+		    snapped_lines++;
+		    G_debug(3, "line %d snapped", line);
+		}
+	    }
+	}
+	Vect_destroy_boxlist(boxlist);
+	Vect_destroy_list(reflist);
+
+	G_verbose_message(_("%d boundaries snapped"), snapped_lines);
     }
 
     /* same procedure like for v.in.ogr
@@ -49,7 +108,7 @@
      * and Vect_clean_small_angles_at_nodes() until no more small dangles are found */
     do {
 	G_message(_("Breaking lines..."));
-	Vect_break_lines_list(Out, NULL, BList, GV_LINE | GV_BOUNDARY, NULL);
+	Vect_break_lines_list(Out, NULL, BList, GV_BOUNDARY, NULL);
 
 	/* Probably not necessary for LINE x AREA */
 	G_message(_("Removing duplicates..."));

Modified: grass/trunk/vector/v.overlay/main.c
===================================================================
--- grass/trunk/vector/v.overlay/main.c	2012-12-01 19:45:13 UTC (rev 54131)
+++ grass/trunk/vector/v.overlay/main.c	2012-12-01 19:46:15 UTC (rev 54132)
@@ -9,6 +9,7 @@
  *               Markus Neteler <neteler itc.it>,
  *               Paul Kelly <paul-grass stjohnspoint.co.uk>
  *               OGR support by Martin Landa <landa.martin gmail.com>
+ *               Markus Metz
  * PURPOSE:      
  * COPYRIGHT:    (C) 2003-2009 by the GRASS Development Team
  *
@@ -228,6 +229,7 @@
 	nlines_out = 0;
 	for (line = 1; line <= nlines; line++) {
 	    int ltype;
+	    int vertices = 100; /* max number of vertices per line */
 
 	    G_percent(line, nlines, 1);	/* must be before any continue */
 
@@ -248,10 +250,11 @@
 		continue;
 
 	    /* TODO: figure out a reasonable threshold */
-	    if (Points->n_points > 100) {
-		int vertices = 100;
+	    if (Points->n_points > vertices) {
 		int start = 0;	/* number of coordinates written */
 		
+		vertices = Points->n_points / (Points->n_points / vertices + 1);
+		
 		/* split */
 		while (start < Points->n_points - 1) {
 		    int v = 0;

Modified: grass/trunk/vector/v.overlay/v.overlay.html
===================================================================
--- grass/trunk/vector/v.overlay/v.overlay.html	2012-12-01 19:45:13 UTC (rev 54131)
+++ grass/trunk/vector/v.overlay/v.overlay.html	2012-12-01 19:46:15 UTC (rev 54132)
@@ -11,9 +11,12 @@
 can be created. Snapping is enabled by default and can be disabled by 
 setting the <em>snap</em> option to a negative value. Recommended values 
 are between 0.00000001 and 0.0001. Using larger values for snapping can 
-have undesired side-effects. Snapping modifies only boundaries in binput, 
-which are snapped to boundaries in ainput. Boundaries in ainput are not 
-modified.
+have undesired side-effects, but may sometimes be necessary to get a 
+clean output (see example below). In general, it is recommended to start 
+with a small snapping threshold, gradually increasing the threshold until 
+the result is reasonably clean. Snapping modifies only boundaries in 
+binput, which are snapped to boundaries in ainput. Boundaries in ainput 
+are not modified.
 <!-- This is outdated 
 There are 3 links attached to features in output map, 
 <ul>
@@ -70,13 +73,13 @@
 it! Therefore it is advisable to copy tables from ainput and binput first and
 connect the copied tables to the output map.-->
 
-<h2>EXAMPLE POLYGON TO POLYGON UNION</h2>
+<h2>EXAMPLES</h2>
+
+<h4>Polygons overlaid with ploygons</h4>
 <div class="code"><pre>
 v.overlay ainput=lake binput=province output=lakeXprovince operator=or
 </pre></div>
 
-<h2>EXAMPLE POLYGON TO POLYGON UNION</h2>
-
 Polygon union of urban area and Census 2000 areas (North Carolina dataset):
 
 <div class="code"><pre>
@@ -120,11 +123,14 @@
 <img src="v_overlay_census_wake2000.png" alt="GRASS v.overlay: polygon to polygon union (input 2)" border=1>
 <img src="v_overlay_urban_census2000.png" alt="GRASS v.overlay: polygon to polygon union (result)" border=1>
 <br>
-<i>v.overlay: Polygon union of urban area and Census 2000 areas (North Carolina dataset)</i>
+<i>v.overlay: Polygon union (right) of urban area (left) and Census 2000 (middle) areas (North Carolina dataset)</i>
 </center>
 
+As can be seen by the resulting large number of centroids on boundaries, 
+the urban areas do not match exactly the Census 2000 areas. In this case 
+a clean result can be obtained by snapping with a threshold of 0.1 (1 cm).
 
-<h2>EXAMPLE LINE TO POLYGON CLIPPING</h2>
+<h4>Lines overlaid with polygons</h4>
 
 Using the North Carolina sample dataset, we clip the roads map to the area
 of city of Raleigh, preserving road attributes in layer 1:



More information about the grass-commit mailing list