Example #1
0
        /// <summary>
        /// Searches for all data points below the input root for points that
        /// fall within the searchbox
        /// </summary>
        /// <param name="SearchBox">Area to search</param>
        /// <param name="aRoot">Node to start looking</param>
        /// <returns>List of all leafRecords that reside within the searchbox</returns>
        private List <LeafRecord <T> > search(RTreeRectangle SearchBox, NodeRecord <T> aRoot)
        {
            var matches = new List <LeafRecord <T> >();

            if (!SearchBox.Overlaps(aRoot.BBox))
            {
                // If there is no overlap, return nothing.
                return(matches);
            }
            else if (!aRoot.Node.IsLeaf())
            {
                // If the node is not a leaf, recursively call this function
                // for each of its children.
                foreach (var childNode in aRoot.Node.GetRecords())
                {
                    NodeRecord <T> node = (NodeRecord <T>)childNode;
                    matches = matches.Concat(search(SearchBox, node)).ToList();
                }
                return(matches);
            }
            else
            {
                // If this node is a leaf, add each data point that resides in the
                // search box to the match list.
                foreach (var childNode in aRoot.Node.GetRecords())
                {
                    LeafRecord <T> node = (LeafRecord <T>)childNode;
                    if (SearchBox.Overlaps(node.BBox))
                    {
                        matches.Add(node);
                    }
                }
                return(matches);
            }
        }
Example #2
0
        /// <summary>
        /// Finds the leaf node that contains the leaf record if able.
        /// </summary>
        /// <param name="item">Item to find</param>
        /// <param name="rRoot">Tree to search</param>
        /// <param name="rLeafPath">Path to node from root</param>
        /// <returns>true if leaf is found</returns>
        private bool findLeaf(LeafRecord <T> item, ref NodeRecord <T> rRoot, List <NodeRecord <T> > rLeafPath)
        {
            NodeRecord <T> node = rRoot;

            if (!node.Node.IsLeaf())
            {
                foreach (var childNode in node.Node.GetRecords())
                {
                    if (childNode.BBox.Overlaps(item.BBox))
                    {
                        node = (NodeRecord <T>)childNode;
                        if (findLeaf(item, ref node, rLeafPath))
                        {
                            rLeafPath.Insert(0, node);
                            rRoot = node;
                            return(true);
                        }
                    }
                }
            }
            else
            {
                foreach (var childNode in node.Node.GetRecords())
                {
                    LeafRecord <T> leaf = (LeafRecord <T>)childNode;
                    if (leaf.IsEqual(item))
                    {
                        return(true);
                    }
                }
            }

            return(false);
        }
Example #3
0
        private void RDeletionTest()
        {
            Console.WriteLine("/////Deletion/////");
            RTreeRectangle searchArea = new RTreeRectangle();

            searchArea.X1 = -5;
            searchArea.Y1 = -1;
            searchArea.X2 = 0;
            searchArea.Y2 = 3;

            RTree <int> testTree = new RTree <int>();

            // Outside
            testTree.Insert(99, 1, 0);
            testTree.Insert(100, 1, 6);

            var newleaf = new LeafRecord <int> {
                Data = 1, BBox = new RTreeRectangle()
            };

            // Inside
            testTree.Insert(newleaf);
            testTree.Insert(2, -5, -1);
            testTree.Insert(3, 0, 3);
            testTree.Insert(4, -1, 2);
            testTree.Delete(newleaf);
            foreach (var leaf in testTree.Search(searchArea))
            {
                Console.WriteLine(leaf.Data);
            }

            Console.WriteLine("/////Deletion Done/////");
        }
