読者です 読者をやめる 読者になる 読者になる

Snippets

対抗して作ってみた。

ヒュベニの式

ヒュベニの式

緯度経度から距離をもとめるのにヒュベニの式というのがあると聞いた。 カシミールのマニュアルによると以下のとおりである:

  D=sqrt((M*dP)^2+(N*cos(P)*dR)^2) 
  
           D:  2点間の距離(m) 
           P:  2点の平均緯度 
           dP: 2点の緯度差 
           dR: 2点の経度差 
           M:  子午線曲率半径
           N:  卯酉線曲率半径 
  
               M=6334834/sqrt((1-0.006674*sin(P)*sin(P))^3) 
               N=6377397/sqrt(1-0.006674*sin(P)*sin(P))

ちょっと見ればわかるように、ピタゴラスの定理に楕円体であることの補正を加えたものだ。平面の距離がもとになってるので、東京からNYCへの距離のような大圏コースをもとめるのはムリだろう。

そこの定数が一瞬謎だが、山だらけというサイトを見るといろいろわかる。

  • 6334834: 長半径 * (1 - 第一離心率 ^ 2)
  • 6377397: 長半径
  • 0.006674: 第一離心率 ^ 2

これを elispでかいてみる。ちなみに上の式は旧日本測地系になっているので、GRS80にあわせるよう適宜数値を直した。

(setq long-radius 6378137.0)
(setq flattening (/ 1 298.257222101))
(setq eccentricity2 (* flattening (- 2 flattening)))

(defun hubeny-radian (x0 y0 x1 y1) 
   (let* ((dr (- x0 x1))
          (dp (- y0 y1))
          (p (/ (+ y0 y1) 2.0))
          (sinp (sin p))
          (w (sqrt (- 1.0 (* eccentricity2 sinp sinp))))
          (m (/ (* long-radius (- 1 eccentricity2)) (* w w w)))
          (n (/ long-radius w)))
     (sqrt (+ (expt (* m dp) 2) (expt (* n (cos p) dr) 2)))))

(defun deg2rad (x) (/ (* pi x) 180))

(defun hubeny (lat0 lng0 lat1 lng1) 
   (hubeny-radian (deg2rad lng0) (deg2rad lat0)
                  (deg2rad lng1) (deg2rad lat1)))

さっそく計算してみる。山だらけにある例で見る.

; 東京、筑波
(hubeny 35.65500 139.74472 36.10056 140.09111)
=> 58502.45893124258


; 成田空港滑走路
(hubeny 35.802739 140.380034 35.785796 140.392265) 
=> 2180.9484697650064

途中で、 latと lngの位置を勘違いしてハマったが、なんとか正しい値が出たようだ。

本当は、さらに大圏コースも含めて正しい測地線の長さが出るようにしてみたかったが、すごく頑張ると楕円積分とか出てきそうなのでやめにする。