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); } }
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); }