GRASS Programmer's Manual 6.4.1(2011)
sindex.c
Go to the documentation of this file.
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 }
 All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Defines