/// <summary> /// Converts Geodetic coords to Geocentric cartesian. /// </summary> /// <param name="GeodeticLat">Geodetic lat in degrees.</param> /// <param name="GeodeticLon">Geodetic lon in degrees.</param> /// <param name="GeodeticHeight">Geodetic height in meters.</param> /// <param name="GeocentricX">Geocentric x.</param> /// <param name="GeocentricY">Geocentric y.</param> /// <param name="GeocentricZ">Geocentric z.</param> /// <param name="R">R.</param> public static void GeodeticToGeocentric(double GeodeticLat, double GeodeticLon, double GeodeticHeight, out double GeocentricX, out double GeocentricY, out double GeocentricZ, RefEllipsoid R) { GeodeticLat = DegToRad(GeodeticLat); GeodeticLon = DegToRad(GeodeticLon); double MajorAxis, MinorAxis; GetEllipsoidAxis(R, out MajorAxis, out MinorAxis); double Esq = (Math.Pow(MajorAxis, 2) - Math.Pow(MinorAxis, 2)) / Math.Pow(MajorAxis, 2); double V = MajorAxis / Math.Sqrt(1 - (Esq * Math.Pow(Math.Sin(GeodeticLat), 2))); GeocentricX = (V + GeodeticHeight) * Math.Cos(GeodeticLat) * Math.Cos(GeodeticLon); GeocentricY = (V + GeodeticHeight) * Math.Cos(GeodeticLat) * Math.Sin(GeodeticLon); GeocentricZ = ((1 - Esq) * V + GeodeticHeight) * Math.Sin(GeodeticLat); }
public static void GeocentricToGeodetic(double x, double y, double z, out double lat, out double lon, out double alt, RefEllipsoid R) { double a, b, t; GetEllipsoidAxis(R, out a, out b); double e2 = 1.0 - (b * b) / (a * a); // 1st eccentricity sqrd double ed2 = (a * a) / (b * b) - 1.0; // 2nd eccentricity sqrd double a2 = a * a; double b2 = b * b; double z2 = z * z; double e4 = e2 * e2; double r2 = x * x + y * y; double r = Math.Sqrt(r2); double E2 = a2 - b2; double F = 54.0 * b2 * z2; double G = r2 + (1.0 - e2) * z2 - e2 * E2; double C = e4 * F * r2 / (G * G * G); double S = Math.Pow(1.0 + C + Math.Sqrt(C * C + 2.0 * C), 1.0 / 3.0); t = S + 1.0 / S + 1.0; double P = F / (3.0 * t * t * G * G); double Q = Math.Sqrt(1.0 + 2.0 * e4 * P); double r0 = -(P * e2 * r) / (1.0 + Q) + Math.Sqrt(0.5 * a2 * (1.0 + 1.0 / Q) - (P * (1 - e2) * z2) / (Q * (1.0 + Q)) - 0.5 * P * r2); t = r - e2 * r0; double U = Math.Sqrt(t * t + z2); double V = Math.Sqrt(t * t + (1.0 - e2) * z2); t = b2 / (a * V); alt = U * (1.0 - t); lat = Math.Atan2(z + ed2 * t * z, r); lon = Math.Atan2(y, x); // convert to degrees lat = RadToDeg(lat); lon = RadToDeg(lon); }
public static void GetEllipsoidAxis(RefEllipsoid R, out double MajorAxis, out double MinorAxis) { switch (R) { case RefEllipsoid.Airy: MajorAxis = 6377563.396; MinorAxis = 6356256.909; // 1/F 299.324965 break; case RefEllipsoid.Airy_Modified: MajorAxis = 6377340.189; MinorAxis = 6356034.448; // 1/F 299.324965 break; case RefEllipsoid.Australian_National: MajorAxis = 6378160.000; MinorAxis = 6356774.719; // 1/F 298.250000 break; case RefEllipsoid.Bessel_1841: MajorAxis = 6377397.155; MinorAxis = 6356078.963; // 1/F 299.152813 break; case RefEllipsoid.Bessel_1841_Namibia: MajorAxis = 6377483.865; MinorAxis = 6356078.963; // 1/F 299.152813 break; case RefEllipsoid.Clarke_1866: MajorAxis = 6378206.400; MinorAxis = 6356583.800; // 1/F 294.978698 break; case RefEllipsoid.Clarke_1880: MajorAxis = 6378249.145; MinorAxis = 6356514.870; // 1/F 293.465000 break; case RefEllipsoid.Everest_Sabah_Sarawak: MajorAxis = 6377298.556; MinorAxis = 6356097.550; // 1/F 300.801700 break; case RefEllipsoid.Everest_1830: MajorAxis = 6377276.345; MinorAxis = 6356075.413; // 1/F 300.801700 break; case RefEllipsoid.Everest_1948: MajorAxis = 6377304.063; MinorAxis = 6356103.039; // 1/F 300.801700 break; case RefEllipsoid.Everest_1956: MajorAxis = 6377301.243; MinorAxis = 6356100.228; // 1/F 300.801700 break; case RefEllipsoid.Everest_1969: MajorAxis = 6377295.664; MinorAxis = 6356094.668; // 1/F 300.801700 break; case RefEllipsoid.Fischer_1960: MajorAxis = 6378166.000; MinorAxis = 6356784.284; // 1/F 298.300000 break; case RefEllipsoid.Fischer_1960_Modified: MajorAxis = 6378155.000; MinorAxis = 6356773.320; // 1/F 298.300000 break; case RefEllipsoid.Fischer_1968: MajorAxis = 6378150.000; MinorAxis = 6356768.337; // 1/F 298.300000 break; case RefEllipsoid.GRS_1980: MajorAxis = 6378137.000; MinorAxis = 6356752.314; // 1/F 298.257222 break; case RefEllipsoid.Helmert_1906: MajorAxis = 6378200.000; MinorAxis = 6356818.170; // 1/F 298.300000 break; case RefEllipsoid.Hough: MajorAxis = 6378270.000; MinorAxis = 6356794.343; // 1/F 297.000000 break; case RefEllipsoid.International_1924: MajorAxis = 6378388.000; MinorAxis = 6356911.946; // 1/F 297.000000 break; case RefEllipsoid.Karsovsky_1940: MajorAxis = 6378245.000; MinorAxis = 6356863.019; // 1/F 298.300000 break; case RefEllipsoid.SGS_1985: MajorAxis = 6378136.000; MinorAxis = 6356751.302; // 1/F 298.257000 break; case RefEllipsoid.South_American_1969: MajorAxis = 6378160.000; MinorAxis = 6356774.719; // 1/F 298.250000 break; case RefEllipsoid.Sphere_6371km: MajorAxis = 6371000; MinorAxis = 6371000; break; case RefEllipsoid.WGS_1960: MajorAxis = 6378165.000; MinorAxis = 6356783.287; // 1/F 298.300000 break; case RefEllipsoid.WGS_1966: MajorAxis = 6378145.000; MinorAxis = 6356759.769; // 1/F 298.250000 break; case RefEllipsoid.WGS_1972: MajorAxis = 6378135.000; MinorAxis = 6356750.520; // 1/F 298.260000 break; case RefEllipsoid.WGS_1984: MajorAxis = 6378137.000; MinorAxis = 6356752.314245; // 1/F 298.257224 break; default: // TODO: evaluate, what default value should be assigned? MajorAxis = 0; MinorAxis = 0; break; } }