地球上の2地点間の距離を取得するアルゴリズム(ヒュベニ or 球面三角法)比較【JavaScript】

地球上の2地点間の距離を取得するアルゴリズム(ヒュベニ or 球面三角法)比較【JavaScript】

2018-05-0613 min read

目次

  1. 概要
  2. ソース
  3. 結果
  4. まとめ
  5. 参考

概要

以前、地球上の2地点間の距離を計算する実装を行なった際に「ヒュベニの公式」と「球面三角法」を比較したことがあります。 ここでは改めて2つのアルゴリズムを実装して比較してみようと思います。

ヒュベニの公式

http://hp.vector.co.jp/authors/VA002244/yacht/geo.htm

ヒュベニの式を用いた、緯度・経度と距離・方位の相互変換の解説

球面三角法

https://ja.wikipedia.org/wiki/%E7%90%83%E9%9D%A2%E4%B8%89%E8%A7%92%E6%B3%95

球面三角法 基本的な三角関数を組み合わせたものです。 球面三角法はヒュベニと比べ計算結果は荒くなります。

ソース

下記のソースでは「ヒュベニの公式」 と 「球面三角法」 を比較しています。

//
// ヒュベニの公式
//
function hubeny(lat1, lng1, lat2, lng2) {
    function rad(deg) {
        return deg * Math.PI / 180;
    }
    //degree to radian
    lat1 = rad(lat1);
    lng1 = rad(lng1);
    lat2 = rad(lat2);
    lng2 = rad(lng2);

    // 緯度差
    var latDiff = lat1 - lat2;
    // 経度差算
    var lngDiff = lng1 - lng2;
    // 平均緯度
    var latAvg = (lat1 + lat2) / 2.0;
    // 赤道半径
    var a = 6378137.0;
    // 極半径
    var b = 6356752.314140356;
    // 第一離心率^2
    var e2 = 0.00669438002301188;
    // 赤道上の子午線曲率半径
    var a1e2 = 6335439.32708317;

    var sinLat = Math.sin(latAvg);
    var W2 = 1.0 - e2 * (sinLat * sinLat);

    // 子午線曲率半径M
    var M = a1e2 / (Math.sqrt(W2) * W2);
    // 卯酉線曲率半径
    var N = a / Math.sqrt(W2);

    t1 = M * latDiff;
    t2 = N * Math.cos(latAvg) * lngDiff;
    return Math.sqrt((t1 * t1) + (t2 * t2));
}

//
// 球面三角法
//
function sphericalTrigonometry(lat1, lng1, lat2, lng2) {
    // 赤道半径
    var R = 6378137.0;

    function rad(deg) {
        return deg * Math.PI / 180;
    }

    return R *
        Math.acos(
            Math.cos(rad(lat1)) *
            Math.cos(rad(lat2)) *
            Math.cos(rad(lng2) - rad(lng1)) +
            Math.sin(rad(lat1)) *
            Math.sin(rad(lat2))
        );
}

GeoLocationAPIとの組み合わせ

https://developer.mozilla.org/ja/docs/Web/API/Geolocation/Using_geolocation

GeoLocationAPIと組み合わせて現在地と任意の地点間の距離を計測します。

var getSuccess = function(pos) {

    //現在地の緯度経度
    var lat1 = pos.coords.latitude;
    var lng1 = pos.coords.longitude;

    //新宿都庁の座標
    var lat2 = 35.689487;
    var lng2 = 139.691706;

    //距離の計算//
    var ans1, ans2;
    try {
        ans1 = hubeny(lat1, lng1, lat2, lng2);
        ans2 = sphericalTrigonometry(lat1, lng1, lat2, lng2);
    } catch (e) {
        alert(e);
    }

    //結果
    document.getElementById("result1").innerHTML = ans1 + " m";
    document.getElementById("result2").innerHTML = ans2 + " m";
};

var geoError = function() {
    var pos = {
        'coords': {
            'latitude': 35.5562073,
            'longitude': 139.5723855
        }
    };
    getSuccess(pos);
    alert('Getting location failed.');
};

// GeoLocationAPIで現在地の座標を取得する
document.getElementById("start").onclick = function() {
    navigator.geolocation.getCurrentPosition(getSuccess, geoError, {
        enableHighAccuracy: true
    });
};

