Vlib/select.c

Go to the documentation of this file.
00001 
00020 #include <stdlib.h>
00021 #include <grass/gis.h>
00022 #include <grass/Vect.h>
00023 
00037 int
00038 Vect_select_lines_by_box(struct Map_info *Map, BOUND_BOX * Box,
00039                          int type, struct ilist *list)
00040 {
00041     int i, line, nlines;
00042     struct Plus_head *plus;
00043     P_LINE *Line;
00044     static struct ilist *LocList = NULL;
00045 
00046     G_debug(3, "Vect_select_lines_by_box()");
00047     G_debug(3, "  Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
00048             Box->E, Box->W, Box->T, Box->B);
00049     plus = &(Map->plus);
00050 
00051     if (!(plus->Spidx_built)) {
00052         G_debug(3, "Building spatial index.");
00053         Vect_build_sidx_from_topo(Map);
00054     }
00055 
00056     list->n_values = 0;
00057     if (!LocList)
00058         LocList = Vect_new_list();
00059 
00060     nlines = dig_select_lines(plus, Box, LocList);
00061     G_debug(3, "  %d lines selected (all types)", nlines);
00062 
00063     /* Remove lines of not requested types */
00064     for (i = 0; i < nlines; i++) {
00065         line = LocList->value[i];
00066         if (plus->Line[line] == NULL)
00067             continue;           /* Should not happen */
00068         Line = plus->Line[line];
00069         if (!(Line->type & type))
00070             continue;
00071         dig_list_add(list, line);
00072     }
00073 
00074     G_debug(3, "  %d lines of requested type", list->n_values);
00075 
00076     return list->n_values;
00077 }
00078 
00091 int
00092 Vect_select_areas_by_box(struct Map_info *Map, BOUND_BOX * Box,
00093                          struct ilist *list)
00094 {
00095     int i;
00096 
00097     G_debug(3, "Vect_select_areas_by_box()");
00098     G_debug(3, "Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
00099             Box->E, Box->W, Box->T, Box->B);
00100 
00101     if (!(Map->plus.Spidx_built)) {
00102         G_debug(3, "Building spatial index.");
00103         Vect_build_sidx_from_topo(Map);
00104     }
00105 
00106     dig_select_areas(&(Map->plus), Box, list);
00107     G_debug(3, "  %d areas selected", list->n_values);
00108     for (i = 0; i < list->n_values; i++) {
00109         G_debug(3, "  area = %d pointer to area structure = %lx",
00110                 list->value[i],
00111                 (unsigned long)Map->plus.Area[list->value[i]]);
00112 
00113     }
00114     return list->n_values;
00115 }
00116 
00117 
00130 int
00131 Vect_select_isles_by_box(struct Map_info *Map, BOUND_BOX * Box,
00132                          struct ilist *list)
00133 {
00134     G_debug(3, "Vect_select_isles_by_box()");
00135     G_debug(3, "Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
00136             Box->E, Box->W, Box->T, Box->B);
00137 
00138     if (!(Map->plus.Spidx_built)) {
00139         G_debug(3, "Building spatial index.");
00140         Vect_build_sidx_from_topo(Map);
00141     }
00142 
00143     dig_select_isles(&(Map->plus), Box, list);
00144     G_debug(3, "  %d isles selected", list->n_values);
00145 
00146     return list->n_values;
00147 }
00148 
00158 int
00159 Vect_select_nodes_by_box(struct Map_info *Map, BOUND_BOX * Box,
00160                          struct ilist *list)
00161 {
00162     struct Plus_head *plus;
00163 
00164     G_debug(3, "Vect_select_nodes_by_box()");
00165     G_debug(3, "Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
00166             Box->E, Box->W, Box->T, Box->B);
00167 
00168     plus = &(Map->plus);
00169 
00170     if (!(plus->Spidx_built)) {
00171         G_debug(3, "Building spatial index.");
00172         Vect_build_sidx_from_topo(Map);
00173     }
00174 
00175     list->n_values = 0;
00176 
00177     dig_select_nodes(plus, Box, list);
00178     G_debug(3, "  %d nodes selected", list->n_values);
00179 
00180     return list->n_values;
00181 }
00182 
00197 int
00198 Vect_select_lines_by_polygon(struct Map_info *Map, struct line_pnts *Polygon,
00199                              int nisles, struct line_pnts **Isles, int type,
00200                              struct ilist *List)
00201 {
00202     int i;
00203     BOUND_BOX box;
00204     static struct line_pnts *LPoints = NULL;
00205     static struct ilist *LocList = NULL;
00206 
00207     /* TODO: this function was not tested with isles */
00208     G_debug(3, "Vect_select_lines_by_polygon() nisles = %d", nisles);
00209 
00210     List->n_values = 0;
00211     if (!LPoints)
00212         LPoints = Vect_new_line_struct();
00213     if (!LocList)
00214         LocList = Vect_new_list();
00215 
00216     /* Select first all lines by box */
00217     dig_line_box(Polygon, &box);
00218     Vect_select_lines_by_box(Map, &box, type, LocList);
00219     G_debug(3, "  %d lines selected by box", LocList->n_values);
00220 
00221     /* Check all lines if intersect the polygon */
00222     for (i = 0; i < LocList->n_values; i++) {
00223         int j, line, intersect = 0;
00224 
00225         line = LocList->value[i];
00226         /* Read line points */
00227         Vect_read_line(Map, LPoints, NULL, line);
00228 
00229         /* Check if any of line vertices is within polygon */
00230         for (j = 0; j < LPoints->n_points; j++) {
00231             if (Vect_point_in_poly(LPoints->x[j], LPoints->y[j], Polygon) >= 1) {       /* inside polygon */
00232                 int k, inisle = 0;
00233 
00234                 for (k = 0; k < nisles; k++) {
00235                     if (Vect_point_in_poly(LPoints->x[j], LPoints->y[j], Isles[k]) >= 1) {      /* in isle */
00236                         inisle = 1;
00237                         break;
00238                     }
00239                 }
00240 
00241                 if (!inisle) {  /* inside polygon, outside isles -> select */
00242                     intersect = 1;
00243                     break;
00244                 }
00245             }
00246         }
00247         if (intersect) {
00248             dig_list_add(List, line);
00249             continue;
00250         }
00251 
00252         /* Check intersections of the line with area/isles boundary */
00253         /* Outer boundary */
00254         if (Vect_line_check_intersection(LPoints, Polygon, 0)) {
00255             dig_list_add(List, line);
00256             continue;
00257         }
00258 
00259         /* Islands */
00260         for (j = 0; j < nisles; j++) {
00261             if (Vect_line_check_intersection(LPoints, Isles[j], 0)) {
00262                 intersect = 1;
00263                 break;
00264             }
00265         }
00266         if (intersect) {
00267             dig_list_add(List, line);
00268         }
00269     }
00270 
00271     G_debug(4, "  %d lines selected by polygon", List->n_values);
00272 
00273     return List->n_values;
00274 }
00275 
00276 
00293 int
00294 Vect_select_areas_by_polygon(struct Map_info *Map, struct line_pnts *Polygon,
00295                              int nisles, struct line_pnts **Isles,
00296                              struct ilist *List)
00297 {
00298     int i, area;
00299     static struct ilist *BoundList = NULL;
00300 
00301     /* TODO: this function was not tested with isles */
00302     G_debug(3, "Vect_select_areas_by_polygon() nisles = %d", nisles);
00303 
00304     List->n_values = 0;
00305     if (!BoundList)
00306         BoundList = Vect_new_list();
00307 
00308     /* Select boundaries by polygon */
00309     Vect_select_lines_by_polygon(Map, Polygon, nisles, Isles, GV_BOUNDARY,
00310                                  BoundList);
00311 
00312     /* Add areas on left/right side of selected boundaries */
00313     for (i = 0; i < BoundList->n_values; i++) {
00314         int line, left, right;
00315 
00316         line = BoundList->value[i];
00317 
00318         Vect_get_line_areas(Map, line, &left, &right);
00319         G_debug(4, "boundary = %d left = %d right = %d", line, left, right);
00320 
00321         if (left > 0) {
00322             dig_list_add(List, left);
00323         }
00324         else if (left < 0) {    /* island */
00325             area = Vect_get_isle_area(Map, abs(left));
00326             G_debug(4, "  left island -> area = %d", area);
00327             if (area > 0)
00328                 dig_list_add(List, area);
00329         }
00330 
00331         if (right > 0) {
00332             dig_list_add(List, right);
00333         }
00334         else if (right < 0) {   /* island */
00335             area = Vect_get_isle_area(Map, abs(right));
00336             G_debug(4, "  right island -> area = %d", area);
00337             if (area > 0)
00338                 dig_list_add(List, area);
00339         }
00340     }
00341 
00342     /* But the Polygon may be completely inside the area (only one), in that case 
00343      * we find the area by one polygon point and add it to the list */
00344     area = Vect_find_area(Map, Polygon->x[0], Polygon->y[0]);
00345     if (area > 0)
00346         dig_list_add(List, area);
00347 
00348     G_debug(3, "  %d areas selected by polygon", List->n_values);
00349 
00350     return List->n_values;
00351 }
Generated on Tue Apr 6 13:28:10 2010 for GRASS Programmer's Manual by  doxygen 1.6.3