Ruby on RailsでのGPS連携について
GPSで取得した現在地から、Ruby on RailsのDBに登録した複数の地点までの距離をそれぞれ計算し、下記画面のように一覧で表示させるモバイル機能を開発した。

Ruby on RailsとGPS連携の概要は以下のようになっている。
1. Railsのビューの<head></head>にインクルードするjavascriptを記述。
2. インクルードしたapplication.jsにGoogleからライブラリを取得する記述。
3. GoogleAPIにより現在地の取得。
4. Railsのビューの中にGoogleAPIのCallBack関数を記述。
5. CallBack関数で実行されるyorimichiList関数をapplication.jsに記述。
6. 取得した緯度、経度の値をRailsのコントローラーに明記した"yorimichi_sort"アクションにPOSTメソッドで渡す。
7. Railsの"yorimichi_sort"アクションにパラメーターで渡された緯度、経度とデータベースに登録されたスポットの緯度、経度の値を用いて現在地から各スポットまでの直線距離を算出、距離で昇順にソート。
8. ソートされたスポットの距離がjavascriptに返される。
9. Railsのビューの指定したタグに7.のRailsアクションでソートされたスポットの一覧が表示される。
1.Railsのビューの<head></head>内でインクルードするjavascriptを記述。
http://www.google.com/jsapi?key=hogehoge のhogehogeにはGoogleAPIのキーを記述。
(※キーの取得はGoogle Maps APIのページを参照)
<head> <title>GPSDemo</title> <metahttp-equiv="Content-Type" content="text/html;charset=UTF-8" /> <metahttp-equiv="Content-Style-Type" content="text/css" /> <metahttp-equiv="Content-Script-Type" content="text/javascript"/> <meta name="viewport"content="width=device-width, user-scalable=no, initial-scale=1,maximum-scale=1" /> <scripttype="text/javascript" src="http://www.google.com/jsapi?key=hogehoge"></script> <%= stylesheet_link_tag'default', :media => 'screen' %> <%= stylesheet_link_tag 'hvga', :media=> 'only screen and (min-device-width: 320px) and (max-device-width:480px)' %> <%= stylesheet_link_tag 'xga-landscape',:media => "only screen and(min-device-width : 768px) and(max-device-width : 1024px) and (orientation : landscape)" %> <%= stylesheet_link_tag'xga-portrait.css', :media => "only screen and (min-device-width :768px) and (max-device-width : 1024px) and (orientation : portrait)" %> <%#=javascript_include_tag :defaults %> <%=javascript_include_tag 'application' %> <%=javascript_include_tag 'iui' %> <%= csrf_meta_tag %> <%= yield(:javascripts)if content_for?(:javascripts) %> </head>
2. インクルードしたapplication.jsにGoogleからライブラリを取得する記述。
google.load("maps","3",{other_params :'sensor=true'});
google.load("jquery","1.4");
google.load("gdata","2");
3.GoogleAPIにより現在地の取得を行う。
function getClientLocation(stLatitude, stLongitude) {
if(navigator.geolocation){
navigator.geolocation.getCurrentPosition(
function (val){
getLocationCallBack(val.coords.latitude,val.coords.longitude);
gpsInfoDisplay(val.coords.latitude,val.coords.longitude,val.coords.accuracy);
},
function(){
getLocationCallBack(stLatitude, stLongitude);
},
{maximumAge: 0,enableHighAccuracy: true}
)
}else{
getLocationCallBack(stLatitude, stLongitude);
}
}
4.Railsのビューの中にGoogleAPIのCallBack関数を記述。
<% content_for :javascripts do %>
<script type="text/javascript">
$(document).ready(function(){
google.setOnLoadCallback(getClientLocation('<%=@organization.st_latitude %>','<%= @organization.st_longitude %>'));
getLocationCallBack =function(lat, longi){
yorimichiList(lat,longi);
}
})
</script>
<% end %>
5.CallBack関数で実行されるyorimichiList関数をapplication.jsに記述。
取得した緯度、経度の値をRailsのコントローラーに明記した"yorimichi_sort"アクションにPOSTメソッドで渡す。
function yorimichiList(latitude,longitude){
var division_id =document.getElementById("division_id").value;
$.post("yorimichi_sort", {division_id: division_id, lat:latitude, longi: longitude}, function(result){
$("#location").html(result);
})
}
6. 緯度、経度の値を用いて現在地から各スポットまでの直線距離を算出、距離で昇順にソート。
Railsの"yorimichi_sort"アクションにパラメーターで渡された緯度、経度とデータベースに登録されたスポットの緯度、経度の値を用いて現在地から各スポットまでの直線距離を算出、距離で昇順にソート。
def yorimichi_sort
@division =Division.find(params[:division_id])
start_lat = params[:lat].to_f
start_longi = params[:longi].to_f
@start_end = @organization.distance(start_lat,start_longi)
@spot_distance_ary = []
@division.spot_divisions.each do |spot_division|
spot = spot_division.spot
st_mid_distance = spot.distance(start_lat,start_longi)
mid_end_distance = spot.distance(@organization.dest_latitude,@organization.dest_longitude)
yorimichi_total = st_mid_distance + mid_end_distance
@spot_distance_ary<< [yorimichi_total, spot, st_mid_distance,mid_end_distance]
end
@spot_distance_ary.sort_by!{|yorimichi_total,spot, st_mid_distance, mid_end_distance| st_mid_distance}
if @organization.means_route == 'DRIVING'
difflag = '&dirflg=d'
elsif @organization.means_route == 'WALKING'
difflag = '&dirflg=w'
end
@dest_map_url ="http://maps.google.co.jp/maps?saddr=" + start_lat.to_s + ',' +start_longi.to_s + '&daddr=' + @organization.dest_latitude.to_s + ',' +@organization.dest_longitude.to_s + difflag
render :partial => "spot_list", :layout => false
end
defdistance(lat,longi)
dp = (self.latitude - lat).abs
dr = (self.longitude - longi).abs
p= ((self.latitude + lat) / 2)*Math::PI/180
t= (1-0.006674*Math.sin(p)*Math.sin(p))
m= 6334834 / (Math::sqrt(t*t*t))
n= 6377397 / (Math::sqrt(t))
return((Math::sqrt((m*dp*Math::PI/180)*(m*dp*Math::PI/180)+(n*Math.cos(p)*dr*Math::PI/180)*(n*Math.cos(p)*dr*Math::PI/180)))/100).round/10.0
end
7.下記のresultにソートされたスポットの距離が返される。
function yorimichiList(latitude,longitude){
var division_id =document.getElementById("division_id").value;
$.post("yorimichi_sort", {division_id: division_id, lat:latitude, longi: longitude}, function(result){
$("#location").html(result);
})
}
8.スポットの一覧が表示
Railsのビューに以下のように明記したid=locationのタグに4.のRailsアクションでソートされたスポットの一覧が表示される。
<article id="location"> <p> </p> </article>
※上記の内容は、平成22年度「Ruby 人材育成によるビジネス利用拡大業務」で開発したシステムの概要を解説したものです。