Phụ thuộc vào yêu cầu chính xác của bạn. Một lần lặp của Heiskanen là hiệu quả, nhưng phải mất 3 lần lặp để phù hợp với độ chính xác của một lần lặp của phương pháp 1985 của Bowring. Ngay cả thuật toán của Lin và Wang cũng không thể phù hợp với hiệu quả của Bowring, nếu tối ưu hóa lượng giác bao gồm bên dưới được sử dụng. Do đó, đối với tất cả xung quanh hiệu suất, tôi muốn giới thiệu thuật toán 1985 của Bowring.
-- 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;