예제 #1
0
        private static ISpatialIndexNode <IExtents, TItem> findParentNode(ISpatialIndexNode <IExtents, TItem> lookFor,
                                                                          ISpatialIndexNode <IExtents, TItem> searchNode)
        {
            foreach (ISpatialIndexNode <IExtents, TItem> node in searchNode.SubNodes)
            {
                if (node.Equals(lookFor))
                {
                    return(searchNode);
                }
            }

            IExtents itemBounds = lookFor.Bounds;

            // TODO: I think a breadth-first search would be more efficient here
            foreach (ISpatialIndexNode <IExtents, TItem> child in searchNode.SubNodes)
            {
                if (child.Intersects(itemBounds))
                {
                    ISpatialIndexNode <IExtents, TItem> found = findParentNode(lookFor, child);

                    if (found != null)
                    {
                        return(found);
                    }
                }
            }

            return(null);
        }
        public void Insert(IExtents bounds, TItem entry, ISpatialIndexNode <IExtents, TItem> node, INodeSplitStrategy <IExtents, TItem> nodeSplitStrategy, IndexBalanceHeuristic heuristic, out ISpatialIndexNode <IExtents, TItem> newSiblingFromSplit)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            if (!(node is QuadTreeNode <TItem>))
            {
                throw new ArgumentException("Parameter 'node' must be of type QuadTreeNode<TItem>", "node");
            }

            QuadTreeNode <TItem> quadTreeNode = node as QuadTreeNode <TItem>;

            insertEntryRecursive(quadTreeNode, entry, nodeSplitStrategy, heuristic, out newSiblingFromSplit);

            if (newSiblingFromSplit != null)
            {
                if (quadTreeNode.ItemCount == 4)
                {
                    throw new QuadTreeIndexInsertOverflowException();
                }

                quadTreeNode.Add(newSiblingFromSplit);
            }
        }
예제 #3
0
        private static ISpatialIndexNode <IExtents, TItem> findLeastExpandedChild(
            IEnumerable <ISpatialIndexNode <IExtents, TItem> > children,
            ComputationExtents currentBounds,
            Double leastExpandedArea,
            Double leastExpandedChildArea)
        {
            ISpatialIndexNode <IExtents, TItem> leastExpandedChild = null;

            foreach (ISpatialIndexNode <IExtents, TItem> child in children)
            {
                ComputationExtents childBounds = child.Bounds != null
                                                        ? new ComputationExtents(child.Bounds)
                                                        : new ComputationExtents();
                ComputationExtents candidateRegion = childBounds.Union(currentBounds);

                Double candidateRegionArea = candidateRegion.Area;
                Double childArea           = childBounds.Area;
                Double expandedArea        = candidateRegionArea - childArea;

                if (expandedArea < leastExpandedArea)
                {
                    leastExpandedChild     = child;
                    leastExpandedChildArea = childArea;
                    leastExpandedArea      = expandedArea;
                }
                else if (expandedArea == leastExpandedArea &&
                         childArea < leastExpandedChildArea)
                {
                    leastExpandedChild     = child;
                    leastExpandedChildArea = childArea;
                }
            }

            return(leastExpandedChild);
        }
예제 #4
0
            private static ISpatialIndexNode <TBounds, TItem> findLeastExpandedChild(
                IEnumerable <ISpatialIndexNode <TBounds, TItem> > children,
                TBounds currentBounds,
                Double leastExpandedArea,
                Double leastExpandedChildArea)
            {
                ISpatialIndexNode <TBounds, TItem> leastExpandedChild = null;

                foreach (ISpatialIndexNode <TBounds, TItem> child in children)
                {
                    TBounds childBounds = child.Bounds;

                    TBounds candidateRegion = (TBounds)childBounds.Union(currentBounds);

                    Double candidateRegionArea = Area(candidateRegion);
                    Double childArea           = Area(childBounds);
                    Double expandedArea        = candidateRegionArea - childArea;

                    if (expandedArea < leastExpandedArea)
                    {
                        leastExpandedChild     = child;
                        leastExpandedChildArea = childArea;
                        leastExpandedArea      = expandedArea;
                    }
                    else if (expandedArea == leastExpandedArea &&
                             childArea < leastExpandedChildArea)
                    {
                        leastExpandedChild     = child;
                        leastExpandedChildArea = childArea;
                    }
                }

                return(leastExpandedChild);
            }
