select.c

Go to the documentation of this file.
00001 /*
00002 ****************************************************************************
00003 *
00004 * MODULE:       Vector library 
00005 *               
00006 * AUTHOR(S):    Radim Blazek
00007 *
00008 * PURPOSE:      Higher level functions for reading/writing/manipulating vectors.
00009 *
00010 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00011 *
00012 *               This program is free software under the GNU General Public
00013 *               License (>=v2). Read the file COPYING that comes with GRASS
00014 *               for details.
00015 *
00016 *****************************************************************************/
00017 #include <stdlib.h>
00018 #include <grass/gis.h>
00019 #include <grass/Vect.h>
00020 
00032 int 
00033 Vect_select_lines_by_box (struct Map_info *Map, BOUND_BOX *Box, 
00034                                     int type, struct ilist *list)
00035 {
00036     int       i, line, nlines;
00037     struct    Plus_head *plus ;
00038     P_LINE    *Line;
00039     static struct ilist *LocList = NULL;
00040     
00041     G_debug ( 3, "Vect_select_lines_by_box()" );
00042     G_debug ( 3, "  Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
00043                            Box->E, Box->W, Box->T, Box->B);
00044     plus = &(Map->plus);
00045 
00046     if ( !(plus->Spidx_built) ) {
00047         G_debug ( 3, "Building spatial index." );
00048         Vect_build_sidx_from_topo ( Map, NULL );
00049     }
00050     
00051     list->n_values = 0; 
00052     if ( !LocList ) LocList = Vect_new_list();
00053     
00054     nlines = dig_select_lines ( plus, Box, LocList );
00055     G_debug ( 3, "  %d lines selected (all types)", nlines );
00056 
00057     /* Remove lines of not requested types */
00058     for ( i = 0; i < nlines; i++ ) { 
00059         line = LocList->value[i];
00060         if (  plus->Line[line] == NULL ) continue; /* Should not happen */
00061         Line = plus->Line[line];
00062         if ( !(Line->type & type) ) continue; 
00063         dig_list_add ( list, line ); 
00064     }
00065 
00066     G_debug ( 3, "  %d lines of requested type", list->n_values );
00067     
00068     return list->n_values;
00069 }
00070 
00080 int 
00081 Vect_select_areas_by_box (struct Map_info *Map, BOUND_BOX *Box, struct ilist *list)
00082 {
00083     int i;
00084     
00085     G_debug ( 3, "Vect_select_areas_by_box()" );
00086     G_debug ( 3, "Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
00087                            Box->E, Box->W, Box->T, Box->B);
00088 
00089     if ( !(Map->plus.Spidx_built) ) {
00090         G_debug ( 3, "Building spatial index." );
00091         Vect_build_sidx_from_topo ( Map, NULL );
00092     }
00093 
00094     dig_select_areas ( &(Map->plus), Box, list );
00095     G_debug ( 3, "  %d areas selected", list->n_values );
00096     for ( i = 0; i < list->n_values; i++ ) {
00097         G_debug ( 3, "  area = %d pointer to area structure = %d", list->value[i], 
00098                       Map->plus.Area[list->value[i]] );
00099             
00100     }
00101     return list->n_values;
00102 }
00103 
00104 
00114 int 
00115 Vect_select_isles_by_box (struct Map_info *Map, BOUND_BOX *Box, struct ilist *list)
00116 {
00117     G_debug ( 3, "Vect_select_isles_by_box()" );
00118     G_debug ( 3, "Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
00119                            Box->E, Box->W, Box->T, Box->B);
00120 
00121     if ( !(Map->plus.Spidx_built) ) {
00122         G_debug ( 3, "Building spatial index." );
00123         Vect_build_sidx_from_topo ( Map, NULL );
00124     }
00125     
00126     dig_select_isles ( &(Map->plus), Box, list );
00127     G_debug ( 3, "  %d isles selected", list->n_values );
00128     
00129     return list->n_values;
00130 }
00131 
00140 int 
00141 Vect_select_nodes_by_box (struct Map_info *Map, BOUND_BOX *Box, struct ilist *list)
00142 {
00143     struct    Plus_head *plus ;
00144     
00145     G_debug ( 3, "Vect_select_nodes_by_box()" );
00146     G_debug ( 3, "Box(N,S,E,W,T,B): %e, %e, %e, %e, %e, %e", Box->N, Box->S,
00147                            Box->E, Box->W, Box->T, Box->B);
00148 
00149     plus = &(Map->plus);
00150 
00151     if ( !(plus->Spidx_built) ) {
00152         G_debug ( 3, "Building spatial index." );
00153         Vect_build_sidx_from_topo ( Map, NULL );
00154     }
00155 
00156     list->n_values = 0; 
00157     
00158     dig_select_nodes ( plus, Box, list );
00159     G_debug ( 3, "  %d nodes selected", list->n_values );
00160     
00161     return list->n_values;
00162 }
00163 
00177 int 
00178 Vect_select_lines_by_polygon ( struct Map_info *Map, struct line_pnts *Polygon, int nisles,
00179                                struct line_pnts **Isles, int type, struct ilist *List)
00180 {
00181     int       i;
00182     BOUND_BOX box;
00183     static struct line_pnts *LPoints = NULL;
00184     static struct ilist *LocList = NULL;
00185     
00186     /* TODO: this function was not tested with isles */
00187     G_debug ( 3, "Vect_select_lines_by_polygon() nisles = %d", nisles );
00188 
00189     List->n_values = 0; 
00190     if ( !LPoints ) LPoints = Vect_new_line_struct();
00191     if ( !LocList ) LocList = Vect_new_list();
00192     
00193     /* Select first all lines by box */
00194     dig_line_box ( Polygon, &box );
00195     Vect_select_lines_by_box ( Map, &box, type, LocList);
00196     G_debug ( 3, "  %d lines selected by box", LocList->n_values );
00197 
00198     /* Check all lines if intersect the polygon */
00199     for ( i = 0; i < LocList->n_values; i++ ) { 
00200         int j, line, intersect = 0;
00201         
00202         line = LocList->value[i];
00203         /* Read line points */
00204         Vect_read_line (Map, LPoints, NULL, line);
00205 
00206         /* Check if any of line vertices is within polygon */
00207         for (j = 0; j < LPoints->n_points; j++ ) {
00208             if ( Vect_point_in_poly(LPoints->x[j], LPoints->y[j], Polygon) >= 1 ) { /* inside polygon */
00209                 int k, inisle = 0;
00210                 
00211                 for (k = 0; k < nisles; k++ ) {
00212                     if ( Vect_point_in_poly(LPoints->x[j], LPoints->y[j], Isles[k]) >= 1 ) { /* in isle */
00213                         inisle = 1;
00214                         break;
00215                     }
00216                 }
00217 
00218                 if ( !inisle ) { /* inside polygon, outside isles -> select */
00219                     intersect = 1;
00220                     break;
00221                 }
00222             }
00223         }
00224         if ( intersect ) {
00225             dig_list_add ( List, line );
00226             continue;
00227         }
00228 
00229         /* Check intersections of the line with area/isles boundary */
00230         /* Outer boundary */
00231         if ( Vect_line_check_intersection(LPoints, Polygon, 0) ) {
00232             dig_list_add ( List, line );
00233             continue;
00234         }
00235 
00236         /* Islands */
00237         for ( j = 0; j < nisles; j++ ) {
00238             if ( Vect_line_check_intersection(LPoints, Isles[j], 0) ) {
00239                 intersect = 1;
00240                 break;
00241             }
00242         }
00243         if ( intersect ) {
00244             dig_list_add ( List, line );
00245         }
00246     }
00247         
00248     G_debug ( 4, "  %d lines selected by polygon", List->n_values );
00249     
00250     return List->n_values;
00251 }
00252 
00253 
00267 int 
00268 Vect_select_areas_by_polygon ( struct Map_info *Map, struct line_pnts *Polygon, int nisles,
00269                                struct line_pnts **Isles, struct ilist *List)
00270 {
00271     int  i, area;
00272     static struct ilist *BoundList = NULL;
00273     
00274     /* TODO: this function was not tested with isles */
00275     G_debug ( 3, "Vect_select_areas_by_polygon() nisles = %d", nisles );
00276 
00277     List->n_values = 0; 
00278     if ( !BoundList ) BoundList = Vect_new_list();
00279     
00280     /* Select boundaries by polygon */
00281     Vect_select_lines_by_polygon ( Map, Polygon, nisles, Isles, GV_BOUNDARY, BoundList);
00282 
00283     /* Add areas on left/right side of selected boundaries */
00284     for ( i = 0; i < BoundList->n_values; i++ ) { 
00285         int line, left, right;
00286 
00287         line = BoundList->value[i];
00288 
00289         Vect_get_line_areas ( Map, line, &left, &right );
00290         G_debug (4, "boundary = %d left = %d right = %d", line, left, right );
00291 
00292         if ( left > 0 ) {
00293             dig_list_add ( List, left );
00294         } else if ( left < 0 ) { /* island */
00295             area = Vect_get_isle_area ( Map, abs(left) );
00296             G_debug (4, "  left island -> area = %d", area );
00297             if ( area > 0 ) dig_list_add ( List, area );
00298         }
00299 
00300         if ( right > 0 ) {
00301             dig_list_add ( List, right );
00302         } else if ( right < 0 ) { /* island */
00303             area = Vect_get_isle_area ( Map, abs(right) );
00304             G_debug (4, "  right island -> area = %d", area );
00305             if ( area > 0 ) dig_list_add ( List, area );
00306         }
00307     }
00308 
00309     /* But the Polygon may be completely inside the area (only one), in that case 
00310      * we find the area by one polygon point and add it to the list */
00311     area = Vect_find_area ( Map, Polygon->x[0], Polygon->y[0]);
00312     if ( area > 0 ) dig_list_add ( List, area );
00313 
00314     G_debug ( 3, "  %d areas selected by polygon", List->n_values );
00315     
00316     return List->n_values;
00317 }
00318     

Generated on Sun Apr 6 17:32:44 2008 for GRASS by  doxygen 1.5.5