Ruby on RailsでのGPS連携について

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

GPS画像

 

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>&nbsp;</p>
</article>

 


※上記の内容は、平成22年度「Ruby 人材育成によるビジネス利用拡大業務」で開発したシステムの概要を解説したものです。