示例#1
0
 /// <inheritdoc />
 protected override void OnForward(double[] lp, double[] xy, int startIndex, int numPoints)
 {
     for (int i = startIndex; i < startIndex + numPoints; i++)
     {
         int    phi = i * 2 + PHI;
         int    lam = i * 2 + LAMBDA;
         int    x = i * 2 + X;
         int    y = i * 2 + Y;
         double ul, us;
         double vl = Math.Sin(_bl * lp[lam]);
         if (Math.Abs(Math.Abs(lp[phi]) - Math.PI / 2) <= EPS10)
         {
             ul = lp[phi] < 0 ? -_singam : _singam;
             us = _al * lp[phi] / _bl;
         }
         else
         {
             double q = _el / (_ellips ? Math.Pow(Proj.Tsfn(lp[phi], Math.Sin(lp[phi]), E), _bl) : Tsfn0(lp[phi]));
             double s = .5 * (q - 1 / q);
             ul = 2.0 * (s * _singam - vl * _cosgam) / (q + 1.0 / q);
             double con = Math.Cos(_bl * lp[lam]);
             if (Math.Abs(con) >= TOLERANCE)
             {
                 us = _al * Math.Atan((s * _cosgam + vl * _singam) / con) / _bl;
                 if (con < 0)
                 {
                     us += Math.PI * _al / _bl;
                 }
             }
             else
             {
                 us = _al * _bl * lp[lam];
             }
         }
         if (Math.Abs(Math.Abs(ul) - 1.0) <= EPS10)
         {
             xy[x] = double.NaN;
             xy[y] = double.NaN;
             continue;
             //ProjectionException(20);
         }
         double vs = .5 * _al * Math.Log((1 - ul) / (1 + ul)) / _bl;
         us -= _u0;
         if (!_rot)
         {
             xy[x] = us;
             xy[y] = vs;
         }
         else
         {
             xy[x] = vs * _cosrot + us * _sinrot;
             xy[y] = us * _cosrot - vs * _sinrot;
         }
     }
 }
示例#2
0
        /// <inheritdoc />
        protected override void EllipticalForward(double[] lp, double[] xy, int startIndex, int numPoints)
        {
            for (int i = startIndex; i < startIndex + numPoints; i++)
            {
                int    phi = i * 2 + PHI;
                int    lam = i * 2 + LAMBDA;
                int    x = i * 2 + X;
                int    y = i * 2 + Y;
                double sinX = 0.0, cosX = 0.0;

                double coslam = Math.Cos(lp[lam]);
                double sinlam = Math.Sin(lp[lam]);
                double sinphi = Math.Sin(lp[phi]);
                if (_mode == Modes.Oblique || _mode == Modes.Equitorial)
                {
                    double cx;
                    sinX = Math.Sin(cx = 2 * Math.Atan(Ssfn(lp[phi], sinphi, E)) - HALF_PI);
                    cosX = Math.Cos(cx);
                }
                if (_mode == Modes.Oblique || _mode == Modes.Equitorial)
                {
                    double a;
                    if (_mode == Modes.Oblique)
                    {
                        a = _akm1 / (_cosX1 * (1 + _sinX1 * sinX +
                                               _cosX1 * cosX * coslam));
                        xy[y] = a * (_cosX1 * sinX - _sinX1 * cosX * coslam);
                    }
                    else
                    {
                        a     = 2 * _akm1 / (1 + cosX * coslam);
                        xy[y] = a * sinX;
                    }
                    xy[x] = a * cosX;
                }
                else
                {
                    if (_mode == Modes.SouthPole)
                    {
                        lp[phi] = -lp[phi];
                        coslam  = -coslam;
                        sinphi  = -sinphi;
                    }
                    xy[x] = _akm1 * Proj.Tsfn(lp[phi], sinphi, E);
                    xy[y] = -xy[x] * coslam;
                }
                xy[x] = xy[x] * sinlam;
            }
        }
 /// <inheritdoc />
 protected override void EllipticalForward(double[] lp, double[] xy, int startIndex, int numPoints)
 {
     for (int i = startIndex; i < startIndex + numPoints; i++)
     {
         int phi = i * 2 + PHI;
         int lam = i * 2 + LAMBDA;
         int x   = i * 2 + X;
         int y   = i * 2 + Y;
         if (Math.Abs(Math.Abs(lp[phi]) - HALF_PI) <= EPS10)
         {
             xy[x] = double.NaN;
             xy[y] = double.NaN;
             continue;
             //throw new ProjectionException(20);
         }
         xy[x] = K0 * lp[lam];
         xy[y] = -K0 *Math.Log(Proj.Tsfn(lp[phi], Math.Sin(lp[phi]), E));
     }
 }
