25
© Copyright 2008 Oki Electric Industry Co., Ltd. MySQL������������� distance_sphere()����GPL�� �����������

MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Page 1: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

© Copyright 2008 Oki Electric Industry Co., Ltd.

MySQLへの地理空間距離関数の追加

distance_sphere()の移植とGPL公開

奥村幸治@沖電気工業㈱

Page 2: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--11--© Copyright 2008 Oki Electric Industry Co., Ltd.

位置表現抽出・管理サービス LocoStickerとは

位置(緯度経度)をキーにコンテンツ検索を可能に

周辺地域もまとめて検索可能

異表記(住所とスポット名、別名)もまとめて検索可能

複数地点で存在する地名を区別して検索可能

位置情報で検索位置情報で検索キーワードで検索キーワードで検索

位置表現抽出

エンジン

N34.25, E135.32

N35.75, E134.38N36.11, E132.43

N35.54, E133.44

秋芳洞

京都瓦河原町 東京ミッドタウン

五条

Page 3: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--22--© Copyright 2008 Oki Electric Industry Co., Ltd.

LocoStickerの処理の流れ

名古屋(35.170794, 136.882291)東京(35.680964, 139.766688)虎ノ門駅(35.670158, 139.750117)日本橋駅(34.666957, 135.506985)日本橋駅(35.681882, 139.773334)

■データベースに緯度経度とURLを関連付けて格納■データベースに緯度経度とURLを関連付けて格納

今朝は名古屋から東京に移動しました。午前中は、日本橋駅付近のお客様を訪問しました。午後は、早めの昼食を取って、日本橋駅から地下鉄に乗って、虎ノ門駅まで行きました。

今朝は名古屋から東京に移動しました。午前中は、日本橋駅付近のお客様を訪問しました。午後は、早めの昼食を取って、日本橋駅から地下鉄に乗って、虎ノ門駅まで行きました。

■文章から位置表現(住所、施設名等)を抽出■文章から位置表現(住所、施設名等)を抽出

■複数の緯度経度を持つ位置表現の緯度経度特定■複数の緯度経度を持つ位置表現の緯度経度特定

■ 文 章 の 内 容 か ら 主 要 エ リ ア を 決 定■ 文 章 の 内 容 か ら 主 要 エ リ ア を 決 定

■URLをデータベースから緯度経度で検索■URLをデータベースから緯度経度で検索

Page 4: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--33--© Copyright 2008 Oki Electric Industry Co., Ltd.

LocoStickerを使ったアプリケーションの例

Open API公開中 http://locosticker.jp/

Page 5: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--44--© Copyright 2008 Oki Electric Industry Co., Ltd.

ブログサーチ http://locosticker.jp/blogsearch/

LocoSticker を使ったアプリケーションのデモ

Page 6: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--55--© Copyright 2008 Oki Electric Industry Co., Ltd.

データベースでは

1. 十字マークから近い位置数か所について、

2. 新しいコンテンツを数個ずつ取得

ブログ記事数:10,000,000以上

スポット数:300,000件以上

今も増加中

Page 7: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--66--© Copyright 2008 Oki Electric Industry Co., Ltd.

LocoStickerで使用しているデータベース

オープンソースで空間情報を扱うデータベースといえば、

PostGIS(PostgreSQLのGIS拡張版)

Page 8: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--77--© Copyright 2008 Oki Electric Industry Co., Ltd.

PostGISで作ってみた結果は…

重い!

特に複数同時リクエスト(Webサービスアクセス集中)時

機能は十分でしたが…

Page 9: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--88--© Copyright 2008 Oki Electric Industry Co., Ltd.

MySQLなら?

WebサービスならMySQL? (LinuxApacheMySQLPHP)

MySQL-GIS(MySQLのGIS拡張版)

Page 10: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--99--© Copyright 2008 Oki Electric Industry Co., Ltd.

処理時間を比較してみました。

0.55710.517100

0.2201.8171MySQLPostGIS同時タスク数

単体でもMySQLの方が速いが、特に複数同時に処理したときにMySQLのほうが速いことが判明

検索応答平均処理時間(単位秒)

注:我々の仕様、条件での測定。常にMySQLが速いと言ってるわけではありません。

•PostgreSQL8.3.1 + PostGIS1.3.2

•MySQL5.1.23-beta-GIS

Page 11: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--1010--© Copyright 2008 Oki Electric Industry Co., Ltd.

