コード例 #1
0
        /// <summary>
        /// Find the cell of the given level that covers the given Geoposition.
        /// This method uses the library given S2RegionCoverer to find the leaf cell containing the given Geoposition
        /// and uses binary operation on the leaf cell's Id to find the higher level cell containing the leaf.
        /// This is somehow more accurate than using the S2RegionCoverer for the higher level cell, where some errors occured.
        /// </summary>
        /// <param name="pos">Position in the cell</param>
        /// <param name="level">Level of the cell</param>
        /// <returns>The cell covering the given position that matches the specifications</returns>
        private S2Cell FindExactCell(BasicGeoposition pos, int level)
        {
            var point = S2LatLngRect.FromPoint(S2LatLng.FromDegrees(pos.Latitude, pos.Longitude));

            var cells = new List <S2CellId>();

            // find leaf cell
            var coverer = new S2RegionCoverer()
            {
                MinLevel = 30,
                MaxLevel = 30,
                MaxCells = 1
            };

            coverer.GetCovering(point, cells);

            var leaf = new S2Cell(cells[0]);

            int   shift = 64 - (3 + level * 2 + 1);
            ulong id    = leaf.Id.Id & ulong.MaxValue << shift;

            id |= 0 | ((ulong)1 << shift);

            return(new S2Cell(new S2CellId(id)));
        }
コード例 #2
0
        private static List <Coordinate> GetS2Cells(BoundingBox bbox)
        {
            var regionCoverer = new S2RegionCoverer
            {
                MinLevel = 15,
                MaxLevel = 15,
                //MaxCells = 100,
            };
            var region = new S2LatLngRect(
                S2LatLng.FromDegrees(bbox.MinimumLatitude, bbox.MinimumLongitude),
                S2LatLng.FromDegrees(bbox.MaximumLatitude, bbox.MaximumLongitude)
                );
            var cellIds = regionCoverer.GetCovering(region);
            var list    = new List <Coordinate>();

            foreach (var cellId in cellIds)
            {
                var center = cellId.ToLatLng();
                list.Add(new Coordinate(center.LatDegrees, center.LngDegrees));
            }
            // TODO: Check if point is within geofence
            //var filtered = FilterCoordinates(coordinates);
            //return filtered;
            return(list);
        }
コード例 #3
0
    // Verifies that an arbitrary S2ShapeIndex is buffered correctly, by first
    // converting the covering to an S2Polygon and then checking that (a) the
    // S2Polygon contains the original geometry and (b) the distance between the
    // original geometry and the boundary of the S2Polygon is at least "radius".
    //
    // The "radius" parameter is an S1Angle for convenience.
    // TODO(ericv): Add Degrees, Radians, etc, methods to S1ChordAngle?
    private static void TestBufferIndex(string index_str, S1Angle radius_angle, S2RegionCoverer coverer)
    {
        var          index    = MakeIndexOrDie(index_str);
        S1ChordAngle radius   = new(radius_angle);
        var          region   = new S2ShapeIndexBufferedRegion(index, radius);
        S2CellUnion  covering = coverer.GetCovering(region);
        // Compute an S2Polygon representing the union of the cells in the covering.
        S2Polygon covering_polygon = new();

        covering_polygon.InitToCellUnionBorder(covering);
        MutableS2ShapeIndex covering_index = new();

        covering_index.Add(new S2Polygon.Shape(covering_polygon));

        // (a) Check that the covering contains the original index.
        Assert.True(S2BooleanOperation.Contains(covering_index, index));

        // (b) Check that the distance between the boundary of the covering and the
        // the original indexed geometry is at least "radius".
        S2ClosestEdgeQuery query = new(covering_index);

        query.Options_.IncludeInteriors = (false);
        var target = new S2ClosestEdgeQuery.ShapeIndexTarget(index);

        Assert.False(query.IsDistanceLess(target, radius));
    }
コード例 #4
0
        public List <S2CellId> GetS2CellIds(ushort level, int maxCells)
        {
            //var geofence = Geofence.FromMultiPolygon(this);
            var bbox          = GetBoundingBox();
            var regionCoverer = new S2RegionCoverer
            {
                MinLevel = level,
                MaxLevel = level,
                MaxCells = maxCells,
            };
            var region = new S2LatLngRect(
                S2LatLng.FromDegrees(bbox.MinimumLatitude, bbox.MinimumLongitude),
                S2LatLng.FromDegrees(bbox.MaximumLatitude, bbox.MaximumLongitude)
                );
            var coverage = new List <S2CellId>();

            regionCoverer.GetCovering(region, coverage);
            var result = new List <S2CellId>();

            foreach (var cellId in coverage)
            {
                var cell = new S2Cell(cellId);
                for (var i = 0; i <= 3; i++)
                {
                    var vertex = cell.GetVertex(i);
                    var coord  = new S2LatLng(new S2Point(vertex.X, vertex.Y, vertex.Z));
                    //if (geofence.Intersects(coord.LatDegrees, coord.LngDegrees))
                    if (GeofenceService.InPolygon(this, coord.LatDegrees, coord.LngDegrees))
                    {
                        result.Add(cellId);
                    }
                }
            }
            return(result);
        }
