ECEF座標から測地(geodetic)座標への変換

Last updated:

XYZ座標の形で表された人工衛星の位置を、緯度・経度・高度に変換したいとき、ざっくりでよければ地球を球体と仮定してarctanを使って求めることはできる。 ただ、もう少しきちんと求める場合には、地球を回転楕円体として考えるべきで、この場合の変換はそれほど簡単ではない。 ECEF(Earth Centered Earth Fixed)座標から測地(geodetic)座標への効率的な変換方法の開発は、多くの研究者の興味を集めてきたトピックで、何十年も前から最近まで多くの論文が発表されている。

ECEF座標と測地(geodetic)座標の関係

まず地球表面上の点rsite\boldsymbol{r}_\mathrm{site}を式で表すことを考えよう。 地球はおおよそ回転楕円体Spheroid(楕円体Ellipsoidのうち1軸に関しては軸対称なもの)で、地軸回りで対称、南北方向に少し押しつぶしたような形をしているので、以下のように表すことができる。 ここでφrd\varphi_\mathrm{rd}はreduced latitudeと呼ばれるもので、geocentric latitude φgc\varphi_\mathrm{gc}ではないことに注意しよう。

rsite=[RcosφrdcosλRcosφrdsinλbsinφrd]\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}

ecef-geodetic-1 Figure 1: Spheroidal Earth Geometry and Geodetic Coordinate Parameters.

一方で、geocentric latitude φgc\varphi_\mathrm{gc}を使って表すこともできるはずで、rsiter_\mathrm{site}は何かしらの緯度の関数になる。

rsite=[rsitecosφgccosλrsitecosφgcsinλrsitesinφgc]\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}

これらの式を見比べると、φrd\varphi_\mathrm{rd}φgc\varphi_\mathrm{gc}の間に以下の関係が得られる。

tanφgc=bRtanφrd\begin{gather} \tan \varphi_\mathrm{gc} = \frac{b_\oplus}{R_\oplus} \tan \varphi_\mathrm{rd} \end{gather}

次に、φrd\varphi_\mathrm{rd}φgd\varphi_\mathrm{gd}の関係を導く。 rsite\boldsymbol{r}_\mathrm{site}での接面の方向は、φrd\varphi_\mathrm{rd}λ\lambdaについて微分してやると分かる。

ddφrdrsite=[RsinφrdcosλRsinφrdsinλbcosφrd],ddλrsite=[Rcosφrdsinλ+Rcosφrdcosλ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}

で、これをよく見ると、rsite\bm{r}_\mathrm{site}での法線方向が分かる。

n=[bcosφrdcosλbcosφrdsinλRsinφrd]\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}

法線方向が分かると、reduced latitude φrd\varphi_\mathrm{rd}とgeodetic latitude φgd\varphi_\mathrm{gd}の関係を求めることができる。

tanφgd=Rbtanφrd\begin{gather} \tan \varphi_\mathrm{gd} = \frac{R_\oplus}{b_\oplus} \tan \varphi_\mathrm{rd} \end{gather}

式(3)および式(7)より、geocentric latitude φgc\varphi_\mathrm{gc}はgeodetic latitude φgd\varphi_\mathrm{gd}を用いて次のようにあらわされる。

tanφgc=b2R2tanφgd\begin{gather} \tan \varphi_\mathrm{gc} = \frac{b_\oplus^2}{R_\oplus^2} \tan \varphi_\mathrm{gd} \end{gather}

これで、地表面でgeocentricなパラメタからgeodeticなパラメタへ変換することができた。 ただ今知りたいのは、軌道上の点(x,y,z)(x,y,z)からgeodeticなパラメタを求めることで、これにはもうひと手間いる。 目標は(x,y,z)(x,y,z)をgeodeticなパラメタのみで表して、逆に解くことである。 そのためにradius of curvature in the prime vertical CC_\oplusφgd\varphi_\mathrm{gd}を用いて表す。

[xyz]=[(C+hellp)cosφgdcosλ(C+hellp)cosφgdsinλ(S+hellp)sinφgd]\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} rδ=rsitecosφgc=Rcosφrd=Ccosφgdrk=rsitesinφgc=R1e2sinφrd=Ssinφgd\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}

