/*! \file diglib/spindex.c \brief Vector library - spatial index (lower level functions) Lower level functions for reading/writing/manipulating vectors. (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 Original author CERL, probably Dave Gerdes \author Update to GRASS 5.7 Radim Blazek \author Update to GRASS 7 Markus Metz */ #include #include #include #include #include #include #include #include /*! \brief Initit spatial index (nodes, lines, areas, isles) \param Plus pointer to Plus_head structure \return 1 OK \return 0 on error */ int dig_spidx_init(struct Plus_head *Plus) { int ndims; ndims = (Plus->with_z != 0) ? 3 : 2; Plus->spidx_with_z = (Plus->with_z != 0); G_debug(1, "dig_spidx_init(), %d dims", ndims); if (Plus->Spidx_file) { int fd; char *filename; filename = G_tempfile(); fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); Plus->Node_spidx = RTreeCreateTree(fd, 0, ndims); remove(filename); filename = G_tempfile(); fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); Plus->Line_spidx = RTreeCreateTree(fd, 0, ndims); remove(filename); filename = G_tempfile(); fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); Plus->Area_spidx = RTreeCreateTree(fd, 0, ndims); remove(filename); filename = G_tempfile(); fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); Plus->Isle_spidx = RTreeCreateTree(fd, 0, ndims); remove(filename); Plus->Face_spidx = NULL; Plus->Volume_spidx = NULL; Plus->Hole_spidx = NULL; if (!Plus->Spidx_new) { close(Plus->Node_spidx->fd); close(Plus->Line_spidx->fd); close(Plus->Area_spidx->fd); close(Plus->Isle_spidx->fd); } } else { Plus->Node_spidx = RTreeCreateTree(-1, 0, ndims); Plus->Line_spidx = RTreeCreateTree(-1, 0, ndims); Plus->Area_spidx = RTreeCreateTree(-1, 0, ndims); Plus->Isle_spidx = RTreeCreateTree(-1, 0, ndims); Plus->Face_spidx = NULL; Plus->Volume_spidx = NULL; Plus->Hole_spidx = NULL; } Plus->Node_spidx_offset = 0L; Plus->Line_spidx_offset = 0L; Plus->Area_spidx_offset = 0L; Plus->Isle_spidx_offset = 0L; Plus->Face_spidx_offset = 0L; Plus->Volume_spidx_offset = 0L; Plus->Hole_spidx_offset = 0L; Plus->Spidx_built = FALSE; return 1; } /*! \brief Free spatial index for nodes \param Plus pointer to Plus_head structure */ void dig_spidx_free_nodes(struct Plus_head *Plus) { int ndims; ndims = Plus->with_z ? 3 : 2; /* Node spidx */ if (Plus->Node_spidx->fd > -1) { int fd; char *filename; if (Plus->Spidx_new) close(Plus->Node_spidx->fd); RTreeDestroyTree(Plus->Node_spidx); filename = G_tempfile(); fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); Plus->Node_spidx = RTreeCreateTree(fd, 0, ndims); remove(filename); if (!Plus->Spidx_new) close(Plus->Node_spidx->fd); } else { RTreeDestroyTree(Plus->Node_spidx); Plus->Node_spidx = RTreeCreateTree(-1, 0, ndims); } } /*! \brief Free spatial index for lines \param Plus pointer to Plus_head structure */ void dig_spidx_free_lines(struct Plus_head *Plus) { int ndims; ndims = Plus->with_z ? 3 : 2; /* Line spidx */ if (Plus->Line_spidx->fd > -1) { int fd; char *filename; if (Plus->Spidx_new) close(Plus->Line_spidx->fd); RTreeDestroyTree(Plus->Line_spidx); filename = G_tempfile(); fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); Plus->Line_spidx = RTreeCreateTree(fd, 0, ndims); remove(filename); if (!Plus->Spidx_new) close(Plus->Line_spidx->fd); } else { RTreeDestroyTree(Plus->Line_spidx); Plus->Line_spidx = RTreeCreateTree(-1, 0, ndims); } } /*! \brief Reset spatial index for areas \param Plus pointer to Plus_head structure */ void dig_spidx_free_areas(struct Plus_head *Plus) { int ndims; ndims = Plus->with_z ? 3 : 2; /* Area spidx */ if (Plus->Area_spidx->fd > -1) { int fd; char *filename; if (Plus->Spidx_new) close(Plus->Area_spidx->fd); RTreeDestroyTree(Plus->Area_spidx); filename = G_tempfile(); fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); Plus->Area_spidx = RTreeCreateTree(fd, 0, ndims); remove(filename); if (!Plus->Spidx_new) close(Plus->Area_spidx->fd); } else { RTreeDestroyTree(Plus->Area_spidx); Plus->Area_spidx = RTreeCreateTree(-1, 0, ndims); } } /*! \brief Reset spatial index for isles \param Plus pointer to Plus_head structure */ void dig_spidx_free_isles(struct Plus_head *Plus) { int ndims; ndims = Plus->with_z ? 3 : 2; /* Isle spidx */ if (Plus->Isle_spidx->fd > -1) { int fd; char *filename; if (Plus->Spidx_new) close(Plus->Isle_spidx->fd); RTreeDestroyTree(Plus->Isle_spidx); filename = G_tempfile(); fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600); Plus->Isle_spidx = RTreeCreateTree(fd, 0, ndims); remove(filename); if (!Plus->Spidx_new) close(Plus->Isle_spidx->fd); } else { RTreeDestroyTree(Plus->Isle_spidx); Plus->Isle_spidx = RTreeCreateTree(-1, 0, ndims); } } /*! \brief Free spatial index (nodes, lines, areas, isles) \param Plus pointer to Plus_head structure */ void dig_spidx_free(struct Plus_head *Plus) { /* close tmp files */ if (Plus->Spidx_new) { /* Node spidx */ if (Plus->Node_spidx->fd > -1) close(Plus->Node_spidx->fd); /* Line spidx */ if (Plus->Spidx_new && Plus->Line_spidx->fd > -1) close(Plus->Line_spidx->fd); /* Area spidx */ if (Plus->Area_spidx->fd > -1) close(Plus->Area_spidx->fd); /* Isle spidx */ if (Plus->Isle_spidx->fd > -1) close(Plus->Isle_spidx->fd); } /* destroy tree structures */ /* Node spidx */ if (Plus->Node_spidx) RTreeDestroyTree(Plus->Node_spidx); /* Line spidx */ if (Plus->Line_spidx) RTreeDestroyTree(Plus->Line_spidx); /* Area spidx */ if (Plus->Area_spidx) RTreeDestroyTree(Plus->Area_spidx); /* Isle spidx */ if (Plus->Isle_spidx) RTreeDestroyTree(Plus->Isle_spidx); /* 3D future : */ /* Face spidx */ /* Volume spidx */ /* Hole spidx */ } /*! \brief Add new node to spatial index \param Plus pointer to Plus_head structure \param node node id \param x,y,z node coordinates \return 1 OK \return 0 on error */ int dig_spidx_add_node(struct Plus_head *Plus, int node, double x, double y, double z) { static struct RTree_Rect rect; static int rect_init = 0; if (!rect_init) { /* always 6 sides for 3D */ rect.boundary = G_malloc(6 * sizeof(RectReal)); rect_init = 6; } G_debug(3, "dig_spidx_add_node(): node = %d, x,y,z = %f, %f, %f", node, x, y, z); rect.boundary[0] = x; rect.boundary[1] = y; rect.boundary[2] = z; rect.boundary[3] = x; rect.boundary[4] = y; rect.boundary[5] = z; RTreeInsertRect(&rect, node, Plus->Node_spidx); return 1; } /*! \brief Add new line to spatial index \param Plus pointer to Plus_head structure \param line line id \param box bounding box \return 0 */ 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; if (!rect_init) { /* always 6 sides for 3D */ rect.boundary = G_malloc(6 * sizeof(RectReal)); rect_init = 6; } G_debug(3, "dig_spidx_add_line(): line = %d", line); 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, line, Plus->Line_spidx); return 0; } /*! \brief Add new area to spatial index \param Plus pointer to Plus_head structure \param area area id \param box bounding box \return 0 */ 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; if (!rect_init) { /* always 6 sides for 3D */ rect.boundary = G_malloc(6 * sizeof(RectReal)); rect_init = 6; } G_debug(3, "dig_spidx_add_area(): area = %d", area); 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, area, Plus->Area_spidx); return 0; } /*! \brief Add new island to spatial index \param Plus pointer to Plus_head structure \param isle isle id \param box bounding box \return 0 */ 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; if (!rect_init) { /* always 6 sides for 3D */ rect.boundary = G_malloc(6 * sizeof(RectReal)); rect_init = 6; } G_debug(3, "dig_spidx_add_isle(): isle = %d", isle); 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, isle, Plus->Isle_spidx); return 0; } /*! \brief Delete node from spatial index G_fatal_error() called on error. \param Plus pointer to Plus_head structure \param node node id \return 0 */ int dig_spidx_del_node(struct Plus_head *Plus, int node) { int ret; struct P_node *Node; static struct RTree_Rect rect; static int rect_init = 0; if (!rect_init) { /* always 6 sides for 3D */ rect.boundary = G_malloc(6 * sizeof(RectReal)); rect_init = 6; } G_debug(3, "dig_spidx_del_node(): node = %d", node); Node = Plus->Node[node]; 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; ret = RTreeDeleteRect(&rect, node, Plus->Node_spidx); if (ret) G_fatal_error(_("Unable to delete node %d from spatial index"), node); return 0; } /*! \brief Delete line from spatial index G_fatal_error() called on error. \param Plus pointer to Plus_head structure \param line line id \param x,y,z coordinates \return 0 */ int dig_spidx_del_line(struct Plus_head *Plus, int line, double x, double y, double z) { int ret; static struct RTree_Rect rect; static int rect_init = 0; if (!rect_init) { /* always 6 sides for 3D */ rect.boundary = G_malloc(6 * sizeof(RectReal)); rect_init = 6; } G_debug(3, "dig_spidx_del_line(): line = %d", line); rect.boundary[0] = x; rect.boundary[1] = y; rect.boundary[2] = z; rect.boundary[3] = x; rect.boundary[4] = y; rect.boundary[5] = z; ret = RTreeDeleteRect(&rect, line, Plus->Line_spidx); G_debug(3, " ret = %d", ret); if (ret) G_fatal_error(_("Unable to delete line %d from spatial index"), line); return 0; } /*! \brief Delete area from spatial index G_fatal_error() called on error. \param Plus pointer to Plus_head structure \param area area id \return 0 */ int dig_spidx_del_area(struct Plus_head *Plus, int area) { int ret; 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; if (!rect_init) { /* always 6 sides for 3D */ rect.boundary = G_malloc(6 * sizeof(RectReal)); rect_init = 6; } G_debug(3, "dig_spidx_del_area(): area = %d", area); Area = Plus->Area[area]; if (Area == NULL) { G_fatal_error(_("Attempt to delete sidx for dead area")); } Line = Plus->Line[abs(Area->lines[0])]; topo = (struct P_topo_b *)Line->topo; 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; ret = RTreeDeleteRect(&rect, area, Plus->Area_spidx); if (ret) G_fatal_error(_("Unable to delete area %d from spatial index"), area); return 0; } /*! \brief Delete isle from spatial index G_fatal_error() called on error. \param Plus pointer to Plus_head structure \param isle isle id \return 0 */ int dig_spidx_del_isle(struct Plus_head *Plus, int isle) { int ret; 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; if (!rect_init) { /* always 6 sides for 3D */ rect.boundary = G_malloc(6 * sizeof(RectReal)); rect_init = 6; } G_debug(3, "dig_spidx_del_isle(): isle = %d", isle); Isle = Plus->Isle[isle]; Line = Plus->Line[abs(Isle->lines[0])]; topo = (struct P_topo_b *)Line->topo; 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; ret = RTreeDeleteRect(&rect, isle, Plus->Isle_spidx); if (ret) G_fatal_error(_("Unable to delete isle %d from spatial index"), isle); return 0; } /* This function is called by RTreeSearch() to add selected node/line/area/isle to the list */ static int _add_item(int id, const struct RTree_Rect *rect, struct ilist *list) { G_ilist_add(list, id); return 1; } /* 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, const struct RTree_Rect *rect, struct boxlist *list) { struct bound_box box; box.W = rect->boundary[0]; box.S = rect->boundary[1]; box.B = rect->boundary[2]; box.E = rect->boundary[3]; box.N = rect->boundary[4]; box.T = rect->boundary[5]; dig_boxlist_add(list, id, &box); 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, const struct RTree_Rect *rect, struct boxid *box_id) { if (id == box_id->id) { 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; } return 1; } /*! \brief Select nodes by bbox \param Plus pointer to Plus_head structure \param box bounding box \param list list of selected lines \return number of selected nodes \return -1 on error */ int dig_select_nodes(struct Plus_head *Plus, const struct bound_box * box, struct ilist *list) { static struct RTree_Rect rect; static int rect_init = 0; if (!rect_init) { /* always 6 sides for 3D */ rect.boundary = G_malloc(6 * sizeof(RectReal)); rect_init = 6; } G_debug(3, "dig_select_nodes()"); list->n_values = 0; 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; if (Plus->Spidx_new) RTreeSearch(Plus->Node_spidx, &rect, (void *)_add_item, list); else rtree_search(Plus->Node_spidx, &rect, (void *)_add_item, list, Plus); return (list->n_values); } /* This function is called by RTreeSearch() for nodes to find the node id */ static int _add_node(int id, const struct RTree_Rect *rect, int *node) { *node = id; return 0; } /*! \brief Find one node by coordinates \param Plus pointer to Plus_head structure \param x,y,z coordinates \return number of node \return 0 not found */ int dig_find_node(struct Plus_head *Plus, double x, double y, double z) { int node; static struct RTree_Rect rect; static int rect_init = 0; if (!rect_init) { /* always 6 sides for 3D */ rect.boundary = G_malloc(6 * sizeof(RectReal)); rect_init = 6; } G_debug(3, "dig_find_node()"); rect.boundary[0] = x; rect.boundary[1] = y; rect.boundary[2] = z; rect.boundary[3] = x; rect.boundary[4] = y; rect.boundary[5] = z; node = 0; if (Plus->Spidx_new) RTreeSearch(Plus->Node_spidx, &rect, (void *)_add_node, &node); else rtree_search(Plus->Node_spidx, &rect, (void *)_add_node, &node, Plus); return node; } /*! \brief Select lines with boxes by box \param Plus pointer to Plus_head structure \param box bounding box \param list boxlist of selected lines \return number of selected lines \return 0 not found */ int dig_select_lines(struct Plus_head *Plus, const struct bound_box *box, struct boxlist *list) { static struct RTree_Rect rect; static int rect_init = 0; if (!rect_init) { /* always 6 sides for 3D */ rect.boundary = G_malloc(6 * sizeof(RectReal)); rect_init = 6; } G_debug(3, "dig_select_lines_with_box()"); list->n_values = 0; 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; if (Plus->Spidx_new) RTreeSearch(Plus->Line_spidx, &rect, (void *)_add_item_with_box, list); else rtree_search(Plus->Line_spidx, &rect, (void *)_add_item_with_box, list, Plus); return (list->n_values); } /*! \brief Find box for line \param Plus pointer to Plus_head structure \param line line id \param[out] box bounding box \return > 0 bounding box for line found \return 0 not found */ int dig_find_line_box(struct Plus_head *Plus, int line, struct bound_box *box) { 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; } Line = Plus->Line[line]; type = Line->type; /* GV_LINES: retrieve box from spatial index */ if (type & GV_LINES) { struct P_node *Node = NULL; if (type == GV_LINE) { struct P_topo_l *topo = (struct P_topo_l *)Line->topo; Node = Plus->Node[topo->N1]; } else if (type == GV_BOUNDARY) { struct P_topo_b *topo = (struct P_topo_b *)Line->topo; 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; } /*! \brief Select areas with boxes by box \param Plus pointer to Plus_head structure \param box bounding box \param list boxlist of selected areas \return number of selected areas */ int dig_select_areas(struct Plus_head *Plus, const struct bound_box *box, struct boxlist *list) { static struct RTree_Rect rect; static int rect_init = 0; if (!rect_init) { /* always 6 sides for 3D */ rect.boundary = G_malloc(6 * sizeof(RectReal)); rect_init = 6; } G_debug(3, "dig_select_areas_with_box()"); list->n_values = 0; 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; if (Plus->Spidx_new) RTreeSearch(Plus->Area_spidx, &rect, (void *)_add_item_with_box, list); else rtree_search(Plus->Area_spidx, &rect, (void *)_add_item_with_box, list, Plus); return (list->n_values); } /*! \brief Find bounding box for given area \param Plus pointer to Plus_head structure \param area area id \param[out] box bounding box \return > 0 bounding box for area found \return 0 not found */ 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; } Area = Plus->Area[area]; Line = Plus->Line[abs(Area->lines[0])]; topo = (struct P_topo_b *)Line->topo; 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 = area; box_id.box = box; if (Plus->Spidx_new) ret = RTreeSearch(Plus->Area_spidx, &rect, (void *)_set_item_box, &box_id); else ret = rtree_search(Plus->Area_spidx, &rect, (void *)_set_item_box, &box_id, Plus); return ret; } /*! \brief Select isles with boxes by box \param Plus pointer to Plus_head structure \param box bounding box \param list boxlist of selected isles \return number of selected isles */ int dig_select_isles(struct Plus_head *Plus, const struct bound_box * box, struct boxlist *list) { static struct RTree_Rect rect; static int rect_init = 0; if (!rect_init) { /* always 6 sides for 3D */ rect.boundary = G_malloc(6 * sizeof(RectReal)); rect_init = 6; } G_debug(3, "dig_select_areas_with_box()"); list->n_values = 0; 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; if (Plus->Spidx_new) RTreeSearch(Plus->Isle_spidx, &rect, (void *)_add_item_with_box, list); else rtree_search(Plus->Isle_spidx, &rect, (void *)_add_item_with_box, list, Plus); return (list->n_values); } /*! \brief Find box for isle \param Plus pointer to Plus_head structure \param isle isle id \param[out] box bounding box \return > 0 bounding box for isle found \return 0 not found */ 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; } Isle = Plus->Isle[isle]; Line = Plus->Line[abs(Isle->lines[0])]; topo = (struct P_topo_b *)Line->topo; 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 = isle; box_id.box = box; if (Plus->Spidx_new) ret = RTreeSearch(Plus->Isle_spidx, &rect, (void *)_set_item_box, &box_id); else ret = rtree_search(Plus->Isle_spidx, &rect, (void *)_set_item_box, &box_id, Plus); return ret; }