GPSTagr もどきを作る

10キロ走が終わってから何をしていたかというと、GPSTagr もどきの製作にいそしんでいました。VNWA のパーツも届いたので、ハンダ付けを再開しても良いのですが、Shure ヘッドホンの修理に時間を取られたりして、なかなか再開できません。これに比べて、プログラミングは昼休み時間を使えるので、時間的な制約が比較的少ないのです。

GPSTagr とはなんぞや? これは、Flickr に「既に」アップロードしてしまった写真に対して、GPS の位置情報を与える、ウェブ上のアプリケーションでしたFlickr コミュニティでも、これほど、価値を認める人と理解しない人の差が明確なツールもないでしょう。(注意: 現在の http://gpstagr.com は、ドメインの乗っ取りにあっているように見受けられます。下記の Flickr での議論では使えそうな感じに読めますが、私が試した限りダメです。悪質なサイトに誘導される可能性がゼロとは言えないので、試さないほうが無難でしょう。)

実は去年の 9月くらいから、GPSTagr が使えなくなってしまい、Flickr コミュニティでも嘆かれているのですが、このツールの有用性を理解しない人は、「そんなの、EXIF 位置情報を付加してからアップロードすればいいじゃん」と、そっけないです。GPSTagr の真の利点は、一度アップロードしてしまった写真に対して、容易に GPX ファイルを使って緯度経度を与えることができる点なんですけどね。
閑話休題。しょうがないので、自分で Pythonflickr.py を使って書き始めました。ほぼ完成しているのですが、いまは、GPX の trkseg で記録された時間範囲から、やや外れてしまっている写真に対して、ある程度位置を予測して緯度経度を記録するコードに苦労しています。アルゴリズムは簡単なものなのですが、コードに例外的な処理がたくさん入ってしまい、テストも面倒です。
なお、Flickr では位置情報を登録する際に、その精度(accuracy)を与えることができます。現在のところ、これは有効に活用されていないのですが、私のソフトでは、これも与えることができます。位置情報の誤差が 10m 以下と予測される場合は、accuracy = 16、誤差が 2倍になるに従って、accuracy を 1ずつ減少させるという、等比数列的な扱いを考えています。
今のところ、完成後にウェブ上のアプリとするか、スタンドアロンCUI ツールにするか決めかねていますが、これでようやく、GPS ロガーを従来通り活用できるようになりそうです。

二つの緯度経度間の距離を計算する

緯度はともかく、経度は、1度あたりの距離(正確には、曲がっているので大圏コースとも呼べないが)が緯度に依存するので、二点間の距離を計算するのは、やや困難です。また、北極や南極近辺では、地図を緯度経度を使って直交平面座標系に射影するのはほぼ不可能になります。そこで、素直に空間座標系を用います。
ところで、地球は真の球体ではなく回転楕円体ですが、今回の用途にはそこまでこだわることもないでしょう。(真面目に計算したい人は、理科年表が詳しいです。) ここでは、地球を完全な球体として考えます。緯度を\varphi、経度を\lambdaとすれば、その地点の直交座標(地球が原点)は以下で与えられます。

\large\left(\begin{array}x\\y\\z\end{array}\right)=r\cdot\left(\begin{array}\cos\varphi\cdot\cos\lambda\\\cos\varphi\cdot\sin\lambda\\\sin\varphi\end{array}\right)

r は、地球の半径(およそ 6400km)です。直交座標が求められれば、その間の距離はすぐに分かりますね。(中学校か高校の教科書を参照のこと。)

大圏コースの長さを求める

もし、二点間の大圏コースの長さを求めたい場合は、どうすれば良いでしょうか。
それにはまず最初に、地球中心を原点とするそれぞれの単位方向ベクトルのなす角度を求めます。角度は、二つの単位方向ベクトルの内積から得られます。(内積を計算するには、地球半径を乗ずる前の x, y, z を用い、二つのベクトルの x, y, z の要素をそれぞれ掛け合わせて、足し算すれば良い。つまり、\normalsize x_1x_2+y_1y_2+z_1z_2。) 次に、その内積の逆余弦cos^{-1})を計算します。これがベクトルのなす角度です。
角度がラジアンであれば、これに地球半径をかければ大圏コースの長さが分かります。簡単ですね。