public static GeoPoint3 EcefToGeodetic(Vector3 ecef, GeoDatum datum) { const double precision2 = 1e-6; const int maxIterations = 16; var norm = ecef.Norm; var phi = Math.Atan2(ecef.Y, ecef.X); var theta0 = BasicMath.Asin(ecef.Z / ecef.Norm); // first approximation var h0 = norm - datum.Semiminor; // first approximation var theta = theta0; var h = h0; var error2 = double.PositiveInfinity; for (var i = 0; i < maxIterations && error2 > precision2; i++) { var ecefPrime = new GeoPoint3(theta, phi, h).ToEcef(datum); var normPrime = ecefPrime.Norm; var thetaSphere = BasicMath.Asin(ecefPrime.Z / normPrime); var hSphere = normPrime - datum.Semiminor; theta += theta0 - thetaSphere; h += h0 - hSphere; error2 = Vector3.Distance2(ecef, ecefPrime); } return(new GeoPoint3(theta, phi, h)); }