示例#1
0
    /// <summary>
    /// Converts a string in the format returned by ToString() to an S2CellId.
    /// Returns S2CellId.None if the string could not be parsed.
    ///
    /// The method name includes "Debug" in order to avoid possible confusion
    /// with FromToken() above.
    /// </summary>
    private static S2CellId S2CellId_FromDebugString(string str)
    {
        // This function is reasonably efficient, but is only intended for use in
        // tests.
        var level = str.Length - 2;

        if (level < 0 || level > S2.kMaxCellLevel)
        {
            return(S2CellId.None);
        }

        var face = (int)char.GetNumericValue(str[0]);

        if (face < 0 || face > 5 || str[1] != '/')
        {
            return(S2CellId.None);
        }

        var id = S2CellId.FromFace(face);

        for (var i = 2; i < str.Length; i++)
        {
            var child_pos = (int)char.GetNumericValue(str[i]);
            if (child_pos < 0 || child_pos > 3)
            {
                return(S2CellId.None);
            }
            id = id.Child(child_pos);
        }
        return(id);
    }
示例#2
0
        public void Test_S2CellId_Advance()
        {
            S2CellId id = S2CellId.FromFacePosLevel(3, 0x12345678,
                                                    S2.kMaxCellLevel - 4);

            // Check basic properties of advance().
            Assert.Equal(S2CellId.End(0), S2CellId.Begin(0).Advance(7));
            Assert.Equal(S2CellId.End(0), S2CellId.Begin(0).Advance(12));
            Assert.Equal(S2CellId.Begin(0), S2CellId.End(0).Advance(-7));
            Assert.Equal(S2CellId.Begin(0), S2CellId.End(0).Advance(-12000000));
            int num_level_5_cells = 6 << (2 * 5);

            Assert.Equal(S2CellId.End(5).Advance(500 - num_level_5_cells),
                         S2CellId.Begin(5).Advance(500));
            Assert.Equal(id.Next().ChildBegin(S2.kMaxCellLevel),
                         id.ChildBegin(S2.kMaxCellLevel).Advance(256));
            Assert.Equal(S2CellId.FromFacePosLevel(5, 0, S2.kMaxCellLevel),
                         S2CellId.FromFacePosLevel(1, 0, S2.kMaxCellLevel)
                         .Advance((long)(4UL << (2 * S2.kMaxCellLevel))));

            // Check basic properties of advance_wrap().
            Assert.Equal(S2CellId.FromFace(1), S2CellId.Begin(0).AdvanceWrap(7));
            Assert.Equal(S2CellId.Begin(0), S2CellId.Begin(0).AdvanceWrap(12));
            Assert.Equal(S2CellId.FromFace(4), S2CellId.FromFace(5).AdvanceWrap(-7));
            Assert.Equal(S2CellId.Begin(0), S2CellId.Begin(0).AdvanceWrap(-12000000));
            Assert.Equal(S2CellId.Begin(5).AdvanceWrap(6644),
                         S2CellId.Begin(5).AdvanceWrap(-11788));
            Assert.Equal(id.Next().ChildBegin(S2.kMaxCellLevel),
                         id.ChildBegin(S2.kMaxCellLevel).AdvanceWrap(256));
            Assert.Equal(S2CellId.FromFacePosLevel(1, 0, S2.kMaxCellLevel),
                         S2CellId.FromFacePosLevel(5, 0, S2.kMaxCellLevel)
                         .AdvanceWrap((long)(2UL << (2 * S2.kMaxCellLevel))));
        }
示例#3
0
 public void Test_S2CellId_ToString()
 {
     Assert.Equal("3/", S2CellId.FromFace(3).ToString());
     Assert.Equal("4/000000000000000000000000000000",
                  S2CellId.FromFace(4).RangeMin().ToString());
     Assert.Equal("Invalid: 0000000000000000", S2CellId.None.ToString());
 }
示例#4
0
        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);
            }
        }
示例#5
0
 public void Test_S2CellId_FromFace()
 {
     for (int face = 0; face < 6; ++face)
     {
         Assert.Equal(S2CellId.FromFacePosLevel(face, 0, 0), S2CellId.FromFace(face));
     }
 }
