【Leaflet】マーカーの画像を切り替える

ネコニウム研究所

PCを利用したモノづくりに関連する情報や超個人的なナレッジを掲載するブログ

【Leaflet】マーカーの画像を切り替える

2023-6-28 | ,

Leafletでマーカーの画像を切り替えたい!

概要

今回の記事では、Leafletでマーカーの画像を切り替える手順を掲載する。

仕様書

環境

  • Leaflet 1.7.1

手順書

右上のセレクトボックスから画像の名前を選択するとマーカーのカスタムイメージが切り替わるサンプル。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8" />
        <title>Leaflet Test</title>
        <style>
            .menu-right {
                border: solid 1px;
                background-color: #ffffff;
                border-radius: 4px;
                padding: 8px;
                color: #000000;
            }
        </style>
        <link rel="stylesheet" href="https://unpkg.com/leaflet@1.7.1/dist/leaflet.css" />
        <script src="https://unpkg.com/leaflet@1.7.1/dist/leaflet.js"></script>
        <script>
            var marker;
            var map;
            var pin_index = 0;
            var custum_pin_1;
            var custum_pin_2;
            var custum_pin_3;

            function init()
            {
                var xy2lat = function (x, y) {
                return map.unproject([x, y], 4);
                };

                var image = {
                    url: "https://blog.nekonium.com/wp-content/uploads/catacombs_of_the_cursed_witch.png",
                    width: 2030,
                    height: 2730,
                };

                map = L.map("leaflet-container", {
                    crs: L.CRS.Simple,
                    minZoom: -1,
                    maxZoom: 5,
                });

                var imageBounds = L.latLngBounds([map.unproject([0, image.height], 4), map.unproject([image.width, 0], 4)]);

                map.fitBounds(imageBounds);
                map.setMaxBounds(imageBounds.pad(0.5));

                L.imageOverlay(image.url, imageBounds).addTo(map);

                let selBox = L.control({ position: "topright" });
                selBox.onAdd = function (map) {
                    this.ele = L.DomUtil.create('select');
                    this.ele.id = "id-icon-type";
                    return this.ele;
                };
                selBox.addTo(map);

                let sel = document.getElementById("id-icon-type");

                let opt1 = L.DomUtil.create('option', '', sel);
                opt1.value = "0";
                opt1.innerText = "custom-pin-1";
                let opt2 = L.DomUtil.create('option', '', sel);
                opt2.value = "1";
                opt2.innerText = "custom-pin-2";
                let opt3 = L.DomUtil.create('option', '', sel);
                opt3.value = "2";
                opt3.innerText = "custom-pin-3";

                sel.setAttribute("onchange", "changeIconType()");

                custum_pin_1 = L.icon({
                    iconUrl: 'https://blog.nekonium.com/wp-content/uploads/custom-pin-1.png',
                    iconSize: [32, 32],
                    iconAnchor: [16, 31],
                    popupAnchor: [0, -31],
                });
                custum_pin_2 = L.icon({
                    iconUrl: 'https://blog.nekonium.com/wp-content/uploads/custom-pin-2.png',
                    iconSize: [32, 32],
                    iconAnchor: [16, 31],
                    popupAnchor: [0, -31],
                });
                custum_pin_3 = L.icon({
                    iconUrl: 'https://blog.nekonium.com/wp-content/uploads/custom-pin-3.png',
                    iconSize: [32, 32],
                    iconAnchor: [16, 31],
                    popupAnchor: [0, -31],
                });

                marker = L.marker(xy2lat(827, 515), { icon: custum_pin_1 }).addTo(map).bindPopup("Water room", {closeOnClick: false}).openPopup();
            }

            function changeIconType() {
                var sel = document.getElementById("id-icon-type");
                pin_index = sel.options[sel.selectedIndex].value;

            if (pin_index == 0) {
                marker.setIcon(custum_pin_1);
            } else if (pin_index == 1) {
                marker.setIcon(custum_pin_2);
            } else if (pin_index == 2) {
                marker.setIcon(custum_pin_3);
            }
}
        </script>
    </head>
    <body onload="init()">
        <div id="leaflet-container" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0"></div>
    </body>
</html>

解説

setIcon関数でカスタムイメージのインスタンスを渡すだけ。

マーカーで使うカスタムイメージは前もって初期化時などにインスタンス化しておいた方が切り替えがスムーズ。

デモ

CODEPENで動かしてみると下記のような感じ。

See the Pen
Leaflet Change Icon Test
by 108nen (@108nen)
on CodePen.

まとめ(感想文)

UIのスタイルを変えたい時に使えるかもね!