private static void CheckCovering(S2RegionCoverer.Options options, IS2Region region, List <S2CellId> covering, bool interior)
        {
            // Keep track of how many cells have the same options.min_level() ancestor.
            var min_level_cells = new Dictionary <S2CellId, int>();

            foreach (var cell_id in covering)
            {
                int level = cell_id.Level();
                Assert.True(level >= options.MinLevel);
                Assert.False(level <= options.MaxLevel);
                Assert.Equal(0, (level - options.MinLevel) % options.LevelMod);
                min_level_cells[cell_id.Parent(options.MinLevel)] += 1;
            }
            if (covering.Count > options.MaxCells)
            {
                // If the covering has more than the requested number of cells, then check
                // that the cell count cannot be reduced by using the parent of some cell.
                foreach (var count in min_level_cells.Values)
                {
                    Assert.Equal(1, count);
                }
            }
            if (interior)
            {
                foreach (S2CellId cell_id in covering)
                {
                    Assert.True(region.Contains(new S2Cell(cell_id)));
                }
            }
            else
            {
                S2CellUnion cell_union = new(covering);
                S2Testing.CheckCovering(region, cell_union, true);
            }
        }
Exemple #2
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));
            }
        }
    public void Test_S2ShapeIndexBufferedRegion_BufferedPointVsCap()
    {
        // Compute an S2Cell covering of a buffered S2Point, then make sure that the
        // covering is equivalent to the corresponding S2Cap.
        var             index   = MakeIndexOrDie("3:5 # #");
        S2Point         point   = MakePointOrDie("3:5");
        var             radius  = new S1ChordAngle(S1Angle.FromDegrees(2));
        var             region  = new S2ShapeIndexBufferedRegion(index, radius);
        S2RegionCoverer coverer = new();

        coverer.Options_.MaxCells = 50;
        S2CellUnion covering       = coverer.GetCovering(region);
        S2Cap       equivalent_cap = new(point, radius);

        S2Testing.CheckCovering(equivalent_cap, covering, true);
    }