00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00082 G_fatal_error ( "Vect_spatial_index_del_item() not implemented" );
00083
00084
00085
00086
00087
00088
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
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
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
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
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
00214
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