はじめに
今考えているアプリで住所から緯度経度を求める必要があり、ちょうど 再就職のために Rubyの勉強をしているので試してみました。
geocodingをするなら Google Maps API を直ぐに思い付きましたが、下記の様な制限があり、利用制限が比較的緩い Yahoo!ジオコーダAPI を使ってみます。
Google Geocoding API 使用時のクエリ制限として、1 日あたりの位置情報リクエストが 2,500 回に制限されています(Google Maps API for Business をご利用の場合は、1 日あたり 100,000 件までリクエストを実行できます)。
ちなみにジオコーディングとは
ジオコーディング(英語: geocoding)は、各種情報に対して、関連する地理座標(典型的には緯度・経度)を付加すること、およびこれに関する技術やソフトウェアをいう。付加された地理座標のことをジオコードと称する。
準備
- Yahoo!ジオコーダAPI を使う場合に Yahoo! JAPAN ID が必要なため持っていない人はここで作成して下さい。
- Yahoo!ジオコーダAPI を使う場合は、事前に アプリケーションID を発行する必要があります。 アプリケーションID の発行についてはここを参照して下さい。
APIの概要
1.住所から緯度経度を求める Yahoo!ジオコーダAPI についてはここを参照して下さい
2.緯度経度から住所を求める Yahoo!リバースジオコーダAPI についてはここを参照して下さい
さてコーディング
Google Maps API との比較もしてみましょう。
require 'net/http'
require 'json'
BASE_URL_GOOGLE_MAP = "http://maps.google.com/maps/api/geocode/json"
BASE_URL_YOLP_GEOCODER = "http://geo.search.olp.yahooapis.jp/OpenLocalPlatform/V1/geoCoder"
BASE_URL_YOLP_REVERSE_GEOCODER = "http://reverse.search.olp.yahooapis.jp/OpenLocalPlatform/V1/reverseGeoCoder"
APP_ID_YAHOO = "取得したアプリケーションIDを記述する"
# Google Map API
def geocode_google_map(address)
puts "Geocode by Google Map API"
address = URI.encode(address)
hash = Hash.new
reqUrl = "#{BASE_URL_GOOGLE_MAP}?address=#{address}&sensor=false&language=ja"
response = Net::HTTP.get_response(URI.parse(reqUrl))
# レスポンスコードのチェック
# 詳細は http://magazine.rubyist.net/?0013-BundledLibraries
case response
# 200 OK
when Net::HTTPSuccess then
data = JSON.parse(response.body)
hash['lat'] = data['results'][0]['geometry']['location']['lat']
hash['lng'] = data['results'][0]['geometry']['location']['lng']
# それ以外
else
hash['lat'] = 0.00
hash['lng'] = 0.00
end
return hash
end
# Yahoo!ジオコーダAPI
def geocode_yolp(address)
puts "Geocode by Yahoo!ジオコーダAPI"
address = URI.encode(address)
hash = Hash.new
# 出力形式にJSONを指定する
reqUrl = "#{BASE_URL_YOLP_GEOCODER}?appid=#{APP_ID_YAHOO}&query=#{address}&output=json"
response = Net::HTTP.get_response(URI.parse(reqUrl))
# レスポンスコードのチェック
# 詳細は http://magazine.rubyist.net/?0013-BundledLibraries
case response
# 200 OK
when Net::HTTPSuccess then
data = JSON.parse(response.body)
#p status # for DEBUG
# YOLPでの座標情報は緯度経度に分かれていない(カンマ区切りの)ため分解する
coordinates = data['Feature'][0]['Geometry']['Coordinates'].split(/,\s?/)
hash['lat'] = coordinates[1].to_f # 緯度
hash['lng'] = coordinates[0].to_f # 経度
# それ以外
else
hash['lat'] = 0.00
hash['lng'] = 0.00
end
return hash
end
# Yahoo!リバースジオコーダAPI
def reverse_geocode_yolp(coordinates)
puts "Reverse Geocode by Yahoo!リバースジオコーダAPI"
lat = coordinates['lat'].to_s
lng = coordinates['lng'].to_s
# 出力形式にJSONを指定する
reqUrl = "#{BASE_URL_YOLP_REVERSE_GEOCODER}?appid=#{APP_ID_YAHOO}&lat=#{lat}&lon=#{lng}&output=json"
#p reqUrl # for DEBUG
response = Net::HTTP.get_response(URI.parse(reqUrl))
# レスポンスコードのチェック
# 詳細は http://magazine.rubyist.net/?0013-BundledLibraries
case response
# 200 OK
when Net::HTTPSuccess then
data = JSON.parse(response.body)
#p status # for DEBUG
address = data['Feature'][0]['Property']['Address']
# それ以外
else
address = "住所が取得出来ません"
end
end
puts "========================================================="
p geocode_google_map("東京都港区芝公園4‐2‐8")
puts "========================================================="
coordinates = geocode_yolp("東京都港区芝公園4‐2‐8")
p coordinates
p reverse_geocode_yolp(coordinates)
puts "========================================================="
実行結果
$ ruby geocoder_test.rb
=========================================================
Geocode by Google Map API
{"lat"=>35.6587039, "lng"=>139.7454081}
=========================================================
Geocode by Yahoo!ジオコーダAPI
{"lat"=>35.65870316, "lng"=>139.74540779}
Reverse Geocode by Yahoo!リバースジオコーダAPI
"東京都港区芝公園4丁目2-8"
=========================================================
$
まとめ
「Yahoo! Open Local Platform」の ジオコーダAPI と リバースジオコーダAPI の紹介でした。