select.c 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161
  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 = RTreeCreateTree(-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. RTreeDestroyTree(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. static struct RTree_Rect rect;
  48. static int rect_init = 0;
  49. if (!rect_init) {
  50. rect.boundary = G_malloc(si->si_tree->nsides_alloc * sizeof(RectReal));
  51. rect_init = si->si_tree->nsides_alloc;
  52. }
  53. G_debug(3, "Vect_spatial_index_add_item(): id = %d", id);
  54. rect.boundary[0] = box->W;
  55. rect.boundary[1] = box->S;
  56. rect.boundary[2] = box->B;
  57. rect.boundary[3] = box->E;
  58. rect.boundary[4] = box->N;
  59. rect.boundary[5] = box->T;
  60. RTreeInsertRect(&rect, id, si->si_tree);
  61. }
  62. /*!
  63. \brief Delete item from spatial index structure
  64. \param[in,out] si pointer to spatial index structure
  65. \param id item identifier
  66. \return void
  67. */
  68. void Vect_spatial_index_del_item(struct spatial_index * si, int id,
  69. const struct bound_box * box)
  70. {
  71. int ret;
  72. static struct RTree_Rect rect;
  73. static int rect_init = 0;
  74. if (!rect_init) {
  75. rect.boundary = G_malloc(si->si_tree->nsides_alloc * sizeof(RectReal));
  76. rect_init = si->si_tree->nsides_alloc;
  77. }
  78. G_debug(3, "Vect_spatial_index_del_item(): id = %d", id);
  79. rect.boundary[0] = box->W;
  80. rect.boundary[1] = box->S;
  81. rect.boundary[2] = box->B;
  82. rect.boundary[3] = box->E;
  83. rect.boundary[4] = box->N;
  84. rect.boundary[5] = box->T;
  85. ret = RTreeDeleteRect(&rect, id, si->si_tree);
  86. if (ret)
  87. G_fatal_error(_("Unable to delete item %d from spatial index"), id);
  88. }
  89. /************************* SELECT BY BOX *********************************/
  90. /* This function is called by RTreeSearch() to add selected item to the list */
  91. static int _add_item(int id, const struct RTree_Rect *rect, struct ilist *list)
  92. {
  93. G_ilist_add(list, id);
  94. return 1;
  95. }
  96. /*!
  97. \brief Select items by bounding box to list
  98. \param si pointer to spatial index structure
  99. \param box bounding box
  100. \param[out] list pointer to list where selected items are stored
  101. \return number of selected items
  102. */
  103. int Vect_spatial_index_select(const struct spatial_index * si, const struct bound_box * box,
  104. struct ilist *list)
  105. {
  106. static struct RTree_Rect rect;
  107. static int rect_init = 0;
  108. if (!rect_init) {
  109. rect.boundary = G_malloc(si->si_tree->nsides_alloc * sizeof(RectReal));
  110. rect_init = si->si_tree->nsides_alloc;
  111. }
  112. Vect_reset_list(list);
  113. rect.boundary[0] = box->W;
  114. rect.boundary[1] = box->S;
  115. rect.boundary[2] = box->B;
  116. rect.boundary[3] = box->E;
  117. rect.boundary[4] = box->N;
  118. rect.boundary[5] = box->T;
  119. RTreeSearch(si->si_tree, &rect, (void *)_add_item, list);
  120. G_debug(3, "Vect_spatial_index_select(): %d items selected", list->n_values);
  121. return list->n_values;
  122. }