Ejemplo n.º 1
0
        // The point 'p' does not need to be normalized.

        private void Init(S2CellId id)
        {
            _cellId = id;
            var ij           = new int[2];
            int?mOrientation = 0;

            for (var d = 0; d < 2; ++d)
            {
                ij[d] = 0;
            }

            _face        = (byte)id.ToFaceIjOrientation(ref ij[0], ref ij[1], ref mOrientation);
            _orientation = (byte)mOrientation.Value; // Compress int to a byte.
            _level       = (byte)id.Level;
            var cellSize = 1 << (S2CellId.MaxLevel - _level);

            for (var d = 0; d < 2; ++d)
            {
                // Compute the cell bounds in scaled (i,j) coordinates.
                var sijLo = (ij[d] & -cellSize) * 2 - MaxCellSize;
                var sijHi = sijLo + cellSize * 2;
                _uv[d][0] = S2Projections.StToUv((1.0 / MaxCellSize) * sijLo);
                _uv[d][1] = S2Projections.StToUv((1.0 / MaxCellSize) * sijHi);
            }
        }
Ejemplo n.º 2
0
        /**
         * Convert (face, si, ti) coordinates (see s2.h) to a direction vector (not
         * necessarily unit length).
         */

        private static S2Point FaceSiTiToXyz(int face, int si, int ti)
        {
            const double kScale = 1.0 / MaxSize;
            var          u      = S2Projections.StToUv(kScale * si);
            var          v      = S2Projections.StToUv(kScale * ti);

            return(S2Projections.FaceUvToXyz(face, u, v));
        }
Ejemplo n.º 3
0
        /**
         * Return the leaf cell containing the given point (a direction vector, not
         * necessarily unit length).
         */

        public static S2CellId FromPoint(S2Point p)
        {
            var face = S2Projections.XyzToFace(p);
            var uv   = S2Projections.ValidFaceXyzToUv(face, p);
            var i    = StToIj(S2Projections.UvToSt(uv.X));
            var j    = StToIj(S2Projections.UvToSt(uv.Y));

            return(FromFaceIj(face, i, j));
        }
Ejemplo n.º 4
0
        public bool Contains(S2Point p)
        {
            // We can't just call XYZtoFaceUV, because for points that lie on the
            // boundary between two faces (i.e. u or v is +1/-1) we need to return
            // true for both adjacent cells.
            var uvPoint = S2Projections.FaceXyzToUv(_face, p);

            if (uvPoint == null)
            {
                return(false);
            }
            return(uvPoint.Value.X >= _uv[0][0] && uvPoint.Value.X <= _uv[0][1] &&
                   uvPoint.Value.Y >= _uv[1][0] && uvPoint.Value.Y <= _uv[1][1]);
        }
Ejemplo n.º 5
0
        public S2Point GetEdgeRaw(int k)
        {
            switch (k)
            {
            case 0:
                return(S2Projections.GetVNorm(_face, _uv[1][0]));    // South

            case 1:
                return(S2Projections.GetUNorm(_face, _uv[0][1]));    // East

            case 2:
                return(-S2Projections.GetVNorm(_face, _uv[1][1]));    // North

            default:
                return(-S2Projections.GetUNorm(_face, _uv[0][0]));    // West
            }
        }
Ejemplo n.º 6
0
        /**
         * Given (i, j) coordinates that may be out of bounds, normalize them by
         * returning the corresponding neighbor cell on an adjacent face.
         */

        private static S2CellId FromFaceIjWrap(int face, int i, int j)
        {
            // Convert i and j to the coordinates of a leaf cell just beyond the
            // boundary of this face. This prevents 32-bit overflow in the case
            // of finding the neighbors of a face cell, and also means that we
            // don't need to worry about the distinction between (s,t) and (u,v).
            i = Math.Max(-1, Math.Min(MaxSize, i));
            j = Math.Max(-1, Math.Min(MaxSize, j));

            // Find the (s,t) coordinates corresponding to (i,j). At least one
            // of these coordinates will be just outside the range [0, 1].
            const double kScale = 1.0 / MaxSize;
            var          s      = kScale * ((i << 1) + 1 - MaxSize);
            var          t      = kScale * ((j << 1) + 1 - MaxSize);

            // Find the leaf cell coordinates on the adjacent face, and convert
            // them to a cell id at the appropriate level.
            var p = S2Projections.FaceUvToXyz(face, s, t);

            face = S2Projections.XyzToFace(p);
            var st = S2Projections.ValidFaceXyzToUv(face, p);

            return(FromFaceIj(face, StToIj(st.X), StToIj(st.Y)));
        }
Ejemplo n.º 7
0
        private double GetLongitude(int i, int j)
        {
            var p = S2Projections.FaceUvToXyz(_face, _uv[0][i], _uv[1][j]);

            return(Math.Atan2(p.Y, p.X));
        }
Ejemplo n.º 8
0
        // Internal method that does the actual work in the constructors.

        private double GetLatitude(int i, int j)
        {
            var p = S2Projections.FaceUvToXyz(_face, _uv[0][i], _uv[1][j]);

            return(Math.Atan2(p.Z, Math.Sqrt(p.X * p.X + p.Y * p.Y)));
        }
Ejemplo n.º 9
0
        /**
         * Return the k-th vertex of the cell (k = 0,1,2,3). Vertices are returned in
         * CCW order. The points returned by GetVertexRaw are not necessarily unit
         * length.
         */

        public S2Point GetVertexRaw(int k)
        {
            // Vertices are returned in the order SW, SE, NE, NW.
            return(S2Projections.FaceUvToXyz(_face, _uv[0][(k >> 1) ^ (k & 1)], _uv[1][k >> 1]));
        }