Edited at

住所(市区町村番地)から緯度経度を取得する

More than 3 years have passed since last update.

関連して以下も参考にしてください




やりたい事

GoogleのGeocodingであったりYahoo!のジオコーダAPIを用いれば、住所の表記ゆれにも対応したよりスマートな緯度経度取得が可能ですが、利用数の制限や規約があるのが不便です。

もっと何度でも繰り返し自由に使える環境が欲しい!ということで本記事の内容となります。

「市区町村番地から緯度経度」ではなく、「緯度経度から市区町村番地」を取得する格好いいやり方は、masuidrive様の素晴らしく参考になる記事を参考下さい。


国土交通省のデータを使って、緯度経度から市区町村までを取り出す - Qiita



サマリ


  1. データ取得

  2. PostgreSQLに突っ込む

  3. 動作確認


データ取得

位置参照情報ダウンロードサービスについてからデータ取得

国土交通省が出してくれているデータです。

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のインストールはこのあたりを参考に。

格納先のテーブルは以下の形式としています。

(ジオグラフィー型とか知らない!)



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 が使えない時



処理対象を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を作成。


copy.sh

#!/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丁目」の緯度経度を調べてみる。

prefecturescityareaカラムそれぞれにバインドする必要があります。


緯度経度結果

=# 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を使いたい!