private static void CollectLeaf( PointRegionQuadTreeNodeLeaf<object> node, double x, double y, double width, double height, EventBean eventBean, TT target, QuadTreeCollector<TL, TT> collector) { var points = node.Points; if (points == null) return; if (points is XYPointWValue<TL> point) { if (BoundingBox.ContainsPoint(x, y, width, height, point.X, point.Y)) collector.CollectInto(eventBean, point.Value, target); return; } var collection = (ICollection<XYPointWValue<TL>>) points; foreach(var pointX in collection) { if (BoundingBox.ContainsPoint(x, y, width, height, pointX.X, pointX.Y)) collector.CollectInto(eventBean, pointX.Value, target); } }
private static ICollection<object> Visit( PointRegionQuadTreeNodeLeaf<object> node, double x, double y, double width, double height, ICollection<object> result) { object points = node.Points; if (points == null) { return result; } if (points is XYPointMultiType) { XYPointMultiType point = (XYPointMultiType) points; return Visit(point, x, y, width, height, result); } ICollection<XYPointMultiType> collection = (ICollection<XYPointMultiType>) points; foreach (XYPointMultiType point in collection) { result = Visit(point, x, y, width, height, result); } return result; }
private static PointRegionQuadTreeNode Subdivide( PointRegionQuadTreeNodeLeaf<object> leaf, PointRegionQuadTree<object> tree, bool unique, string indexName) { var w = (leaf.Bb.MaxX - leaf.Bb.MinX) / 2d; var h = (leaf.Bb.MaxY - leaf.Bb.MinY) / 2d; var minx = leaf.Bb.MinX; var miny = leaf.Bb.MinY; var bbNW = new BoundingBox(minx, miny, minx + w, miny + h); var bbNE = new BoundingBox(minx + w, miny, leaf.Bb.MaxX, miny + h); var bbSW = new BoundingBox(minx, miny + h, minx + w, leaf.Bb.MaxY); var bbSE = new BoundingBox(minx + w, miny + h, leaf.Bb.MaxX, leaf.Bb.MaxY); var nw = new PointRegionQuadTreeNodeLeaf<object>(bbNW, leaf.Level + 1, null, 0); var ne = new PointRegionQuadTreeNodeLeaf<object>(bbNE, leaf.Level + 1, null, 0); var sw = new PointRegionQuadTreeNodeLeaf<object>(bbSW, leaf.Level + 1, null, 0); var se = new PointRegionQuadTreeNodeLeaf<object>(bbSE, leaf.Level + 1, null, 0); var branch = new PointRegionQuadTreeNodeBranch(leaf.Bb, leaf.Level, nw, ne, sw, se); var points = leaf.Points; if (points is XYPointMultiType) { var point = (XYPointMultiType) points; SubdividePoint(point, branch, tree, unique, indexName); } else { foreach (var point in (ICollection<XYPointMultiType>) points) { SubdividePoint(point, branch, tree, unique, indexName); } } return branch; }
static XYPointMultiType[] AssertPointCollection( PointRegionQuadTreeNodeLeaf <object> leaf) { Assert.That(leaf, Is.Not.Null); Assert.That(leaf.Points, Is.InstanceOf <ICollection <XYPointMultiType> >()); return(leaf.Points.UnwrapIntoArray <XYPointMultiType>()); }
private static void CollectLeaf( PointRegionQuadTreeNodeLeaf<object> node, double x, double y, double width, double height, EventBean eventBean, TT target, QuadTreeCollector<TT> collector, ExprEvaluatorContext ctx) { var points = node.Points; if (points == null) { return; } if (points is XYPointWValue<TL> pointWValueWithType) { if (BoundingBox.ContainsPoint(x, y, width, height, pointWValueWithType.X, pointWValueWithType.Y)) { collector.CollectInto(eventBean, pointWValueWithType.Value, target, ctx); } return; } else if (points is XYPointWValue<object> pointWValueWithoutType) { if (BoundingBox.ContainsPoint( x, y, width, height, pointWValueWithoutType.X, pointWValueWithoutType.Y)) { collector.CollectInto(eventBean, (TL) pointWValueWithoutType.Value, target, ctx); } return; } else if (points is IEnumerable<XYPointWValue<TL>> enumerableWithType) { foreach (var point in enumerableWithType) { if (BoundingBox.ContainsPoint(x, y, width, height, point.X, point.Y)) { collector.CollectInto(eventBean, point.Value, target, ctx); } } } else if (points is IEnumerable<XYPointWValue<object>> enumerableWithoutType) { foreach (var point in enumerableWithoutType) { if (BoundingBox.ContainsPoint(x, y, width, height, point.X, point.Y)) { collector.CollectInto(eventBean, (TL) point.Value, target, ctx); } } } else { throw new IllegalStateException("unknown type for points"); } }
private static int SetOnLeaf( PointRegionQuadTreeNodeLeaf<object> leaf, double x, double y, XYPointWValue<TL> pointXY) { if (pointXY.X != x && pointXY.Y != y) { throw new IllegalStateException(); } return SetOnLeaf(leaf, x, y, pointXY.Value); }
public void TestSuperslim() { PointRegionQuadTree <object> tree = PointRegionQuadTreeFactory <object> .Make(0, 0, 100, 100, 1, 100); Set(tree, 10, 90, "P1"); Set(tree, 10, 95, "P2"); PointRegionQuadTreeNodeLeaf <object> ne = NavigateLeaf(tree, "sw,sw,sw,ne"); Compare(10, 90, "P1", (XYPointWValue <object>)ne.Points); PointRegionQuadTreeNodeLeaf <object> se = NavigateLeaf(tree, "sw,sw,sw,se"); Compare(10, 95, "P2", (XYPointWValue <object>)se.Points); }
public void TestSuperSlim() { PointRegionQuadTree <object> tree = PointRegionQuadTreeFactory <object> .Make(0, 0, 100, 100, 1, 100); AddNonUnique(tree, 10, 90, "P1"); AddNonUnique(tree, 10, 95, "P2"); PointRegionQuadTreeNodeLeaf <object> ne = NavigateLeaf(tree, "sw,sw,sw,ne"); Compare(10, 90, "\"P1\"", (XYPointMultiType)ne.Points); PointRegionQuadTreeNodeLeaf <object> se = NavigateLeaf(tree, "sw,sw,sw,se"); Compare(10, 95, "\"P2\"", (XYPointMultiType)se.Points); }
private static int CountLeaf(PointRegionQuadTreeNodeLeaf<object> leaf) { if (leaf.Points == null) return 0; if (leaf.Points is XYPointWValue<object>) return CountCallbacks(leaf.Points); var coll = (ICollection<XYPointWValue<object>>) leaf.Points; var count = 0; foreach (var p in coll) count += CountCallbacks(p.Value); return count; }
private static int CountLeaf(PointRegionQuadTreeNodeLeaf<object> leaf) { if (leaf.Points == null) return 0; if (leaf.Points is XYPointWOpaqueValue) return CountCallbacks(leaf.Points); var coll = leaf.Points.Unwrap<XYPointWOpaqueValue>(); var count = 0; foreach (var p in coll) { count += CountCallbacks(p.OpaqueValue); } return count; }
public void TestSubdivideMultiChild() { PointRegionQuadTree <object> tree = PointRegionQuadTreeFactory <object> .Make(0, 0, 100, 100, 4, 3); Set(tree, 60, 11, "P1"); Set(tree, 60, 40, "P2"); Set(tree, 70, 30, "P3"); Set(tree, 60, 10, "P4"); Set(tree, 90, 45, "P5"); NavigateLeaf(tree, "nw"); NavigateLeaf(tree, "se"); NavigateLeaf(tree, "sw"); PointRegionQuadTreeNodeBranch ne = NavigateBranch(tree, "ne"); Assert.AreEqual(2, ne.Level); PointRegionQuadTreeNodeLeaf <object> nw = NavigateLeaf(ne, "nw"); IList <XYPointWValue <object> > collection = (IList <XYPointWValue <object> >)nw.Points; Compare(60, 11, "P1", collection[0]); Compare(60, 10, "P4", collection[1]); Assert.AreEqual(2, nw.Count); PointRegionQuadTreeNodeLeaf <object> se = NavigateLeaf(ne, "se"); Compare(90, 45, "P5", (XYPointWValue <object>)se.Points); Assert.AreEqual(1, se.Count); PointRegionQuadTreeNodeLeaf <object> sw = NavigateLeaf(ne, "sw"); collection = (IList <XYPointWValue <object> >)sw.Points; Compare(60, 40, "P2", collection[0]); Compare(70, 30, "P3", collection[1]); Assert.AreEqual(2, sw.Count); Delete(tree, 60, 11); Delete(tree, 60, 40); PointRegionQuadTreeNodeLeaf <object> root = NavigateLeaf(tree, ""); collection = (IList <XYPointWValue <object> >)root.Points; Assert.AreEqual(3, root.Count); Assert.AreEqual(3, collection.Count); Compare(60, 10, "P4", collection[0]); Compare(70, 30, "P3", collection[1]); Compare(90, 45, "P5", collection[2]); }
public void TestSubdivideMultiChild() { PointRegionQuadTree <object> tree = PointRegionQuadTreeFactory <object> .Make(0, 0, 100, 100, 4, 3); AddNonUnique(tree, 60, 10, "P1"); AddNonUnique(tree, 60, 40, "P2"); AddNonUnique(tree, 70, 30, "P3"); AddNonUnique(tree, 60, 10, "P4"); AddNonUnique(tree, 90, 45, "P5"); NavigateLeaf(tree, "nw"); NavigateLeaf(tree, "se"); NavigateLeaf(tree, "sw"); PointRegionQuadTreeNodeBranch ne = NavigateBranch(tree, "ne"); Assert.AreEqual(2, ne.Level); PointRegionQuadTreeNodeLeaf <object> nw = NavigateLeaf(ne, "nw"); Compare(60, 10, "[\"P1\", \"P4\"]", (XYPointMultiType)nw.Points); Assert.AreEqual(2, nw.Count); PointRegionQuadTreeNodeLeaf <object> se = NavigateLeaf(ne, "se"); Compare(90, 45, "\"P5\"", (XYPointMultiType)se.Points); Assert.AreEqual(1, se.Count); PointRegionQuadTreeNodeLeaf <object> sw = NavigateLeaf(ne, "sw"); var collection = AssertPointCollection(sw); Compare(60, 40, "\"P2\"", collection[0]); Compare(70, 30, "\"P3\"", collection[1]); Assert.AreEqual(2, sw.Count); Remove(tree, 60, 10, "P1"); Remove(tree, 60, 40, "P2"); PointRegionQuadTreeNodeLeaf <object> root = NavigateLeaf(tree, ""); collection = AssertPointCollection(root); Assert.AreEqual(3, root.Count); Assert.AreEqual(3, collection.Length); Compare(60, 10, "[\"P4\"]", collection[0]); Compare(70, 30, "\"P3\"", collection[1]); Compare(90, 45, "\"P5\"", collection[2]); }
private static int SetOnLeaf( PointRegionQuadTreeNodeLeaf <object> leaf, double x, double y, TL value) { var currentValue = leaf.Points; if (currentValue == null) { leaf.Points = new XYPointWValue <TL>(x, y, value); return(1); } if (currentValue is XYPointWValue <TL> otherXY) { if (otherXY.X == x && otherXY.Y == y) { otherXY.Value = value; return(0); } var collectionX = new List <XYPointWValue <TL> >(); collectionX.Add(otherXY); collectionX.Add(new XYPointWValue <TL>(x, y, value)); leaf.Points = collectionX; return(1); } var collection = currentValue.Unwrap <XYPointWValue <TL> >(); foreach (var other in collection) { if (other.X == x && other.Y == y) { other.Value = value; return(0); } } collection.Add(new XYPointWValue <TL>(x, y, value)); return(1); }
public static int AddToLeaf( PointRegionQuadTreeNodeLeaf<object> leaf, double x, double y, object value, bool unique, string indexName) { var currentValue = leaf.Points; // value can be multitype itself since we may subdivide-add and don't want to allocate a new object if (value is XYPointMultiType) { var point = (XYPointMultiType) value; if (point.X != x && point.Y != y) { throw new IllegalStateException(); } if (currentValue == null) { leaf.Points = point; return point.Count(); } if (currentValue is XYPointMultiType) { var other = (XYPointMultiType) currentValue; if (other.X == x && other.Y == y) { if (unique) { throw HandleUniqueViolation(indexName, other.X, other.Y); } other.AddMultiType(point); return point.Count(); } var collectionX = new LinkedList<XYPointMultiType>(); collectionX.AddLast(other); collectionX.AddLast(point); leaf.Points = collectionX; return point.Count(); } var xyPointMultiTypes = (ICollection<XYPointMultiType>) currentValue; foreach (var other in xyPointMultiTypes) { if (other.X == x && other.Y == y) { if (unique) { throw HandleUniqueViolation(indexName, other.X, other.Y); } other.AddMultiType(point); return point.Count(); } } xyPointMultiTypes.Add(point); return point.Count(); } if (currentValue == null) { var point = new XYPointMultiType(x, y, value); leaf.Points = point; return 1; } if (currentValue is XYPointMultiType) { var other = (XYPointMultiType) currentValue; if (other.X == x && other.Y == y) { if (unique) { throw HandleUniqueViolation(indexName, other.X, other.Y); } other.AddSingleValue(value); return 1; } var xyPointMultiTypes = new LinkedList<XYPointMultiType>(); xyPointMultiTypes.AddLast(other); xyPointMultiTypes.AddLast(new XYPointMultiType(x, y, value)); leaf.Points = xyPointMultiTypes; return 1; } var collection = (ICollection<XYPointMultiType>) currentValue; foreach (var other in collection) { if (other.X == x && other.Y == y) { if (unique) { throw HandleUniqueViolation(indexName, other.X, other.Y); } other.AddSingleValue(value); return 1; } } collection.Add(new XYPointMultiType(x, y, value)); return 1; }