Home > googlemap
Web 酒 肴
GoogleMapでマッシュアップの練習(Rails編) #7
- 2008-01-09 (Wed)
- 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編) #6
- 2008-01-06 (Sun)
- Ruby On Rails , googlemap
エマージェンシー発生
フォートラベルのAPIを再確認してみたところ、地名からの旅行記取得の仕様が期待していたものと違う。「北海道」とかいうパラメータで旅行記が取得できると思っていたけど、それは無理。「hokkaido」というアルファベット形式で送信しなくてはならない。漢字の地名をいちいちアルファベットに変換なんて面倒だしやりたくない。ということで別の方法を考えなくては。こういう見切り発車な性格は災いもおおいけど、勢いがなくては何も始められない。と肯定的に捉えてみる。
調査を続けるとフォートラベルでは残された方法は一つしかなかった。それは郵便番号による検索。
ということで住所から郵便番号を取得する処理を一つ追加する。APIはぽすたんというサービスを見つけた。さっそく組み込んでみる。
処理内容はこういうふうになる。
[修正前]
- GoogleMAP上をクリック
- 住所取得(京都市など)
- 旅行記取得(これができない)
[修正後]
- GoogleMAP上をクリック
- 住所取得(京都市など)
- 郵便番号取得(605xxxxなど)
- 旅行記取得
上記処理を実装するのに、あれやこれやと結構時間を食ってしまって。
その経緯をブログに残すのを忘れてた・・・。
突然だけど、急転直下で次回完成!!!
(テキトーですみません)
GoogleMapでマッシュアップの練習(Rails編) #5
- 2007-12-31 (Mon)
- Ruby On Rails , googlemap
4travelにパラメータとして地名を送信するには、返されたXMLの中から地名だけを取りだす必要がある。難しいことはしないけどRubyでXMLをいじった経験はなし。きっとそういうライブラリがあるはず、と思って探すとREXMLというものを発見。日本語情報が少なくここを参考になんとかやってみた。
どうもREXMLの日本語情報が少ないようで、これ以上調べるのも時間がかかりそうな気がしたので、見よう見まねでかなり強引に作ってみた。きっともっとスマートな方法があるはず。main_controller.rbにget_name_of_placeというメソッドを追加し、そこにXMLのデータを渡すと都道府県名と都市名を別々にようにした。取得失敗時は取得失敗という文字を返す。
main_controller.rb
require 'net/http'
require 'rexml/document'
class MainController < ApplicationController
def index
end
def search
#HTTP通信設定
site = Net::HTTP.start('refits.cgk.affrc.go.jp')
#地名情報取得
response = site.get("/tsrv/jp/rgeocode.php?lon=#{params[:x]}&lat=#{params[:y]}")
resXML = response.body
site.finish
#XML要素から都道府県名と都市名を取得する
pref, munic = get_name_of_place(resXML)
#画面表示用のテキスト整形
@resText = "都道府県名:#{pref} 都市名:#{munic}"
render(:layout => false)
end
def get_name_of_place xml
#XMLツリー作成
docTree = REXML::Document.new xml
#ステータス取得(地名の取得が成功したかどうか)
status = docTree.elements.each("/rgeocode/status"){}[0].text
return "取得失敗", "取得失敗" if status != "true"
#都道府県取得
pref = docTree.elements.each("/rgeocode/prefecture/pname"){}[0].text
#都市名取得
munic = docTree.elements.each("/rgeocode/municipality/mname"){}[0].text
return pref, munic
end
end
今回もサーバサイドのみの変更なのでそのまま地図をクリック。よし、成功!僕の住んでる近辺を狙って何度かクリックするものの、なかなか難しい。よし、面白くなってきたぞ。

