select.c 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*!
  2. \file lib/vector/Vlib/select.c
  3. \brief Vector library - spatial index
  4. Higher level functions for a custom spatial index.
  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 Radim Blazek
  9. */
  10. #include <stdlib.h>
  11. #include <unistd.h>
  12. #include <sys/stat.h>
  13. #include <string.h>
  14. #include <grass/vector.h>
  15. #include <grass/glocale.h>
  16. /*!
  17. \brief Initialize spatial index structure
  18. \param si pointer to spatial index structure
  19. \return void
  20. */
  21. void Vect_spatial_index_init(struct spatial_index * si, int with_z)
  22. {
  23. G_debug(1, "Vect_spatial_index_init()");
  24. si->si_tree = RTreeNewIndex(-1, 0, 2 + (with_z != 0));
  25. }
  26. /*!
  27. \brief Destroy existing spatial index
  28. Vect_spatial_index_init() must be call before new use.
  29. \param si pointer to spatial index structure
  30. \return void
  31. */
  32. void Vect_spatial_index_destroy(struct spatial_index * si)
  33. {
  34. G_debug(1, "Vect_spatial_index_destroy()");
  35. RTreeFreeIndex(si->si_tree);
  36. }
  37. /*!
  38. \brief Add a new item to spatial index structure
  39. \param[in,out] si pointer to spatial index structure
  40. \param id item identifier
  41. \param box pointer to item bounding box
  42. \return void
  43. */
  44. void Vect_spatial_index_add_item(struct spatial_index * si, int id,
  45. const struct bound_box * box)
  46. {
  47. struct Rect rect;
  48. G_debug(3, "Vect_spatial_index_add_item(): id = %d", id);
  49. rect.boundary[0] = box->W;
  50. rect.boundary[1] = box->S;
  51. rect.boundary[2] = box->B;
  52. rect.boundary[3] = box->E;
  53. rect.boundary[4] = box->N;
  54. rect.boundary[5] = box->T;
  55. RTreeInsertRect(&rect, id, si->si_tree);
  56. }
  57. /*!
  58. \brief Delete item from spatial index structure
  59. \param[in,out] si pointer to spatial index structure
  60. \param id item identifier
  61. \return void
  62. */
  63. void Vect_spatial_index_del_item(struct spatial_index * si, int id,
  64. const struct bound_box * box)
  65. {
  66. int ret;
  67. struct Rect rect;
  68. G_debug(3, "Vect_spatial_index_del_item(): id = %d", id);
  69. rect.boundary[0] = box->W;
  70. rect.boundary[1] = box->S;
  71. rect.boundary[2] = box->B;
  72. rect.boundary[3] = box->E;
  73. rect.boundary[4] = box->N;
  74. rect.boundary[5] = box->T;
  75. ret = RTreeDeleteRect(&rect, id, si->si_tree);
  76. if (ret)
  77. G_fatal_error(_("Unable to delete item %d from spatial index"), id);
  78. }
  79. /************************* SELECT BY BOX *********************************/
  80. /* This function is called by RTreeSearch() to add selected item to the list */
  81. static int _add_item(int id, struct ilist *list)
  82. {
  83. dig_list_add(list, id);
  84. return 1;
  85. }
  86. /*!
  87. \brief Select items by bounding box to list
  88. \param si pointer to spatial index structure
  89. \param box bounding box
  90. \param[out] list pointer to list where selected items are stored
  91. \return number of selected items
  92. */
  93. int
  94. Vect_spatial_index_select(const struct spatial_index * si, const struct bound_box * box,
  95. struct ilist *list)
  96. {
  97. struct Rect rect;
  98. G_debug(3, "Vect_spatial_index_select()");
  99. Vect_reset_list(list);
  100. rect.boundary[0] = box->W;
  101. rect.boundary[1] = box->S;
  102. rect.boundary[2] = box->B;
  103. rect.boundary[3] = box->E;
  104. rect.boundary[4] = box->N;
  105. rect.boundary[5] = box->T;
  106. RTreeSearch(si->si_tree, &rect, (void *)_add_item, list);
  107. G_debug(3, " %d items selected", list->n_values);
  108. return (list->n_values);
  109. }