コード例 #1
0
ファイル: RBushSpeedTest.cs プロジェクト: DrShushen/RBush
        public void RunTestGroup(int maxEntries, int numberOfItems)
        {
            RBush <Item> rBush = new RBush <Item>(maxEntries);

            double             spaceScale = 50;
            IEnumerable <Item> items      = ItemListGenerator.GenerateItems(numberOfItems, spaceScale);

            Console.WriteLine("maxEntries = " + maxEntries);

            // Tests:

            RunTest("BulkLoad", numberOfItems, () => { rBush.BulkLoad(items); });

            RunTest("Search OLD", numberOfItems, () => { rBush.Search_Old(); });
            RunTest("Search NEW", numberOfItems, () => { rBush.Search(); });

            RunTest("Search envelope (Inf. bounds) OLD", numberOfItems, () => { rBush.Search_Old(Envelope.InfiniteBounds); });
            RunTest("Search envelope (Inf. bounds) NEW", numberOfItems, () => { rBush.Search(Envelope.InfiniteBounds); });

            RunTest("Iterate through IEnumerable [for comparison]", numberOfItems, () => { foreach (Item i in items)
                                                                                           {
                                                                                           }
                    });

            Console.ReadLine();
        }
コード例 #2
0
 public static IReadOnlyList <T> KnnToPointSearch <T>(this RBush <T> tree, double x, double y, int n,
                                                      Func <T, bool> predicate = null, double maxDist = -1) where T : ISpatialData
 {
     return(tree.KnnSearch(new KnnToPointQuery {
         X = x, Y = y
     }, n, predicate, maxDist));
 }
コード例 #3
0
        public void FindNeighborsThatSatisfyAGivenPredicate()
        {
            RBush <Box> bush = new RBush <Box>();

            bush.BulkLoad(richData);

            IEnumerable <Box> result = bush.KnnToPointSearch(2, 4, 1, b => b.Version < 5);

            if (result.Count() == 1)
            {
                Box item = result.First();
                if (item.Envelope.MinX == 3 && item.Envelope.MinY == 3 &&
                    item.Envelope.MaxX == 3 && item.Envelope.MaxY == 3 &&
                    item.Version == 2)
                {
                    //Test passes. Found the correct item
                }
                else
                {
                    //Could not find the correct item
                    Assert.True(false);
                }
            }
            else
            {
                //Could not find the correct item
                Assert.True(false);
            }
        }
コード例 #4
0
        public void BasicRemoveTest()
        {
            var tree = new RBush <Point>(maxEntries: 4);

            tree.BulkLoad(points);

            var len = points.Length;

            tree.Delete(points[0]);
            tree.Delete(points[1]);
            tree.Delete(points[2]);

            tree.Delete(points[len - 1]);
            tree.Delete(points[len - 2]);
            tree.Delete(points[len - 3]);

            var shouldFindPoints = points
                                   .Skip(3).Take(len - 6)
                                   .OrderBy(x => x)
                                   .ToList();
            var foundPoints = tree.Search()
                              .OrderBy(x => x)
                              .ToList();

            Assert.Equal(shouldFindPoints, foundPoints);
        }
コード例 #5
0
ファイル: RBushTests.cs プロジェクト: DrShushen/RBush
        public void DeleteAndSearchTest()
        {
            var tree = new RBush <Point>(maxEntries: 4);

            tree.BulkLoad(points);

            var len = points.Length;

            // Delete an existent point.
            bool resultExistent           = tree.Delete(points[0]);
            var  shouldFindPointsExistent = points
                                            .Skip(1)
                                            .OrderBy(x => x)
                                            .ToList();
            var foundPointsExistent = tree.Search()
                                      .OrderBy(x => x)
                                      .ToList();

            // Try to delete a non-existent point.
            bool resultNonExistent           = tree.Delete(new Point(1245, 1233, 1245, 1233));
            var  shouldFindPointsNonExistent = shouldFindPointsExistent;
            var  foundPointsNonExistent      = tree.Search()
                                               .OrderBy(x => x)
                                               .ToList();

            Assert.True(resultExistent);
            Assert.Equal(shouldFindPointsExistent, foundPointsExistent);
            Assert.False(resultNonExistent);
            Assert.Equal(shouldFindPointsNonExistent, foundPointsNonExistent);
        }
