GRASS Programmer's Manual  6.4.3(2013)-r
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Macros Pages
sindex.c
Go to the documentation of this file.
1 
20 #include <stdlib.h>
21 #include <string.h>
22 #include <grass/glocale.h>
23 #include <grass/gis.h>
24 #include <grass/Vect.h>
25 #include <grass/glocale.h>
26 
34 void Vect_spatial_index_init(SPATIAL_INDEX * si)
35 {
36  G_debug(1, "Vect_spatial_index_init()");
37 
38  si->root = RTreeNewIndex();
39 }
40 
50 void Vect_spatial_index_destroy(SPATIAL_INDEX * si)
51 {
52  G_debug(1, "Vect_spatial_index_destroy()");
53 
54  RTreeDestroyNode(si->root);
55 }
56 
66 void Vect_spatial_index_add_item(SPATIAL_INDEX * si, int id, BOUND_BOX * box)
67 {
68  struct Rect rect;
69 
70  G_debug(3, "Vect_spatial_index_add_item(): id = %d", id);
71 
72  rect.boundary[0] = box->W;
73  rect.boundary[1] = box->S;
74  rect.boundary[2] = box->B;
75  rect.boundary[3] = box->E;
76  rect.boundary[4] = box->N;
77  rect.boundary[5] = box->T;
78  RTreeInsertRect(&rect, id, &(si->root), 0);
79 }
80 
89 void Vect_spatial_index_del_item(SPATIAL_INDEX * si, int id)
90 {
91  int ret;
92  struct Rect rect;
93 
94  G_debug(3, "Vect_spatial_index_del_item(): id = %d", id);
95 
96  /* TODO */
97  G_fatal_error("Vect_spatial_index_del_item() %s", _("not implemented"));
98 
99  /* Bounding box of item would be needed, which is not stored in si. */
100 
101  /*
102  rect.boundary[0] = ; rect.boundary[1] = ; rect.boundary[2] = ;
103  rect.boundary[3] = ; rect.boundary[4] = ; rect.boundary[5] = ;
104  */
105 
106  ret = RTreeDeleteRect(&rect, id, &(si->root));
107 
108  if (ret)
109  G_fatal_error(_("Unable to delete item %d from spatial index"), id);
110 }
111 
124 int Vect_build_spatial_index(struct Map_info *Map)
125 {
126  if (Map->level < 2) {
127  G_fatal_error(_("Unable to build spatial index from topology, "
128  "vector map is not opened at topo level 2"));
129  }
130  if (!(Map->plus.Spidx_built)) {
131  return (Vect_build_sidx_from_topo(Map));
132  }
133  return 0;
134 }
135 
144 int Vect_build_sidx_from_topo(struct Map_info *Map)
145 {
146  int i, total, done;
147  struct Plus_head *plus;
148  BOUND_BOX box;
149  P_LINE *Line;
150  P_NODE *Node;
151  P_AREA *Area;
152  P_ISLE *Isle;
153 
154  G_debug(3, "Vect_build_sidx_from_topo()");
155 
156  plus = &(Map->plus);
157 
158  dig_spidx_init(plus);
159 
160  total = plus->n_nodes + plus->n_lines + plus->n_areas + plus->n_isles;
161 
162  /* Nodes */
163  for (i = 1; i <= plus->n_nodes; i++) {
164  G_percent(i, total, 3);
165 
166  Node = plus->Node[i];
167  if (!Node)
168  G_fatal_error(_("BUG (Vect_build_sidx_from_topo): node does not exist"));
169 
170  dig_spidx_add_node(plus, i, Node->x, Node->y, Node->z);
171  }
172 
173  /* Lines */
174  done = plus->n_nodes;
175  for (i = 1; i <= plus->n_lines; i++) {
176  G_percent(done + i, total, 3);
177 
178  Line = plus->Line[i];
179  if (!Line)
180  G_fatal_error(_("BUG (Vect_build_sidx_from_topo): line does not exist"));
181 
182  box.N = Line->N;
183  box.S = Line->S;
184  box.E = Line->E;
185  box.W = Line->W;
186  box.T = Line->T;
187  box.B = Line->B;
188 
189  dig_spidx_add_line(plus, i, &box);
190  }
191 
192  /* Areas */
193  done += plus->n_lines;
194  for (i = 1; i <= plus->n_areas; i++) {
195  G_percent(done + i, total, 3);
196 
197  Area = plus->Area[i];
198  if (!Area)
199  G_fatal_error(_("BUG (Vect_build_sidx_from_topo): area does not exist"));
200 
201  box.N = Area->N;
202  box.S = Area->S;
203  box.E = Area->E;
204  box.W = Area->W;
205  box.T = Area->T;
206  box.B = Area->B;
207 
208  dig_spidx_add_area(plus, i, &box);
209  }
210 
211  /* Isles */
212  done += plus->n_areas;
213  for (i = 1; i <= plus->n_isles; i++) {
214  G_percent(done + i, total, 3);
215 
216  Isle = plus->Isle[i];
217  if (!Isle)
218  G_fatal_error(_("BUG (Vect_build_sidx_from_topo): isle does not exist"));
219 
220  box.N = Isle->N;
221  box.S = Isle->S;
222  box.E = Isle->E;
223  box.W = Isle->W;
224  box.T = Isle->T;
225  box.B = Isle->B;
226 
227  dig_spidx_add_isle(plus, i, &box);
228  }
229 
230  Map->plus.Spidx_built = 1;
231 
232  G_debug(3, "Spatial index was built");
233 
234  return 0;
235 }
236 
237 /************************* SELECT BY BOX *********************************/
238 /* This function is called by RTreeSearch() to add selected item to the list */
239 static int _add_item(int id, struct ilist *list)
240 {
241  dig_list_add(list, id);
242  return 1;
243 }
244 
254 int
255 Vect_spatial_index_select(SPATIAL_INDEX * si, BOUND_BOX * box,
256  struct ilist *list)
257 {
258  struct Rect rect;
259 
260  G_debug(3, "Vect_spatial_index_select()");
261 
262  list->n_values = 0;
263 
264  rect.boundary[0] = box->W;
265  rect.boundary[1] = box->S;
266  rect.boundary[2] = box->B;
267  rect.boundary[3] = box->E;
268  rect.boundary[4] = box->N;
269  rect.boundary[5] = box->T;
270  RTreeSearch(si->root, &rect, (void *)_add_item, list);
271 
272  G_debug(3, " %d items selected", list->n_values);
273  return (list->n_values);
274 }