LoginSignup
104
112

More than 5 years have passed since last update.

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

Last updated at Posted at 2015-06-18

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

やりたい事

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

もっと何度でも繰り返し自由に使える環境が欲しい!ということで本記事の内容となります。
「市区町村番地から緯度経度」ではなく、「緯度経度から市区町村番地」を取得する格好いいやり方は、masuidrive様の素晴らしく参考になる記事を参考下さい。

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

サマリ

  1. データ取得
  2. PostgreSQLに突っ込む
  3. 動作確認

データ取得

位置参照情報ダウンロードサービスについてからデータ取得
国土交通省が出してくれているデータです。
2014年ころから町丁目レベルのデータを提供してくれているそうです。

位置参照サービス.png

「位置参照情報ダウンロードサービスへ」のリンクをクリック
 →「都道府県選択」のリンクをクリック
  →「全ての都道府県を選択」
   →「街区レベル」を選択してそれぞれポチポチ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.png

…合ってますね!

まとめ

  • 住所の揺れさえ無視できる環境であれば緯度・経度を取得できる!
  • 住所から緯度経度を大量件数引き当てたい時を除けば、とても賢いgiocodingかジオコーダAPIを使いたい!
104
112
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
104
112