RailsでGoogle Mapsを扱うときのライブラリを公開しました
ウェブサービス作っていてGoogle Mapsを使うことって凄く多い。
個人的に旅とか海外とかのサービスが多いだけなのかもしれないけど。
coffee scriptのファイルをプロジェクト毎に作っていたけど、結局同じコードなのでGithubに公開しておきました。
レポジトリはこちら
shunwitter/map_helper
デモはこちら(定期的に消えるので地図登録してOKです)
https://shunwitter-test-app.herokuapp.com/places
実際のプロジェクトではこんな感じ
http://www.canpath.jp/ (ページ最下部のマップとか)
できることは、
- 1. 緯度経度を受け取ってマップ表示
- 2. 住所を入力してボタンを押したら、マップ表示&緯度経度セット
- 3. マップ表示 + たくさんのマーカー表示
以下 Github とほぼ同じですが日本語で。
jQueryが必要です。
読み込み
vendorフォルダに置いたファイルを読み込む。
ここに置きました。
vendor/javascripts/map_helper/maphelper.coffee
/app/assets/javascripts/application.js
1
//= require map_helper/map_helper
Railsアプリ
この例では、Place model があると想定します。
scaffoldでつくるとこんな感じですね。
1
rails g scaffold place name:string address:stiring latitude:float longitude:float
RailsのTurbolinksを使っている場合はこんな感じでGoogle maps apiを読み込むかと思います。
triggerMapでこのライブラリを使うコードを書いていきます。
/app/assets/javascripts/places.js.coffee
coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
ready = ->
if !window.google
script = document.createElement('script')
script.type = 'text/javascript';
script.src = 'https://maps.googleapis.com/maps/api/js?v=3.exp&' +
'language=ja&callback=triggerMap'
document.body.appendChild(script)
else
triggerMap()
window.triggerMap = ->
# your code
# For turbolinks
$(document).ready(ready)
$(document).on 'page:load', ready
1. マップを表示する
マップを表示するdiv要素に data-latitude
と data-longitude
を設定してください。
View
app/views/places/show.html.erb
erb
1
2
3
4
5
6
<div class="map-show-canvas"
data-latitude="<%= @place.latitude %>"
data-longitude="<%= @place.longitude %>">
</div>
Javascript
MapHelper.showMap(canvas, options)
/app/assets/javascripts/places.js.coffee
coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
window.triggerMap = ->
# --- show --- #
mapCanvas = $('.map-show-canvas')
if mapCanvas.length && mapCanvas.attr('data-latitude')
MapHelper.showMap(mapCanvas.get(0),
{
mapHeight: 300,
mapLat: mapCanvas.attr('data-latitude'),
mapLng: mapCanvas.attr('data-longitude'),
zoom: 10
#scaleControl: ,
#scrollwheel: ,
#showMarker: ,
#draggable: ,
}
)
Options
Name | Type | Default |
---|---|---|
mapHeight | integer | 300 |
mapLat | float | 35.6894875 #Tokyo |
mapLng | float | 139.6917064 #Tokyo |
zoom | integer | 4 |
scaleControl | boolean | true |
scrollwheel | boolean | false |
showMarker | boolean | true |
draggable | boolean | false |
afterShow | function | null |
2. 検索ボタンをしたらマップ表示
DEMOです。
検索ボタンがされたら、
住所から位置を特定してマップを表示 & 緯度経度フィールドに値をセットする。
addressInput
で指定された要素を全部合わせた住所で検索するので複数になってもOKです。
例えば、
| address | state | postcode |
みたいになっていれば、それぞれに同じクラス名をつけることで
address + state + postcode みたいな文字列を Google maps api に投げます。
View
app/views/places/new.html.erb
erb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
<%= form_for(@place) do |f| %>
<div class="field">
<%= f.label :name %><br>
<%= f.text_field :name %>
</div>
<div class="field">
<%= f.label :address %><br>
<%= f.text_field :address, class: "address" %>
<%= link_to "SEARCH", "#", class: "map-search-button" %>
<div class="map-canvas" style="height: 0;"
data-lat="<%= f.object.latitude %>"
data-lng="<%= f.object.longitude %>">
</div>
<%= f.text_field :latitude, readonly: true %>
<%= f.text_field :longitude,readonly: true %>
</div>
<% end %>
Javascript
MapHelper.searchShowMap(canvas, options)
coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
window.triggerMap = ->
# --- new/edit --- #
if $('.map-search-button').length
MapHelper.searchShowMap($('.map-canvas').get(0),
{
mapHeight: 300,
trigger: $('.map-search-button'),
addressInput: $('.address'), #could be multiple
latInput: $('#place_latitude'),
lngInput: $('#place_longitude'),
zoom: 10
#scaleControl: ,
#scrollwheel: ,
#showMarker: ,
#draggable: ,
afterShow: ->
console.log "Map is displayed."
}
)
Options
Name | Type | Default |
---|---|---|
mapHeight | integer | 300 |
trigger | jQuery object | $('.search-map-trigger') |
addressInput | jQuery object | $('.search-map-address') |
latInput | jQuery object | $('input.latitude') |
lngInput | jQuery object | $('input.longitude') |
zoom | integer | 4 |
scaleControl | boolean | true |
scrollwheel | boolean | false |
showMarker | boolean | true |
draggable | boolean | false |
afterShow | function | null |
3. マップ表示とたくさんマーカー表示
マーカーを地図上に沢山表示する時に便利です。
jsonを受け取りますので、コントローラー側の設定もしてください。
Controller
/app/controllers/places_controller.rb
ruby
1
2
3
4
5
6
7
8
9
def index
@places = Place.all
respond_to do |f|
f.html
f.json { render json: @places }
end
end
View
app/views/places/index.html.erb
erb
1
2
3
<div class="map-index"></div>
Javascript
MapHelper.showMapWithMarkers(canvas, options, json)
coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
window.triggerMap = ->
# --- index --- #
if $('.map-index').length
$.ajax(
type: 'GET',
url: '/places.json',
# data: { if you need }
).done( (data) ->
if data.length
MapHelper.showMapWithMarkers($('.map-index').get(0),
{
mapHeight: 400,
mapLat: data[0].latitude, #center
mapLng: data[0].longitude, #center
zoom: 2,
showMarker: false,
draggable: false,
controller: 'places',
titleField: 'name'
}, data)
)
Options
controller
and titleField
は表示されたマーカーをクリックした時にでるウインドウのために使用されます。
Placeモデルにnameというフィールドがあったら titleField: 'name'
としてください。
タイトルには /controller/:id みたいなリンクが貼られます。
ウインドウとはコチラのことです。
Name | Type | Default |
---|---|---|
mapHeight | integer | 300 |
mapLat | float | 35.6894875 #Tokyo |
mapLng | float | 139.6917064 #Tokyo |
zoom | integer | 4 |
scaleControl | boolean | true |
scrollwheel | boolean | false |
showMarker | boolean | true |
draggable | boolean | false |
afterShow | function | null |
controller | string | "posts" |
titleField | string | "title" |
いろいろ変えたい
ホントは Gem化してみたりしたかったけど、
やり方を覚えるのに時間かかりそうなので後日。
また、Javascriptファイルでもなく、Coffee script のままという何とも乱暴な感じです。
jQuery なんて必要ないじゃないかとか色々突っ込みどころはありますが、
ひとまず公開してしまいました。