2009年03月18日
郵便番号マップ作成記 (2) - ジオコーディングで経度緯度を求める
第1回 では郵便番号データをデータベースに格納するところまでを作った。今回は住所から緯度経度を求めていこう。ビジュアライズのための下準備は今回で完了だ。
ジオコーディング API は何を使おう
ジオコーディングとは、住所や名所から緯度経度を求めること。世の中にはいくつかジオコーディングの API が存在するが、今回は Google が提供する ジオコーディング API を選択した。
理由はGoogle が提供するという安心感と、1日あたり1万5千回まで OK と太っ腹なところ。REST で利用できるのも魅力的だった。
いざ実行
スクリプトをがーっと書いてひたすら実行する。
require 'EntrySchema' require 'cgi' require 'open-uri' $URL = "http://maps.google.com/maps/geo?" Code.find_all_by_low("0000").each do |code| # 経度緯度を既に求めていたら次 next unless code.lat.nil? and code.lng.nil? # URL を求める q = code.pref + code.city url = $URL + {"q" => q, "output" => "xml"}.map { |key, value| "#{CGI.escape(key)}=#{CGI.escape(value)}" }.join("&") # 読み取る open(url) do |f| xml = f.read puts xml doc = REXML::Document.new(xml) # coordinates タグの中身を読み取る latlng = REXML::XPath.first(doc.root, '//coordinates').text lng, lat = latlng.split(/,/) code.lng = lng.to_f code.lat = lat.to_f puts "#{q} #{lng} #{lat}" end # 保存 code.save # 3秒スリープしておく sleep(3) end
エラー処理は特にやってないので、例外が起きたらそこで止まる。データ量も多くないので、止まってたらそのときに手作業で対応すればよいだろう。
途中、「岡山市北区」でエラーになった。「Google さん、しっかりしてよー」と調べてみたら…
北区(きたく)は岡山県岡山市が2009年4月1日の政令指定都市移行に伴い設置を決めた4つの行政区のうちの一つ
とのことらしい。
まだ存在してない区ならば、取得できなくても仕方がない…。
岡山市の4つの区については Google Maps で検索して、見つかった適当なデータから緯度経度を直接 INSERT して対応しておいた。
DB の中身を JSON で出力
さて、これで緯度経度のデータが出揃った。JavaScript で扱いやすいように、JSON データとして出力しておく。
これも簡単なスクリプトを書いて実現した。住所に \ が含まれることはないので凝った JSON 化は不要だろう。何も考えず使い捨てな勢いで出力コードを書いておいた。
require 'EntrySchema' json = Code.find_all_by_low("0000").map { |code| %Q|{"lat" : #{code.lat}, "lng" : #{code.lng}, "name" : "#{code.pref}#{code.city}", "code " : "#{code.high}"}| }.join(",\n") puts "[#{json}]"
続く。