示例#4
0
 /// <summary>
 /// Special factor calculations for a factors calculation
 /// </summary>
 /// <param name="lp">lambda-phi</param>
 /// <param name="p">The projection</param>
 /// <param name="fac">The Factors</param>
 protected override void OnSpecial(double[] lp, ProjectionInfo p, Factors fac)
 {
     if (Math.Abs(Math.Abs(lp[PHI]) - HALF_PI) < EPS10)
     {
         if ((lp[PHI] * _n) <= 0)
         {
             return;
         }
         _rho = 0;
     }
     else
     {
         _rho = _c * (_ellipse ? Math.Pow(Proj.Tsfn(lp[PHI], Math.Sin(lp[PHI]),
                                                    p.GeographicInfo.Datum.Spheroid.Eccentricity()), _n)
                          : Math.Pow(Math.Tan(Math.PI / 4 + .5 * lp[PHI]), -_n));
     }
     fac.Code = AnalyticModes.IsAnalHk | AnalyticModes.IsAnalConv;
     fac.K    = fac.H = p.ScaleFactor * _n * _rho / Proj.Msfn(Math.Sin(lp[PHI]), Math.Cos(lp[PHI]), p.GeographicInfo.Datum.Spheroid.EccentricitySquared());
     fac.Conv = -_n * lp[LAMBDA];
 }
示例#5
0
 /// <inheritdoc />
 protected override void OnForward(double[] lp, double[] xy, int startIndex, int numPoints)
 {
     for (int i = startIndex; i < startIndex + numPoints; i++)
     {
         int phi = i * 2 + PHI;
         int lam = i * 2 + LAMBDA;
         int x   = i * 2 + X;
         int y   = i * 2 + Y;
         if (Math.Abs(Math.Abs(lp[phi]) - HALF_PI) < EPS10)
         {
             if (lp[phi] * _n <= 0)
             {
                 xy[x] = double.NaN;
                 xy[y] = double.NaN;
                 continue;
                 //throw new ProjectionException(20);
             }
             _rho = 0;
         }
         else
         {
             double cx;
             if (_ellipse)
             {
                 cx = Math.Pow(Proj.Tsfn(lp[phi], Math.Sin(lp[phi]), E), _n);
             }
             else
             {
                 cx = Math.Pow(Math.Tan(Math.PI / 4 + .5 * lp[phi]), -_n);
             }
             _rho = _c * cx;
         }
         double nLam = lp[lam] * _n;
         xy[x] = K0 * (_rho * Math.Sin(nLam));
         xy[y] = K0 * (_rho0 - _rho * Math.Cos(nLam));
     }
 }
