Vikingはまずい、とわかった段階で考えた。いっそ自分で計算してやるか。Vikingにパッチをあててやろうか、と——。結局、パッチはやめた。個人的なパッチなのでVikingがバージョンアップするたびに、対応することになる。面倒だ。
で、Emacsでやることにした。
GPXには位置(経度、緯度)と時刻(グリニッジ時)がある。そこから二点間の速度を計算するのを自前でやるのはそれほど、むずかしくないはずだ。問題は位置情報から距離をもとめるやり方だ。
一瞬、ピタゴラスの定理で求められるんじゃね? と思ったのだが、もちろんちがう。まちがっている。だいたい単位がちがうじゃないか。
で、調べてみると、いくつか方法はあるようで。
どうやらVikingは「2地点間の距離と方位角 - 高精度計算サイト」と同じやり方らしく、似た値になる。ほかに有名な「カシミール 3D」で使っているという「ヒュベニの公式」というものもあるらしい。さらにRのライブラリにあるだろうと、見当をつけてみたところ、2Dでの距離関数も見つけた。
さいわい「二地点の緯度・経度からその距離を計算する(日本は山だらけ〜)」というサイトに「ヒュベニの公式」のR実装があった。それを参考にelispで組み直した(引数の順番は変えた)。
(defun deg2rad(x) (/ (* x pi) 180.0)) (defun dist(lon1 lat1 lon2 lat2) "緯度1 経度1 緯度2 経度2" (let* ((a 6378137.0) (b 6356752.314140) (dy (deg2rad (- lon1 lon2))) (dx (deg2rad (- lat1 lat2))) (my (deg2rad (/ (+ lon1 lon2) 2))) (e2 (/ (- (expt a 2) (expt b 2)) (expt a 2))) (Mnum (* a (- 1 e2))) (W (sqrt (- 1 (* e2 (expt (sin my) 2))))) (M (/ Mnum (expt W 3))) (N (/ a W))) (sqrt (+ (expt (* dy M) 2) (expt (* dx N (cos my)) 2)))))
(dist 36.10056 140.09111 35.65500 139.74472) 58502.45893124113
まあ、だいじょうぶみたいだ。