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);
        }
예제 #3
0
 public PointRegionQuadTree(
     int leafCapacity,
     int maxTreeHeight,
     PointRegionQuadTreeNode root)
 {
     LeafCapacity = leafCapacity;
     MaxTreeHeight = maxTreeHeight;
     Root = root;
 }
예제 #4
0
        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);
        }
예제 #5
0
        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));
            }
        }
예제 #6
0
        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);
        }
예제 #7
0
        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);
        }
예제 #8
0
        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);
        }
예제 #10
0
        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);
        }
예제 #12
0
 public static bool IsEmpty(PointRegionQuadTreeNode node)
 {
     return(node is PointRegionQuadTreeNodeLeaf <object> leaf && leaf.Points == null);
 }
예제 #13
0
 public void Clear()
 {
     Root = new PointRegionQuadTreeNodeLeaf<TL>(Root.Bb, Root.Level, default(TL), 0);
 }