示例#6
0
        /// <summary>
        /// Initializes the transform using the parameters from the specified coordinate system information
        /// </summary>
        /// <param name="projInfo">A ProjectionInfo class contains all the standard and custom parameters needed to initialize this transform</param>
        protected override void OnInit(ProjectionInfo projInfo)
        {
            double con;
            double f;
            double d;
            double toRadians = projInfo.GeographicInfo.Unit.Radians;

            _rot = !projInfo.no_rot.HasValue || projInfo.no_rot.Value == 0;

            _lamc = projInfo.LongitudeOfCenter.Value * toRadians;

            if (projInfo.alpha.HasValue)
            {
                _alpha = projInfo.alpha.Value * toRadians;
            }
            if (Math.Abs(_alpha) < TOLERANCE ||
                Math.Abs(Math.Abs(Phi0) - HALF_PI) <= TOLERANCE ||
                Math.Abs(Math.Abs(_alpha) - HALF_PI) <= TOLERANCE)
            {
                throw new ProjectionException(32);
            }

            _ellips = Es > 0;
            double com = _ellips ? Math.Sqrt(OneEs) : 1;

            if (Math.Abs(Phi0) > EPS10)
            {
                double sinph0 = Math.Sin(Phi0);
                double cosph0 = Math.Cos(Phi0);
                if (_ellips)
                {
                    con = 1 - Es * sinph0 * sinph0;
                    _bl = cosph0 * cosph0;
                    _bl = Math.Sqrt(1 + Es * _bl * _bl / OneEs);
                    _al = _bl * K0 * com / con;
                    d   = _bl * com / (cosph0 * Math.Sqrt(con));
                }
                else
                {
                    _bl = 1;
                    _al = K0;
                    d   = 1 / cosph0;
                }

                if ((f = d * d - 1) <= 0)
                {
                    f = 0;
                }
                else
                {
                    f = Math.Sqrt(f);
                    if (Phi0 < 0)
                    {
                        f = -f;
                    }
                }
                _el = f += d;
                if (_ellips)
                {
                    _el *= Math.Pow(Proj.Tsfn(Phi0, sinph0, E), _bl);
                }
                else
                {
                    _el *= Tsfn0(Phi0);
                }
            }
            else
            {
                _bl = 1 / com;
                _al = K0;
                _el = d = f = 1;
            }

            _gamma        = Math.Asin(Math.Sin(_alpha) / d);
            Lam0          = _lamc - Math.Asin((.5 * (f - 1 / f)) * Math.Tan(_gamma)) / _bl;
            projInfo.Lam0 = Lam0;

            _singam = Math.Sin(_gamma);
            _cosgam = Math.Cos(_gamma);

            _sinrot = Math.Sin(_alpha);
            _cosrot = Math.Cos(_alpha);
        }
示例#7
0
        /// <summary>
        /// Initializes the transform using the parameters from the specified coordinate system information
        /// </summary>
        /// <param name="projInfo">A ProjectionInfo class contains all the standard and custom parameters needed to initialize this transform</param>
        protected override void OnInit(ProjectionInfo projInfo)
        {
            double sinphi;

            _phi1 = projInfo.Phi1;
            if (projInfo.StandardParallel2 != null)
            {
                _phi2 = projInfo.Phi2;
            }
            else
            {
                _phi2 = _phi1;
                _phi1 = projInfo.Phi0;
            }
            if (Math.Abs(_phi1 + _phi2) < EPS10)
            {
                throw new ProjectionException(21);
            }
            _n = sinphi = Math.Sin(_phi1);
            double cosphi = Math.Cos(_phi1);
            bool   secant = Math.Abs(_phi1 - _phi2) >= EPS10;

            _ellipse = projInfo.GeographicInfo.Datum.Spheroid.IsOblate();
            if (_ellipse)
            {
                double m1  = Proj.Msfn(sinphi, cosphi, Es);
                double ml1 = Proj.Tsfn(_phi1, sinphi, E);
                if (secant)
                {
                    sinphi = Math.Sin(_phi2);
                    _n     = Math.Log(m1 / Proj.Msfn(sinphi, Math.Cos(_phi2), Es));
                    _n     = _n / Math.Log(ml1 / Proj.Tsfn(_phi2, sinphi, E));
                }
                _rho0 = m1 * Math.Pow(ml1, -_n) / _n;
                _c    = _rho0;
                if (Math.Abs(Math.Abs(Phi0) - HALF_PI) < EPS10)
                {
                    _rho0 = 0;
                }
                else
                {
                    _rho0 *= Math.Pow(Proj.Tsfn(Phi0, Math.Sin(Phi0), E), _n);
                }
            }
            else
            {
                if (secant)
                {
                    _n = Math.Log(cosphi / Math.Cos(_phi2)) /
                         Math.Log(Math.Tan(Math.PI / 4 + .5 * _phi2) /
                                  Math.Tan(Math.PI / 4 + .5 * _phi1));
                    _c = cosphi * Math.Pow(Math.Tan(Math.PI / 4 + .5 * _phi1), _n) / _n;
                }
                if (Math.Abs(Math.Abs(Phi0) - HALF_PI) < EPS10)
                {
                    _rho0 = 0;
                }
                else
                {
                    _rho0 = _c * Math.Pow(Math.Tan(Math.PI / 4 + .5 * Phi0), -_n);
                }
            }
        }