コード例 #5
0
        public List <Guid> Search(double lon, double lat, int radius)
        {
            var latlng = S2LatLng.FromDegrees(lat, lon);

            var centerPoint = pointFromLatLng(lat, lon);

            var centerAngle = ((double)radius) / EarthRadiusM;

            var cap = S2Cap.FromAxisAngle(centerPoint, S1Angle.FromRadians(centerAngle));

            var regionCoverer = new S2RegionCoverer();

            regionCoverer.MaxLevel = 13;

            //  regionCoverer.MinLevel = 13;


            //regionCoverer.MaxCells = 1000;
            // regionCoverer.LevelMod = 0;


            var covering = regionCoverer.GetCovering(cap);



            var res = new List <Guid>();


            foreach (var u in covering)
            {
                var sell = new S2CellId(u.Id);

                if (sell.Level < _level)
                {
                    var begin = sell.ChildBeginForLevel(_level);
                    var end   = sell.ChildEndForLevel(_level);
                    do
                    {
                        var cur = tree.Search(new S2CellId(begin.Id));

                        if (cur != null)
                        {
                            res.AddRange(cur.Pointer);
                        }

                        begin = begin.Next;
                    } while (begin.Id != end.Id);
                }
                else
                {
                    var item = tree.Search(sell);
                    if (item != null)
                    {
                        res.AddRange(item.Pointer);
                    }
                }
            }
            return(res);
        }
コード例 #6
0
        public List <Guid> Search(double lon, double lat, int radius)
        {
            var latlng = S2LatLng.FromDegrees(lat, lon);

            var centerPoint = Index.pointFromLatLng(lat, lon);

            var centerAngle = ((double)radius) / Index.EarthRadiusM;

            var cap = S2Cap.FromAxisAngle(centerPoint, S1Angle.FromRadians(centerAngle));

            var regionCoverer = new S2RegionCoverer();

            regionCoverer.MaxLevel = 13;

            //  regionCoverer.MinLevel = 13;


            //regionCoverer.MaxCells = 1000;
            // regionCoverer.LevelMod = 0;


            var covering = regionCoverer.GetCovering(cap);



            var res = new List <Guid>();


            foreach (var u in covering)
            {
                var sell = new S2CellId(u.Id);

                if (sell.Level < _level)
                {
                    var begin = sell.ChildBeginForLevel(_level);
                    var end   = sell.ChildEndForLevel(_level);

                    var qres = rtree.Query(new Range <S2CellId>(begin, end));

                    foreach (var r in qres)
                    {
                        res.AddRange(r.Content);
                    }
                }
                else
                {
                    var qres = rtree.Query(new Range <S2CellId>(sell));
                    if (qres.Count > 0)
                    {
                        foreach (var r in qres)
                        {
                            res.AddRange(r.Content);
                        }
                    }
                }
            }
            return(res);
        }
コード例 #7
0
        public void testRandomCaps()
        {
            Console.WriteLine("TestRandomCaps");

            var kMaxLevel = S2CellId.MaxLevel;
            var coverer   = new S2RegionCoverer();

            for (var i = 0; i < 1000; ++i)
            {
                do
                {
                    coverer.MinLevel = random(kMaxLevel + 1);
                    coverer.MaxLevel = random(kMaxLevel + 1);
                } while (coverer.MinLevel > coverer.MaxLevel);
                coverer.MaxCells = skewed(10);
                coverer.LevelMod = 1 + random(3);
                var maxArea = Math.Min(
                    4 * S2.Pi, (3 * coverer.MaxCells + 1) * S2Cell.AverageArea(coverer.MinLevel));
                var cap      = getRandomCap(0.1 * S2Cell.AverageArea(kMaxLevel), maxArea);
                var covering = new List <S2CellId>();
                var interior = new List <S2CellId>();

                coverer.GetCovering(cap, covering);
                checkCovering(coverer, cap, covering, false);

                coverer.GetInteriorCovering(cap, interior);
                checkCovering(coverer, cap, interior, true);


                // Check that GetCovering is deterministic.
                var covering2 = new List <S2CellId>();
                coverer.GetCovering(cap, covering2);
                assertTrue(covering.SequenceEqual(covering2));

                // Also check S2CellUnion.denormalize(). The denormalized covering
                // may still be different and smaller than "covering" because
                // S2RegionCoverer does not guarantee that it will not output all four
                // children of the same parent.
                var cells = new S2CellUnion();
                cells.InitFromCellIds(covering);
                var denormalized = new List <S2CellId>();
                cells.Denormalize(coverer.MinLevel, coverer.LevelMod, denormalized);
                checkCovering(coverer, cap, denormalized, false);
            }
        }