示例#6
0
 public void Test_S2CellUnion_ToStringOneCell()
 {
     Assert.Equal(new S2CellUnion(new List <S2CellId> {
         S2CellId.FromFace(1)
     }).ToString(),
                  "Size:1 S2CellIds:3");
 }
示例#7
0
        public void Test_S2CellId_Containment()
        {
            // Test contains() and intersects().
            var parent_map = new Dictionary <S2CellId, S2CellId>();
            var cells      = new List <S2CellId>();

            for (int face = 0; face < 6; ++face)
            {
                ExpandCell(S2CellId.FromFace(face), cells, parent_map);
            }
            foreach (var end_id in cells)
            {
                foreach (var begin_id in cells)
                {
                    bool contained = true;
                    for (var id = begin_id; id != end_id; id = parent_map[id])
                    {
                        if (!parent_map.ContainsKey(id))
                        {
                            contained = false;
                            break;
                        }
                    }
                    Assert.Equal(contained, end_id.Contains(begin_id));
                    Assert.Equal(contained,
                                 begin_id >= end_id.RangeMin() &&
                                 begin_id <= end_id.RangeMax());
                    Assert.Equal(end_id.Intersects(begin_id),
                                 end_id.Contains(begin_id) || begin_id.Contains(end_id));
                }
            }
        }
示例#8
0
        public void Test_S2CellUnion_FromBeginEnd()
        {
            // Since FromMinMax() is implemented in terms of FromBeginEnd(), we
            // focus on test cases that generate an empty range.
            S2CellId initial_id = S2CellId.FromFace(3);

            // Test an empty range before the minimum S2CellId.
            S2CellUnion cell_union = new(new List <S2CellId> {
                initial_id
            });
            S2CellId id_begin      = S2CellId.Begin(S2.kMaxCellLevel);

            cell_union.InitFromBeginEnd(id_begin, id_begin);
            Assert.True(cell_union.IsEmpty());

            // Test an empty range after the maximum S2CellId.
            cell_union = new S2CellUnion(new List <S2CellId> {
                initial_id
            });
            S2CellId id_end = S2CellId.End(S2.kMaxCellLevel);

            cell_union.InitFromBeginEnd(id_end, id_end);
            Assert.True(cell_union.IsEmpty());

            // Test the full sphere.
            cell_union = S2CellUnion.FromBeginEnd(id_begin, id_end);
            Assert.Equal(6, cell_union.Size());
            foreach (S2CellId id in cell_union)
            {
                Assert.True(id.IsFace());
            }
        }
示例#9
0
 public void Test_S2CellUnion_ToStringTwoCells()
 {
     Assert.Equal(
         new S2CellUnion(new List <S2CellId> {
         S2CellId.FromFace(1), S2CellId.FromFace(2)
     }).ToString(),
         "Size:2 S2CellIds:3,5");
 }
示例#10
0
    public void Test_MakeCellUnion_ValidInput()
    {
        Assert.True(MakeCellUnion("1/3, 4/", out var cellUnion));
        var expected = new S2CellUnion(new List <S2CellId> {
            S2CellId.FromFace(1).Child(3), S2CellId.FromFace(4)
        });

        Assert.Equal(cellUnion, expected);
    }
    public void Test_EncodedS2CellIdVector_SixFaceCells()
    {
        List <S2CellId> ids = new();

        for (int face = 0; face < 6; ++face)
        {
            ids.Add(S2CellId.FromFace(face));
        }
        TestEncodedS2CellIdVector(ids, 8);
    }
示例#12
0
        public void Test_S2CellUnion_S2CellIdConstructor()
        {
            var face1_id    = S2CellId.FromFace(1);
            var face1_union = new S2CellUnion(new List <S2CellId> {
                face1_id
            });

            Assert.Equal(1, face1_union.Size());
            Assert.Equal(face1_id, face1_union.CellId(0));
        }
示例#13
0
        public void Test_S2CellUnion_WorksInContainers()
        {
            var ids = new List <S2CellId> {
                S2CellId.FromFace(1)
            };
            var union_vector = new List <S2CellUnion> {
                new S2CellUnion(ids)
            };

            Assert.Equal(ids, union_vector.Last().CellIds);
        }