示例#8
0
        /// <inheritdoc />
        protected override void OnForward(double[] lp, double[] xy, int startIndex, int numPoints)
        {
            bool   bAlphaIs90     = Math.Abs(Math.Abs(_alpha) - HALF_PI) <= EPS10;
            double _lamcMinusLam0 = Proj.Adjlon(_lamc - Lam0);

            for (int i = startIndex; i < startIndex + numPoints; i++)
            {
                int    phi = i * 2 + PHI;
                int    lam = i * 2 + LAMBDA;
                int    x = i * 2 + X;
                int    y = i * 2 + Y;
                double ul, us;
                double vl = Math.Sin(_bl * lp[lam]);
                if (Math.Abs(Math.Abs(lp[phi]) - Math.PI / 2) <= EPS10)
                {
                    ul = lp[phi] < 0 ? -_singam : _singam;
                    us = _al * lp[phi] / _bl;
                }
                else
                {
                    double q = _el / (_ellips ? Math.Pow(Proj.Tsfn(lp[phi], Math.Sin(lp[phi]), E), _bl) : Tsfn0(lp[phi]));
                    double s = .5 * (q - 1 / q);
                    ul = 2.0 * (s * _singam - vl * _cosgam) / (q + 1.0 / q);
                    double con = Math.Cos(_bl * lp[lam]);
                    if (Math.Abs(con) >= TOLERANCE)
                    {
                        us = _al * Math.Atan((s * _cosgam + vl * _singam) / con) / _bl;
                        // if (con < 0) us += Math.PI * _al / _bl; taken care of below...
                    }
                    else
                    {
                        us = _al * _bl * lp[lam];
                    }
                }
                if (Math.Abs(Math.Abs(ul) - 1.0) <= EPS10)
                {
                    xy[x] = double.NaN;
                    xy[y] = double.NaN;
                    continue;
                    //ProjectionException(20);
                }
                double vs = .5 * _al * Math.Log((1 - ul) / (1 + ul)) / _bl;

                if (bAlphaIs90)
                {
                    if (Math.Abs(_lamcMinusLam0 - lp[lam]) < EPS10)
                    {
                        us = 0;
                    }
                    else if (_lamcMinusLam0 - lp[lam] < 0)  // from OGP guidance note 7 term: "SIGN(lamc-lam)"
                    {
                        us -= -_u0;
                    }
                    else
                    {
                        us -= _u0;
                    }
                }
                else
                {
                    us -= _u0;
                }

                xy[x] = vs * _cosrot + us * _sinrot;
                xy[y] = us * _cosrot - vs * _sinrot;
            }
        }
