/// <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.AuxiliarySphereType == AuxiliarySphereType.AuthalicWithConvertedLatitudes) { throw new NotSupportedException("The conversion which requries latitude conversion to authalic latitudes is not yet supported"); } double phits = 0.0; bool isPhits = false; if (projInfo.StandardParallel1 != null) { isPhits = true; phits = projInfo.Phi1; if (phits >= HALF_PI) throw new ProjectionException(-24); } if (IsElliptical) { /* ellipsoid */ if (isPhits) K0 = Proj.Msfn(Math.Sin(phits), Math.Cos(phits), Es); } else { /* sphere */ if (isPhits) K0 = Math.Cos(phits); } if (projInfo.AuxiliarySphereType == AuxiliarySphereType.AuthalicWithConvertedLatitudes) { Spheroid sph = new(Proj4Ellipsoid.WGS_1984); _ae = Math.Acos(sph.PolarRadius / sph.EquatorialRadius); _geodeticToAuthalic = true; } }
/// <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 phits = 0.0; bool isPhits = false; if (projInfo.StandardParallel1 != null) { isPhits = true; phits = projInfo.Phi1; if (phits >= HALF_PI) { throw new ProjectionException(-24); } } if (IsElliptical) { /* ellipsoid */ if (isPhits) { K0 = Proj.Msfn(Math.Sin(phits), Math.Cos(phits), Es); } } else { /* sphere */ if (isPhits) { K0 = Math.Cos(phits); } } }
/// <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) { 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; } }
/// <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]; }
/// <summary> /// Internal code handling the setup operations for the transform /// </summary> protected void Setup() { double sinphi; 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; if (IsElliptical) { double m1 = Proj.Msfn(sinphi, cosphi, Es); double ml1 = Proj.Qsfn(sinphi, E, OneEs); if (secant) { /* secant cone */ sinphi = Math.Sin(_phi2); cosphi = Math.Cos(_phi2); double m2 = Proj.Msfn(sinphi, cosphi, Es); double ml2 = Proj.Qsfn(sinphi, E, OneEs); _n = (m1 * m1 - m2 * m2) / (ml2 - ml1); } _ec = 1 - .5 * OneEs * Math.Log((1 - E) / (1 + E)) / E; _c = m1 * m1 + _n * ml1; _dd = 1 / _n; _rho0 = _dd * Math.Sqrt(_c - _n * Proj.Qsfn(Math.Sin(Phi0), E, OneEs)); } else { if (secant) { _n = .5 * (_n + Math.Sin(_phi2)); } _n2 = _n + _n; _c = cosphi * cosphi + _n2 * sinphi; _dd = 1 / _n; _rho0 = _dd * Math.Sqrt(_c - _n2 * Math.Sin(Phi0)); } }
/// <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])); } } }
/// <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); } } }