Leaflet上のチェックボックスで表示/非表示を切り替えたい

# はじめに
とにもかくにも、**Leaflet上にチェックボックスを配置して、
マーカーなり何なりの表示/非表示を切り替えたい**という記事です。
（下図みたいなやつ）

表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/2a4b2e0d-0c6c-27ed-90a5-47e8b263c204.png)

非表示
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/9707d6cb-a112-be62-6414-d69aef53803c.png)

# 忙しい人向けの結論
Leafletのオーバーレイレイヤ機能を使うことで実現できます。

```js
// 表示を切り替えたいレイヤ
// layer = L.marker(), L.layerGroup(), L.polyline()...など

// UIコントローラー上の表示名とレイヤを紐付け
var overlayLayerControls = {
    '表示名': layer
};

// オーバーレイレイヤ設定を地図に追加
// ベースレイヤは固定・UI表示不要なため、nullを設定
L.control.layers(null, overlayLayerControls, {collapsed: false}).addTo(map);
```

# 予想される検索ワード
以下、この記事を求めているであろう方が入力しそうな
（というか実際に私が必死で検索した）検索ワードです。

Leaflet, チェックボックス, 表示, 非表示

# 実行環境
- Microsoft Edge 99.0.1150.36
- Leaflet 1.7.1

# チェックボックスの配置方法
ここからは、実際にLeaflet上にチェックボックスを配置し
チェックボックスのON/OFFによって
地図上のマーカー表記を切り替えるところまでやってみます。

ちなみに、Leafletを全く触ったことがない方は
先に以下の記事やチュートリアルを触ってみることをお勧めします。
（私もこの辺を触りながら少しずつ慣れているところなので）

https://qiita.com/studio_haneya/items/f108bd49f59c543b6b64

https://ktgis.net/service/leafletlearn/index.html

## Leaflet.jsでブラウザ上に地図を表示させる
まずは、ブラウザ上に地図を表示させます。

正直、ブラウザに地図が表示できれば何でもよいですが、
チェックボックスによる表示の切り替えを試すための
適当なマーカーだけ追加しておいてください。

ここでは、以下の構成でtestファイルを作ってみました。

```tex:ファイル構成
test_folder
 |
 ├─ test.html
 └─ test.js
```

```html:test.html
<!DOCTYPE html>
<html lang="ja">
<head>
    <meta charset="utf-8">
    <title>Leaflet テスト</title>

    <!-- Leaflet読み込み -->
    <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>

    <!-- Javascriptファイルの読み込み -->
    <script type="text/javascript" src="test.js"></script>
</head>
<body onload="leaflet()">
    <section>
        <div id="div_map" style="width:1200px;height:600px"></div>
    </section>
</body>
```

```js:test.js
function leaflet() {
    // Leafletの初期表示設定の値
    longitude = 43.38;
    latitude = 142.6;
    zoom_level = 7;

    // 地図を表示するdiv要素のidを設定 & 初期のズームコントロールを非表示
    var map = L.map('div_map', { zoomControl: false });

    // 地図の中心位置とズームレベルをセット
    map.setView([longitude, latitude], zoom_level);

    // 表示するタイルレイヤのURLとAttributionコントロール
    var tileLayer = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', {
        attribution: "<a href='https://maps.gsi.go.jp/development/ichiran.html' target='_blank'>地理院タイル</a>"
    });

    // 設定したタイルレイヤをmapに追加
    tileLayer.addTo(map);

    // スケールコントロールを最大幅200px、右下、m単位で地図に追加
    L.control.scale({ maxWidth: 200, position: 'bottomright', imperial: false }).addTo(map);

    // ズームコントロールを左下で地図に追加
    L.control.zoom({ position: 'bottomleft' }).addTo(map);

    // マーカー情報の定義
    add_marker = L.marker([43.122222, 141.54222]).bindTooltip("まーかー");

    // // マーカーを地図上に配置
    add_marker.addTo(map);
}
```