上式で、cosφrd\cos \varphi_\mathrm{rd}が未知となっているが、 以下の関係式から、cosφrd\cos \varphi_\mathrm{rd}φgd\varphi_\mathrm{gd}を用いて表すことができる。

tan2φgd=R2b2(1cos2φrd1)1cos2φrd=b2R2tan2φgd+1cosφrd=1b2R2tan2φgd+1,whereπ2φrdπ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}

最終的に、CC_\oplusは次のように表される。

C=Rcosφgd1b2R2tan2φgd+1=Rb2R2sin2φgd+cos2φgd=R(1e2)sin2φgd+cos2φgd=R1e2sin2φgd\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}

SS_\oplusも同様に整理できて、以下のように表される。

S=R(1e2)1e2sin2φgd\begin{equation} S_\oplus = \frac{R_\oplus(1-e_\oplus^2)}{\sqrt{1 - e_\oplus^2 \sin^2 \varphi_{\mathrm{gd}}}} \end{equation}

数値計算による変換

ここで具体的な変換方法について考えてみよう。 基準となる楕円体としてWGS84を用いることとし、これは長半径(semi-major axis)RR_\oplusおよび扁平率(flattening)ff_\oplusで表される。

R=6378.137 km,f=1298.257223563\begin{gather} R_\oplus = 6378.137~\mathrm{km}, \quad f_\oplus = \frac{1}{298.257223563} \end{gather}

その他のパラメタは次のように計算できる。

e=2ff2=0.0818191908426215,b=R1e2=R(1f)=6356.75231424518 km.\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}

経度に関しては、特に問題なく次のように計算できる。

λ=arctan2(y,x)\begin{gather} \lambda = \arctan2 (y,x) \end{gather}

緯度と高度に関してはexplicitに解けなさそうなので、数値的に求めることを考えてみる。 まず、仮にφgd\varphi_\mathrm{gd}が分かっていた場合には、hellph_\mathrm{ellp}は簡単に決定できる。

hellp=x2+y2cosφgdC=x2+y2cosφgdR1e2sin2φgdhellp=zsinφgdS=zsinφgdR(1e2)1e2sin2φgd\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}

これらが等しくなるように、以下の関係を満たすφgd\varphi_\mathrm{gd}を数値的に求めればよい。

zx2+y2tanφgd+e2Rsinφgd1e2sin2φgd=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} φ0=arctan(zx2+y2)\begin{gather} \varphi_0 = \arctan \left( \frac{z}{\sqrt{x^2 + y^2}} \right) \end{gather}

初期値は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]。 この方法では、かなりアクロバットな変数の置き換えをすることで、解析的に解を求めることができる。

まず、次のような変数kkを定義する。これは常にk>0k>0となる。

k=QSPR=hellp+Ce2CChellp=(k+e21)C=kCS\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}

このkkを用いた関係式を作るために、CC_\opluskkで表す。

sinφgd=zS+hellp=zkC\begin{align} \sin\varphi_\mathrm{gd} = \frac{z}{S_\oplus + h_\mathrm{ellp}} = \frac{z}{k C_\oplus} \end{align} C2=R2(1e2sin2φgd)=R2+C2e2sin2φgd=R2+e2z2k2\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}

これらを用いて、x2+y2x^2+y^2を書き換えていく。

x2+y2=(hellp+C)2cos2φgd=(k+e)2C2(1sin2φgd)=(k+e)2C2(1z2k2C2)=(k+e)2(R2+e2z2k2z2k2)\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} x2+y2(k+e2)2+(1e2)z2k2=R2\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}

ここで、p,qp, qを以下のようにおく。

p=x2+y2R2,q=1e2R2z2\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}

これらを用いて、kkについて4次の代数方程式を作る。 4次の代数方程式は一般に解くことが可能で、Ferrariの解法をはじめ様々な手法がある。 ただ、Vermeilleはそれらの手法をそのまま用いるのではなく、ところどころに式変形のアイデアを取り入れて、因数分解していっている。

k4+2e2k3(p+qe4)k22e2qke4q=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}

ここで謎のパラメタuuを導入する。uuが任意の値の場合について、次の式が成り立つ。

(k2+e2ku)2[(p+q2u)k2+2e2(qu)k+u2+e4q]=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}

