public void Test_S2CellUnion_FromMinMax() { // Check the very first leaf cell and face cell. S2CellId face1_id = S2CellId.FromFace(0); TestFromMinMax(face1_id.RangeMin(), face1_id.RangeMin()); TestFromMinMax(face1_id.RangeMin(), face1_id.RangeMax()); // Check the very last leaf cell and face cell. S2CellId face5_id = S2CellId.FromFace(5); TestFromMinMax(face5_id.RangeMin(), face5_id.RangeMax()); TestFromMinMax(face5_id.RangeMax(), face5_id.RangeMax()); // Check random ranges of leaf cells. for (int iter = 0; iter < 100; ++iter) { S2CellId x = S2Testing.GetRandomCellId(S2.kMaxCellLevel); S2CellId y = S2Testing.GetRandomCellId(S2.kMaxCellLevel); if (x > y) { var tmp = x; x = y; y = tmp; } TestFromMinMax(x, y); } }
public void Test_S2CellId_ParentChildRelationships() { S2CellId id = S2CellId.FromFacePosLevel(3, 0x12345678, S2.kMaxCellLevel - 4); Assert.True(id.IsValid()); Assert.Equal(3UL, id.Face()); Assert.Equal(0x12345700UL, id.Pos()); Assert.Equal(S2.kMaxCellLevel - 4, id.Level()); Assert.False(id.IsLeaf()); Assert.Equal(0x12345610UL, id.ChildBegin(id.Level() + 2).Pos()); Assert.Equal(0x12345640UL, id.ChildBegin().Pos()); Assert.Equal(0x12345400UL, id.Parent().Pos()); Assert.Equal(0x12345000UL, id.Parent(id.Level() - 2).Pos()); // Check ordering of children relative to parents. Assert.True(id.ChildBegin() < id); Assert.True(id.ChildEnd() > id); Assert.Equal(id.ChildEnd(), id.ChildBegin().Next().Next().Next().Next()); Assert.Equal(id.RangeMin(), id.ChildBegin(S2.kMaxCellLevel)); Assert.Equal(id.RangeMax().Next(), id.ChildEnd(S2.kMaxCellLevel)); // Check that cells are represented by the position of their center // along the Hilbert curve. Assert.Equal(2 * id.Id, id.RangeMin().Id + id.RangeMax().Id); }
// Let T be the target S2CellId. If T is contained by some index cell I // (including equality), this method positions the iterator at I and // returns INDEXED. Otherwise if T contains one or more (smaller) index // cells, it positions the iterator at the first such cell I and returns // SUBDIVIDED. Otherwise it returns DISJOINT. public (CellRelation cellRelation, int pos) LocateCell(S2CellId target) { // Let T be the target, let I = cell_map_.GetLowerBound(T.RangeMin), and // let I' be the predecessor of I. If T contains any index cells, then T // contains I. Similarly, if T is contained by an index cell, then the // containing cell is either I or I'. We test for containment by comparing // the ranges of leaf cells spanned by T, I, and I'. var(pos, _) = SeekCell(target.RangeMin()); var id = GetCellId(pos); if (id is not null) { if (id >= target && id.Value.RangeMin() <= target) { return(CellRelation.INDEXED, pos); } if (id <= target.RangeMax()) { return(CellRelation.SUBDIVIDED, pos); } } if (--pos >= 0) { id = GetCellId(pos); if (id != null && id.Value.RangeMax() >= target) { return(CellRelation.INDEXED, pos); } } return(CellRelation.DISJOINT, 0); }
// Replaces all descendants of "id" in "covering" with "id". // REQUIRES: "covering" contains at least one descendant of "id". private static void ReplaceCellsWithAncestor(List <S2CellId> covering, S2CellId id) { var begin = covering.GetLowerBound(id.RangeMin()); var end = covering.GetUpperBound(id.RangeMax()); System.Diagnostics.Debug.Assert(begin != end); covering.RemoveRange(begin + 1, end); covering[begin] = id; }