コード例 #1
0
        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);
            }
        }
コード例 #2
0
        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;
        }
コード例 #3
0
        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;
        }
コード例 #4
0
 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>());
 }
コード例 #5
0
        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");
            }
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }
コード例 #8
0
        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);
        }
コード例 #9
0
        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;
        }
コード例 #10
0
        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;
        }
コード例 #11
0
        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]);
        }
コード例 #12
0
        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]);
        }
コード例 #13
0
        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);
        }
コード例 #14
0
        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;
        }