untitled .engineer

技術系のブログ(仮)

MySQL8.0でGIS機能を試す 投影座標系のデータを使うケースの訂正


目次


eyechatch

まえおき

ポイント

  • 地理座標系でGEOMETRY(POINT)型のデータを作る際にPOINT(北緯X度 東経Y度)という構文を使っていました。これは問題ありません。
  • 投影座標系ではこの書き方ではなく、座標系原点からそれぞれ北にXm 東にYm移動した地点かを引数にとるようです。ここを理解していませんでした。
    • 座標系原点はそのSRIDごとに個別に定義されています

さて、では「座標系原点からそれぞれ北にXm 東にYm移動した地点か」の変換はどうすればよいのでしょうか。
残念ながら現(2018/12/03)時点での最新版MySQL8.0.13においてはその方法が提供されてないようです。
ST_Transform()は実装されたものの、地理座標系から投影座標系への変換は対応していないと。(ソースはsakaikさん。)

なので今回は一旦別のサービスを使って変換を行い、その数値を使うことにします。

地理座標系で計測

以下の2点間の距離をST_Distance()で測ってみます。

  1. 37.749957 140.467734 福島県
  2. 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% となりました。
  • 地理座標系と投影座標系との比較なうえに、途中で別のサービスで値を変換しているので当然ながら結果は変わるでしょう。
  • ただ、訂正前の意味不明な比較よりはだいぶマシな結果に落ち着くことができました。