GRASS Programmer's Manual  6.5.svn(2012)-r51648
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines
vector/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     const char *dstr;
00097     int debug_level;
00098 
00099     dstr = G__getenv("DEBUG");
00100 
00101     if (dstr != NULL)
00102         debug_level = atoi(dstr);
00103     else
00104         debug_level = 0;
00105 
00106     G_debug(3, "Vect_select_areas_by_box()");
00107     G_debug(3, "Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
00108             Box->E, Box->W, Box->T, Box->B);
00109 
00110     if (!(Map->plus.Spidx_built)) {
00111         G_debug(3, "Building spatial index.");
00112         Vect_build_sidx_from_topo(Map);
00113     }
00114 
00115     dig_select_areas(&(Map->plus), Box, list);
00116     G_debug(3, "  %d areas selected", list->n_values);
00117     /* avoid loop when not debugging */
00118     if (debug_level > 2) {
00119         for (i = 0; i < list->n_values; i++) {
00120             G_debug(3, "  area = %d pointer to area structure = %lx",
00121                     list->value[i],
00122                     (unsigned long)Map->plus.Area[list->value[i]]);
00123         }
00124     }
00125     
00126     return list->n_values;
00127 }
00128 
00129 
00142 int
00143 Vect_select_isles_by_box(struct Map_info *Map, BOUND_BOX * Box,
00144                          struct ilist *list)
00145 {
00146     G_debug(3, "Vect_select_isles_by_box()");
00147     G_debug(3, "Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
00148             Box->E, Box->W, Box->T, Box->B);
00149 
00150     if (!(Map->plus.Spidx_built)) {
00151         G_debug(3, "Building spatial index.");
00152         Vect_build_sidx_from_topo(Map);
00153     }
00154 
00155     dig_select_isles(&(Map->plus), Box, list);
00156     G_debug(3, "  %d isles selected", list->n_values);
00157 
00158     return list->n_values;
00159 }
00160 
00170 int
00171 Vect_select_nodes_by_box(struct Map_info *Map, BOUND_BOX * Box,
00172                          struct ilist *list)
00173 {
00174     struct Plus_head *plus;
00175 
00176     G_debug(3, "Vect_select_nodes_by_box()");
00177     G_debug(3, "Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
00178             Box->E, Box->W, Box->T, Box->B);
00179 
00180     plus = &(Map->plus);
00181 
00182     if (!(plus->Spidx_built)) {
00183         G_debug(3, "Building spatial index.");
00184         Vect_build_sidx_from_topo(Map);
00185     }
00186 
00187     list->n_values = 0;
00188 
00189     dig_select_nodes(plus, Box, list);
00190     G_debug(3, "  %d nodes selected", list->n_values);
00191 
00192     return list->n_values;
00193 }
00194 
00209 int
00210 Vect_select_lines_by_polygon(struct Map_info *Map, struct line_pnts *Polygon,
00211                              int nisles, struct line_pnts **Isles, int type,
00212                              struct ilist *List)
00213 {
00214     int i;
00215     BOUND_BOX box;
00216     static struct line_pnts *LPoints = NULL;
00217     static struct ilist *LocList = NULL;
00218 
00219     /* TODO: this function was not tested with isles */
00220     G_debug(3, "Vect_select_lines_by_polygon() nisles = %d", nisles);
00221 
00222     List->n_values = 0;
00223     if (!LPoints)
00224         LPoints = Vect_new_line_struct();
00225     if (!LocList)
00226         LocList = Vect_new_list();
00227 
00228     /* Select first all lines by box */
00229     dig_line_box(Polygon, &box);
00230     box.T = PORT_DOUBLE_MAX;
00231     box.B = -PORT_DOUBLE_MAX;
00232     Vect_select_lines_by_box(Map, &box, type, LocList);
00233     G_debug(3, "  %d lines selected by box", LocList->n_values);
00234 
00235     /* Check all lines if intersect the polygon */
00236     for (i = 0; i < LocList->n_values; i++) {
00237         int j, line, intersect = 0;
00238 
00239         line = LocList->value[i];
00240         /* Read line points */
00241         Vect_read_line(Map, LPoints, NULL, line);
00242 
00243         /* Check if any of line vertices is within polygon */
00244         for (j = 0; j < LPoints->n_points; j++) {
00245             if (Vect_point_in_poly(LPoints->x[j], LPoints->y[j], Polygon) >= 1) {       /* inside polygon */
00246                 int k, inisle = 0;
00247 
00248                 for (k = 0; k < nisles; k++) {
00249                     if (Vect_point_in_poly(LPoints->x[j], LPoints->y[j], Isles[k]) >= 1) {      /* in isle */
00250                         inisle = 1;
00251                         break;
00252                     }
00253                 }
00254 
00255                 if (!inisle) {  /* inside polygon, outside isles -> select */
00256                     intersect = 1;
00257                     break;
00258                 }
00259             }
00260         }
00261         if (intersect) {
00262             dig_list_add(List, line);
00263             continue;
00264         }
00265 
00266         /* Check intersections of the line with area/isles boundary */
00267         /* Outer boundary */
00268         if (Vect_line_check_intersection(LPoints, Polygon, 0)) {
00269             dig_list_add(List, line);
00270             continue;
00271         }
00272 
00273         /* Islands */
00274         for (j = 0; j < nisles; j++) {
00275             if (Vect_line_check_intersection(LPoints, Isles[j], 0)) {
00276                 intersect = 1;
00277                 break;
00278             }
00279         }
00280         if (intersect) {
00281             dig_list_add(List, line);
00282         }
00283     }
00284 
00285     G_debug(4, "  %d lines selected by polygon", List->n_values);
00286 
00287     return List->n_values;
00288 }
00289 
00290 
00307 int
00308 Vect_select_areas_by_polygon(struct Map_info *Map, struct line_pnts *Polygon,
00309                              int nisles, struct line_pnts **Isles,
00310                              struct ilist *List)
00311 {
00312     int i, area;
00313     static struct ilist *BoundList = NULL;
00314 
00315     /* TODO: this function was not tested with isles */
00316     G_debug(3, "Vect_select_areas_by_polygon() nisles = %d", nisles);
00317 
00318     List->n_values = 0;
00319     if (!BoundList)
00320         BoundList = Vect_new_list();
00321 
00322     /* Select boundaries by polygon */
00323     Vect_select_lines_by_polygon(Map, Polygon, nisles, Isles, GV_BOUNDARY,
00324                                  BoundList);
00325 
00326     /* Add areas on left/right side of selected boundaries */
00327     for (i = 0; i < BoundList->n_values; i++) {
00328         int line, left, right;
00329 
00330         line = BoundList->value[i];
00331 
00332         Vect_get_line_areas(Map, line, &left, &right);
00333         G_debug(4, "boundary = %d left = %d right = %d", line, left, right);
00334 
00335         if (left > 0) {
00336             dig_list_add(List, left);
00337         }
00338         else if (left < 0) {    /* island */
00339             area = Vect_get_isle_area(Map, abs(left));
00340             G_debug(4, "  left island -> area = %d", area);
00341             if (area > 0)
00342                 dig_list_add(List, area);
00343         }
00344 
00345         if (right > 0) {
00346             dig_list_add(List, right);
00347         }
00348         else if (right < 0) {   /* island */
00349             area = Vect_get_isle_area(Map, abs(right));
00350             G_debug(4, "  right island -> area = %d", area);
00351             if (area > 0)
00352                 dig_list_add(List, area);
00353         }
00354     }
00355 
00356     /* But the Polygon may be completely inside the area (only one), in that case 
00357      * we find the area by one polygon point and add it to the list */
00358     area = Vect_find_area(Map, Polygon->x[0], Polygon->y[0]);
00359     if (area > 0)
00360         dig_list_add(List, area);
00361 
00362     G_debug(3, "  %d areas selected by polygon", List->n_values);
00363 
00364     return List->n_values;
00365 }