sindex.c

Go to the documentation of this file.
00001 /****************************************************************************
00002 *
00003 * MODULE:       Vector library 
00004 *               
00005 * AUTHOR(S):    Radim Blazek
00006 *
00007 * PURPOSE:      Lower level functions for reading/writing/manipulating vectors.
00008 *
00009 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00010 *
00011 *               This program is free software under the GNU General Public
00012 *               License (>=v2). Read the file COPYING that comes with GRASS
00013 *               for details.
00014 *
00015 *****************************************************************************/
00016 #include <stdlib.h>
00017 #include <string.h>
00018 #include <grass/glocale.h>
00019 #include <grass/gis.h>
00020 #include <grass/Vect.h>
00021 
00027 void 
00028 Vect_spatial_index_init ( SPATIAL_INDEX *si ) 
00029 {
00030     G_debug(1, "Vect_spatial_index_init()");
00031     
00032     si->root = RTreeNewIndex();
00033 }
00034 
00040 void 
00041 Vect_spatial_index_destroy ( SPATIAL_INDEX *si ) 
00042 {
00043     G_debug(1, "Vect_spatial_index_destroy()");
00044     
00045     RTreeDestroyNode ( si->root );
00046 }
00047 
00055 void 
00056 Vect_spatial_index_add_item ( SPATIAL_INDEX *si, int id, BOUND_BOX *box ) 
00057 {
00058     struct Rect rect;
00059     
00060     G_debug(3, "Vect_spatial_index_add_item(): id = %d", id );
00061 
00062     rect.boundary[0] = box->W; rect.boundary[1] = box->S; rect.boundary[2] = box->B;
00063     rect.boundary[3] = box->E; rect.boundary[4] = box->N; rect.boundary[5] = box->T;
00064     RTreeInsertRect( &rect, id, &(si->root), 0);
00065 }
00066 
00073 void 
00074 Vect_spatial_index_del_item ( SPATIAL_INDEX *si, int id ) 
00075 {
00076     int    ret;
00077     struct Rect rect;
00078     
00079     G_debug(3, "Vect_spatial_index_del_item(): id = %d", id );
00080 
00081     /* TODO */
00082     G_fatal_error ( "Vect_spatial_index_del_item() not implemented" );
00083 
00084     /* Bounding box of item would be needed, which is not stored in si. */
00085     
00086     /* 
00087     rect.boundary[0] = ; rect.boundary[1] = ; rect.boundary[2] = ;
00088     rect.boundary[3] = ; rect.boundary[4] = ; rect.boundary[5] = ;
00089     */
00090     
00091     ret = RTreeDeleteRect( &rect, id, &(si->root) ); 
00092 
00093     if ( ret ) G_fatal_error ( "Cannot delete item %d from spatial index", id );
00094 }
00095 
00104 int 
00105 Vect_build_spatial_index ( struct Map_info *Map, FILE *msgout ) 
00106 {
00107     if ( Map->level < 2 ) {
00108         G_fatal_error ( _( "Cannot build spatial index from topology, the map is not opened on level2"));
00109     }
00110     if ( !(Map->plus.Spidx_built) ) {
00111         return ( Vect_build_sidx_from_topo ( Map, msgout ) );
00112     }
00113     return 0;
00114 }
00115 
00123 int 
00124 Vect_build_sidx_from_topo ( struct Map_info *Map, FILE *msgout ) 
00125 {
00126     int  i, total, done;
00127     struct Plus_head *plus;
00128     BOUND_BOX box;
00129     P_LINE *Line;
00130     P_NODE *Node;
00131     P_AREA *Area;
00132     P_ISLE *Isle;
00133 
00134     G_debug ( 3, "Vect_build_sidx_from_topo()" );
00135 
00136     plus = &(Map->plus);
00137 
00138     dig_spidx_init ( plus );
00139 
00140     total = plus->n_nodes + plus->n_lines + plus->n_areas + plus->n_isles;
00141 
00142     /* Nodes */
00143     for (i = 1; i <= plus->n_nodes; i++) {
00144         G_percent2 ( i, total, 1, msgout );
00145         
00146         Node = plus->Node[i];
00147         if ( !Node ) G_fatal_error ("BUG (Vect_build_sidx_from_topo): node does not exist");
00148 
00149         dig_spidx_add_node ( plus, i, Node->x, Node->y, Node->z );
00150     }
00151 
00152     /* Lines */
00153     done = plus->n_nodes;
00154     for (i = 1; i <= plus->n_lines; i++) {
00155         G_percent2 ( done+i, total, 1, msgout );
00156 
00157         Line = plus->Line[i];
00158         if ( !Line ) G_fatal_error ("BUG (Vect_build_sidx_from_topo): line does not exist");
00159 
00160         box.N = Line->N;
00161         box.S = Line->S;
00162         box.E = Line->E;
00163         box.W = Line->W;
00164         box.T = Line->T;
00165         box.B = Line->B;
00166 
00167         dig_spidx_add_line ( plus, i, &box );
00168     }
00169     
00170     /* Areas */
00171     done += plus->n_lines;
00172     for (i = 1; i <= plus->n_areas; i++) {
00173         G_percent2 ( done+i, total, 1, msgout );
00174         
00175         Area = plus->Area[i];
00176         if ( !Area ) G_fatal_error ("BUG (Vect_build_sidx_from_topo): area does not exist");
00177 
00178         box.N = Area->N;
00179         box.S = Area->S;
00180         box.E = Area->E;
00181         box.W = Area->W;
00182         box.T = Area->T;
00183         box.B = Area->B;
00184 
00185         dig_spidx_add_area ( plus, i, &box );
00186     }
00187 
00188     /* Isles */
00189     done += plus->n_areas;
00190     for (i = 1; i <= plus->n_isles; i++) {
00191         G_percent2 ( done+i, total, 1, msgout );
00192 
00193         Isle = plus->Isle[i];
00194         if ( !Isle ) G_fatal_error ("BUG (Vect_build_sidx_from_topo): isle does not exist");
00195 
00196         box.N = Isle->N;
00197         box.S = Isle->S;
00198         box.E = Isle->E;
00199         box.W = Isle->W;
00200         box.T = Isle->T;
00201         box.B = Isle->B;
00202 
00203         dig_spidx_add_isle ( plus, i, &box );
00204     }
00205 
00206     Map->plus.Spidx_built = 1;
00207     
00208     G_debug ( 3, "Spatial index was built" );
00209 
00210     return 0;
00211 }
00212 
00213 /************************* SELECT BY BOX *********************************/
00214 /* This function is called by  RTreeSearch() to add selected item to the list */
00215 static int _add_item(int id, struct ilist *list)
00216 {
00217     dig_list_add ( list, id );
00218     return 1;
00219 }
00220 
00229 int
00230 Vect_spatial_index_select ( SPATIAL_INDEX *si, BOUND_BOX *box, struct ilist *list ) 
00231 {
00232     struct Rect rect;
00233     
00234     G_debug(3, "Vect_spatial_index_select()" );
00235     
00236     list->n_values = 0;
00237 
00238     rect.boundary[0] = box->W; rect.boundary[1] = box->S; rect.boundary[2] = box->B;
00239     rect.boundary[3] = box->E; rect.boundary[4] = box->N; rect.boundary[5] = box->T;
00240     RTreeSearch( si->root, &rect, (void *) _add_item, list);
00241     
00242     G_debug(3, "  %d items selected", list->n_values );
00243     return ( list->n_values );
00244 }
00245 

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