読者です 読者をやめる 読者になる 読者になる

INPUTしたらOUTPUT!

忘れっぽいんでメモっとく

PostGISで逆ジオコーディングする

以前、逆ジオコーディングするためにelasticsearchを使用する記事を書いた。


PostgreSQLの<->演算子で近傍探索すると簡単に逆ジオコーディングできたのでメモしとく。


データの準備

今回は位置参照情報ダウンロードサービスからダウンロードできるデータを使用する。

街区レベル位置参照情報とは、全国の都市計画区域相当範囲を対象に、街区単位(「○○町△丁目□番」)の位置座標(代表点の緯度・経度、平面直角座標)を整備したデータです。このデータを利用することで、住所などを含む表や台帳データに位置座標(緯度経度等)を付け、GISで地図上に展開して空間的な分析をすることができるようになります。

とあるのでより精度を求めるのであれば以下のようなデータを購入する必要がある。


テーブルの作成

ダウンロードしたデータを格納するテーブルを作成する。

位置参照情報ダウンロードサービス(http://nlftp.mlit.go.jp/isj/)からダウ ...


データのロード

ダウンロードしたファイルをテーブルに格納するにはcopyコマンドを使用する。encodingオプションでSJISを指定する必要がある。以下は東京都のデータをロードする例。

COPY loc_ref_info FROM '/tmp/13_2015.csv' WITH CSV HEADER ENCODING 'SJIS';


ジオメトリ型の列の作成

Geometry型のデータを追加する。緯度・経度の測地系世界測地系日本測地系2000)なのでSRIDは4612を指定する。

SELECT AddGeometryColumn('loc_ref_info', 'the_geom', 4612, 'POINT', 2);


追加したGeometry型の列を緯度・経度から更新する。

UPDATE loc_ref_info SET the_geom = ST_SETSRID(ST_POINT(lon, lat), 4612);


GiSTインデックスの作成

USING GIST句を指定してGiSTインデックスを作成する。

CREATE INDEX gist_loc_ref_info ON loc_ref_info USING GIST (the_geom);


逆ジオコーディング

近傍探索を行うにはORDER BY句で<->演算子を使用する。東京タワー(@35.658581,139.745433)で試して見る。

SELECT pref, city, town, block, lat, lon
FROM   loc_ref_info
WHERE  representative = 1
ORDER BY ST_SETSRID(ST_POINT(139.745433, 35.658581), 4326) <-> the_geom
LIMIT 5;
pref city town block lat lon
東京都 港区 芝公園四丁目 2 35.658537 139.745418
東京都 港区 東麻布一丁目 2 35.657928 139.744644
東京都 港区 芝公園四丁目 3 35.657780 139.746259
東京都 港区 芝公園四丁目 4 35.657498 139.745022
東京都 港区 東麻布一丁目 1 35.658388 139.744269

東京タワーの住所は 東京都港区芝公園4丁目2−8なので合っていそう。


念のためRとLeafletで地図にプロットして確認してみる。

f:id:tak95:20161104111541p:plain

逆ジオコーディング結果を地図にプロット

ほとんど重なってしまっているが東京タワーと一番近いレコードが最初に取得できているようだ。



ちゃんとしたデータを使えば号レベルの逆ジオコーディングができることが確認できた。PostgreSQLを使用すると近傍探索が簡単にできるので近隣の店舗・施設検索なども容易に実装できそう。