예제 #5
0
        protected override void addSubNode(ISpatialIndexNode <IExtents, TItem> child)
        {
            if (child == null)
            {
                throw new ArgumentNullException("child");
            }

            RTreeNode <TItem> node = child as RTreeNode <TItem>;

            if (node == null)
            {
                throw new ArgumentException("Parameter must be of type RTreeNode<TItem>.");
            }

            ensureChildren();

            _children.Add(node);

            if (Bounds == null)
            {
                Bounds = node.Bounds.Clone() as IExtents;
            }
            else
            {
                Bounds.ExpandToInclude(child.Bounds);
            }
        }
예제 #6
0
        private static ISpatialIndexNode <IExtents, TItem> findNodeForItem(TItem item,
                                                                           ISpatialIndexNode <IExtents, TItem> node)
        {
            foreach (TItem nodeItem in node.Items)
            {
                if (item.Equals(nodeItem))
                {
                    return(node);
                }
            }

            IExtents itemBounds = item.Bounds;

            // TODO: I think a breadth-first search would be more efficient here
            foreach (ISpatialIndexNode <IExtents, TItem> child in node.SubNodes)
            {
                if (child.Intersects(itemBounds))
                {
                    ISpatialIndexNode <IExtents, TItem> found = findNodeForItem(item, child);

                    if (found != null)
                    {
                        return(found);
                    }
                }
            }

            return(null);
        }
        public ISpatialIndexNode <IExtents, TItem> SplitNode(ISpatialIndexNode <IExtents, TItem> node, IndexBalanceHeuristic heuristic)
        {
            if (node == null)
            {
                return(null);
            }

            QuadTreeNode <TItem>            quadTreeNode      = node as QuadTreeNode <TItem>;
            DynamicQuadTreeBalanceHeuristic quadTreeHeuristic = heuristic as DynamicQuadTreeBalanceHeuristic;

            throw new NotImplementedException();
        }
예제 #8
0
            public ISpatialIndexNode <TBounds, TItem> SplitNode(ISpatialIndexNode <TBounds, TItem> node, IndexBalanceHeuristic heuristic)
            {
                if (node == null)
                {
                    throw new ArgumentNullException("node");
                }



                DynamicRTreeBalanceHeuristic rTreeHueristic
                    = heuristic as DynamicRTreeBalanceHeuristic;

                return(doSplit(node, rTreeHueristic));
            }
예제 #9
0
        /// <summary>
        /// Removes an item from the index.
        /// </summary>
        /// <param name="item">The item to remove.</param>
        public override Boolean Remove(TItem item)
        {
            ISpatialIndexNode <IExtents, TItem> itemNode = findNodeForItem(item, Root);

            bool removed = itemNode != null && itemNode.Remove(item);

            if (itemNode.IsPrunable)
            {
                ISpatialIndexNode <IExtents, TItem> parent = findParentNode(itemNode, Root);
                parent.Remove(itemNode);
            }

            return(removed);
        }
예제 #10
0
        public ISpatialIndexNode <IExtents, TItem> SplitNode(
            ISpatialIndexNode <IExtents, TItem> node, IndexBalanceHeuristic heuristic)
        {
            if (node == null)
            {
                throw new ArgumentNullException("node");
            }

            RTreeNode <TItem> rTreeNode = node as RTreeNode <TItem>;

            Debug.Assert(rTreeNode != null);

            DynamicRTreeBalanceHeuristic rTreeHueristic
                = heuristic as DynamicRTreeBalanceHeuristic;

            return(doSplit(rTreeNode, rTreeHueristic));
        }