GoogleMapでマッシュアップの練習(Rails編) #4
- 2007-11-03 (Sat)
- Ruby On Rails , googlemap
今度はダミーの文字ではなくて実際にデータを取得しましょう。4travelの旅行記取得APIの仕様を調べたところ、緯度と経度から取得はできないようです。残念。終了。。。。。。。
というわけにもいかないので、何とか実現可能な方法を模索します。地名から旅行記は取得できるようですので地名を取得する方法を考えましょう。Google検索でこんな素晴らしい質問がヒットしました。僕も人力検索使おうかな。
人力検索はてな 緯度経度からだいだいの地名(○県○市くらいの精度で十分です)を得る方法を教えてください。
ここの回答No9の方が紹介されているサイトがこちら(URLは変更されてた。)
これで方針決定。以下のような2段階処理をすることにしよう。
- 緯度、経度から地名(都道府県、都市名)を取得
- その地名で旅行記を取得
まずは1つ目、地名を取得する処理をサーバ側で実装。これはmain_controller.rbのsearchメソッドを修正。ブラウザから送信されたx, yのパラメータを逆ジオコーディングのlon, latパラメータに代入してリクエスト送信でOK。とりあえず返ってきた文字列をそのまま表示するため@resXMLに全文字列を代入。
main_controller.rb
require 'net/http'
class MainController < ApplicationController
def index
end
def search
#HTTP通信設定
site = Net::HTTP.start('refits.cgk.affrc.go.jp')
#地名情報取得
response = site.get("/tsrv/jp/rgeocode.php?lon=#{params[:x]}&lat=#{params[:y]}")
@resXML = response.body #とりあえず全結果文字列を表示させる
site.finish
render(:layout => false)
end
def getNameOfPlace
#XML要素から都道府県名と都市名を取得する
end
end
resXMLを返信するためにviewを変更
app/views/main/search.rhtml
<%= @resXML %>
今度の修正はサーバ上のみなのでブラウザの再読み込みは必要なし。そのまま先ほどと同じように地図上をクリック。マジで動いた・・・・。すげぇ。

