Edited at

Rails + Google map でマップ表示

More than 3 years have passed since last update.


1) Gemのインストール


Gemfileに追加

# Google map

gem 'gmaps4rails' # railsでGoogle mapを使えるようにする
gem 'geocoder' # 地名から緯度経度を引けるようにする


コマンド実行

bundle install



2) 緯度経度カラムをもつモデルを作成

新しくモデルを作成しても良いし, 既存のモデルにカラムを追加してもよい. 以下は後者の例. Spotモデル(観光地を表すモデル)に緯度経度を追加.


コマンド実行

rails generate migration add_columns_to_spots latitude:float longitude:float

bundle exec rake db:migrate


3) 緯度経度を計算し保存

地名を緯度経度に変換してくれるgem geocoderによって, 任意のタイミングで緯度経度を得ることができる. 住所カラムをもつモデルに対しては, 通常, 住所が変更されるたびに緯度経度を更新すべきだ. したがって, modelファイルに以下のようなコールバックを書くのが良い.


model/spot.rbを以下のように更新

class Spot < ActiveRecord::Base

before_save :geocode_full_address

def geocode_full_address
coords = Geocoder.coordinates(
self.prefecture + self.city + self.address # 県名 + 市町村名 + 丁目番地
)
self.latitude = coords[0]
self.longitude = coords[1]
end
end



4) API Keyの取得

https://developers.google.com/maps/documentation/javascript/get-api-key


5) <script>タグ挿入


application.html.erbのhead内に追加

  <script src="//maps.google.com/maps/api/js?key=[*******************]"></script>

<script src="//cdn.rawgit.com/mahnunchik/markerclustererplus/master/dist/markerclusterer.min.js"></script>


6) Underscore.jsの追加

underscore.jsと依存関係にあるらしい. 以下の中身をすべてコピーし, app/assets/javascripts/underscore.jsに貼り付け.

http://underscorejs.org/underscore-min.js


app/assets/javascripts/underscore.jsを新規作成

// 上のリンクを開いて出てくるソースを貼る


その後, underscore、gmaps/googleをapplicaton.jsに追加する.


app/assets/javascripts/application.jsに追加

//= require underscore

//= require gmaps/google


7) Viewを編集

好きなところにマップ用のdivを追加


hogehoge.html.erbの任意の場所に追加

 <div style='width: 100%;'>

<div id="map" style='width: 100%; height: 33vh;'></div>
</div>


hogehoge.html.erbの末尾に追加

<script type="text/javascript">

handler = Gmaps.build('Google');
handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
markers = handler.addMarkers([
{
"lat": <%= @spot.latitude %>,
"lng": <%= @spot.longitude %>,
"picture": {
"width": 32,
"height": 32
},
"infowindow": '<%= @spot.name %>'
}
]);
handler.bounds.extendWith(markers);
handler.fitMapToBounds();
handler.getMap().setZoom(15);
});
</script>

以上!