Exemplo n.º 1
0
        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);
        }
Exemplo n.º 2
0
    private readonly int orientation_;  // Hilbert curve orientation of this cell (see s2coords.h)

    #region Constructors

    // Construct an S2PaddedCell for the given cell id and padding.
    public S2PaddedCell(S2CellId id, double padding)
    {
        ij_lo_  = new int[2];
        Id      = id;
        Padding = padding;
        if (Id.IsFace())
        {
            // Fast path for constructing a top-level face (the most common case).
            double limit = 1 + padding;
            Bound = new R2Rect(new R1Interval(-limit, limit),
                               new R1Interval(-limit, limit));
            middle_ = new R2Rect(new R1Interval(-padding, padding),
                                 new R1Interval(-padding, padding));
            ij_lo_[0]    = ij_lo_[1] = 0;
            orientation_ = (int)(Id.Face() & 1);
            Level        = 0;
        }
        else
        {
            var ij = new int[2];
            id.ToFaceIJOrientation(out ij[0], out ij[1], out orientation_, true);
            Level = id.Level();
            Bound = S2CellId.IJLevelToBoundUV(ij, Level).Expanded(padding);
            int ij_size = S2CellId.SizeIJ(Level);
            ij_lo_[0] = ij[0] & -ij_size;
            ij_lo_[1] = ij[1] & -ij_size;
        }
    }
Exemplo n.º 3
0
 public void Test_S2CellId_Inverses()
 {
     // Check the conversion of random leaf cells to S2LatLngs and back.
     for (int i = 0; i < 200000; ++i)
     {
         S2CellId id = S2Testing.GetRandomCellId(S2.kMaxCellLevel);
         Assert.True(id.IsLeaf());
         Assert.Equal(S2.kMaxCellLevel, id.Level());
         S2LatLng center = id.ToLatLng();
         Assert.Equal(id.Id, new S2CellId(center).Id);
     }
 }
Exemplo n.º 4
0
    private static S2Shape NewPaddedCell(S2CellId id, double padding_uv)
    {
        var ij       = new int[2];
        var face     = id.ToFaceIJOrientation(out ij[0], out ij[1], out _, false);
        var uv       = S2CellId.IJLevelToBoundUV(ij, id.Level()).Expanded(padding_uv);
        var vertices = new S2Point[4];

        for (int i = 0; i < 4; ++i)
        {
            vertices[i] = S2.FaceUVtoXYZ(face, uv.GetVertex(i)).Normalize();
        }
        return(new S2LaxLoopShape(vertices));
    }
Exemplo n.º 5
0
        public void Test_S2CellId_DistanceFromBegin()
        {
            Assert.Equal(6, S2CellId.End(0).DistanceFromBegin());
            Assert.Equal(6 * (1L << (2 * S2.kMaxCellLevel)),
                         S2CellId.End(S2.kMaxCellLevel).DistanceFromBegin());

            Assert.Equal(0, S2CellId.Begin(0).DistanceFromBegin());
            Assert.Equal(0, S2CellId.Begin(S2.kMaxCellLevel).DistanceFromBegin());

            S2CellId id = S2CellId.FromFacePosLevel(3, 0x12345678, S2.kMaxCellLevel - 4);

            Assert.Equal(id, S2CellId.Begin(id.Level()).Advance(id.DistanceFromBegin()));
        }
Exemplo n.º 6
0
    // Returns true if "covering" contains all children of "id" at level
    // (id.Level + options_.level_mod()).
    private bool ContainsAllChildren(List <S2CellId> covering, S2CellId id)
    {
        var it    = covering.GetLowerBound(id.RangeMin());
        int level = id.Level() + Options_.LevelMod;
        var limit = id.ChildEnd(level);

        for (var child = id.ChildBegin(level); child != limit; child = child.Next())
        {
            if (it == covering.Count || covering[it] != child)
            {
                return(false);
            }
            it++;
        }
        return(true);
    }
Exemplo n.º 7
0
        public void Test_S2PaddedCell_ShrinkToFit()
        {
            const int kIters = 1000;

            for (int iter = 0; iter < kIters; ++iter)
            {
                // Start with the desired result and work backwards.
                S2CellId result    = S2Testing.GetRandomCellId();
                R2Rect   result_uv = result.BoundUV();
                R2Point  size_uv   = result_uv.GetSize();

                // Find the biggest rectangle that fits in "result" after padding.
                // (These calculations ignore numerical errors.)
                double max_padding = 0.5 * Math.Min(size_uv[0], size_uv[1]);
                double padding     = max_padding * S2Testing.Random.RandDouble();
                R2Rect max_rect    = result_uv.Expanded(-padding);

                // Start with a random subset of the maximum rectangle.
                R2Point a = new(SampleInterval(max_rect[0]), SampleInterval(max_rect[1]));
                R2Point b = new(SampleInterval(max_rect[0]), SampleInterval(max_rect[1]));
                if (!result.IsLeaf())
                {
                    // If the result is not a leaf cell, we must ensure that no child of
                    // "result" also satisfies the conditions of ShrinkToFit().  We do this
                    // by ensuring that "rect" intersects at least two children of "result"
                    // (after padding).
                    int    axis   = S2Testing.Random.Uniform(2);
                    double center = result.CenterUV()[axis];

                    // Find the range of coordinates that are shared between child cells
                    // along that axis.
                    R1Interval shared = new(center - padding, center + padding);
                    double     mid    = SampleInterval(shared.Intersection(max_rect[axis]));
                    a = a.SetAxis(axis, SampleInterval(new R1Interval(max_rect[axis].Lo, mid)));
                    b = b.SetAxis(axis, SampleInterval(new R1Interval(mid, max_rect[axis].Hi)));
                }
                R2Rect rect = R2Rect.FromPointPair(a, b);

                // Choose an arbitrary ancestor as the S2PaddedCell.
                S2CellId initial_id = result.Parent(S2Testing.Random.Uniform(result.Level() + 1));
                Assert.Equal(result, new S2PaddedCell(initial_id, padding).ShrinkToFit(rect));
            }
        }
Exemplo n.º 8
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);
            }
        }