GRASS Programmer's Manual
6.4.2(2012)
|
00001 00020 #include <stdlib.h> 00021 #include <string.h> 00022 #include <grass/glocale.h> 00023 #include <grass/gis.h> 00024 #include <grass/Vect.h> 00025 #include <grass/glocale.h> 00026 00034 void Vect_spatial_index_init(SPATIAL_INDEX * si) 00035 { 00036 G_debug(1, "Vect_spatial_index_init()"); 00037 00038 si->root = RTreeNewIndex(); 00039 } 00040 00050 void Vect_spatial_index_destroy(SPATIAL_INDEX * si) 00051 { 00052 G_debug(1, "Vect_spatial_index_destroy()"); 00053 00054 RTreeDestroyNode(si->root); 00055 } 00056 00066 void Vect_spatial_index_add_item(SPATIAL_INDEX * si, int id, BOUND_BOX * box) 00067 { 00068 struct Rect rect; 00069 00070 G_debug(3, "Vect_spatial_index_add_item(): id = %d", id); 00071 00072 rect.boundary[0] = box->W; 00073 rect.boundary[1] = box->S; 00074 rect.boundary[2] = box->B; 00075 rect.boundary[3] = box->E; 00076 rect.boundary[4] = box->N; 00077 rect.boundary[5] = box->T; 00078 RTreeInsertRect(&rect, id, &(si->root), 0); 00079 } 00080 00089 void Vect_spatial_index_del_item(SPATIAL_INDEX * si, int id) 00090 { 00091 int ret; 00092 struct Rect rect; 00093 00094 G_debug(3, "Vect_spatial_index_del_item(): id = %d", id); 00095 00096 /* TODO */ 00097 G_fatal_error("Vect_spatial_index_del_item() %s", _("not implemented")); 00098 00099 /* Bounding box of item would be needed, which is not stored in si. */ 00100 00101 /* 00102 rect.boundary[0] = ; rect.boundary[1] = ; rect.boundary[2] = ; 00103 rect.boundary[3] = ; rect.boundary[4] = ; rect.boundary[5] = ; 00104 */ 00105 00106 ret = RTreeDeleteRect(&rect, id, &(si->root)); 00107 00108 if (ret) 00109 G_fatal_error(_("Unable to delete item %d from spatial index"), id); 00110 } 00111 00124 int Vect_build_spatial_index(struct Map_info *Map) 00125 { 00126 if (Map->level < 2) { 00127 G_fatal_error(_("Unable to build spatial index from topology, " 00128 "vector map is not opened at topo level 2")); 00129 } 00130 if (!(Map->plus.Spidx_built)) { 00131 return (Vect_build_sidx_from_topo(Map)); 00132 } 00133 return 0; 00134 } 00135 00144 int Vect_build_sidx_from_topo(struct Map_info *Map) 00145 { 00146 int i, total, done; 00147 struct Plus_head *plus; 00148 BOUND_BOX box; 00149 P_LINE *Line; 00150 P_NODE *Node; 00151 P_AREA *Area; 00152 P_ISLE *Isle; 00153 00154 G_debug(3, "Vect_build_sidx_from_topo()"); 00155 00156 plus = &(Map->plus); 00157 00158 dig_spidx_init(plus); 00159 00160 total = plus->n_nodes + plus->n_lines + plus->n_areas + plus->n_isles; 00161 00162 /* Nodes */ 00163 for (i = 1; i <= plus->n_nodes; i++) { 00164 G_percent(i, total, 3); 00165 00166 Node = plus->Node[i]; 00167 if (!Node) 00168 G_fatal_error(_("BUG (Vect_build_sidx_from_topo): node does not exist")); 00169 00170 dig_spidx_add_node(plus, i, Node->x, Node->y, Node->z); 00171 } 00172 00173 /* Lines */ 00174 done = plus->n_nodes; 00175 for (i = 1; i <= plus->n_lines; i++) { 00176 G_percent(done + i, total, 3); 00177 00178 Line = plus->Line[i]; 00179 if (!Line) 00180 G_fatal_error(_("BUG (Vect_build_sidx_from_topo): line does not exist")); 00181 00182 box.N = Line->N; 00183 box.S = Line->S; 00184 box.E = Line->E; 00185 box.W = Line->W; 00186 box.T = Line->T; 00187 box.B = Line->B; 00188 00189 dig_spidx_add_line(plus, i, &box); 00190 } 00191 00192 /* Areas */ 00193 done += plus->n_lines; 00194 for (i = 1; i <= plus->n_areas; i++) { 00195 G_percent(done + i, total, 3); 00196 00197 Area = plus->Area[i]; 00198 if (!Area) 00199 G_fatal_error(_("BUG (Vect_build_sidx_from_topo): area does not exist")); 00200 00201 box.N = Area->N; 00202 box.S = Area->S; 00203 box.E = Area->E; 00204 box.W = Area->W; 00205 box.T = Area->T; 00206 box.B = Area->B; 00207 00208 dig_spidx_add_area(plus, i, &box); 00209 } 00210 00211 /* Isles */ 00212 done += plus->n_areas; 00213 for (i = 1; i <= plus->n_isles; i++) { 00214 G_percent(done + i, total, 3); 00215 00216 Isle = plus->Isle[i]; 00217 if (!Isle) 00218 G_fatal_error(_("BUG (Vect_build_sidx_from_topo): isle does not exist")); 00219 00220 box.N = Isle->N; 00221 box.S = Isle->S; 00222 box.E = Isle->E; 00223 box.W = Isle->W; 00224 box.T = Isle->T; 00225 box.B = Isle->B; 00226 00227 dig_spidx_add_isle(plus, i, &box); 00228 } 00229 00230 Map->plus.Spidx_built = 1; 00231 00232 G_debug(3, "Spatial index was built"); 00233 00234 return 0; 00235 } 00236 00237 /************************* SELECT BY BOX *********************************/ 00238 /* This function is called by RTreeSearch() to add selected item to the list */ 00239 static int _add_item(int id, struct ilist *list) 00240 { 00241 dig_list_add(list, id); 00242 return 1; 00243 } 00244 00254 int 00255 Vect_spatial_index_select(SPATIAL_INDEX * si, BOUND_BOX * box, 00256 struct ilist *list) 00257 { 00258 struct Rect rect; 00259 00260 G_debug(3, "Vect_spatial_index_select()"); 00261 00262 list->n_values = 0; 00263 00264 rect.boundary[0] = box->W; 00265 rect.boundary[1] = box->S; 00266 rect.boundary[2] = box->B; 00267 rect.boundary[3] = box->E; 00268 rect.boundary[4] = box->N; 00269 rect.boundary[5] = box->T; 00270 RTreeSearch(si->root, &rect, (void *)_add_item, list); 00271 00272 G_debug(3, " %d items selected", list->n_values); 00273 return (list->n_values); 00274 }