17
23

More than 3 years have passed since last update.

【MySQL】Geometry型で位置情報を扱う

Posted at

はじめに

MySQL8.0では位置情報に関する機能が充実した...という情報を見かけたので、試しにGeometry型というデータ型を使って、位置情報を格納するテーブルを作ってみることにしました。

※GIS関連は全く詳しくないので、誤りがありましたらご指摘頂けると幸いです。

使用した環境

  • OS
    • CentOS7.7(1908)
  • RDBMS
    • MySQL8.0.19

テーブルの作成

  • 駅の位置を表すstationというテーブルをnkojimaデータベース内に作成しました。
  • 位置情報はlocationというGeometry型のカラムに持たせています。
  • 位置情報を表すデータ型はGeometry以外にも幾つか用意されており、以下に示したものは「OpenGIS クラスに対応するデータ型」となっています。
    • POINT:地点を表す。
    • LINESTRING:地点間を直線で結んだ線分を表す。
    • POLYGON:多辺の幾何図形を表す。
    • GEOMETRY:POINT、LINESTRING、POLYGONのいずれにも対応するルートクラス。
テーブルの作成
-- 駅情報テーブルの作成。
CREATE TABLE `nkojima`.`station` (
  `id` INT AUTO_INCREMENT comment '駅ID',
  `name` VARCHAR(50) NOT NULL comment '駅名', 
  `location` GEOMETRY NOT NULL comment '駅の座標',
  `note` VARCHAR(200) comment '備考',
  PRIMARY KEY (id),
  INDEX name_idx(name)
)
ENGINE = InnoDB,
default charset=utf8mb4
comment='駅情報';

データの登録

  • 都内のJRの駅から主要なものを選んで、大まかな座標を国土地理院の地図で取得しました。
  • Geometry型として利用するにはSRID(空間参照系識別子)が必要になりますが、ここでは4326(WGS84)にセットしました。
  • MySQL5.7ではGeomFromText関数が使われていましたが、MySQL8.0以降はGeomFromText関数は非推奨となっているため、ST_GeomFromTextを使うことになります。
    • GeomFromTextという名称はおそらく「Geometry From Text」の略で、「テキストからGeometry型に変換する」という処理がそのまま名称になっているのだと思われます。
INSERT文
USE nkojima;
INSERT INTO station (name, location, note) VALUES
("東京", ST_GeomFromText('POINT(35.681300 139.767165)', 4326), "23区"),
("新橋", ST_GeomFromText('POINT(35.666471 139.758357)', 4326), "23区"),
("品川", ST_GeomFromText('POINT(35.628829 139.739141)', 4326), "23区"),
("大崎", ST_GeomFromText('POINT(35.619131 139.728563)', 4326), "23区"),
("渋谷", ST_GeomFromText('POINT(35.658177 139.701741)', 4326), "23区"),
("新宿", ST_GeomFromText('POINT(35.688803 139.700925)', 4326), "23区"),
("池袋", ST_GeomFromText('POINT(35.730114 139.711053)', 4326), "23区"),
("日暮里", ST_GeomFromText('POINT(35.728163 139.770598)', 4326), "23区"),
("上野", ST_GeomFromText('POINT(35.713756 139.776950)', 4326), "23区"),
("四ツ谷", ST_GeomFromText('POINT(35.684834 139.730204)', 4326), "23区"),
("三鷹", ST_GeomFromText('POINT(35.702727 139.560978)', 4326), "多摩地区"),
("立川", ST_GeomFromText('POINT(35.698170 139.413671)', 4326), "多摩地区"),
("八王子", ST_GeomFromText('POINT(35.655370 139.339921)', 4326), "多摩地区"),
("北千住", ST_GeomFromText('POINT(35.749612 139.805059)', 4326), "23区"),
("赤羽", ST_GeomFromText('POINT(35.777732 139.721031)', 4326), "23区"),
("蒲田", ST_GeomFromText('POINT(35.562491 139.715924)', 4326), "23区");

データの検索

  • ST_AsText関数を使うことで、Geometry型のカラムを人が見て理解できる形式で取得できます。
    • ST_AsText関数を使わないと、Geometry型のカラムは16進数のデータとして表示されます。
mysql> SELECT
    ->   name AS 駅名,
    ->   ST_AsText(location) AS 緯度経度
    -> FROM station
    -> WHERE note='多摩地区';
+-----------+-----------------------------+
| 駅名      | 緯度経度                    |
+-----------+-----------------------------+
| 三鷹      | POINT(35.702727 139.560978) |
| 立川      | POINT(35.69817 139.413671)  |
| 八王子    | POINT(35.65537 139.339921)  |
+-----------+-----------------------------+

まとめ

  • ここまでの内容だとGeometry型などのデータ型を使うメリットがほとんど感じられませんが、「地点間の距離を計測する」「最寄りの地点を調べる」などの処理で力を発揮してくれるそうです。
    • この辺りについては次に投稿する記事で触れたいと思います。

参考URL

17
23
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
17
23