- 2008-01-09 (Wed) 22:40
- Ruby On Rails , googlemap
では最終的に作ったソースをもとに解説していく。
main_controller.rb
require 'net/http'
require 'rexml/document'
require 'cgi'
class MainController < ApplicationController
def index
end
def search
#HTTP通信設定(rgoecode)
site = Net::HTTP.start('refits.cgk.affrc.go.jp')
#地名情報取得 ← 1
response = site.get("/tsrv/jp/rgeocode.php?lon=#{params[:x]}&lat=#{params[:y]}")
resXML = response.body
site.finish
#XML要素から都道府県名と都市名を取得する ← 2
@got, @pref, @munic = get_name_of_place(resXML)
unless @got then # ← 3
@resText = "Error!"
render(:layout => false)
return
end
#HTTP通信設定(郵便番号)
site = Net::HTTP.start('webservice.est.co.jp')
#郵便番号情報取得 ← 4
response = site.post("/zipcode/SearchEngine.asmx/FromAddress2", "Address=" + CGI.escape(@pref + @munic))
@got, @zipcode = get_zipcode(response.body) # ← 5
unless @got then # ← 6
response = site.post("/zipcode/SearchEngine.asmx/FromAddress2", "Address=" + CGI.escape(@pref))
@got, @zipcode = get_zipcode(response.body)
end
site.finish
#HTTP通信設定(旅行記)
site = Net::HTTP.start('api.4travel.jp')
#旅行記情報取得 ← 7
response = site.get("/Ver1/SearchAlbum.php?zip=#{@zipcode}&oc=utf8")
@travel_info = TravelInfo.new response.body # ← 8
site.finish
#郵便番号に-(ハイフンを入れる)
@zipcode.insert(3, "-")
end
def get_name_of_place xml
#XMLツリー作成
docTree = REXML::Document.new xml
#ステータス取得(地名の取得が成功したかどうか)
status = docTree.elements.each("/rgeocode/status"){}[0].text
return false, "取得失敗", "取得失敗" if status != "true"
#都道府県取得
@pref = docTree.elements.each("/rgeocode/prefecture/pname"){}[0].text
#都市名取得
@munic = docTree.elements.each("/rgeocode/municipality/mname"){}[0].text
return true, @pref, @munic
end
def get_zipcode xml
#XMLツリー作成
docTree = REXML::Document.new xml
#ステータス取得(地名の取得が成功したかどうか)
status = docTree.elements.each("/FindList/TotalFindCount"){}[0].text
return false, "" if status == "0"
#郵便番号取得
zipcode = docTree.elements.each("/FindList/Item/FindItem/ZipCode"){}[0].text
return true, zipcode
end
end
メインはsearchメソッド。
これがGoogleMapの地図上をクリックしたときに呼び出されるメソッド。
番号をつけているあたりで以下の処理をしている。
- ジオコードから地名をXML形式で取得
- 取得したXMLから都市名、町名などを取得(get_name_of_placeメソッド呼び出し)
- 取得できなければ終了
- 地名をもとに郵便番号をXML形式で取得
- 取得したXMLから郵便番号を取得(get_zipcodeメソッド呼び出し)
- 取得に失敗したらリトライ(町名は外して県名のみで取得)
- 郵便番号をもとに旅行記をXML形式で取得
- 取得したXMLから旅行記の配列を取得(TravelInfoクラス ※ソースは下)
旅行記のXMLを解析し、Travelogueというクラスのインスタンスにする。
それを旅行記の配列をTravelInfoが保持している。
この2つのクラスはコントローラから呼び出せるようにhelpersの下に配備する。
travel_info.rb
require 'rexml/document'
class Travelogue
attr_accessor :album_title, :album_url, :traveler, :traveler_url, :picture_url, :picture_link, :area, :area_url, :description
def initialize(doc)
@album_title = doc.elements.each("albumtitle"){}[0].text
@album_url = doc.elements.each("albumurl"){}[0].text
@traveler = doc.elements.each("traveler"){}[0].text
@traveler_url = doc.elements.each("travelerurl"){}[0].text
picture_url = doc.elements.each("picture"){}
picture_url = doc.elements.each("pictlist/picturl"){} unless picture_url
@picture_url = picture_url[0].text if picture_url.size > 0
picture_link = doc.elements.each("pictlist/pictlink"){}
@picture_link = picture_link[0].text if picture_link.size > 0
area = doc.elements.each("area"){}
@area = area[0].text if area.size > 0
area_url = doc.elements.each("areaurl"){}
@area_url = area_url[0].text if area_url.size > 0
description = doc.elements.each("description"){}
@description = description[0].text.split(//u)[0..100].join.gsub /\r?\n/, "<br />\r\n" if description.size > 0
end
end
class TravelInfo
attr_accessor :num_of_results, :travelogue_array
def initialize(xml)
#XMLツリー作成
docTree = REXML::Document.new xml
#検索結果件数取得(旅行記の取得が成功したかどうか)
num_of_results = docTree.elements.each("/results/numofresult"){}
if num_of_results.size > 0
@num_of_results = num_of_results[0].text
else
@num_of_results = 0
end
@travelogue_array = []
if @num_of_results != 0 then
docTree.elements.each("/results/travelogue/item"){|travelogue|
@travelogue_array << Travelogue.new(travelogue)
}
end
end
end
さて、これで必要な情報は取得できたわけだが、それを画面上に表示できるようにHTMLに変換してやる必要がある。
これはsearchメソッドと結びつくviews/main/search.rhtmlを作成すれば自動的に呼び出される。
search.rhtml
<div id="search_area">
<div class="search_info">
<h3>検索条件</h3>
<div class="search_parts">
<div class="search_lable">都道府県名</div>
<div class="search_word"><%= @pref %></div>
</div>
<div class="search_parts">
<div class="search_lable">都市名</div>
<div class="search_word"><%= @munic %></div>
</div>
<div class="search_parts">
<%
if @got then
-%>
<div class="search_lable">郵便番号</div>
<div class="search_word"><%= @zipcode %></div>
<% else -%>
<div class="search_lable">郵便番号</div>
<div class="search_word">取得失敗</div>
<% end -%>
</div>
</div>
<div id="search_result">
<%
if @travel_info != nil && @travel_info.num_of_results != 0 then
@travel_info.travelogue_array.each{|t|
-%>
<div class="an_result">
<div class="travel_title">
<a href="<%= t.album_url %>" target="_blank"><%= t.album_title %></a>
<% if t.area %>
(<a href="<%= t.area_url %>" target="_blank"><%= t.area %></a>)
<% end %>
</div>
<div class="travel_description">
<% if t.picture_url %>
<a href="<%= t.album_url %>" target="_blank"><img src="<%= t.picture_url %>" align="left"/></a>
<% end %>
<% if t.description %>
<%= t.description %>
<% end %>
</div>
<div class="traveller">
<a href="<%= t.traveler_url %>" target="_blank"><%= t.traveler %></a>
</div>
<br style="clear: both;" />
</div>
<% } %>
<% else %>
見つかりませんでした.
<% end %>
</div>
</div>
eRubyがわかれば特に難しい事はしていない。
検索情報と、検索結果をHTMLにしているだけだ。
ただし、作る方はこういうデザインに一番時間がかかるんだけどね。
そしてそれっぽく見えるスタイルシートをフリー配布のところからダウンロードしてきて適用。
最終的にこんな感じになりました。
関連するエントリー GoogleMapでマッシュアップの練習 (Rails編) #7
- Newer: [RoR]routes.rbの更新が反映されない
- Older: GoogleMapでマッシュアップの練習(Rails編) #6
トラックバック:No Trackbacks
- トラックバック URL
- http://blog.garden-place.jp/action.php?action=plugin&name=TrackBack&tb_id=58
- Listed below are links to weblogs that reference
- GoogleMapでマッシュアップの練習(Rails編) #7 from Web 酒 肴
このエントリにトラックバックはありません
このトラックバックURLを使ってこの記事にトラックバックを送ることができます。
もしあなたのブログがトラックバック送信に対応していない場合にはこちらのフォームからトラックバックを送信することができます。.