コード例 #6
0
        public void RootLeafSplitWorks()
        {
            var data = GetPoints(12);

            var tree = new RBush <Point>();

            for (var i = 0; i < 9; i++)
            {
                tree.Insert(data[i]);
            }

            Assert.Equal(1, tree.Root.Height);
            Assert.Equal(9, tree.Root.children.Count);
            Assert.True(tree.Root.IsLeaf);

            Assert.Equal(0, tree.Root.Envelope.MinX);
            Assert.Equal(0, tree.Root.Envelope.MinY);
            Assert.Equal(8, tree.Root.Envelope.MaxX);
            Assert.Equal(8, tree.Root.Envelope.MaxY);

            tree.Insert(data[9]);

            Assert.Equal(2, tree.Root.Height);
            Assert.Equal(2, tree.Root.children.Count);
            Assert.False(tree.Root.IsLeaf);

            Assert.Equal(0, tree.Root.Envelope.MinX);
            Assert.Equal(0, tree.Root.Envelope.MinY);
            Assert.Equal(9, tree.Root.Envelope.MaxX);
            Assert.Equal(9, tree.Root.Envelope.MaxY);
        }
コード例 #7
0
        public static IEnumerable <IPoint> Execute(IGeometry line1, IGeometry line2)
        {
            IDictionary <string, IPoint> unique = new Dictionary <string, IPoint>();
            IList <IPoint> intersections        = new List <IPoint>();

            RBush <Extensions.SpatialDataWrapper <Segment> > tree = new RBush <Extensions.SpatialDataWrapper <Segment> >();

            tree.BulkLoad(LineSegment.Execute(line2).Select(a => a.AsSpatialData <Segment>()));
            foreach (Segment segment in LineSegment.Execute(line1))
            {
                foreach (Extensions.SpatialDataWrapper <Segment> match in tree.Search(segment.BBox.AsEnvelope()))
                {
                    IPoint intersect = Intersects(segment.LineString, match.GetOriginalData <Segment>().LineString);
                    if (intersect != null)
                    {
                        var key = string.Join(",", intersect.X, intersect.Y);
                        if (!unique.ContainsKey(key))
                        {
                            unique.Add(key, intersect);
                            intersections.Add(intersect);
                        }
                    }
                }
            }

            return(intersections);
        }
コード例 #8
0
ファイル: RBushTests.cs プロジェクト: DrShushen/RBush
        public void TestSearch_AfterBulkLoadWithSplitRoot()
        {
            int maxEntries = 4;
            var tree       = new RBush <Point>(maxEntries);

            int      numFirstSet      = maxEntries * maxEntries + 2;    // Split-root will occur twice.
            var      firstSet         = points.Take(numFirstSet);
            Envelope firstSetEnvelope =
                new Envelope(
                    firstSet.Min(p => p.Envelope.MinX),
                    firstSet.Min(p => p.Envelope.MinY),
                    firstSet.Max(p => p.Envelope.MaxX),
                    firstSet.Max(p => p.Envelope.MaxY));

            tree.BulkLoad(firstSet);

            int      numExtraPoints         = 5;
            var      extraPointsSet         = points.TakeLast(numExtraPoints);
            Envelope extraPointsSetEnvelope =
                new Envelope(
                    extraPointsSet.Min(p => p.Envelope.MinX),
                    extraPointsSet.Min(p => p.Envelope.MinY),
                    extraPointsSet.Max(p => p.Envelope.MaxX),
                    extraPointsSet.Max(p => p.Envelope.MaxY));

            foreach (var p in extraPointsSet)
            {
                tree.Insert(p);
            }

            Assert.Equal(extraPointsSet.OrderBy(x => x), tree.Search(extraPointsSetEnvelope).OrderBy(x => x));
        }
