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 */