[GRASS-SVN] r52542 - in grass/trunk: include/vect lib/vector/Vlib lib/vector/diglib
svn_grass at osgeo.org
svn_grass at osgeo.org
Sun Aug 5 12:42:38 PDT 2012
Author: mmetz
Date: 2012-08-05 12:42:38 -0700 (Sun, 05 Aug 2012)
New Revision: 52542
Modified:
grass/trunk/include/vect/dig_externs.h
grass/trunk/lib/vector/Vlib/box.c
grass/trunk/lib/vector/diglib/spindex.c
Log:
vector libs: optimize bbox search
Modified: grass/trunk/include/vect/dig_externs.h
===================================================================
--- grass/trunk/include/vect/dig_externs.h 2012-08-05 19:33:54 UTC (rev 52541)
+++ grass/trunk/include/vect/dig_externs.h 2012-08-05 19:42:38 UTC (rev 52542)
@@ -207,9 +207,9 @@
int dig_select_areas(struct Plus_head *, const struct bound_box *, struct boxlist *);
int dig_select_isles(struct Plus_head *, const struct bound_box *, struct boxlist *);
int dig_find_node(struct Plus_head *, double, double, double);
-int dig_find_line_box(struct Plus_head *, struct boxlist *);
-int dig_find_area_box(struct Plus_head *, struct boxlist *);
-int dig_find_isle_box(struct Plus_head *, struct boxlist *);
+int dig_find_line_box(struct Plus_head *, int, struct bound_box *);
+int dig_find_area_box(struct Plus_head *, int, struct bound_box *);
+int dig_find_isle_box(struct Plus_head *, int, struct bound_box *);
/* spindex_rw.c */
int dig_Rd_spidx_head(struct gvfile *, struct Plus_head *);
Modified: grass/trunk/lib/vector/Vlib/box.c
===================================================================
--- grass/trunk/lib/vector/Vlib/box.c 2012-08-05 19:33:54 UTC (rev 52541)
+++ grass/trunk/lib/vector/Vlib/box.c 2012-08-05 19:42:38 UTC (rev 52542)
@@ -28,15 +28,12 @@
\return 1 point is in box
\return 0 point is not in box
*/
-int Vect_point_in_box(double x, double y, double z, const struct bound_box * Box)
+int Vect_point_in_box(double x, double y, double z, const struct bound_box *Box)
{
- if (x >= Box->W && x <= Box->E &&
- y >= Box->S && y <= Box->N && z >= Box->B && z <= Box->T) {
- return 1;
- }
-
- return 0;
+ return (x >= Box->W && x <= Box->E &&
+ y >= Box->S && y <= Box->N &&
+ z >= Box->B && z <= Box->T);
}
/*!
@@ -48,7 +45,7 @@
\return 1 boxes overlap
\return 0 boxes do not overlap
*/
-int Vect_box_overlap(const struct bound_box * A, const struct bound_box * B)
+int Vect_box_overlap(const struct bound_box *A, const struct bound_box *B)
{
if (A->E < B->W || A->W > B->E ||
@@ -67,7 +64,7 @@
\return 1
*/
-int Vect_box_copy(struct bound_box * A, const struct bound_box * B)
+int Vect_box_copy(struct bound_box *A, const struct bound_box *B)
{
A->N = B->N;
@@ -88,7 +85,7 @@
\return 1
*/
-int Vect_box_extend(struct bound_box * A, const struct bound_box * B)
+int Vect_box_extend(struct bound_box *A, const struct bound_box *B)
{
if (B->N > A->N)
@@ -133,7 +130,7 @@
*/
int
-Vect_box_clip(double *x, double *y, double *c_x, double *c_y, const struct bound_box * Box)
+Vect_box_clip(double *x, double *y, double *c_x, double *c_y, const struct bound_box *Box)
{
int mod;
@@ -202,19 +199,18 @@
\return 1 on success
\return 0 line is dead
*/
-int Vect_get_line_box(const struct Map_info *Map, int line, struct bound_box * Box)
+int Vect_get_line_box(const struct Map_info *Map, int line, struct bound_box *Box)
{
struct Plus_head *Plus;
struct P_line *Line;
int type;
static struct line_pnts *Points = NULL;
- static struct boxlist *list = NULL;
Plus = (struct Plus_head *)&(Map->plus);
Line = Plus->Line[line];
if (Line == NULL) { /* dead */
- G_zero(Box, sizeof(struct bound_box));
+ Box->N = Box->S = Box->E = Box->W = Box->T = Box->B = 0. / 0.;
return 0;
}
@@ -222,44 +218,10 @@
/* GV_LINES: retrieve box from spatial index */
if (type & GV_LINES) {
- int node = 0;
- struct bound_box bbox;
-
- if (type == GV_LINE) {
- struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
-
- node = topo->N1;
- }
- else if (type == GV_BOUNDARY) {
- struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
-
- node = topo->N1;
- }
- if (list == NULL) {
- list = Vect_new_boxlist(1);
- }
- Vect_reset_boxlist(list);
-
- bbox.N = Plus->Node[node]->y;
- bbox.S = Plus->Node[node]->y;
- bbox.E = Plus->Node[node]->x;
- bbox.W = Plus->Node[node]->x;
- bbox.T = Plus->Node[node]->z;
- bbox.B = Plus->Node[node]->z;
-
- dig_boxlist_add(list, line, bbox);
-
- if (dig_find_line_box(Plus, list) == 0)
+ if (dig_find_line_box(Plus, line, Box) == 0)
G_fatal_error(_("Unable to find bbox for feature %d"), line);
- Box->N = list->box[0].N;
- Box->S = list->box[0].S;
- Box->E = list->box[0].E;
- Box->W = list->box[0].W;
- Box->T = list->box[0].T;
- Box->B = list->box[0].B;
-
if (!Vect_is_3d(Map)) {
Box->T = PORT_DOUBLE_MAX;
Box->B = -PORT_DOUBLE_MAX;
@@ -294,52 +256,27 @@
\return 1 on success
\return 0 area is dead
*/
-int Vect_get_area_box(const struct Map_info *Map, int area, struct bound_box * Box)
+int Vect_get_area_box(const struct Map_info *Map, int area, struct bound_box *Box)
{
struct Plus_head *Plus;
struct P_area *Area;
- struct P_line *Line;
- struct P_node *Node;
- static struct boxlist *list = NULL;
- struct bound_box bbox;
- struct P_topo_b *topo;
Plus = (struct Plus_head *)&(Map->plus);
Area = Plus->Area[area];
if (Area == NULL) { /* dead */
- G_zero(Box, sizeof(struct bound_box));
+ Box->N = Box->S = Box->E = Box->W = Box->T = Box->B = 0. / 0.;
return 0;
}
- Line = Plus->Line[abs(Area->lines[0])];
- topo = (struct P_topo_b *)Line->topo;
- Node = Plus->Node[topo->N1];
+ if (dig_find_area_box(Plus, area, Box) == 0)
+ G_fatal_error(_("Unable to get bounding box for area %d"), area);
- if (list == NULL) {
- list = Vect_new_boxlist(TRUE);
+ if (!Vect_is_3d(Map)) {
+ Box->T = PORT_DOUBLE_MAX;
+ Box->B = -PORT_DOUBLE_MAX;
}
- Vect_reset_boxlist(list);
-
- bbox.N = Node->y;
- bbox.S = Node->y;
- bbox.E = Node->x;
- bbox.W = Node->x;
- bbox.T = Node->z;
- bbox.B = Node->z;
- dig_boxlist_add(list, area, bbox);
-
- if (dig_find_area_box(Plus, list) == 0)
- G_fatal_error(_("Unable to get bounding box for area %d"), area);
-
- Box->N = list->box[0].N;
- Box->S = list->box[0].S;
- Box->E = list->box[0].E;
- Box->W = list->box[0].W;
- Box->T = list->box[0].T;
- Box->B = list->box[0].B;
-
return 1;
}
@@ -351,59 +288,29 @@
\param[out] Box bounding box
\return 1 on success
- \return 0 isle is dead
+ \return 0 isle is dead / bounding box not found
*/
-int Vect_get_isle_box(const struct Map_info *Map, int isle, struct bound_box * Box)
+int Vect_get_isle_box(const struct Map_info *Map, int isle, struct bound_box *Box)
{
struct Plus_head *Plus;
struct P_isle *Isle;
- struct P_line *Line;
- struct P_node *Node;
- static struct boxlist *list = NULL;
- struct bound_box bbox;
- struct P_topo_b *topo;
Plus = (struct Plus_head *)&(Map->plus);
Isle = Plus->Isle[isle];
if (Isle == NULL) { /* dead */
- Box->N = 0;
- Box->S = 0;
- Box->E = 0;
- Box->W = 0;
- Box->T = 0;
- Box->B = 0;
+ Box->N = Box->S = Box->E = Box->W = Box->T = Box->B = 0. / 0.;
return 0;
}
- Line = Plus->Line[abs(Isle->lines[0])];
- topo = (struct P_topo_b *)Line->topo;
- Node = Plus->Node[topo->N1];
+ if (dig_find_isle_box(Plus, isle, Box) == 0)
+ G_fatal_error(_("Could not find isle box"));
- if (list == NULL) {
- list = Vect_new_boxlist(1);
+ if (!Vect_is_3d(Map)) {
+ Box->T = PORT_DOUBLE_MAX;
+ Box->B = -PORT_DOUBLE_MAX;
}
- Vect_reset_boxlist(list);
-
- bbox.N = Node->y;
- bbox.S = Node->y;
- bbox.E = Node->x;
- bbox.W = Node->x;
- bbox.T = Node->z;
- bbox.B = Node->z;
- dig_boxlist_add(list, isle, bbox);
-
- if (dig_find_isle_box(Plus, list) == 0)
- G_fatal_error(_("Could not find isle box"));
-
- Box->N = list->box[0].N;
- Box->S = list->box[0].S;
- Box->E = list->box[0].E;
- Box->W = list->box[0].W;
- Box->T = list->box[0].T;
- Box->B = list->box[0].B;
-
return 1;
}
@@ -416,7 +323,7 @@
\return 1 on success
\return 0 on error
*/
-int Vect_get_map_box(const struct Map_info *Map, struct bound_box * Box)
+int Vect_get_map_box(const struct Map_info *Map, struct bound_box *Box)
{
const struct Plus_head *Plus;
@@ -442,7 +349,7 @@
\return 1 on success
\return 0 on error
*/
-int Vect_region_box(const struct Cell_head *Window, struct bound_box * Box)
+int Vect_region_box(const struct Cell_head *Window, struct bound_box *Box)
{
Box->N = Window->north;
Modified: grass/trunk/lib/vector/diglib/spindex.c
===================================================================
--- grass/trunk/lib/vector/diglib/spindex.c 2012-08-05 19:33:54 UTC (rev 52541)
+++ grass/trunk/lib/vector/diglib/spindex.c 2012-08-05 19:42:38 UTC (rev 52542)
@@ -287,7 +287,8 @@
\return 0
*/
-int dig_spidx_add_line(struct Plus_head *Plus, int line, const struct bound_box * box)
+int dig_spidx_add_line(struct Plus_head *Plus, int line,
+ const struct bound_box *box)
{
static struct RTree_Rect rect;
static int rect_init = 0;
@@ -320,7 +321,8 @@
\return 0
*/
-int dig_spidx_add_area(struct Plus_head *Plus, int area, const struct bound_box * box)
+int dig_spidx_add_area(struct Plus_head *Plus, int area,
+ const struct bound_box *box)
{
static struct RTree_Rect rect;
static int rect_init = 0;
@@ -354,7 +356,8 @@
\return 0
*/
-int dig_spidx_add_isle(struct Plus_head *Plus, int isle, const struct bound_box * box)
+int dig_spidx_add_isle(struct Plus_head *Plus, int isle,
+ const struct bound_box *box)
{
static struct RTree_Rect rect;
static int rect_init = 0;
@@ -430,7 +433,8 @@
\return 0
*/
-int dig_spidx_del_line(struct Plus_head *Plus, int line, double x, double y, double z)
+int dig_spidx_del_line(struct Plus_head *Plus, int line,
+ double x, double y, double z)
{
int ret;
static struct RTree_Rect rect;
@@ -572,7 +576,8 @@
/* This function is called by RTreeSearch() to add
* selected node/line/area/isle to the box list */
-static int _add_item_with_box(int id, struct RTree_Rect rect, struct boxlist *list)
+static int _add_item_with_box(int id, struct RTree_Rect rect,
+ struct boxlist *list)
{
struct bound_box box;
@@ -587,18 +592,25 @@
return 1;
}
+struct boxid
+{
+ int id;
+ struct bound_box *box;
+};
+
/* This function is called by RTreeSearch() to add
* selected node/line/area/isle to the box list */
-static int _set_item_box(int id, struct RTree_Rect rect, struct boxlist *list)
+static int _set_item_box(int id, struct RTree_Rect rect,
+ struct boxid *box_id)
{
- if (id == list->id[0]) {
+ if (id == box_id->id) {
- list->box[0].W = rect.boundary[0];
- list->box[0].S = rect.boundary[1];
- list->box[0].B = rect.boundary[2];
- list->box[0].E = rect.boundary[3];
- list->box[0].N = rect.boundary[4];
- list->box[0].T = rect.boundary[5];
+ box_id->box->W = rect.boundary[0];
+ box_id->box->S = rect.boundary[1];
+ box_id->box->B = rect.boundary[2];
+ box_id->box->E = rect.boundary[3];
+ box_id->box->N = rect.boundary[4];
+ box_id->box->T = rect.boundary[5];
return 0;
}
@@ -739,41 +751,71 @@
\brief Find box for line
\param Plus pointer to Plus_head structure
- \param[in,out] list line with isle id and search box (in)/line box (out)
+ \param line line id
+ \param[out] box bounding box
- \return number of lines found
+ \return > 0 bounding box for line found
\return 0 not found
*/
-int dig_find_line_box(struct Plus_head *Plus, struct boxlist *list)
+int dig_find_line_box(struct Plus_head *Plus, int line,
+ struct bound_box *box)
{
- int ret;
+ int ret, type;
+ struct P_line *Line;
+ struct boxid box_id;
static struct RTree_Rect rect;
static int rect_init = 0;
+ G_debug(3, "dig_find_line_box()");
+
if (!rect_init) {
/* always 6 sides for 3D */
rect.boundary = G_malloc(6 * sizeof(RectReal));
rect_init = 6;
}
- G_debug(3, "dig_find_line_box()");
+ Line = Plus->Line[line];
+ type = Line->type;
- if (list->n_values < 1)
- G_fatal_error(_("No line id given"));
+ /* GV_LINES: retrieve box from spatial index */
+ if (type & GV_LINES) {
+ struct P_node *Node = NULL;
- rect.boundary[0] = list->box[0].W;
- rect.boundary[1] = list->box[0].S;
- rect.boundary[2] = list->box[0].B;
- rect.boundary[3] = list->box[0].E;
- rect.boundary[4] = list->box[0].N;
- rect.boundary[5] = list->box[0].T;
+ if (type == GV_LINE) {
+ struct P_topo_l *topo = (struct P_topo_l *)Line->topo;
- if (Plus->Spidx_new)
- ret = RTreeSearch(Plus->Line_spidx, &rect, (void *)_set_item_box, list);
- else
- ret = rtree_search(Plus->Line_spidx, &rect, (void *)_set_item_box, list, Plus);
+ Node = Plus->Node[topo->N1];
+ }
+ else if (type == GV_BOUNDARY) {
+ struct P_topo_b *topo = (struct P_topo_b *)Line->topo;
- return (ret);
+ Node = Plus->Node[topo->N1];
+ }
+
+ rect.boundary[0] = Node->x;
+ rect.boundary[1] = Node->y;
+ rect.boundary[2] = Node->z;
+ rect.boundary[3] = Node->x;
+ rect.boundary[4] = Node->y;
+ rect.boundary[5] = Node->z;
+
+ box_id.id = line;
+ box_id.box = box;
+
+ if (Plus->Spidx_new)
+ ret = RTreeSearch(Plus->Line_spidx, &rect, (void *)_set_item_box, &box_id);
+ else
+ ret = rtree_search(Plus->Line_spidx, &rect, (void *)_set_item_box, &box_id, Plus);
+
+ return ret;
+ }
+
+ /* do not translate this error because
+ * 1. this error is not supposed to happen
+ * 2. the maintainer at which this message is directed prefers english */
+ G_fatal_error("Bug in vector lib: dig_find_line_box() may only be used for lines and boundaries.");
+
+ return 0;
}
/*!
@@ -786,7 +828,7 @@
\return number of selected areas
*/
int
-dig_select_areas(struct Plus_head *Plus, const struct bound_box * box,
+dig_select_areas(struct Plus_head *Plus, const struct bound_box *box,
struct boxlist *list)
{
static struct RTree_Rect rect;
@@ -821,39 +863,51 @@
\brief Find bounding box for given area
\param Plus pointer to Plus_head structure
- \param[in,out] list list with area id and search box (in)/area box (out)
+ \param area area id
+ \param[out] box bounding box
- \return number of areas found
+ \return > 0 bounding box for area found
\return 0 not found
*/
-int dig_find_area_box(struct Plus_head *Plus, struct boxlist *list)
+int dig_find_area_box(struct Plus_head *Plus, int area,
+ struct bound_box *box)
{
int ret;
+ struct boxid box_id;
+ struct P_area *Area;
+ struct P_line *Line;
+ struct P_node *Node;
+ struct P_topo_b *topo;
static struct RTree_Rect rect;
static int rect_init = 0;
+ G_debug(3, "dig_find_area_box()");
+
if (!rect_init) {
/* always 6 sides for 3D */
rect.boundary = G_malloc(6 * sizeof(RectReal));
rect_init = 6;
}
- G_debug(3, "dig_find_area_box()");
+ Area = Plus->Area[area];
+ Line = Plus->Line[abs(Area->lines[0])];
+ topo = (struct P_topo_b *)Line->topo;
+ Node = Plus->Node[topo->N1];
- if (list->n_values < 1)
- G_fatal_error(_("No area id given"));
+ rect.boundary[0] = Node->x;
+ rect.boundary[1] = Node->y;
+ rect.boundary[2] = Node->z;
+ rect.boundary[3] = Node->x;
+ rect.boundary[4] = Node->y;
+ rect.boundary[5] = Node->z;
+
+ box_id.id = area;
+ box_id.box = box;
- rect.boundary[0] = list->box[0].W;
- rect.boundary[1] = list->box[0].S;
- rect.boundary[2] = list->box[0].B;
- rect.boundary[3] = list->box[0].E;
- rect.boundary[4] = list->box[0].N;
- rect.boundary[5] = list->box[0].T;
-
if (Plus->Spidx_new)
- ret = RTreeSearch(Plus->Area_spidx, &rect, (void *)_set_item_box, list);
+ ret = RTreeSearch(Plus->Area_spidx, &rect, (void *)_set_item_box, &box_id);
else
- ret = rtree_search(Plus->Area_spidx, &rect, (void *)_set_item_box, list, Plus);
+ ret = rtree_search(Plus->Area_spidx, &rect, (void *)_set_item_box, &box_id, Plus);
return ret;
}
@@ -903,39 +957,51 @@
\brief Find box for isle
\param Plus pointer to Plus_head structure
- \param[in,out] list list with isle id and search box (in)/isle box (out)
+ \param isle isle id
+ \param[out] box bounding box
- \return number of isles found
+ \return > 0 bounding box for isle found
\return 0 not found
*/
-int dig_find_isle_box(struct Plus_head *Plus, struct boxlist *list)
+int dig_find_isle_box(struct Plus_head *Plus, int isle,
+ struct bound_box *box)
{
int ret;
+ struct boxid box_id;
+ struct P_isle *Isle;
+ struct P_line *Line;
+ struct P_node *Node;
+ struct P_topo_b *topo;
static struct RTree_Rect rect;
static int rect_init = 0;
+ G_debug(3, "dig_find_isle_box()");
+
if (!rect_init) {
/* always 6 sides for 3D */
rect.boundary = G_malloc(6 * sizeof(RectReal));
rect_init = 6;
}
- G_debug(3, "dig_find_isle_box()");
+ Isle = Plus->Isle[isle];
+ Line = Plus->Line[abs(Isle->lines[0])];
+ topo = (struct P_topo_b *)Line->topo;
+ Node = Plus->Node[topo->N1];
- if (list->n_values < 1)
- G_fatal_error(_("No isle id given"));
+ rect.boundary[0] = Node->x;
+ rect.boundary[1] = Node->y;
+ rect.boundary[2] = Node->z;
+ rect.boundary[3] = Node->x;
+ rect.boundary[4] = Node->y;
+ rect.boundary[5] = Node->z;
+
+ box_id.id = isle;
+ box_id.box = box;
- rect.boundary[0] = list->box[0].W;
- rect.boundary[1] = list->box[0].S;
- rect.boundary[2] = list->box[0].B;
- rect.boundary[3] = list->box[0].E;
- rect.boundary[4] = list->box[0].N;
- rect.boundary[5] = list->box[0].T;
-
if (Plus->Spidx_new)
- ret = RTreeSearch(Plus->Isle_spidx, &rect, (void *)_set_item_box, list);
+ ret = RTreeSearch(Plus->Isle_spidx, &rect, (void *)_set_item_box, &box_id);
else
- ret = rtree_search(Plus->Isle_spidx, &rect, (void *)_set_item_box, list, Plus);
+ ret = rtree_search(Plus->Isle_spidx, &rect, (void *)_set_item_box, &box_id, Plus);
- return (ret);
+ return ret;
}
More information about the grass-commit
mailing list