rtree.h 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224
  1. /****************************************************************************
  2. * MODULE: R-Tree library
  3. *
  4. * AUTHOR(S): Antonin Guttman - original code
  5. * Daniel Green (green@superliminal.com) - major clean-up
  6. * and implementation of bounding spheres
  7. * Markus Metz - file-based and memory-based R*-tree
  8. *
  9. * PURPOSE: Multidimensional index
  10. *
  11. * COPYRIGHT: (C) 2010-2012 by the GRASS Development Team
  12. *
  13. * This program is free software under the GNU General Public
  14. * License (>=v2). Read the file COPYING that comes with GRASS
  15. * for details.
  16. *****************************************************************************/
  17. #ifndef _R_TREE_H_
  18. #define _R_TREE_H_
  19. #include <stdlib.h>
  20. #include <stdio.h>
  21. #include <string.h>
  22. #include <sys/types.h>
  23. #include <grass/config.h> /* needed for LFS */
  24. typedef double RectReal;
  25. /*-----------------------------------------------------------------------------
  26. | Global definitions.
  27. -----------------------------------------------------------------------------*/
  28. #ifndef TRUE
  29. #define TRUE 1
  30. #endif
  31. #ifndef FALSE
  32. #define FALSE 0
  33. #endif
  34. /* max branching factor of a node */
  35. /* was (PGSIZE-(2 * sizeof(int))) / sizeof(struct Branch)
  36. * this is LFS dependent, not good
  37. * on 32 bit without LFS this is 9.69
  38. * on 32 bit with LFS and on 64 bit this is 9 */
  39. #define MAXCARD 9
  40. #define NODECARD MAXCARD
  41. #define LEAFCARD MAXCARD
  42. /* maximum no of levels = tree depth */
  43. #define MAXLEVEL 20 /* 8^MAXLEVEL items are guaranteed to fit into the tree */
  44. struct RTree_Rect
  45. {
  46. RectReal *boundary; /* xmin,ymin,...,xmax,ymax,... */
  47. };
  48. struct RTree_Node; /* node for spatial index */
  49. union RTree_Child
  50. {
  51. int id; /* child id */
  52. struct RTree_Node *ptr; /* pointer to child node */
  53. off_t pos; /* position of child node in file */
  54. };
  55. struct RTree_Branch /* branch for spatial index */
  56. {
  57. struct RTree_Rect rect;
  58. union RTree_Child child;
  59. };
  60. struct RTree_Node /* node for spatial index */
  61. {
  62. int count; /* number of branches */
  63. int level; /* 0 is leaf, others positive */
  64. struct RTree_Branch branch[MAXCARD];
  65. };
  66. /*
  67. * If passed to a tree search, this callback function will be called
  68. * with the ID of each data rect that overlaps the search rect
  69. * plus whatever user specific pointer was passed to the search.
  70. * It can terminate the search early by returning 0 in which case
  71. * the search will return the number of hits found up to that point.
  72. */
  73. typedef int SearchHitCallback(int id, const struct RTree_Rect *rect, void *arg);
  74. struct RTree;
  75. typedef int rt_search_fn(struct RTree *, const struct RTree_Rect *,
  76. SearchHitCallback *, void *);
  77. typedef int rt_insert_fn(struct RTree_Rect *, union RTree_Child, int, struct RTree *);
  78. typedef int rt_delete_fn(struct RTree_Rect *, union RTree_Child, struct RTree *);
  79. typedef int rt_valid_child_fn(union RTree_Child *);
  80. /* temp vars for each tree */
  81. /* stacks used for non-recursive insertion/deletion */
  82. /* stack for file-based index */
  83. struct fstack
  84. {
  85. struct RTree_Node sn; /* stack node */
  86. int branch_id; /* branch number to follow down */
  87. off_t pos; /* file position of stack node */
  88. };
  89. /* stack for memory-based index */
  90. struct mstack
  91. {
  92. struct RTree_Node *sn; /* stack node pointer */
  93. int branch_id; /* branch number to follow down */
  94. };
  95. /* temp vars for node splitting */
  96. struct RTree_PartitionVars {
  97. int partition[MAXCARD + 1];
  98. int total, minfill;
  99. int taken[MAXCARD + 1];
  100. int count[2];
  101. struct RTree_Rect cover[2];
  102. RectReal area[2];
  103. };
  104. struct RTree
  105. {
  106. /* RTree setup info */
  107. int fd; /* file descriptor */
  108. unsigned char ndims; /* number of dimensions */
  109. unsigned char nsides; /* number of sides = 2 * ndims */
  110. unsigned char ndims_alloc; /* number of dimensions allocated */
  111. unsigned char nsides_alloc; /* number of sides allocated = 2 * ndims allocated */
  112. int nodesize; /* node size in bytes */
  113. int branchsize; /* branch size in bytes */
  114. int rectsize; /* rectangle size in bytes */
  115. /* RTree info, useful to calculate space requirements */
  116. int n_nodes; /* number of nodes */
  117. int n_leafs; /* number of data items (level 0 leafs) */
  118. int rootlevel; /* root level = tree depth */
  119. /* settings for RTree building */
  120. int nodecard; /* max number of childs in node */
  121. int leafcard; /* max number of childs in leaf */
  122. int min_node_fill; /* balance criteria for node removal */
  123. int min_leaf_fill; /* balance criteria for leaf removal */
  124. int minfill_node_split; /* balance criteria for splitting */
  125. int minfill_leaf_split; /* balance criteria for splitting */
  126. /* free node positions for recycling */
  127. struct _recycle {
  128. int avail; /* number of available positions */
  129. int alloc; /* number of allcoated positions in *pos */
  130. off_t *pos; /* array of available positions */
  131. } free_nodes;
  132. /* node buffer for file-based index, three nodes per level
  133. * more than three nodes per level would require too complex cache management */
  134. struct NodeBuffer
  135. {
  136. struct RTree_Node n; /* buffered node */
  137. off_t pos; /* file position of buffered node */
  138. char dirty; /* node in buffer was modified */
  139. } nb[MAXLEVEL][3];
  140. /* usage order of buffered nodes per level
  141. * used[level][0] = most recently used
  142. * used[level][2] = least recently used */
  143. char used[MAXLEVEL][3];
  144. /* insert, delete, search */
  145. rt_insert_fn *insert_rect;
  146. rt_delete_fn *delete_rect;
  147. rt_search_fn *search_rect;
  148. rt_valid_child_fn *valid_child;
  149. struct RTree_Node *root; /* pointer to root node */
  150. /* internal variables, specific for each tree,
  151. * allocated with tree initialization */
  152. /* stacks for tree traversal */
  153. struct mstack ms[MAXLEVEL];
  154. struct fstack fs[MAXLEVEL];
  155. /* variables for splitting / forced reinsertion */
  156. struct RTree_PartitionVars p;
  157. struct RTree_Branch BranchBuf[MAXCARD + 1];
  158. struct RTree_Branch tmpb1, tmpb2, c;
  159. int BranchCount;
  160. struct RTree_Rect rect_0, rect_1, upperrect, orect;
  161. RectReal *center_n;
  162. off_t rootpos; /* root node position in file */
  163. };
  164. /* RTree main functions */
  165. int RTreeSearch(struct RTree *, struct RTree_Rect *,
  166. SearchHitCallback *, void *);
  167. int RTreeInsertRect(struct RTree_Rect *, int, struct RTree *);
  168. int RTreeDeleteRect(struct RTree_Rect *, int, struct RTree *);
  169. struct RTree *RTreeNewIndex(int, off_t, int);
  170. void RTreeFreeIndex(struct RTree *);
  171. int RTreeOverlap(struct RTree_Rect *, struct RTree_Rect *, struct RTree *);
  172. int RTreeContained(struct RTree_Rect *, struct RTree_Rect *, struct RTree *);
  173. int RTreeContains(struct RTree_Rect *, struct RTree_Rect *, struct RTree *);
  174. /* RTree node management */
  175. struct RTree_Node *RTreeNewNode(struct RTree *, int);
  176. void RTreeInitNode(struct RTree *, struct RTree_Node *, int);
  177. void RTreeCopyNode(struct RTree_Node *, struct RTree_Node *, struct RTree *);
  178. void RTreeFreeNode(struct RTree_Node *);
  179. void RTreeDestroyNode(struct RTree_Node *, int);
  180. void RTreeNewRect(struct RTree_Rect *, struct RTree *);
  181. /* RTree IO */
  182. size_t RTreeReadNode(struct RTree_Node *, off_t, struct RTree *);
  183. size_t RTreeWriteNode(struct RTree_Node *, struct RTree *);
  184. off_t RTreeGetNodePos(struct RTree *);
  185. void RTreeFlushBuffer(struct RTree *);
  186. #endif