private static PointRegionQuadTreeNode AddToNode( double x, double y, object value, PointRegionQuadTreeNode node, PointRegionQuadTree<object> tree, bool unique, string indexName) { if (node is PointRegionQuadTreeNodeLeaf<object>) { var leaf = (PointRegionQuadTreeNodeLeaf<object>) node; if (leaf.Count < tree.LeafCapacity || node.Level >= tree.MaxTreeHeight) { // can be multiple as value can be a collection var numAdded = AddToLeaf(leaf, x, y, value, unique, indexName); leaf.IncCount(numAdded); if (leaf.Count <= tree.LeafCapacity || node.Level >= tree.MaxTreeHeight) { return leaf; } } node = Subdivide(leaf, tree, unique, indexName); } var branch = (PointRegionQuadTreeNodeBranch) node; AddToBranch(branch, x, y, value, tree, unique, indexName); return node; }
private static void CollectRange( PointRegionQuadTreeNode node, double x, double y, double width, double height, EventBean eventBean, TT target, QuadTreeCollector<TT> collector, ExprEvaluatorContext ctx) { if (!node.Bb.IntersectsBoxIncludingEnd(x, y, width, height)) { return; } if (node is PointRegionQuadTreeNodeLeaf<object>) { var leaf = (PointRegionQuadTreeNodeLeaf<object>) node; CollectLeaf(leaf, x, y, width, height, eventBean, target, collector, ctx); return; } var branch = (PointRegionQuadTreeNodeBranch) node; CollectRange(branch.Nw, x, y, width, height, eventBean, target, collector, ctx); CollectRange(branch.Ne, x, y, width, height, eventBean, target, collector, ctx); CollectRange(branch.Sw, x, y, width, height, eventBean, target, collector, ctx); CollectRange(branch.Se, x, y, width, height, eventBean, target, collector, ctx); }
public PointRegionQuadTree( int leafCapacity, int maxTreeHeight, PointRegionQuadTreeNode root) { LeafCapacity = leafCapacity; MaxTreeHeight = maxTreeHeight; Root = root; }
private static int Count(PointRegionQuadTreeNode node) { if (node is PointRegionQuadTreeNodeLeaf<object> treeNodeLeaf) { return CountLeaf(treeNodeLeaf); } var branch = (PointRegionQuadTreeNodeBranch) node; return Count(branch.Nw) + Count(branch.Ne) + Count(branch.Sw) + Count(branch.Se); }
private static TL Get(double x, double y, PointRegionQuadTreeNode node) { if (node is PointRegionQuadTreeNodeLeaf <object> ) { var leaf = (PointRegionQuadTreeNodeLeaf <object>)node; if (leaf.Points == null) { return(default(TL)); } if (leaf.Points is XYPointWValue <TL> value) { if (value.X == x && value.Y == y) { return(value.Value); } return(default(TL)); } var collection = (ICollection <XYPointWValue <TL> >)leaf.Points; foreach (XYPointWValue <TL> point in collection) { if (point.X == x && point.Y == y) { return(point.Value); } } return(default(TL)); } var branch = (PointRegionQuadTreeNodeBranch)node; var q = node.Bb.GetQuadrant(x, y); switch (q) { case QuadrantEnum.NW: return(Get(x, y, branch.Nw)); case QuadrantEnum.NE: return(Get(x, y, branch.Ne)); case QuadrantEnum.SW: return(Get(x, y, branch.Sw)); default: return(Get(x, y, branch.Se)); } }
public static void Traverse( PointRegionQuadTreeNode node, Consumer<object> consumer) { if (node is PointRegionQuadTreeNodeLeaf<object>) { var leaf = (PointRegionQuadTreeNodeLeaf<object>) node; TraverseData(leaf.Points, consumer); return; } var branch = (PointRegionQuadTreeNodeBranch) node; Traverse(branch.Nw, consumer); Traverse(branch.Ne, consumer); Traverse(branch.Sw, consumer); Traverse(branch.Se, consumer); }
private static PointRegionQuadTreeNode DeleteFromNode( double x, double y, PointRegionQuadTreeNode node, PointRegionQuadTree<object> tree) { if (node is PointRegionQuadTreeNodeLeaf<object> leaf) { var removed = DeleteFromPoints(x, y, leaf.Points); if (removed) { leaf.DecCount(); if (leaf.Count == 0) leaf.Points = null; } return leaf; } var branch = (PointRegionQuadTreeNodeBranch) node; var quadrant = node.Bb.GetQuadrant(x, y); if (quadrant == QuadrantEnum.NW) branch.Nw = DeleteFromNode(x, y, branch.Nw, tree); else if (quadrant == QuadrantEnum.NE) branch.Ne = DeleteFromNode(x, y, branch.Ne, tree); else if (quadrant == QuadrantEnum.SW) branch.Sw = DeleteFromNode(x, y, branch.Sw, tree); else branch.Se = DeleteFromNode(x, y, branch.Se, tree); if (!(branch.Nw is PointRegionQuadTreeNodeLeaf<object> nwLeaf) || !(branch.Ne is PointRegionQuadTreeNodeLeaf<object> neLeaf) || !(branch.Sw is PointRegionQuadTreeNodeLeaf<object> swLeaf) || !(branch.Se is PointRegionQuadTreeNodeLeaf<object> seLeaf)) return branch; var total = nwLeaf.Count + neLeaf.Count + swLeaf.Count + seLeaf.Count; if (total >= tree.LeafCapacity) return branch; var collection = new List<XYPointWValue<TL>>(); var count = MergeChildNodes(collection, nwLeaf.Points); count += MergeChildNodes(collection, neLeaf.Points); count += MergeChildNodes(collection, swLeaf.Points); count += MergeChildNodes(collection, seLeaf.Points); return new PointRegionQuadTreeNodeLeaf<object>(branch.Bb, branch.Level, collection, count); }
private static PointRegionQuadTreeNode SetOnNode( double x, double y, TL value, PointRegionQuadTreeNode node, PointRegionQuadTree<object> tree) { if (node is PointRegionQuadTreeNodeLeaf<object> leaf) { var count = SetOnLeaf(leaf, x, y, value); leaf.IncCount(count); if (leaf.Count <= tree.LeafCapacity || node.Level >= tree.MaxTreeHeight) { return leaf; } node = Subdivide(leaf, tree); } var branch = (PointRegionQuadTreeNodeBranch) node; AddToBranch(branch, x, y, value, tree); return node; }
private static void CollectRange( PointRegionQuadTreeNode node, double x, double y, double width, double height, EventBean eventBean, TT target, QuadTreeCollector<TL, TT> collector) { if (!node.Bb.IntersectsBoxIncludingEnd(x, y, width, height)) return; if (node is PointRegionQuadTreeNodeLeaf<object> leaf) { CollectLeaf(leaf, x, y, width, height, eventBean, target, collector); return; } PointRegionQuadTreeNodeBranch branch = (PointRegionQuadTreeNodeBranch) node; CollectRange(branch.Nw, x, y, width, height, eventBean, target, collector); CollectRange(branch.Ne, x, y, width, height, eventBean, target, collector); CollectRange(branch.Sw, x, y, width, height, eventBean, target, collector); CollectRange(branch.Se, x, y, width, height, eventBean, target, collector); }
private static ICollection<object> QueryNode( PointRegionQuadTreeNode node, double x, double y, double width, double height, ICollection<object> result) { if (!node.Bb.IntersectsBoxIncludingEnd(x, y, width, height)) { return result; } if (node is PointRegionQuadTreeNodeLeaf<object> leaf) { return Visit(leaf, x, y, width, height, result); } var branch = (PointRegionQuadTreeNodeBranch) node; result = QueryNode(branch.Nw, x, y, width, height, result); result = QueryNode(branch.Ne, x, y, width, height, result); result = QueryNode(branch.Sw, x, y, width, height, result); result = QueryNode(branch.Se, x, y, width, height, result); return result; }
private static PointRegionQuadTreeNode RemoveFromNode( double x, double y, object value, PointRegionQuadTreeNode node, PointRegionQuadTree<object> tree) { if (node is PointRegionQuadTreeNodeLeaf<object> leaf) { var removed = RemoveFromPoints(x, y, value, leaf.Points); if (removed) { leaf.DecCount(); if (leaf.Count == 0) { leaf.Points = null; } } return leaf; } var branch = (PointRegionQuadTreeNodeBranch) node; var quadrant = node.Bb.GetQuadrant(x, y); switch (quadrant) { case QuadrantEnum.NW: branch.Nw = RemoveFromNode(x, y, value, branch.Nw, tree); break; case QuadrantEnum.NE: branch.Ne = RemoveFromNode(x, y, value, branch.Ne, tree); break; case QuadrantEnum.SW: branch.Sw = RemoveFromNode(x, y, value, branch.Sw, tree); break; default: branch.Se = RemoveFromNode(x, y, value, branch.Se, tree); break; } if (!(branch.Nw is PointRegionQuadTreeNodeLeaf<object>) || !(branch.Ne is PointRegionQuadTreeNodeLeaf<object>) || !(branch.Sw is PointRegionQuadTreeNodeLeaf<object>) || !(branch.Se is PointRegionQuadTreeNodeLeaf<object>)) { return branch; } var nwLeaf = (PointRegionQuadTreeNodeLeaf<object>) branch.Nw; var neLeaf = (PointRegionQuadTreeNodeLeaf<object>) branch.Ne; var swLeaf = (PointRegionQuadTreeNodeLeaf<object>) branch.Sw; var seLeaf = (PointRegionQuadTreeNodeLeaf<object>) branch.Se; var total = nwLeaf.Count + neLeaf.Count + swLeaf.Count + seLeaf.Count; if (total >= tree.LeafCapacity) { return branch; } var collection = new LinkedList<XYPointMultiType>(); var count = MergeChildNodes(collection, nwLeaf.Points); count += MergeChildNodes(collection, neLeaf.Points); count += MergeChildNodes(collection, swLeaf.Points); count += MergeChildNodes(collection, seLeaf.Points); return new PointRegionQuadTreeNodeLeaf<object>(branch.Bb, branch.Level, collection, count); }
public static bool IsEmpty(PointRegionQuadTreeNode node) { return(node is PointRegionQuadTreeNodeLeaf <object> leaf && leaf.Points == null); }
public void Clear() { Root = new PointRegionQuadTreeNodeLeaf<TL>(Root.Bb, Root.Level, default(TL), 0); }