Stories/2020-07-06 の元ネタは国土地理院データでしたが、これだと一部抜け漏れが出ていました
例)茨城県だと、桜川市、石岡市、水戸市、茨木町、のデータが掛ける(←それ以外もあるけど・・・)
国土地理院データ以外でどうにかして「とある市区町村に属する町字名を取得」する方法が無いかと探した結果、
API | HeartRails Geo API | 郵便番号/住所/緯度経度データ変換サービス の使い勝手が良さそうなので新たな手順を考えてみました
ざっくり解説
# 関数定義
getCities ()
{
curl -s "http://geoapi.heartrails.com/api/json?method=getCities&prefecture=$1" | jq -r '.response.location[]|.city'
}
# 実行例
export pref=茨城県 # あとあと都道府県名を使うので環境変数に格納しておく
getCities $pref | head -n3
水戸市
日立市
土浦市
# 関数定義
getTowns ()
{
case "$#" in
1)
curl -s "http://geoapi.heartrails.com/api/json?method=getTowns&city=$1" | jq -r '.response.location[]|[.x, .y, .city, .town] | @csv'
;;
2)
curl -s "http://geoapi.heartrails.com/api/json?method=getTowns&city=$1&prefecture=$2" | jq -r '.response.location[]|[.x, .y, .city, .town] | @csv'
;;
esac
}
# 実行例1: 市区町村名のみ指定
getTowns 大宮 | head -n3
"139.626988","35.903223","さいたま市大宮区","下町一丁目"
"139.628315","35.903642","さいたま市大宮区","下町二丁目"
"139.630028","35.904032","さいたま市大宮区","下町三丁目"
# 実行例2: 市区町村名と都道府県名を指定
getTowns 大宮 $pref | head -n3
"140.427461","36.541261","常陸大宮市","宇留野"
"140.408893","36.563089","常陸大宮市","姥賀町"
"140.418712","36.542245","常陸大宮市","栄町"
export pref=茨城県; for c in $(getCities $pref); do getTowns $c $pref; done | tee $pref-ichiran-plain.csv
# 前述の手順で作成したファイルを入力
cat $pref-ichiran-plain.csv | \
# ダブルクォーテーションを削除
tr -d \" | \
# awkでいい感じに編集
awk -F, -v OFS=, '
{
# 町域レベル住所を加工するために変数に格納
# ただし /(その他)/ にマッチした場合は市区町村レベルの住所を利用する
if($NF~/(その他)/) a=$(NF-1); else a=$NF
# 「最後の一文字」に相応しくない文字を消す
# 例:山本町南五丁目町 -> 「本」より後ろを削除
# 例:豊田町 -> 「田」より後ろを削除
# 例:中村 -> 「中」より後ろを削除
# 例:中村南一丁目 -> 「村」より後ろを削除/いかんともしがたい
sub(/(町?[東西南北]?[〇一二三四五六七八九十百]+丁目|[市区町村])$/, "", a)
# 緯度、経度、町域レベル住所、最後の一文字 を出力
print $0,substr(a,length(a))
}' >$pref-ichiran.csv # 結果をファイルにリダイレクト