Depende dos seus requisitos de precisão. Uma iteração do Heiskanen é eficiente, mas são necessárias três iterações para corresponder à precisão de uma única iteração do método de Bowring de 1985. Mesmo o algoritmo de Lin e Wang não pode corresponder à eficiência de Bowring, se as otimizações trigonométricas incluídas abaixo forem usadas. Portanto, para todo o desempenho, eu recomendaria o algoritmo de Bowring, de 1985.
-- Based on B. R. Bowring's 1985 algorithm (single iteration)
-----------------------------------------------------------------------------
function ECEF_to_Geo(ECEF : Vector3;
Datum : Datum_Id_Type) return Geographic_Type is
Spheroid : Spheroid_Type := EARTH.DATUMS.Spheroid(Datum);
x : Meters renames ECEF(1);
y : Meters renames ECEF(2);
z : Meters renames ECEF(3);
a : Meters renames Models(Spheroid).Semi_Major_Axis;
b : Meters renames Models(Spheroid).Semi_Minor_Axis;
e2 : Unitless renames Models(Spheroid).Eccentricity_Squared;
eb2 : Unitless renames Models(Spheroid).Second_Eccen_Squared;
a2 : Scalar := a**2;
d : Meters := eb2*b;
Ome2 : Unitless := 1.0 - e2;
p2, p, r, tu, tu2, su3, cu3, Phi, Lam, tp, cp, sp, h : Scalar;
Lat : Radians;
Lon : Radians;
Alt : Meters;
Geo : Geographic_Type;
begin -- ECEF_to_Geo
if ((x = 0.0) and (y = 0.0)) then
r := abs(z);
Phi := Scalar'copy_sign(Half_Pi, z);
Lam := 0.0;
h := r - b;
elsif (z = 0.0) then
Phi := 0.0;
Lam := arctan(y, x);
p := sqrt(x**2 + y**2);
h := p - a;
else
p2 := x**2 + y**2;
p := sqrt(p2);
r := sqrt(p2 + z**2);
tu := b*z*(1.0 + d/r)/(a*p);
tu2 := tu**2;
cu3 := (1.0/sqrt(1.0 + tu2))**3;
su3 := cu3*tu2*tu;
tp := (z + d*su3)/(p - e2*a*cu3);
Phi := arctan(tp);
Lam := arctan(y, x);
cp := 1.0/sqrt(1.0 + tp**2);
sp := cp*tp;
h := p*cp + z*sp - a*sqrt(1.0 - e2*sp**2);
end if;
Lat := Radians(Phi);
Lon := Radians(Lam);
Alt := h;
Geo := Make_Geo(Lat, Lon, Alt, Datum);
return Geo;
end ECEF_to_Geo;