/** * 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); } } }
// Like GetSimpleCovering(), but accepts a starting S2CellId rather than a // starting point and cell level. Returns all edge-connected cells at the // same level as "start" that intersect "region", in arbitrary order. public static void FloodFill(IS2Region region, S2CellId start, List <S2CellId> output) { var all = new List <(S2CellId, int)>(); var frontier = new List <S2CellId>(); output.Clear(); all.Add((start, start.GetHashCode())); frontier.Add(start); while (frontier.Any()) { S2CellId id = frontier.Last(); frontier.RemoveAt(frontier.Count - 1); if (!region.MayIntersect(new S2Cell(id))) { continue; } output.Add(id); var neighbors = new S2CellId[4]; id.EdgeNeighbors(neighbors); for (int edge = 0; edge < 4; ++edge) { var nbr = neighbors[edge]; var hash = nbr.GetHashCode(); all.Add((nbr, hash)); if (hash != 0) { frontier.Add(nbr); } } } }
/** * Given a region and a starting cell, return the set of all the * edge-connected cells at the same level that intersect "region". The output * cells are returned in arbitrary order. */ private static void FloodFill(IS2Region region, S2CellId start, List <S2CellId> output) { var all = new HashSet <S2CellId>(); var frontier = new List <S2CellId>(); output.Clear(); all.Add(start); frontier.Add(start); while (frontier.Any()) { var id = frontier[frontier.Count - 1]; frontier.RemoveAt(frontier.Count - 1); if (!region.MayIntersect(new S2Cell(id))) { continue; } output.Add(id); var neighbors = id.GetEdgeNeighbors(); for (var edge = 0; edge < 4; ++edge) { var nbr = neighbors[edge]; var hasNbr = all.Contains(nbr); if (!all.Contains(nbr)) { frontier.Add(nbr); all.Add(nbr); } } } }