コード例 #8
0
    public void Test_S2ShapeIndexBufferedRegion_EmptyIndex()
    {
        // Test buffering an empty S2ShapeIndex.
        var         index    = new MutableS2ShapeIndex();
        var         radius   = new S1ChordAngle(S1Angle.FromDegrees(2));
        var         region   = new S2ShapeIndexBufferedRegion(index, radius);
        var         coverer  = new S2RegionCoverer();
        S2CellUnion covering = coverer.GetCovering(region);

        Assert.True(covering.IsEmpty());
    }
コード例 #9
0
        public void Test_S2CellUnion_Expand()
        {
            // This test generates coverings for caps of random sizes, expands
            // the coverings by a random radius, and then make sure that the new
            // covering covers the expanded cap.  It also makes sure that the
            // new covering is not too much larger than expected.

            var coverer = new S2RegionCoverer();

            for (var i = 0; i < 1000; ++i)
            {
                _logger.WriteLine($"Iteration {i}");
                var cap = S2Testing.GetRandomCap(
                    S2Cell.AverageArea(S2.kMaxCellLevel), S2.M_4_PI);

                // Expand the cap area by a random factor whose log is uniformly
                // distributed between 0 and log(1e2).
                var expanded_cap = S2Cap.FromCenterHeight(
                    cap.Center, Math.Min(2.0, Math.Pow(1e2, rnd.RandDouble()) * cap.Height()));

                var radius         = (expanded_cap.Radius - cap.Radius).Radians();
                var max_level_diff = rnd.Uniform(8);

                // Generate a covering for the original cap, and measure the maximum
                // distance from the cap center to any point in the covering.
                coverer.Options_.MaxCells = 1 + rnd.Skewed(10);
                var covering = coverer.GetCovering(cap);
                S2Testing.CheckCovering(cap, covering, true);
                var covering_radius = GetRadius(covering, cap.Center);

                // This code duplicates the logic in Expand(min_radius, max_level_diff)
                // that figures out an appropriate cell level to use for the expansion.
                int min_level = S2.kMaxCellLevel;
                foreach (var id in covering)
                {
                    min_level = Math.Min(min_level, id.Level());
                }
                var expand_level = Math.Min(min_level + max_level_diff,
                                            S2.kMinWidth.GetLevelForMinValue(radius));

                // Generate a covering for the expanded cap, and measure the new maximum
                // distance from the cap center to any point in the covering.
                covering.Expand(S1Angle.FromRadians(radius), max_level_diff);
                S2Testing.CheckCovering(expanded_cap, covering, false);
                double expanded_covering_radius = GetRadius(covering, cap.Center);

                // If the covering includes a tiny cell along the boundary, in theory the
                // maximum angle of the covering from the cap center can increase by up to
                // twice the maximum length of a cell diagonal.
                Assert.True(expanded_covering_radius - covering_radius <=
                            2 * S2.kMaxDiag.GetValue(expand_level));
            }
        }
