spindex.c

Go to the documentation of this file.
00001 /*
00002 * $Id: spindex.c,v 1.10 2006/02/09 03:08:58 glynn Exp $
00003 *
00004 ****************************************************************************
00005 *
00006 * MODULE:       Vector library 
00007 *               
00008 * AUTHOR(S):    Original author CERL, probably Dave Gerdes.
00009 *               Update to GRASS 5.7 Radim Blazek.
00010 *
00011 * PURPOSE:      Lower level functions for reading/writing/manipulating vectors.
00012 *
00013 * COPYRIGHT:    (C) 2001 by the GRASS Development Team
00014 *
00015 *               This program is free software under the GNU General Public
00016 *               License (>=v2). Read the file COPYING that comes with GRASS
00017 *               for details.
00018 *
00019 *****************************************************************************/
00020 #include <stdlib.h>
00021 #include <string.h>
00022 #include <grass/gis.h>
00023 #include <grass/Vect.h>
00024 
00025 /* 
00026 *  dig_spindex_init ()
00027 *  initit spatial index (nodes, lines, areas, isles)
00028 *
00029 *  returns 1 OK
00030 *          0 on error      
00031 */
00032 int 
00033 dig_spidx_init ( struct Plus_head *Plus) 
00034 {
00035     
00036     G_debug(1, "dig_spidx_init()");
00037     
00038     Plus->Node_spidx = RTreeNewIndex();
00039     Plus->Line_spidx = RTreeNewIndex();
00040     Plus->Area_spidx = RTreeNewIndex();
00041     Plus->Isle_spidx = RTreeNewIndex();
00042 
00043     Plus->Node_spidx_offset = 0L;
00044     Plus->Edge_spidx_offset = 0L;
00045     Plus->Line_spidx_offset = 0L;
00046     Plus->Area_spidx_offset = 0L;
00047     Plus->Isle_spidx_offset = 0L;
00048     Plus->Volume_spidx_offset = 0L;
00049     Plus->Hole_spidx_offset = 0L;
00050 
00051     return 1;
00052 }
00053 
00054 void
00055 dig_spidx_free_nodes ( struct Plus_head *Plus) {
00056     RTreeDestroyNode ( Plus->Node_spidx );
00057     Plus->Node_spidx = RTreeNewIndex();
00058 }
00059 void
00060 dig_spidx_free_lines ( struct Plus_head *Plus) {
00061     RTreeDestroyNode ( Plus->Line_spidx );
00062     Plus->Line_spidx = RTreeNewIndex();
00063 }
00064 void
00065 dig_spidx_free_areas ( struct Plus_head *Plus) {
00066     RTreeDestroyNode ( Plus->Area_spidx );
00067     Plus->Area_spidx = RTreeNewIndex();
00068 }
00069 void
00070 dig_spidx_free_isles ( struct Plus_head *Plus) {
00071     RTreeDestroyNode ( Plus->Isle_spidx );
00072     Plus->Isle_spidx = RTreeNewIndex();
00073 }
00074 
00075 /* 
00076 *  dig_spidx_free ()
00077 *  free spatial index (nodes, lines, areas, isles)
00078 *
00079 */
00080 void 
00081 dig_spidx_free ( struct Plus_head *Plus) 
00082 {
00083     dig_spidx_free_nodes ( Plus );
00084     dig_spidx_free_lines ( Plus );
00085     dig_spidx_free_areas ( Plus );
00086     dig_spidx_free_isles ( Plus );
00087 }
00088 
00089 /************************* ADD NEW *********************************/
00090 /* 
00091 *  dig_spindex_add_node ()
00092 *  add new node to spatial index 
00093 *
00094 *  returns 1 OK
00095 *          0 on error      
00096 */
00097 int 
00098 dig_spidx_add_node ( struct Plus_head *Plus, int node, 
00099                        double x, double y, double z) 
00100 {
00101     struct Rect rect;
00102     
00103     G_debug(3, "dig_spidx_add_node(): node = %d, x,y,z = %f, %f, %f", node, x, y, z );
00104 
00105     rect.boundary[0] = x; rect.boundary[1] = y; rect.boundary[2] = z;
00106     rect.boundary[3] = x; rect.boundary[4] = y; rect.boundary[5] = z;
00107     RTreeInsertRect( &rect, node, &(Plus->Node_spidx), 0);
00108 
00109     return 1;
00110 }
00111 
00112 /* 
00113 *  dig_spindex_add_line ()
00114 *  add new line to spatial index 
00115 *
00116 *  returns 1 OK
00117 *          0 on error      
00118 */
00119 int 
00120 dig_spidx_add_line ( struct Plus_head *Plus, int line, BOUND_BOX *box ) 
00121 {
00122     struct Rect rect;
00123     
00124     G_debug(3, "dig_spidx_add_line(): line = %d", line );
00125 
00126     rect.boundary[0] = box->W; rect.boundary[1] = box->S; rect.boundary[2] = box->B;
00127     rect.boundary[3] = box->E; rect.boundary[4] = box->N; rect.boundary[5] = box->T;
00128     RTreeInsertRect( &rect, line, &(Plus->Line_spidx), 0);
00129 
00130     return 0;
00131 }
00132 
00133 /* 
00134 *  dig_spindex_add_area ()
00135 *  add new area to spatial index 
00136 *
00137 *  returns 1 OK
00138 *          0 on error      
00139 */
00140 int 
00141 dig_spidx_add_area ( struct Plus_head *Plus, int area, BOUND_BOX *box ) 
00142 {
00143     struct Rect rect;
00144     
00145     G_debug(3, "dig_spidx_add_area(): area = %d", area );
00146 
00147     rect.boundary[0] = box->W; rect.boundary[1] = box->S; rect.boundary[2] = box->B;
00148     rect.boundary[3] = box->E; rect.boundary[4] = box->N; rect.boundary[5] = box->T;
00149     RTreeInsertRect( &rect, area, &(Plus->Area_spidx), 0);
00150 
00151     return 0;
00152 }
00153 
00154 /* 
00155 *  dig_spindex_add_isle ()
00156 *  add new island to spatial index 
00157 *
00158 *  returns 1 OK
00159 *          0 on error      
00160 */
00161 
00162 int 
00163 dig_spidx_add_isle ( struct Plus_head *Plus, int isle, BOUND_BOX *box ) 
00164 {
00165     struct Rect rect;
00166     
00167     G_debug(3, "dig_spidx_add_isle(): isle = %d", isle );
00168 
00169     rect.boundary[0] = box->W; rect.boundary[1] = box->S; rect.boundary[2] = box->B;
00170     rect.boundary[3] = box->E; rect.boundary[4] = box->N; rect.boundary[5] = box->T;
00171     RTreeInsertRect( &rect, isle, &(Plus->Isle_spidx), 0);
00172 
00173     return 0;
00174 }
00175 
00176 /* 
00177 *  dig_spindex_del_node ()
00178 *  delete node from spatial index 
00179 *
00180 *  returns 1 OK
00181 *          0 on error      
00182 */
00183 int 
00184 dig_spidx_del_node ( struct Plus_head *Plus, int node ) 
00185 {
00186     int    ret;
00187     P_NODE *Node; 
00188     struct Rect rect;
00189     
00190     G_debug(3, "dig_spidx_del_node(): node = %d", node );
00191 
00192     Node = Plus->Node[node];
00193 
00194     rect.boundary[0] = Node->x; rect.boundary[1] = Node->y; rect.boundary[2] = Node->z;
00195     rect.boundary[3] = Node->x; rect.boundary[4] = Node->y; rect.boundary[5] = Node->z;
00196     
00197     ret = RTreeDeleteRect( &rect, node, &(Plus->Node_spidx) ); 
00198 
00199     if ( ret ) G_fatal_error ( "Cannot delete node %d from spatial index", node );
00200     
00201     return 0;
00202 }
00203 
00204 /* 
00205 *  dig_spindex_del_line ()
00206 *  delete line from spatial index 
00207 *
00208 *  returns 1 OK
00209 *          0 on error      
00210 */
00211 int 
00212 dig_spidx_del_line ( struct Plus_head *Plus, int line ) 
00213 {
00214     P_LINE *Line; 
00215     struct Rect rect;
00216     int ret;
00217     
00218     G_debug(3, "dig_spidx_del_line(): line = %d", line );
00219 
00220     Line = Plus->Line[line];
00221 
00222     G_debug(3, "  box(x1,y1,z1,x2,y2,z2): %f %f %f %f %f %f",Line->W,Line->S,Line->B,Line->E,Line->N, Line->T );
00223 
00224     rect.boundary[0] = Line->W; rect.boundary[1] = Line->S; rect.boundary[2] = Line->B;
00225     rect.boundary[3] = Line->E; rect.boundary[4] = Line->N; rect.boundary[5] = Line->T;
00226     
00227     ret = RTreeDeleteRect( &rect, line, &(Plus->Line_spidx) ); 
00228     
00229     G_debug(3, "  ret = %d", ret );
00230     
00231     if ( ret ) G_fatal_error ( "Cannot delete line %d from spatial index", line );
00232 
00233     return 0;
00234 }
00235 
00236 /* 
00237 *  dig_spindex_del_area ()
00238 *  delete area from spatial index 
00239 *
00240 *  returns 1 OK
00241 *          0 on error      
00242 */
00243 int 
00244 dig_spidx_del_area ( struct Plus_head *Plus, int area ) 
00245 {
00246     int ret;
00247     P_AREA *Area; 
00248     struct Rect rect;
00249     
00250     G_debug(3, "dig_spidx_del_area(): area = %d", area );
00251 
00252     Area = Plus->Area[area];
00253 
00254     if (Area == NULL) {
00255         G_fatal_error ("Attempt to delete sidx for dead area");
00256     }
00257 
00258     rect.boundary[0] = Area->W; rect.boundary[1] = Area->S; rect.boundary[2] = Area->B;
00259     rect.boundary[3] = Area->E; rect.boundary[4] = Area->N; rect.boundary[5] = Area->T;
00260     
00261     ret = RTreeDeleteRect( &rect, area, &(Plus->Area_spidx) ); 
00262 
00263     if ( ret ) G_fatal_error ( "Cannot delete area %d from spatial index", area );
00264     
00265     return 0;
00266 }
00267 
00268 /* 
00269 *  dig_spindex_del_isle ()
00270 *  delete isle from spatial index 
00271 *
00272 *  returns 1 OK
00273 *          0 on error      
00274 */
00275 int 
00276 dig_spidx_del_isle ( struct Plus_head *Plus, int isle ) 
00277 {
00278     int ret;
00279     P_ISLE *Isle; 
00280     struct Rect rect;
00281     
00282     G_debug(3, "dig_spidx_del_isle(): isle = %d", isle );
00283 
00284     Isle = Plus->Isle[isle];
00285 
00286     rect.boundary[0] = Isle->W; rect.boundary[1] = Isle->S; rect.boundary[2] = Isle->B;
00287     rect.boundary[3] = Isle->E; rect.boundary[4] = Isle->N; rect.boundary[5] = Isle->T;
00288 
00289     ret = RTreeDeleteRect( &rect, isle, &(Plus->Isle_spidx) ); 
00290 
00291     if ( ret ) G_fatal_error ( "Cannot delete isle %d from spatial index", isle );
00292     
00293     return 0;
00294 }
00295 /************************* SELECT BY BOX *********************************/
00296 /* This function is called by  RTreeSearch() to add selected node/line/area/isle to thelist */
00297 static int _add_item(int id, struct ilist *list)
00298 {
00299     dig_list_add ( list, id );
00300     return 1;
00301 }
00302 /* 
00303 *  dig_select_nodes ()
00304 *  select nodes by bbox 
00305 *
00306 *  returns: number of selected nodes
00307 *           -1 error
00308 */
00309 int 
00310 dig_select_nodes ( struct Plus_head *Plus, BOUND_BOX *box, struct ilist *list ) 
00311 {
00312     struct Rect rect;
00313     
00314     G_debug(3, "dig_select_nodes()" );
00315     
00316     list->n_values = 0;
00317 
00318     rect.boundary[0] = box->W; rect.boundary[1] = box->S; rect.boundary[2] = box->B;
00319     rect.boundary[3] = box->E; rect.boundary[4] = box->N; rect.boundary[5] = box->T;
00320     RTreeSearch( Plus->Node_spidx, &rect, (void *) _add_item, list);
00321     
00322     return ( list->n_values );
00323 }
00324 
00325 /* This function is called by  RTreeSearch() for nodes to add selected node to list */
00326 static int _add_node(int id, int *node)
00327 {
00328     *node = id;
00329     return 0;
00330 }
00331 
00332 /* 
00333 *  dig_find_node ()
00334 *  find one node by coordinates 
00335 *
00336 *  returns: number of node
00337 *           0 not found
00338 */
00339 int 
00340 dig_find_node ( struct Plus_head *Plus, double x, double y, double z ) 
00341 {
00342     struct Rect rect;
00343     struct ilist list;
00344     int    node;
00345     
00346     G_debug(3, "dig_find_node()" );
00347     
00348     dig_init_list ( &list );
00349     
00350     rect.boundary[0] = x; rect.boundary[1] = y; rect.boundary[2] = z;
00351     rect.boundary[3] = x; rect.boundary[4] = y; rect.boundary[5] = z;
00352 
00353     node = 0; 
00354     RTreeSearch( Plus->Node_spidx, &rect, (void *) _add_node, &node);
00355 
00356     return node;
00357 }
00358 
00359 /* 
00360 *  dig_select_lines ()
00361 *  select lines by box 
00362 *
00363 *  returns: number of selected lines
00364 */
00365 int 
00366 dig_select_lines ( struct Plus_head *Plus, BOUND_BOX *box, struct ilist *list ) 
00367 {
00368     struct Rect rect;
00369     
00370     G_debug(3, "dig_select_lines()" );
00371     
00372     list->n_values = 0;
00373 
00374     rect.boundary[0] = box->W; rect.boundary[1] = box->S; rect.boundary[2] = box->B;
00375     rect.boundary[3] = box->E; rect.boundary[4] = box->N; rect.boundary[5] = box->T;
00376     RTreeSearch( Plus->Line_spidx, &rect, (void *) _add_item, list);
00377     
00378     return ( list->n_values );
00379 }
00380 
00381 /* 
00382 *  dig_select_areas ()
00383 *  select areas by box 
00384 *
00385 *  returns: number of selected areas
00386 */
00387 int 
00388 dig_select_areas ( struct Plus_head *Plus, BOUND_BOX *box, struct ilist *list ) 
00389 {
00390     struct Rect rect;
00391     
00392     G_debug(3, "dig_select_areas()" );
00393     
00394     list->n_values = 0;
00395 
00396     rect.boundary[0] = box->W; rect.boundary[1] = box->S; rect.boundary[2] = box->B;
00397     rect.boundary[3] = box->E; rect.boundary[4] = box->N; rect.boundary[5] = box->T;
00398     RTreeSearch( Plus->Area_spidx, &rect, (void *) _add_item, list);
00399     
00400     return ( list->n_values );
00401 }
00402 
00403 /* 
00404 *  dig_select_isles ()
00405 *  select isles by box 
00406 *
00407 *  returns: number of selected isles
00408 */
00409 int 
00410 dig_select_isles ( struct Plus_head *Plus, BOUND_BOX *box, struct ilist *list ) 
00411 {
00412     struct Rect rect;
00413     
00414     G_debug(3, "dig_select_isles()" );
00415     
00416     list->n_values = 0;
00417 
00418     rect.boundary[0] = box->W; rect.boundary[1] = box->S; rect.boundary[2] = box->B;
00419     rect.boundary[3] = box->E; rect.boundary[4] = box->N; rect.boundary[5] = box->T;
00420     RTreeSearch( Plus->Isle_spidx, &rect, (void *) _add_item, list);
00421     
00422     return ( list->n_values );
00423 }
00424 
00425 

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