Esempio n. 1
0
        /// <summary>
        /// Removes the specified geometry from the tree.
        /// </summary>
        /// <param name="geometry">The geometry.</param>
        /// <returns><c>true</c>, if the tree contains the geometry, otherwise, <c>false</c>.</returns>
        protected virtual Boolean RemoveGeometry(IGeometry geometry)
        {
            RTreeNode leafContainer = null;

            FindLeafContainer(geometry, _root, ref leafContainer);

            if (leafContainer == null)
            {
                return(false);
            }

            RTreeNode nodeToRemove = leafContainer.Children.First(x => x.Geometry == geometry);

            leafContainer.RemoveChild(nodeToRemove);

            CondenseTree(leafContainer);

            while (_root.ChildrenCount == 1 && !_root.IsLeafContainer)
            {
                _root        = _root.Children[0];
                _root.Parent = null;
                _height--;
            }

            if (_root.ChildrenCount == 0) // occurs when the last element is removed
            {
                Clear();
            }

            return(true);
        }
Esempio n. 2
0
        /// <summary>
        /// Adjusts the tree after insertion, and corrects the bounding envelope of the nodes.
        /// </summary>
        /// <param name="node">The node where the adjustment starts.</param>
        /// <param name="splitted">The second part of the node if the original node was split.</param>
        /// <param name="nodeToRemove">The original node which should be removed if the original node was split.</param>
        protected void AdjustTree(RTreeNode node, RTreeNode splitted = null, RTreeNode nodeToRemove = null)
        {
            RTreeNode n  = node;
            RTreeNode nn = splitted;

            while (n.Parent != null)
            {
                RTreeNode parent = n.Parent;

                parent.CorrectBounding(n.Envelope);

                if (nn == null)
                {
                    n = parent;
                }
                else
                {
                    if (nodeToRemove != null)
                    {
                        parent.RemoveChild(nodeToRemove);
                        parent.AddChild(n);
                    }

                    if (!parent.IsFull)
                    {
                        parent.AddChild(nn);
                        n  = parent;
                        nn = null;
                    }
                    else
                    {
                        parent.AddChild(nn);
                        SplitNode(parent, out n, out nn);

                        nodeToRemove = parent;
                    }
                }
            }

            // create new root node if the root is split
            if (nn != null)
            {
                _root = new RTreeNode(n.MaxChildren);
                _root.AddChild(n);
                _root.AddChild(nn);

                _height++;
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Condenses the tree after removing a leaf node.
        /// </summary>
        /// <param name="leafContainerNode">The node which contained the removed node.</param>
        private void CondenseTree(RTreeNode leafContainerNode)
        {
            Dictionary <RTreeNode, Int32> deletedNodes = new Dictionary <RTreeNode, Int32>();
            RTreeNode p = leafContainerNode;

            Int32 height = Height - 1;

            while (p.Parent != null)
            {
                RTreeNode parent = p.Parent;
                if (p.ChildrenCount < MinChildren)
                {
                    parent.RemoveChild(p);

                    if (p.Children != null)
                    {
                        foreach (RTreeNode node in p.Children)
                        {
                            deletedNodes.Add(node, height);
                        }
                    }
                }
                else
                {
                    p.CorrectBounding();
                }

                p = parent;
                height--;
            }

            Int32 startHeight = Height;

            foreach (KeyValuePair <RTreeNode, Int32> reInsert in deletedNodes)
            {
                AddNode(reInsert.Key, reInsert.Value + (Height - startHeight));
            }
        }