rtree.h 8.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238
  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. /* number of nodes buffered per level */
  45. #define NODE_BUFFER_SIZE 32
  46. struct RTree_Rect
  47. {
  48. RectReal *boundary; /* xmin,ymin,...,xmax,ymax,... */
  49. };
  50. struct RTree_Node; /* node for spatial index */
  51. union RTree_Child
  52. {
  53. int id; /* child id */
  54. struct RTree_Node *ptr; /* pointer to child node */
  55. off_t pos; /* position of child node in file */
  56. };
  57. struct RTree_Branch /* branch for spatial index */
  58. {
  59. struct RTree_Rect rect;
  60. union RTree_Child child;
  61. };
  62. struct RTree_Node /* node for spatial index */
  63. {
  64. int count; /* number of branches */
  65. int level; /* 0 is leaf, others positive */
  66. struct RTree_Branch *branch;
  67. };
  68. /*
  69. * If passed to a tree search, this callback function will be called
  70. * with the ID of each data rect that overlaps the search rect
  71. * plus whatever user specific pointer was passed to the search.
  72. * It can terminate the search early by returning 0 in which case
  73. * the search will return the number of hits found up to that point.
  74. */
  75. typedef int SearchHitCallback(int id, const struct RTree_Rect *rect, void *arg);
  76. struct RTree;
  77. typedef int rt_search_fn(struct RTree *, struct RTree_Rect *,
  78. SearchHitCallback *, void *);
  79. typedef int rt_insert_fn(struct RTree_Rect *, union RTree_Child, int, struct RTree *);
  80. typedef int rt_delete_fn(struct RTree_Rect *, union RTree_Child, struct RTree *);
  81. typedef int rt_valid_child_fn(union RTree_Child *);
  82. /* temp vars for each tree */
  83. /* node stack used for non-recursive insertion/deletion */
  84. struct nstack
  85. {
  86. struct RTree_Node *sn; /* stack node */
  87. int branch_id; /* branch number to follow down */
  88. off_t pos; /* file position of stack node */
  89. };
  90. /* node buffer for file-based index */
  91. struct NodeBuffer
  92. {
  93. struct RTree_Node n; /* buffered node */
  94. off_t pos; /* file position of buffered node */
  95. char dirty; /* node in buffer was modified */
  96. };
  97. /* temp vars for node splitting */
  98. struct RTree_PartitionVars {
  99. int partition[MAXCARD + 1];
  100. int total, minfill;
  101. int taken[MAXCARD + 1];
  102. int count[2];
  103. struct RTree_Rect cover[2];
  104. RectReal area[2];
  105. };
  106. struct RTree
  107. {
  108. /* RTree setup info */
  109. int fd; /* file descriptor */
  110. unsigned char ndims; /* number of dimensions */
  111. unsigned char nsides; /* number of sides = 2 * ndims */
  112. unsigned char ndims_alloc; /* number of dimensions allocated */
  113. unsigned char nsides_alloc; /* number of sides allocated = 2 * ndims allocated */
  114. int nodesize; /* node size in bytes */
  115. int branchsize; /* branch size in bytes */
  116. int rectsize; /* rectangle size in bytes */
  117. /* RTree info, useful to calculate space requirements */
  118. int n_nodes; /* number of nodes */
  119. int n_leafs; /* number of data items (level 0 leafs) */
  120. int rootlevel; /* root level = tree depth */
  121. /* settings for RTree building */
  122. int nodecard; /* max number of childs in node */
  123. int leafcard; /* max number of childs in leaf */
  124. int min_node_fill; /* balance criteria for node removal */
  125. int min_leaf_fill; /* balance criteria for leaf removal */
  126. int minfill_node_split; /* balance criteria for splitting */
  127. int minfill_leaf_split; /* balance criteria for splitting */
  128. char overflow; /* enable/disable overflow */
  129. /* free node positions for recycling */
  130. struct _recycle {
  131. int avail; /* number of available positions */
  132. int alloc; /* number of allcoated positions in *pos */
  133. off_t *pos; /* array of available positions */
  134. } free_nodes;
  135. /* node buffer for file-based index */
  136. struct NodeBuffer **nb;
  137. /* usage order of buffered nodes per level
  138. * used[level][0] = most recently used
  139. * used[level][NODE_BUFFER_SIZE - 1] = least recently used */
  140. int **used;
  141. /* insert, delete, search */
  142. rt_insert_fn *insert_rect;
  143. rt_delete_fn *delete_rect;
  144. rt_search_fn *search_rect;
  145. rt_valid_child_fn *valid_child;
  146. struct RTree_Node *root; /* pointer to root node */
  147. /* internal variables, specific for each tree,
  148. * allocated with tree initialization */
  149. /* node stack for tree traversal */
  150. struct nstack *ns;
  151. /* variables for splitting / forced reinsertion */
  152. struct RTree_PartitionVars p;
  153. struct RTree_Branch *BranchBuf;
  154. struct RTree_Branch tmpb1, tmpb2, c;
  155. int BranchCount;
  156. struct RTree_Rect rect_0, rect_1, upperrect, orect;
  157. RectReal *center_n;
  158. off_t rootpos; /* root node position in file */
  159. };
  160. /* RTree main functions */
  161. int RTreeSearch(struct RTree *, struct RTree_Rect *,
  162. SearchHitCallback *, void *);
  163. int RTreeInsertRect(struct RTree_Rect *, int, struct RTree *);
  164. void RTreeSetRect1D(struct RTree_Rect *r, struct RTree *t, double x_min,
  165. double x_max);
  166. void RTreeSetRect2D(struct RTree_Rect *r, struct RTree *t, double x_min,
  167. double x_max, double y_min, double y_max);
  168. void RTreeSetRect3D(struct RTree_Rect *r, struct RTree *t, double x_min,
  169. double x_max, double y_min, double y_max, double z_min,
  170. double z_max);
  171. void RTreeSetRect4D(struct RTree_Rect *r, struct RTree *t, double x_min,
  172. double x_max, double y_min, double y_max, double z_min,
  173. double z_max, double t_min, double t_max);
  174. int RTreeDeleteRect(struct RTree_Rect *, int, struct RTree *);
  175. void RTreePrintRect(struct RTree_Rect *, int, struct RTree *);
  176. struct RTree *RTreeCreateTree(int, off_t, int);
  177. void RTreeSetOverflow(struct RTree *, char);
  178. void RTreeDestroyTree(struct RTree *);
  179. int RTreeOverlap(struct RTree_Rect *, struct RTree_Rect *, struct RTree *);
  180. int RTreeContained(struct RTree_Rect *, struct RTree_Rect *, struct RTree *);
  181. int RTreeContains(struct RTree_Rect *, struct RTree_Rect *, struct RTree *);
  182. /* RTree node management */
  183. struct RTree_Node *RTreeAllocNode(struct RTree *, int);
  184. void RTreeInitNode(struct RTree *, struct RTree_Node *, int);
  185. void RTreeCopyNode(struct RTree_Node *, struct RTree_Node *, struct RTree *);
  186. void RTreeFreeNode(struct RTree_Node *);
  187. void RTreeDestroyNode(struct RTree_Node *, int);
  188. /* RTree rectangle allocation and deletion */
  189. struct RTree_Rect *RTreeAllocRect(struct RTree *t);
  190. void RTreeFreeRect(struct RTree_Rect *r);
  191. RectReal *RTreeAllocBoundary(struct RTree *t);
  192. void RTreeFreeBoundary(struct RTree_Rect *r);
  193. /* RTree IO */
  194. size_t RTreeReadNode(struct RTree_Node *, off_t, struct RTree *);
  195. size_t RTreeWriteNode(struct RTree_Node *, struct RTree *);
  196. off_t RTreeGetNodePos(struct RTree *);
  197. void RTreeFlushBuffer(struct RTree *);
  198. #endif