ブログやサイトに APIでgoogle mapsを埋め込んでいる人って多いですよね。
これ、便利だけど頭が痛いという人が多いと思います。というのも、表示数に応じてお金がかかるから。
何かいい解決策はないか?と探していると、 オープンソースで使える地図ソフトを見つけました。
Leaflet – a JavaScript library for interactive maps
Facebookや Flickrでも使われているらしく、信頼できます。早速導入してみました。
- 1)基本的な地図を描く
- 2)地図にマーカーを置く
- 3)マーカークラスターを入れる
- 4)フルスクリーン機能を入れる
- 5)クラスターがまとまらない問題を解決する
- 6)マーカーをクリックしてフルスクリーンを解除したい!
- 7)スマホとPCで地図の大きさを変えたい
Leafletのことを知るにあたって、上記の公式ページのほかに、こちらのページを参考にしました。本当にありがとうございます!
とても参考になりますので、ぜひご覧になってください
Google Maps APIに頼らなくてもできる!「Leaflet」で地図を埋め込む – Eyes, JAPAN Blog
- ライセンスのこと
- 地図JavascriptとCSSの読み込み
- タイルレイヤーのこと
などが簡潔に分かりやすく書かれています。
1)基本的な地図を描く
まず基本的な地図を描きます。
最初に、Leafletを使うためのjavascriptとCSSを読み込みます
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.6.0/dist/leaflet.css"/> <script src="https://unpkg.com/leaflet@1.6.0/dist/leaflet.js"></script>
さらに地図を表示するdivをとって、idを打ち、幅と高さをcssで指定します
<div id="mapid" style="width: 600px; height: 400px;"></div>
博多駅の緯度経度([33.590188, 130.420685])、ズームは15で指定しています。地図はLeaflet以外にタイルレイヤーが必要(上述リンク参照)ですが、国土地理院さんのを利用しています。ありがとうございます。
// 地図を作成する ([緯度,経度], ズーム) var mymap = L.map('mapid').setView([33.590188, 130.420685], 15); // タイルレイヤーを作成し、地図にセット。レイヤーは国土地理院のを使わせていただいてます L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', { maxZoom: 18, attribution: '<a href="https://maps.gsi.go.jp/development/ichiran.html" target="_blank">国土地理院</a>', }).addTo(mymap);
2)地図にマーカーを置く
1)で作った地図にマーカーを置きます。最初からついていてる青いマーカー以外にも自作のマーカーを使うこともできます。さらに、クリックしたらポップアップして情報を表示することもできます。
//マーカー01を設置する var marker01 = L.marker([33.587847, 130.416411]);//緯経度指定 marker01.bindPopup("元祖 ぴかいち");//クリック時ポップ marker01.addTo(mymap);//地図に加える //マーカー02を設置する var marker02 = L.marker([33.592459, 130.411014]);//緯経度指定 marker02.bindPopup("かろのうろん");//クリック時ポップ marker02.addTo(mymap);//地図に加える //カスタマイズアイコンを中央マーカーとして設置する var markercentericon = L.icon({ iconUrl: 'img/red-marker.png', // アイコン画像のURL iconSize: [32, 36], // アイコンの大きさ iconAnchor: [16, 32], // 画像内でマーカーの位置を指し示す点の位置 popupAnchor: [0, -32] // ポップアップが出現する位置(iconAnchorからの相対位置) });
マーカーは、こちらのサイトを参考に造りました。ありがとうございます。
3)マーカークラスターを入れる
マーカーが少ないうちは問題ないんですが、たくさん増えてくると重なって見づらくなります。そこで、距離が近いマーカーをまとめてくれるマーカークラスターはありがたいです。
マーカークラスターはプラグイン形式で入れることができます。まずはマーカー用のjavascriptとCSSを読み込みます。
<script src="https://unpkg.com/leaflet.markercluster@1.3.0/dist/leaflet.markercluster.js"></script> <link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.3.0/dist/MarkerCluster.css" /> <link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster@1.3.0/dist/MarkerCluster.Default.css" />
さらに、マーカー用の変数を用意して、まとめたいマーカーを全部まとめておきます。
//マーカークラスターを定義する var markers = L.markerClusterGroup(); //マーカー01を設置する var marker01 = L.marker([33.587847, 130.416411]);//緯経度指定 marker01.bindPopup("元祖 ぴかいち");//クリック時ポップ markers.addLayer(marker01);//マーカークラスターに加える //マーカー02を設置する var marker02 = L.marker([33.592459, 130.411014]);//緯経度指定 marker02.bindPopup("かろのうろん");//クリック時ポップ markers.addLayer(marker02);//マーカークラスターに加える //マーカー03を設置する var marker03 = L.marker([33.592989, 130.410500]);//緯経度指定 marker03.bindPopup("櫛田神社");//クリック時ポップ markers.addLayer(marker03);//マーカークラスターに加える //マーカークラスターを地図に加える mymap.addLayer(markers);
4)フルスクリーン機能を入れる
画面の左側にある□マークをタップ(クリック)すると地図が全画面に広がります。これは、スマホ向けユーザーには必須の機能です。
マーカークラスターと同様にプラグイン形式で入れることができます。まずは javascriptとCSSを読み込みます
<script src='https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/Leaflet.fullscreen.min.js'></script> <link href='https://api.mapbox.com/mapbox.js/plugins/leaflet-fullscreen/v1.0.1/leaflet.fullscreen.css' rel='stylesheet' />
さらに、以下のようにスクリプトに書き込むことで導入できます
//フルスクリーンを使うため mymap.addControl(new L.Control.Fullscreen({ title: { 'false': '最大化', 'true': '元に戻す' } }));
以上が、管理人が地図に盛り込みたい機能でした。Leafletには、もっとユニークなプラグインも用意されていますので、自分にあうものを探すのも面白いと思います。
Plugins – Leaflet – a JavaScript library for interactive maps
5)クラスターがまとまらない問題を解決する
ここで、管理人がやった失敗例をご紹介します。マーカーがクラスターにまとまらないというか上手に機能しなかったんです。
これはコードでミスをしています
//マーカー03を設置する var marker03 = L.marker([33.592989, 130.410500]);//緯経度指定 marker03.bindPopup("櫛田神社");//クリック時ポップ marker03.addTo(mymap);//地図に加える ←この行は要らない!!! markers.addLayer(marker03);//マーカークラスターに加える //マーカークラスターを地図に加える mymap.addLayer(markers);
冷静に見ると分かるんですが、マーカーを定義した後、地図に加える。
さらにクラスターにまとめて最後に地図に加える
と2回同じ操作(地図に加えること)をやっています。
javascriptの中級者以上の方には、もっと勉強しなさいと笑われるような話ですが、
自分のように初心者の人で悩んでいる人がいるかもと思って書いておきます。
(この問題を解決するのにすごく時間がかかったんです。。。)
6)マーカーをクリックしてフルスクリーンを解除したい!
最後にもう一つ悩んだこと。マーカーのリンクをクリックして、フルスクリーンを解除。さらにページ内遷移させること。これがなかなかできなかったんです。
地図上のマーカーリンクをクリックさせて、下の説明書きにページ内遷移させたい。
普通に <a href=”#”></a> で idタグを持つ場所に飛ばすと、よさそうに見えるんですが。
この方法だとフルスクリーンモードにすると上手くいきません。
(タップ(クリック)しても反応しない)
一方、以下のやり方だと上手くいきます
GitHub – Leaflet/Leaflet.fullscreen: A fullscreen control for Leafletにヒントが書いてあります。
The plugin also adds several methods to L.Map which are always available, even if you choose not to use the fullscreen button:
map.isFullscreen() // Is the map fullscreen? (フルスクリーン or not判定)
map.toggleFullscreen() // Either go fullscreen, or cancel the existing fullscreen. (フルスクリーン ⇔ 解除)
onclickで、フルスクリーン状態なら解除するというコードをアンカーリンクに書きました。
<a onclick="if (mymap.isFullscreen()) {mymap.toggleFullscreen()}" href="#"></a>
これは、もっとうまいやり方があるのかもしれません。
よかったらコメントで教えてください。
7)スマホとPCで地図の大きさを変えたい
地図はスマートフォンで見るときは小さく、PCで見るときは大きく表示したいですよね。特にスマホは地図そのものがスライドするので、大きいと扱いが難しいです。
PHPで大きさを変える方法もあるんですが、CSSで幅が変更したら自動的に大きさが変わるほうがスマートな感じがします。
css に以下のコードを加えて
@media only screen and (max-width: 750px) { #mapid{ width : 300px; height: 300px; } } @media only screen and (min-width: 750px) { #mapid{ width : 600px; height: 400px; } }
div 部分のstyle部分を消します
<div id="mapid"></div>
こちらのページが分かりやすかったです。ありがとうございます!
【レスポンシブ】PCとスマホで違う画像に切り替える方法!CSSだけで簡単画像切り替え! | FASTCODING BLOG
最後にちょっと宣伝します。姉妹サイトのホテル予約サイト。
ホテルここから
このサイトで地図が必要なので、一生懸命勉強しました。
よかったらブックマークをお願いします!