位置情報から住所に変換する方法

2020-03-01

位置情報から住所を取得する

Opendata 等で位置情報を扱っていると位置情報と住所で困ることとして、片方しかデータが入っていない場合があります。

他にも、車での移動を位置情報で取得している場合等も考えられます。

今回は住所が存在せず位置情報しかない場合の方法を紹介します。

Geocoding (ジオコーディング)

Wikipediaの ジオコーディング にはこう書かれています。

ジオコーディング(英語: geocoding)は、各種情報に対して、関連する地理座標(典型的には緯度・経度)を付加すること、およびこれに関する技術やソフトウェアをいう。付加された地理座標のことをジオコードと称する。

非常に分かりづらいですが、一例には住所と緯度経度を対応させる技術が上げられます。 実際位置情報関係の API では住所から緯度経度への変換を行う事を Geocoding と言い、その逆を Reverse Geocoding という場合が多いです。

実際 YOLP を見てみると、このように説明されています

  • Yahoo!ジオコーダAPI には 住所を指定して、その位置情報(緯度、経度)を出力します
  • Yahoo!リバースジオコーダAPI には Yahoo!リバースジオコーダAPI(以下、リバースジオコーダAPI)は、緯度・経度で指定された場所の住所検索結果を返します

今回は各種 Reverse Geocoding API を紹介します

YOLP

先程あげたように Yahoo では YOLP(Yahoo! Open Local Platform) という形で地図全般に関わる API を公開しています(登録が必要)。

今回は東京駅を例にします。東京駅の位置情報は 35.681111, 139.766667 で、住所は 東京都千代田区丸の内一丁目 です。データは Wikipediaの東京駅 から取得しています API の利用ですので curl で十分でしょう。

YOLPの利用の為にはユーザ登録を行い appid を先に取得しておく必要があります。

$ curl https://map.yahooapis.jp/geoapi/V1/reverseGeoCoder -G -d "lat=35.681111" -G -d "lon=139.766667" -G -d "output=json" -G -d "recursive=true" -G -d "appid=xxxxxxxxxxxxxxxxxxxx"
{"ResultInfo":{"Count":1,"Total":1,"Start":1,"Latency":0.005102872848510742,"Status":200,"Description":"\u6307\u5b9a\u306e\u5730\u70b9\u306e\u4f4f\u6240\u60c5\u5831\u3092\u53d6\u5f97\u3059\u308b\u6a5f\u80fd\u3092\u63d0\u4f9b\u3057\u307e\u3059\u3002","Copyright":"Copyright (C) 2020 Yahoo Japan Corporation. All Rights Reserved.","CompressType":""},"Feature":[{"Property":{"Country":{"Code":"JP","Name":"\u65e5\u672c"},"Address":"\u6771\u4eac\u90fd\u5343\u4ee3\u7530\u533a\u4e38\u306e\u5185\uff11\u4e01\u76ee\uff19","AddressElement":[{"Name":"\u6771\u4eac\u90fd","Kana":"\u3068\u3046\u304d\u3087\u3046\u3068","Level":"prefecture","Code":"13"},{"Name":"\u5343\u4ee3\u7530\u533a","Kana":"\u3061\u3088\u3060\u304f","Level":"city","Code":"13101"},{"Name":"\u4e38\u306e\u5185","Kana":"\u307e\u308b\u306e\u3046\u3061","Level":"oaza"},{"Name":"\uff11\u4e01\u76ee","Kana":"\uff11\u3061\u3087\u3046\u3081","Level":"aza"},{"Name":"\uff19","Kana":"\uff19","Level":"detail1"}],"Building":[{"Id":"B@lH6-pWaiO","Name":"","Floor":"2","Area":""}]},"Geometry":{"Type":"point","Coordinates":"139.766667,35.681111"}}]}

# 文字列がencodeされていて見づらいので変換します
{"ResultInfo"=>{"Count"=>1, "Total"=>1, "Start"=>1, "Latency"=>0.0029969215393066406, "Status"=>200, "Description"=>"指定の地点の住所情報を取得する機能を提供します。", "Copyright"=>"Copyright (C) 2020 Yahoo Japan Corporation. All Rights Reserved.", "CompressType"=>""}, "Feature"=>[{"Property"=>{"Country"=>{"Code"=>"JP", "Name"=>"日本"}, "Address"=>"東京都千代田区丸の内1丁目9", "AddressElement"=>[{"Name"=>"東京都", "Kana"=>"とうきょうと", "Level"=>"prefecture", "Code"=>"13"}, {"Name"=>"千代田区", "Kana"=>"ちよだく", "Level"=>"city", "Code"=>"13101"}, {"Name"=>"丸の内", "Kana"=>"まるのうち", "Level"=>"oaza"}, {"Name"=>"1丁目", "Kana"=>"1ちょうめ", "Level"=>"aza"}, {"Name"=>"9", "Kana"=>"9", "Level"=>"detail1"}], "Building"=>[{"Id"=>"B@lH6-pWaiO", "Name"=>"", "Floor"=>"2", "Area"=>""}]}, "Geometry"=>{"Type"=>"point", "Coordinates"=>"139.766667,35.681111"}}]}

YOLPは、住所全体の文字列("Address") と住所を Level(Prefecture, City) 等で個別に値を返してくれるのが便利です。

OSM(Open Street Map)

Open Street Map は誰でも自由に利用が出来、編集も可能な世界地図を作る市民参加型の共同作業プロジェクトです。 Wikipediaの地図版と言えば分かりやすいでしょう。

