LoginSignup
31
31

More than 5 years have passed since last update.

MySQL の Buffer という関数が位置範囲検索(中心から◯mとか)に便利そうだった

Last updated at Posted at 2014-07-22

MySQL 5.6.1 からみたいだけど、Buffer() という関数があるのを見つけたのでメモ。

Buffer( g , d )
Returns a geometry that represents all points whose distance from the geometry value g is less than or equal to a distance of d.
-- MySQL 5.6 Reference Manual :: 12.18.7 Spatial Operator Functions

ジオメトリの値 g から、範囲 d円形の ポリゴンを作成してくれる関数みたい。

実験例1

例えば以下のようなSQLを実行すると、

SELECT AsText(Buffer(POINT(139.663987,35.676577), 0.0005));

以下のようなポリゴンデータが返ってきた。

結果
POLYGON((139.663987 35.676077,139.66396246616281 35.676077602271896,139.66393799142983 35.676079407636664,139.66391363476276 35.67608241174502,139.663889454839 35.6760866073598,139.66386550991004 35.67609198437341,139.66384185766137 35.67609852983214,139.6638185550733 35.67610622796741,139.66379565828382.......))

上記のポリゴンをGoogleマップで描画してみると、このようになった。

第二引数 d についてはよくわからない・・・
上記画像の横の直径は約90mだったので、とりあえず 0.0005 = 約100m と思っておくことにしたw

これまでこういうのは複雑な計算してやってたけど、一発でいけたのでちょっと嬉しかった。

実験例2

実験例1 の中心点は、渋谷区、中野区、杉並区が隣接するあたり。
試しにこの地点の「範囲100mぐらいに何区が含まれるか」というのをやってみる。

市区町村の境界データは 国土数値情報 行政区域データ の東京都版を使用し、あらかじめ以下のようなテーブル構成で MySQL にブチ込んでおいた。

cities テーブル

city name polygon
11385 千代田区 POLYGON((139.770135 35.705352,139.770131...
11385 中央区 POLYGON((139.788911 35.694704,139.787379...
11385 港区 POLYGON((139.77326 35.629484,139.773459...
11385 新宿区 POLYGON((139.722506 35.712266,139.722399...
... ... ...

そして、とりあえず Intersects() 関数で、範囲約100mぐらいに含まれる市区町村を検索してみる。

SELECT
`city`,
`name`
FROM `cities`
WHERE Intersects(`polygon`, Buffer(POINT(139.663987,35.676577), 0.0005));
結果
+-------+-----------+
| city  | name      | 
+-------+-----------+
| 13114 | 中野区    |
| 13115 | 杉並区    |
| 13112 | 世田谷区  |
| 13113 | 渋谷区    |
+-------+-----------+

あら、なぜか世田谷区が登場したので MySQL 5.6 からまともになった ST_Intersects() でやってみる。

SELECT
`city`,
`name`
FROM `cities`
WHERE ST_Intersects(`polygon`, Buffer(POINT(139.663987,35.676577), 0.0005));
結果
+-------+-----------+
| city  | name      | 
+-------+-----------+
| 13114 | 中野区    |
| 13115 | 杉並区    |
| 13113 | 渋谷区    |
+-------+-----------+

今度はちゃんと返ってきた。


なんだか ST_Buffer() というのもあるっぽい(SQL文の Buffer() を ST_Buffer() にしても動く)けどソースを見つけられなかった。

それにしてもググラビリティの低い関数名がややこしいw


追記メモ(2014/07/23)

MySQL 5.6 から ST_Distance() という関数もあったので追記メモ。
その名の通り2点間の距離を測定する。

ST_Distance( g1 , g2 )
Returns the distance between g1 and g2.
-- MySQL 5.6 Reference Manual :: 12.18.8.1 Spatial Relation Functions That Use Object Shapes

返り値は 100倍するとキロメートル、10万倍するとメートルになる。

東京タワーから東京スカイツリーまでの距離
SELECT ST_Distance(POINT(139.745437, 35.658644), POINT(139.810571, 35.710172))*100;
/* = 8.305162695576657 km */

SELECT ST_Distance(POINT(139.745437, 35.658644), POINT(139.810571, 35.710172))*100000;
/* = 8305.162695576657 m */
31
31
1

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
31
31