コード例 #9
0
        public void FindNeighborsThatSatisfyAGivenPredicate()
        {
            RBush <Box> bush = new RBush <Box>();

            bush.BulkLoad(richData);

            IEnumerable <Box> result = bush.KnnToLineSegmentSearch(6386.5, 3349.5, 6393, 3353.5, 1, b => b.Version > 2);

            if (result.Count() == 1)
            {
                Box item = result.First();
                if (item.Envelope.MinX == 6393.8 && item.Envelope.MinY == 3354.0 &&
                    item.Envelope.MaxX == 6395.3 && item.Envelope.MaxY == 3356.0 &&
                    item.Version == 3)
                {
                    //Test passes. Found the correct item
                }
                else
                {
                    Assert.True(false, "Could not find the correct item");
                }
            }
            else
            {
                Assert.True(false, "Could not find the correct item");
            }
        }
コード例 #10
0
        public void FindsNNeighbors1()
        {
            RBush <Box> bush = new RBush <Box>();

            bush.BulkLoad(boxes);
            IEnumerable <Box> result = bush.KnnToLineSegmentSearch(6362, 3343.5, 6360.75, 3344, 10);

            Box[] mustBeReturned = Box.CreateBoxes(new double[, ]
            {
                { 6359.0, 3343.0, 6362.5, 3345.0 }, { 6357.0, 3342.0, 6363.5, 3343.0 }, { 6360.5, 3340.0, 6361.5, 3342.0 },
                { 6364.0, 3342.0, 6365.0, 3344.5 }, { 6362.0, 3340.5, 6363.0, 3341.5 }, { 6358.5, 3337.5, 6360.5, 3341.5 },
                { 6361.0, 3339.0, 6363.0, 3340.0 }, { 6364.5, 3340.5, 6368.0, 3341.0 }, { 6363.5, 3337.5, 6365.0, 3340.0 },
                { 6367.0, 3342.0, 6368.0, 3344.0 },
            });
            Assert.True(mustBeReturned.Length == result.Count());


            Assert.True(result.ElementAt(0).CompareTo(mustBeReturned[0]) == 0);
            Assert.True(result.ElementAt(1).CompareTo(mustBeReturned[1]) == 0);
            Assert.True(result.ElementAt(2).CompareTo(mustBeReturned[2]) == 0);
            Assert.True(result.ElementAt(3).CompareTo(mustBeReturned[3]) == 0 ||
                        result.ElementAt(3).CompareTo(mustBeReturned[4]) == 0);
            Assert.True(result.ElementAt(4).CompareTo(mustBeReturned[3]) == 0 ||
                        result.ElementAt(4).CompareTo(mustBeReturned[4]) == 0);
            Assert.True(result.ElementAt(5).CompareTo(mustBeReturned[5]) == 0);

            Assert.True(result.ElementAt(6).CompareTo(mustBeReturned[6]) == 0);
            Assert.True(result.ElementAt(7).CompareTo(mustBeReturned[7]) == 0);
            Assert.True(result.ElementAt(8).CompareTo(mustBeReturned[8]) == 0);
            Assert.True(result.ElementAt(9).CompareTo(mustBeReturned[9]) == 0);
        }
コード例 #11
0
        public void TestSearchAfterInsertWithSplitRoot()
        {
            var maxEntries = 4;
            var tree       = new RBush <Point>(maxEntries);

            var numFirstSet = maxEntries * maxEntries + 2;              // Split-root will occur twice.
            var firstSet    = points.Take(numFirstSet);

            foreach (var p in firstSet)
            {
                tree.Insert(p);
            }

            var numExtraPoints         = 5;
            var extraPointsSet         = points.Skip(points.Length - numExtraPoints);
            var extraPointsSetEnvelope =
                extraPointsSet.Aggregate(Envelope.EmptyBounds, (e, p) => e.Extend(p.Envelope));

            foreach (var p in extraPointsSet)
            {
                tree.Insert(p);
            }

            // first 10 entries and last 5 entries are completely mutually exclusive
            // so searching the bounds of the new set should only return the new set exactly
            Assert.Equal(extraPointsSet.OrderBy(x => x), tree.Search(extraPointsSetEnvelope).OrderBy(x => x));
        }