示例#14
0
        public void Test_S2CellUnion_ToStringOver500Cells()
        {
            List <S2CellId> ids = new();

            new S2CellUnion(new List <S2CellId> {
                S2CellId.FromFace(1)
            }).Denormalize(6, 1, ids);                                                           // 4096 cells
            var result = S2CellUnion.FromVerbatim(ids).ToString();

            Assert.Equal(result.Count(t => t == ','), 500);
            Assert.Equal(result[^ 4..], ",...");
示例#15
0
        public void Test_S2Cell_TestFaces()
        {
            var edge_counts   = new Dictionary <S2Point, int>();
            var vertex_counts = new Dictionary <S2Point, int>();

            for (int face = 0; face < 6; ++face)
            {
                S2CellId id   = S2CellId.FromFace(face);
                S2Cell   cell = new(id);
                Assert.Equal(id, cell.Id);
                Assert.Equal(face, cell.Face);
                Assert.Equal(0, cell.Level);
                // Top-level faces have alternating orientations to get RHS coordinates.
                Assert.Equal(face & S2.kSwapMask, cell.Orientation);
                Assert.False(cell.IsLeaf());
                for (int k = 0; k < 4; ++k)
                {
                    var key = cell.EdgeRaw(k);
                    if (edge_counts.ContainsKey(key))
                    {
                        edge_counts[key] += 1;
                    }
                    else
                    {
                        edge_counts[key] = 1;
                    }
                    var key2 = cell.VertexRaw(k);
                    if (vertex_counts.ContainsKey(key2))
                    {
                        vertex_counts[key2] += 1;
                    }
                    else
                    {
                        vertex_counts[key2] = 1;
                    }
                    Assert2.DoubleEqual(0.0, cell.VertexRaw(k).DotProd(key));
                    Assert2.DoubleEqual(0.0, cell.VertexRaw(k + 1).DotProd(key));
                    Assert2.DoubleEqual(1.0, cell.VertexRaw(k).CrossProd(cell.VertexRaw(k + 1))
                                        .Normalize().DotProd(cell.Edge(k)));
                }
            }
            // Check that edges have multiplicity 2 and vertices have multiplicity 3.
            foreach (var p in edge_counts)
            {
                Assert.Equal(2, p.Value);
            }
            foreach (var p in vertex_counts)
            {
                Assert.Equal(3, p.Value);
            }
        }
示例#16
0
        public void Test_S2CellUnion_EmptyAndNonEmptyBooleanOps()
        {
            S2CellUnion empty_cell_union     = new();
            S2CellId    face1_id             = S2CellId.FromFace(1);
            S2CellUnion non_empty_cell_union = new(new List <S2CellId> {
                face1_id
            });

            // Contains(...)
            Assert.False(empty_cell_union.Contains(face1_id));
            Assert.True(non_empty_cell_union.Contains(face1_id));
            Assert.True(empty_cell_union.Contains(empty_cell_union));
            Assert.True(non_empty_cell_union.Contains(empty_cell_union));
            Assert.False(empty_cell_union.Contains(non_empty_cell_union));
            Assert.True(non_empty_cell_union.Contains(non_empty_cell_union));

            // Intersects(...)
            Assert.False(empty_cell_union.Intersects(face1_id));
            Assert.True(non_empty_cell_union.Intersects(face1_id));
            Assert.False(empty_cell_union.Intersects(empty_cell_union));
            Assert.False(non_empty_cell_union.Intersects(empty_cell_union));
            Assert.False(empty_cell_union.Intersects(non_empty_cell_union));
            Assert.True(non_empty_cell_union.Intersects(non_empty_cell_union));

            // Union(...)
            Assert.Equal(empty_cell_union, empty_cell_union.Union(empty_cell_union));
            Assert.Equal(non_empty_cell_union, non_empty_cell_union.Union(empty_cell_union));
            Assert.Equal(non_empty_cell_union, empty_cell_union.Union(non_empty_cell_union));
            Assert.Equal(non_empty_cell_union,
                         non_empty_cell_union.Union(non_empty_cell_union));

            // Intersection(...)
            Assert.Equal(empty_cell_union, empty_cell_union.Intersection(face1_id));
            Assert.Equal(non_empty_cell_union, non_empty_cell_union.Intersection(face1_id));
            Assert.Equal(empty_cell_union, empty_cell_union.Intersection(empty_cell_union));
            Assert.Equal(empty_cell_union,
                         non_empty_cell_union.Intersection(empty_cell_union));
            Assert.Equal(empty_cell_union,
                         empty_cell_union.Intersection(non_empty_cell_union));
            Assert.Equal(non_empty_cell_union,
                         non_empty_cell_union.Intersection(non_empty_cell_union));

            // Difference(...)
            Assert.Equal(empty_cell_union, empty_cell_union.Difference(empty_cell_union));
            Assert.Equal(non_empty_cell_union,
                         non_empty_cell_union.Difference(empty_cell_union));
            Assert.Equal(empty_cell_union,
                         empty_cell_union.Difference(non_empty_cell_union));
            Assert.Equal(new S2CellUnion(),
                         non_empty_cell_union.Difference(non_empty_cell_union));
        }
示例#17
0
    public void Test_S2ConvexHullQuery_NonConvexPoints()
    {
        // Generate a point set such that the only convex region containing them is
        // the entire sphere.  In other words, you can generate any point on the
        // sphere by repeatedly linearly interpolating between the points.  (The
        // four points of a tetrahedron would also work, but this is easier.)
        S2ConvexHullQuery query = new();

        for (int face = 0; face < 6; ++face)
        {
            query.AddPoint(S2CellId.FromFace(face).ToPoint());
        }
        var result = (query.GetConvexHull());

        Assert.True(result.IsFull());
    }
示例#18
0
        public void Test_S2CellUnion_Release()
        {
            S2CellId    face1_id    = S2CellId.FromFace(1);
            S2CellUnion face1_union = new(new List <S2CellId> {
                face1_id
            });

            Assert.Equal(1, face1_union.Size());
            Assert.Equal(face1_id, face1_union.CellId(0));

            var released = face1_union.Release();

            Assert.True(1 == released.Count);
            Assert.Equal(face1_id, released[0]);
            Assert.Equal(0, face1_union.Size());
        }
示例#19
0
        public void Test_S2CellUnion_Clear()
        {
            S2CellId    face1_id    = S2CellId.FromFace(1);
            S2CellUnion face1_union = new(new List <S2CellId> {
                face1_id
            });

            Assert.Equal(1, face1_union.Size());
            Assert.True(1 == face1_union.CellIds.Count);
            Assert.True(1 <= face1_union.CellIds.Capacity);

            face1_union.Clear();
            Assert.Equal(0, face1_union.Size());
            Assert.True(0 == face1_union.CellIds.Count);
            Assert.Equal(0, face1_union.CellIds.Capacity);
        }
示例#20
0
 public void Test_S2CellId_FromDebugString()
 {
     Assert.Equal(S2CellId.FromFace(3), S2CellId.FromDebugString("3/"));
     Assert.Equal(S2CellId.FromFace(0).Child(2).Child(1),
                  S2CellId.FromDebugString("0/21"));
     Assert.Equal(S2CellId.FromFace(4).RangeMin(),
                  S2CellId.FromDebugString("4/000000000000000000000000000000"));
     Assert.Equal(S2CellId.None,
                  S2CellId.FromDebugString("4/0000000000000000000000000000000"));
     Assert.Equal(S2CellId.None, S2CellId.FromDebugString(""));
     Assert.Equal(S2CellId.None, S2CellId.FromDebugString("7/"));
     Assert.Equal(S2CellId.None, S2CellId.FromDebugString(" /"));
     Assert.Equal(S2CellId.None, S2CellId.FromDebugString("3:0"));
     Assert.Equal(S2CellId.None, S2CellId.FromDebugString("3/ 12"));
     Assert.Equal(S2CellId.None, S2CellId.FromDebugString("3/1241"));
 }
示例#21
0
    public void Test_VisitCells_QueryEdgeOnFaceBoundary()
    {
        int kIters = 100;

        for (int iter = 0; iter < kIters; ++iter)
        {
            _logger.WriteLine("Iteration " + iter);

            // Choose an edge AB such that B is nearly on the edge between two S2 cube
            // faces, and such that the result of clipping AB to the face that nominally
            // contains B (according to S2.GetFace) is empty when no padding is used.
            int     a_face, b_face;
            S2Point a, b;
            R2Point a_uv, b_uv;
            do
            {
                a_face = S2Testing.Random.Uniform(6);
                a      = S2.FaceUVtoXYZ(a_face, S2Testing.Random.UniformDouble(-1, 1),
                                        S2Testing.Random.UniformDouble(-1, 1)).Normalize();
                b_face = S2.GetUVWFace(a_face, 0, 1);  // Towards positive u-axis
                var uTmp = 1 - S2Testing.Random.Uniform(2) * 0.5 * S2.DoubleEpsilon;
                b = S2.FaceUVtoXYZ(b_face, uTmp, S2Testing.Random.UniformDouble(-1, 1)).Normalize();
            } while (S2.GetFace(b) != b_face ||
                     S2EdgeClipping.ClipToFace(a, b, b_face, out a_uv, out b_uv));

            // Verify that the clipping result is non-empty when a padding of
            // S2EdgeClipping.kFaceClipErrorUVCoord is used instead.
            Assert.True(S2EdgeClipping.ClipToPaddedFace(a, b, b_face, S2EdgeClipping.kFaceClipErrorUVCoord,
                                                        out a_uv, out b_uv));

            // Create an S2ShapeIndex containing a single edge BC, where C is on the
            // same S2 cube face as B (which is different than the face containing A).
            S2Point c = S2.FaceUVtoXYZ(b_face, S2Testing.Random.UniformDouble(-1, 1),
                                       S2Testing.Random.UniformDouble(-1, 1)).Normalize();
            MutableS2ShapeIndex index = new();
            index.Add(new S2Polyline.OwningShape(
                          new S2Polyline(new S2Point[] { b, c })));

            // Check that the intersection between AB and BC is detected when the face
            // containing BC is specified as a root cell.  (Note that VisitCells()
            // returns false only if the CellVisitor returns false, and otherwise
            // returns true.)
            S2CrossingEdgeQuery query = new(index);
            S2PaddedCell        root  = new(S2CellId.FromFace(b_face), 0);
            Assert.False(query.VisitCells(a, b, root, (S2ShapeIndexCell x) => false));
        }
    }
示例#22
0
    public void Test_VisitIntersectingShapes_Polygons()
    {
        MutableS2ShapeIndex index = new();
        S2Cap center_cap          = new(new(1, 0, 0), S1Angle.FromRadians(0.5));

        S2Testing.Fractal fractal = new();
        for (int i = 0; i < 10; ++i)
        {
            fractal.SetLevelForApproxMaxEdges(3 * 64);
            S2Point center = S2Testing.SamplePoint(center_cap);
            index.Add(new S2Loop.Shape(
                          fractal.MakeLoop(S2Testing.GetRandomFrameAt(center),
                                           S1Angle.FromRadians(S2Testing.Random.RandDouble()))));
        }
        // Also add a big polygon containing most of the polygons above to ensure
        // that we test containment of cells that are ancestors of index cells.
        index.Add(NewPaddedCell(S2CellId.FromFace(0), 0));
        new VisitIntersectingShapesTest(index).Run();
    }
示例#23
0
        public void Test_S2CellUnion_LeafCellsCovered()
        {
            S2CellUnion cell_union = new();

            Assert.Equal(0UL, cell_union.LeafCellsCovered());

            var ids = new List <S2CellId>
            {
                // One leaf cell on face 0.
                S2CellId.FromFace(0).ChildBegin(S2.kMaxCellLevel)
            };

            cell_union = new S2CellUnion(ids);
            Assert.Equal(1UL, cell_union.LeafCellsCovered());

            // Face 0 itself (which includes the previous leaf cell).
            ids.Add(S2CellId.FromFace(0));
            cell_union = new S2CellUnion(ids);
            Assert.Equal(1UL << 60, cell_union.LeafCellsCovered());
            // Five faces.
            cell_union.Expand(0);
            Assert.Equal(5UL << 60, cell_union.LeafCellsCovered());
            // Whole world.
            cell_union.Expand(0);
            Assert.Equal(6UL << 60, cell_union.LeafCellsCovered());

            // Add some disjoint cells.
            ids.Add(S2CellId.FromFace(1).ChildBegin(1));
            ids.Add(S2CellId.FromFace(2).ChildBegin(2));
            ids.Add(S2CellId.FromFace(2).ChildEnd(2).Prev());
            ids.Add(S2CellId.FromFace(3).ChildBegin(14));
            ids.Add(S2CellId.FromFace(4).ChildBegin(27));
            ids.Add(S2CellId.FromFace(4).ChildEnd(15).Prev());
            ids.Add(S2CellId.FromFace(5).ChildBegin(30));
            cell_union = new S2CellUnion(ids);
            UInt64 expected = 1UL + (1UL << 6) + (1UL << 30) + (1UL << 32) +
                              (2UL << 56) + (1UL << 58) + (1UL << 60);

            Assert.Equal(expected, cell_union.LeafCellsCovered());
        }
示例#24
0
        public void Test_S2CellId_GetCommonAncestorLevel()
        {
            // Two identical cell ids.
            Assert.Equal(0, S2CellId.FromFace(0)
                         .CommonAncestorLevel(S2CellId.FromFace(0)));
            Assert.Equal(30, S2CellId.FromFace(0).ChildBegin(30).CommonAncestorLevel(S2CellId.FromFace(0).ChildBegin(30)));

            // One cell id is a descendant of the other.
            Assert.Equal(0, S2CellId.FromFace(0).ChildBegin(30).CommonAncestorLevel(S2CellId.FromFace(0)));
            Assert.Equal(0, S2CellId.FromFace(5).CommonAncestorLevel(S2CellId.FromFace(5).ChildEnd(30).Prev()));

            // Two cells that have no common ancestor.
            Assert.Equal(-1, S2CellId.FromFace(0).CommonAncestorLevel(S2CellId.FromFace(5)));
            Assert.Equal(-1, S2CellId.FromFace(2).ChildBegin(30).CommonAncestorLevel(S2CellId.FromFace(3).ChildEnd(20)));

            // Two cells that have a common ancestor distinct from both of them.
            Assert.Equal(8, S2CellId.FromFace(5).ChildBegin(9).Next().ChildBegin(15).CommonAncestorLevel(
                             S2CellId.FromFace(5).ChildBegin(9).ChildBegin(20)));
            Assert.Equal(1, S2CellId.FromFace(0).ChildBegin(2).ChildBegin(30).
                         CommonAncestorLevel(
                             S2CellId.FromFace(0).ChildBegin(2).Next().ChildBegin(5)));
        }
示例#25
0
        public void Test_S2RegionEncodeDecodeTest_S2CellUnion()
        {
            S2CellUnion cu_empty = new();
            S2CellUnion cu_face1 = new(new List <S2CellId> {
                S2CellId.FromFace(1)
            });
            // Cell ids taken from S2CellUnion EncodeDecode test.
            S2CellUnion cu_latlngs = S2CellUnion.FromNormalized(new List <S2CellId>
            {
                new S2CellId(0x33),
                new S2CellId(0x8e3748fab),
                new S2CellId(0x91230abcdef83427),
            });

            var cu = TestEncodeDecode(kEncodedCellUnionEmpty, cu_empty);

            Assert.Equal(cu_empty, cu);
            cu = TestEncodeDecode(kEncodedCellUnionFace1, cu_face1);
            Assert.Equal(cu_face1, cu);
            cu = TestEncodeDecode(kEncodedCellUnionFromCells, cu_latlngs);
            Assert.Equal(cu_latlngs, cu);
        }
示例#26
0
        public void Test_S2CellId_Tokens()
        {
            // Test random cell ids at all levels.
            for (int i = 0; i < 10000; ++i)
            {
                var id    = S2Testing.GetRandomCellId();
                var token = id.ToToken();
                Assert.True(token.Length <= 16);
                Assert.Equal(id, S2CellId.FromToken(token));
                Assert.Equal(id, S2CellId.FromToken(token));
            }
            // Check that invalid cell ids can be encoded, and round-trip is
            // the identity operation.
            string token2 = S2CellId.None.ToToken();

            Assert.Equal(S2CellId.None, S2CellId.FromToken(token2));
            Assert.Equal(S2CellId.None, S2CellId.FromToken(token2));

            // Sentinel is invalid.
            token2 = S2CellId.Sentinel.ToToken();
            Assert.Equal(S2CellId.FromToken(token2), S2CellId.Sentinel);
            Assert.Equal(S2CellId.FromToken(token2),
                         S2CellId.Sentinel);

            // Check an invalid face.
            token2 = S2CellId.FromFace(7).ToToken();
            Assert.Equal(S2CellId.FromToken(token2), S2CellId.FromFace(7));
            Assert.Equal(S2CellId.FromToken(token2),
                         S2CellId.FromFace(7));

            // Check that supplying tokens with non-alphanumeric characters
            // returns S2CellId.None.
            Assert.Equal(S2CellId.None, S2CellId.FromToken("876b e99"));
            Assert.Equal(S2CellId.None, S2CellId.FromToken("876bee99\n"));
            Assert.Equal(S2CellId.None, S2CellId.FromToken("876[ee99"));
            Assert.Equal(S2CellId.None, S2CellId.FromToken(" 876bee99"));
        }
示例#27
0
 public void Test_MakeCellId_ValidInput()
 {
     Assert.True(MakeCellId("3/", out var cellId));
     Assert.Equal(cellId, S2CellId.FromFace(3));
 }
示例#28
0
        public void Test_S2CellId_Neighbors()
        {
            // Check the edge neighbors of face 1.
            var out_faces = new[] { 5, 3, 2, 0 };
            var face_nbrs = new S2CellId[4];

            S2CellId.FromFace(1).EdgeNeighbors(face_nbrs);
            for (int i = 0; i < 4; ++i)
            {
                Assert.True(face_nbrs[i].IsFace());
                Assert.Equal(out_faces[i], (int)face_nbrs[i].Face());
            }

            // Check the edge neighbors of the corner cells at all levels.  This case is
            // trickier because it requires projecting onto adjacent faces.
            const int kMaxIJ = S2CellId.kMaxSize - 1;

            for (int level = 1; level <= S2.kMaxCellLevel; ++level)
            {
                S2CellId id2   = S2CellId.FromFaceIJ(1, 0, 0).Parent(level);
                var      nbrs2 = new S2CellId[4];
                id2.EdgeNeighbors(nbrs2);
                // These neighbors were determined manually using the face and axis
                // relationships defined in s2coords.cc.
                int size_ij = S2CellId.SizeIJ(level);
                Assert.Equal(S2CellId.FromFaceIJ(5, kMaxIJ, kMaxIJ).Parent(level), nbrs2[0]);
                Assert.Equal(S2CellId.FromFaceIJ(1, size_ij, 0).Parent(level), nbrs2[1]);
                Assert.Equal(S2CellId.FromFaceIJ(1, 0, size_ij).Parent(level), nbrs2[2]);
                Assert.Equal(S2CellId.FromFaceIJ(0, kMaxIJ, 0).Parent(level), nbrs2[3]);
            }

            // Check the vertex neighbors of the center of face 2 at level 5.
            var nbrs = new List <S2CellId>();

            new S2CellId(new S2Point(0, 0, 1)).AppendVertexNeighbors(5, nbrs);
            nbrs.Sort();
            for (int i = 0; i < 4; ++i)
            {
                Assert.Equal(S2CellId.FromFaceIJ(
                                 2, (1 << 29) - ((i < 2) ? 1 : 0), (1 << 29) - ((i == 0 || i == 3) ? 1 : 0))
                             .Parent(5), nbrs[i]);
            }
            nbrs.Clear();

            // Check the vertex neighbors of the corner of faces 0, 4, and 5.
            S2CellId id1 = S2CellId.FromFacePosLevel(0, 0, S2.kMaxCellLevel);

            id1.AppendVertexNeighbors(0, nbrs);
            nbrs.Sort();
            Assert.Equal(3, nbrs.Count);
            Assert.Equal(S2CellId.FromFace(0), nbrs[0]);
            Assert.Equal(S2CellId.FromFace(4), nbrs[1]);
            Assert.Equal(S2CellId.FromFace(5), nbrs[2]);

            // Check that AppendAllNeighbors produces results that are consistent
            // with AppendVertexNeighbors for a bunch of random cells.
            for (var i = 0; i < 1000; ++i)
            {
                S2CellId id2 = S2Testing.GetRandomCellId();
                if (id2.IsLeaf())
                {
                    id2 = id2.Parent();
                }

                // TestAllNeighbors computes approximately 2**(2*(diff+1)) cell ids,
                // so it's not reasonable to use large values of "diff".
                int max_diff = Math.Min(5, S2.kMaxCellLevel - id2.Level() - 1);
                int level    = id2.Level() + S2Testing.Random.Uniform(max_diff + 1);
                TestAllNeighbors(id2, level);
            }
        }