[GRASS-SVN] r74206 - grass/trunk/vector/v.patch

svn_grass at osgeo.org svn_grass at osgeo.org
Sat Mar 9 10:51:06 PST 2019


Author: mmetz
Date: 2019-03-09 10:51:06 -0800 (Sat, 09 Mar 2019)
New Revision: 74206

Modified:
   grass/trunk/vector/v.patch/main.c
Log:
v.patch: +automagic cleaning of boundaries if areas have been patched

Modified: grass/trunk/vector/v.patch/main.c
===================================================================
--- grass/trunk/vector/v.patch/main.c	2019-03-09 18:43:05 UTC (rev 74205)
+++ grass/trunk/vector/v.patch/main.c	2019-03-09 18:51:06 UTC (rev 74206)
@@ -32,6 +32,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <stdio.h>
+#include <math.h>
 #include <grass/gis.h>
 #include <grass/vector.h>
 #include <grass/dbmi.h>
@@ -64,6 +65,7 @@
     int maxcat = 0;
     int out_is_3d = WITHOUT_Z;
     char colnames[4096];
+    double snap = -1;
 
     G_gisinit(argv[0]);
 
@@ -457,6 +459,108 @@
     if (!no_topo->answer) {
 	if (append->answer)
 	    Vect_build_partial(&OutMap, GV_BUILD_NONE);
+
+	Vect_build_partial(&OutMap, GV_BUILD_BASE);
+
+	if (Vect_get_num_primitives(&OutMap, GV_BOUNDARY) > 0) {
+	    int nmodif;
+	    struct bound_box box;
+	    double xmax, ymax, min_snap, max_snap;
+	    int exp;
+	    char *separator = "-----------------------------------------------------";
+
+	    Vect_get_map_box(&OutMap, &box);
+
+	    if (abs(box.E) > abs(box.W))
+		xmax = abs(box.E);
+	    else
+		xmax = abs(box.W);
+	    if (abs(box.N) > abs(box.S))
+		ymax = abs(box.N);
+	    else
+		ymax = abs(box.S);
+
+	    if (xmax < ymax)
+		xmax = ymax;
+
+	    /* double precision ULP */
+	    min_snap = frexp(xmax, &exp);
+	    exp -= 52;
+	    min_snap = ldexp(min_snap, exp);
+	    /* human readable */
+	    min_snap = log10(min_snap);
+	    if (min_snap < 0)
+		min_snap = (int)min_snap;
+	    else
+		min_snap = (int)min_snap + 1;
+
+	    /* single precision ULP */
+	    max_snap = frexp(xmax, &exp);
+	    exp -= 23;
+	    max_snap = ldexp(max_snap, exp);
+	    /* human readable */
+	    max_snap = log10(max_snap);
+	    if (max_snap < 0)
+		max_snap = (int)max_snap;
+	    else
+		max_snap = (int)max_snap + 1;
+
+	    snap = (min_snap + max_snap) / 2 - 1.5;
+	    snap = pow(10, snap);
+
+	    if (snap >= 0) {
+		G_message("%s", separator);
+		G_message(_("Snapping boundaries (threshold = %.3e)..."), snap);
+		Vect_snap_lines(&OutMap, GV_BOUNDARY, snap, NULL);
+	    }
+
+	    G_message("%s", separator);
+	    G_message(_("Breaking polygons..."));
+	    Vect_break_polygons(&OutMap, GV_BOUNDARY, NULL);
+
+	    G_message("%s", separator);
+	    G_message(_("Removing duplicates..."));
+	    Vect_remove_duplicates(&OutMap, GV_BOUNDARY, NULL);
+
+	    /* in non-pathological cases, the bulk of the cleaning is now done */
+
+	    /* Vect_clean_small_angles_at_nodes() can change the geometry so that new intersections
+	     * are created. We must call Vect_break_lines(), Vect_remove_duplicates()
+	     * and Vect_clean_small_angles_at_nodes() until no more small angles are found */
+	    do {
+		G_message("%s", separator);
+		G_message(_("Breaking boundaries..."));
+		Vect_break_lines(&OutMap, GV_BOUNDARY, NULL);
+
+		G_message("%s", separator);
+		G_message(_("Removing duplicates..."));
+		Vect_remove_duplicates(&OutMap, GV_BOUNDARY, NULL);
+
+		G_message("%s", separator);
+		G_message(_("Cleaning boundaries at nodes..."));
+		nmodif =
+		    Vect_clean_small_angles_at_nodes(&OutMap, GV_BOUNDARY, NULL);
+	    } while (nmodif > 0);
+
+	    /* merge boundaries */
+	    G_message("%s", separator);
+	    G_message(_("Merging boundaries..."));
+	    Vect_merge_lines(&OutMap, GV_BOUNDARY, NULL, NULL);
+
+	    G_message("%s", separator);
+	    G_message(_("Removing dangles..."));
+	    Vect_remove_dangles(&OutMap, GV_BOUNDARY, -1.0, NULL);
+
+	    G_message("%s", separator);
+	    Vect_build_partial(&OutMap, GV_BUILD_ALL);
+
+	    G_message(_("Removing bridges..."));
+	    Vect_remove_bridges(&OutMap, NULL, &nmodif, NULL);
+
+	    /* Boundaries are hopefully clean, build areas */
+	    G_message("%s", separator);
+	    Vect_build_partial(&OutMap, GV_BUILD_NONE);
+	}
 	Vect_build(&OutMap);
     }
     Vect_close(&OutMap);



More information about the grass-commit mailing list