$30 off During Our Annual Pro Sale. View Details »

MySQL 8.0 GIS機能チュートリアル

MySQL 8.0 GIS機能チュートリアル

2019年10月13日(日)に開催された「FOSS4G 2019 KOBE.KANSAI コアデイ」での発表資料です。
https://www.osgeo.jp/events/foss4g-2019/foss4g-2019-kobe-kansai/foss4g-2019-kobe-coreday

YoshiakiYamasaki

October 13, 2019
Tweet

More Decks by YoshiakiYamasaki

Other Decks in Technology

Transcript

  1. Yoshiaki Yamasaki / 山﨑 由章
    MySQL Principal Solution Engineer, Asia Pacific and Japan
    MySQL 8.0 GIS機能チュートリアル
    2019/10/13 FOSS4G KOBE.KANSAI
    1

    View Slide

  2. 2
    Safe harbor statement

    View Slide

  3. MySQLのGIS機能の歴史
    アジェンダ
    MySQLのGIS機能を使用したシステムの例
    MySQLで扱えるデータ型、データの挿入/参照方法
    外部ファイルからMySQLへのデータ取り込み方法
    まとめ、お知らせ
    3

    View Slide

  4. MySQLのGIS機能の歴史
    アジェンダ
    MySQLのGIS機能を使用したシステムの例
    MySQLで扱えるデータ型、データの挿入/参照方法
    外部ファイルからMySQLへのデータ取り込み方法
    まとめ、お知らせ
    4

    View Slide

  5. MySQLのGIS機能の歴史
    • MySQL 5.7
    • Boost.GeometryというC++のオープンソースライブラリを採用して独自実装をやめ、
    InnoDBでGIS関連機能を再実装
    • MySQL 8.0
    • 演算、データ変換に役立つ各種のSpatial関数の追加
    • MySQL 5.7で非推奨になった関数の廃止
    • Geography サポート
    • Spatial Data、Spatial Index、Spatial関数のSRIDサポート
    5
    ※Boost.Geometryコミュニティとも活発に交流し、MySQLチームからBoost.Geometryへの
    コントリビュートも行っている

    View Slide

  6. MySQLは積極的にGIS機能を開発しています!!
    6

    View Slide

  7. MySQLのGIS機能の歴史
    アジェンダ
    MySQLのGIS機能を使用したシステムの例
    MySQLで扱えるデータ型、データの挿入/参照方法
    外部ファイルからMySQLへのデータ取り込み方法
    まとめ、お知らせ
    7

    View Slide

  8. アップルップル
    8
    アプリケーション
    「a-blog cms」は、アップルップルが開発する国産のCMSです。
    様々な業種のWebサイト制作に使われており、2019年10月現在
    公開可能事例550件、非公開事例3,400件以上の実績があります。
    「a-blog cms」では、投稿記事の属性として位置情報を含めること
    ができます。位置情報は MySQLのgeometry型に保存されています。
    この機能を活用することで、ユーザーの近くの情報を表示する、
    といったWebページ制作を可能にしています。
    MySQLのGIS機能の活用例

    View Slide

  9. アップルップル
    9
    位置情報を使用したWebページの例
    名古屋地区の情報を発信しているSpyMasterでは、この機能を活用
    してユーザーの近くのスポット情報を表示できるようにしています。
    ユーザーの現在地をJavaScriptのGeolocation APIを使って取得し、
    現在地からの距離をMySQLのST_Length関数で計算しています。
    MySQLのGEOMETRY型とJavaScriptのGeolocation APIの活用事例(※)
    https://speakerdeck.com/steelydylan/mysqlfalse-geometry-xing-
    tojavascriptfalse-geolocation-api-falsehuo-yong-shi-li
    ※本資料ではGLength関数を使った例が紹介されていますが、今後実装する際は
    ST_ Length関数を使用下さい。
    (GLength関数はMySQL 5.7で非推奨になり、MySQL 8.0で廃止されました).

    View Slide

  10. SpyMaster (https://spymaster.jp)
    10
    GLength関数(ST_Length関数)で距離計算することで、現在地から近い
    スポット情報や、今表示しているスポットから近いスポットを表示

    View Slide

  11. ヤマレコ
    11
    アプリケーション
    ヤマレコは「また山に行きたくなる」Webサービスです。登山の記
    録をヤマレコに残し、他の人と共有することが出来ます。登山者の
    知識・情報を共有することで登山計画を立てやすくし、遭難防止に
    も役立っています。また、登山者の位置情報をリアルタイムで共有
    することで家族が登山状況を確認出来たり、万が一の場合の救助活
    動にも役立ったりしています。
    2005年10月にサービスを開始し、2019年9月時点で「月間140万人
    が訪問するWebサイト」、「40万ダウンロードの登山地図アプリ」
    となっています。

    View Slide

  12. ヤマレコ
    12
    MySQLのGIS機能の活用例
    山行記録の地図検索機能をMySQLのGIS機能を活用して実装して
    います。空間インデックスを使用し、標準検索モードでは
    MBRContains関数を、高精度検索モードではST_Contains関数を
    利用して、検索範囲に含まれる山行記録を高速に検索できるように
    しています。

    View Slide

  13. 山行記録の地図検索機能
    13
    Leaflet、MySQL(Spatialインデックス+Spatial関数)を使って実装
    ST_Contains関数
    (オブジェクト形状を考慮)
    MBRContains関数
    (最小外接矩形で判定)
    検索範囲
    他の登山者のGPS
    ログ(点の集合)

    View Slide

  14. MySQLのGIS機能の歴史
    アジェンダ
    MySQLのGIS機能を使用したシステムの例
    MySQLで扱えるデータ型、データの挿入/参照方法
    外部ファイルからMySQLへのデータ取り込み方法
    まとめ、お知らせ
    14

    View Slide

  15. MySQLで扱えるデータ型
    • POINT:点
    • LINESTRING:線
    • POLYGON:多角形
    15

    View Slide

  16. MySQLで扱えるデータ型
    • POINT:点
    • 例:緯度、経度
    • LINESTRING:線
    • 例:ルート(道筋)
    • POLYGON:多角形
    • 例:市町村の区画
    16

    View Slide

  17. MySQLで扱えるデータ型
    • POINT:点
    • 例:緯度、経度
    • LINESTRING:線
    • 例:ルート(道筋)
    • POLYGON:多角形
    • 例:市町村の区画
    • GEOMETRY:POINT、LINESTRING、POLYGONをまとめて扱える
    17

    View Slide

  18. MySQLで扱えるデータ型
    • 集合を扱えるデータ型
    • MULTIPOINT:POINTの集合
    • MULTILINESTRING:LINESTRINGの集合
    • MULTIPOLYGON:POLYGONの集合
    • GEOMETRYCOLLECTION: GEOMETRYの集合
    18

    View Slide

  19. MySQLのGEOMETRY型に関する補足
    • PostGISでいうジオグラフィ型(※)に相当するものはない
    • SRID:4326のデータも扱うことはできるが、それだけに特化したデータ型は無い
    19
    ※WGS84 地理座標系(SRID:4326)のみサポートするデータ型

    View Slide

  20. 空間データの表現方法
    • WKT(Well-Known Text)
    • 幾何学オブジェクトをテキストで表現するための仕様
    • WKB(Well-Known Binary)
    • 幾何学オブジェクトをバイナリで表現するための仕様
    • MySQLの内部表現
    • WKBの先頭にSRIDを追加したもの
    20

    View Slide

  21. WKTの例
    • POINT(15 20) ※区切りはスペース
    • LINESTRING(0 0, 10 10, 20 25, 50 60)
    • POLYGON((0 0,10 0,10 10,0 10,0 0)) ※最初の点に戻る
    • POLYGON((0 0,10 0,10 10,0 10,0 0),(5 5,7 5,7 7,5 7, 5 5))
    ※中をくりぬくことも可能
    21

    View Slide

  22. WKTから空間データを生成する関数
    • ST_GeomFromText()
    • ST_PointFromText()
    • ST_LineStringFromText()
    • ST_PolygonFromText()
    • ST_MultiPointFromText()
    • ST_MultiLineStringFromText()
    • ST_MultiPolygonFromText()
    • ST_GeometryCollectionFromText()
    22

    View Slide

  23. WKBから空間データを生成する関数
    • ST_GeomFromWKB()
    • ST_PointFromWKB()
    • ST_LineStringFromWKB()
    • ST_PolygonFromWKB()
    • ST_MultiPointFromWKB()
    • ST_MultiLineStringFromWKB()
    • ST_MultiPolygonFromWKB()
    • ST_GeometryCollectionFromWKB()
    23

    View Slide

  24. データを変換する関数
    • ST_AsText()
    • ST_AsBinary()
    • ST_SwapXY()
    24

    View Slide

  25. 使用例:ST_GeomFromText、ST_AsTextの動作確認
    mysql> SELECT ST_GeomFromText('LineString(1 1,2 2,3 3)');
    +---------------------------------------------------------------+
    | ST_GeomFromText('LineString(1 1,2 2,3 3)') |
    +---------------------------------------------------------------+
    | ð? ð? @ @ @ @ |
    +---------------------------------------------------------------+
    1 row in set (0.00 sec)
    mysql> SELECT ST_AsText(ST_GeomFromText('LineString(1 1,2 2,3 3)'));
    +-------------------------------------------------------+
    | ST_AsText(ST_GeomFromText('LineString(1 1,2 2,3 3)')) |
    +-------------------------------------------------------+
    | LINESTRING(1 1,2 2,3 3) |
    +-------------------------------------------------------+
    1 row in set (0.00 sec)
    25

    View Slide

  26. 使用例:SRID:4326を指定して、緯度経度を格納
    mysql> CREATE TABLE test(id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(30),
    location POINT SRID 4326);
    Query OK, 0 rows affected (0.04 sec)
    mysql> INSERT INTO test(name, location) VALUES(’KIITO’,
    ST_GeomFromText('POINT(34.6850502 135.1987589)', 4326));
    Query OK, 1 row affected (0.01 sec)
    mysql> SELECT id, name, ST_ASTEXT(location) FROM test;
    +----+-------+-------------------------------+
    | id | name | ST_ASTEXT(location) |
    +----+-------+-------------------------------+
    | 1 | KIITO | POINT(34.6850502 135.1987589) |
    +----+-------+-------------------------------+
    1 row in set (0.00 sec)
    26
    SRID:4326のAxis OrderはLat-Long
    なので、緯度-経度の順番で指定

    View Slide

  27. 使用例:2点の距離を計算
    mysql> INSERT INTO test(name, location) VALUES(‘ひょうたん’,
    ST_GeomFromText('POINT(34.6922791 135.1918453)', 4326));
    Query OK, 1 row affected (0.01 sec)
    mysql> SELECT ST_Distance((SELECT location FROM test WHERE id=1),
    (SELECT location FROM test WHERE id=2), 'metre')/1000 AS Km FROM dual;
    +--------------------+
    | Km |
    +--------------------+
    | 1.0219803291719762 |
    +--------------------+
    1 row in set (0.00 sec)
    27

    View Slide

  28. 備考:異なるSRIDのデータをINSERTするとエラーになる
    mysql> INSERT INTO test(name, location) VALUES(‘KIITO’,
    ST_GeomFromText('POINT(34.6850502 135.1987589)', 6668));
    ERROR 3643 (HY000): The SRID of the geometry does not match the SRID of the
    column 'location'. The SRID of the geometry is 6668, but the SRID of the
    column is 4326. Consider changing the SRID of the geometry or the SRID
    property of the column.
    28

    View Slide

  29. 備考:データINSERT時にAxis Orderを明示的に指定可能
    mysql> INSERT INTO test(name, location) VALUES(‘KIITO’,
    ST_GeomFromText(‘POINT(135.1987589 34.6850502)’, 4326,
    'axis-order=long-lat'));
    Query OK, 1 row affected (0.01 sec)
    29
    ※axis-orderオプションは、地理座標系場合のみ指定可能

    View Slide

  30. 参考情報:SRID:4326の定義を確認
    mysql> SELECT * FROM INFORMATION_SCHEMA.ST_SPATIAL_REFERENCE_SYSTEMS WHERE
    SRS_ID=4326¥G
    *************************** 1. row ***************************
    SRS_NAME: WGS 84
    SRS_ID: 4326
    ORGANIZATION: EPSG
    ORGANIZATION_COORDSYS_ID: 4326
    DEFINITION: GEOGCS["WGS 84",DATUM["World Geodetic System
    1984",SPHEROID["WGS
    84",6378137,298.257223563,AUTHORITY["EPSG","7030"]],AUTHORITY["EPSG","6326"]]
    ,PRIMEM["Greenwich",0,AUTHORITY["EPSG","8901"]],UNIT["degree",0.0174532925199
    43278,AUTHORITY["EPSG","9122"]],AXIS["Lat",NORTH],AXIS["Lon",EAST],AUTHORITY[
    "EPSG","4326"]]
    DESCRIPTION: NULL
    1 row in set (0.00 sec)
    30

    View Slide

  31. MySQL Workbenchでデータを確認しOpenStreetMapで表示
    31
    • 手順は以下のQiitaの記事参照
    • MySQL 8.0にPOINTデータ(経度、緯度)を入れてMySQL Workbenchから検索し、
    OpenStreetMapで表示する
    https://qiita.com/yyamasaki1/items/c05f60357c69936fa0e7

    View Slide

  32. MySQL Workbenchでデータを確認しOpenStreetMapで表示
    32

    View Slide

  33. MySQL Workbenchでデータを確認しOpenStreetMapで表示
    33
    日本一短い国道
    (全長187.1m)
    ボウリング発祥の地
    (記念碑あり)

    View Slide

  34. GeoJSONを扱えるSpatial関数もある
    • ST_AsGeoJSON():ジオメトリ型のデータを入力し、GeoJSONデータを出力
    • ST_GeomFromGeoJSON():GeoJSONデータを入力し、ジオメトリ型の
    データを出力
    34
    ※詳細を解説しているマニュアル
    MySQL 8.0 Reference Manual / 12.15.11 Spatial GeoJSON Functions
    https://dev.mysql.com/doc/refman/8.0/en/spatial-geojson-functions.html

    View Slide

  35. MySQLのGIS機能の歴史
    アジェンダ
    MySQLのGIS機能を使用したシステムの例
    MySQLで扱えるデータ型、データの挿入/参照方法
    外部ファイルからMySQLへのデータ取り込み方法
    まとめ、お知らせ
    35

    View Slide

  36. 外部ファイルからMySQLへのデータ格納方法
    • シェープファイル、GeoJSONファイルのデータを取り込む方法について、
    先日のFOSS4G Niigataでの発表資料にまとめています
    • MySQL 8.0で強化されたGIS機能と使用事例のご紹介+α
    https://speakerdeck.com/yoshiakiyamasaki/mysql-8-dot-0deqiang-hua-saretagisji-
    neng-toshi-yong-shi-li-falsegoshao-jie-a
    36

    View Slide

  37. MySQLのGIS機能を手軽に試してもらうために
    • (会社としての公式な活動では無く)私の個人的なプロジェクトとして、
    MySQLに取り込み済みのGISデータの配布を始めました
    • 手始めに、兵庫県の小地域の境界データ(※)を以下で配布しています
    • https://github.com/YoshiakiYamasaki/MySQL-GIS-Data-Japan-eStat
    • 今後他の都道府県の境界データも追加予定
    37
    ※出典:政府統計の総合窓口(e-Stat)(https://www.e-stat.go.jp/)
    (e-Statからダウンロードした世界測地系のシェープファイルをMySQLに取り込み、
    SHAPE列にSRIDとSpatialインデックスを追加したものを配布)

    View Slide

  38. 備考
    • ST_Intersects()、ST_Overlaps()の実行速度が非常に遅いという問題に
    関して、残念ながらまだ調査状況に進展はありません
    • Bug#96311: ST_Intersects() is very slow on MySQL 8.0
    https://bugs.mysql.com/bug.php?id=96311
    • ST_Within()で代替できるケースでは、現状はST_Within()を使用下さい
    (ST_Within()は高速に実行できています)
    38

    View Slide

  39. MySQLのGIS機能の歴史
    アジェンダ
    MySQLのGIS機能を使用したシステムの例
    MySQLで扱えるデータ型、データの挿入/参照方法
    外部ファイルからMySQLへのデータ取り込み方法
    まとめ、お知らせ
    39

    View Slide

  40. まとめ
    • MySQLのGIS機能を是非試してみて下さい!!
    • 試してみて気づいたことがあれば、是非フィードバック下さい
    • MySQL Bugs
    https://bugs.mysql.com/
    40

    View Slide

  41. お知らせ
    • 明日開催のハンズオン、参加者絶賛募集中です!!
    • 日時:2019年10月14日(月・祝) 14:00-17:00
    • タイトル:JavaScriptとMySQLでGISを作ってみよう
    • 概要:MySQLのGIS機能や位置情報の取り扱いについて解説し、
    その実例としてJavaScriptでお手軽にGISを実装してみます。
    • 参加費:2,000円
    • 詳細:https://www.osgeo.jp/events/foss4g-2019/foss4g-2019-kobe-kansai/foss4g2019-
    kobe-handson
    41

    View Slide

  42. お知らせ
    • (東京開催ですが)
    MySQLのGIS機能に焦点を当てたイベント開催予定です!!
    • 日時:2019年12月5日(月) 18:30-21:00頃 ※開催時間調整中
    • 場所:日本オラクル株式会社 本社 (外苑前駅直結)
    • 参加費:無料
    • 詳細:後日connpassのOracle Code Nightグループで公開予定
    https://oracle-code-tokyo-dev.connpass.com/
    • 今日より時間が長いのでもう少し詳しいチュートリアルセッションを
    開催することを検討中です!!
    42

    View Slide