コード例 #10
0
        public void Test_S2RegionUnionTest_Basic()
        {
            S2RegionUnion ru_empty = new(new List <IS2Region>());

            Assert.Equal(0, ru_empty.Count());
            Assert.Equal(S2Cap.Empty, ru_empty.GetCapBound());
            Assert.Equal(S2LatLngRect.Empty, ru_empty.GetRectBound());
            var empty_clone = (S2RegionUnion)ru_empty.CustomClone();

            var two_point_region = new List <IS2Region>
            {
                new S2PointRegion(S2LatLng.FromDegrees(35, 40).ToPoint()),
                new S2PointRegion(S2LatLng.FromDegrees(-35, -40).ToPoint())
            };

            var two_points_orig = new S2RegionUnion(two_point_region);
            // two_point_region is in a valid, but unspecified, state.

            // Check that Clone() returns a deep copy.
            var two_points = (S2RegionUnion)two_points_orig.CustomClone();

            // The bounds below may not be exactly equal because the S2PointRegion
            // version converts each S2LatLng value to an S2Point and back.
            Assert.True(MakeLatLngRectOrDie("-35:-40,35:40") !.Value
                        .ApproxEquals(two_points.GetRectBound()));

            S2Cell face0 = S2Cell.FromFace(0);

            Assert.True(two_points.MayIntersect(face0));
            Assert.False(two_points.Contains(face0));

            Assert.True(two_points.Contains(S2LatLng.FromDegrees(35, 40).ToPoint()));
            Assert.True(two_points.Contains(S2LatLng.FromDegrees(-35, -40).ToPoint()));
            Assert.False(two_points.Contains(S2LatLng.FromDegrees(0, 0).ToPoint()));

            // Check that we can Add() another region.
            var three_points = (S2RegionUnion)two_points.CustomClone();

            Assert.False(three_points.Contains(S2LatLng.FromDegrees(10, 10).ToPoint()));
            three_points.Add(new S2RegionUnion(new List <IS2Region> {
                new S2PointRegion(S2LatLng.FromDegrees(10, 10).ToPoint())
            }));
            Assert.True(three_points.Contains(S2LatLng.FromDegrees(10, 10).ToPoint()));

            var coverer = new S2RegionCoverer();

            coverer.Options_.MaxCells = 1;
            coverer.GetCovering(two_points, out var covering);
            Assert.Single(covering);
            Assert.Equal(face0.Id, covering[0]);
        }
コード例 #11
0
    public void Test_S2ShapeIndexBufferedRegion_PointZeroRadius()
    {
        // Test that buffering a point using a zero radius produces a non-empty
        // covering.  (This requires using "less than or equal to" distance tests.)
        var         index    = MakeIndexOrDie("34:25 # #");
        var         region   = new S2ShapeIndexBufferedRegion(index, S1ChordAngle.Zero);
        var         coverer  = new S2RegionCoverer();
        S2CellUnion covering = coverer.GetCovering(region);

        Assert.Equal(1, covering.Size());
        foreach (S2CellId id in covering)
        {
            Assert.True(id.IsLeaf());
        }
    }
コード例 #12
0
    public void Test_S2ShapeIndexBufferedRegion_FullPolygon()
    {
        // Test buffering an S2ShapeIndex that contains a full polygon.
        var         index    = MakeIndexOrDie("# # full");
        var         radius   = new S1ChordAngle(S1Angle.FromDegrees(2));
        var         region   = new S2ShapeIndexBufferedRegion(index, radius);
        var         coverer  = new S2RegionCoverer();
        S2CellUnion covering = coverer.GetCovering(region);

        Assert.Equal(6, covering.Size());
        foreach (S2CellId id in covering)
        {
            Assert.True(id.IsFace());
        }
    }
コード例 #13
0
    public void Test_S2ShapeIndexBufferedRegion_FullAfterBuffering()
    {
        // Test a region that becomes the full polygon after buffering.
        var index   = MakeIndexOrDie("0:0 | 0:90 | 0:180 | 0:-90 | 90:0 | -90:0 # #");
        var radius  = new S1ChordAngle(S1Angle.FromDegrees(60));
        var region  = new S2ShapeIndexBufferedRegion(index, radius);
        var coverer = new S2RegionCoverer();

        coverer.Options_.MaxCells = 1000;
        S2CellUnion covering = coverer.GetCovering(region);

        Assert.Equal(6, covering.Size());
        foreach (S2CellId id in covering)
        {
            Assert.True(id.IsFace());
        }
    }
コード例 #14
0
        public void testRandomCells()
        {
            Console.WriteLine("TestRandomCells");

            var coverer = new S2RegionCoverer();

            coverer.MaxCells = 1;

            // Test random cell ids at all levels.
            for (var i = 0; i < 10000; ++i)
            {
                var id       = getRandomCellId();
                var covering = new S2CellUnion();
                coverer.GetCovering(new S2Cell(id), covering.CellIds);
                assertEquals(covering.Count, 1);
                assertEquals(covering.CellId(0), id);
            }
        }
