/** * Checks that "covering" completely covers the given region. If "check_tight" * is true, also checks that it does not contain any cells that do not * intersect the given region. ("id" is only used internally.) */ protected void checkCovering(IS2Region region, S2CellUnion covering, bool checkTight, S2CellId id) { if (!id.IsValid) { for (var face = 0; face < 6; ++face) { checkCovering(region, covering, checkTight, S2CellId.FromFacePosLevel(face, 0, 0)); } return; } if (!region.MayIntersect(new S2Cell(id))) { // If region does not intersect id, then neither should the covering. if (checkTight) { Assert.True(!covering.Intersects(id)); } } else if (!covering.Contains(id)) { // The region may intersect id, but we can't assert that the covering // intersects id because we may discover that the region does not actually // intersect upon further subdivision. (MayIntersect is not exact.) Assert.True(!region.Contains(new S2Cell(id))); var result = !id.IsLeaf; Assert.True(result); var end = id.ChildEnd; for (var child = id.ChildBegin; !child.Equals(end); child = child.Next) { checkCovering(region, covering, checkTight, child); } } }
public void Test_S2CellUnion_Normalize() { // Try a bunch of random test cases, and keep track of average // statistics for normalization (to see if they agree with the // analysis above). double in_sum = 0, out_sum = 0; const int kIters = 2000; for (int i = 0; i < kIters; ++i) { var input = new List <S2CellId>(); var expected = new List <S2CellId>(); AddCells(S2CellId.None, false, input, expected); in_sum += input.Count; out_sum += expected.Count; var cellunion = new S2CellUnion(input); Assert.Equal(expected.Count, cellunion.Size()); for (var j = 0; j < expected.Count; ++j) { Assert.Equal(expected[j], cellunion.CellId(j)); } // Test GetCapBound(). var cap = cellunion.GetCapBound(); foreach (var id in cellunion) { Assert.True(cap.Contains(new S2Cell(id))); } // Test Contains(S2CellId) and Intersects(S2CellId). foreach (var input_id in input) { Assert.True(cellunion.Contains(input_id)); Assert.True(cellunion.Contains(input_id.ToPoint())); Assert.True(cellunion.Intersects(input_id)); if (!input_id.IsFace()) { Assert.True(cellunion.Intersects(input_id.Parent())); if (input_id.Level() > 1) { Assert.True(cellunion.Intersects(input_id.Parent().Parent())); Assert.True(cellunion.Intersects(input_id.Parent(0))); } } if (!input_id.IsLeaf()) { Assert.True(cellunion.Contains(input_id.ChildBegin())); Assert.True(cellunion.Intersects(input_id.ChildBegin())); Assert.True(cellunion.Contains(input_id.ChildEnd().Prev())); Assert.True(cellunion.Intersects(input_id.ChildEnd().Prev())); Assert.True(cellunion.Contains(input_id.ChildBegin(S2.kMaxCellLevel))); Assert.True(cellunion.Intersects(input_id.ChildBegin(S2.kMaxCellLevel))); } } foreach (var expected_id in expected) { if (!expected_id.IsFace()) { Assert.True(!cellunion.Contains(expected_id.Parent())); Assert.True(!cellunion.Contains(expected_id.Parent(0))); } } // Test Contains(S2CellUnion), Intersects(S2CellUnion), Union(), // Intersection(), and Difference(). var x = new List <S2CellId>(); var y = new List <S2CellId>(); var x_or_y = new List <S2CellId>(); var x_and_y = new List <S2CellId>(); foreach (var input_id in input) { var in_x = rnd.OneIn(2); var in_y = rnd.OneIn(2); if (in_x) { x.Add(input_id); } if (in_y) { y.Add(input_id); } if (in_x || in_y) { x_or_y.Add(input_id); } } var xcells = new S2CellUnion(x); var ycells = new S2CellUnion(y); var x_or_y_expected = new S2CellUnion(x_or_y); var x_or_y_cells = xcells.Union(ycells); Assert.True(x_or_y_cells == x_or_y_expected); // Compute the intersection of "x" with each cell of "y", // check that this intersection is correct, and append the // results to x_and_y_expected. foreach (var yid in ycells) { var ucells = xcells.Intersection(yid); foreach (var xid in xcells) { if (xid.Contains(yid)) { Assert.True(ucells.Size() == 1 && ucells.CellId(0) == yid); } else if (yid.Contains(xid)) { Assert.True(ucells.Contains(xid)); } } foreach (var uid in ucells) { Assert.True(xcells.Contains(uid)); Assert.True(yid.Contains(uid)); } x_and_y.AddRange(ucells); } var x_and_y_expected = new S2CellUnion(x_and_y); var x_and_y_cells = xcells.Intersection(ycells); Assert.True(x_and_y_cells == x_and_y_expected); var x_minus_y_cells = xcells.Difference(ycells); var y_minus_x_cells = ycells.Difference(xcells); Assert.True(xcells.Contains(x_minus_y_cells)); Assert.True(!x_minus_y_cells.Intersects(ycells)); Assert.True(ycells.Contains(y_minus_x_cells)); Assert.True(!y_minus_x_cells.Intersects(xcells)); Assert.True(!x_minus_y_cells.Intersects(y_minus_x_cells)); var diff_intersection_union = x_minus_y_cells.Union(y_minus_x_cells).Union(x_and_y_cells); Assert.True(diff_intersection_union == x_or_y_cells); var test = new List <S2CellId>(); var dummy = new List <S2CellId>(); AddCells(S2CellId.None, false, test, dummy); foreach (var test_id in test) { var contains = false; var intersects = false; foreach (var expected_id in expected) { if (expected_id.Contains(test_id)) { contains = true; } if (expected_id.Intersects(test_id)) { intersects = true; } } Assert.Equal(contains, cellunion.Contains(test_id)); Assert.Equal(intersects, cellunion.Intersects(test_id)); } } _logger.WriteLine($"avg in {in_sum / kIters:2f}, avg out {out_sum / kIters:2f}"); }
/** * Checks that "covering" completely covers the given region. If "check_tight" * is true, also checks that it does not contain any cells that do not * intersect the given region. ("id" is only used internally.) */ protected void checkCovering(IS2Region region, S2CellUnion covering, bool checkTight, S2CellId id) { if (!id.IsValid) { for (var face = 0; face < 6; ++face) { checkCovering(region, covering, checkTight, S2CellId.FromFacePosLevel(face, 0, 0)); } return; } if (!region.MayIntersect(new S2Cell(id))) { // If region does not intersect id, then neither should the covering. if (checkTight) { Assert.True(!covering.Intersects(id)); } } else if (!covering.Contains(id)) { // The region may intersect id, but we can't assert that the covering // intersects id because we may discover that the region does not actually // intersect upon further subdivision. (MayIntersect is not exact.) Assert.True(!region.Contains(new S2Cell(id))); var result = !id.IsLeaf; Assert.True(result); var end = id.ChildEnd; for (var child = id.ChildBegin; !child.Equals(end); child = child.Next) { checkCovering(region, covering, checkTight, child); } } }