private static LatitudeLongtitude CalculateAiry1830(OSGB36 coordinates, double latitude, double transverseRadiusOfCurvature, double eccentricitySquared) { var meridionalRadiusOfCurvature = Airy180SemiMajorAxis * ScaleFactorOnCentralMeridian * (1 - eccentricitySquared) * Math.Pow((1 - (eccentricitySquared * latitude.SinToPower(2))), -1.5); var eta2 = (transverseRadiusOfCurvature / meridionalRadiusOfCurvature) - 1; var secLat = 1.0 / Math.Cos(latitude); var vii = Math.Tan(latitude) / (2 * meridionalRadiusOfCurvature * transverseRadiusOfCurvature); var viii = Math.Tan(latitude) / (24 * meridionalRadiusOfCurvature * Math.Pow(transverseRadiusOfCurvature, 3)) * (5 + 3 * latitude.TanToPower(2) + eta2 - 9 * latitude.TanToPower(2) * eta2); var ix = Math.Tan(latitude) / (720 * meridionalRadiusOfCurvature * Math.Pow(transverseRadiusOfCurvature, 5)) * (61 + 90 * latitude.TanToPower(2) + 45 * latitude.TanToPower(4)); var x = secLat / transverseRadiusOfCurvature; var xi = secLat / (6 * Math.Pow(transverseRadiusOfCurvature, 3)) * (transverseRadiusOfCurvature / meridionalRadiusOfCurvature + 2 * latitude.TanToPower(2)); var xii = secLat / (120 * Math.Pow(transverseRadiusOfCurvature, 5)) * (5 + 28 * latitude.TanToPower(2) + 24 * latitude.TanToPower(4)); var xiia = secLat / (5040 * Math.Pow(transverseRadiusOfCurvature, 7)) * (61 + 662 * latitude.TanToPower(2) + 1320 * latitude.TanToPower(4) + 720 * latitude.TanToPower(6)); var eastingDifference = coordinates.Easting - EastingOfTrueOrigin; return(new LatitudeLongtitude { Latitude = latitude - vii * Math.Pow(eastingDifference, 2) + viii * Math.Pow(eastingDifference, 4) - ix * Math.Pow(eastingDifference, 6), Longtitude = LongtitudeOfTrueOrigin + x * eastingDifference - xi * Math.Pow(eastingDifference, 3) + xii * Math.Pow(eastingDifference, 5) - xiia * Math.Pow(eastingDifference, 7) }); }
public static WGS84 Convert(OSGB36 coordinates) { var latitude = InitializeLatitude(coordinates); var grs80 = CalculateGrs80(coordinates, latitude); latitude = RecalculateLatitude(grs80); return(new WGS84 { Latitude = latitude * 180 / Math.PI, Longtitude = Math.Atan2(grs80.Y, grs80.X) * 180 / Math.PI }); }
private static Cartesian CalculateGrs80(OSGB36 coordinates, double latitude) { var eccentricitySquared = 1 - (Math.Pow(Airy180SemiMinorAxis, 2) / Math.Pow(Airy180SemiMajorAxis, 2)); var transverseRadiusOfCurvature = Airy180SemiMajorAxis * ScaleFactorOnCentralMeridian / Math.Sqrt(1 - (eccentricitySquared * latitude.SinToPower(2))); var airy1830 = CalculateAiry1830(coordinates, latitude, transverseRadiusOfCurvature, eccentricitySquared); var cartesian = new Cartesian { X = (transverseRadiusOfCurvature / ScaleFactorOnCentralMeridian) * Math.Cos(airy1830.Latitude) * Math.Cos(airy1830.Longtitude), Y = (transverseRadiusOfCurvature / ScaleFactorOnCentralMeridian) * Math.Cos(airy1830.Latitude) * Math.Sin(airy1830.Longtitude), Z = ((1 - eccentricitySquared) * transverseRadiusOfCurvature / ScaleFactorOnCentralMeridian) * Math.Sin(airy1830.Latitude) }; var grs80 = new Cartesian { X = 446.448 + (1 + ScaleFactor) * cartesian.X - ZRadians * cartesian.Y + YRadians * cartesian.Z, Y = -125.157 + ZRadians * cartesian.X + (1 + ScaleFactor) * cartesian.Y - XRadians * cartesian.Z, Z = 542.060 - YRadians * cartesian.X + XRadians * cartesian.Y + (1 + ScaleFactor) * cartesian.Z }; return(grs80); }
private static double InitializeLatitude(OSGB36 coordinates) { var latitude = LatitudeOfTrueOrigin; var meridionalArc = 0.0; while (coordinates.Northing - NorthingOfTrueOrigin - meridionalArc >= 0.00001) { latitude += (coordinates.Northing - NorthingOfTrueOrigin - meridionalArc) / (Airy180SemiMajorAxis * ScaleFactorOnCentralMeridian); var meridionalArc1 = (1.0 + N + (1.25 * Math.Pow(N, 2)) + (1.25 * Math.Pow(N, 3))) * (latitude - LatitudeOfTrueOrigin); var meridionalArc2 = ((3 * N) + (3 * Math.Pow(N, 2)) + ((21.0 / 8) * Math.Pow(N, 3))) * Math.Sin(latitude - LatitudeOfTrueOrigin) * Math.Cos(latitude + LatitudeOfTrueOrigin); var meridionalArc3 = ((15.0 / 8) * Math.Pow(N, 2) + (15.0 / 8) * Math.Pow(N, 3)) * Math.Sin(2 * (latitude - LatitudeOfTrueOrigin)) * Math.Cos(2 * (latitude + LatitudeOfTrueOrigin)); var meridionalArc4 = (35.0 / 24) * Math.Pow(N, 3) * Math.Sin(3 * (latitude - LatitudeOfTrueOrigin)) * Math.Cos(3 * (latitude + LatitudeOfTrueOrigin)); meridionalArc = Airy180SemiMinorAxis * ScaleFactorOnCentralMeridian * (meridionalArc1 - meridionalArc2 + meridionalArc3 - meridionalArc4); } return(latitude); }