internal void condenseTree(RTree rTree)
{
// CT1 [Initialize] Set n=l. Set the list of eliminated nodes to be empty.
NodeBase n = this;
NodeInternal parent = null;
int parentEntry = 0;
Stack<NodeBase> eliminatedNodes = new Stack<NodeBase>();
// CT2 [Find parent entry] If N is the root, go to CT6. Otherwise
// let P be the parent of N, and let En be N's entry in P
while (n.level != rTree.treeHeight)
{
parent = rTree.parents.Pop() as NodeInternal;
parentEntry = rTree.parentsEntry.Pop();
// CT3 [Eliminiate under-full node] If N has too few entries,
// delete En from P and add N to the list of eliminated nodes
if (n.entryCount < rTree.minNodeEntries)
{
parent.deleteEntry(parentEntry);
eliminatedNodes.Push(n);
}
else
{
// CT4 [Adjust covering rectangle] If N has not been eliminated,
// adjust EnI to tightly contain all entries in N
if (n.minimumBoundingRectangle.MinX != parent.entries[parentEntry].Value.MinX || n.minimumBoundingRectangle.MinY != parent.entries[parentEntry].Value.MinY ||
n.minimumBoundingRectangle.MaxX != parent.entries[parentEntry].Value.MaxX || n.minimumBoundingRectangle.MaxY != parent.entries[parentEntry].Value.MaxY)
{
Rectangle d = parent.entries[parentEntry].Value;
parent.entries[parentEntry] = n.minimumBoundingRectangle;
parent.recalculateMBRIfInfluencedBy(ref d);
}
}
// CT5 [Move up one level in tree] Set N=P and repeat from CT2
n = parent;
}
// CT6 [Reinsert orphaned entries] Reinsert all entries of nodes in set Q. Entries from eliminated leaf nodes are reinserted in tree leaves as in
// Insert(), but entries from higher level nodes must be placed higher in the tree, so that leaves of their dependent subtrees will be on the same
// level as leaves of the main tree
while (eliminatedNodes.Count > 0)
{
NodeBase e = eliminatedNodes.Pop();
for (int j = 0; j < e.entryCount; j++)
{
if (e.level == 1)
rTree.AddInternal(e.entries[j].Value);
else
{
NodeInternal nInternal = e as NodeInternal;
rTree.AddInternal(e.entries[j].Value, e.level, nInternal.childNodes[j]);
}
}
}
}