[GRASS-SVN] r64163 - grass/branches/releasebranch_7_0/lib/vector/Vlib

svn_grass at osgeo.org svn_grass at osgeo.org
Wed Jan 14 01:03:20 PST 2015


Author: mmetz
Date: 2015-01-14 01:03:20 -0800 (Wed, 14 Jan 2015)
New Revision: 64163

Modified:
   grass/branches/releasebranch_7_0/lib/vector/Vlib/build.c
Log:
Vlib: fix topology updating

Modified: grass/branches/releasebranch_7_0/lib/vector/Vlib/build.c
===================================================================
--- grass/branches/releasebranch_7_0/lib/vector/Vlib/build.c	2015-01-14 08:43:30 UTC (rev 64162)
+++ grass/branches/releasebranch_7_0/lib/vector/Vlib/build.c	2015-01-14 09:03:20 UTC (rev 64163)
@@ -374,7 +374,7 @@
  */
 int Vect_attach_isle(struct Map_info *Map, int isle)
 {
-    int sel_area;
+    int area;
     struct P_isle *Isle;
     struct Plus_head *plus;
 
@@ -385,24 +385,24 @@
 
     plus = &(Map->plus);
 
-    sel_area = Vect_isle_find_area(Map, isle);
-    G_debug(3, "\tisle = %d -> area outside = %d", isle, sel_area);
-    if (sel_area > 0) {
+    area = Vect_isle_find_area(Map, isle);
+    G_debug(3, "\tisle = %d -> area outside = %d", isle, area);
+    if (area > 0) {
 	Isle = plus->Isle[isle];
 	if (Isle->area > 0) {
 	    G_debug(3, "Attempt to attach isle %d to more areas "
 		    "(=>topology is not clean)", isle);
 	}
 	else {
-	    Isle->area = sel_area;
-	    dig_area_add_isle(plus, sel_area, isle);
+	    Isle->area = area;
+	    dig_area_add_isle(plus, area, isle);
 	}
     }
     return 0;
 }
 
 /*!
-   \brief (Re)Attach isles to areas in given bounding box
+   \brief (Re)Attach isles in given bounding box to areas
 
    \param Map vector map
    \param box bounding box
@@ -411,7 +411,8 @@
  */
 int Vect_attach_isles(struct Map_info *Map, const struct bound_box *box)
 {
-    int i, isle;
+    int i, isle, area;
+    struct bound_box abox;
     static struct boxlist *List = NULL;
     struct Plus_head *plus;
 
@@ -427,15 +428,34 @@
 
     for (i = 0; i < List->n_values; i++) {
 	isle = List->id[i];
-	/* only attach isles that are not yet attached, see Vect_attach_isle() */
-	if (plus->Isle[isle]->area == 0)
+
+	area = plus->Isle[isle]->area;
+
+	if (area > 0) {
+	    /* if the area box is not fully inside the box, detach
+	     * this might detach more than needed, 
+	     * but all that need to be reattached and
+	     * is faster than reattaching all */
+	    Vect_get_area_box(Map, area, &abox);
+	    if (box->W < abox.W && box->E > abox.E &&
+	        box->S < abox.S && box->N > abox.N) {
+		G_debug(3, "Outer area is fully inside search box");
+	    }
+	    else {
+		dig_area_del_isle(plus, area, isle);
+		plus->Isle[isle]->area = 0;
+		area = 0;
+	    }
+	}
+
+	if (area == 0)
 	    Vect_attach_isle(Map, isle);
     }
     return 0;
 }
 
 /*!
-   \brief (Re)Attach centroids to areas in given bounding box
+   \brief (Re)Attach centroids in given bounding box to areas
 
     Warning: If map is updated on level2, it may happen that
     previously correct island becomes incorrect. In that case,
@@ -459,11 +479,8 @@
     Because of this, when the centroid is reattached to another area,
     it is always necessary to check if original area exist, unregister
     centroid from previous area.  To simplify code, this is
-    implemented so that centroid is always firs unregistered and if
+    implemented so that centroid is always first unregistered and if
     new area is found, it is registered again.
-      
-    This problem can be avoided altogether if properly attached
-    centroids are skipped MM 2009
 
    \param Map vector map
    \param box bounding box
@@ -472,8 +489,9 @@
  */
 int Vect_attach_centroids(struct Map_info *Map, const struct bound_box * box)
 {
-    int i, sel_area, centr;
+    int i, area, centr;
     static int first = 1;
+    struct bound_box abox;
     static struct boxlist *List;
     struct P_area *Area;
     struct P_line *Line;
@@ -497,28 +515,44 @@
 	Line = plus->Line[centr];
 	topo = (struct P_topo_c *)Line->topo;
 
-	/* only attach unregistered and duplicate centroids because 
-	 * 1) all properly attached centroids are properly attached, really! Don't touch.
-	 * 2) Vect_find_area() below does not always return the correct area
-	 * 3) it's faster
-	 */
-	if (topo->area > 0)
+	area = topo->area;
+
+	if (area > 0) {
+	    /* if the area box is not fully inside the box, detach
+	     * this might detach more than needed, 
+	     * but all that need to be reattached and
+	     * is faster than reattaching all */
+	    Vect_get_area_box(Map, area, &abox);
+	    if (box->W < abox.W && box->E > abox.E &&
+	        box->S < abox.S && box->N > abox.N) {
+		G_debug(3, "Centroid's area is fully inside search box");
+	    }
+	    else {
+		Area = plus->Area[area];
+		Area->centroid = 0;
+		topo->area = 0;
+		area = 0;
+	    }
+	}
+
+	if (area > 0) {
 	    continue;
+	}
 
-	sel_area = Vect_find_area(Map, List->box[i].E, List->box[i].N);
-	G_debug(3, "\tcentroid %d is in area %d", centr, sel_area);
-	if (sel_area > 0) {
-	    Area = plus->Area[sel_area];
+	area = Vect_find_area(Map, List->box[i].E, List->box[i].N);
+	G_debug(3, "\tcentroid %d is in area %d", centr, area);
+	if (area > 0) {
+	    Area = plus->Area[area];
 	    if (Area->centroid == 0) {	/* first centroid */
 		G_debug(3, "\tfirst centroid -> attach to area");
 		Area->centroid = centr;
-		topo->area = sel_area;
+		topo->area = area;
 	    }
 	    else if (Area->centroid != centr) {	/* duplicate centroid */
 		/* Note: it cannot happen that Area->centroid == centr, because the centroid
 		 * was not registered or a duplicate */
 		G_debug(3, "\tduplicate centroid -> do not attach to area");
-		topo->area = -sel_area;
+		topo->area = -area;
 	    }
 	}
     }



More information about the grass-commit mailing list