[*Rails*] 指定座標のGoogleMapを表示させたい


はじめに

Railsで指定した座標のGoogleMapを表示させようとして、詰まったのでやり方メモ。

設定手順

プロジェクト作成してGemfileに以下2行追加。

Gemfile
(省略)...
# Google map
gem 'gmaps4rails'
48 gem 'geocoder'

gemのインストール。

$ bundle install

Google Mapに表示するようのデータ用にCicadaモデルを作ります。

$ rails g model Cicada title:string description:string address:string latitude:float longitude:float
$ rake db:migrate

中に以下2行を追加。

app/models/cicada.rb
class Cicada < ActiveRecord::Base
    geocoded_by :address
    after_validation :geocode
end

マップ表示用のコントローラーとビューを作ります。

$ rails g controller map index

ビューの中に以下を。

app/views/map/index.html.erb
<script src="//maps.google.com/maps/api/js?v=3.13&amp;sensor=false&amp;libraries=geometry" type="text/javascript"></script>
<script src='//google-maps-utility-library-v3.googlecode.com/svn/tags/markerclustererplus/2.0.14/src/markerclusterer_packed.js' type='text/javascript'></script>

<div style='width: 800px;'>
  <div id="map" style='width: 800px; height: 400px;'></div>
</div>

<script type="text/javascript">
    handler = Gmaps.build('Google');
    handler.buildMap({ provider: {}, internal: {id: 'map'}}, function(){
      markers = handler.addMarkers(<%=raw @hash.to_json %>);
      handler.bounds.extendWith(markers);
      handler.fitMapToBounds();
    });
</script>

以下ファイルの下の方に//= require underscore//= require gmaps/googleを追加。

app/assets/javascripts/application.js
(省略)...
//= require jquery
//= require jquery_ujs
//= require turbolinks
//= require underscore
//= require gmaps/google
//= require_tree .

コントローラーの中は以下。

app/controllers/map_controller.rb
class MapController < ApplicationController
  def index
        @cicadas = Cicada.all
        @hash = Gmaps4rails.build_markers(@cicadas) do |cicada, marker|
            marker.lat cicada.latitude
            marker.lng cicada.longitude
            marker.infowindow cicada.description
            marker.json({ title: cicada.title })
        end
  end
end

さっき作ったビューをroot_urlに指定。

config/routes.rb
Rails.application.routes.draw do
  root 'map#index'
  (省略)...
end

以下のファイルを作ってunderscore/underscore.jsunderscore/underscore-min.jsの中身を貼り付ける。
Underscore.jsはjavascriptの関数や配列など、オブジェクトを扱う際に頻繁に発生する処理がまとめられていて、そういうのを簡単に扱えるようにする便利なライブラリらしいです。
Githubからダウンロードしてみると、underscore.jsは52KB、underscore-min.jpは16KBだったので、何が違うのかまでは調べてませんが軽いに越したことは無いのでunderscore-min.jpを使いました。

vendor/assets/javascripts/underscore.js
  //(underscore.jsまたはunderscore-min.jsの中身を貼り付ける。)

データを入れます。

$ rails c
irb(main):001:0> Cicada.create(title: "abura", address: "kobe station")
=> #<Cicada id: 13, title: "abura", description: nil, address: "kobe station", latitude: 34.679526, longitude: 135.178021, created_at: "2015-02-22 05:11:26", updated_at: "2015-02-22 05:11:26">

latitudelongitudeaddressに指定したものから検索か何かして勝手に入ってるみたいですね。
指定した座標でなんで入らないんだろうと思って調べるのに時間がかかりました。
下のように座標適当に設定しても実際に入るのは全く違う値になってます。
最初の方にやってgeocoded_byに指定してるものがキーになってるんですね。よく分からず指定してました。

irb(main):001:0> Cicada.create(title: "abura", address: "tokyo station", latitude:10, longitude:140)
=> #<Cicada id: 15, title: "abura", description: nil, address: "tokyo station", latitude: 35.681382, longitude: 139.766084, created_at: "2015-02-22 05:14:58", updated_at: "2015-02-22 05:14:58">

以下のように変更したら、

app/models/cicada.rb
class Cicada < ActiveRecord::Base
    reverse_geocoded_by :latitude, :longitude
    after_validation :geocode
end

この通り、座標が指定した値で入ります。
地図に表示されるのも、tokyo stationではなく、座標に合致したところが出ます。

irb(main):001:0> Cicada.create(title: "abura", address: "tokyo station", latitude:36.091521, longitude:139.372694)
=> #<Cicada id: 17, title: "abura", description: nil, address: "tokyo station", latitude: 36.091521, longitude: 139.372694, created_at: "2015-02-22 05:23:54", updated_at: "2015-02-22 05:23:54">

表示されるマップ。

最後に

座標のところをなんで表示してくれないんだろうというところで大分詰まりました。
埼玉県の森林公園を表示させたいのに何故か千葉県のよくわからない場所が表示されて???ってなりました。
詰まったおかげで参考サイトさんを参考に意味はよく分からず指定している部分が何なのか分かってよかったです。

参考サイト