コード例 #15
0
        public void testRandomCaps()
        {
            Console.WriteLine("TestRandomCaps");

            var kMaxLevel = S2CellId.MaxLevel;
            var coverer = new S2RegionCoverer();
            for (var i = 0; i < 1000; ++i)
            {
                do
                {
                    coverer.MinLevel = random(kMaxLevel + 1);
                    coverer.MaxLevel = random(kMaxLevel + 1);
                } while (coverer.MinLevel > coverer.MaxLevel);
                coverer.MaxCells = skewed(10);
                coverer.LevelMod = 1 + random(3);
                var maxArea = Math.Min(
                    4*S2.Pi, (3*coverer.MaxCells + 1)*S2Cell.AverageArea(coverer.MinLevel));
                var cap = getRandomCap(0.1*S2Cell.AverageArea(kMaxLevel), maxArea);
                var covering = new List<S2CellId>();
                var interior = new List<S2CellId>();

                coverer.GetCovering(cap, covering);
                checkCovering(coverer, cap, covering, false);

                coverer.GetInteriorCovering(cap, interior);
                checkCovering(coverer, cap, interior, true);


                // Check that GetCovering is deterministic.
                var covering2 = new List<S2CellId>();
                coverer.GetCovering(cap, covering2);
                assertTrue(covering.SequenceEqual(covering2));

                // Also check S2CellUnion.denormalize(). The denormalized covering
                // may still be different and smaller than "covering" because
                // S2RegionCoverer does not guarantee that it will not output all four
                // children of the same parent.
                var cells = new S2CellUnion();
                cells.InitFromCellIds(covering);
                var denormalized = new List<S2CellId>();
                cells.Denormalize(coverer.MinLevel, coverer.LevelMod, denormalized);
                checkCovering(coverer, cap, denormalized, false);
            }
        }
コード例 #16
0
        private IEnumerable <S2CellId> GetCurrentS2CellIds(GPSLatLong currentLatLong)
        {
            // Info on S2 Geometry - https://s2geometry.io/
            // Code taken from this video - https://www.youtube.com/watch?v=UZsf3bqmmKs  (6:26)
            // Min/Max Level and Max Cells taken from here - https://s2.sidewalklabs.com/regioncoverer/
            // Using Nuget S2Geometry vs 1.0.3 (https://www.nuget.org/packages/S2Geometry/)
            S2RegionCoverer rc = new S2RegionCoverer();

            rc.MaxCells = S2RegionCoverer.DefaultMaxCells;
            rc.MinLevel = rc.MaxLevel = 14;

            // var southwestLat = new GPSLatLong { Latitude = 47.013859, Longitude = -122.920682 };
            // var northeast = new GPSLatLong { Latitude = 47.033532, Longitude = -122.894687 };
            //
            // S2LatLng low = S2LatLng.FromDegrees(southwestLat.Latitude, southwestLat.Longitude);
            // S2LatLng high = S2LatLng.FromDegrees(northeast.Latitude, northeast.Longitude);
            //
            // S2LatLngRect latLngRect = new S2LatLngRect(low, high);
            // return rc.GetCovering(latLngRect);


            //// https://stackoverflow.com/questions/7477003/calculating-new-longitude-latitude-from-old-n-meters
            //// number of km per degree = ~111km (111.32 in google maps, but range varies
            //// between 110.567km at the equator and 111.699km at the poles)
            //// 1km in degree = 1 / 111.32km = 0.0089
            //// 1m in degree = 0.0089 / 1000 = 0.0000089
            double meters   = this.loadRadiusInMeters;
            double coef     = meters * 0.0000089;
            double new_lat  = /*currentLatLong.Latitude +*/ coef;
            double new_long = /*currentLatLong.Longitude +*/ coef / Math.Cos(currentLatLong.Latitude * (Math.PI / 180.0));

            S2LatLng center = S2LatLng.FromDegrees(currentLatLong.Latitude, currentLatLong.Longitude);
            S2LatLng size   = S2LatLng.FromDegrees(new_lat, new_long);

            return(rc.GetCovering(S2LatLngRect.FromCenterSize(center, size)));
        }
コード例 #17
0
        public void testRandomCells()
        {
            Console.WriteLine("TestRandomCells");

            var coverer = new S2RegionCoverer();
            coverer.MaxCells = 1;

            // Test random cell ids at all levels.
            for (var i = 0; i < 10000; ++i)
            {
                var id = getRandomCellId();
                var covering = new S2CellUnion();
                coverer.GetCovering(new S2Cell(id), covering.CellIds);
                assertEquals(covering.Count, 1);
                assertEquals(covering.CellId(0), id);
            }
        }
