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