spindex.c 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936
  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 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 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 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 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 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 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 Rect rect;
  343. struct P_line *Line;
  344. struct P_node *Node;
  345. struct P_topo_b *topo;
  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[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 Rect rect;
  377. struct P_line *Line;
  378. struct P_node *Node;
  379. struct P_topo_b *topo;
  380. G_debug(3, "dig_spidx_del_isle(): isle = %d", isle);
  381. Isle = Plus->Isle[isle];
  382. Line = Plus->Line[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 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 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 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 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 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 Rect rect;
  474. struct ilist list;
  475. int node;
  476. G_debug(3, "dig_find_node()");
  477. dig_init_list(&list);
  478. rect.boundary[0] = x;
  479. rect.boundary[1] = y;
  480. rect.boundary[2] = z;
  481. rect.boundary[3] = x;
  482. rect.boundary[4] = y;
  483. rect.boundary[5] = z;
  484. node = 0;
  485. if (Plus->Spidx_new)
  486. RTreeSearch(Plus->Node_spidx, &rect, (void *)_add_node, &node);
  487. else
  488. rtree_search(Plus->Node_spidx, &rect, (void *)_add_node, &node, Plus);
  489. return node;
  490. }
  491. /*!
  492. \brief Select lines by box
  493. \param Plus pointer to Plus_head structure
  494. \param box bounding box
  495. \param list list of selected lines
  496. \return number of selected lines
  497. */
  498. int
  499. dig_select_lines(struct Plus_head *Plus, const struct bound_box * box,
  500. struct ilist *list)
  501. {
  502. struct Rect rect;
  503. G_debug(3, "dig_select_lines()");
  504. list->n_values = 0;
  505. rect.boundary[0] = box->W;
  506. rect.boundary[1] = box->S;
  507. rect.boundary[2] = box->B;
  508. rect.boundary[3] = box->E;
  509. rect.boundary[4] = box->N;
  510. rect.boundary[5] = box->T;
  511. if (Plus->Spidx_new)
  512. RTreeSearch(Plus->Line_spidx, &rect, (void *)_add_item, list);
  513. else
  514. rtree_search(Plus->Line_spidx, &rect, (void *)_add_item, list, Plus);
  515. return (list->n_values);
  516. }
  517. /*!
  518. \brief Select lines with boxes by box
  519. \param Plus pointer to Plus_head structure
  520. \param box bounding box
  521. \param list boxlist of selected lines
  522. \return number of selected lines
  523. \return 0 not found
  524. */
  525. int dig_select_lines_with_box(struct Plus_head *Plus, const struct bound_box *box,
  526. struct boxlist *list)
  527. {
  528. struct Rect rect;
  529. G_debug(3, "dig_select_lines_with_box()");
  530. list->n_values = 0;
  531. rect.boundary[0] = box->W;
  532. rect.boundary[1] = box->S;
  533. rect.boundary[2] = box->B;
  534. rect.boundary[3] = box->E;
  535. rect.boundary[4] = box->N;
  536. rect.boundary[5] = box->T;
  537. if (Plus->Spidx_new)
  538. RTreeSearch(Plus->Line_spidx, &rect, (void *)_add_item_with_box, list);
  539. else
  540. rtree_search(Plus->Line_spidx, &rect, (void *)_add_item_with_box, list, Plus);
  541. return (list->n_values);
  542. }
  543. /*!
  544. \brief Find box for line
  545. \param Plus pointer to Plus_head structure
  546. \param[in,out] list line with isle id and search box (in)/line box (out)
  547. \return number of lines found
  548. \return 0 not found
  549. */
  550. int dig_find_line_box(const struct Plus_head *Plus, struct boxlist *list)
  551. {
  552. struct Rect rect;
  553. int ret;
  554. G_debug(3, "dig_find_line_box()");
  555. if (list->n_values < 1)
  556. G_fatal_error(_("No line id given"));
  557. rect.boundary[0] = list->box[0].W;
  558. rect.boundary[1] = list->box[0].S;
  559. rect.boundary[2] = list->box[0].B;
  560. rect.boundary[3] = list->box[0].E;
  561. rect.boundary[4] = list->box[0].N;
  562. rect.boundary[5] = list->box[0].T;
  563. if (Plus->Spidx_new)
  564. ret = RTreeSearch(Plus->Line_spidx, &rect, (void *)_set_item_box, list);
  565. else
  566. ret = rtree_search(Plus->Line_spidx, &rect, (void *)_set_item_box, list, Plus);
  567. return (ret);
  568. }
  569. /*!
  570. \brief Select areas by box
  571. \param Plus pointer to Plus_head structure
  572. \param box bounding box
  573. \param list list of selected lines
  574. \return number of selected areas
  575. */
  576. int
  577. dig_select_areas(struct Plus_head *Plus, const struct bound_box * box,
  578. struct ilist *list)
  579. {
  580. struct Rect rect;
  581. G_debug(3, "dig_select_areas()");
  582. list->n_values = 0;
  583. rect.boundary[0] = box->W;
  584. rect.boundary[1] = box->S;
  585. rect.boundary[2] = box->B;
  586. rect.boundary[3] = box->E;
  587. rect.boundary[4] = box->N;
  588. rect.boundary[5] = box->T;
  589. if (Plus->Spidx_new)
  590. RTreeSearch(Plus->Area_spidx, &rect, (void *)_add_item, list);
  591. else
  592. rtree_search(Plus->Area_spidx, &rect, (void *)_add_item, list, Plus);
  593. return (list->n_values);
  594. }
  595. /*!
  596. \brief Select areas with boxes by box
  597. \param Plus pointer to Plus_head structure
  598. \param box bounding box
  599. \param list boxlist of selected areas
  600. \return number of selected areas
  601. */
  602. int
  603. dig_select_areas_with_box(struct Plus_head *Plus, const struct bound_box * box,
  604. struct boxlist *list)
  605. {
  606. struct Rect rect;
  607. G_debug(3, "dig_select_areas_with_box()");
  608. list->n_values = 0;
  609. rect.boundary[0] = box->W;
  610. rect.boundary[1] = box->S;
  611. rect.boundary[2] = box->B;
  612. rect.boundary[3] = box->E;
  613. rect.boundary[4] = box->N;
  614. rect.boundary[5] = box->T;
  615. if (Plus->Spidx_new)
  616. RTreeSearch(Plus->Area_spidx, &rect, (void *)_add_item_with_box, list);
  617. else
  618. rtree_search(Plus->Area_spidx, &rect, (void *)_add_item_with_box, list, Plus);
  619. return (list->n_values);
  620. }
  621. /*!
  622. \brief Find box for area
  623. \param Plus pointer to Plus_head structure
  624. \param[in,out] list list with area id and search box (in)/area box (out)
  625. \return number of areas found
  626. \return 0 not found
  627. */
  628. int dig_find_area_box(const struct Plus_head *Plus, struct boxlist *list)
  629. {
  630. struct Rect rect;
  631. int ret;
  632. G_debug(3, "dig_find_line_box()");
  633. if (list->n_values < 1)
  634. G_fatal_error(_("No line id given"));
  635. rect.boundary[0] = list->box[0].W;
  636. rect.boundary[1] = list->box[0].S;
  637. rect.boundary[2] = list->box[0].B;
  638. rect.boundary[3] = list->box[0].E;
  639. rect.boundary[4] = list->box[0].N;
  640. rect.boundary[5] = list->box[0].T;
  641. if (Plus->Spidx_new)
  642. ret = RTreeSearch(Plus->Area_spidx, &rect, (void *)_set_item_box, list);
  643. else
  644. ret = rtree_search(Plus->Area_spidx, &rect, (void *)_set_item_box, list, Plus);
  645. return (ret);
  646. }
  647. /*!
  648. \brief Select isles by box
  649. \param Plus pointer to Plus_head structure
  650. \param box bounding box
  651. \param list list of selected lines
  652. \return number of selected isles
  653. */
  654. int
  655. dig_select_isles(struct Plus_head *Plus, const struct bound_box * box,
  656. struct ilist *list)
  657. {
  658. struct Rect rect;
  659. G_debug(3, "dig_select_isles()");
  660. list->n_values = 0;
  661. rect.boundary[0] = box->W;
  662. rect.boundary[1] = box->S;
  663. rect.boundary[2] = box->B;
  664. rect.boundary[3] = box->E;
  665. rect.boundary[4] = box->N;
  666. rect.boundary[5] = box->T;
  667. if (Plus->Spidx_new)
  668. RTreeSearch(Plus->Isle_spidx, &rect, (void *)_add_item, list);
  669. else
  670. rtree_search(Plus->Isle_spidx, &rect, (void *)_add_item, list, Plus);
  671. return (list->n_values);
  672. }
  673. /*!
  674. \brief Select isles with boxes by box
  675. \param Plus pointer to Plus_head structure
  676. \param box bounding box
  677. \param list boxlist of selected isles
  678. \return number of selected isles
  679. */
  680. int
  681. dig_select_isles_with_box(struct Plus_head *Plus, const struct bound_box * box,
  682. struct boxlist *list)
  683. {
  684. struct Rect rect;
  685. G_debug(3, "dig_select_areas_with_box()");
  686. list->n_values = 0;
  687. rect.boundary[0] = box->W;
  688. rect.boundary[1] = box->S;
  689. rect.boundary[2] = box->B;
  690. rect.boundary[3] = box->E;
  691. rect.boundary[4] = box->N;
  692. rect.boundary[5] = box->T;
  693. if (Plus->Spidx_new)
  694. RTreeSearch(Plus->Isle_spidx, &rect, (void *)_add_item_with_box, list);
  695. else
  696. rtree_search(Plus->Isle_spidx, &rect, (void *)_add_item_with_box, list, Plus);
  697. return (list->n_values);
  698. }
  699. /*!
  700. \brief Find box for isle
  701. \param Plus pointer to Plus_head structure
  702. \param[in,out] list list with isle id and search box (in)/isle box (out)
  703. \return number of isles found
  704. \return 0 not found
  705. */
  706. int dig_find_isle_box(const struct Plus_head *Plus, struct boxlist *list)
  707. {
  708. struct Rect rect;
  709. int ret;
  710. G_debug(3, "dig_find_line_box()");
  711. if (list->n_values < 1)
  712. G_fatal_error(_("No line id given"));
  713. rect.boundary[0] = list->box[0].W;
  714. rect.boundary[1] = list->box[0].S;
  715. rect.boundary[2] = list->box[0].B;
  716. rect.boundary[3] = list->box[0].E;
  717. rect.boundary[4] = list->box[0].N;
  718. rect.boundary[5] = list->box[0].T;
  719. if (Plus->Spidx_new)
  720. ret = RTreeSearch(Plus->Isle_spidx, &rect, (void *)_set_item_box, list);
  721. else
  722. ret = rtree_search(Plus->Isle_spidx, &rect, (void *)_set_item_box, list, Plus);
  723. return (ret);
  724. }