示例#9
0
        /// <summary>
        /// Initializes the transform using the parameters from the specified coordinate system information
        /// </summary>
        /// <param name="projInfo">A ProjectionInfo class contains all the standard and custom parameters needed to initialize this transform</param>
        protected override void OnInit(ProjectionInfo projInfo)
        {
            if (projInfo.StandardParallel1 != null)
            {
                _phits = projInfo.Phi1;
            }
            else
            {
                _phits = HALF_PI;
            }
            double t;

            if (Math.Abs((t = Math.Abs(Phi0)) - HALF_PI) < EPS10)
            {
                _mode = Phi0 < 0 ? Modes.SouthPole : Modes.NorthPole;
            }
            else
            {
                _mode = t > EPS10 ? Modes.Oblique : Modes.Equitorial;
            }
            _phits = Math.Abs(_phits);
            if (Es != 0)
            {
                switch (_mode)
                {
                case Modes.NorthPole:
                case Modes.SouthPole:
                    if (Math.Abs(_phits - HALF_PI) < EPS10)
                    {
                        _akm1 = 2 * K0 / Math.Sqrt(Math.Pow(1 + E, 1 + E) * Math.Pow(1 - E, 1 - E));
                    }
                    else
                    {
                        _akm1  = Math.Cos(_phits) / Proj.Tsfn(_phits, t = Math.Sin(_phits), E);
                        t     *= E;
                        _akm1 /= Math.Sqrt(1 - t * t);
                    }
                    break;

                case Modes.Equitorial:
                    _akm1 = 2 * K0;
                    break;

                case Modes.Oblique:
                    t = Math.Sin(Phi0);
                    double x = 2 * Math.Atan(Ssfn(Phi0, t, E)) - HALF_PI;
                    t     *= E;
                    _akm1  = 2 * K0 * Math.Cos(Phi0) / Math.Sqrt(1 - t * t);
                    _sinX1 = Math.Sin(x);
                    _cosX1 = Math.Cos(x);
                    break;
                }
            }
            else
            {
                if (_mode == Modes.Oblique || _mode == Modes.Equitorial)
                {
                    if (_mode == Modes.Oblique)
                    {
                        _sinX1 = Math.Sin(Phi0);
                        _cosX1 = Math.Cos(Phi0);
                    }
                    _akm1 = 2 * K0;
                }
                else
                {
                    _akm1 = Math.Abs(_phits - HALF_PI) >= EPS10?
                            Math.Cos(_phits) / Math.Tan(FORT_PI - .5 * _phits) :
                                2 * K0;
                }
            }
        }
