関連して以下も参考にしてください
- [初めて地図周りの技術に触れた時に作ったまとめ資料 - Qiita] (http://qiita.com/laqiiz/items/7d256108920ff7afbf08)
やりたい事
GoogleのGeocodingであったりYahoo!のジオコーダAPIを用いれば、住所の表記ゆれにも対応したよりスマートな緯度経度取得が可能ですが、利用数の制限や規約があるのが不便です。
もっと何度でも繰り返し自由に使える環境が欲しい!ということで本記事の内容となります。
「市区町村番地から緯度経度」ではなく、「緯度経度から市区町村番地」を取得する格好いいやり方は、masuidrive様の素晴らしく参考になる記事を参考下さい。
サマリ
- データ取得
- PostgreSQLに突っ込む
- 動作確認
データ取得
位置参照情報ダウンロードサービスについてからデータ取得
国土交通省が出してくれているデータです。
2014年ころから町丁目レベルのデータを提供してくれているそうです。
「位置参照情報ダウンロードサービスへ」のリンクをクリック
→「都道府県選択」のリンクをクリック
→「全ての都道府県を選択」
→「街区レベル」を選択してそれぞれポチポチDL
(※)都道府県ごとにポチポチするので時間かかります‥。
ダウンロード結果
% ls
01000-12.0a.zip 09000-12.0a.zip 17000-12.0a.zip 25000-12.0a.zip 33000-12.0a.zip 41000-12.0a.zip
02000-12.0a.zip 10000-12.0a.zip 18000-12.0a.zip 26000-12.0a.zip 34000-12.0a.zip 42000-12.0a.zip
03000-12.0a.zip 11000-12.0a.zip 19000-12.0a.zip 27000-12.0a.zip 35000-12.0a.zip 43000-12.0a.zip
04000-12.0a.zip 12000-12.0a.zip 20000-12.0a.zip 28000-12.0a.zip 36000-12.0a.zip 44000-12.0a.zip
05000-12.0a.zip 13000-12.0a.zip 21000-12.0a.zip 29000-12.0a.zip 37000-12.0a.zip 45000-12.0a.zip
06000-12.0a.zip 14000-12.0a.zip 22000-12.0a.zip 30000-12.0a.zip 38000-12.0a.zip 46000-12.0a.zip
07000-12.0a.zip 15000-12.0a.zip 23000-12.0a.zip 31000-12.0a.zip 39000-12.0a.zip 47000-12.0a.zip
08000-12.0a.zip 16000-12.0a.zip 24000-12.0a.zip 32000-12.0a.zip 40000-12.0a.zip
# データ構造
以下で定義されています。
http://nlftp.mlit.go.jp/isj/data.html
# PostgreSQLに突っ込む
PostgreSQLのインストールはこの[あたり](http://blog.scimpr.com/2012/09/01/ubuntu12-04%E3%81%A7postgresql%E3%82%92%E3%82%A4%E3%83%B3%E3%82%B9%E3%83%88%E3%83%BC%E3%83%AB%E3%81%99%E3%82%8B/)を参考に。
格納先のテーブルは以下の形式としています。
(ジオグラフィー型とか知らない!)
>```sql:create文
>create table m_address_gaiku (
> prefectures_nm varchar(4),
> city_nm varchar(10),
> oaza_nm varchar(20),
> block_no varchar(15),
> coordinate_no numeric(3),
> x_coordinate numeric(8, 1),
> y_coordinate numeric(8,1 ),
> latitude varchar(15),
> longitude varchar(15),
> displayed_address_flg char(1),
> representative_flg char(1),
> before_history_flg char(1),
> after_history_flg char(1)
>);
>```
先ほどダウンロードしたZIPファイルを解凍して、格納されているCSVファイルをPostgreSQLに読み込ませます
Copyコマンドを用いるので、ユーザ権限をSuperUserにしておく必要があります。
> [参考情報 - PostgreSQL で COPY が使えない時](http://bmath.org/wordpress/?p=1427)
```sh:処理対象をCSVに抽出
# 解凍
find ./ -name "*.zip" -type f -print0 | xargs -0 -I {} unzip {}
# 対象のCSV一覧を出力
find ./ -name "*.csv" -type f -print0 | xargs -0 -I {} echo `pwd`/{} > list.txt
Copyコマンド実行用のshellを作成。
#!/bin/sh
# copyコマンド作成
cd `dirname $0`
cat list.txt | while read file; do
echo $file
psql gis << EOF
COPY m_address_gaiku (
prefectures_nm,
city_nm,
oaza_nm,
block_no,
coordinate_no,
x_coordinate,
y_coordinate,
latitude,
longitude,
displayed_address_flg,
representative_flg,
before_history_flg,
after_history_flg
)
FROM
'$file'
WITH
(
format csv,
header true,
delimiter ',',
quote '"',
encoding 'Shift-JIS'
);
EOF
done
先ほど作成したcopy.sh
を実行します。
ファイルパスとそれぞれの取り込み件数が表示されます。
# 取り込みshellの実行
% sh copy.sh
# 実行結果
/home/mano/postgis/data/./38000-12.0a/38_2013.csv
COPY 202088
/home/mano/postgis/data/./41000-12.0a/41_2013.csv
COPY 101563
/home/mano/postgis/data/./02000-12.0a/02_2013.csv
COPY 136475
#・・・以下略・・・
動作確認
969万件とか結構な件数になってます。
=# select count(*) from m_address_gaiku;
count
---------
9696619
(1 row)
肝心の中身チェック。
「北海道の旭川四条通20丁目」の緯度経度を調べてみる。
prefectures
やcity
やarea
カラムそれぞれにバインドする必要があります。
=# select prefectures_nm, city_nm, oaza_nm, block_no, latitude, longitude from m_address_gaiku where prefectures_nm= '北海道' and city_nm= '旭川市' and oaza_nm like '四条通二十丁%';
prefectures_nm| city_nm| oaza_nm | block_no | latitude | longitude
-------------+--------+----------------+------------+-----------+------------
北海道 | 旭川市 | 四条通二十丁目 | 1720 | 43.763105 | 142.379743
北海道 | 旭川市 | 四条通二十丁目 | 右5 | 43.763105 | 142.379743
北海道 | 旭川市 | 四条通二十丁目 | 9 | 43.763105 | 142.379743
北海道 | 旭川市 | 四条通二十丁目 | 右10 | 43.763105 | 142.379743
北海道 | 旭川市 | 四条通二十丁目 | 1717 | 43.763671 | 142.380069
北海道 | 旭川市 | 四条通二十丁目 | 4 | 43.763671 | 142.380069
北海道 | 旭川市 | 四条通二十丁目 | 左9 | 43.763671 | 142.380069
北海道 | 旭川市 | 四条通二十丁目 | 左6 | 43.763671 | 142.380069
北海道 | 旭川市 | 四条通二十丁目 | 左5 | 43.763671 | 142.380069
北海道 | 旭川市 | 四条通二十丁目 | 左2 | 43.763671 | 142.380069
北海道 | 旭川市 | 四条通二十丁目 | 左4 | 43.763671 | 142.380069
このクエリ結果をgiocoding結果と比べてみると…
www.geocoding.jp/?q=北海道四条通20丁目
…合ってますね!
まとめ
- 住所の揺れさえ無視できる環境であれば緯度・経度を取得できる!
- 住所から緯度経度を大量件数引き当てたい時を除けば、とても賢いgiocodingかジオコーダAPIを使いたい!