コード例 #12
0
        public void BasicRemoveTest()
        {
            var tree = new RBush <Point>(maxEntries: 4);

            tree.BulkLoad(points);

            var len = points.Length;

            tree.Delete(points[0]);
            tree.Delete(points[1]);
            tree.Delete(points[2]);

            tree.Delete(points[len - 1]);
            tree.Delete(points[len - 2]);
            tree.Delete(points[len - 3]);

            var shouldFindPoints = points
                                   .Skip(3).Take(len - 6)
                                   .OrderBy(x => x)
                                   .ToList();
            var foundPoints = tree.Search()
                              .OrderBy(x => x)
                              .ToList();

            Assert.Equal(shouldFindPoints, foundPoints);
            Assert.Equal(shouldFindPoints.Count, tree.Count);
            Assert.Equal(
                shouldFindPoints.Aggregate(Envelope.EmptyBounds, (e, p) => e.Extend(p.Envelope)),
                tree.Envelope);
        }
コード例 #13
0
        public void NonExistentItemCanBeDeleted()
        {
            var tree = new RBush <Point>(maxEntries: 4);

            tree.BulkLoad(points);

            tree.Delete(new Point(13, 13, 13, 13));
        }
コード例 #14
0
        public void SearchReturnsEmptyResultIfNothingFound()
        {
            var tree = new RBush <Point>(maxEntries: 4);

            tree.BulkLoad(points);

            Assert.Equal(new Point[] { }, tree.Search(new Envelope(200, 200, 210, 210)));
        }
コード例 #15
0
ファイル: RBushTests.cs プロジェクト: viceroypenguin/RBush
        public void Delete_TreeIsEmpty_ShouldNotThrow()
        {
            var tree = new RBush <Point>();

            tree.Delete(new Point(1, 1, 1, 1));

            Assert.Equal(0, tree.Count);
        }
コード例 #16
0
 public static IReadOnlyList <T> KnnToLineSegmentSearch <T>(this RBush <T> tree,
                                                            double x0, double y0, double x1, double y1, int n, Func <T, bool> predicate = null, double maxDist = -1)
     where T : ISpatialData
 {
     return(tree.KnnSearch(new KnnToLineSegmentQuery {
         X0 = x0, Y0 = y0, X1 = x1, Y1 = y1
     }, n, predicate, maxDist));
 }
コード例 #17
0
        public void DoesNotThrowIfRequestingTooManyItems()
        {
            var bush = new RBush <Box>();

            bush.BulkLoad(boxes);

            bush.Knn(1000, 40, 40);
        }
コード例 #18
0
        public void DoesNotThrowIfRequestingTooManyItemsForMaxDistance()
        {
            var bush = new RBush <Box>();

            bush.BulkLoad(boxes);

            bush.Knn(1000, 40, 40, maxDistance: 10);
        }
コード例 #19
0
        public void BulkLoadTestData()
        {
            var tree = new RBush <Point>();

            tree.BulkLoad(points);

            Assert.Equal(points.Length, tree.Count);
            Assert.Equal(points.OrderBy(x => x).ToList(), tree.Search().OrderBy(x => x).ToList());
        }
コード例 #20
0
        public void NonExistentItemCanBeDeleted()
        {
            var tree = new RBush <Point>(maxEntries: 4);

            tree.BulkLoad(points);

            tree.Delete(new Point(13, 13, 13, 13));
            Assert.Equal(points.Length, tree.Count);
        }
