MySQL8.0でGIS機能を試す 投影座標系のデータを使うケースの訂正
目次
まえおき
- これは RDBMS-GIS(MySQL,PostgreSQLなど) Advent Calendar 2018 - Qiita の8日目です。
- 以前MySQL8.0でGIS機能を試す No.4 - 投影座標系のデータを使ってみるというタイトルで書いた内容(以降「訂正前」と表現します)について大きな勘違いをしていることに気づいたので書き直しです。
- なお、私の「MySQL8.0でGIS機能を試す」シリーズの記事は主に「ARスマートフォンアプリIngressの機能をMySQLのGIS機能で再現してみる」ことを目的にしていますが、No.4はIngressとは直接関係ないネタになっています。
ポイント
- 地理座標系でGEOMETRY(POINT)型のデータを作る際に
POINT(北緯X度 東経Y度)
という構文を使っていました。これは問題ありません。 - 投影座標系ではこの書き方ではなく、座標系原点からそれぞれ北にXm 東にYm移動した地点かを引数にとるようです。ここを理解していませんでした。
- 座標系原点はそのSRIDごとに個別に定義されています
さて、では「座標系原点からそれぞれ北にXm 東にYm移動した地点か」の変換はどうすればよいのでしょうか。
残念ながら現(2018/12/03)時点での最新版MySQL8.0.13においてはその方法が提供されてないようです。
ST_Transform()は実装されたものの、地理座標系から投影座標系への変換は対応していないと。(ソースはsakaikさん。)
なので今回は一旦別のサービスを使って変換を行い、その数値を使うことにします。
地理座標系で計測
以下の2点間の距離をST_Distance()で測ってみます。
- 37.749957 140.467734 福島県庁
- 35.44771 139.642536 神奈川県庁
(この2か所の採用理由は下で説明しますのでここではスキップします。)
SET @g1 = ST_GeomFromText('POINT(37.749957 140.467734)', 4612); SET @g2 = ST_GeomFromText('POINT(35.44771 139.642536)', 4612); SELECT ST_Distance(@g1, @g2);
結果: 265934.59137509
約265.93km です。
投影座標系で計測
投影座標系の場合エリアによってSRIDが違います。
違うSRID同士の比較はSQLでエラーになってしまうのは前回試したので省略します。
今回は同じ JGC2000の平面直角座標系の9系の中に収まる2点間を比較することにします。
わかりやすい平面直角座標系|国土地理院
ということで同じ9系に収まる「福島県庁」と「神奈川県庁」を採用します。
JGC2000の平面直角座標系の9系のSRIDは2451です。
訂正前の方法はここでうっかり
SET @g1 = ST_GeomFromText('POINT(37.749957 140.467734)', 2451); SET @g2 = ST_GeomFromText('POINT(35.44771 139.642536)', 2451); SELECT ST_Distance(@g1, @g2);
としてしまい、
結果: 2.44566820893861
2.4という小さすぎる値になりました。
そしてその理由を愚かなことに単位の違いに求めてさまよいまってしまいました。
繰り返しになりますが、投影座標系でPOINT()は、座標系原点からそれぞれ北にXm 東にYm移動した地点かを引数にとるようですので根本的に間違ってます。
まずは「座標系原点からそれぞれ北にXm 東にYm移動した地点か」の変換に皆さんおなじみ(?)の国土地理院のサイトにあるサービスを使うことにします。
平面直角座標への換算
上記ページでは「世界測地系」と「日本測地系」を選択できるのですが、「日本測地系」は古い測地系Tokyoを意味するようなので「世界測地系」で計算します。
本当はMySQLの中でできるのが理想なんですが・・・
参考名 | 北緯 | 東経 | 変換後X | 変換後Y |
---|---|---|---|---|
福島県庁 | 37.749957 | 140.467734 | 194372.1113 | 55904.3307 |
神奈川県庁 | 35.44771 | 139.642536 | -61255.8721 | -17320.4159 |
訂正後のSQLはこうなります。
SET @g1 = ST_GeomFromText('POINT(194372.1113 55904.3307)', 2451); SET @g2 = ST_GeomFromText('POINT(-61255.8721 -17320.4159)', 2451); SELECT ST_Distance(@g1, @g2);
結果: 265908.874262942
約265.91km です。
まとめ
- 計算結果との差は 25.7m 0.0096% となりました。
- 地理座標系と投影座標系との比較なうえに、途中で別のサービスで値を変換しているので当然ながら結果は変わるでしょう。
- ただ、訂正前の意味不明な比較よりはだいぶマシな結果に落ち着くことができました。