コード例 #18
0
        public List <Guid> Search(double lon, double lat, int radius)
        {
            lock (locker)
            {
                var latlng = S2LatLng.FromDegrees(lat, lon);

                var centerPoint = pointFromLatLng(lat, lon);

                var centerAngle = ((double)radius) / EarthRadiusM;

                var cap = S2Cap.FromAxisAngle(centerPoint, S1Angle.FromRadians(centerAngle));

                var regionCoverer = new S2RegionCoverer();

                regionCoverer.MaxLevel = 13;

                //  regionCoverer.MinLevel = 13;


                //regionCoverer.MaxCells = 1000;
                // regionCoverer.LevelMod = 0;


                var covering = regionCoverer.GetCovering(cap);



                var res = new List <Guid>();


                foreach (var u in covering)
                {
                    var sell = new S2CellId(u.Id);

                    if (sell.Level < _level)
                    {
                        var begin = sell.ChildBeginForLevel(_level);
                        var end   = sell.ChildEndForLevel(_level);

                        var qres = rtree.Search(new Interval <UserList>(new UserList()
                        {
                            s2CellId = begin
                        }, new UserList()
                        {
                            s2CellId = end
                        }));


                        foreach (var item in qres)
                        {
                            res.AddRange(item.Start.list);
                        }
                    }
                    else
                    {
                        var qres = rtree.Search(new UserList()
                        {
                            s2CellId = sell
                        });
                        if (qres.Count > 0)
                        {
                            foreach (var r in qres)
                            {
                                res.AddRange(r.Start.list);
                            }
                        }
                    }
                }
                return(res);
            }
        }
コード例 #19
0
    private void TestRandomCaps(S2RegionTermIndexer.Options options, QueryType query_type)
    {
        // This function creates an index consisting either of points (if
        // options.index_contains_points_only() is true) or S2Caps of random size.
        // It then executes queries consisting of points (if query_type == POINT)
        // or S2Caps of random size (if query_type == CAP).
        var indexer = new S2RegionTermIndexer(options);
        var coverer = new S2RegionCoverer(options);
        var caps = new List <S2Cap>();
        var coverings = new List <S2CellUnion>();
        var index = new Dictionary <string, List <int> >();
        int index_terms = 0, query_terms = 0;

        for (int i = 0; i < iters; ++i)
        {
            // Choose the region to be indexed: either a single point or a cap
            // of random size (up to a full sphere).
            S2Cap         cap;
            List <string> terms;
            if (options.IndexContainsPointsOnly)
            {
                cap   = S2Cap.FromPoint(S2Testing.RandomPoint());
                terms = indexer.GetIndexTerms(cap.Center, "");
            }
            else
            {
                cap = S2Testing.GetRandomCap(
                    0.3 * S2Cell.AverageArea(options.MaxLevel),
                    4.0 * S2Cell.AverageArea(options.MinLevel));
                terms = indexer.GetIndexTerms(cap, "");
            }
            caps.Add(cap);
            coverings.Add(coverer.GetCovering(cap));
            foreach (var term in terms)
            {
                if (!index.ContainsKey(term))
                {
                    index.Add(term, new List <int>());
                }

                index[term].Add(i);
            }
            index_terms += terms.Count;
        }
        for (int i = 0; i < iters; ++i)
        {
            // Choose the region to be queried: either a random point or a cap of
            // random size.
            S2Cap         cap;
            List <string> terms;
            if (query_type == QueryType.CAP)
            {
                cap   = S2Cap.FromPoint(S2Testing.RandomPoint());
                terms = indexer.GetQueryTerms(cap.Center, "");
            }
            else
            {
                cap = S2Testing.GetRandomCap(
                    0.3 * S2Cell.AverageArea(options.MaxLevel),
                    4.0 * S2Cell.AverageArea(options.MinLevel));
                terms = indexer.GetQueryTerms(cap, "");
            }
            // Compute the expected results of the S2Cell query by brute force.
            S2CellUnion covering = coverer.GetCovering(cap);
            var         expected = new List <int>();
            var         actual   = new List <int>();
            for (int j = 0; j < caps.Count; ++j)
            {
                if (covering.Intersects(coverings[j]))
                {
                    expected.Add(j);
                }
            }
            foreach (var term in terms)
            {
                actual.AddRange(index[term]);
            }
            Assert.Equal(expected, actual);
            query_terms += terms.Count;
        }
        _logger.WriteLine($"Index terms/doc: {((double)index_terms) / iters:2f},  Query terms/doc: {((double)query_terms) / iters:2f}");
    }
