MySQLはLat-Lon記述順にST_SPATIAL_REFERENCE_SYSTEMSの定義を参照しているのか?

MySQLでは、より正確に書くと、我々がよく使う JGD2011やWGS84を使う際には、緯度(Lat)と経度(Lon)を表す際 (Lat Lon)の順序で記述します。これは PostGISなど他のGISツールでよく使われている記述順序と逆のものです。この挙動は「ST_SPATIAL_REFERENCE_SYSTEMS上にある JGD2011の定義情報の中で Lat-Lon の順序で示されているからだ」と私は理解し、そのように語ってもきました。
 しかし考えてみたら、本当にST_SRSを参照しているのか。実は決め打ちで (Lat-Lon)なのではないか、というウラを取ったことがなかったので、このたび、動作を確認してみました。 MySQL 8.1.0を使用しています。

SRS:6668の定義の確認

INFORMATION_SCHEMA内でST_SPATIAL_REFERENCE_SYSTEMSテーブルの内容を確認します。SRS_IDが 6668(JGD2011)の定義は以下のようになっています。なおこの定義は、先日の当ブログの記事「MySQLのJGD2011での座標系変換/換算にトライ」にてTOWGS84に対応済みのものとなっています(デフォルトの情報とは異なっているのでご注意ください)。

mysql> select * FROM st_spatial_reference_systems where srs_id=6668;
+----------+--------+--------------+--------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+
| SRS_NAME | SRS_ID | ORGANIZATION | ORGANIZATION_COORDSYS_ID | DEFINITION                                                                                                                                                                                                                                                                                                                                          | DESCRIPTION |
+----------+--------+--------------+--------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+
| JGD2011  |   6668 | EPSG         |                     6668 | GEOGCS["JGD2011",DATUM["Japanese Geodetic Datum 2011",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","1128"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943278,AUTHORITY["EPSG","9122"]],AXIS["Lat",NORTH],AXIS["Lon",EAST],AUTHORITY["EPSG","6668"]] | NULL        |
+----------+--------+--------------+--------------------------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+-------------+

AXIS["Lat",NORTH],AXIS["Lon",EAST], の順で記述されていますね。

SRS:4326から6668への変換

 WGS84からJGD2011への変換を試みましょう。
ここへは掲載しませんが、SRS:4326(WGS84)も(Lat-Lon)なので、値は変化しないと予測されます。

mysql> SELECT ST_AsText( ST_Transform( ST_GeomFromText('POINT(35 135)',4326), 6668 )) g;
+---------------+
| g             |
+---------------+
| POINT(35 135) |
+---------------+

 ちょっと分かりにくいですが上のクエリは、

  • SRS4326 (WGS84)で、POINT(35 135)を作成し、
  • それを ST_Transform で 6668 (JGD2011) に変換し、
  • ST_AsTextで可読化している

というクエリです。

WGS84で与えられた (35 135) が、JGD2011での (35 135)へと無事変換されていることが確認できました。

Lon-Lat順で定義されたSRSへと変換したら?

 いま私たちは「実際には存在しない測地系を作成する」ワザを持っています(先日のエントリ)。
ここで、SRS:6668をコピーしてLat/Lonの順序だけを入れ替えた SRS:16668を作成して確認することにしましょう!

mysql> CREATE OR REPLACE SPATIAL REFERENCE SYSTEM 16668
    -> NAME 'JGD2011LonLat'
    -> ORGANIZATION 'EPSG' IDENTIFIED BY 16668
    -> DEFINITION 'GEOGCS["JGD2011",DATUM["Japanese Geodetic Datum 2011",SPHEROID["GRS 1980",6378137,298.257222101,AUTHORITY["EPSG","7019"]],TOWGS84[0,0,0,0,0,0,0],AUTHORITY["EPSG","1128"]],PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.017453292519943278,AUTHORITY["EPSG","9122"]],AXIS["Lon",EAST],AXIS["Lat",NORTH],AUTHORITY["EPSG","16668"]]';
Query OK, 0 rows affected, 1 warning (0.01 sec)

 名称や数字など細々いじっていますが、ポイントは AXIS["Lon",EAST],AXIS["Lat",NORTH] 順の定義にしたことです。
warningが出ていますが、指定したIDに関するものなのでここでは無視します。

mysql> show warnings;
+---------+------+--------------------------------------------------------------------------------------------------------------------------------------------------+
| Level   | Code | Message                                                                                                                                          |
+---------+------+--------------------------------------------------------------------------------------------------------------------------------------------------+
| Warning | 3715 | The SRID range [0, 32767] has been reserved for system use. SRSs in this range may be added, modified or removed without warning during upgrade. |
+---------+------+--------------------------------------------------------------------------------------------------------------------------------------------------+

SRS:4326から今作った16668への変換

 先ほどと同様に、WGS84(SRS:4326)からJGD2011(Lon-Lat順) (SRS:16668) への変換を試みましょう。

mysql> SELECT ST_AsText( ST_Transform( ST_GeomFromText('POINT(35 135)',4326), 16668 )) g;
+---------------+
| g             |
+---------------+
| POINT(135 35) |
+---------------+


おおお!!! Lon-Lat順の数値が返ってきました!

まとめ

 このことから、MySQLの Lat/Lon の記述順序は、その測地系のものとして定義された内容に従うことを確認できました。
すばらしきMySQL