#はじめに
過去に自分のポートフォリオでGoogleMapsAPIを利用していましたが、流れを忘れていたのでリマインドです。
#環境
rails 5.2.3
ruby 2.6.3
#今回すること
・現在地情報から経度緯度を取得しマーカーを表示する。
・取得した一覧情報をjson形式に変え、マーカーとして地図上に配置。
・地図の表示
###表示させるコントローラー作成、今回アクション名はsearchで。
spaces_controller.rb
def search
@spaces = Space.all
end
###モデルの作成、住所を入力後緯度経度を自動取得させる。
space.rb
class Space < ApplicationRecord
geocoded_by :address
after_validation :geocode, if: :address_changed?
end
schema.rb
create_table "spaces", force: :cascade do |t|
t.string "address"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.float "latitude"
t.float "longitude"
end
###MAPを表示させるscript
javascript
function initMap()
//マップを表示させる箇所
var target = document.getElementById('gmap');
//マップ表示
var map = new google.maps.Map(document.getElementById('gmap'), {
center: {lat: 35.681167, lng: 139.767052},//中心点設定
zoom: 8//mapの拡大率設定
});
//現在地マーカーの作成
//現在地取得できない場合
if(!navigator.geolocation){
infoWindow.setPosition(map.getCenter());
infoWindow.setContent('Geolocation に対応していません。');
infoWindow.open(map);
}
navigator.geolocation.getCurrentPosition(function(position) {
//現在地の軽度緯度取得
var pos = { lat: position.coords.latitude, lng: position.coords.longitude };
var mark = new google.maps.Marker({
//ドロップダウンアニメーションの設定
animation: google.maps.Animation.DROP,
position: pos,
map: map,
// 現在地ピンのアイコン作成。今回デフォルトのデザインは複数のマーカーに使用するので変更。
icon: {
fillColor: "rgb(48, 255, 176)",
fillOpacity: 1.0,
path: google.maps.SymbolPath.BACKWARD_CLOSED_ARROW,
scale: 4,
strokeColor: "green",
strokeWeight: 1.0
}
});
}, function() {
infoWindow.setPosition(map.getCenter());
infoWindow.setContent('Error: Geolocation が無効です。');
infoWindow.open(map);
});
//複数マーカー
//一覧のデータをjson形式に
var spaces = #{raw @spaces.to_json};
var marker = [];
var info;
for(var i = 0; i < spaces.length; ++i) {
//一覧から一つずつ経度緯度の情報を取り出してマーカー作成
spot = new google.maps.LatLng({lat: spaces[i].latitude, lng: spaces[i].longitude});
marker[i] = new google.maps.Marker({
position: spot,
map: map,
animation: google.maps.Animation.DROP
});
markerEvent(i);
}
//複数マーカーのhover時イベント
function markerEvent(i) {
marker[i].addListener('mouseover', function() {
var target = $('#' + (i + 1));
$(".highlight").removeClass("highlight");
target.addClass("highlight");
var position = target.offset().top - 280;
$('body,html').animate({scrollTop:position}, 400, 'swing');
});
}
//-------------------------------------------------------------
}
script src="https://maps.googleapis.com/maps/api/js?key=#{ENV[""]}&callback=initMap" async defer
今回はテンプレートエンジンをslimにしてその中に直接書いているのでデータの変数格納のあたりが通常と違っているので注意。
gemのgeocoderを使用すると名前から経度と緯度を取得するのが非常に楽ですが、精度が悪く、番地単位まで表示してくれないので今回はGoogle Geocodingを使用しています。