XYZ座標の形で表された人工衛星の位置を、緯度・経度・高度に変換したいとき、ざっくりでよければ地球を球体と仮定してarctanを使って求めることはできる。
ただ、もう少しきちんと求める場合には、地球を回転楕円体として考えるべきで、この場合の変換はそれほど簡単ではない。
ECEF(Earth Centered Earth Fixed)座標から測地(geodetic)座標への効率的な変換方法の開発は、多くの研究者の興味を集めてきたトピックで、何十年も前から最近まで多くの論文が発表されている。
ECEF座標と測地(geodetic)座標の関係
まず地球表面上の点r s i t e \boldsymbol{r}_\mathrm{site} r site を式で表すことを考えよう。
地球はおおよそ回転楕円体Spheroid(楕円体Ellipsoidのうち1軸に関しては軸対称なもの)で、地軸回りで対称、南北方向に少し押しつぶしたような形をしているので、以下のように表すことができる。
ここでφ r d \varphi_\mathrm{rd} φ rd はreduced latitudeと呼ばれるもので、geocentric latitude φ g c \varphi_\mathrm{gc} φ gc ではないことに注意しよう。
r s i t e = [ R ⊕ cos φ r d cos λ R ⊕ cos φ r d sin λ b ⊕ sin φ r d ] \begin{gather}
\boldsymbol{r}_\mathrm{site} = \left[ \begin{array}{c}
R_\oplus \cos\varphi_\mathrm{rd} \cos\lambda \\
R_\oplus \cos\varphi_\mathrm{rd} \sin\lambda \\
b_\oplus \sin\varphi_\mathrm{rd} \end{array} \right]
\end{gather} r site = R ⊕ cos φ rd cos λ R ⊕ cos φ rd sin λ b ⊕ sin φ rd
Figure 1: Spheroidal Earth Geometry and Geodetic Coordinate Parameters.
一方で、geocentric latitude φ g c \varphi_\mathrm{gc} φ gc を使って表すこともできるはずで、r s i t e r_\mathrm{site} r site は何かしらの緯度の関数になる。
r s i t e = [ r s i t e cos φ g c cos λ r s i t e cos φ g c sin λ r s i t e sin φ g c ] \begin{gather}
\boldsymbol{r}_\mathrm{site} = \left[ \begin{array}{c}
r_\mathrm{site} \cos\varphi_\mathrm{gc} \cos\lambda \\
r_\mathrm{site} \cos\varphi_\mathrm{gc} \sin\lambda \\
r_\mathrm{site} \sin\varphi_\mathrm{gc} \end{array} \right]
\end{gather} r site = r site cos φ gc cos λ r site cos φ gc sin λ r site sin φ gc
これらの式を見比べると、φ r d \varphi_\mathrm{rd} φ rd とφ g c \varphi_\mathrm{gc} φ gc の間に以下の関係が得られる。
tan φ g c = b ⊕ R ⊕ tan φ r d \begin{gather}
\tan \varphi_\mathrm{gc} = \frac{b_\oplus}{R_\oplus} \tan \varphi_\mathrm{rd}
\end{gather} tan φ gc = R ⊕ b ⊕ tan φ rd
次に、φ r d \varphi_\mathrm{rd} φ rd とφ g d \varphi_\mathrm{gd} φ gd の関係を導く。
r s i t e \boldsymbol{r}_\mathrm{site} r site での接面の方向は、φ r d \varphi_\mathrm{rd} φ rd とλ \lambda λ について微分してやると分かる。
d d φ r d r s i t e = [ − R ⊕ sin φ r d cos λ − R ⊕ sin φ r d sin λ b ⊕ cos φ r d ] , d d λ r s i t e = [ − R ⊕ cos φ r d sin λ + R ⊕ cos φ r d cos λ 0 ] . \begin{align}
\frac{d}{d\varphi_\mathrm{rd}} \boldsymbol{r}_\mathrm{site} &= \left[ \begin{array}{c}
-R_\oplus \sin\varphi_\mathrm{rd} \cos\lambda \\
-R_\oplus \sin\varphi_\mathrm{rd} \sin\lambda \\
b_\oplus \cos\varphi_\mathrm{rd} \end{array} \right], \\
\frac{d}{d\lambda} \boldsymbol{r}_\mathrm{site} &=
\left[ \begin{array}{c}
-R_\oplus\cos\varphi_\mathrm{rd} \sin\lambda \\
+R_\oplus\cos\varphi_\mathrm{rd} \cos\lambda \\
0
\end{array} \right]. \\
\end{align} d φ rd d r site d λ d r site = − R ⊕ sin φ rd cos λ − R ⊕ sin φ rd sin λ b ⊕ cos φ rd , = − R ⊕ cos φ rd sin λ + R ⊕ cos φ rd cos λ 0 .
で、これをよく見ると、r s i t e \bm{r}_\mathrm{site} r site での法線方向が分かる。
n = [ b ⊕ cos φ r d cos λ b ⊕ cos φ r d sin λ R ⊕ sin φ r d ] \begin{gather}
\boldsymbol{n} = \left[ \begin{array}{c}
b_\oplus \cos\varphi_\mathrm{rd} \cos\lambda \\
b_\oplus \cos\varphi_\mathrm{rd} \sin\lambda \\
R_\oplus \sin\varphi_\mathrm{rd}
\end{array} \right]
\end{gather} n = b ⊕ cos φ rd cos λ b ⊕ cos φ rd sin λ R ⊕ sin φ rd
法線方向が分かると、reduced latitude φ r d \varphi_\mathrm{rd} φ rd とgeodetic latitude φ g d \varphi_\mathrm{gd} φ gd の関係を求めることができる。
tan φ g d = R ⊕ b ⊕ tan φ r d \begin{gather}
\tan \varphi_\mathrm{gd} = \frac{R_\oplus}{b_\oplus} \tan \varphi_\mathrm{rd}
\end{gather} tan φ gd = b ⊕ R ⊕ tan φ rd
式(3)および式(7)より、geocentric latitude φ g c \varphi_\mathrm{gc} φ gc はgeodetic latitude φ g d \varphi_\mathrm{gd} φ gd を用いて次のようにあらわされる。
tan φ g c = b ⊕ 2 R ⊕ 2 tan φ g d \begin{gather}
\tan \varphi_\mathrm{gc} = \frac{b_\oplus^2}{R_\oplus^2} \tan \varphi_\mathrm{gd}
\end{gather} tan φ gc = R ⊕ 2 b ⊕ 2 tan φ gd
これで、地表面でgeocentricなパラメタからgeodeticなパラメタへ変換することができた。
ただ今知りたいのは、軌道上の点( x , y , z ) (x,y,z) ( x , y , z ) からgeodeticなパラメタを求めることで、これにはもうひと手間いる。
目標は( x , y , z ) (x,y,z) ( x , y , z ) をgeodeticなパラメタのみで表して、逆に解くことである。
そのためにradius of curvature in the prime vertical C ⊕ C_\oplus C ⊕ をφ g d \varphi_\mathrm{gd} φ gd を用いて表す。
[ x y z ] = [ ( C ⊕ + h e l l p ) cos φ g d cos λ ( C ⊕ + h e l l p ) cos φ g d sin λ ( S ⊕ + h e l l p ) sin φ g d ] \begin{align}
\left[ \begin{array}{c} x \\ y \\ z \end{array} \right] =
\left[ \begin{array}{c}
(C_\oplus + h_\mathrm{ellp}) \cos\varphi_\mathrm{gd} \cos\lambda \\
(C_\oplus + h_\mathrm{ellp}) \cos\varphi_\mathrm{gd} \sin\lambda \\
(S_\oplus + h_\mathrm{ellp}) \sin\varphi_\mathrm{gd}
\end{array} \right]
\end{align} x y z = ( C ⊕ + h ellp ) cos φ gd cos λ ( C ⊕ + h ellp ) cos φ gd sin λ ( S ⊕ + h ellp ) sin φ gd
r δ = r s i t e cos φ g c = R ⊕ cos φ r d = C ⊕ cos φ g d r k = r s i t e sin φ g c = R ⊕ 1 − e ⊕ 2 sin φ r d = S ⊕ sin φ g d \begin{align}
r_\delta
&= r_\mathrm{site} \cos \varphi_\mathrm{gc}
= R_\oplus \cos \varphi_\mathrm{rd}
= C_\oplus \cos \varphi_\mathrm{gd} \\
r_\mathrm{k}
&= r_\mathrm{site} \sin \varphi_\mathrm{gc}
% = R_\oplus \frac{b_\oplus}{R_\oplus}\sin \varphi_\mathrm{rd}
= R_\oplus \sqrt{1-e_\oplus^2}\sin \varphi_\mathrm{rd}
= S_\oplus \sin \varphi_\mathrm{gd}
\end{align} r δ r k = r site cos φ gc = R ⊕ cos φ rd = C ⊕ cos φ gd = r site sin φ gc = R ⊕ 1 − e ⊕ 2 sin φ rd = S ⊕ sin φ gd
上式で、cos φ r d \cos \varphi_\mathrm{rd} cos φ rd が未知となっているが、
以下の関係式から、cos φ r d \cos \varphi_\mathrm{rd} cos φ rd はφ g d \varphi_\mathrm{gd} φ gd を用いて表すことができる。
tan 2 φ g d = R ⊕ 2 b ⊕ 2 ( 1 cos 2 φ r d − 1 ) 1 cos 2 φ r d = b ⊕ 2 R ⊕ 2 tan 2 φ g d + 1 cos φ r d = 1 b ⊕ 2 R ⊕ 2 tan 2 φ g d + 1 , w h e r e − π 2 ≤ φ r d ≤ π 2 \begin{align}
&\tan^2\varphi_\mathrm{gd} = \frac{R_\oplus^2}{b_\oplus^2} \left(\frac{1}{\cos^2\varphi_\mathrm{rd}} - 1 \right) \\
&\frac{1}{\cos^2\varphi_\mathrm{rd}} = \frac{b_\oplus^2}{R_\oplus^2} \tan^2\varphi_\mathrm{gd} + 1 \\
&\cos\varphi_\mathrm{rd} = \frac{1}{\sqrt{\frac{b_\oplus^2}{R_\oplus^2} \tan^2\varphi_\mathrm{gd} + 1}}, \quad \mathrm{where} \quad -\frac{\pi}{2} \le \varphi_\mathrm{rd} \le \frac{\pi}{2}
\end{align} tan 2 φ gd = b ⊕ 2 R ⊕ 2 ( cos 2 φ rd 1 − 1 ) cos 2 φ rd 1 = R ⊕ 2 b ⊕ 2 tan 2 φ gd + 1 cos φ rd = R ⊕ 2 b ⊕ 2 tan 2 φ gd + 1 1 , where − 2 π ≤ φ rd ≤ 2 π
最終的に、C ⊕ C_\oplus C ⊕ は次のように表される。
C ⊕ = R ⊕ cos φ g d 1 b ⊕ 2 R ⊕ 2 tan 2 φ g d + 1 = R ⊕ b ⊕ 2 R ⊕ 2 sin 2 φ g d + cos 2 φ g d = R ⊕ ( 1 − e ⊕ 2 ) sin 2 φ g d + cos 2 φ g d = R ⊕ 1 − e ⊕ 2 sin 2 φ g d \begin{align}
C_\oplus &= \frac{R_\oplus}{\cos\varphi_\mathrm{gd}} \frac{1}{\sqrt{\frac{b_\oplus^2}{R_\oplus^2} \tan^2\varphi_\mathrm{gd} + 1}}
= \frac{R_\oplus}{\sqrt{\frac{b_\oplus^2}{R_\oplus^2} \sin^2\varphi_\mathrm{gd} + \cos^2\varphi_\mathrm{gd}}} \notag \\
&= \frac{R_\oplus}{\sqrt{(1-e_\oplus^2) \sin^2\varphi_\mathrm{gd} + \cos^2\varphi_\mathrm{gd}}}
= \frac{R_\oplus}{\sqrt{1 - e_\oplus^2 \sin^2\varphi_\mathrm{gd}}}
\end{align} C ⊕ = cos φ gd R ⊕ R ⊕ 2 b ⊕ 2 tan 2 φ gd + 1 1 = R ⊕ 2 b ⊕ 2 sin 2 φ gd + cos 2 φ gd R ⊕ = ( 1 − e ⊕ 2 ) sin 2 φ gd + cos 2 φ gd R ⊕ = 1 − e ⊕ 2 sin 2 φ gd R ⊕
S ⊕ S_\oplus S ⊕ も同様に整理できて、以下のように表される。
S ⊕ = R ⊕ ( 1 − e ⊕ 2 ) 1 − e ⊕ 2 sin 2 φ g d \begin{equation}
S_\oplus = \frac{R_\oplus(1-e_\oplus^2)}{\sqrt{1 - e_\oplus^2 \sin^2 \varphi_{\mathrm{gd}}}}
\end{equation} S ⊕ = 1 − e ⊕ 2 sin 2 φ gd R ⊕ ( 1 − e ⊕ 2 )
数値計算による変換
ここで具体的な変換方法について考えてみよう。
基準となる楕円体としてWGS84を用いることとし、これは長半径(semi-major axis)R ⊕ R_\oplus R ⊕ および扁平率(flattening)f ⊕ f_\oplus f ⊕ で表される。
R ⊕ = 6378.137 k m , f ⊕ = 1 298.257223563 \begin{gather}
R_\oplus = 6378.137~\mathrm{km}, \quad
f_\oplus = \frac{1}{298.257223563}
\end{gather} R ⊕ = 6378.137 km , f ⊕ = 298.257223563 1
その他のパラメタは次のように計算できる。
e ⊕ = 2 f ⊕ − f ⊕ 2 = 0.0818191908426215 , b ⊕ = R ⊕ 1 − e ⊕ 2 = R ⊕ ( 1 − f ⊕ ) = 6356.75231424518 k m . \begin{align}
e_\oplus &= \sqrt{2f_\oplus - f_\oplus^2} = 0.0818191908426215, \\
b_\oplus &= R_\oplus \sqrt{1-e_\oplus^2} = R_\oplus(1-f_\oplus) = 6356.75231424518~\mathrm{km}. \\
\end{align} e ⊕ b ⊕ = 2 f ⊕ − f ⊕ 2 = 0.0818191908426215 , = R ⊕ 1 − e ⊕ 2 = R ⊕ ( 1 − f ⊕ ) = 6356.75231424518 km .
経度に関しては、特に問題なく次のように計算できる。
λ = arctan 2 ( y , x ) \begin{gather}
\lambda = \arctan2 (y,x)
\end{gather} λ = arctan 2 ( y , x )
緯度と高度に関してはexplicitに解けなさそうなので、数値的に求めることを考えてみる。
まず、仮にφ g d \varphi_\mathrm{gd} φ gd が分かっていた場合には、h e l l p h_\mathrm{ellp} h ellp は簡単に決定できる。
h e l l p = x 2 + y 2 cos φ g d − C ⊕ = x 2 + y 2 cos φ g d − R ⊕ 1 − e ⊕ 2 sin 2 φ g d h e l l p = z sin φ g d − S ⊕ = z sin φ g d − R ⊕ ( 1 − e ⊕ 2 ) 1 − e ⊕ 2 sin 2 φ g d \begin{align}
h_\mathrm{ellp} &= \frac{\sqrt{x^2+y^2}}{\cos\varphi_\mathrm{gd}} - C_\oplus
= \frac{\sqrt{x^2+y^2}}{\cos\varphi_\mathrm{gd}} - \frac{R_\oplus}{\sqrt{1 - e_\oplus^2 \sin^2\varphi_\mathrm{gd}}} \\
h_\mathrm{ellp} &= \frac{z}{\sin\varphi_\mathrm{gd}} - S_\oplus
= \frac{z}{\sin\varphi_\mathrm{gd}} - \frac{R_\oplus(1-e_\oplus^2)}{\sqrt{1 - e_\oplus^2 \sin^2 \varphi_{\mathrm{gd}}}}
\end{align} h ellp h ellp = cos φ gd x 2 + y 2 − C ⊕ = cos φ gd x 2 + y 2 − 1 − e ⊕ 2 sin 2 φ gd R ⊕ = sin φ gd z − S ⊕ = sin φ gd z − 1 − e ⊕ 2 sin 2 φ gd R ⊕ ( 1 − e ⊕ 2 )
これらが等しくなるように、以下の関係を満たすφ g d \varphi_\mathrm{gd} φ gd を数値的に求めればよい。
z − x 2 + y 2 tan φ g d + e ⊕ 2 R ⊕ sin φ g d 1 − e ⊕ 2 sin 2 φ g d = 0 \begin{gather}
z - \sqrt{x^2+y^2} \tan \varphi_\mathrm{gd} + \frac{e_\oplus^2 R_\oplus \sin\varphi_\mathrm{gd}}{\sqrt{1 - e_\oplus^2 \sin^2 \varphi_{\mathrm{gd}}}} = 0
\end{gather} z − x 2 + y 2 tan φ gd + 1 − e ⊕ 2 sin 2 φ gd e ⊕ 2 R ⊕ sin φ gd = 0
φ 0 = arctan ( z x 2 + y 2 ) \begin{gather}
\varphi_0 = \arctan \left( \frac{z}{\sqrt{x^2 + y^2}} \right)
\end{gather} φ 0 = arctan ( x 2 + y 2 z )
初期値はgeocentricなパラメタを用いることとして、
例えばPythonで以下のようなスクリプトを書くと、実際にgeodetic latitudeを求めることができる。
# WGS84 parameters
flattening = 1 / 298.257223563
semimajor = 6378.137
eccentricity = np.sqrt( 2 * flattening - flattening ** 2 )
def geodetic_latitude (x, y, z):
""" calculate the geodetic latitude
# Args:
x(ndarray): x coordinate in ECEF, km
y(ndarray): y coordinate in ECEF, km
z(ndarray): z coordinate in ECEF, km
# Returns:
latitude(ndarray): geodetic latitude, rad
"""
params = (x, y, z)
latitude = np.arctan(z / np.sqrt(x ** 2 + y ** 2 ))
return optimize.fsolve(latitude_equation, latitude, args = params)
def latitude_equation (x: np.ndarray, * args) -> np.ndarray:
""" equation to be solved
# Args:
*args(tuple): (x, y, z)
# Returns:
latitude(ndarray): latitude
"""
return args[ 2 ] - np.sqrt(args[ 0 ] ** 2 + args[ 1 ] ** 2 ) * np.tan(x) + eccentricity ** 2 * semimajor * np.sin(x) / np.sqrt( 1 - eccentricity ** 2 * np.sin(x) ** 2 )
これでECEF座標からgeodeticなパラメタへの変換の基本は理解できた。
ただこの方法で解を探すと、データ量が増えるにつれてかなりの計算量が必要になってしまうので、できればより効率的な方法が欲しくなってくる。
Vermeilleの解析的な変換手法
より効率的な変換手法で、論文としてもよく引用されているものに、Vermeilleの手法がある[2] 。
この方法では、かなりアクロバットな変数の置き換えをすることで、解析的に解を求めることができる。
まず、次のような変数k k k を定義する。これは常にk > 0 k>0 k > 0 となる。
k = Q S P R = h e l l p + C ⊕ − e ⊕ 2 C ⊕ C ⊕ h e l l p = ( k + e ⊕ 2 − 1 ) C ⊕ = k C ⊕ − S ⊕ \begin{align}
&k = \frac{QS}{PR} = \frac{h_\mathrm{ellp} + C_\oplus - e_\oplus^2 C_\oplus}{C_\oplus} \\
&h_\mathrm{ellp} = (k + e_\oplus^2 - 1) C_\oplus = k C_\oplus - S_\oplus
\end{align} k = PR QS = C ⊕ h ellp + C ⊕ − e ⊕ 2 C ⊕ h ellp = ( k + e ⊕ 2 − 1 ) C ⊕ = k C ⊕ − S ⊕
このk k k を用いた関係式を作るために、C ⊕ C_\oplus C ⊕ をk k k で表す。
sin φ g d = z S ⊕ + h e l l p = z k C ⊕ \begin{align}
\sin\varphi_\mathrm{gd} = \frac{z}{S_\oplus + h_\mathrm{ellp}}
= \frac{z}{k C_\oplus}
\end{align} sin φ gd = S ⊕ + h ellp z = k C ⊕ z
C ⊕ 2 = R ⊕ 2 ( 1 − e ⊕ 2 sin 2 φ g d ) = R ⊕ 2 + C ⊕ 2 e ⊕ 2 sin 2 φ g d = R ⊕ 2 + e ⊕ 2 z 2 k 2 \begin{align}
C_\oplus^2 &= \frac{R_\oplus^2}{(1 - e_\oplus^2 \sin^2\varphi_\mathrm{gd})} = R_\oplus^2 + C_\oplus^2 e_\oplus^2 \sin^2\varphi_\mathrm{gd} \notag \\
&= R_\oplus^2 + \frac{e_\oplus^2 z^2}{k^2}
\end{align} C ⊕ 2 = ( 1 − e ⊕ 2 sin 2 φ gd ) R ⊕ 2 = R ⊕ 2 + C ⊕ 2 e ⊕ 2 sin 2 φ gd = R ⊕ 2 + k 2 e ⊕ 2 z 2
これらを用いて、x 2 + y 2 x^2+y^2 x 2 + y 2 を書き換えていく。
x 2 + y 2 = ( h e l l p + C ⊕ ) 2 cos 2 φ g d = ( k + e ⊕ ) 2 C ⊕ 2 ( 1 − sin 2 φ g d ) = ( k + e ⊕ ) 2 C ⊕ 2 ( 1 − z 2 k 2 C ⊕ 2 ) = ( k + e ⊕ ) 2 ( R ⊕ 2 + e ⊕ 2 z 2 k 2 − z 2 k 2 ) \begin{align}
x^2 + y^2
&=(h_\mathrm{ellp} + C_\oplus)^2 \cos^2\varphi_\mathrm{gd}
= (k + e_\oplus)^2 C_\oplus^2 (1 - \sin^2\varphi_\mathrm{gd}) \notag \\
&=(k + e_\oplus)^2 C_\oplus^2 \left( 1 - \frac{z^2}{k^2 C_\oplus^2} \right) \notag \\
&=(k + e_\oplus)^2 \left( R_\oplus^2 + \frac{e_\oplus^2 z^2}{k^2} - \frac{z^2}{k^2}\right)
\end{align} x 2 + y 2 = ( h ellp + C ⊕ ) 2 cos 2 φ gd = ( k + e ⊕ ) 2 C ⊕ 2 ( 1 − sin 2 φ gd ) = ( k + e ⊕ ) 2 C ⊕ 2 ( 1 − k 2 C ⊕ 2 z 2 ) = ( k + e ⊕ ) 2 ( R ⊕ 2 + k 2 e ⊕ 2 z 2 − k 2 z 2 )
x 2 + y 2 ( k + e ⊕ 2 ) 2 + ( 1 − e ⊕ 2 ) z 2 k 2 = R ⊕ 2 \begin{align}
\frac{x^2+y^2}{(k+e_\oplus^2)^2} + \frac{(1 - e_\oplus^2) z^2}{k^2} = R_\oplus^2
\end{align} ( k + e ⊕ 2 ) 2 x 2 + y 2 + k 2 ( 1 − e ⊕ 2 ) z 2 = R ⊕ 2
ここで、p , q p, q p , q を以下のようにおく。
p = x 2 + y 2 R ⊕ 2 , q = 1 − e ⊕ 2 R ⊕ 2 z 2 \begin{align}
p = \frac{x^2 + y^2}{R_\oplus^2}, \quad q = \frac{1-e_\oplus^2}{R_\oplus^2} z^2
\end{align} p = R ⊕ 2 x 2 + y 2 , q = R ⊕ 2 1 − e ⊕ 2 z 2
これらを用いて、k k k について4次の代数方程式を作る。
4次の代数方程式は一般に解くことが可能で、Ferrariの解法をはじめ様々な手法がある。
ただ、Vermeilleはそれらの手法をそのまま用いるのではなく、ところどころに式変形のアイデアを取り入れて、因数分解していっている。
k 4 + 2 e ⊕ 2 k 3 − ( p + q − e ⊕ 4 ) k 2 − 2 e ⊕ 2 q k − e ⊕ 4 q = 0 \begin{align}
k^4 + 2e_\oplus^2 k^3 - (p+q-e_\oplus^4) k^2 - 2e_\oplus^2 q k - e_\oplus^4 q = 0
\end{align} k 4 + 2 e ⊕ 2 k 3 − ( p + q − e ⊕ 4 ) k 2 − 2 e ⊕ 2 q k − e ⊕ 4 q = 0
ここで謎のパラメタu u u を導入する。u u u が任意の値の場合について、次の式が成り立つ。
( k 2 + e ⊕ 2 k − u ) 2 − [ ( p + q − 2 u ) k 2 + 2 e ⊕ 2 ( q − u ) k + u 2 + e ⊕ 4 q ] = 0 \begin{align}
(k^2 + e_\oplus^2 k - u)^2 - \left[ (p+q-2u) k^2 + 2e_\oplus^2(q-u)k + u^2 + e_\oplus^4 q \right] = 0
\end{align} ( k 2 + e ⊕ 2 k − u ) 2 − [ ( p + q − 2 u ) k 2 + 2 e ⊕ 2 ( q − u ) k + u 2 + e ⊕ 4 q ] = 0
カギ括弧の中身はk k k の2次方程式になっているが、
これについて判別式がゼロになるように要求すると、以下の関係式が得られる。
この式が満たされるときカギ括弧の中は( ⋯ ) 2 (\cdots)^2 ( ⋯ ) 2 の形で書けて、式全体が因数分解できることが分かる。
形は少し異なるものの、謎パラメタを導入しつつ、判別式ゼロを要求することで、因数分解できる形にする、というのはFerrariの解法と類似している。
e ⊕ 4 ( q − u ) 2 − ( p + q − 2 u ) ( u 2 + e ⊕ 4 q ) = 0 \begin{align}
e_\oplus^4 (q-u)^2 - (p+q-2u)(u^2 + e_\oplus^4 q) = 0
\end{align} e ⊕ 4 ( q − u ) 2 − ( p + q − 2 u ) ( u 2 + e ⊕ 4 q ) = 0
2 u 3 − ( p + q − e ⊕ 4 ) u 2 + e ⊕ 4 p q = 0 \begin{align}
2u^3 - (p + q - e_\oplus^4) u^2 + e_\oplus^4 pq = 0
\end{align} 2 u 3 − ( p + q − e ⊕ 4 ) u 2 + e ⊕ 4 pq = 0
さらに、変数r , s r, s r , s を以下のように置く。
r = p + q − e ⊕ 4 6 , s = e ⊕ 4 p q 4 r 3 \begin{align}
r = \frac{p+q-e_\oplus^4}{6}, \quad s = e_\oplus^4 \frac{pq}{4r^3}
\end{align} r = 6 p + q − e ⊕ 4 , s = e ⊕ 4 4 r 3 pq
ただし、これらの変数は常に正である。
p + q = x 2 + y 2 R ⊕ 2 + ( 1 − e ⊕ 2 ) z 2 R ⊕ 2 = x 2 R ⊕ 2 + y 2 R ⊕ 2 + z 2 b ⊕ 2 > 1 \begin{align}
p + q = \frac{x^2 + y^2}{R_\oplus^2} + \frac{(1-e_\oplus^2) z^2}{R_\oplus^2}
= \frac{x^2}{R_\oplus^2} + \frac{y^2}{R_\oplus^2} + \frac{z^2}{b_\oplus^2} > 1
\end{align} p + q = R ⊕ 2 x 2 + y 2 + R ⊕ 2 ( 1 − e ⊕ 2 ) z 2 = R ⊕ 2 x 2 + R ⊕ 2 y 2 + b ⊕ 2 z 2 > 1
これらを用いて、さらに式(35)の全体を2 r 3 2r^3 2 r 3 で割ると以下ようにu / r u/r u / r に関する3次方程式が得られる。
u 3 r 3 − 3 u 2 r 2 − 2 s = 0 \begin{align}
\frac{u^3}{r^3} - 3\frac{u^2}{r^2} - 2s = 0
\end{align} r 3 u 3 − 3 r 2 u 2 − 2 s = 0
ここでu / r u/r u / r を式(39)のように置いて、t t t の式に書き換える。t > 0 t>0 t > 0 の範囲では、t = 1 t=1 t = 1 で1 + t + 1 t 1+t+\frac{1}{t} 1 + t + t 1 は極小値3をとり、式(40)の左辺は− 2 s -2s − 2 s になる。
t t t が動けば、u r \frac{u}{r} r u は増加し、0 < t < 1 0<t<1 0 < t < 1 の範囲でひとつ、t > 1 t>1 t > 1 の範囲でもひとつ解を持つはずだ。
(ちなみに、相反方程式と呼ばれる形の代数方程式は、x + 1 x = t x+\frac{1}{x}=t x + x 1 = t という変形をすることで、うまく因数分解できる。ちょっと形は違うがその辺からインスピレーションを受けているのかもしれない。)
u r = 1 + t + 1 t \begin{align}
\frac{u}{r} = 1 + t + \frac{1}{t}
\end{align} r u = 1 + t + t 1
t 6 − 2 ( 1 + s ) t 3 + 1 = 0 \begin{gather}
t^6 - 2(1+s)t^3 + 1 = 0
\end{gather} t 6 − 2 ( 1 + s ) t 3 + 1 = 0
実際、0 < t < 1 0<t<1 0 < t < 1 とt > 1 t>1 t > 1 の範囲に以下のような解を見つけることができる。
t 3 = 1 + s ± s ( 2 + s ) t = 1 + s ± s ( 2 + s ) 3 \begin{align}
t^3 &= 1 + s \pm \sqrt{s(2+s)} \\
t &= \sqrt[3]{1 + s \pm \sqrt{s(2+s)}}
\end{align} t 3 t = 1 + s ± s ( 2 + s ) = 3 1 + s ± s ( 2 + s )
で、いずれのt t t の解が得られてもu r \frac{u}{r} r u の値は同じなので、どっちか好きな方を選べばよい。とりあえず、ここではプラスの方を選ぶことにしよう。
これで、式(33)のカギ括弧内を2乗の形で表せるようなu u u を求めることができた。
( k 2 + e ⊕ 2 k − u ) 2 − ( e ⊕ 2 q − u v k + v ) 2 = 0 , w h e r e v = u 2 + e ⊕ 4 q \begin{align}
(k^2 + e_\oplus^2 k - u)^2 - \left( e_\oplus^2 \frac{q-u}{v}k + v \right)^2 = 0, \quad
\mathrm{where}\quad v = \sqrt{u^2 + e_\oplus^4 q}
\end{align} ( k 2 + e ⊕ 2 k − u ) 2 − ( e ⊕ 2 v q − u k + v ) 2 = 0 , where v = u 2 + e ⊕ 4 q
( k 2 + v − u + q v e ⊕ 2 k + v − u ) ( k 2 + v − u + q v e ⊕ 2 k − v − u ) = 0 \begin{align}
\left( k^2 + \frac{v-u+q}{v}e_\oplus^2k + v - u\right)\left( k^2 + \frac{v-u+q}{v}e_\oplus^2k - v - u\right) = 0
\end{align} ( k 2 + v v − u + q e ⊕ 2 k + v − u ) ( k 2 + v v − u + q e ⊕ 2 k − v − u ) = 0
式(44)のひとつ目の括弧内は、v − u , v , q v-u, v, q v − u , v , q がいずれも正なので、k > 0 k>0 k > 0 に解は持たない。
なので、興味があるのはふたつ目の括弧内の方である。u + v u+v u + v が正なので、k > 0 k>0 k > 0 の解はひとつだけで、これは以下のように書ける。
k = u + v + w 2 − w , w h e r e w = e ⊕ 2 u + v − q 2 v \begin{gather}
k = \sqrt{u+v+w^2} - w, \quad \mathrm{where} \quad w = e_\oplus^2\frac{u+v-q}{2v}
\end{gather} k = u + v + w 2 − w , where w = e ⊕ 2 2 v u + v − q
これでk k k が一意に求まったので、geodetic latitude φ g d \varphi_\mathrm{gd} φ gd も高度h e l l p h_\mathrm{ellp} h ellp も求めることができる。
D = k x 2 + y 2 k + e ⊕ 2 , C ⊕ = D 2 + z 2 k \begin{equation}
D = \frac{k\sqrt{x^2+y^2}}{k+e_\oplus^2}, \quad
C_\oplus = \frac{\sqrt{D^2+z^2}}{k}
\end{equation} D = k + e ⊕ 2 k x 2 + y 2 , C ⊕ = k D 2 + z 2
h e l l p = k + e ⊕ 2 − 1 k , φ g d = 2 arctan z D + D 2 + z 2 \begin{equation}
h_\mathrm{ellp} = \frac{k+e_\oplus^2-1}{k}, \quad
\varphi_\mathrm{gd} = 2 \arctan \frac{z}{D+\sqrt{D^2+z^2}}
\end{equation} h ellp = k k + e ⊕ 2 − 1 , φ gd = 2 arctan D + D 2 + z 2 z
元論文[2] には変換に最低限必要な式がリストアップされているので、
それらをもとに簡単なスクリプトを書くと、ECEF座標からgeodeticなパラメタへの変換を実行できる。
# WGS84 parameters
flattening = 1 / 298.257223563
semimajor = 6378.137
eccentricity = np.sqrt( 2 * flattening - flattening ** 2 )
def geodetic_vermeille (x, y, z):
""" calculate the geodetic latitude and altitude based on
H. Vermeille, "Direct transformation from geocentric to geodetic coordinates", 2002, Journal of Geodesy, 76:451-454
# Args:
x(ndarray): x coordinate in ECEF, km
y(ndarray): y coordinate in ECEF, km
z(ndarray): z coordinate in ECEF, km
# Returns:
lat(ndarray): geodetic latitude, rad
lon(ndarray): geodetic longitude, rad
h(ndarray): geodetic altitude, km
"""
p = (x ** 2 + y ** 2 ) / semimajor ** 2
q = ( 1 - eccentricity ** 2 ) * z ** 2 / semimajor ** 2
r = (p + q - eccentricity ** 4 ) / 6
s = eccentricity ** 4 * p * q / ( 4 * r ** 3 )
t = ( 1 + s + np.sqrt(s * ( 2 + s))) ** ( 1 / 3 )
u = r * ( 1 + t + 1 / t)
v = np.sqrt(u ** 2 + eccentricity ** 4 * q)
w = eccentricity ** 2 * (u + v - q) / ( 2 * v)
k = np.sqrt(u + v + w ** 2 ) - w
D = k * np.sqrt(x ** 2 + y ** 2 ) / (k + eccentricity ** 2 )
lat = 2 * np.arctan(z / (D + np.sqrt(D ** 2 + z ** 2 )))
lon = np.arctan2(y, x)
h = (k + eccentricity ** 2 - 1 ) / k * np.sqrt(D ** 2 + z ** 2 )
return lat, lon, h
Reference
David A. Vallado, Fundamentals of Astrodynamics and Applications Fourth Edition, 2013, Microsoft Press
H. Vermeille, “Direct transformation from geocentric to geodetic coordinates”, 2002, Journal of Geodesy, 76:451-454, doi: 10.1007/s00190-002-0273-6 .