/// <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; }
/// <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; }
/// <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); } }