緯度経度って奴をDBにいれる。 PostgresならPostGISって奴があるらしい。

とりあえずローカルで試す。

brew install postgresql
brew install postgis

データベースを作る

createdb postgis_sample
psql -d postgis_sample -c "CREATE EXTENSION postgis;"

CREATE EXTENSION postgis; すれば postgis が使えるらしい。

八丁堀から510ビルまでの距離を求めてみる。

$ psql -d postgis_sample -c "SELECT ST_Distance(ST_GeographyFromText('Point(132.463495 34.393817)'), ST_GeographyFromText('Point(132.468527 34.393366)'));"
  st_distance
---------------
 465.421862299

ST_Distanceで距離を算出できる。

テーブルをつくってみる。

CREATE table places ( name VARCHAR(255),geog GEOGRAPHY(Point));
INSERT INTO places  VALUES ('ShakeHands', 'POINT(132.458767 34.394010)');
INSERT INTO places  VALUES ('MOVIN''ON', 'POINT(132.465314 34.393052)');

シャレオ中央からの距離を求めてみる。

> SELECT name, ST_Distance(geog, ST_GeographyFromText('POINT(132.457589 34.395300)')) FROM places;

ShakeHands | 179.475100761
 MOVIN'ON   | 752.858070591

500m 以内の絞り込みをしてみる。

SELECT name FROM places WHERE ST_Distance(geog, ST_GeographyFromText('POINT(132.457589 34.395300)')) < 500;

ShakeHands

3000件つっこんで検索してみる

$ for i in `seq 3000`
> do
>   psql -d postgis_sample -c "INSERT INTO places  VALUES ('$i', 'POINT(132.$i 34.$i)');"
> done

$ psql -d postgis_sample

> /timing

> SELECT name FROM places WHERE ST_Distance(geog, ST_GeographyFromText('POINT(132.457589 34.395300)')) < 5000

Time: 12.816 ms;

12msだった。ジオグラフィ型だと計算量があれこれらしいの狭い範囲ならジオメトリでやるほうがよいようだけど、どうしたらよいかわからないけど、ジオグラフィのままでも場合によっては良さそう。

参考文献