コード例 #21
0
        public void ClearWorks()
        {
            var tree = new RBush <Point>(maxEntries: 4);

            tree.BulkLoad(points);
            tree.Clear();

            Assert.Equal(0, tree.Count);
            Assert.Empty(tree.Root.children);
        }
コード例 #22
0
        public void BulkLoadSplitsTreeProperly()
        {
            var tree = new RBush <Point>(maxEntries: 4);

            tree.BulkLoad(points);
            tree.BulkLoad(points);

            Assert.Equal(points.Length * 2, tree.Count);
            Assert.Equal(4, tree.Root.Height);
        }
コード例 #23
0
        internal static IReadOnlyList <T> KnnSearch <T>(this RBush <T> tree, object query, int n,
                                                        Func <T, bool> predicate = null, double maxDist = -1) where T : ISpatialData
        {
            var distCalculator = new DistanceToSpatialCalculator();

            if (maxDist > 0)
            {
                maxDist = maxDist * maxDist;                //compare quadratic distances
            }
            List <T> result = new List <T>();

            //priority queue
            var queue = new C5.IntervalHeap <IDistanceToSpatial>(new DistComparer());

            RBush <T> .Node node = tree.Root;

            while (node != null)
            {
                foreach (ISpatialData child in node.Children)                                    //for each child
                {
                    var childDistData = distCalculator.CalculateDistanceToSpatial(query, child); //calc distance to box
                    if (maxDist < 0 || childDistData.SquaredDistanceToBox <= maxDist)            //check if distance less than max distance
                    {
                        queue.Add(childDistData);                                                //add to queue
                    }
                }

                //dequeue all objects that are items stored in RBush
                while (queue.Count > 0 && queue.FindMin().SpatialData is T)
                {
                    var candidateWr = queue.DeleteMin();                  //this item goes to result
                    T   candidate   = (T)candidateWr.SpatialData;
                    if (predicate == null || predicate.Invoke(candidate)) //if element satisfy the condition
                    {
                        result.Add(candidate);                            //add to result
                    }
                    if (n > 0 && result.Count == n)                       //if the desired amount is already in the result
                    {
                        return(result);                                   //return result
                    }
                }

                //process next element in queue
                if (queue.Count > 0)
                {
                    node = queue.DeleteMin().SpatialData as RBush <T> .Node;
                }
                else
                {
                    node = null;
                }
            }

            return(result);
        }
コード例 #24
0
ファイル: RBushTests.cs プロジェクト: viceroypenguin/RBush
        public void Delete_DeletingLastPoint_ShouldNotThrow()
        {
            var   tree = new RBush <Point>();
            Point p    = new Point(1, 1, 1, 1);

            tree.Insert(p);

            tree.Delete(p);

            Assert.Equal(0, tree.Count);
        }
