/// <summary> /// Increases the height when a split has propagated to the root node (in other words, the root node had to be split). /// </summary> /// <param name="rightRoot">The newly created sibling for the root node.</param> private void IncreaseHeight(HilbertNode rightRoot) { if (rightRoot == null) { return; } HilbertNode newRoot = new HilbertNode(this.MaxChildren); newRoot.AddChild(this.Root); newRoot.AddChild(rightRoot); this.Root = newRoot; this.Height++; }
/// <summary> /// Adjusts the tree ascending from the leaf level up to the root. /// </summary> /// <param name="node">The node where the overflow happened.</param> /// <param name="newNode">The new node, if a split was inevitable in <see cref="HandleOverflow(HilbertNode, HilbertNode)"/>, otherwise it's <c>null</c>.</param> /// <returns>The new <see cref="HilbertNode"/> on the root level, if the root node had to be split.</returns> private HilbertNode AdjustTree(HilbertNode node, HilbertNode newNode = null) { while (node != this.Root) { // propagate node split upward HilbertNode nParent = (HilbertNode)node.Parent; HilbertNode pParent = null; if (newNode != null) { if (this.IsFull(nParent)) { pParent = this.HandleOverflow(nParent, newNode); } else { nParent.AddChild(newNode); } } // update MBR and LHV in parent level nParent.CorrectBounding(); nParent.Children?.Sort(this.comparer); nParent.LargestHilbertValue = nParent.ChildrenCount == 0 ? new BigInteger(-1) : ((HilbertNode)nParent.Children[nParent.ChildrenCount - 1]).LargestHilbertValue; node = nParent; newNode = pParent; } return(newNode); }
/// <summary> /// Adds a geometry by creating a new leaf node. /// </summary> /// <param name="geometry">The geometry to be added.</param> protected override void AddGeometry(IBasicGeometry geometry) { HilbertNode leaf = new HilbertNode(geometry, this.GetHilbertValue(geometry)); HilbertNode leafContainer = this.ChooseLeafContainer(leaf); if (leafContainer == this.Root && leafContainer.ChildrenCount == 0) { this.Height = 1; } HilbertNode newNode = null; if (!this.IsFull(leafContainer)) { leafContainer.AddChild(leaf); } else { newNode = this.HandleOverflow(leafContainer, leaf); } HilbertNode rightRoot = this.AdjustTree(leafContainer, newNode); this.IncreaseHeight(rightRoot); }