Webサービスでは速さは重要なポイント

MySQLに移行することに

Page 12: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--1111--© Copyright 2008 Oki Electric Industry Co., Ltd.

移行作業途中で機能が足りないことに気づく

distance_sphere(point1, point2):

緯度経度で示された2点間の距離を球面計算して返す。

distance(point1, point2):

X,Yで示された2点間の距離を平面計算して返す。

誤差: 大阪→東京間: 403,095m(球) → 438,233m(平面)

がない!

でも、もう PostGISには戻れない

Page 13: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--1212--© Copyright 2008 Oki Electric Industry Co., Ltd.

自作する?

国土地理院で計算式が公開…緯度・経度から平面直角座標 x,yを求める計算

2点の平面直角座標 x,yから測地線長および方向角を求める計算

Ss

yyxxS

212

212

2221

212

020

0 611 yyyymR

mSs

220 cos

21 tNSSx {

086428

6222426

44224

54331111385cos40320

1

3302705861cos7201

495cos241

mttttN

ttttN

ttN

cosNy {

076427

5222425

3223

17947961cos5040

1

5814185cos1201

1cos61

mtttN

tttN

tN

私の頭では理解不能… orz

Page 14: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--1313--© Copyright 2008 Oki Electric Industry Co., Ltd.

一から自作はむりぽ

PostGIS,MySQLは OpenSourceだ!

Page 15: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--1414--© Copyright 2008 Oki Electric Industry Co., Ltd.

まずはハック

該当部の記述言語はPostGISがC,MySQLがC++。

geometory型のデータはPostGIS, MySQLとも内部では独自のバイナリ形式で格納、両者に互換性はなし。

MySQLのUDF(User Defined Function)の引数の型はSTRING_RESULT, INT_RESULT, REAL_RESULT, DECIMAL_RESULTのいずれか…無理やりgeometry型を渡すとSTRING_RESULT。

STRING_RESULTのとき、データはCの文字列形式(¥0終端)ではなく、データの先頭アドレスと長さが取得できる。

MySQLのGeometry型を使えば内部形式から x, y, geometry_typeが取得できる

Page 16: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--1515--© Copyright 2008 Oki Electric Industry Co., Ltd.

PostGIS→MySQLへdistance_sphere()を移植

移植手順

1. PostGISの該当関数[LWGEOM_distance_sphere()]をPostGISのgeometry型から緯度経度を取得する部分と、緯度経度から距離を求める関数[calc_distance_sphere()]に分離。

2. MySQLのUDFの引数(STRING)からGeometryデータを作成し、それから緯度経度を取得する処理と1のcalc_distance_sphere()を呼ぶ処理をUDFに記述。

3. 1の緯度経度から距離を求める関数と、2の緯度経度を取得する関数の組み合わせでdistance_sphere()のUDF(User Defined Function)を実現

Geometry → x,y x,y → distance

STRING→ Geomety → x,y x,y → distance

PostGIS

MySQL

distance_sphere() calc_distance_sphere()

LWGEOM_distance_sphere()

Page 17: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--1616--© Copyright 2008 Oki Electric Industry Co., Ltd.

書いた処理 -MySQLのUDFの引数(STRING)から緯度経度取得

イリーガルな作成方法で省力化。

distance_sphere()に書いたのは実はこれだけ

Geometry *g1, *g2;Geometry_bufferbuffer1, buffer2;g1 = Geometry::construct(&buffer1, args->args[0], args->lengths[0]);g2 = Geometry::construct(&buffer2, args->args[1], args->lengths[1]);

double x1, x2, y1, y2;((Gis_point*)g1)->get_xy(&x1, &y1);((Gis_point*)g2)->get_xy(&x2, &y2);

UDFの引数からGeometryデータを作成

Geometryデータから緯度経度を取得

公開時にパラメータのエラーチェックとかを少し追加しました。

return calc_distance_sphere(x1, y1, x2, y2);

緯度経度から距離を計算

Page 18: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--1717--© Copyright 2008 Oki Electric Industry Co., Ltd.

省力化の副作用

イリーガルなUDF作成手順が必要

mysql.h

UDF自作ソース

MySQL-GISソース

通常のUDF作成に必要なもの

今回のUDFで更に必要なもの

spatial.ccmysql_priv.h spatial.h

udf_distance_spheroid.cc calc_distance_spheroid.cc

通常のUDFライブラリ

今回のUDFライブラリ

Page 19: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--1818--© Copyright 2008 Oki Electric Industry Co., Ltd.

公開

ライセンスは迷うことなく(強制的に)GPLWebサービスとして提供している間はソース配布義務はない。

作ったのはこれだけ。

Geometry *g1, *g2;Geometry_bufferbuffer1, buffer2;g1 = Geometry::construct(&buffer1, args->args[0], args->lengths[0]);g2 = Geometry::construct(&buffer2, args->args[1], args->lengths[1]);

double x1, x2, y1, y2;((Gis_point*)g1)->get_xy(&x1, &y1);((Gis_point*)g2)->get_xy(&x2, &y2);

return calc_distance_sphere(x1, y1, x2, y2);

目立つ方が得! →公開してGPLに貢献しよう。

http://okilab.jp/でソース公開中

Page 20: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--1919--© Copyright 2008 Oki Electric Industry Co., Ltd.

反響

MySQLな世界 GISな世界GPL公開

小さいですが…コーディング量の割にはMySQLの身内で受けてます。

Okilab.jp

MySQLForum

MySQLProject

Lenz Grimmer'sblog

magnifier

Page 21: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--2020--© Copyright 2008 Oki Electric Industry Co., Ltd.

MySQL創始者直筆サイン入りバッグが貰えました。

DavidAxmark氏をはじめ来日したキーマンと直接話もできました。

タダ酒(FreeBeer)飲めました。

GISの充実をお願いしておきました。(私の英語が通じたかは謎)

Page 22: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--2121--© Copyright 2008 Oki Electric Industry Co., Ltd.

MySQLコミュニティから応援メッセージも貰えました。

Lenz Grimmer氏(MySQLシニア・プロダクション・エンジニア )のブログでも紹介されました。

応援メッセージも貰えました。気分よくおだててもらえます。

"I am very excited about Mr. Okumura's work. His MySQL UDF implementssome often requested functionality and nicely compliments our ongoingefforts to improve the GIS functions in MySQL. I am looking forward tofurther improvements of this plugin!"

私の英語力をみかねて日本法人の梶山隆輔氏(MySQL シニアエバンジェリスト)が翻訳してくれました(笑)

“奥村さんの活動を非常にうれしく思っています。奥村さんが開発されたMySQLのUDFの実装は、要望を多く受ける機能であり、我々が現在行っているMySQLのGIS関数に対する改良の方向性と非常にうまくマッチしています。このプラグインのさらなる改良を心より期待しております。"

http://lenz.homelinux.org/archives/220-New-UDF-for-MySQL-5.1-provides-GIS-functions-distance_sphere-and-distance_spheroid.html

Page 23: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--2222--© Copyright 2008 Oki Electric Industry Co., Ltd.

MySQLへのGISの貢献は

おいしい分野! 貢献しがいのある分野!

MySQL側も注目するはず!

オープンソースで空間情報を扱うデータベースの充実

利用条件に応じて最適なデータベースが選択可能に!

貢献が増えると

注目されると

GIS,日本語が充実するはず

Page 24: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--2323--© Copyright 2008 Oki Electric Industry Co., Ltd.

いきなり、むりやり、まとめ。

GISを扱うデータベースといえば PostGIS。 ですが、時には MySQLを採用するといい場面もある。

現状、MySQLのGIS機能はPostGISに比べ足りないものがある。

GIS機能をUDFの仕組みを使ってMySQLに追加できる。

Geometry型のデータはMySQL本体のソースをUDFに取り込むことでUDFの中でも容易に扱うことができる。

MySQLのGIS分野にはオープンソースプログラマとして貢献できる余地が大きい。

特に今ならMySQL側も積極的に応援してくれる。

GIS分野への貢献が多くなると、 MySQL側もよりGISに力をいれてくれるはず。

オープンソースなGISデータベースの選択肢が増えれば嬉しいですよね。

Page 25: MySQLへの地理空間距離関数の追加 - old.osgeo.jp · 複数地点で存在する地名を区別して検索可能 キキーーワワードードでで検索検索 位置情報位置情報でで検索検索

--2424--© Copyright 2008 Oki Electric Industry Co., Ltd.

ありがとうございました。

連絡先

関連サイトURL(再掲)

http://okilab.jp/

http://locosticker.jp/

MySQLdistance UDF検索