Kaynağa Gözat

Vlib: fix Vect_find_area()

git-svn-id: https://svn.osgeo.org/grass/grass/trunk@64340 15284696-431f-4ddb-bdfa-cd5b030d7da7
Markus Metz 10 yıl önce
ebeveyn
işleme
7e2481921f
1 değiştirilmiş dosya ile 26 ekleme ve 5 silme
  1. 26 5
      lib/vector/Vlib/find.c

+ 26 - 5
lib/vector/Vlib/find.c

@@ -263,11 +263,13 @@ Vect_find_line_list(struct Map_info *map,
  */
 int Vect_find_area(struct Map_info *Map, double x, double y)
 {
-    int i, ret, area;
+    int i, j, ret, area, isle;
     struct bound_box box;
     static struct boxlist *List = NULL;
     static BOX_SIZE *size_list;
     static int alloc_size_list = 0;
+    const struct Plus_head *Plus;
+    struct P_area *Area;
 
     G_debug(3, "Vect_find_area() x = %f y = %f", x, y);
 
@@ -277,6 +279,8 @@ int Vect_find_area(struct Map_info *Map, double x, double y)
 	size_list = G_malloc(alloc_size_list * sizeof(BOX_SIZE));
     }
 
+    Plus = &(Map->plus);
+
     /* select areas by box */
     box.E = x;
     box.W = x;
@@ -320,14 +324,31 @@ int Vect_find_area(struct Map_info *Map, double x, double y)
 
     for (i = 0; i < List->n_values; i++) {
 	area = size_list[i].i;
-	/* testing only the outer ring is sufficient because 
-	 * inner rings have been tested earlier (sorted list) */
+	/* outer ring */
 	ret = Vect_point_in_area_outer_ring(x, y, Map, area, &size_list[i].box);
 
-	G_debug(3, "    area = %d Vect_point_in_area() = %d", area, ret);
+	G_debug(3, "    area = %d Vect_point_in_area_outer_ring() = %d", area, ret);
+
+	if (ret >= 1) {
+	    /* check if in islands */
+	    Area = Plus->Area[area];
+	    for (j = 0; j < Area->n_isles; j++) {
+		isle = Area->isles[j];
+		Vect_get_isle_box(Map, isle, &box);
+		ret = Vect_point_in_island(x, y, Map, isle, &box);
+
+		G_debug(3, "    area = %d Vect_point_in_island() = %d", area, ret);
 
-	if (ret >= 1)
+		if (ret >= 1) {
+		    /* point is not in area
+		     * point is also not in any inner area, those have 
+		     * been tested before (sorted list) 
+		     * -> area inside island could not be built */
+		    return 0;
+		}
+	    }
 	    return (area);
+	}
     }
 
     return 0;