デモ(外部リンク)

結果

https://vldb.gsi.go.jp/sokuchi/surveycalc/main.html

国土地理院のサイトの計算結果と一緒に2つの実装を比較してみました。

※単位 : m

東京-川崎

東京(35.689487, 139.691706) 〜 川崎(35.5562073, 139.5723855)

球面三角法 : 18317.126210821592
ヒュベニ    : 18349.45459166647
地理院    : 18317.122

数メートルの誤差が生じる。

東京-名古屋

東京 〜 名古屋(35.2, 136.9)

球面三角法 : 259215.96201641572
ヒュベニ    : 258964.81739383226
地理院    : 259205.815

1km未満ではあるが誤差が生じた。

東京-ギニア湾

東京 〜 ギニア湾(0.0, 0.0)

球面三角法 : 15324766.692400709
ヒュベニ    : 14278853.174450254
地理院    : 14274245.589

まとめ

数キロ程度の距離の計算では、ヒュベニと球面三角法の差は小さいものとなりましたが、 実用するのであれば様々なソフトウェアで採用実績のあるヒュベニの公式を使うのが無難かもしれません。

また、今回のソースでは測地系の差を考慮していないので、用いる測地系によって計算結果が少し変わってくると思います。

参考

https://keisan.casio.jp/exec/system/1257670779

https://qiita.com/chiyoyo/items/b10bd3864f3ce5c56291

https://qiita.com/port-development/items/eea3a0a225be47db0fd4

