/// <summary> /// Compute the meridian convergence for a location /// </summary> /// <param name="point">The location defined by latitude/longitude</param> /// <returns>The meridian convergence</returns> public Angle MeridianConvergence(GlobalCoordinates point) { double scaleFactor; double meridianConvergence; var c = ToUtmCoordinates(point, out scaleFactor, out meridianConvergence); return(Angle.RadToDeg(meridianConvergence)); }
/// <summary> /// Convert the Y coordinate (in meters) on a Mercator map back into the longitude /// </summary> /// <param name="y">The Y coordinate (in meters) on a Mercator map</param> /// <returns>The longitude (in degrees)</returns> public override double YToLatitude(double y) { var ts = Math.Exp(-y / ReferenceGlobe.SemiMajorAxis); var phi = 0.5 * Math.PI - 2.0 * Math.Atan(ts); var dphi = 1.0; var i = 0; while ((Math.Abs(dphi) > 0.000000001) && (i < 15)) { var con = ReferenceGlobe.Eccentricity * Math.Sin(phi); dphi = 0.5 * Math.PI - 2.0 * Math.Atan(ts * Math.Pow((1.0 - con) / (1.0 + con), 0.5 * ReferenceGlobe.Eccentricity)) - phi; phi += dphi; i++; } var d = Angle.RadToDeg(phi); return(NormalizeLatitude(d).Degrees); }
/// <summary> /// Convert the X coordinate (in meters) on a Mercator map back into the longitude /// </summary> /// <param name="x">The X coordinate (in meters) on a Mercator map</param> /// <returns>The longitude (in degrees)</returns> public double XToLongitude(double x) { var longitude = ReferenceMeridian + Angle.RadToDeg(x / ReferenceGlobe.SemiMajorAxis); return(NormalizeLongitude(longitude).Degrees); }
/// <summary> /// Compute the meridian convergence for a location /// </summary> /// <param name="point">The location defined by latitude/longitude</param> /// <returns>The meridian convergence</returns> public Angle MeridianConvergence(GlobalCoordinates point) { ToUtmCoordinates(point, out _, out var meridianConvergence); return(Angle.RadToDeg(meridianConvergence)); }
internal GlobalCoordinates FromEuclidian( EuclidianCoordinate xy, out double scaleFactor, out double meridianConvergence) { if (!(xy is UtmCoordinate point)) { throw new ArgumentException(Properties.Resource.NO_UTM_COORDINATE); } var hemi = point.Grid.IsNorthern ? 1 : -1; var northingOffset = point.Grid.IsNorthern ? 0.0 : Southern_Northing_Offset; var chi = (point.Y - northingOffset) / (MathConsts.K0 * _m.A); var eta = (point.X - MathConsts.E0) / (MathConsts.K0 * _m.A); var sum = 0.0; for (var j = 1; j <= 3; j++) { sum += (_m.Beta[j - 1] * Math.Sin(2.0 * j * chi) * Math.Cosh(2.0 * j * eta)); } var chitick = chi - sum; sum = 0.0; for (var j = 1; j <= 3; j++) { sum += (_m.Beta[j - 1] * Math.Cos(2.0 * j * chi) * Math.Sinh(2.0 * j * eta)); } var etatick = eta - sum; sum = 0.0; for (var j = 1; j <= 3; j++) { sum += (2.0 * j * _m.Beta[j - 1] * Math.Cos(2.0 * j * chi) * Math.Cosh(2.0 * j * eta)); } var sigmatick = 1.0 - sum; var tautick = 0.0; for (var j = 1; j <= 3; j++) { tautick += (2.0 * j * _m.Beta[j - 1] * Math.Sin(2.0 * j * chi) * Math.Sinh(2.0 * j * eta)); } var xi = Math.Asin(Math.Sin(chitick) / Math.Cosh(etatick)); var phi = xi; for (var j = 1; j <= 3; j++) { phi += (_m.Delta[j - 1] * Math.Sin(2.0 * j * xi)); } var lambda0 = point.Grid.CenterMeridian.Radians; var lambda = lambda0 + Math.Atan(Math.Sinh(etatick) / Math.Cos(chitick)); var k = ((MathConsts.K0 * _m.A) / ReferenceGlobe.SemiMajorAxis) * Math.Sqrt(((Math.Pow(Math.Cos(chitick), 2.0) + Math.Pow(Math.Sinh(etatick), 2.0)) / (sigmatick * sigmatick + tautick * tautick)) * (1.0 + Math.Pow(((1.0 - _m.N) / (1.0 + _m.N)) * Math.Tan(phi), 2.0))); var gamma = Math.Atan((tautick + sigmatick * Math.Tan(chitick) * Math.Tanh(etatick)) / (sigmatick - tautick * Math.Tan(chitick) * Math.Tanh(etatick))) * hemi; scaleFactor = k; meridianConvergence = gamma; return(new GlobalCoordinates(Angle.RadToDeg(phi), Angle.RadToDeg(lambda))); }
/// <summary> /// Convert the Y coordinate (in meters) on a Mercator map back into the longitude /// </summary> /// <param name="y">The Y coordinate (in meters) on a Mercator map</param> /// <returns>The longitude (in degrees)</returns> public override double YToLatitude(double y) { var latitude = Angle.RadToDeg(2.0 * Math.Atan(Math.Exp(y / ReferenceGlobe.SemiMajorAxis)) - 0.5 * Math.PI); return(NormalizeLatitude(latitude).Degrees); }