MySQL8.0のGIS距離計算を検証してみた
目次
まえおき
- これは RDBMS-GIS(MySQL,PostgreSQLなど) Advent Calendar 2018 - Qiita の4日目です。
- MySQL8.0のGIS機能を使って2点間の距離を計算した結果が確からしいかどうかを確かめることにします。
- 本当に小ネタです。
- 先に書いておきますが、中途半端な結論になってます。
検証
方法
とはいえどうやって検証すればよいか悩みました。
いろいろ悩んであちこち遠回りしたり試行錯誤したりした結果、「国土地理院のサイトにあるサービスの距離計算と比較する」ということに勝手に落ち着きました。
国土地理院のサイトの中にある 測量計算サイト トップページ の中にある、 測量計算(距離と方位角の計算) (以下 「「距離と方位角の計算」のページ」と記述)の計算結果とMySQL8.0.12での計算結果を比べます。
「距離と方位角の計算」のページでは測地系を指定することはできず、楕円体を選択できます。
今回は「GRS80」という楕円体を使用します。
「GRS80」を調べると日本測地系JGD2000およびJGD2011でも採用している楕円体らしいのですが、同サイトの別のページに「PatchJGD」という地殻変動による補正値をパッチする機能があることから、「距離と方位角の計算」のページはパッチ適用前の値であると推測/仮定し、今回MySQLで距離計算に使うSRIDはJGD2000とすることにします。
(ここ考え方自体が間違ってるかもしれません。)
検証1
以下の2点間の距離を測ります。
- 26.212299 127.679203 (那覇市役所)
- 43.062031 141.354375 (札幌市役所)
座標はGoogleMapで建物の中央付近を調べたものであり、公式な座標値ではありません。
名前は参考としてお考え下さい。
まずは「距離と方位角の計算」のページでの計測です。
結果 2,244,138.116(m)
次にMySQL8.0での計算結果です。
JGD2000の地理座標系のSRIDは4612なのでSQLは以下のように記載しました。
SET @g1 = ST_GeomFromText('POINT(26.212299 127.679203)', 4612); SET @g2 = ST_GeomFromText('POINT(43.062031 141.354375)', 4612); SELECT ST_Distance(@g1, @g2);
結果 2244143.71316939
差は約5.6m、0.00025% となりました。
検証2
以下の2点間の距離を測ります。
- 51.507881, -0.087731 (ロンドン橋)
- 35.662233, 139.774887 (勝鬨橋)
座標はGoogleMapで橋の中央付近を調べたものであり、公式な座標値ではありません。
橋の名前は参考としてお考え下さい。
まずは「距離と方位角の計算」のページでの計測です。
結果 9,586,604.159(m)
次にMySQL8.0での計算結果です。
SET @g1 = ST_GeomFromText('POINT(51.507881 -0.087731)', 4612); SET @g2 = ST_GeomFromText('POINT(35.662233 139.774887)', 4612); SELECT ST_Distance(@g1, @g2);
結果
9586598.67397081
差は約6m、0.00006% となりました。
まとめ
さて、わずかとはいえ誤差が出た以上は「確か」とは言い難いところです。
この差がどこから生まれるのかはいずれのソースコードも見ていない(見てもわからない)私にはどうしようもないのですが、以下のいずれかによるのではないかと思っています。
- 私の勘違い(使うべき数値やSRID)
- 内部的な算術桁数
- 内部的な計算順序の違い
現時点での結論としては
わずかな違いはあるが、とても近い数値が出ているのでそれっぽい
とさせてください。
なんとも中途半端なもので申し訳ないです。
(カレンダーなので締め切りがありますゆえご容赦願います。)
言い訳
- sakaiさんからこのカレンダーへの参加をお誘いいただいてから色々ネタを考えていたんですが、調べ事をするたびに新しい疑問がわいてしまい、なかなか本題に戻れない=記事が書けない状態が続いていました。
- 前提知識の薄さに加えて、高校のころ数学全般が苦手で赤点ばかり取っていただけのことはあり、調べ事の過程で数学に関する知識を要求されるたびに思考停止してしまう自分が情けないです。
- ただ、せっかく調べたんだし、何かしらの成果をスコープを絞ってできる範囲でアウトプットしようとこの記事を書きました。まさかりはコメント欄などに投げつけてください。
参考にさせていただきました
おまけ
上の「検証2」について測地系(SRID)を追加してMySQLで計算してみました。
測地系 | SRID | 楕円体 | 結果 | JGD2000との差 |
---|---|---|---|---|
JDG2000 | 4612 | GRS80 | 9586598.67397081 | - |
JDG2011 | 6668 | GRS80 | 9586598.67397081 | 0 |
WGS84 | 4326 | WGS84 | 9586598.6739077 | 0.06mm |
Tokyo | 4301 | ベッセル楕円体 | 9585448.11720308 | 1150m |
これらはSRID間での比較ですので記事本題とはあまり関係ありません。
が、楕円体の違うSRID 4301だけ違いが明らかで面白いですね。