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
まあ、だいじょうぶみたいだ。