OSM には様々な機能がありますが、その1つにNominatim という逆ジオコーディングの機能があります。

$ curl https://nominatim.openstreetmap.org/reverse -G -d "lat=35.681111" -G -d "lon=139.766667" -G -d "format=json"
{"place_id":46234350,"licence":"Data © OpenStreetMap contributors, ODbL 1.0. https://osm.org/copyright","osm_type":"node","osm_id":3589537651,"lat":"35.6812103","lon":"139.766771","display_name":"東京, 丸の内中央広場, 丸の内1, 丸の内, 千代田区, 東京都, 100-0005, 日本 (Japan)","address":{"address29":"東京","pedestrian":"丸の内中央広場","suburb":"丸の内1","city_district":"丸の内","city":"千代田区","state":"東京都","postcode":"100-0005","country":"日本 (Japan)","country_code":"jp"},"boundingbox":["35.6811103","35.6813103","139.766671","139.766871"]}

YOLP よりは情報が多少少なめではありますが情報としては十分です。 YOLP とは異なりアプリケーションIDが必要ないので利用開始がしやすいでしょう。

使いすぎるとサーバへの負荷問題もあるので開発側である程度の制御を行うのが良いでしょう。 大量のリクエストを送る場合にはメールアドレスを指定するようにという指示もありますので従うのが良いでしょう

農研機構

農研機構で簡易逆ジオコーディングサービス が公開されています。

$ curl https://aginfo.cgk.affrc.go.jp/ws/rgeocode.php -G -d "lat=35.681111" -G -d "lon=139.766667" -G -d "json"           
{"status":200,"result":{"prefecture":{"pcode":13,"pname":"\u6771\u4eac\u90fd"},"municipality":{"mname":"\u5343\u4ee3\u7530\u533a","mcode":13101},"local":[{"section":"\u4e38\u306e\u5185\u4e00\u4e01\u76ee","homenumber":"9","distance":53.694620647599,"latitude":35.681252,"longitude":139.767235}]},"argument":{"latitude":35.681111,"longitude":139.766667,"localradius":500,"localmax":1},"meta":[{"name":"thanks","content":"\u3053\u306e\u30b5\u30fc\u30d3\u30b9\u306f \u56fd\u571f\u4ea4\u901a\u7701 \u63d0\u4f9b \u56fd\u571f\u6570\u5024\u60c5\u5831(\u884c\u653f\u533a\u57df) \u3092\u5229\u7528\u3057\u3066\u3044\u307e\u3059"},{"name":"thanks","content":"\u3053\u306e\u30b5\u30fc\u30d3\u30b9\u306f \u56fd\u571f\u4ea4\u901a\u7701 \u63d0\u4f9b \u8857\u533a\u30ec\u30d9\u30eb\u4f4d\u7f6e\u53c2\u7167\u60c5\u5831\u304a\u3088\u3073\u5927\u5b57\u30fb\u753a\u4e01\u76ee\u30ec\u30d9\u30eb\u4f4d\u7f6e\u53c2\u7167\u60c5\u5831 \u3092\u5229\u7528\u3057\u3066\u3044\u307e\u3059"}]}

# 文字列がencodeされていて見づらいので変換します
{"status"=>200, "result"=>{"prefecture"=>{"pcode"=>13, "pname"=>"東京都"}, "municipality"=>{"mname"=>"千代田区", "mcode"=>13101}, "local"=>[{"section"=>"丸の内一丁目", "homenumber"=>"9", "distance"=>53.694620647599, "latitude"=>35.681252, "longitude"=>139.767235}]}, "argument"=>{"latitude"=>35.681111, "longitude"=>139.766667, "localradius"=>500, "localmax"=>1}, "meta"=>[{"name"=>"thanks", "content"=>"このサービスは 国土交通省 提供 国土数値情報(行政
区域) を利用しています"}, {"name"=>"thanks", "content"=>"このサービスは 国土交通省 提供 街区レベル位置参照情報および大字・町丁目レベル位置参照情報 を利
用しています"}]}

他 API と異なる点は距離(distance) がある事でしょう。 これは説明にある通り国土交通省のデータを利用しているため、公開されている一番近い位置を取得するという仕様の為かと思われます。

アクセス数に気をつけつつ利用すれば、通常の範囲であれば問題は無いかと思われます。

国土地理院API

国土地理院もAPIを公開しています。

実行してみるとなんとも素っ気ないデータが返ってきます。

$ curl https://mreversegeocoder.gsi.go.jp/reverse-geocoder/LonLatToAddress -G -d "lat=35.681111" -G -d "lon=139.766667"   
{"results":{"muniCd":"13101","lv01Nm":"丸の内一丁目"}}

調べてみると muniCdmuni.js のデータとのことですが、データを見る限り市区町村コードでしょう。 全国地方公共団体コード で公開されていますので都道府県、市区町村を取得したい場合はこちらを自前でデータベース化するのが良いでしょう。

特筆すべきは CORS許可 が与えられているという点です。 これにより安心してサービス構築が可能となっています。

少し処理が増えるという点で利用の優先順位は下がるかもしれませんが、国土地理院の公式な API ですので信頼性は高いでしょう。

まとめ

無料の範囲で利用できるサービスを4つ紹介しましたが、いかがでしたでしょうか?

より精度が高いサービスが必要な場合は有料サービスを検討するのが良いでしょう。 例えば Google Geocoding API , Bing Maps API が代表的なサービスでしょう。

次回は住所から位置情報を取得するGeocoding APIについて紹介します