郵便番号で緯度経度(joinコマンドでデータを連結)

6-2.並び替え


(銀の匙のEDオトノナルホウヘを歌ってるGoose houseです)

TVアニメ『銀の匙 Silver Spoon』(2013,2014)。
食べられるって幸せですね。

食べるためには食べ物を作らなければなりませんが、一から作ることの大変さと素晴らしさの理解へ一歩近づきます。本当の意味での素晴らしさや大変なのってやっぱり体験しないと分からないことが多いと思います。

私は若い時に農家で作ったお米をお餅にする仕事をしてましたが、ものすごく大変でした。
朝は早い。まあ、朝が早いぐらいは当たり前として、熱い餅を触るから火傷が絶えず、常時蒸しているので熱中症になるわ等、労働条件が過酷なので体力精神力がすべてでした。ん! 大変さしか思い出せません。

郵便番号で経度緯度を表示するコマンド(bash関数)を、銀の匙の舞台である北海道の住所データを元に作ってみます。まずは、北海道のの郵便番号データをwgetします。

~$ wget http://www.post.japanpost.jp/zipcode/dl/kogaki/zip/01hokkai.zip
~$

取得したら、UTF8に変換して分かりやすいファイル名を付けておきます。

~$ unzip 01hokkai.zip 
Archive:  01hokkai.zip
  inflating: 01HOKKAI.CSV            
~$ nkf -w8 < 01HOKKAI.CSV > zipdata-utf8.txt
~$ 

次に位置情報ダウンロードサービスで北海道の位置情報をダウンロードします。
http://nlftp.mlit.go.jp/isj/index.html

site-location-service
01000-13.0a.zipというファイルがダウンロードされました。

~$ unzip 01000-13.0a.zip 
Archive:  01000-13.0a.zip
   creating: 01000-13.0a/
  inflating: 01000-13.0a/01_2014.csv  
  inflating: 01000-13.0a/format_2014.html  
  inflating: 01000-13.0a/md_01_2014.xml  
~$ nkf -w < 01000-13.0a/01_2014.csv > locdata-utf8.txt

郵便番号データと位置情報データ。それぞれデータフォーマットを確認してみましょう。

~$ head -2 *utf8.txt
==> locdata-utf8.txt <==
"都道府県名","市区町村名","大字・町丁目名","街区符号・地番","座標系番号","X座標","Y座標","緯度","経度","住居表示フラグ","代表フラグ","更新前履歴フラグ","更新後履歴フラグ"
"北海道","札幌市中央区","旭ケ丘五丁目","5","12","-106529.3","-75681.1","43.037301","141.321212","1","1","0","0"

==> zipdata-utf8.txt <==
01101,"060  ","0600000","ホッカイドウ","サッポロシチュウオウク","イカニケイサイガナイバアイ","北海道","札幌市中央区","以下に掲載がない場合",0,0,0,0,0,0
01101,"064  ","0640941","ホッカイドウ","サッポロシチュウオウク","アサヒガオカ","北海道","札幌市中央区","旭ケ丘",0,0,1,0,0,0
~$ 

zipcode-locdate

郵便番号が1丁目〜19丁目で、まとまっているところを見ると、

郵便番号 ⊂ 住所
(郵便番号は、住所の部分集合)

となりますが、今回は簡単にするため住所を間引いたデータを使います。awkでzipデータを整理してみましょう。

~$ cut -d, -f3,7-9 zipdata-utf8.txt | sed 's/"//g;s/(.*$//' |
 awk -F, '{printf "%s%s%s\t%s\n",$2,$3,$4,$1}' |
 sort > zipdata-easy.txt
~$ 

住所を一列目としたタブ区切りの郵便番号データができました。住所以外の注意事項とかも書かれていますが、そのまま使っています。

~$ head zipdata-easy.txt 
北海道阿寒郡鶴居村アトコシヤラカ	0851146
北海道阿寒郡鶴居村以下に掲載がない場合	0851200
北海道阿寒郡鶴居村温根内	0851145
北海道阿寒郡鶴居村下久著呂	0851262
北海道阿寒郡鶴居村下雪裡	0851211
北海道阿寒郡鶴居村下幌呂	0851144
北海道阿寒郡鶴居村支雪裡	0851212
北海道阿寒郡鶴居村支幌呂	0851133
北海道阿寒郡鶴居村上幌呂	0851132
北海道阿寒郡鶴居村新幌呂	0851131
~$ 

次は位置情報を簡単にしたデータを作成します。(ソートには時間がかかります。あしからず)

~$ cut -d, -f1-3,8,9 locdata-utf8.txt | sed 's/"//g' |
 awk -F, '{printf "%s%s%s\t%s\t%s\n",$1,$2,$3,$4,$5}' |
 sort > locdata-easy.txt

今回の要、joinコマンドを使います。joinのデフォルト動作では、一列目データ、つまり住所を共通IDにして各フィールドを結合します。

~$ join locdata-easy.txt zipdata-easy.txt > ziploc-verbose.txt
~$ wc -l ziploc.txt
70363 ziploc.txt
~$ sed -n "${RANDOM}p" ziploc-verbose.txt
北海道枝幸郡枝幸町梅ケ枝町 44.939435 142.584845 0985806
~$ 

スペース区切りで、
住所、経度、緯度、郵便番号
の順序です。

上記コマンドラインでのwc -lの結果は70363行あり、大変多いですが、簡略化したデータであるために同一郵便番号含まれたデータとなっています。
冗長なので、最初に出てくる郵便番号だけを残して他を削除したいと思います。

~$ cat ziploc-verbose.txt | awk '{if(pre != $4){pre=$4;print $0}}' > ziploc.txt
~$ wc -l ziploc.txt
5055 ziploc.txt
~$ 

これで少し軽いデータとなりました。

最後に、郵便番号で経度緯度を検索するbash関数を作ってみましょう。尚、データを簡略化していますので、正確さには欠けます。

~$ z(){
 grep "$1$" ziploc.txt}
~$ z 0985806
北海道枝幸郡枝幸町梅ケ枝町 44.934340 142.577503 0985806
~$ 

コメント

タイトルとURLをコピーしました