カギ括弧の中身はkkの2次方程式になっているが、 これについて判別式がゼロになるように要求すると、以下の関係式が得られる。 この式が満たされるときカギ括弧の中は()2(\cdots)^2の形で書けて、式全体が因数分解できることが分かる。 形は少し異なるものの、謎パラメタを導入しつつ、判別式ゼロを要求することで、因数分解できる形にする、というのはFerrariの解法と類似している。

e4(qu)2(p+q2u)(u2+e4q)=0\begin{align} e_\oplus^4 (q-u)^2 - (p+q-2u)(u^2 + e_\oplus^4 q) = 0 \end{align} 2u3(p+qe4)u2+e4pq=0\begin{align} 2u^3 - (p + q - e_\oplus^4) u^2 + e_\oplus^4 pq = 0 \end{align}

さらに、変数r,sr, sを以下のように置く。

r=p+qe46,s=e4pq4r3\begin{align} r = \frac{p+q-e_\oplus^4}{6}, \quad s = e_\oplus^4 \frac{pq}{4r^3} \end{align}

ただし、これらの変数は常に正である。

p+q=x2+y2R2+(1e2)z2R2=x2R2+y2R2+z2b2>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}

これらを用いて、さらに式(35)の全体を2r32r^3で割ると以下ようにu/ru/rに関する3次方程式が得られる。

u3r33u2r22s=0\begin{align} \frac{u^3}{r^3} - 3\frac{u^2}{r^2} - 2s = 0 \end{align}

ここでu/ru/rを式(39)のように置いて、ttの式に書き換える。t>0t>0の範囲では、t=1t=11+t+1t1+t+\frac{1}{t}は極小値3をとり、式(40)の左辺は2s-2sになる。 ttが動けば、ur\frac{u}{r}は増加し、0<t<10<t<1の範囲でひとつ、t>1t>1の範囲でもひとつ解を持つはずだ。 (ちなみに、相反方程式と呼ばれる形の代数方程式は、x+1x=tx+\frac{1}{x}=tという変形をすることで、うまく因数分解できる。ちょっと形は違うがその辺からインスピレーションを受けているのかもしれない。)

ur=1+t+1t\begin{align} \frac{u}{r} = 1 + t + \frac{1}{t} \end{align} t62(1+s)t3+1=0\begin{gather} t^6 - 2(1+s)t^3 + 1 = 0 \end{gather}

実際、0<t<10<t<1t>1t>1の範囲に以下のような解を見つけることができる。

t3=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}

で、いずれのttの解が得られてもur\frac{u}{r}の値は同じなので、どっちか好きな方を選べばよい。とりあえず、ここではプラスの方を選ぶことにしよう。 これで、式(33)のカギ括弧内を2乗の形で表せるようなuuを求めることができた。

(k2+e2ku)2(e2quvk+v)2=0,wherev=u2+e4q\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} (k2+vu+qve2k+vu)(k2+vu+qve2kvu)=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}

式(44)のひとつ目の括弧内は、vu,v,qv-u, v, qがいずれも正なので、k>0k>0に解は持たない。 なので、興味があるのはふたつ目の括弧内の方である。u+vu+vが正なので、k>0k>0の解はひとつだけで、これは以下のように書ける。

k=u+v+w2w,wherew=e2u+vq2v\begin{gather} k = \sqrt{u+v+w^2} - w, \quad \mathrm{where} \quad w = e_\oplus^2\frac{u+v-q}{2v} \end{gather}

これでkkが一意に求まったので、geodetic latitude φgd\varphi_\mathrm{gd}も高度hellph_\mathrm{ellp}も求めることができる。

D=kx2+y2k+e2,C=D2+z2k\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} hellp=k+e21k,φgd=2arctanzD+D2+z2\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}

元論文[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

  1. David A. Vallado, Fundamentals of Astrodynamics and Applications Fourth Edition, 2013, Microsoft Press
  2. H. Vermeille, “Direct transformation from geocentric to geodetic coordinates”, 2002, Journal of Geodesy, 76:451-454, doi: 10.1007/s00190-002-0273-6.

関連記事

剛体の運動方程式

剛体の運動を考えるためにまず必要となるのは、運動方程式を立てることです。今回は並進・回転運動する剛体の運動エネルギーを求めて、これをもとにLagrangeの運動方程式を立てていきます。