Esempio n. 1
0
 /// <summary>
 /// Creates a new updatable QuadTree instance
 /// </summary>
 /// <param name="insertStrategy">Strategy used to insert new entries into the index.</param>
 /// <param name="nodeSplitStrategy">Strategy used to split nodes when they are full.</param>
 /// <param name="heuristic">Heuristics used to build the index and keep it balanced.</param>
 public DynamicQuadTree(IGeometryFactory geoFactory, IItemInsertStrategy <IExtents, TItem> insertStrategy, INodeSplitStrategy <IExtents, TItem> nodeSplitStrategy, DynamicQuadTreeBalanceHeuristic heuristic)
     : base(geoFactory)
 {
     _insertStrategy    = insertStrategy;
     _nodeSplitStrategy = nodeSplitStrategy;
     _heuristic         = heuristic;
 }
Esempio n. 2
0
 /// <summary>
 /// Creates a new updatable R-Tree instance
 /// </summary>
 /// <param name="insertStrategy">Strategy used to insert new entries into the index.</param>
 /// <param name="nodeSplitStrategy">Strategy used to split nodes when they are full.</param>
 /// <param name="heuristic">Heuristics used to build the index and keep it balanced.</param>
 public DynamicRTree(IEntryInsertStrategy insertStrategy, INodeSplitStrategy nodeSplitStrategy, DynamicRTreeHeuristic heuristic)
     : base()
 {
     _insertStrategy    = insertStrategy;
     _nodeSplitStrategy = nodeSplitStrategy;
     _heuristic         = heuristic;
 }
Esempio n. 3
0
        /// <summary>
        /// Creates a new updatable R-Tree instance.
        /// </summary>
        /// <param name="geoFactory">
        /// An <see cref="IGeometryFactory"/> for creating extent instances.
        /// </param>
        /// <param name="insertStrategy">
        /// Strategy used to insert new entries into the index.
        /// </param>
        /// <param name="nodeSplitStrategy">
        /// Strategy used to split nodes when they are full.
        /// </param>
        /// <param name="heuristic">
        /// Heuristics used to build the index and keep it balanced.
        /// </param>
        public DynamicRTree(
            IGeometryFactory geoFactory,
            IItemInsertStrategy <IExtents, TItem> insertStrategy,
            INodeSplitStrategy <IExtents, TItem> nodeSplitStrategy,
            DynamicRTreeBalanceHeuristic heuristic)
            : base(geoFactory)
        {
            if (insertStrategy == null)
            {
                throw new ArgumentNullException("insertStrategy");
            }

            if (nodeSplitStrategy == null)
            {
                throw new ArgumentNullException("nodeSplitStrategy");
            }

            if (heuristic == null)
            {
                throw new ArgumentNullException("heuristic");
            }

            _insertStrategy    = insertStrategy;
            _nodeSplitStrategy = nodeSplitStrategy;
            _heuristic         = heuristic;
        }
        /// <summary>
        /// Creates a new SelfOptimizingDynamicSpatialIndex.
        /// </summary>
        /// <param name="geoFactory">An <see cref="IGeometryFactory"/> instance.</param>
        /// <param name="restructureStrategy">The strategy used to restructure the index.</param>
        /// <param name="restructureHeuristic">The heuristic to control when the index is restructured.</param>
        /// <param name="insertStrategy">The strategy used to insert entries into the index.</param>
        /// <param name="nodeSplitStrategy">The strategy used to split index nodes.</param>
        /// <param name="indexHeuristic">A heuristic used to balance the index for optimum efficiency.</param>
        /// <param name="idleMonitor">A monitor to determine idle conditions on the executing machine.</param>
        public SelfOptimizingDynamicSpatialIndex(IGeometryFactory geoFactory,
                                                 IIndexRestructureStrategy <IExtents, TItem> restructureStrategy,
                                                 RestructuringHuristic restructureHeuristic,
                                                 IItemInsertStrategy <IExtents, TItem> insertStrategy,
                                                 INodeSplitStrategy <IExtents, TItem> nodeSplitStrategy,
                                                 DynamicRTreeBalanceHeuristic indexHeuristic,
                                                 IdleMonitor idleMonitor)
            : base(geoFactory, insertStrategy, nodeSplitStrategy, indexHeuristic)
        {
            _periodMilliseconds = restructureHeuristic.WhenToRestructure == RestructureOpportunity.Periodic
                                                                        ? (Int32)(restructureHeuristic.Period / 1000.0)
                                                                        : -1;

            _restructureStrategy    = restructureStrategy;
            _restructuringHeuristic = restructureHeuristic;
            _idleMonitor            = idleMonitor;

            _userIdleEvent    = new AutoResetEvent(false);
            _machineIdleEvent = new AutoResetEvent(false);
            _terminateEvent   = new ManualResetEvent(false);

            if (restructureHeuristic.WhenToRestructure != RestructureOpportunity.None)
            {
                _restructureThread = new Thread(doRestructure);
                _restructureThread.Start();
            }

            RestructureOpportunity idle = RestructureOpportunity.OnMachineIdle | RestructureOpportunity.OnUserIdle;

            if (((Int32)(restructureHeuristic.WhenToRestructure & idle)) > 0)
            {
                if (_idleMonitor == null)
                {
                    throw new ArgumentNullException("idleMonitor",
                                                    "If the restructuring heuristic has a value of anything but " +
                                                    "None for WhenToRestructure, the idleMonitor cannot be null.");
                }

                _idleMonitor.UserIdle    += _idleMonitor_UserIdle;
                _idleMonitor.UserBusy    += _idleMonitor_UserBusy;
                _idleMonitor.MachineIdle += _idleMonitor_MachineIdle;
                _idleMonitor.MachineBusy += _idleMonitor_MachineBusy;
            }
        }
            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);
                        }
                    }
                }
            }
 private void insertEntryRecursive(QuadTreeNode <TItem> quadTreeNode, TItem entry, INodeSplitStrategy <IExtents, TItem> nodeSplitStrategy, IndexBalanceHeuristic heuristic, out ISpatialIndexNode <IExtents, TItem> newSiblingFromSplit)
 {
     throw new NotImplementedException();
 }
        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);
            }
        }