GoogleMapでマッシュアップの練習(Rails編) #3
- 2007-11-03 (Sat)
- Ruby On Rails , googlemap
クリックしたら場所をサーバに送信して旅行情報を取得・表示を行う。まずはサーバと通信するところだけを作ってみよう。どこぞのGoogleMapのサンプルで以下のようなコードを拾ってきた。ほぼそのまま使っている。
サーバとの通信部分
function xmlRpc(point){
var req = GXmlHttp.create();
req.open("GET", "main/search?x=" + point.x + "&y=" + point.y, true);
req.onreadystatechange = function(){
if(req.readyState == 4){
//dummy
alert(req.responseXML);
}
}
req.setRequestHeader("Content-Type", "text/html; charset=UTF-8");
req.send(null);
}
これをトップページに組み込んでクリック時のリスナ関数から呼び出すようにする。
GEvent.addListener(map, 'click', function(overlay, point) {
if (point) {
alert("x = " + point.x + ", y = " + point.y);
xmlRpc(point);
}
});
全体としてこうなった。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Mapテスト</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAABWYMASZTPMzQMXu2alSa6xTvcRCYKSpWpPqDL-sNMuxVdHFI_BTd8zF9kdpV97QhhvGd0NWsQckXsw"
type="text/javascript"></script>
</head>
<body>
<div id="map" style="width: 500px; height: 500px"></div>
<script type="text/javascript">
//<![CDATA[
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(38, 138), 5);
map.disableDragging();
}
GEvent.addListener(map, 'click', function(overlay, point) {
if (point) {
alert("x = " + point.x + ", y = " + point.y);
//map.openInfoWindow(point,
//document.createTextNode("openInfoWindow Test"));
xmlRpc(point);
}
});
function xmlRpc(point){
var req = GXmlHttp.create();
req.open("GET", "main/search?x=" + point.x + "&y=" + point.y, true); //app/controllers/main_controller.rb のsearchメソッドが呼び出される(パラメータはxが経度、yが緯度)
req.onreadystatechange = function(){
if(req.readyState == 4){
//dummy
alert(req.responseXML); (←とりあえず結果を表示させるだけ)
}
}
req.setRequestHeader("Content-Type", "text/html; charset=UTF-8");
req.send(null);
}
//]]>
</script>
</body>
</html>
次はサーバ側の処理。app/controllers/main_controller.rbにsearchメソッドを追加。
class MainController < ApplicationController
def index
end
def search
render(:layout => false)
end
end
レイアウトは使用してないけど、画面表示をさせないということから念の為に無効化しています。次にviewを作成。app/views/main/search.rhtmlを以下のように作成します。
dummyString!!
で、ページを再読み込みして地図上をクリック。 緯度、経度が表示された後、「dummyString!!」が表示されれば・・・・
されない・・・
nullが表示されます。なぜだ?と調査開始。サーバのログを見るとsearchメソッドは正常に呼び出されてHTTPレスポンスコードも200。つまりサーバに問題はない。それならクライアント側ってことで、JavaScript部分を見直していると気になったのはこの部分。
alert(req.responseXML);
メソッド名から察するに結果XMLを取得しているわけだが、今回は結果は単なる文字列であってXMLではない。そう思って調査していると以下のページを見つけた。予想は正しくreq.responseTextじゃないというメソッドもあるようだ。
XMLHttpRequest入門【メソッド等の確認とシンプルなコード】
修正後、ページを再読み込みして画面クリックすると、見ごとに「dummyString!!」が表示された。今回はここまで。
- TrackBack: No Trackbacks
GoogleMapでマッシュアップの練習(Rails編) #2
- 2007-10-19 (Fri)
- Ruby On Rails , googlemap
環境
- Windows上でVMwareにFedoraCore4 + Ruby On Rails(Rubyともにバージョンは現在2007/09/17の最新←テキトーだな)
- Puttyで接続してvimで開発
- Googleでキー取得のときに申請したホスト名は本番環境用なので、暫定的にHostsファイルをいじってローカルのFedoraのIPを割り当てる。
Rails でアプリ作成(アプリ名:map)
[obanetty@fedora ~]$rails map
トップページ用のmainコントローラとindexページ作成
[obanetty@fedora ~]$script/generate controller main index
トップページであるapp/views/main/index.rhtmlにGoogleMapを設置
もう、このサイトの言う通りにやったらすぐにできました。 素晴らしいです。
Geekなぺーじ - Google MAPS APIプログラミング
app/views/main/index.rhtmlの内容
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8"/>
<title>Google Mapテスト</title>
<script src="http://maps.google.com/maps?file=api&v=2&key=ABQIAAAABWYMASZTPMzQMXu2alSa6xTvcRCYKSpWpPqDL-sNMuxVdHFI_BTd8zF9kdpV97QhhvGd0NWsQckXsw"
type="text/javascript"></script>
</head>
<body>
<div id="map" style="width: 500px; height: 500px"></div>
<script type="text/javascript">
//<![CDATA[
if (GBrowserIsCompatible()) {
var map = new GMap2(document.getElementById("map"));
map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());
map.setCenter(new GLatLng(38, 138), 5);
map.disableDragging();
}
GEvent.addListener(map, 'click', function(overlay, point) {
if (point) {
alert("x = " + point.x + ", y = " + point.y);
map.openInfoWindow(point,
document.createTextNode("openInfoWindow Test"));
}
});
//]]>
</script>
</body>
</html>
設定内容は以下(日本列島だけを表示するようにした) + 初期化位置を指定する + コントロールボタンを表示する + 地図をドラッグで移動できないようにする + クリック処理
クリックしたポイントの緯度と経度をalert表示させる処理も入れておいた。alertのスペルを忘れてて2、3度苦戦。
サーバ起動
[obanetty@fedora map]$ script/server -p 80
80番ポートで起動しないと申請した内容と変わるため。んで80番ポートを使用するには管理者権限が必要だった。
以降はサーバ起動したままで別のPutty窓からアプリを編集。この方がサーバの再起動が必要ないから楽。これはRailのWebrickサーバがデフォルト指定ではdevelopmentモードで起動し、サーバの再起動なしに動的にアプリケーションを読み込んでくれるから。
- TrackBack: No Trackbacks
GoogleMapでマッシュアップの練習(Rails編) #1
- 2007-09-17 (Mon)
- googlemap , Ruby On Rails
マッシュアップをしてみたい。とりあえずGoogleMapでやってみたい。Ruby On Railsも使ってみたい。でもどっちもあんまりやったことない。備忘録程度にその軌跡を残しておこう。
使うもの
- RubyOnRails
- GoogleMap
- 4travel.jp 旅行記検索API
地図上の場所をクリックしたら、その近辺の旅行記が表示されるものでも作ってみる。多分、そんなのすでにどこかにあるだろう。それはわかってる。何事も最初は模倣から。ありきたりなものを作って基礎体力を作る。これが大事なのだと思う今日この頃。
必要な知識
- JavaScript(Ajax)
- GoogleMap
- Ruby On Rails
- WEB API
- Linuxサーバ
僕のスペック
- Java歴・・・5年
- JavaScript(Ajax)・・・入門
- GoogleMap・・・初めて
- Ruby ( On Rails )・・・ だらだらと1年
- WEB API・・・初めて
上記の知識をある程度前提として、自分が知らなかった部分を中心にメモしているので、このブログを見て同じことをしてもらおうというつもりでは書いていません。部分的にでも誰かの役に立てば、というつもりで書いています。
まとめ記事としてはまた別の場所に書くつもり。では、次回より構築します
Home > googlemap