Example #4
0
        /// <summary>
        /// Returns the node that the item should be added to. Additionally,
        /// it tracks each node it traversed to find the proper location. That list
        /// is called the leafPath and is used for split, and resize propagation.
        /// </summary>
        /// <param name="item">Item to insert</param>
        /// <param name="rLeafPath">Path from root to node where the item should be added.</param>
        /// <returns></returns>
        private NodeRecord <T> chooseLeaf(LeafRecord <T> item, List <NodeRecord <T> > rLeafPath)
        {
            // See Paper for naming
            // CL1.
            NodeRecord <T> N = root;

            rLeafPath.Add(N);

            while (true)
            {
                // CL2.
                if (N.Node.IsLeaf())
                {
                    return(N);
                }

                int minEnlargementArea = int.MaxValue;
                int minArea            = int.MaxValue;

                // CL3.
                // Find the node that would require the least enlargement area to
                // add the new item. If there is a tie, use the node with the
                // smallest area.
                int enlargementArea;
                int nodeArea;
                foreach (var childNode in N.Node.GetRecords())
                {
                    NodeRecord <T> nodeRecord = (NodeRecord <T>)childNode;
                    NodeRecord <T> F          = nodeRecord; // See Paper for naming.
                    enlargementArea = EnclosingArea(nodeRecord.BBox, item.BBox) - item.BBox.GetArea();
                    nodeArea        = nodeRecord.BBox.GetArea();

                    if (enlargementArea < minEnlargementArea)
                    {
                        minEnlargementArea = enlargementArea;
                        minArea            = nodeArea;
                        // CL4.
                        N = F;
                    }
                    // Resolve ties using the node with the smallest size.
                    else if (enlargementArea == minEnlargementArea)
                    {
                        if (nodeArea < minArea)
                        {
                            minArea = nodeArea;
                            // CL4.
                            N = F;
                        }
                    }
                }

                // N is now the child needing the least enlargement.
                rLeafPath.Add(N);
            }
        }
Example #5
0
        /// <summary>
        /// Inserts Data into the tree structure at point (X,Y)
        /// </summary>
        /// <param name="Data">Data to insert</param>
        /// <param name="X">X Coord of data</param>
        /// <param name="Y">Y Coord of data</param>
        public void Insert(T Data, int X, int Y)
        {
            LeafRecord <T> insert = new LeafRecord <T>();

            insert.Data    = Data;
            insert.BBox.X1 = X;
            insert.BBox.Y1 = Y;
            insert.BBox.X2 = X;
            insert.BBox.Y2 = Y;

            Insert(insert);
        }
Example #6
0
        /// <summary>
        /// Remove the input item from the list.
        /// </summary>
        /// <param name="item">Item to remove</param>
        public void Delete(LeafRecord <T> item)
        {
            NodeRecord <T>         node     = root;
            List <NodeRecord <T> > nodePath = new List <NodeRecord <T> >();

            if (findLeaf(item, ref node, nodePath))
            {
                nodePath.Insert(0, root);
                node.Node.GetRecords().Remove(item);
                condenseTree(node, nodePath);
            }
        }
Example #7
0
        /// <summary>
        /// Performs the insertion algorithm.
        /// </summary>
        /// <param name="item">Item to insert</param>
        public void Insert(LeafRecord <T> item)
        {
            List <NodeRecord <T> > leafPath = new List <NodeRecord <T> >();

            // I1.
            // Track the nodes traversed to get to the point that we
            // want to add the node. This list of nodes will be used
            // to propagate changes up the tree.
            NodeRecord <T> insertNode = chooseLeaf(item, leafPath);
            NodeRecord <T> splitNode  = null;

            // I2.
            // Attempts to insert the item in the given node.
            // If it fails, we split the node. Store the new
            // node in splitNode, so it can be propagated up
            // later.
            if (!insertNode.TryInsert(item))
            {
                // Split.
                splitNode = insertNode.Split(item);
            }

            // I3.
            // Propagate resizing up the tree. Propagate split node
            // if necessary.
            if (adjustTree(leafPath, insertNode, ref splitNode))
            {
                // I4.
                // Create a new root if the root was split. This new root is not a leaf.
                NodeRecord <T> newRoot = new NodeRecord <T>()
                {
                    Node = new RTreeNode <T>(Leaf: false)
                };
                newRoot.TryInsert(root);
                newRoot.TryInsert(splitNode);
                root = newRoot;
            }
        }
Example #8
0
 public bool IsEqual(LeafRecord <T> obj)
 {
     return(obj.BBox.IsEqual(BBox) && Data.Equals(obj.Data));
 }