はじめに
こんにちは。kosukein38です。
最近仕事でGoogle map API(Maps JavaScript API
)を使っていました。
後学も兼ねて、マーカー(ピン📍)を色々カスタマイズして遊んでみました🥳
自分は"ピン"を立てるとかってよくいうのですが、公式に習って、本記事では"マーカー"と呼ぶことにします。
徐々にステップアップする感じで書いてみたので、良かったら参考にしていただけたら幸いです。
この記事の対象者
- Google map API(
Maps JavaScript API
)を初めて触る方 - RailsアプリにGoogle mapを組み込んで、あれこれ情報を表示したい方
内容(この記事でやること、やらないこと)
やること
- Google map API(
Maps JavaScript API
)をRailsに導入する - 地図を描画する
- 地図にマーカーを立てる
- マーカーの見た目を変える
- マーカーに吹き出しをつける + マーカークリックで吹き出しを表示する
- 【ちょっと応用】複数のマーカーを設置、その属性値で吹き出しやHTMLを書き換える
やらないこと
- Rails側の設定やAPIの設定の詳細
- 詳しい設定方法は書いていません、Googleの公式ドキュメントや、またasset周り設定方法は公式ドキュメント、Railsガイドを参照してください。
本題
Google map API(Maps JavaScript API
)をRailsに導入する
まずは以下の公式ドキュメントを参照ください。
以下の公式ドキュメントを参考にしてください
Maps JavaScript API を読み込む | Google for Developers
以下の 3 つの方法で読み込むことができます。
- Dynamic Library Import を使用する(推奨)
- NPM js-api-loader パッケージを使用する
- 以前のスクリプト読み込みタグを使用する
ちょっと古い方法のようですが、今回は3つめのスクリプト読み込みタグを利用します。
以下のタグをGoogle Mapを読み込ませたいビューに配置します。
<script async
src="https://maps.googleapis.com/maps/api/js?key=YOUR_API_KEY&callback=initMap">
</script>
APIキーは秘匿情報に当たるので、.env
やCredentials
で管理してください。
自分はRails4.2を使って(古いのは承知の上ですw)テストしましたので、以下のようなビューを作りました。
<div class="mt10" id='custom-map'></div>
<div id='text'>
<h1>テスト文字列</h1>
</div>
<%= javascript_include_tag 'test' %>
<%= javascript_include_tag "https://maps.googleapis.com/maps/api/js?key=#{ENV['API_KEY']}&libraries=places&callback=initMap" %>
ビューを表示できるように、適当にコントローラーとルーティングを設定します。(詳細は省略)
今回はtest.js
ファイルにJavaScriptを書いて、操作していきます。
地図を描画する
Maps JavaScript API を読み込む | Google for Developers
initMap()関数でGoogleMapを描画します。
let map;
function initMap() {
map = new google.maps.Map(document.getElementById("custom-map"), {
center: { lat: 35.658581, lng: 139.745433 },
zoom: 12,
});
}
window.initMap = initMap;
結果はこんな感じです。簡単に地図が表示できますね。(For development purposes onlyは気にせず...w)
地図にマーカーを立てる
マーカー | Maps JavaScript API | Google for Developers
実際にマーカーを立てていきますmarker = new google.maps.Marker()
でマーカーのインスタンスを作成します。
let map;
function initMap() {
const position = { lat: 35.658581, lng: 139.745433 };
map = new google.maps.Map(document.getElementById("custom-map"), {
center: { lat: 35.658581, lng: 139.745433 },
zoom: 8,
});
marker = new google.maps.Marker({
position: position,
map: map,
title: "tokyo-tower",
});
}
window.initMap = initMap;
結果はこんな感じ、見慣れたマーカー📍が立ちました。
マーカーの見た目を変える
Google マップのカスタマイズ: カスタムのマーカー | Maps JavaScript API | Google for Developers
マーカーがデフォルトのままでは寂しいのでちょっと変えてみましょう。
例えばRailsではpublic/img/map_logo.png
といったように、マーカーにしたい画像ファイルを配置してみます。
↓こんな画像
let map;
function initMap() {
const position = { lat: 35.658581, lng: 139.745433 };
map = new google.maps.Map(document.getElementById("custom-map"), {
center: { lat: 35.658581, lng: 139.745433 },
zoom: 8,
});
marker = new google.maps.Marker({
position: position,
map: map,
title: "tokyo-tower",
});
marker.setOptions({
icon: {
url: '/img/map_logo.png'
}
});
}
window.initMap = initMap;
結果はこんな感じ、マーカーに色がつきました!
マーカーに吹き出しをつける + マーカークリックで吹き出しを表示する
情報ウィンドウ | Maps JavaScript API | Google for Developers
さらにレベルアップして、マーカーをクリックすると、情報ウィンドウ(吹き出し)が出てくるようにしてみましょう。
let map;
function initMap() {
const position = { lat: 35.658581, lng: 139.745433 };
const contentString =
'<div class="ks_pin">'
+ '<div class="mb5"><a href="'
+ 'https://ja.wikipedia.org/wiki/%E6%9D%B1%E4%BA%AC%E3%82%BF%E3%83%AF%E3%83%BC'
+ '" class="btn btn-sm btn-default mb5"'
+ '>'
+ 'wikipediaを見る'
+ '</a></div>'
+ '</div>';
const infowindow = new google.maps.InfoWindow({
content: contentString,
});
map = new google.maps.Map(document.getElementById("custom-map"), {
center: { lat: 35.658581, lng: 139.745433 },
zoom: 12,
});
marker = new google.maps.Marker({
position: position,
map: map,
title: "tokyo-tower",
});
marker.setOptions({
icon: {
url: '/img/map_logo.png'
}
});
marker.addListener("click", () => {
infowindow.open({
anchor: marker,
map,
});
});
}
window.initMap = initMap;
結果はこんな感じ、簡単に吹き出しを出すことができます。
【ちょっと応用】複数のマーカーを設置、その属性値で吹き出しやHTMLを書き換える
最後にちょっと応用編ということで、2つのマーカーを設置して、その属性値を利用して吹き出しの内容や、ビューのHTMLを書き換えるようなことをやってみます。
let map;
let marker = [];
let infoWindow = [];
let previous_i;
// マーカーにクリックイベントを付与
function markerEvent(i) {
marker[i].addListener('click', function() {
let markerTitle = marker[i].title;
toggleText(markerTitle);
// 前のピンをクリックしたら吹き出しをクローズする処理
if (previous_i !== undefined) {
infoWindow[previous_i].close(map, marker[previous_i]);
}
infoWindow[i].open({
anchor: marker[i],
map,
});
previous_i = i
});
}
// マーカーに付与する吹き出しの詳細
function windowDetail(obj) {
if (obj.title === "tokyo-tower") {
return '<div>'
+ '<div class="mb5"><a href="'
+ 'https://ja.wikipedia.org/wiki/%E6%9D%B1%E4%BA%AC%E3%82%BF%E3%83%AF%E3%83%BC'
+ '" class="btn btn-sm btn-default mb5"'
+ '>'
+ 'wikipediaを見る'
+ '</a></div>'
+ '</div>';
} else if (obj.title === "sky-tree") {
return '<div>'
+ '<div class="mb5"><a href="'
+ 'https://ja.wikipedia.org/wiki/%E6%9D%B1%E4%BA%AC%E3%82%B9%E3%82%AB%E3%82%A4%E3%83%84%E3%83%AA%E3%83%BC'
+ '" class="btn btn-sm btn-default mb5"'
+ '>'
+ 'wikipediaを見る'
+ '</a></div>'
+ '</div>';
}
}
// マーカーのタイトル属性でテキストを書き換える
function toggleText(title) {
let h1Element = document.querySelector('#text h1');
if (title === "tokyo-tower") {
h1Element.innerHTML = "東京タワーですよ!";
} else if (title === "sky-tree") {
h1Element.innerHTML = "スカイツリーですよ!";
}
}
// 複数のデータを受け取ってマーカーを設置する
function setMarkers(data) {
for (var i = 0; i < data.length; i++) {
// マーカーを立てる
position = {lat: parseFloat(data[i]['lat']), lng: parseFloat(data[i]['lng'])};
markerLatLng = new google.maps.LatLng(position);
marker[i] = new google.maps.Marker({
position: markerLatLng,
map: map,
title: data[i]['title'],
});
// マーカーのアイコンを変える
marker[i].setOptions({
icon: {
url: '/img/map_logo.png'
}
});
// マーカーに吹き出しセット
infoWindow[i] = new google.maps.InfoWindow({
content: windowDetail(data[i])
});
// マーカーにクリックイベントセット
markerEvent(i);
}
}
// 地図の描画処理
function initMap() {
data =[
{
title: "tokyo-tower",
lat: "35.65871123089065",
lng: "139.74537925206033",
},
{
title: "sky-tree",
lat: "35.71292005728178",
lng: "139.81072185646673",
},
]
map = new google.maps.Map(document.getElementById("custom-map"), {
center: { lat: 35.658581, lng: 139.745433 },
zoom: 12,
});
setMarkers(data);
}
// initMap関数の呼び出し
window.initMap = initMap;
結果はこんな感じ。あなたは東京タワー派ですか?スカイツリー派ですか??
まとめ
- 最後の例を応用すると、例えば、RailsバックエンドのAPI経由でDBのデータをJSONで取得して、そのデータ配列からピンを生成するみたいなこともできますね。
- GoogleMap APIは色んなプロダクトでよく使われるAPIだと思いますので、参考にしていただけたら幸いです。
- 本記事で紹介したコードで、非推奨のメソッドなどが今後出てくる可能性もありますので、最新情報は必ず公式ドキュメントで確認してください。
- 最後まで読んでいただきありがとうございました。
参考