Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

2 Safe harbor statement

Slide 3

Slide 3 text

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

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

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への コントリビュートも行っている

Slide 6

Slide 6 text

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

Slide 7

Slide 7 text

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

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

アップルップル 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で廃止されました).

Slide 10

Slide 10 text

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

Slide 11

Slide 11 text

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

Slide 12

Slide 12 text

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

Slide 13

Slide 13 text

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

Slide 14

Slide 14 text

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

Slide 15

Slide 15 text

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

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

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

Slide 18

Slide 18 text

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

Slide 19

Slide 19 text

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

Slide 20

Slide 20 text

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

Slide 21

Slide 21 text

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

Slide 22

Slide 22 text

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

Slide 23

Slide 23 text

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

Slide 24

Slide 24 text

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

Slide 25

Slide 25 text

使用例: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

Slide 26

Slide 26 text

使用例: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 なので、緯度-経度の順番で指定

Slide 27

Slide 27 text

使用例: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

Slide 28

Slide 28 text

備考:異なる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

Slide 29

Slide 29 text

備考:データ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オプションは、地理座標系場合のみ指定可能

Slide 30

Slide 30 text

参考情報: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

Slide 31

Slide 31 text

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

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

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

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

外部ファイルから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

Slide 37

Slide 37 text

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インデックスを追加したものを配布)

Slide 38

Slide 38 text

備考 • 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

Slide 39

Slide 39 text

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

Slide 40

Slide 40 text

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

Slide 41

Slide 41 text

お知らせ • 明日開催のハンズオン、参加者絶賛募集中です!! • 日時: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

Slide 42

Slide 42 text

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