12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697 |
- package base
- import "math"
- // Load bulk load items into the R-tree.
- func (tr *RTree) Load(mins, maxs [][]float64, items []interface{}) {
- if len(items) < tr.minEntries {
- for i := 0; i < len(items); i++ {
- tr.Insert(mins[i], maxs[i], items[i])
- }
- return
- }
- // prefill the items
- fitems := make([]*treeNode, len(items))
- for i := 0; i < len(items); i++ {
- item := &treeItem{min: mins[i], max: maxs[i], item: items[i]}
- fitems[i] = item.unsafeNode()
- }
- // following equations are defined in the paper describing OMT
- N := len(fitems)
- M := tr.maxEntries
- h := int(math.Ceil(math.Log(float64(N)) / math.Log(float64(M))))
- Nsubtree := int(math.Pow(float64(M), float64(h-1)))
- S := int(math.Ceil(math.Sqrt(float64(N) / float64(Nsubtree))))
- // sort by the initial axis
- axis := 0
- sortByAxis(fitems, axis)
- // build the root node. it's split differently from the subtrees.
- children := make([]*treeNode, 0, S)
- for i := 0; i < S; i++ {
- var part []*treeNode
- if i == S-1 {
- // last split
- part = fitems[len(fitems)/S*i:]
- } else {
- part = fitems[len(fitems)/S*i : len(fitems)/S*(i+1)]
- }
- children = append(children, tr.omt(part, h-1, axis+1))
- }
- node := tr.createNode(children)
- node.leaf = false
- node.height = h
- tr.calcBBox(node)
- if tr.data.count == 0 {
- // save as is if tree is empty
- tr.data = node
- } else if tr.data.height == node.height {
- // split root if trees have the same height
- tr.splitRoot(tr.data, node)
- } else {
- if tr.data.height < node.height {
- // swap trees if inserted one is bigger
- tr.data, node = node, tr.data
- }
- // insert the small tree into the large tree at appropriate level
- tr.insert(node, nil, tr.data.height-node.height-1, true)
- }
- }
- func (tr *RTree) omt(fitems []*treeNode, h, axis int) *treeNode {
- if len(fitems) <= tr.maxEntries {
- // reached leaf level; return leaf
- children := make([]*treeNode, len(fitems))
- copy(children, fitems)
- node := tr.createNode(children)
- node.height = h
- tr.calcBBox(node)
- return node
- }
- // sort the items on a different axis than the previous level.
- sortByAxis(fitems, axis%tr.dims)
- children := make([]*treeNode, 0, tr.maxEntries)
- partsz := len(fitems) / tr.maxEntries
- for i := 0; i < tr.maxEntries; i++ {
- var part []*treeNode
- if i == tr.maxEntries-1 {
- // last part
- part = fitems[partsz*i:]
- } else {
- part = fitems[partsz*i : partsz*(i+1)]
- }
- children = append(children, tr.omt(part, h-1, axis+1))
- }
- node := tr.createNode(children)
- node.height = h
- node.leaf = false
- tr.calcBBox(node)
- return node
- }
|