コード例 #25
0
ファイル: KnnSearcher.cs プロジェクト: Kirill78Z/RBush
        /// <summary>
        /// Search k nearest neighbors to given point or to to given line segment
        /// </summary>
        /// <typeparam name="T">type of RBush items</typeparam>
        /// <param name="tree">RBush object</param>
        /// <param name="x1">x coordinate of query point.
        /// Or if x2 and y2 not null, x coordinate of first endpoint of query line segment</param>
        /// <param name="y1">y coordinate of query point.
        /// Or if x2 and y2 not null, y coordinate of first endpoint of query line segment</param>
        /// <param name="n">number of nearest neighbors to get</param>
        /// <param name="predicate">condition for neighbors</param>
        /// <param name="maxDist">max distance for nearest neighbors</param>
        /// <param name="x2">if not null is x coordinate of second endpoint of query line segment</param>
        /// <param name="y2">if not null is y coordinate of second endpoint of query line segment</param>
        /// <returns></returns>
        public static IReadOnlyList <T> KnnSearch <T>(this RBush <T> tree, double x1, double y1, int n,
                                                      Func <T, bool> predicate = null, double maxDist = -1, double?x2 = null, double?y2 = null) where T : ISpatialData
        {
            if (maxDist > 0)
            {
                maxDist = maxDist * maxDist;                //All distances are quadratic!!!
            }
            List <T> result = new List <T>();

            //priority queue
            C5.IntervalHeap <SpatialDataWrapper> queue = new C5.IntervalHeap <SpatialDataWrapper>(new DistComparer());

            RBush <T> .Node node = tree.Root;

            while (node != null)
            {
                foreach (ISpatialData child in node.Children)                                         //for each child
                {
                    SpatialDataWrapper childDistData = new SpatialDataWrapper(child, x1, y1, x2, y2); //calc distance to box
                    if (maxDist < 0 || childDistData.SquaredDistanceToBox <= maxDist)                 //check if distance less than max distance
                    {
                        queue.Add(childDistData);                                                     //add to queue
                    }
                }

                //dequeue all objects that are items stored in RBush
                while (queue.Count > 0 && queue.FindMin().SpatialData is T)
                {
                    SpatialDataWrapper candidate = queue.DeleteMin();      //this item goes to result
                    T _candidate = (T)candidate.SpatialData;
                    if (predicate == null || predicate.Invoke(_candidate)) //if element satisfy the condition
                    {
                        result.Add(_candidate);                            //add to result
                    }
                    if (n > 0 && result.Count == n)                        //if the desired amount is already in the result
                    {
                        return(result);                                    //return result
                    }
                }

                //process next element in queue
                if (queue.Count > 0)
                {
                    node = queue.DeleteMin().SpatialData as RBush <T> .Node;
                }
                else
                {
                    node = null;
                }
            }

            return(result);
        }
コード例 #26
0
        public void InsertTestData()
        {
            var tree = new RBush <Point>();

            foreach (var p in points)
            {
                tree.Insert(p);
            }

            Assert.Equal(points.Length, tree.Count);
            Assert.Equal(points.OrderBy(x => x), tree.Search().OrderBy(x => x));
        }
コード例 #27
0
        public void FindsNNeighbors()
        {
            var bush = new RBush <Box>();

            bush.BulkLoad(boxes);
            var result   = bush.Knn(10, 40, 40);
            var expected = boxes
                           .OrderBy(b => b.DistanceTo(40, 40))
                           .Take(10)
                           .ToList();

            Assert.Equal(expected, result);
        }
コード例 #28
0
        public void FindAllNeighborsForMaxDistance()
        {
            RBush <Box> bush = new RBush <Box>();

            bush.BulkLoad(boxes);

            IEnumerable <Box> result = bush.KnnToPointSearch(40, 40, 0, maxDist: 10);

            foreach (Box resBox in result)
            {
                Assert.True(CalcBoxDist(resBox, 40, 40) <= 10);
            }
        }
コード例 #29
0
        /// <summary>
        /// Method used to split all the bounding boxes into a predefined config based smaller buckets to be able to parallely searched
        /// </summary>
        private void SplitToBuckets()
        {
            int subListSize      = BoundingBoxes.Count / MaxConcurrentEngines;
            int elementsIterated = 0;

            while (elementsIterated < BoundingBoxes.Count)
            {
                int remainingElements = Math.Min(BoundingBoxes.Count - elementsIterated, subListSize);
                var newBush           = new RBush <BoundingBox>();
                newBush.BulkLoad((BoundingBoxes as List <BoundingBox>).GetRange(elementsIterated, remainingElements));
                BoxesEnginesBuckets.Add(newBush);
                elementsIterated += subListSize;
            }
        }
コード例 #30
0
        public void FindAllNeighborsForMaxDistance()
        {
            var bush = new RBush <Box>();

            bush.BulkLoad(boxes);

            var result   = bush.Knn(0, 40, 40, maxDistance: 10);
            var expected = boxes
                           .Where(b => b.DistanceTo(40, 40) <= 10)
                           .OrderBy(b => b.DistanceTo(40, 40))
                           .ToList();

            Assert.Equal(expected, result);
        }