示例#10
0
        /// <summary>
        /// Initializes the transform using the parameters from the specified coordinate system information
        /// </summary>
        /// <param name="projInfo">A ProjectionInfo class contains all the standard and custom parameters needed to initialize this transform</param>
        protected override void OnInit(ProjectionInfo projInfo)
        {
            double con;
            double f;
            double d;
            double toRadians = projInfo.GeographicInfo.Unit.Radians;

            _rot = !projInfo.no_rot.HasValue || projInfo.no_rot.Value == 0;
            bool azi = projInfo.alpha.HasValue;

            if (azi)
            {
                if (projInfo.lonc.HasValue)
                {
                    _lamc = projInfo.lonc.Value * toRadians;
                }
                if (projInfo.alpha.HasValue)
                {
                    _alpha = projInfo.alpha.Value * toRadians;
                }
                if (Math.Abs(_alpha) < TOLERANCE ||
                    Math.Abs(Math.Abs(Phi0) - HALF_PI) <= TOLERANCE ||
                    Math.Abs(Math.Abs(_alpha) - HALF_PI) <= TOLERANCE)
                {
                    throw new ProjectionException(32);
                }
            }
            else
            {
                _lam1 = projInfo.Lam1;
                _phi1 = projInfo.Phi1;
                _lam2 = projInfo.Lam2;
                _phi2 = projInfo.Phi2;
                if (Math.Abs(_phi1 - _phi2) <= TOLERANCE ||
                    (con = Math.Abs(_phi1)) <= TOLERANCE ||
                    Math.Abs(con - HALF_PI) <= TOLERANCE ||
                    Math.Abs(Math.Abs(Phi0) - HALF_PI) <= TOLERANCE ||
                    Math.Abs(Math.Abs(_phi2) - HALF_PI) <= TOLERANCE)
                {
                    throw new ProjectionException(33);
                }
            }
            _ellips = Es > 0;
            double com = _ellips ? Math.Sqrt(OneEs) : 1;

            if (Math.Abs(Phi0) > EPS10)
            {
                double sinph0 = Math.Sin(Phi0);
                double cosph0 = Math.Cos(Phi0);
                if (_ellips)
                {
                    con = 1 - Es * sinph0 * sinph0;
                    _bl = cosph0 * cosph0;
                    _bl = Math.Sqrt(1 + Es * _bl * _bl / OneEs);
                    _al = _bl * K0 * com / con;
                    d   = _bl * com / (cosph0 * Math.Sqrt(con));
                }
                else
                {
                    _bl = 1;
                    _al = K0;
                    d   = 1 / cosph0;
                }

                if ((f = d * d - 1) <= 0)
                {
                    f = 0;
                }
                else
                {
                    f = Math.Sqrt(f);
                    if (Phi0 < 0)
                    {
                        f = -f;
                    }
                }
                _el = f += d;
                if (_ellips)
                {
                    _el *= Math.Pow(Proj.Tsfn(Phi0, sinph0, E), _bl);
                }
                else
                {
                    _el *= Tsfn0(Phi0);
                }
            }
            else
            {
                _bl = 1 / com;
                _al = K0;
                _el = d = f = 1;
            }
            if (azi)
            {
                _gamma        = Math.Asin(Math.Sin(_alpha) / d);
                Lam0          = _lamc - Math.Asin((.5 * (f - 1 / f)) * Math.Tan(_gamma)) / _bl;
                projInfo.Lam0 = Lam0;
            }
            else
            {
                double h;
                double l;
                if (_ellips)
                {
                    h = Math.Pow(Proj.Tsfn(_phi1, Math.Sin(_phi1), E), _bl);
                    l = Math.Pow(Proj.Tsfn(_phi2, Math.Sin(_phi2), E), _bl);
                }
                else
                {
                    h = Tsfn0(_phi1);
                    l = Tsfn0(_phi2);
                }
                f = _el / h;
                double p = (l - h) / (l + h);
                double j = _el * _el;
                j = (j - l * h) / (j + l * h);
                if ((con = _lam1 - _lam2) < -Math.PI)
                {
                    _lam2 -= Math.PI * 2;
                }
                else if (con > Math.PI)
                {
                    _lam2 += Math.PI * 2;
                }
                Lam0          = Proj.Adjlon(.5 * (_lam1 + _lam2) - Math.Atan(j * Math.Tan(.5 * _bl * (_lam1 - _lam2)) / p) / _bl);
                projInfo.Lam0 = Lam0;
                _gamma        = Math.Atan(2 * Math.Sin(_bl * Proj.Adjlon(_lam1 - Lam0)) / (f - 1 / f));
                _alpha        = Math.Asin(d * Math.Sin(_gamma));
            }
            _singam = Math.Sin(_gamma);
            _cosgam = Math.Cos(_gamma);
            if (projInfo.rot_conv.HasValue)
            {
                f = _alpha;
            }
            else
            {
                f = _gamma;
            }
            _sinrot = Math.Sin(f);
            _cosrot = Math.Cos(f);
            if (projInfo.no_uoff.HasValue)
            {
                _u0 = Math.Abs(_al * Math.Atan(Math.Sqrt(d * d - 1) / _cosrot) / _bl);
            }
            else
            {
                _u0 = 0;
            }
            if (Phi0 < 0)
            {
                _u0 = -_u0;
            }
        }