1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039 |
- /*!
- \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;
-
- 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;
- }
|