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
00097 G_fatal_error("Vect_spatial_index_del_item() %s", _("not implemented"));
00098
00099
00100
00101
00102
00103
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
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
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
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
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
00238
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 }