準備
$ sudo docker run --platform linux/x86_64 -p 3307:3306 -e MYSQL_ROOT_PASSWORD=my-secret-pw -d mysql:latest $ mysql -uroot -pmy-secret-pw -h127.0.0.1 -P3307
mysql > create database geosample;
空間情報の型
空間情報を表現する型は次のとおりです。
型名 | 意味 |
POINT |
点 |
LINESTRING |
線 |
POLYGON |
面 |
GEOMETORY |
上記すべてを表現できる |
MULTIPOINT |
点の集合 |
MULTILINESTRING |
線の集合 |
MULTIPOLYGON |
面の集合 |
GEOMETORYCOLLECTION |
上記すべてを表現できる |
空間情報の表し方
空間情報型を扱うサンプルです。
空間情報型はバイナリで管理されているため、SELECTしても分かりません。
mysql> create table geo (id INTEGER, pos GEOMETRY); Query OK, 0 rows affected (0.02 sec) -- 座標(3, 5)を挿入 mysql> insert into geo values (1, ST_GeomFromText('POINT(3 5)')); Query OK, 1 row affected (0.01 sec) -- (3, 5), (4, 7), (5, 2)を結んだ線を表現する値 LINESTRING(3 5, 4 7, 5 2)を挿入 mysql> insert into geo values (2, ST_GeomFromText('LINESTRING(3 5, 4 7, 5 2)')); Query OK, 1 row affected (0.01 sec) -- POLYGONは点を結んでいき最後に始点に戻る面を表す -- (1, 1), (5, 1), (5, 5), (1, 5), (1, 1)を結んだときにできる面 POLYGON((1 1, 5 1, 5 5, 1 5, 1 1) を挿入 mysql> INSERT INTO geo VALUES (3, ST_GeomFromText('POLYGON((1 1, 5 1, 5 5, 1 5, 1 1))')); Query OK, 1 row affected (0.01 sec) -- selectで直接見るとバイナリで保存されていることがわかる -- 先述のPOINT(3 5)がWKT(Well Known Text)に対してMySQLの内部表現にST_GeomFromText()に変換される. mysql> select * from geo; +------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | id | pos | +------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | 1 | 0x00000000010100000000000000000008400000000000001440 | | 2 | 0x000000000102000000030000000000000000000840000000000000144000000000000010400000000000001C4000000000000014400000000000000040 | | 3 | 0x0000000001030000000100000005000000000000000000F03F000000000000F03F0000000000001440000000000000F03F00000000000014400000000000001440000000000000F03F0000000000001440000000000000F03F000000000000F03F | +------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 3 rows in set (0.00 sec)
MySQL内部表現からWKTへの変換はST_AsText()
で計算できます。
-- pos はGEOMETRY型なのでPOINT, LINESTRINGなどの型が共存できる mysql> SELECT id, ST_AsText(pos) FROM geo; +------+--------------------------------+ | id | ST_AsText(pos) | +------+--------------------------------+ | 1 | POINT(3 5) | | 2 | LINESTRING(3 5,4 7,5 2) | | 3 | POLYGON((1 1,5 1,5 5,1 5,1 1)) | +------+--------------------------------+ 3 rows in set (0.00 sec)
空間情報に対しての関数
POINT間の距離を計算したい場合ST_Distance()
関数を用います。
ST_Distance()
関数への引数にはMySQLの内部表現バイナリを入れることに注意。
mysql> SELECT ST_Distance(ST_GeomFromText('POINT(1 1)'), ST_GeomFromText('POINT(3 2)')) AS dist; +------------------+ | dist | +------------------+ | 2.23606797749979 | +------------------+ 1 row in set (0.01 sec)
地球上の位置情報
上述の計算は平面での話です。
空間情報型の応用先は現実(地球上)の座標間の計算です。
測地系
-- CREATE TABLE geo2 (id INTEGER, カラム GEOMETRY型 SRID 測地系のID); mysql> CREATE TABLE geo2 (id INTEGER, pos GEOMETRY SRID 6668); Query OK, 0 rows affected (0.02 sec) -- 測地系6668で'POINT(43.06416667 141.3469444)'のPOINTを挿入 mysql> INSERT INTO geo2 VALUES (1, ST_GeomFromText('POINT(43.06416667 141.3469444)', 6668)); Query OK, 1 row affected (0.01 sec)