コード例 #20
0
        private async Task <BootstrapTask> GetBootstrapTask()
        {
            ulong target;

            lock (_bootstrapLock)
            {
                target = _bootstrapCellIds.FirstOrDefault();
                if (target == default)
                {
                    return(null);
                }
                _bootstrapCellIds.Remove(target);
            }

            var cell   = new S2Cell(new S2CellId(target));
            var latlng = new S2LatLng(cell.Center);

            double radius;

            if (latlng.LatDegrees <= 39)
            {
                radius = 715;
            }
            else if (latlng.LatDegrees >= 69)
            {
                radius = 330;
            }
            else
            {
                radius = (-13 * latlng.LatDegrees) + 1225;
            }

            var radians = radius / 6378137;
            var centerNormalizedPoint = latlng.Normalized.ToPoint();
            var circle  = S2Cap.FromAxisHeight(centerNormalizedPoint, (radians * radians) / 2);
            var coverer = new S2RegionCoverer
            {
                MinLevel = 15,
                MaxLevel = 15,
                MaxCells = 100
            };
            var nearbyCellIds = coverer.GetCovering(circle).Select(x => x.Id);

            lock (_bootstrapCellIds)
            {
                _bootstrapCellIds.RemoveAll(cell => nearbyCellIds.Contains(cell));
            }
            if (_bootstrapCellIds.Count == 0)
            {
                await Bootstrap().ConfigureAwait(false);

                if (_bootstrapCellIds.Count == 0)
                {
                    await Update().ConfigureAwait(false);
                }
            }
            return(new BootstrapTask
            {
                Action = ActionType.ScanRaid,
                Area = Name,
                Latitude = latlng.LatDegrees,
                Longitude = latlng.LngDegrees,
                MinimumLevel = MinimumLevel,
                MaximumLevel = MaximumLevel,
            });
        }
