Leafletを使って地図を使ったアプリを作成しいていましたが、画面遷移(あるいはリロード)したときに必ずデフォルトの座標に戻ってしまい、使いづらさを感じていました。
そこで、画面遷移しても遷移前に見ていた地図座標を保持したいと思いsessionStorageを使いました。
具体的に実現した方法をまとめてみます。
開発環境
Ruby 2.6.5
Ruby on Rails 5.2.6
Leaflet.js 1.7.1
Leafletの初期設定
ここではLeaflet.jsの導入は省略します。
Leaflet.js
まずLeafletで地図を表示するためのデフォルトの設定をします。
マップタイルはオープンソースのOpenStreetMapを使用します。
<div id="mapid"></div>
<script>
//デフォルトの位置座標とzoomを指定
var mymap = L.map('mapid').setView([35.680196, 139.766746], 16);
//マップタイルを指定
L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png', {
attribution: 'c <a href="//osm.org/copyright">OpenStreetMap</a> contributors, <a href="//creativecommons.org/licenses/by-sa/2.0/">CC-BY-SA</a>',
maxZoom: 18,
minZoom: 3,
}).addTo(mymap);
</script>
デフォルト座標35.680196, 139.766746
は東京駅を中心にした地図を表示しています。
しかし、この設定だと地図をスクロールして別の地域を表示していても、画面を遷移(またはリロード)する度にまた東京駅に戻ってしまいますよね。アプリによってはこの挙動が不便になる場合もあります。
sessionStorageとは?
そこでsessionStorageという仕組みを使いました。
sessionStorageとは、JavaScriptを用いてブラウザにデータを保存できる仕組みです。HTML5から導入されたWebStorageの1つです。
ブラウザ画面を開いているセッションにおいてだけデータを保持でき、新しいタブやウィンドウを開くと新しいセッションが開始します。
画面遷移やリロードしてもデータが保持されるのが特徴です。
他にlocalStorageがありますが、こちらはブラウザを閉じてもデータ保持が持続してしまうので、sessionStorageほど気軽には使えないですね。
sessionStorageで画面遷移前の位置情報を保持する
地図の位置情報をsessionStorageに保持してみます。
まず、現在表示している地図の中心の位置座標をJavaScriptで取得します。
以下のコードを追加します。
<script>
//下記を追記
mymap.on('move', function(e){
currentPosi = mymap.getCenter();
currentZoom = mymap.getZoom();
}
</script>
地図の中心座標とzoomの値を変数に格納します。これで地図を動かすたびに、位置座標を取得して変数に保持することができます。
次に取得した位置座標のデータをsessionStorageに保持していきましょう。
sessionStorageに保持するには、キーと値を設定します。
sessionStorage.setItem('key', value)
<script>
mymap.on('move', function(e){
currentPosi = mymap.getCenter();
currentZoom = mymap.getZoom();
//下記を追記
sessionStorage.setItem('currentLat',currentPosi.lat);
sessionStorage.setItem('currentLng',currentPosi.lng);
sessionStorage.setItem('currentZoom',currentZoom);
}
</script>
GoogleChromeの検証画面でsessionStorageの値が保持されているかどうかを確認できます。
Application > Storage > sessionStorage > http:~
設定したキーと値がセットになって保持されていることが確認できました。
これで画面遷移してもデータを持ち越すことができます。
sessionStorageの値を受け取り、リロード後の地図に反映
次に画面遷移した時にこの位置座標を受け取り、地図に反映させます。
<script>
var sessionKey = sessionStorage.getItem('currentLat');
//sessionStorageが空だった場合と値が存在する場合で分岐し、デフォルト値を動的に生成
if( sessionKey == null ){
var defaultLatlng = [35.678362, 139.715387];
var defaultZoom = 13;
} else {
var defaultLatlng = [Number(sessionStorage.currentLat), Number(sessionStorage.currentLng)];
var defaultZoom = Number(sessionStorage.currentZoom);
};
var mymap = L.map('mapid').setView(defaultLatlng, defaultZoom);//直書きだった座標とzoomの値を、変数にする
//以下省略
</script>
これで画面遷移前の位置情報を、画面遷移後(今回はリロード後)の地図に反映することができました。