Recommends
地球上の2地点間の距離を取得するアルゴリズム(ヒュベニ or 球面三角法)比較【JavaS...
2018-05-06
html5
javascript
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
【JavaScript】K-meansを使って画像を減色する。全てフルスクラッチ【canv...
2018-07-01
html5
javascript
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
【JavaScript】凸包(グラハムスキャン)を可視化・アニメーション【Canvas】
2018-06-21
html5
css3
javascript
【JavaScript】K-meansをアニメーション・可視化したら蜘蛛みたいな動きをした...
2018-06-11
html5
javascript
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
【JavaScript】K-meansをアニメーション・可視化したら蜘蛛みたいな動きをした...
2018-06-10
html5
css3
javascript
javascriptで累積和を解く
2022-02-27
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%83%9F%E3%83%B3%E3%82%B0
atcoder
JSで動的計画法を利用して部分和問題を解く
2022-02-20
javascript
typescript
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
JavaScriptで優先度付きキューを実装する
2021-08-01
javascript
typescript
%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0
next_permutationをJSで実装する
2021-07-22
javascript
typescript
%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0
JSで32ビット符号付き整数に対してのビット演算でハマった
2021-02-17
javascript
node.js
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
JSでIPアドレスがサブネットマスクで指定した範囲内にあるか判定する
2021-02-16
javascript
node.js
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
プログラムの数値計算で発生する誤差の種類 丸め誤差・打ち切り誤差・桁落ち
2021-02-09
javascript
node.js
rust
JSでサブネットマスクの計算
2021-02-04
javascript
node.js
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
10進数から2進数 2進数から10進数への変換 JavaScript
2020-07-12
javascript
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0
JavaScriptの配列ショートハンド (AtCoder用)
2020-07-05
javascript
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0
New Posts
zplug 環境の構築とpromptの調整
2022-11-13
zsh
mac
linux
バッチ処理を採用する際に考慮したことと実装の諸々
2022-10-30
%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3
[JS]Intl.DateTimeFormatで和暦と西暦を変換
2022-08-18
javascript
[NestJS]少し大きな規模のRESTfull APIを構築するディレクトリ構成を考えて...
2022-09-04
nestjs
typescript
%E3%82%A2%E3%83%BC%E3%82%AD%E3%83%86%E3%82%AF%E3%83%81%E3%83%A3
Prisma MySQL でUTC以外の任意のタイムゾーンを利用するのが難しい件
2022-08-08
prisma
typescript
mysql
Prisma TypeScript MySQLなプロジェクトの構築
2022-08-08
prisma
typescript
mysql
Prisma TypeScript SQLiteなプロジェクトの構築
2022-08-06
prisma
typescript
sqlite
[AWS]Lambda vs Fargate. APIを実装する場合に思うこと
2022-07-30
amazon%20aws
amazon%20ecs
%E9%9B%91%E8%AB%87
macOSにzigをインストールしてHello World!する
2022-07-18
zig
mac
[AWS CDK] Cognito の OIDC プロバイダに Auth0 を設定
2022-07-03
auth0
amazon%20aws
aws%20cdk
Amazon S3 でライフサイクルポリシーを設定する
2022-06-19
amazon%20aws
amazon%20s3
AWS Certified Developer Associate に合格した
2022-06-19
amazon%20aws
%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93
Fisher-Yates shuffleで配列シャッフル [js/ts/php]
2022-06-19
javascript
node.js
typescript
JavaScriptでUTF-16コードを文字列に変換
2022-06-18
javascript
node.js
[JS]乱数でランダムな整数を生成する
2022-06-18
javascript
node.js
Hot posts!
Proxy環境下でcurlを実行する
2019-12-07
linux
curl
OpenCVのMatのタイプ一覧表
2018-11-25
%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86
opencv
Macでも利用できるDBクライアント MySQL PostgreSQL Oracle など
2019-12-21
linux
%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9
mysql
TablePlusを使ってみる。シンプルでモダンなSQLクライアントツール
2018-09-30
%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9
DBクライアントツールはDBeaverをおすすめしたい
2021-03-08
oracle
mysql
sqlite
AWS S3のアクセスキーIDとシークレットアクセスキーの取得 作業用ユーザを作成
2019-06-12
amazon%20aws
linux
amazon%20s3
AtCoderで初めて色がつくまでの話(茶色) レートが中々上がらなかった原因
2018-11-25
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0
%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0
%E9%9B%91%E8%AB%87
CentOS8でEPELとPowerToolsリポジトリの有効化
2020-11-30
centos
red%20hat
EPEL
Macでターミナルからポートスキャンを行う方法。
2018-12-09
linux
mac
apple
Python + OpenCVのfillConvexPolyで複雑なポリゴンを描画する
2018-11-27
python
%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86
opencv
Date
▶︎
2022 年 (41)
▶︎
2021 年 (40)
▶︎
2020 年 (30)
▶︎
2019 年 (90)
▶︎
2018 年 (89)
▶︎
2017 年 (1)
Tags
javascript(98)
linux(48)
amazon%20aws(47)
node.js(38)
%E3%82%A2%E3%83%AB%E3%82%B4%E3%83%AA%E3%82%BA%E3%83%A0(36)
%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86(30)
html5(29)
typescript(28)
php(24)
centos(24)
python(22)
%E7%AB%B6%E6%8A%80%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0(21)
mac(20)
mysql(19)
canvas(18)
opencv(17)
%E9%9B%91%E8%AB%87(16)
wordpress(15)
atcoder(14)
docker(14)
apache(12)
%E6%A9%9F%E6%A2%B0%E5%AD%A6%E7%BF%92(12)
%E3%83%87%E3%83%BC%E3%82%BF%E3%83%99%E3%83%BC%E3%82%B9(12)
amazon%20s3(12)
red%20hat(12)
ubuntu(11)
github(10)
git(10)
vue.js(10)
%E7%94%BB%E5%83%8F%E5%87%A6%E7%90%86100%E6%9C%AC%E3%83%8E%E3%83%83%E3%82%AF(10)
mariadb(10)
aws%20cdk(9)
css3(8)
%E5%8F%AF%E8%A6%96%E5%8C%96(8)
%E5%B0%8F%E3%83%8D%E3%82%BF(8)
amazon%20lightsail(7)
react(7)
%E3%83%96%E3%83%AD%E3%82%B0(6)
cms(6)
oracle(6)
perl(6)
gitlab(6)
next.js(6)
iam(5)
amazon%20ec2(5)
%E8%B3%87%E6%A0%BC%E8%A9%A6%E9%A8%93(5)
aws%20amplify(5)
curl(4)
webassembly(4)
ssh(4)
Author
s-yoshiki
s-yoshiki
githubzennqiita
ただの備忘録です。
JavaScript/TypeScript/node.js/React/AWS/OpenCV
※このブログの内容は個人の見解であり、所属する組織等の見解ではありません。