LoginSignup
28
32

More than 5 years have passed since last update.

Rails4で位置情報を扱う実装サンプルまとめ

Last updated at Posted at 2016-06-02

私が開発しているアプリで位置情報をつかった技術を実装したので共有します。

概念・基本

位置情報を扱う際の基本的な語句や概念を整理しておきます。

Geolocation API

  • ユーザーの位置情報を扱うためのAPI
  • HTML5からJavaScriptで位置情報を取得できるように標準化されている
  • getCurrentPosition() …… ユーザーの現在の位置情報を一回だけ取得する
  • watchPosition() …… ユーザーの位置情報を定期的に監視する
  • clearWatch() …… watchPosition()による位置情報の監視をクリアする
  • 参考

ジオコーディング

  • 広義には, 各種情報に対して、関連する地理座標(典型的には緯度・経度)を付加すること(wikipedia)
  • 狭義には, 狭義には地名、住所が示す場所に対して、地理座標を与えることを言う(wikkipedia)
  • 例としてはGoogle Maps API や geocoder gem

実装

やりたかったこと

  • データベースに登録した位置情報をgooglemapで表示したい
  • 現在位置を監視して、特定の住所に近づいたら画面に通知をだす
  • データベースに格納された位置情報を現在位置に近い順に表示する

やりたいことを実現するために必要な実装

  • フロント側で現在位置を取得する
  • データベースに位置情報を格納する
  • mapへサーバの位置情報を表示する
  • フロント側で2つの位置間の距離を計算する
  • サーバ側で距離を2つの位置間の計算する

フロント側で現在位置を取得する

get_current_pos.coffee
    successCallback = (position) ->
      # 位置情報が渡っってくるので、ajaxでおくるなど、距離計算につかうなどすえ

    errorCallback = (errors) ->
        # エラー処理

    navigator.geolocation.getCurrentPosition(successCallback,errorCallback)

データベースに位置情報を格納する

参考:Rails4でGoogleMapを表示させる

GemFile
gem 'geocoder'
gem "gmaps4rails"
space.rb
class Space < ActiveRecord::Base
  geocoded_by :address
  after_validation :geocode
end
class CreateSpaces < ActiveRecord::Migration
  def change
    create_table :spaces do |t|
      t.string :address
      t.decimal :latitude, precision: 9, scale: 6
      t.decimal :longitude, precision: 10, scale: 6
    end
  end
end

Googlemapへサーバの位置情報を表示する

参考:Rails4でGoogleMapを表示させる

application.html.slim
    script[src="//maps.googleapis.com/maps/api/js?key=あなたのキー&libraries=geometry" type="text/javascript"]
application.js
// マーカークラスターの読み込み
// download here! 
// https://github.com/googlemaps/js-marker-clusterer
//= reqire markerclusterer_compiled 

spaces_controller.rb
  def show
    # マーカークラスターに渡す情報を生成する
    @hash = Gmaps4rails.build_markers([@space]) do |space, marker|
      marker.lat space.latitude.to_f
      marker.lng space.longitude.to_f
      marker.infowindow space.name
      marker.json(title: space.name)
    end

    @joined_users = @space.joined_users
  end
spaces/show.html.slim
          .map_container
            #map.space_map
            javascript:

              var latlng = new google.maps.LatLng( parseFloat(#{@hash[0][:lat]}), parseFloat(#{@hash[0][:lng]}) );
              handler = Gmaps.build('Google');
              handler.buildMap(
                {provider: {}, internal: {id: 'map'}},
                function(){
                  markers = handler.addMarkers(#{raw  @hash.to_json});
                  handler.bounds.extendWith(markers);
                  handler.fitMapToBounds();
                  handler.getMap().setCenter(latlng);
                  handler.getMap().setZoom(15);
                }
              );

スクリーンショット 2016-05-26 12.11.30 PM.jpg (86.2 kB)

フロント側で2つの位置間の距離を計算する

gmap_util.coffee
  calc_distance = (from_pos, to_pos) ->

    from = new google.maps.LatLng( parseFloat(from_pos[0]), parseFloat(from_pos[1]) )
    to = new google.maps.LatLng( parseFloat(to_pos[0]), parseFloat(to_pos[1]) )

    google.maps.geometry.spherical.computeDistanceBetween(from, to)

サーバ側で距離を2つの位置間の計算する

config/initializer/geocoder.rb
Geocoder.configure(units: :km)
spacr.rb
  def distance(pos)
    Geocoder::Calculations.distance_between([pos[0], pos[1]], [latitude, longitude]) * 1000.0
  end
# gemの際とみたらいろいろ便利メソッドあった
# if obj.geocoded?
#  obj.nearbys(30)                      # other objects within 30 miles
# obj.distance_from([40.714,-100.234]) # distance from arbitrary point to object
#  obj.bearing_to("Paris, France")      # direction from object to arbitrary point
end

gem geocoder

参考

Rails4でGoogleMapを表示させる
Geolocation API

28
32
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
28
32