勉強したことのメモ

Webエンジニア / プログラマが勉強したことのメモ。

Leafletでマーカーを動的に変更し、変更状況をCookieに保存する方法

  JavaScript

Leafletでポップアップ(フキダシ)内のボタンをクリックするとマーカーを動的に変更させたい。また、マーカーの変更状況をCookieに保存し、ページリロード時等にそのCookieを読み込んで変更状況によってマーカーを出し分けしたい。以下にサンプルと対応方法をメモ。

 

サンプル

https://taitan916.info/sample/leaflet.js/marker/cookie/

マーカークリック→ポップアップ内の「blue」「red」をクリックするとマーカーの色が変わる。

また、マーカーの色を変更後にページリロードすると変更状況が引き継がれている筈。

 

ソースコード

<div id="map"></div>

<script type="text/javascript" src="https://code.jquery.com/jquery-3.7.1.min.js"></script>
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.css"/>
<script src="https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.9.4/leaflet.js"></script>
<script src="https://cdn.jsdelivr.net/npm/leaflet-sprite@1.0.0/dist/leaflet.sprite.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/js-cookie@3.0.5/dist/js.cookie.min.js"></script>
<script>
let map;
map = L.map('map');

//中心の経度緯度
const center = ['35.681236', '139.767125'];

//ズームレベル
const zoom = 12;

//マップの中心地とズームレベルを指定
map.setView(center, zoom);

const tileLayer = L.tileLayer('https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',{
    attribution: '© <a href="http://osm.org/copyright">OpenStreetMap</a>',
    maxZoom: 19
});
tileLayer.addTo(map);

//マーカー生成
const mapData = [
    { 'id' : 0, 'lat' : '35.689607', 'lng' : '139.700571'}, 
    { 'id' : 1, 'lat' : '35.681236', 'lng' : '139.767125'}, 
    { 'id' : 2, 'lat' : '35.628471', 'lng' : '139.73876'}, 
];
var marker = [];
for( key in mapData ){
    //ページ読み込み時はcookieによって赤 or 青のマーカーを設置
    const color = ( Cookies.get(`marker_${key}`) ) ? 'red' : '';
    mapData[key].icon = color;
    marker[key] = makeMarker(mapData[key]);
}

function makeMarker( mapData ){
    L.Icon.Default.imagePath = 'https://unpkg.com/leaflet@1.3.1/dist/images/';
    const icon = L.spriteIcon(mapData.icon);
    const body = makeBody(mapData.icon, mapData.id);

    //ポップアップの表示位置調整
    icon.options.popupAnchor = [2, -35];
    const marker = L.marker([mapData.lat, mapData.lng], {icon: icon})
    .bindPopup(body)
    .addTo(map);

    return marker;
}

function makeBody( color, key ){
    const blueOn = ( color ) ? '' : 'on';
    const redOn = ( color ) ? 'on' : '';
    const body = `
        <div class="blue btn ${blueOn}" data-key="${key}">blue</div>
        <div class="red btn ${redOn}" data-key="${key}">red</div>
    `;
    return body;
}

$(function(){
    //ボタンクリック時
    $('body').on('click', '.btn' , function() {

        const key = $(this).data('key');
        const color = ( $(this).hasClass('red') ) ? 'red' : '';
        const body = makeBody(color, key);
        const icon = L.spriteIcon(color, key);
        icon.options.popupAnchor = [2, -35];

        marker[key]
        .setIcon(icon) //マーカーを変更
        .bindPopup(body) //ポップアップ内のコンテンツを変更
        .closePopup(); //ポップアップを変更

        //cookie作成 or 削除
        if( color ){
            Cookies.set(`marker_${key}`, true);
        }else{
            Cookies.remove(`marker_${key}`);
        }

    });
});

</script>

 

解説等

マーカーの変更について

マーカー変更の際にmakeMarker()関数を使おうと思ったけど、そうすると既存のマーカーの上に重なるような形でマーカーが設置されるっぽい。

そのためsetIcon()でマーカーのみ変更する形を取った。

ポップアップ内のコンテンツの変更について

ポップアップ内のコンテンツも上記のようにmakeMarker()関数を使おうと思ったけど、そうするとCSSがうまく効かなかった。

そのためbindPopup()でポップアップ内のコンテンツを変更する形を取った。

Cookieについて

Cookieの取り扱う際はjs-cookieプラグインを利用した。

 - JavaScript

  関連記事

Leafletでマーカークリック時に当該マーカーをバウンド(跳ねる動作を)させる方法

LeafletとOpenStreetMapでマップ上にマーカーを複数設置した上で ...

Leafletにて操作内容を履歴に残し「進む」「戻る」ボタンで履歴を実行できる「Leaflet.NavBar」の利用方法

Leafletにてマップ移動やズーム等、ユーザーの操作内容を履歴に残して、「進む ...

Leafletで「sidebar-v2」プラグインを導入してマップ上にサイドバーを設置する方法

Leafletでマップ上にサイドバー及びサイドメニューを実装したい。調べたところ ...

leaflet.jsとOSMで現在地を取得しマップ上にマーカーを表示する方法

leaflet.jsとOpenStreetMapで現在位置の経度緯度を取得しマッ ...

Leafletで「Leaflet.markercluster」プラグインを導入してマーカークラスタ機能を追加する方法

LeafletとOpenStreetMapでマップ上にマーカーを複数設置した上で ...