【Leaflet】 複数のマップタイルを切り替える

はじめに

 OpenStreetMap や Stamen Design, 国が公開しているデータなど、マップには様々なオープンデータが存在します。今回はそれらマップタイルを切り替える方法のうち、 ①コントロールを追加して切り替える方法、および ②外部から切り替える方法の2つについてまとめます。

DrawTrail

図1. タイル切り替え用のコントロールの追加

コントロールを追加する方法

 コントロールを追加してマップタイルを切り替える方法について説明します。

 まず、コントロールに追加するタイルレイヤーを定義します。複数のタイルを引用しているが、それぞれの利用範囲については概要を別のページにまとめているので、ご覧いただけると幸いです。

var OSMtile = L.tileLayer('http://tile.openstreetmap.jp/{z}/{x}/{y}.png', {
        attribution: '<a href="https://www.openstreetmap.org/copyright" target="_blank">©OpenStreetMap</a> contributors'
    }).addTo(map); //最初に表示させるタイルに addTo() をつける
var HOTtile = L.tileLayer('http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', {
        attribution: '<a href="https://www.openstreetmap.org/copyright" target="_blank">©OpenStreetMap</a> contributors, Tiles: <a href="http://map.hotosm.org/" target="_blank">©HOT</a>'});
var OTMtile = L.tileLayer('http://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
        attribution: '<a href="https://www.openstreetmap.org/copyright" target="_blank">©OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org/" target="_blank">SRTM</a> | map style: <a href="https://opentopomap.org/" target="_blank">©OpenTopoMap</a>'});
var Stamen_Tonar = L.tileLayer('http://tile.stamen.com/toner/{z}/{x}/{y}.png', {
        attribution: 'Map tiles by <a href="https://stamen.com/" target="_blank">Stamen Design</a>, under CC BY 3.0. Data by <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>, under ODbL'});
var Stamen_Terrain = L.tileLayer('http://tile.stamen.com/terrain/{z}/{x}/{y}.png', {
        attribution: 'Map tiles by <a href="https://stamen.com/" target="_blank">Stamen Design</a>, under CC BY 3.0. Data by <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>, under ODbL'});

 次に、定義したタイルレイヤーをコントロールに紐づけます。
 コントロールのアイコンはマップの右上に表示されますが、位置はオプションで変更することができます。右下に表示させたい場合は、ここで position: “bottomright” と追記します。

L.control.layers({
        "OpenStreetMap": OSMtile,
        "Humanitarian map style": HOTtile,
        "OpenTopoMap": OTMtile,
        "Stamen Design (Tonar)": Stamen_Tonar,
        "Stamen Design (Terrain)": Stamen_Terrain
    }).addTo(map);

//右下に配置する場合:
//L.control.layers ({Tiles...}, null, {position: "bottomright"}).addTo(map)  

 以上まとめると、全体のソースコードは次のようになります。

<!DOCTYPE html>
<html>
<head>
<title>htmlMap</title>
<meta http-equiv='content-type' charset='utf-8'>
<meta name='viewport' content='width=device-width'>
</head>
<body>
<div id='mapcontainer' style='width:100%; height:300px; z-index:0;'></div>
<link rel='stylesheet' href='https://unpkg.com/leaflet@1.3.0/dist/leaflet.css' />
<script src='https://unpkg.com/leaflet@1.3.0/dist/leaflet.js'></script>
<script>
function init_map() {

    var map = L.map('mapcontainer',{
            maxBounds: [[90, -Infinity], [-90, Infinity]], //北極と南極で範囲制限
        });
    map.setView([33.555, 133.572], 7); 

    //マップタイルの定義
    var OSMtile = L.tileLayer('http://tile.openstreetmap.jp/{z}/{x}/{y}.png', {
            attribution: '<a href="https://www.openstreetmap.org/copyright" target="_blank">©OpenStreetMap</a> contributors'
        }).addTo(map); //最初に表示させるタイルに addTo() をつける
    var HOTtile = L.tileLayer('http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', {
            attribution: '<a href="https://www.openstreetmap.org/copyright" target="_blank">©OpenStreetMap</a> contributors, Tiles: <a href="http://map.hotosm.org/" target="_blank">©HOT</a>'});
    var OTMtile = L.tileLayer('http://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
            attribution: '<a href="https://www.openstreetmap.org/copyright" target="_blank">©OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org/" target="_blank">SRTM</a> | map style: <a href="https://opentopomap.org/" target="_blank">©OpenTopoMap</a>'});
    var Stamen_Tonar = L.tileLayer('http://tile.stamen.com/toner/{z}/{x}/{y}.png', {
            attribution: 'Map tiles by <a href="https://stamen.com/" target="_blank">Stamen Design</a>, under CC BY 3.0. Data by <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>, under ODbL'});
    var Stamen_Terrain = L.tileLayer('http://tile.stamen.com/terrain/{z}/{x}/{y}.png', {
            attribution: 'Map tiles by <a href="https://stamen.com/" target="_blank">Stamen Design</a>, under CC BY 3.0. Data by <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>, under ODbL'});

    L.control.layers({
            "OpenStreetMap": OSMtile,
            "Humanitarian map style": HOTtile,
            "OpenTopoMap": OTMtile,
            "Stamen Design (Tonar)": Stamen_Tonar,
            "Stamen Design (Terrain)": Stamen_Terrain
        }).addTo(map);
}
    window.addEventListener('DOMContentLoaded', init_map());
