アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

座標から地名を取得する逆GeocodingAPIのまとめ + サンプル

こんちは。松田です。
トレイン・トレインで使用しているGoogleMapをいじっている時に座標(緯度・経度)から地名を取得する必要が出てきたので、その際に調べた逆Geocoding機能を実装したAPIをまとめてみました。

GoogleMapsAPIなど地図を使ったシステムを使用していると、住所から緯度経度などの情報を取得する方法が必要になります。これはGeocodingと呼ばれる技術で、GoogleMapsAPIではすでに公式なAPIが存在しています。
これとは逆に、ユーザーに登録させたスポットの地名を自動入力させたりする場合など、座標から地名情報を取得したい場合があります。これらは「逆Geocoding」や、「Reverse Geocoding」などと呼ばれていますが、現在のところGoogleMapsのAPIは提供されていません。
この逆Geocoding機能が使えるサービスをいくつか紹介します。

・YahooローカルサーチAPI
http://developer.yahoo.co.jp/map/localsearch/V1/localsearch.html
言わずと知れたYahooのAPI
24時間中1IPアドレスにつき50000件のリクエストまでの制限あり。
本来は座標やキーワードからYahooの持つ周辺情報の検索を行うAPIだが、地名のみに絞って検索することで対応可能。
事前にアプリケーションIDの取得が必要。
取得できる地名は「都道府県・市区町村・番地が連結された文字列」のみ。
そのため、「都道府県名」「町名」を個別に取得する場合は独自の変換が必要。
日本測地系」「世界測地系」の指定が可能。
指定座標からの範囲を指定し、複数の候補地点を取得することができる。
出力はXML形式、JSON形式が選択可。

・ReFITS Lab 逆ジオコーディングサービス
http://refits.cgk.affrc.go.jp/tsrv/jp/rgeocode.html
出力はJSONP形式、phpでserialize化された文字列形式。
PHPスクリプトに組み込みやすい。
1日あたり10万アクセスまで許可。これを超えそうならば事前に要相談。
つい最近バージョン3が公開されたばかりで、YahooローカルサーチAPIのように複数の候補を取得できるようになった。
都道府県名」「市区町村名」などに加えて、「都道府県コード」「市区町村コード」「町丁目」「番地」なども個別に取得可能。
さらに、「候補地点(代表点位置)の座標」や「検索座標から候補地点座標までの距離」も取得できる。
これを使用したサービスを公開する場合は、以下の文章と同じ趣旨の内容をユーザーに通知しなければならない。


「当該サービス提供者は、当該サービスを無保証で提供しており、当該サービスが原因で発生した損害等について、補償等は一切おこないません。」

また、番地情報まで使用・表示させる場合、以下の趣旨の文章を通知しなければならない。


「番地情報は、実態と異なる場合があり、またプライバシーにも関わることがありますので、特に慎重に扱って下さい。」


・invGeocoder
http://www.knya.net/archives/2005/07/rest.html
利用制限無し。
都道府県名」「市町村名」「町名」「番地」と、「候補地点の座標」「候補地点までの距離」を取得できる。
出力はXML形式。
使いやすいが、作者の言っているようにそのうちサービスが止まるかもしれないのがちょっぴり不安。

・Knecht(クネヒト) 逆ジオコーディングAPI
http://api.knecht.jp/reverse_geocoding/
一日当たりの利用制限等については言及無し。
都道府県名」「市町村名」「町名」の取得が可能。
出力はXML形式、JSON形式が選択可。
今回紹介する中では一番シンプル。

ちず丸 「ここの住所は?」機能
http://www.chizumaru.com/czm/currentadr.aspx?x=502779.393&y=128135.353
ちず丸が提供するAPI?それともただの出力結果画面?
どちらにしろ座標から地名を出せるということで一応ピックアップ。
この機能に関する説明ページを見つけられなかったので、これをシステムに組み込んでいいのかどうかは不明。
これはどこから辿り付けるページなのか誰か教えてください・・・。
座標から郵便番号と地名は取得できるが、HTMLページで返されるので、もし使うのであればパース処理を実装しなければならない。
パラメータのx,yの値の算出方法はこちらのページ参照。
http://q.hatena.ne.jp/1203488398


・海外モノ
http://www.geonames.org/export/reverse-geocoding.html とか、
http://groups.google.co.jp/group/Google-Maps-API/web/resources-non-google-geocoders?pli=1 の下のほうとか。
日本の地名取得は無理なのが大半っぽいのでほとんど調べてない。
「reverse geocoding」でググるといっぱいでる!

※各APIの詳細な利用規約はご自分でお確かめください。



せっかくなので、APIを調べているときに作ったサンプルを公開します。
YahooのローカルサーチAPIを使って座標から地名を取り出しています。

まず必要になるのはYahooAPI用のアプリケーションID。
これは以下のページから事前に取得しておきます。
http://e.developer.yahoo.co.jp/webservices/register_application

パラメータのp(検索キーワード)の欄には必須と書いてありますが、lat、lon、distを指定する場合は省略可能のようです。
また、パラメータのnの値で結果取得件数を指定することができますが、今回はnを1にして表示された地名をそのまま座標の地名として使用しています。
取得した地名の並び順が指定座標に近い順かどうかは不明なので、この方法で最適な地名が取れているかどうかは若干怪しいです。

GoogleMapsは日本地図も世界測地系なので(確か)、「datum=wgs」を指定しています。


APIを使用して実際に地名を取得するPHPスクリプト
・getplacename.php


<?php

// POSTされてきた緯度・経度を取得
$lat = isset($_POST['lat']) ? $_POST['lat'] : null;
$lng = isset($_POST['lng']) ? $_POST['lng'] : null;
if (!$lat || !$lng || !is_numeric($lat) || !is_numeric($lng)) {
  exit;
}

// APIを使用するURLを生成
$url = 'http://map.yahooapis.jp/LocalSearchService/V1/LocalSearch?'
	. 'appid=(アプリケーションID)'
	. ' &lat='.urlencode($lat)
	. ' &lon='.urlencode($lng)
	. ' &dist=3' // 上記指定座標からの検索範囲(km)
	. ' &category=address' // 地名のみ検索
	. ' &n=1' // 検索結果は1つだけ取得
	. ' &datum=wgs' // 世界測地系を使う
	. ' &al=3'; // 丁目、字レベルまで取得

// 結果を取得
$contents = file_get_contents($url);

// 住所部分を取得してecho
$xml = simplexml_load_string($contents);
$address = (string)$xml->Item->Address;
echo $address;
exit;
?>

下で表示しているGoogleMapからAjaxで呼び出しています。


ソース表示
ピンをドラッグした先の座標をgetplacename.phpに送り、その座標をYahooローカルサーチAPIに渡し、取得した地名をInfoWindowに表示しています。