예제 #11
0
        protected override Boolean removeSubNode(ISpatialIndexNode <IExtents, TItem> child)
        {
            if (child == null)
            {
                throw new ArgumentNullException("child");
            }

            RTreeNode <TItem> node = child as RTreeNode <TItem>;

            if (node == null)
            {
                throw new ArgumentException("Parameter must be of type RTreeNode<TItem>.");
            }

            ensureChildren();

            return(_children.Remove(node));
        }
예제 #12
0
        /// <summary>
        /// Inserts a node into the tree using <see cref="ItemInsertStrategy"/>.
        /// </summary>
        /// <param name="item">The item to insert into the index.</param>
        public override void Insert(TItem item)
        {
            ISpatialIndexNode <IExtents, TItem> newSiblingFromSplit;

            //printItemCount();

            ItemInsertStrategy.Insert(item.Bounds, item, Root,
                                      _nodeSplitStrategy, Heuristic,
                                      out newSiblingFromSplit);

            if (newSiblingFromSplit == null)
            {
                return;
            }

            //Debug.Print("Node was split.");

            // Add the newly split sibling
            if (newSiblingFromSplit.IsLeaf)
            {
                if (Root.IsLeaf)    // handle the first splitting of the root node.
                {
                    RTreeNode <TItem> oldRoot = Root as RTreeNode <TItem>;
                    Root = CreateNode(0);
                    Root.Add(oldRoot);
                }

                Root.Add(newSiblingFromSplit);
            }
            else // Came from a root split
            {
                ISpatialIndexNode <IExtents, TItem> oldRoot = Root;
                Root = CreateNode(0);
                Root.Add(oldRoot);
                Root.Add(newSiblingFromSplit);
            }
        }
예제 #13
0
 protected override bool removeSubNode(ISpatialIndexNode <IExtents, TItem> child)
 {
     throw new NotImplementedException();
 }
 private void insertEntryRecursive(QuadTreeNode <TItem> quadTreeNode, TItem entry, INodeSplitStrategy <IExtents, TItem> nodeSplitStrategy, IndexBalanceHeuristic heuristic, out ISpatialIndexNode <IExtents, TItem> newSiblingFromSplit)
 {
     throw new NotImplementedException();
 }
예제 #15
0
            public void Insert(TBounds bounds, TItem entry, ISpatialIndexNode <TBounds, TItem> node, INodeSplitStrategy <TBounds, TItem> nodeSplitStrategy, IndexBalanceHeuristic heuristic, out ISpatialIndexNode <TBounds, TItem> newSiblingFromSplit)
            {
                newSiblingFromSplit = null;

                //TODO: handle null node..

                // Terminating case
                if (node.IsLeaf)
                {
                    node.Add(entry);

                    // Handle node overflow
                    if (node.ItemCount > heuristic.NodeItemMaximumCount)
                    {
                        // Split the node using the given strategy
                        newSiblingFromSplit = nodeSplitStrategy.SplitNode(node, heuristic);

                        //if (++_tempSplitCount % 100 == 0)
                        //{
                        //    Debug.Print("Node split # {0}", _tempSplitCount);
                        //}
                    }
                }
                else
                {
                    // NOTE: Descending the tree recursively here
                    // can make for a very expensive build of a tree,
                    // even for moderate amounts of data.

                    Double leastExpandedArea      = Double.MaxValue;
                    Double leastExpandedChildArea = Double.MaxValue;

                    //TBounds currentBounds = new ComputationExtents(bounds);

                    ISpatialIndexNode <TBounds, TItem> leastExpandedChild;
                    leastExpandedChild = findLeastExpandedChild(node.SubNodes,
                                                                bounds,
                                                                leastExpandedArea,
                                                                leastExpandedChildArea);

                    Debug.Assert(leastExpandedChild != null);

                    // Found least expanded child node - insert into it
                    Insert(bounds, entry, leastExpandedChild, nodeSplitStrategy,
                           heuristic, out newSiblingFromSplit);


                    // Adjust this node...
                    node.Bounds.ExpandToInclude(bounds);

                    // Check for overflow and add to current node if it occured
                    if (newSiblingFromSplit != null)
                    {
                        // Add new sibling node to the current node
                        node.Add(newSiblingFromSplit);
                        newSiblingFromSplit = null;

                        // Split the current node, since the child count is too high,
                        // and return the split to the caller
                        if (node.ItemCount > heuristic.NodeItemMaximumCount)
                        {
                            newSiblingFromSplit = nodeSplitStrategy.SplitNode(node, heuristic);
                        }
                    }
                }
            }