</script>
</body>
</html>

 実装例

外部から切り替える方法

 次に、ボタンやプルダウンメニューなど、外部の要素から Leaflet のマップタイルを切り替える方法について説明します。

 まず、remove(Map) で現在設定しているタイルレイヤーを削除します。

TileLayer.remove(Map);

  次に、addTo(Map) で設定したいタイルレイヤーをマップに貼りなおします。

TileLayer.addTo(Map);

 以上のようにして、プルダウンメニューからマップタイルを切り替えられるようにしてみました。このとき全体のソースコードは次のようになります。

<!DOCTYPE html>
<html>
<head>
<title>htmlMap</title>
<meta http-equiv='content-type' charset='utf-8'>
<meta name='viewport' content='width=device-width'>
</head>
<body>
<div id='Mapcontainer' style='width:100%; height:300px; z-index:0;'></div>
<select id="TileSelect" name="Tile_Select" onChange="TileSet()">
    <option value="0" selected>OpenStreetMap</option>
    <option value="1">Humanitarian map style</option>
    <option value="2">OpenTopoMap</option>
    <option value="3">Stamen Design (Tonar)</option>
    <option value="4">Stamen Design (Terrain)</option>
</select>
<link rel='stylesheet' href='https://unpkg.com/leaflet@1.3.0/dist/leaflet.css' />
<script src='https://unpkg.com/leaflet@1.3.0/dist/leaflet.js'></script>
<script>

   //グローバル変数
   var MapTile = [
        L.tileLayer('http://tile.openstreetmap.jp/{z}/{x}/{y}.png', {
            attribution: '<a href="https://www.openstreetmap.org/copyright" target="_blank">©OpenStreetMap</a> contributors'}),
        L.tileLayer('http://{s}.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png', {
            attribution: '<a href="https://www.openstreetmap.org/copyright" target="_blank">©OpenStreetMap</a> contributors, Tiles: <a href="http://map.hotosm.org/" target="_blank">©HOT</a>'}),
        L.tileLayer('http://{s}.tile.opentopomap.org/{z}/{x}/{y}.png', {
            attribution: '<a href="https://www.openstreetmap.org/copyright" target="_blank">©OpenStreetMap</a> contributors, <a href="http://viewfinderpanoramas.org/" target="_blank">SRTM</a> | map style: <a href="https://opentopomap.org/" target="_blank">©OpenTopoMap</a>'}),
        L.tileLayer('http://tile.stamen.com/toner/{z}/{x}/{y}.png', {
            attribution: 'Map tiles by <a href="https://stamen.com/" target="_blank">Stamen Design</a>, under CC BY 3.0. Data by <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>, under ODbL'}),
        L.tileLayer('http://tile.stamen.com/terrain/{z}/{x}/{y}.png', {
            attribution: 'Map tiles by <a href="https://stamen.com/" target="_blank">Stamen Design</a>, under CC BY 3.0. Data by <a href="https://www.openstreetmap.org/copyright" target="_blank">OpenStreetMap</a>, under ODbL'})]

    var currentTile = 0;
    var Map;

function init_Map() {
    Map = L.map('Mapcontainer',{
            maxBounds: [[90, -Infinity], [-90, Infinity]], //北極と南極で範囲制限
        });
    Map.setView([33.555, 133.572], 7);
    MapTile[currentTile].addTo(Map);
}

function TileSet() {
    MapTile[currentTile].remove(Map);
    currentTile = document.getElementById("TileSelect").value;
    MapTile[currentTile].addTo(Map);
}

    window.addEventListener('DOMContentLoaded', init_Map());
    
</script>
</body>
</html>

実装例

 

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です