load.go 2.5 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697
  1. package base
  2. import "math"
  3. // Load bulk load items into the R-tree.
  4. func (tr *RTree) Load(mins, maxs [][]float64, items []interface{}) {
  5. if len(items) < tr.minEntries {
  6. for i := 0; i < len(items); i++ {
  7. tr.Insert(mins[i], maxs[i], items[i])
  8. }
  9. return
  10. }
  11. // prefill the items
  12. fitems := make([]*treeNode, len(items))
  13. for i := 0; i < len(items); i++ {
  14. item := &treeItem{min: mins[i], max: maxs[i], item: items[i]}
  15. fitems[i] = item.unsafeNode()
  16. }
  17. // following equations are defined in the paper describing OMT
  18. N := len(fitems)
  19. M := tr.maxEntries
  20. h := int(math.Ceil(math.Log(float64(N)) / math.Log(float64(M))))
  21. Nsubtree := int(math.Pow(float64(M), float64(h-1)))
  22. S := int(math.Ceil(math.Sqrt(float64(N) / float64(Nsubtree))))
  23. // sort by the initial axis
  24. axis := 0
  25. sortByAxis(fitems, axis)
  26. // build the root node. it's split differently from the subtrees.
  27. children := make([]*treeNode, 0, S)
  28. for i := 0; i < S; i++ {
  29. var part []*treeNode
  30. if i == S-1 {
  31. // last split
  32. part = fitems[len(fitems)/S*i:]
  33. } else {
  34. part = fitems[len(fitems)/S*i : len(fitems)/S*(i+1)]
  35. }
  36. children = append(children, tr.omt(part, h-1, axis+1))
  37. }
  38. node := tr.createNode(children)
  39. node.leaf = false
  40. node.height = h
  41. tr.calcBBox(node)
  42. if tr.data.count == 0 {
  43. // save as is if tree is empty
  44. tr.data = node
  45. } else if tr.data.height == node.height {
  46. // split root if trees have the same height
  47. tr.splitRoot(tr.data, node)
  48. } else {
  49. if tr.data.height < node.height {
  50. // swap trees if inserted one is bigger
  51. tr.data, node = node, tr.data
  52. }
  53. // insert the small tree into the large tree at appropriate level
  54. tr.insert(node, nil, tr.data.height-node.height-1, true)
  55. }
  56. }
  57. func (tr *RTree) omt(fitems []*treeNode, h, axis int) *treeNode {
  58. if len(fitems) <= tr.maxEntries {
  59. // reached leaf level; return leaf
  60. children := make([]*treeNode, len(fitems))
  61. copy(children, fitems)
  62. node := tr.createNode(children)
  63. node.height = h
  64. tr.calcBBox(node)
  65. return node
  66. }
  67. // sort the items on a different axis than the previous level.
  68. sortByAxis(fitems, axis%tr.dims)
  69. children := make([]*treeNode, 0, tr.maxEntries)
  70. partsz := len(fitems) / tr.maxEntries
  71. for i := 0; i < tr.maxEntries; i++ {
  72. var part []*treeNode
  73. if i == tr.maxEntries-1 {
  74. // last part
  75. part = fitems[partsz*i:]
  76. } else {
  77. part = fitems[partsz*i : partsz*(i+1)]
  78. }
  79. children = append(children, tr.omt(part, h-1, axis+1))
  80. }
  81. node := tr.createNode(children)
  82. node.height = h
  83. node.leaf = false
  84. tr.calcBBox(node)
  85. return node
  86. }