コード例 #21
0
        async void Load_Click(object sender, RoutedEventArgs e)
        {
            var picker = new Windows.Storage.Pickers.FileOpenPicker();

            picker.ViewMode = Windows.Storage.Pickers.PickerViewMode.Thumbnail;
            picker.SuggestedStartLocation = Windows.Storage.Pickers.PickerLocationId.PicturesLibrary;
            picker.FileTypeFilter.Add(".geojson");
            picker.FileTypeFilter.Add(".geoJSON");
            picker.FileTypeFilter.Add(".csv");

            Windows.Storage.StorageFile file = await picker.PickSingleFileAsync();

            if (file != null)
            {
                try
                {
                    using (StreamReader sr = new StreamReader(file.Path))
                    {
                        string content = sr.ReadToEnd();
                        if (file.FileType == ".csv")
                        {
                            string[] lines = content.Split('\n');
                            for (int i = 0; i < lines.Length; i++)
                            {
                                var item = lines[i];

                                if (String.IsNullOrWhiteSpace(item))
                                {
                                    continue;
                                }

                                string[] info = item.Split(',');
                                double   lat  = 0;
                                double   lon  = 0;

                                if (!Double.TryParse(info[info.Length - 2], out lon) || !Double.TryParse(info[info.Length - 3], out lat))
                                {
                                    if (i == 0)
                                    {
                                        continue;
                                    }
                                    var messageDialog = new MessageDialog("Zeile " + i + " (" + item + ") hat nicht das richtige Format!");
                                    messageDialog.Commands.Add(new UICommand("OK", new UICommandInvokedHandler(this.CommandInvokedHandler)));
                                    messageDialog.DefaultCommandIndex = 0;
                                    messageDialog.Title = "Fehlerhafte Datei";
                                    await messageDialog.ShowAsync();

                                    return;
                                }

                                StringBuilder sb = new StringBuilder("");

                                for (int j = 0; j < info.Length - 3; j++)
                                {
                                    sb.Append(info[j]);
                                }

                                PointOfInterest poi = new PointOfInterest()
                                {
                                    Location = new Geopoint(new BasicGeoposition()
                                    {
                                        Latitude = lat, Longitude = lon
                                    }),
                                    DisplayName           = sb.ToString(),
                                    NormalizedAnchorPoint = AnchorPoints[2],
                                    Flag = PointOfInterest.PORTAL,
                                    Leaf = FindExactCell(new BasicGeoposition()
                                    {
                                        Latitude = lat, Longitude = lon
                                    }, 30).Id.Id
                                };

                                portals.Add(poi);
                                //DataAccess.AddData(poi);
                            }
                        }
                        else
                        {
                            var features = JsonConvert.DeserializeObject <FeatureCollection>(content).Features;

                            foreach (var p in features)
                            {
                                double lon  = ((Point)p.Geometry).Coordinates.Longitude;
                                double lat  = ((Point)p.Geometry).Coordinates.Latitude;
                                int    flag = PointOfInterest.PORTAL;
                                if (p.Properties.ContainsKey("Flag"))
                                {
                                    flag = (int)p.Properties["Flag"];
                                }

                                PointOfInterest poi = new PointOfInterest()
                                {
                                    Location = new Geopoint(new BasicGeoposition()
                                    {
                                        Latitude = lat, Longitude = lon
                                    }),
                                    DisplayName           = (string)p.Properties["name"],
                                    NormalizedAnchorPoint = AnchorPoints[flag],
                                    Flag = flag,
                                    Leaf = FindExactCell(new BasicGeoposition()
                                    {
                                        Latitude = lat, Longitude = lon
                                    }, 30).Id.Id
                                };

                                portals.Add(poi);
                                //DataAccess.AddData(poi);
                            }
                        }
                        AddLayers();
                    }
                }
                catch (UnauthorizedAccessException)
                {
                    Windows.Storage.StorageFolder installedLocation = Windows.ApplicationModel.Package.Current.InstalledLocation;
                    var messageDialog = new MessageDialog("Zugriff auf den Pfad " + file.Path +
                                                          " wurde verweigert.\nBitte gewähren Sie Zugriff unter \n\nEinstellungen -> Privatsphäre -> Dateisystem\n\noder bewegen Sie die Datei an diesen Ort:\n"
                                                          + installedLocation.Path);
                    messageDialog.Commands.Add(new UICommand("OK", new UICommandInvokedHandler(this.CommandInvokedHandler)));
                    messageDialog.DefaultCommandIndex = 0;
                    messageDialog.Title = "Keine Zugriffsrechte";
                    await messageDialog.ShowAsync();

                    return;
                }

                // outermost bounds
                double maxLat = -360;
                double maxLon = -360;
                double minLat = 360;
                double minLon = 360;

                // Find out all Lvl17 cells
                foreach (var p in portals)
                {
                    double lat = p.Location.Position.Latitude;
                    double lon = p.Location.Position.Longitude;

                    if (lon < minLon)
                    {
                        minLon = lon;
                    }
                    if (lon > maxLon)
                    {
                        maxLon = lon;
                    }
                    if (lat < minLat)
                    {
                        minLat = lat;
                    }
                    if (lat > maxLat)
                    {
                        maxLat = lat;
                    }

                    var cell = FindExactCell(p.Location.Position, 17);

                    MapPolygon polygon = new MapPolygon
                    {
                        Path = new Geopath(new List <BasicGeoposition>()
                        {
                            FromS2Point(cell.GetVertex(0)),
                            FromS2Point(cell.GetVertex(1)),
                            FromS2Point(cell.GetVertex(2)),
                            FromS2Point(cell.GetVertex(3))
                        }),

                        ZIndex          = 1,
                        FillColor       = Color.FromArgb(50, 50, 50, 50),
                        StrokeColor     = Colors.Black,
                        StrokeThickness = 2,
                        StrokeDashed    = false
                    };
                    lvl17Cells.Add(polygon);
                    AddCell(polygon);
                }

                // Find out Lvl14 cells
                var area = S2LatLngRect.FromPointPair(
                    S2LatLng.FromDegrees(minLat, minLon),
                    S2LatLng.FromDegrees(maxLat, maxLon)
                    );

                var cells14 = new List <S2CellId>();
                lvl14Coverer.GetCovering(area, cells14);

                for (int i = 0; i < cells14.Count; i++)
                {
                    S2Cell cell = new S2Cell(cells14[i]);

                    MapPolygon polygon = new MapPolygon
                    {
                        Path = new Geopath(new List <BasicGeoposition>()
                        {
                            FromS2Point(cell.GetVertex(0)),
                            FromS2Point(cell.GetVertex(1)),
                            FromS2Point(cell.GetVertex(2)),
                            FromS2Point(cell.GetVertex(3))
                        }),

                        ZIndex          = 1,
                        FillColor       = Color.FromArgb(50, 0, 0, 50),
                        StrokeColor     = Colors.Blue,
                        StrokeThickness = 2,
                        StrokeDashed    = false
                    };
                    lvl14Cells.Add(polygon);
                    AddCell(polygon);
                }

                BasicGeoposition newCenter = new BasicGeoposition();
                newCenter.Latitude  = (minLat + maxLat) / 2;
                newCenter.Longitude = (minLon + maxLon) / 2;
                PokeMap.Center      = new Geopoint(newCenter);
            }
        }