Posted at

Rubyを使って住所から緯度経度を求めてみよう!

More than 5 years have passed since last update.


はじめに

今考えているアプリで住所から緯度経度を求める必要があり、ちょうど 再就職のために Rubyの勉強をしているので試してみました。

geocodingをするなら Google Maps API を直ぐに思い付きましたが、下記の様な制限があり、利用制限が比較的緩い Yahoo!ジオコーダAPI を使ってみます。

Google Geocoding API - 利用制限


Google Geocoding API 使用時のクエリ制限として、1 日あたりの位置情報リクエストが 2,500 回に制限されています(Google Maps API for Business をご利用の場合は、1 日あたり 100,000 件までリクエストを実行できます)。


ちなみにジオコーディングとは


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



準備



  1. Yahoo!ジオコーダAPI を使う場合に Yahoo! JAPAN ID が必要なため持っていない人はここで作成して下さい。


  2. Yahoo!ジオコーダAPI を使う場合は、事前に アプリケーションID を発行する必要があります。 アプリケーションID の発行についてはここを参照して下さい。


APIの概要

1.住所から緯度経度を求める Yahoo!ジオコーダAPI についてはここを参照して下さい

2.緯度経度から住所を求める Yahoo!リバースジオコーダAPI についてはここを参照して下さい


さてコーディング

Google Maps API との比較もしてみましょう。


geocoder_test.rb

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 の紹介でした。