ecef2geodetic#
- ahrs.common.frames.ecef2geodetic(x: float, y: float, z: float, a: float = 6378137.0, b: float = 6356752.3142) ndarray#
Transform cartesian coordinates in ECEF-frame to Geodetic Coordinates [ZHP11].
Given the Cartesian coordinates \(\begin{pmatrix}x & y & z\end{pmatrix}\) in the Earth-Centered Earth-Fixed (ECEF) frame, we can start by computing the geodetic longitude \(\lambda\):
\[\lambda = \mathrm{arctan2}\left(x, \,y\right)\]Then, we iteratively compute the geodetic latitude \(\phi\) using the initial estimation:
\[\phi_0 = \mathrm{arctan2}\big(z, \,(1-e^2)p \big)\]with \(p = \sqrt{x^2 + y^2}\).
Now we iterate until the difference between two consecutive latitudes (\(\phi_i\) and \(\phi_{i-1}\)) is smaller than a given threshold \(\delta\). Each iteration updates the values as follows:
\[\begin{split}\begin{array}{rcl} N & \leftarrow & \frac{a}{\sqrt{1 - e^2 \sin^2(\phi_{i-1})}} \\ \phi_i & \leftarrow & \mathrm{arctan2}\big(z+e^2N\sin(\phi_{i-1}), \,p\big) \end{array}\end{split}\]where \(N\) is the radius of curvature in the vertical prime, and \(e^2\) is the square of the first eccentricity of the ellipsoid.
\[e^2 = \frac{a^2-b^2}{a^2}\]The value of \(\delta\) is empirically found to perform well when set to \(10^{-8}\) in this implementation.
The altitude (height) \(h\) is computed as:
\[h = \frac{p}{\cos\phi} - N\]Note
The altitude \(h\) has an accuracy up to 0.1 m (10 cm), which is enough for most applications.
The latitude and longitude are returned in degrees. The altitude is returned in meters.
- Parameters:
x (float) – ECEF x-coordinate, in meters.
y (float) – ECEF y-coordinate, in meters.
z (float) – ECEF z-coordinate, in meters.
a (float, default: 6378137.0) – Ellipsoid’s equatorial radius, in meters. Defaults to Earth’s.
b (float, default: 6356752.3142) – Ellipsoid’s polar radius, in meters. Defaults to Earth’s.
- Returns:
lla – Geodetic coordinates [latitude, longitude, altitude].
- Return type:
numpy.ndarray
Examples
>>> from ahrs.common.frames import ecef2geodetic >>> x = 4_201_000 >>> y = 172_460 >>> z = 4_780_100 >>> ecef2geodetic(x, y, z) array([48.85616162, 2.35079383, 67.37006803])