예제 #16
0
            private ISpatialIndexNode <TBounds, TItem> doSplit(ISpatialIndexNode <TBounds, TItem> node, DynamicRTreeBalanceHeuristic heuristic)
            {
                Boolean isLeaf = node.IsLeaf;

                IEnumerable <IBoundable <TBounds> > boundables =
                    isLeaf
                   ? Caster.Upcast <IBoundable <TBounds>, TItem>(node.Items)
                   : Caster.Upcast <IBoundable <TBounds>, ISpatialIndexNode <TBounds, TItem> >(node.SubNodes);

                Int32 boundablesCount = isLeaf ? node.ItemCount : node.SubNodeCount;

                List <IBoundable <TBounds> > entries = new List <IBoundable <TBounds> >(boundablesCount);

                entries.AddRange(boundables);

                IList <IBoundable <TBounds> > group1 = new List <IBoundable <TBounds> >();
                IList <IBoundable <TBounds> > group2 = new List <IBoundable <TBounds> >();

                pickSeeds(entries, group1, group2);

                Int32 group1Count = 1, group2Count = 1;

                distribute(entries, group1, group2, heuristic, ref group1Count, ref group2Count);

                if (entries.Count > 0)
                {
                    if (group1Count < heuristic.NodeItemMinimumCount)
                    {
                        fillShortGroup(entries, group1, ref group1Count);
                    }
                    else // group2Count < heuristic.NodeItemMinimumCount
                    {
                        fillShortGroup(entries, group2, ref group2Count);
                    }
                }

                node.Clear();


                ISpatialIndexNode <TBounds, TItem> sibling = NodeFactory.CreateNode(node.Level);

                IEnumerable <IBoundable <TBounds> > g1Sized = Enumerable.Take(group1, group1Count);
                IEnumerable <IBoundable <TBounds> > g2Sized = Enumerable.Take(group2, group2Count);

                if (isLeaf)
                {
                    //IEnumerable<TItem> g1Cast = Caster.Downcast<TItem, IBoundable<TBounds>>(g1Sized);
                    node.AddRange(g1Sized);


                    //IEnumerable<TItem> g2Cast = Caster.Downcast<TItem, IBoundable<IExtents>>(g2Sized);
                    sibling.AddRange(g2Sized);
                }
                else
                {
                    //IEnumerable<ISpatialIndexNode<IExtents, TItem>> g1Cast
                    //    = Caster.Downcast<ISpatialIndexNode<IExtents, TItem>, IBoundable<IExtents>>(g1Sized);
                    node.AddRange(g1Sized);

                    //IEnumerable<ISpatialIndexNode<IExtents, TItem>> g2Cast
                    //    = Caster.Downcast<ISpatialIndexNode<IExtents, TItem>, IBoundable<IExtents>>(g2Sized);
                    sibling.AddRange(g2Sized);
                }

                return(sibling);
            }
예제 #17
0
 protected abstract Boolean removeSubNode(ISpatialIndexNode <IExtents, TItem> child);
예제 #18
0
 protected abstract void addSubNode(ISpatialIndexNode <IExtents, TItem> child);
 public void RestructureNode(ISpatialIndexNode node)
 {
 }
예제 #20
0
 public void RestructureNode(ISpatialIndexNode <TBounds, TItem> node)
 {
 }