/// <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; } } }
/// <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)); } }
/// <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]; }
/// <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)); } }
/// <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); }
/// <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); } } }
/// <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; } }
/// <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; } } }
/// <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; } }