KMLのLookAtでタイル有効範囲全体を見せるためのカメラ位置標高計算方法
はじめに
Google Earthでタイル画像を表示するためにはKMLを作りますが、ズームレベル0 からKMLを作ると、赤道上アフリカ沖にカメラが行ってしまいました。
こまったので、LookAt要素を活用して、タイル有効範囲の中心にカメラを持っていきますが、緯度、経度、標高の3つを指定する必要があり、標高の計算が難しかったので、メモしておきます。
方針
焦点距離 a[mm] で4隅が収まる標高hを求めます。
ちょっと変えると、「4隅について、焦点距離a[mm]で収まる標高hを求め、最大値を取る」となります。
なお、焦点距離は50mmにしました。どうもGoogle Earthは視野角(焦点距離とは違う)は30度(焦点距離では30mm近辺)のようで、ぎりぎりまでカメラ標高を落とすようにはなってないのですが、逆にその方が良いかんじになったので、やはり50mmとします。
以下は、各隅について計算します。
カメラの緯度経度位置を得る
画像範囲の中心点をカメラの緯度経度位置とします。
以降は、緯度経度を(φc,λc)とします。
緯度経度からxyzを得る
半径Rの球面上の 緯度lat, 経度 lng の点を、x,y,z であらわすと、次の通りとなります。
xn = R*cos(φn)*cos(λn) yn = R*cos(φn)*sin(λn) zn = R*sin(φn)
回転行列と逆行列
まず、こちらは使いませんが、X=(R,0,0)から 緯度φc, 経度λc 上の点に回転させる行列を考えます。
φcの行列 Ap は次の通りです。
cp 0 -sp |
0 1 0 |
sp 0 cp |
cl -sl 0 |
sl cl 0 |
0 0 1 |
X' = Al * Ap * Xこの逆行列を使えば、緯度φc, 経度λc 上の点が(R,0,0)に回転します。 まず、Alの逆行列 invAl は次の通り。
cl sl 0 |
-sl cl 0 |
0 0 1 |
cp 0 sp |
0 1 0 |
-sp 0 cp |
invAp * invAl | cp 0 sp | | cl sl 0 | = | 0 1 0 | * | -sl cl 0 | | -sp 0 cp | | 0 0 1 |(x,y,z)を逆行列で回転させた後の座標(xr,yr,zr)は次の通りです。
xr = x*cp*cl + y*cp*sl + z*sp yr = -x*sl + y*cl zr = -x*sp*cl - y*sp*sl * z*cp
指定画角となる標高を求める
逆行列回転後のカメラ位置は、球面半径 R として、標高 h とすると(R+h, 0, 0)となります。これから原点方向に向いています。 焦点距離 a[mm] から 画角α[rad]のタンジェント ta を求めるのは次の通りです。 35はフィルムサイズが35mmであるから、です。
ta = (35/2)/a = 17.5/ayrについて画角 a で端っこに写るようになる標高 h1 は次の方程式となります。
yr/(R+h1-xr) = ta
h1 = yr/ta - R + xrzrについても見てみます。
h2 = zr/ta - R + xr最大値を採用します。
h = max(h1, h2)