spindex.c 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831
  1. /*!
  2. \file diglib/spindex.c
  3. \brief Vector library - spatial index (lower level functions)
  4. Lower level functions for reading/writing/manipulating vectors.
  5. (C) 2001-2009 by the GRASS Development Team
  6. This program is free software under the GNU General Public License
  7. (>=v2). Read the file COPYING that comes with GRASS for details.
  8. \author Original author CERL, probably Dave Gerdes
  9. \author Update to GRASS 5.7 Radim Blazek
  10. \author Update to GRASS 7 Markus Metz
  11. */
  12. #include <stdlib.h>
  13. #include <sys/types.h>
  14. #include <sys/stat.h>
  15. #include <fcntl.h>
  16. #include <unistd.h>
  17. #include <string.h>
  18. #include <grass/vector.h>
  19. #include <grass/glocale.h>
  20. /*!
  21. \brief Initit spatial index (nodes, lines, areas, isles)
  22. \param Plus pointer to Plus_head structure
  23. \return 1 OK
  24. \return 0 on error
  25. */
  26. int dig_spidx_init(struct Plus_head *Plus)
  27. {
  28. int ndims;
  29. ndims = (Plus->with_z != 0) ? 3 : 2;
  30. Plus->spidx_with_z = (Plus->with_z != 0);
  31. if (Plus->Spidx_file) {
  32. int fd;
  33. char *filename;
  34. filename = G_tempfile();
  35. fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
  36. Plus->Node_spidx = RTreeNewIndex(fd, 0, ndims);
  37. remove(filename);
  38. filename = G_tempfile();
  39. fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
  40. Plus->Line_spidx = RTreeNewIndex(fd, 0, ndims);
  41. remove(filename);
  42. filename = G_tempfile();
  43. fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
  44. Plus->Area_spidx = RTreeNewIndex(fd, 0, ndims);
  45. remove(filename);
  46. filename = G_tempfile();
  47. fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
  48. Plus->Isle_spidx = RTreeNewIndex(fd, 0, ndims);
  49. remove(filename);
  50. Plus->Face_spidx = NULL;
  51. Plus->Volume_spidx = NULL;
  52. Plus->Hole_spidx = NULL;
  53. }
  54. else {
  55. Plus->Node_spidx = RTreeNewIndex(-1, 0, ndims);
  56. Plus->Line_spidx = RTreeNewIndex(-1, 0, ndims);
  57. Plus->Area_spidx = RTreeNewIndex(-1, 0, ndims);
  58. Plus->Isle_spidx = RTreeNewIndex(-1, 0, ndims);
  59. Plus->Face_spidx = NULL;
  60. Plus->Volume_spidx = NULL;
  61. Plus->Hole_spidx = NULL;
  62. }
  63. Plus->Node_spidx_offset = 0L;
  64. Plus->Line_spidx_offset = 0L;
  65. Plus->Area_spidx_offset = 0L;
  66. Plus->Isle_spidx_offset = 0L;
  67. Plus->Face_spidx_offset = 0L;
  68. Plus->Volume_spidx_offset = 0L;
  69. Plus->Hole_spidx_offset = 0L;
  70. Plus->Spidx_built = 0;
  71. return 1;
  72. }
  73. /*!
  74. \brief Free spatial index for nodes
  75. \param Plus pointer to Plus_head structure
  76. */
  77. void dig_spidx_free_nodes(struct Plus_head *Plus)
  78. {
  79. int ndims;
  80. ndims = Plus->with_z ? 3 : 2;
  81. /* Node spidx */
  82. if (Plus->Node_spidx->fd > -1) {
  83. int fd;
  84. char *filename;
  85. close(Plus->Node_spidx->fd);
  86. RTreeFreeIndex(Plus->Node_spidx);
  87. filename = G_tempfile();
  88. fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
  89. Plus->Node_spidx = RTreeNewIndex(fd, 0, ndims);
  90. remove(filename);
  91. }
  92. else {
  93. RTreeFreeIndex(Plus->Node_spidx);
  94. Plus->Node_spidx = RTreeNewIndex(-1, 0, ndims);
  95. }
  96. }
  97. /*!
  98. \brief Free spatial index for lines
  99. \param Plus pointer to Plus_head structure
  100. */
  101. void dig_spidx_free_lines(struct Plus_head *Plus)
  102. {
  103. int ndims;
  104. ndims = Plus->with_z ? 3 : 2;
  105. /* Line spidx */
  106. if (Plus->Line_spidx->fd > -1) {
  107. int fd;
  108. char *filename;
  109. close(Plus->Line_spidx->fd);
  110. RTreeFreeIndex(Plus->Line_spidx);
  111. filename = G_tempfile();
  112. fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
  113. Plus->Line_spidx = RTreeNewIndex(fd, 0, ndims);
  114. remove(filename);
  115. }
  116. else {
  117. RTreeFreeIndex(Plus->Line_spidx);
  118. Plus->Line_spidx = RTreeNewIndex(-1, 0, ndims);
  119. }
  120. }
  121. /*!
  122. \brief Reset spatial index for areas
  123. \param Plus pointer to Plus_head structure
  124. */
  125. void dig_spidx_free_areas(struct Plus_head *Plus)
  126. {
  127. int ndims;
  128. ndims = Plus->with_z ? 3 : 2;
  129. /* Area spidx */
  130. if (Plus->Area_spidx->fd > -1) {
  131. int fd;
  132. char *filename;
  133. close(Plus->Area_spidx->fd);
  134. RTreeFreeIndex(Plus->Area_spidx);
  135. filename = G_tempfile();
  136. fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
  137. Plus->Area_spidx = RTreeNewIndex(fd, 0, ndims);
  138. remove(filename);
  139. }
  140. else {
  141. RTreeFreeIndex(Plus->Area_spidx);
  142. Plus->Area_spidx = RTreeNewIndex(-1, 0, ndims);
  143. }
  144. }
  145. /*!
  146. \brief Reset spatial index for isles
  147. \param Plus pointer to Plus_head structure
  148. */
  149. void dig_spidx_free_isles(struct Plus_head *Plus)
  150. {
  151. int ndims;
  152. ndims = Plus->with_z ? 3 : 2;
  153. /* Isle spidx */
  154. if (Plus->Isle_spidx->fd > -1) {
  155. int fd;
  156. char *filename;
  157. close(Plus->Isle_spidx->fd);
  158. RTreeFreeIndex(Plus->Isle_spidx);
  159. filename = G_tempfile();
  160. fd = open(filename, O_RDWR | O_CREAT | O_EXCL, 0600);
  161. Plus->Isle_spidx = RTreeNewIndex(fd, 0, ndims);
  162. remove(filename);
  163. }
  164. else {
  165. RTreeFreeIndex(Plus->Isle_spidx);
  166. Plus->Isle_spidx = RTreeNewIndex(-1, 0, ndims);
  167. }
  168. }
  169. /*!
  170. \brief Free spatial index (nodes, lines, areas, isles)
  171. \param Plus pointer to Plus_head structure
  172. */
  173. void dig_spidx_free(struct Plus_head *Plus)
  174. {
  175. /* Node spidx */
  176. if (Plus->Node_spidx->fd > -1)
  177. close(Plus->Node_spidx->fd);
  178. RTreeFreeIndex(Plus->Node_spidx);
  179. /* Line spidx */
  180. if (Plus->Line_spidx->fd > -1)
  181. close(Plus->Line_spidx->fd);
  182. RTreeFreeIndex(Plus->Line_spidx);
  183. /* Area spidx */
  184. if (Plus->Area_spidx->fd > -1)
  185. close(Plus->Area_spidx->fd);
  186. RTreeFreeIndex(Plus->Area_spidx);
  187. /* Isle spidx */
  188. if (Plus->Isle_spidx->fd > -1)
  189. close(Plus->Isle_spidx->fd);
  190. RTreeFreeIndex(Plus->Isle_spidx);
  191. /* 3D future : */
  192. /* Face spidx */
  193. /* Volume spidx */
  194. /* Hole spidx */
  195. }
  196. /*!
  197. \brief Add new node to spatial index
  198. \param Plus pointer to Plus_head structure
  199. \param node node id
  200. \param x,y,z node coordinates
  201. \return 1 OK
  202. \return 0 on error
  203. */
  204. int
  205. dig_spidx_add_node(struct Plus_head *Plus, int node,
  206. double x, double y, double z)
  207. {
  208. struct RTree_Rect rect;
  209. G_debug(3, "dig_spidx_add_node(): node = %d, x,y,z = %f, %f, %f", node, x,
  210. y, z);
  211. rect.boundary[0] = x;
  212. rect.boundary[1] = y;
  213. rect.boundary[2] = z;
  214. rect.boundary[3] = x;
  215. rect.boundary[4] = y;
  216. rect.boundary[5] = z;
  217. RTreeInsertRect(&rect, node, Plus->Node_spidx);
  218. return 1;
  219. }
  220. /*!
  221. \brief Add new line to spatial index
  222. \param Plus pointer to Plus_head structure
  223. \param line line id
  224. \param box bounding box
  225. \return 0
  226. */
  227. int dig_spidx_add_line(struct Plus_head *Plus, int line, struct bound_box * box)
  228. {
  229. struct RTree_Rect rect;
  230. G_debug(3, "dig_spidx_add_line(): line = %d", line);
  231. rect.boundary[0] = box->W;
  232. rect.boundary[1] = box->S;
  233. rect.boundary[2] = box->B;
  234. rect.boundary[3] = box->E;
  235. rect.boundary[4] = box->N;
  236. rect.boundary[5] = box->T;
  237. RTreeInsertRect(&rect, line, Plus->Line_spidx);
  238. return 0;
  239. }
  240. /*!
  241. \brief Add new area to spatial index
  242. \param Plus pointer to Plus_head structure
  243. \param area area id
  244. \param box bounding box
  245. \return 0
  246. */
  247. int dig_spidx_add_area(struct Plus_head *Plus, int area, struct bound_box * box)
  248. {
  249. struct RTree_Rect rect;
  250. G_debug(3, "dig_spidx_add_area(): area = %d", area);
  251. rect.boundary[0] = box->W;
  252. rect.boundary[1] = box->S;
  253. rect.boundary[2] = box->B;
  254. rect.boundary[3] = box->E;
  255. rect.boundary[4] = box->N;
  256. rect.boundary[5] = box->T;
  257. RTreeInsertRect(&rect, area, Plus->Area_spidx);
  258. return 0;
  259. }
  260. /*!
  261. \brief Add new island to spatial index
  262. \param Plus pointer to Plus_head structure
  263. \param isle isle id
  264. \param box bounding box
  265. \return 0
  266. */
  267. int dig_spidx_add_isle(struct Plus_head *Plus, int isle, struct bound_box * box)
  268. {
  269. struct RTree_Rect rect;
  270. G_debug(3, "dig_spidx_add_isle(): isle = %d", isle);
  271. rect.boundary[0] = box->W;
  272. rect.boundary[1] = box->S;
  273. rect.boundary[2] = box->B;
  274. rect.boundary[3] = box->E;
  275. rect.boundary[4] = box->N;
  276. rect.boundary[5] = box->T;
  277. RTreeInsertRect(&rect, isle, Plus->Isle_spidx);
  278. return 0;
  279. }
  280. /*!
  281. \brief Delete node from spatial index
  282. G_fatal_error() called on error.
  283. \param Plus pointer to Plus_head structure
  284. \param node node id
  285. \return 0
  286. */
  287. int dig_spidx_del_node(struct Plus_head *Plus, int node)
  288. {
  289. int ret;
  290. struct P_node *Node;
  291. struct RTree_Rect rect;
  292. G_debug(3, "dig_spidx_del_node(): node = %d", node);
  293. Node = Plus->Node[node];
  294. rect.boundary[0] = Node->x;
  295. rect.boundary[1] = Node->y;
  296. rect.boundary[2] = Node->z;
  297. rect.boundary[3] = Node->x;
  298. rect.boundary[4] = Node->y;
  299. rect.boundary[5] = Node->z;
  300. ret = RTreeDeleteRect(&rect, node, Plus->Node_spidx);
  301. if (ret)
  302. G_fatal_error(_("Unable to delete node %d from spatial index"), node);
  303. return 0;
  304. }
  305. /*!
  306. \brief Delete line from spatial index
  307. G_fatal_error() called on error.
  308. \param Plus pointer to Plus_head structure
  309. \param line line id
  310. \return 0
  311. */
  312. int dig_spidx_del_line(struct Plus_head *Plus, int line, double x, double y, double z)
  313. {
  314. struct P_line *Line;
  315. struct RTree_Rect rect;
  316. int ret;
  317. G_debug(3, "dig_spidx_del_line(): line = %d", line);
  318. Line = Plus->Line[line];
  319. rect.boundary[0] = x;
  320. rect.boundary[1] = y;
  321. rect.boundary[2] = z;
  322. rect.boundary[3] = x;
  323. rect.boundary[4] = y;
  324. rect.boundary[5] = z;
  325. ret = RTreeDeleteRect(&rect, line, Plus->Line_spidx);
  326. G_debug(3, " ret = %d", ret);
  327. if (ret)
  328. G_fatal_error(_("Unable to delete line %d from spatial index"), line);
  329. return 0;
  330. }
  331. /*!
  332. \brief Delete area from spatial index
  333. G_fatal_error() called on error.
  334. \param Plus pointer to Plus_head structure
  335. \param area area id
  336. \return 0
  337. */
  338. int dig_spidx_del_area(struct Plus_head *Plus, int area)
  339. {
  340. int ret;
  341. struct P_area *Area;
  342. struct P_line *Line;
  343. struct P_node *Node;
  344. struct P_topo_b *topo;
  345. struct RTree_Rect rect;
  346. G_debug(3, "dig_spidx_del_area(): area = %d", area);
  347. Area = Plus->Area[area];
  348. if (Area == NULL) {
  349. G_fatal_error(_("Attempt to delete sidx for dead area"));
  350. }
  351. Line = Plus->Line[abs(Area->lines[0])];
  352. topo = (struct P_topo_b *)Line->topo;
  353. Node = Plus->Node[topo->N1];
  354. rect.boundary[0] = Node->x;
  355. rect.boundary[1] = Node->y;
  356. rect.boundary[2] = Node->z;
  357. rect.boundary[3] = Node->x;
  358. rect.boundary[4] = Node->y;
  359. rect.boundary[5] = Node->z;
  360. ret = RTreeDeleteRect(&rect, area, Plus->Area_spidx);
  361. if (ret)
  362. G_fatal_error(_("Unable to delete area %d from spatial index"), area);
  363. return 0;
  364. }
  365. /*!
  366. \brief Delete isle from spatial index
  367. G_fatal_error() called on error.
  368. \param Plus pointer to Plus_head structure
  369. \param isle isle id
  370. \return 0
  371. */
  372. int dig_spidx_del_isle(struct Plus_head *Plus, int isle)
  373. {
  374. int ret;
  375. struct P_isle *Isle;
  376. struct P_line *Line;
  377. struct P_node *Node;
  378. struct P_topo_b *topo;
  379. struct RTree_Rect rect;
  380. G_debug(3, "dig_spidx_del_isle(): isle = %d", isle);
  381. Isle = Plus->Isle[isle];
  382. Line = Plus->Line[abs(Isle->lines[0])];
  383. topo = (struct P_topo_b *)Line->topo;
  384. Node = Plus->Node[topo->N1];
  385. rect.boundary[0] = Node->x;
  386. rect.boundary[1] = Node->y;
  387. rect.boundary[2] = Node->z;
  388. rect.boundary[3] = Node->x;
  389. rect.boundary[4] = Node->y;
  390. rect.boundary[5] = Node->z;
  391. ret = RTreeDeleteRect(&rect, isle, Plus->Isle_spidx);
  392. if (ret)
  393. G_fatal_error(_("Unable to delete isle %d from spatial index"), isle);
  394. return 0;
  395. }
  396. /* This function is called by RTreeSearch() to add selected node/line/area/isle to the list */
  397. static int _add_item(int id, struct RTree_Rect rect, struct ilist *list)
  398. {
  399. dig_list_add(list, id);
  400. return 1;
  401. }
  402. /* This function is called by RTreeSearch() to add
  403. * selected node/line/area/isle to the box list */
  404. static int _add_item_with_box(int id, struct RTree_Rect rect, struct boxlist *list)
  405. {
  406. struct bound_box box;
  407. box.W = rect.boundary[0];
  408. box.S = rect.boundary[1];
  409. box.B = rect.boundary[2];
  410. box.E = rect.boundary[3];
  411. box.N = rect.boundary[4];
  412. box.T = rect.boundary[5];
  413. dig_boxlist_add(list, id, box);
  414. return 1;
  415. }
  416. /* This function is called by RTreeSearch() to add
  417. * selected node/line/area/isle to the box list */
  418. static int _set_item_box(int id, struct RTree_Rect rect, struct boxlist *list)
  419. {
  420. if (id == list->id[0]) {
  421. list->box[0].W = rect.boundary[0];
  422. list->box[0].S = rect.boundary[1];
  423. list->box[0].B = rect.boundary[2];
  424. list->box[0].E = rect.boundary[3];
  425. list->box[0].N = rect.boundary[4];
  426. list->box[0].T = rect.boundary[5];
  427. return 0;
  428. }
  429. return 1;
  430. }
  431. /*!
  432. \brief Select nodes by bbox
  433. \param Plus pointer to Plus_head structure
  434. \param box bounding box
  435. \param list list of selected lines
  436. \return number of selected nodes
  437. \return -1 on error
  438. */
  439. int
  440. dig_select_nodes(struct Plus_head *Plus, const struct bound_box * box,
  441. struct ilist *list)
  442. {
  443. struct RTree_Rect rect;
  444. G_debug(3, "dig_select_nodes()");
  445. list->n_values = 0;
  446. rect.boundary[0] = box->W;
  447. rect.boundary[1] = box->S;
  448. rect.boundary[2] = box->B;
  449. rect.boundary[3] = box->E;
  450. rect.boundary[4] = box->N;
  451. rect.boundary[5] = box->T;
  452. if (Plus->Spidx_new)
  453. RTreeSearch(Plus->Node_spidx, &rect, (void *)_add_item, list);
  454. else
  455. rtree_search(Plus->Node_spidx, &rect, (void *)_add_item, list, Plus);
  456. return (list->n_values);
  457. }
  458. /* This function is called by RTreeSearch() for nodes to find the node id */
  459. static int _add_node(int id, struct RTree_Rect rect, int *node)
  460. {
  461. *node = id;
  462. return 0;
  463. }
  464. /*!
  465. \brief Find one node by coordinates
  466. \param Plus pointer to Plus_head structure
  467. \param x,y,z coordinates
  468. \return number of node
  469. \return 0 not found
  470. */
  471. int dig_find_node(struct Plus_head *Plus, double x, double y, double z)
  472. {
  473. struct RTree_Rect rect;
  474. int node;
  475. G_debug(3, "dig_find_node()");
  476. rect.boundary[0] = x;
  477. rect.boundary[1] = y;
  478. rect.boundary[2] = z;
  479. rect.boundary[3] = x;
  480. rect.boundary[4] = y;
  481. rect.boundary[5] = z;
  482. node = 0;
  483. if (Plus->Spidx_new)
  484. RTreeSearch(Plus->Node_spidx, &rect, (void *)_add_node, &node);
  485. else
  486. rtree_search(Plus->Node_spidx, &rect, (void *)_add_node, &node, Plus);
  487. return node;
  488. }
  489. /*!
  490. \brief Select lines with boxes by box
  491. \param Plus pointer to Plus_head structure
  492. \param box bounding box
  493. \param list boxlist of selected lines
  494. \return number of selected lines
  495. \return 0 not found
  496. */
  497. int dig_select_lines(struct Plus_head *Plus, const struct bound_box *box,
  498. struct boxlist *list)
  499. {
  500. struct RTree_Rect rect;
  501. G_debug(3, "dig_select_lines_with_box()");
  502. list->n_values = 0;
  503. rect.boundary[0] = box->W;
  504. rect.boundary[1] = box->S;
  505. rect.boundary[2] = box->B;
  506. rect.boundary[3] = box->E;
  507. rect.boundary[4] = box->N;
  508. rect.boundary[5] = box->T;
  509. if (Plus->Spidx_new)
  510. RTreeSearch(Plus->Line_spidx, &rect, (void *)_add_item_with_box, list);
  511. else
  512. rtree_search(Plus->Line_spidx, &rect, (void *)_add_item_with_box, list, Plus);
  513. return (list->n_values);
  514. }
  515. /*!
  516. \brief Find box for line
  517. \param Plus pointer to Plus_head structure
  518. \param[in,out] list line with isle id and search box (in)/line box (out)
  519. \return number of lines found
  520. \return 0 not found
  521. */
  522. int dig_find_line_box(const struct Plus_head *Plus, struct boxlist *list)
  523. {
  524. struct RTree_Rect rect;
  525. int ret;
  526. G_debug(3, "dig_find_line_box()");
  527. if (list->n_values < 1)
  528. G_fatal_error(_("No line id given"));
  529. rect.boundary[0] = list->box[0].W;
  530. rect.boundary[1] = list->box[0].S;
  531. rect.boundary[2] = list->box[0].B;
  532. rect.boundary[3] = list->box[0].E;
  533. rect.boundary[4] = list->box[0].N;
  534. rect.boundary[5] = list->box[0].T;
  535. if (Plus->Spidx_new)
  536. ret = RTreeSearch(Plus->Line_spidx, &rect, (void *)_set_item_box, list);
  537. else
  538. ret = rtree_search(Plus->Line_spidx, &rect, (void *)_set_item_box, list, Plus);
  539. return (ret);
  540. }
  541. /*!
  542. \brief Select areas with boxes by box
  543. \param Plus pointer to Plus_head structure
  544. \param box bounding box
  545. \param list boxlist of selected areas
  546. \return number of selected areas
  547. */
  548. int
  549. dig_select_areas(struct Plus_head *Plus, const struct bound_box * box,
  550. struct boxlist *list)
  551. {
  552. struct RTree_Rect rect;
  553. G_debug(3, "dig_select_areas_with_box()");
  554. list->n_values = 0;
  555. rect.boundary[0] = box->W;
  556. rect.boundary[1] = box->S;
  557. rect.boundary[2] = box->B;
  558. rect.boundary[3] = box->E;
  559. rect.boundary[4] = box->N;
  560. rect.boundary[5] = box->T;
  561. if (Plus->Spidx_new)
  562. RTreeSearch(Plus->Area_spidx, &rect, (void *)_add_item_with_box, list);
  563. else
  564. rtree_search(Plus->Area_spidx, &rect, (void *)_add_item_with_box, list, Plus);
  565. return (list->n_values);
  566. }
  567. /*!
  568. \brief Find box for area
  569. \param Plus pointer to Plus_head structure
  570. \param[in,out] list list with area id and search box (in)/area box (out)
  571. \return number of areas found
  572. \return 0 not found
  573. */
  574. int dig_find_area_box(const struct Plus_head *Plus, struct boxlist *list)
  575. {
  576. struct RTree_Rect rect;
  577. int ret;
  578. G_debug(3, "dig_find_line_box()");
  579. if (list->n_values < 1)
  580. G_fatal_error(_("No line id given"));
  581. rect.boundary[0] = list->box[0].W;
  582. rect.boundary[1] = list->box[0].S;
  583. rect.boundary[2] = list->box[0].B;
  584. rect.boundary[3] = list->box[0].E;
  585. rect.boundary[4] = list->box[0].N;
  586. rect.boundary[5] = list->box[0].T;
  587. if (Plus->Spidx_new)
  588. ret = RTreeSearch(Plus->Area_spidx, &rect, (void *)_set_item_box, list);
  589. else
  590. ret = rtree_search(Plus->Area_spidx, &rect, (void *)_set_item_box, list, Plus);
  591. return (ret);
  592. }
  593. /*!
  594. \brief Select isles with boxes by box
  595. \param Plus pointer to Plus_head structure
  596. \param box bounding box
  597. \param list boxlist of selected isles
  598. \return number of selected isles
  599. */
  600. int
  601. dig_select_isles(struct Plus_head *Plus, const struct bound_box * box,
  602. struct boxlist *list)
  603. {
  604. struct RTree_Rect rect;
  605. G_debug(3, "dig_select_areas_with_box()");
  606. list->n_values = 0;
  607. rect.boundary[0] = box->W;
  608. rect.boundary[1] = box->S;
  609. rect.boundary[2] = box->B;
  610. rect.boundary[3] = box->E;
  611. rect.boundary[4] = box->N;
  612. rect.boundary[5] = box->T;
  613. if (Plus->Spidx_new)
  614. RTreeSearch(Plus->Isle_spidx, &rect, (void *)_add_item_with_box, list);
  615. else
  616. rtree_search(Plus->Isle_spidx, &rect, (void *)_add_item_with_box, list, Plus);
  617. return (list->n_values);
  618. }
  619. /*!
  620. \brief Find box for isle
  621. \param Plus pointer to Plus_head structure
  622. \param[in,out] list list with isle id and search box (in)/isle box (out)
  623. \return number of isles found
  624. \return 0 not found
  625. */
  626. int dig_find_isle_box(const struct Plus_head *Plus, struct boxlist *list)
  627. {
  628. struct RTree_Rect rect;
  629. int ret;
  630. G_debug(3, "dig_find_line_box()");
  631. if (list->n_values < 1)
  632. G_fatal_error(_("No line id given"));
  633. rect.boundary[0] = list->box[0].W;
  634. rect.boundary[1] = list->box[0].S;
  635. rect.boundary[2] = list->box[0].B;
  636. rect.boundary[3] = list->box[0].E;
  637. rect.boundary[4] = list->box[0].N;
  638. rect.boundary[5] = list->box[0].T;
  639. if (Plus->Spidx_new)
  640. ret = RTreeSearch(Plus->Isle_spidx, &rect, (void *)_set_item_box, list);
  641. else
  642. ret = rtree_search(Plus->Isle_spidx, &rect, (void *)_set_item_box, list, Plus);
  643. return (ret);
  644. }