12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010 |
- /*!
- \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 <stdlib.h>
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <string.h>
- #include <grass/vector.h>
- #include <grass/glocale.h>
- /*!
- \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;
- }
- 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;
-
- 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);
- }
- 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;
-
- 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);
- }
- 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;
-
- 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);
- }
- 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;
-
- 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);
- }
- 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)
- {
- /* Node spidx */
- if (Plus->Node_spidx->fd > -1)
- close(Plus->Node_spidx->fd);
- RTreeDestroyTree(Plus->Node_spidx);
- /* Line spidx */
- if (Plus->Line_spidx->fd > -1)
- close(Plus->Line_spidx->fd);
- RTreeDestroyTree(Plus->Line_spidx);
- /* Area spidx */
- if (Plus->Area_spidx->fd > -1)
- close(Plus->Area_spidx->fd);
- RTreeDestroyTree(Plus->Area_spidx);
- /* Isle spidx */
- if (Plus->Isle_spidx->fd > -1)
- close(Plus->Isle_spidx->fd);
- 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;
- }
|