/// <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) { _phi1 = projInfo.Phi1; if (Math.Abs(_phi1) < EPS10) { throw new ProjectionException(-23); } if (Es > 0) { _en = Proj.Enfn(Es); double c; _m1 = Proj.Mlfn(_phi1, _am1 = Math.Sin(_phi1), c = Math.Cos(_phi1), _en); _am1 = c / (Math.Sqrt(1 - Es * _am1 * _am1) * _am1); } else { if (Math.Abs(_phi1) + EPS10 >= HALF_PI) { _cphi1 = 0; } else { _cphi1 = 1 / Math.Tan(_phi1); } } }
/// <inheritdoc /> protected override void EllipticalForward(double[] lp, double[] xy, int startIndex, int numPoints) { if (_isGuam) { GuamForward(lp, xy, startIndex, numPoints); return; } 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 coslam = Math.Cos(lp[lam]); double cosphi = Math.Cos(lp[phi]); double sinphi = Math.Sin(lp[phi]); switch (_mode) { case Modes.NorthPole: case Modes.SouthPole: if (_mode == Modes.NorthPole) { coslam = -coslam; } double rho; xy[x] = (rho = Math.Abs(_mp - Proj.Mlfn(lp[phi], sinphi, cosphi, _en))) * Math.Sin(lp[lam]); xy[y] = rho * coslam; break; case Modes.Equitorial: case Modes.Oblique: if (Math.Abs(lp[lam]) < EPS10 && Math.Abs(lp[phi] - Phi0) < EPS10) { xy[x] = xy[y] = 0; break; } double t = Math.Atan2(OneEs * sinphi + Es * _n1 * _sinph0 * Math.Sqrt(1 - Es * sinphi * sinphi), cosphi); double ct = Math.Cos(t); double st = Math.Sin(t); double az = Math.Atan2(Math.Sin(lp[lam]) * ct, _cosph0 * st - _sinph0 * coslam * ct); double cA = Math.Cos(az); double sA = Math.Sin(az); double s = Math.Asin(Math.Abs(sA) < TOL ? (_cosph0 * st - _sinph0 * coslam * ct) / cA : Math.Sin(lp[lam]) * ct / sA); double h = _he * cA; double h2 = h * h; double c = _n1 * s * (1 + s * s * (-h2 * (1 - h2) / 6 + s * (_g * h * (1 - 2 * h2 * h2) / 8 + s * ((h2 * (4 - 7 * h2) - 3 * _g * _g * (1 - 7 * h2)) / 120 - s * _g * h / 48)))); xy[x] = c * sA; xy[y] = c * cA; break; } } }
/// <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 (!IsElliptical) { return; } _en = Proj.Enfn(Es); _m0 = Proj.Mlfn(Phi0, Math.Sin(Phi0), Math.Cos(Phi0), _en); }
/// <inheritdoc /> protected override void EllipticalInverse(double[] xy, double[] lp, 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; xy[y] += _ml0; if (Math.Abs(xy[y]) <= TOL) { lp[lam] = xy[x]; lp[phi] = 0; } else { double c; int j; double r = xy[y] * xy[y] + xy[x] * xy[x]; for (lp[phi] = xy[y], j = ITER; j > 0; --j) { double sp = Math.Sin(lp[phi]); double cp; double s2Ph = sp * (cp = Math.Cos(lp[phi])); if (Math.Abs(cp) < ITOL) { lp[lam] = double.NaN; lp[phi] = double.NaN; continue; //ProjectionException(20); } double mlp; c = sp * (mlp = Math.Sqrt(1 - Es * sp * sp)) / cp; double ml = Proj.Mlfn(lp[phi], sp, cp, _en); double mlb = ml * ml + r; mlp = OneEs / (mlp * mlp * mlp); double dPhi; lp[phi] += (dPhi = (ml + ml + c * mlb - 2 * xy[y] * (c * ml + 1)) / (Es * s2Ph * (mlb - 2 * xy[y] * ml) / c + 2 * (xy[y] - ml) * (c * mlp - 1 / s2Ph) - mlp - mlp)); if (Math.Abs(dPhi) <= ITOL) { break; } } if (j == 0) { lp[lam] = double.NaN; lp[phi] = double.NaN; continue; //ProjectionException(20); } c = Math.Sin(lp[phi]); lp[lam] = Math.Asin(xy[x] * Math.Tan(lp[phi]) * Math.Sqrt(1 - Es * c * c)) / Math.Sin(lp[phi]); } } }
/// <summary> /// This exists in the case that we ever develop code to perform the special proj4 calculations /// </summary> /// <param name="lp"></param> /// <param name="p"></param> /// <param name="fac"></param> protected override void OnSpecial(double[] lp, ProjectionInfo p, Factors fac) { double sinphi = Math.Sin(lp[PHI]); double cosphi = Math.Cos(lp[PHI]); fac.Code = fac.Code | AnalyticModes.IsAnalHk; fac.H = 1; fac.K = _n * (_c - (IsElliptical ? Proj.Mlfn(lp[PHI], sinphi, cosphi, _en) : lp[PHI])) / Proj.Msfn(sinphi, cosphi, Es); }
/// <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 (IsElliptical) { _en = Proj.Enfn(Es); _ml0 = Proj.Mlfn(Phi0, Math.Sin(Phi0), Math.Cos(Phi0), _en); } else { _ml0 = -Phi0; } }
/// <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) { Phi0 = projInfo.Phi0; if (Math.Abs(Math.Abs(Phi0) - HALF_PI) < EPS10) { _mode = Phi0 < 0 ? Modes.SouthPole : Modes.NorthPole; _sinph0 = Phi0 < 0 ? -1 : 1; _cosph0 = 0; } else if (Math.Abs(Phi0) < EPS10) { _mode = Modes.Equitorial; _sinph0 = 0; _cosph0 = 1; } else { _mode = Modes.Oblique; _sinph0 = Math.Sin(Phi0); _cosph0 = Math.Cos(Phi0); } if (Es == 0) { return; } _en = Proj.Enfn(Es); if (projInfo.guam.HasValue && projInfo.guam.Value) { _m1 = Proj.Mlfn(Phi0, _sinph0, _cosph0, _en); _isGuam = true; } else { switch (_mode) { case Modes.NorthPole: _mp = Proj.Mlfn(HALF_PI, 1, 0, _en); break; case Modes.SouthPole: _mp = Proj.Mlfn(-HALF_PI, -1, 0, _en); break; case Modes.Equitorial: case Modes.Oblique: _n1 = 1 / Math.Sqrt(1 - Es * _sinph0 * _sinph0); _g = _sinph0 * (_he = E / Math.Sqrt(OneEs)); _he *= _cosph0; break; } } }
/// <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 s, c; xy[y] = Proj.Mlfn(lp[phi], s = Math.Sin(lp[phi]), c = Math.Cos(lp[phi]), _en); xy[x] = lp[lam] * c / Math.Sqrt(1 - Es * s * s); } }
/// <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 e, c; double rh = _am1 + _m1 - Proj.Mlfn(lp[phi], e = Math.Sin(lp[phi]), c = Math.Cos(lp[phi]), _en); e = c * lp[lam] / (rh * Math.Sqrt(1 - Es * e * e)); xy[x] = rh * Math.Sin(e); xy[y] = _am1 - rh * Math.Cos(e); } }
/// <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; if (projInfo.StandardParallel1 != null) { _phi1 = projInfo.StandardParallel1.Value * Math.PI / 180; } if (projInfo.StandardParallel2 != null) { _phi2 = projInfo.StandardParallel2.Value * Math.PI / 180; } if (Math.Abs(_phi1 + _phi2) < EPS10) { throw new ProjectionException(-21); } _en = Proj.Enfn(Es); _n = sinphi = Math.Sin(_phi1); double cosphi = Math.Cos(_phi1); bool secant = Math.Abs(_phi1 - _phi2) >= EPS10; if (IsElliptical) { double m1 = Proj.Msfn(sinphi, cosphi, Es); double ml1 = Proj.Mlfn(_phi1, sinphi, cosphi, _en); if (secant) { /* secant cone */ sinphi = Math.Sin(_phi2); cosphi = Math.Cos(_phi2); _n = (m1 - Proj.Msfn(sinphi, cosphi, Es)) / (Proj.Mlfn(_phi2, sinphi, cosphi, _en) - ml1); } _c = ml1 + m1 / _n; _rho0 = _c - Proj.Mlfn(Phi0, Math.Sin(Phi0), Math.Cos(Phi0), _en); } else { if (secant) { _n = (cosphi - Math.Cos(_phi2)) / (_phi2 - _phi1); } _c = _phi1 + Math.Cos(_phi1) / _n; _rho0 = _c - Phi0; } }
private void GuamForward(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 cosphi = Math.Cos(lp[phi]); double sinphi = Math.Sin(lp[phi]); double t = 1 / Math.Sqrt(1 - Es * sinphi * sinphi); xy[x] = lp[lam] * cosphi * t; xy[y] = Proj.Mlfn(lp[phi], sinphi, cosphi, _en) - _m1 + .5 * lp[lam] * lp[lam] * cosphi * sinphi * t; } }
/// <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; _rho = _c - (IsElliptical ? Proj.Mlfn(lp[phi], Math.Sin(lp[phi]), Math.Cos(lp[phi]), _en) : lp[phi]); xy[x] = _rho * Math.Sin(lp[lam] *= _n); xy[y] = _rho0 - _rho * Math.Cos(lp[lam]); } }
/// <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; xy[y] = Proj.Mlfn(lp[phi], _n = Math.Sin(lp[phi]), _c = Math.Cos(lp[phi]), _en); _n = 1 / Math.Sqrt(1 - Es * _n * _n); _tn = Math.Tan(lp[phi]); _t = _tn * _tn; _a1 = lp[lam] * _c; _c *= Es * _c / (1 - Es); _a2 = _a1 * _a1; xy[x] = _n * _a1 * (1 - _a2 * _t * (C1 - (8 - _t + 8 * _c) * _a2 * C2)); xy[y] -= _m0 - _n * _tn * _a2 * (.5 + (5 - _t + 6 * _c) * _a2 * C3); } }
/// <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(lp[phi]) <= TOL) { xy[x] = lp[lam]; xy[y] = -_ml0; } else { double sp = Math.Sin(lp[phi]); double cp; double ms = Math.Abs(cp = Math.Cos(lp[phi])) > TOL?Proj.Msfn(sp, cp, Es) / sp : 0; xy[x] = ms * Math.Sin(lp[lam] *= sp); xy[y] = (Proj.Mlfn(lp[phi], sp, cp, _en) - _ml0) + ms * (1 - Math.Cos(lp[lam])); } } }