お手持ちのブラウザで開くと、こんな感じで地図が表示されます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/6de7503f-d7db-ceae-fa84-4e8f0bc350f8.png)


## オーバーレイレイヤ設定を追加する
お時間ある方は、以下の記事の方が詳しいです。

https://business.mapfan.com/blog/detail/1571

上記を読む元気が無い方向けに、必要な情報だけ抜き出したものがこちら。

```js
// 表示を切り替えたいレイヤ
// layer = L.marker(), L.layerGroup(), L.polyline()...など

// UIコントローラー上の表示名とレイヤを紐付け
var overlayLayerControls = {
    '表示名': layer
};

// オーバーレイレイヤ設定を地図に追加
// ベースレイヤは固定・UI表示不要なため、nullを設定
L.control.layers(null, overlayLayerControls, {collapsed: false}).addTo(map);
```

test.jsに設定を追加してみたのがこちら。

```js:test.js
function leaflet() {
    // Leafletの初期表示設定の値
    longitude = 43.38;
    latitude = 142.6;
    zoom_level = 7;

    // 地図を表示するdiv要素のidを設定 & 初期のズームコントロールを非表示
    var map = L.map('div_map', { zoomControl: false });

    // 地図の中心位置とズームレベルをセット
    map.setView([longitude, latitude], zoom_level);

    // 表示するタイルレイヤのURLとAttributionコントロール
    var tileLayer = L.tileLayer('https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png', {
        attribution: "<a href='https://maps.gsi.go.jp/development/ichiran.html' target='_blank'>地理院タイル</a>"
    });

    // 設定したタイルレイヤをmapに追加
    tileLayer.addTo(map);

    // スケールコントロールを最大幅200px、右下、m単位で地図に追加
    L.control.scale({ maxWidth: 200, position: 'bottomright', imperial: false }).addTo(map);

    // ズームコントロールを左下で地図に追加
    L.control.zoom({ position: 'bottomleft' }).addTo(map);

    // マーカー情報の定義
    add_marker = L.marker([43.122222, 141.54222]).bindTooltip("まーかー");

    // // マーカーを地図上に配置
    // add_marker.addTo(map);

    // UIコントローラー上の表示名とマーカーを紐付け
    var overlayLayerControls = {
        'マーカー表示': add_marker
    };

    // オーバーレイレイヤ設定を地図に追加
    L.control.layers(null, overlayLayerControls, {collapsed: false}).addTo(map);
}
```

ファイルを保存してtest.htmlをブラウザで開き直すと、チェックボックスが追加されています。
（右上のチェックボックスをクリックするとマーカーの表示/非表示が切り替わります）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1147458/99fec962-a7b2-6c33-be19-aa49349065ab.png)

# おわりに
Web上に地図を表示する場合、「アレもコレも」と情報を載せると
結局、地図が見にくくなってしまう...なんてこともありがちかなと思います。

そうならないようにオーバーレイレイヤを使いこなして、
必要最低限の情報をシンプルに伝えられるようにすると良さそうですね。

ちなみに、今回はLeaflet上にチェックボックスを追加していますが、
Leaflet外のチェックボックスで表示を切り替えることもできそうな気がしているので
参考記事だけ、最後に貼っておきます。（ちゃんと読んでないから違うかも）

# 参考
https://ja.stackoverflow.com/questions/70257/leaflet-%E3%83%81%E3%82%A7%E3%83%83%E3%82%AF%E3%83%9C%E3%83%83%E3%82%AF%E3%82%B9%E3%81%AE%E5%88%A4%E5%AE%9A%E3%82%92%E3%81%97%E3%81%A6%E3%83%9E%E3%83%BC%E3%82%AB%E3%83%BC%E3%81%AE%E5%89%8A%E9%99%A4%E3%82%92%E3%81%97%E3%81%9F%E3%81%84