GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-8828094037
vector/Vlib/select.c
Go to the documentation of this file.
1 /*!
2  \file lib/vector/Vlib/select.c
3 
4  \brief Vector library - spatial index
5 
6  Higher level functions for a custom spatial index.
7 
8  (C) 2001-2009 by the GRASS Development Team
9 
10  This program is free software under the GNU General Public License
11  (>=v2). Read the file COPYING that comes with GRASS for details.
12 
13  \author Radim Blazek
14  */
15 
16 #include <stdlib.h>
17 #include <unistd.h>
18 #include <sys/stat.h>
19 #include <string.h>
20 #include <grass/vector.h>
21 #include <grass/glocale.h>
22 
23 /*!
24  \brief Initialize spatial index structure
25 
26  \param si pointer to spatial index structure
27 
28  \return void
29  */
30 void Vect_spatial_index_init(struct spatial_index *si, int with_z)
31 {
32  G_debug(1, "Vect_spatial_index_init()");
33 
34  si->si_tree = RTreeCreateTree(-1, 0, 2 + (with_z != 0));
35 }
36 
37 /*!
38  \brief Destroy existing spatial index
39 
40  Vect_spatial_index_init() must be call before new use.
41 
42  \param si pointer to spatial index structure
43 
44  \return void
45  */
47 {
48  G_debug(1, "Vect_spatial_index_destroy()");
49 
51 }
52 
53 /*!
54  \brief Add a new item to spatial index structure
55 
56  \param[in,out] si pointer to spatial index structure
57  \param id item identifier
58  \param box pointer to item bounding box
59 
60  \return void
61  */
63  const struct bound_box *box)
64 {
65  static struct RTree_Rect rect;
66  static int rect_init = 0;
67 
68  if (!rect_init) {
69  rect.boundary = G_malloc(si->si_tree->nsides_alloc * sizeof(RectReal));
70  rect_init = si->si_tree->nsides_alloc;
71  }
72 
73  G_debug(3, "Vect_spatial_index_add_item(): id = %d", id);
74 
75  rect.boundary[0] = box->W;
76  rect.boundary[1] = box->S;
77  rect.boundary[2] = box->B;
78  rect.boundary[3] = box->E;
79  rect.boundary[4] = box->N;
80  rect.boundary[5] = box->T;
81  RTreeInsertRect(&rect, id, si->si_tree);
82 }
83 
84 /*!
85  \brief Delete item from spatial index structure
86 
87  \param[in,out] si pointer to spatial index structure
88  \param id item identifier
89 
90  \return void
91  */
93  const struct bound_box *box)
94 {
95  int ret;
96  static struct RTree_Rect rect;
97  static int rect_init = 0;
98 
99  if (!rect_init) {
100  rect.boundary = G_malloc(si->si_tree->nsides_alloc * sizeof(RectReal));
101  rect_init = si->si_tree->nsides_alloc;
102  }
103 
104  G_debug(3, "Vect_spatial_index_del_item(): id = %d", id);
105 
106  rect.boundary[0] = box->W;
107  rect.boundary[1] = box->S;
108  rect.boundary[2] = box->B;
109  rect.boundary[3] = box->E;
110  rect.boundary[4] = box->N;
111  rect.boundary[5] = box->T;
112 
113  ret = RTreeDeleteRect(&rect, id, si->si_tree);
114 
115  if (ret)
116  G_fatal_error(_("Unable to delete item %d from spatial index"), id);
117 }
118 
119 /************************* SELECT BY BOX *********************************/
120 /* This function is called by RTreeSearch() to add selected item to the list */
121 static int _add_item(int id, const struct RTree_Rect *rect UNUSED,
122  struct ilist *list)
123 {
124  G_ilist_add(list, id);
125  return 1;
126 }
127 
128 /*!
129  \brief Select items by bounding box to list
130 
131  \param si pointer to spatial index structure
132  \param box bounding box
133  \param[out] list pointer to list where selected items are stored
134 
135  \return number of selected items
136  */
138  const struct bound_box *box, struct ilist *list)
139 {
140  static struct RTree_Rect rect;
141  static int rect_init = 0;
142 
143  if (!rect_init) {
144  rect.boundary = G_malloc(si->si_tree->nsides_alloc * sizeof(RectReal));
145  rect_init = si->si_tree->nsides_alloc;
146  }
147 
149 
150  rect.boundary[0] = box->W;
151  rect.boundary[1] = box->S;
152  rect.boundary[2] = box->B;
153  rect.boundary[3] = box->E;
154  rect.boundary[4] = box->N;
155  rect.boundary[5] = box->T;
156  RTreeSearch(si->si_tree, &rect, (SearchHitCallback *)_add_item, list);
157 
158  G_debug(3, "Vect_spatial_index_select(): %d items selected",
159  list->n_values);
160 
161  return list->n_values;
162 }
void void void void G_fatal_error(const char *,...) __attribute__((format(printf
#define G_malloc(n)
Definition: defs/gis.h:94
void G_ilist_add(struct ilist *, int)
Add item to ilist.
Definition: ilist.c:78
int G_debug(int, const char *,...) __attribute__((format(printf
int Vect_reset_list(struct ilist *)
Reset ilist structure.
#define UNUSED
A macro for an attribute, if attached to a variable, indicating that the variable is not used.
Definition: gis.h:47
#define _(str)
Definition: glocale.h:10
int SearchHitCallback(int id, const struct RTree_Rect *rect, void *arg)
Definition: rtree.h:86
double RectReal
Definition: rtree.h:26
RectReal * boundary
Definition: rtree.h:55
unsigned char nsides_alloc
Definition: rtree.h:130
Bounding box.
Definition: dig_structs.h:64
double W
West.
Definition: dig_structs.h:80
double T
Top.
Definition: dig_structs.h:84
double S
South.
Definition: dig_structs.h:72
double N
North.
Definition: dig_structs.h:68
double E
East.
Definition: dig_structs.h:76
double B
Bottom.
Definition: dig_structs.h:88
List of integers.
Definition: gis.h:709
Definition: manage.h:4
Spatial index info.
Definition: dig_structs.h:1770
struct RTree * si_tree
Pointer to the search tree (R*-Tree)
Definition: dig_structs.h:1774
void Vect_spatial_index_destroy(struct spatial_index *si)
Destroy existing spatial index.
void Vect_spatial_index_init(struct spatial_index *si, int with_z)
Initialize spatial index structure.
void Vect_spatial_index_del_item(struct spatial_index *si, int id, const struct bound_box *box)
Delete item from spatial index structure.
int Vect_spatial_index_select(const struct spatial_index *si, const struct bound_box *box, struct ilist *list)
Select items by bounding box to list.
void Vect_spatial_index_add_item(struct spatial_index *si, int id, const struct bound_box *box)
Add a new item to spatial index structure.
int RTreeDeleteRect(struct RTree_Rect *r, int tid, struct RTree *t)
Delete an item from a R*-Tree.
int RTreeInsertRect(struct RTree_Rect *r, int tid, struct RTree *t)
Insert an item into a R*-Tree.
void RTreeDestroyTree(struct RTree *t)
Destroy an R*-Tree.
int RTreeSearch(struct RTree *t, struct RTree_Rect *r, SearchHitCallback *shcb, void *cbarg)
Search an R*-Tree.
struct RTree * RTreeCreateTree(int fd, off_t rootpos, int ndims)
Create new empty R*-Tree.