예제 #1
0
        /// <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++;
        }
예제 #2
0
        /// <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);
        }
예제 #3
0
        /// <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);
        }