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

はじめに
マップタイルには、Google Maps のような有料の物だけでなく、OpenStreetMap や国が公開しているデータなど様々なオープンデータも存在します。今回は OpenLayers で、それらのマップタイルを切り替える方法について説明します。
この記事は「【OpenLayers入門】地図を表示する方法と基本的な使い方」の続きです。
マップタイルを設定する方法
まず、マップタイルを設定する方法について説明します。例えば、国土地理院が提供する地理院タイルを使用する場合、以下のようにタイルレイヤーを設定します。
layers: [
new ol.layer.Tile({
source: new ol.source.XYZ({
attributions: "<a href='https://maps.gsi.go.jp/development/ichiran.html' target='_blank'>国土地理院</a>", //クレジット
url: "https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png" //タイルサーバーのURL
})
})
]
このタイルレイヤーを用いて地図を表示するには、以下のようなソースコードになります。
<!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タグ。マップサイズはwidth(幅)とheight(高さ)で決まる -->
<div id='mapcontainer' style='width:100%; height:300px; z-index:0;'></div>
<!-- 以下OpenLayersのJavaScriptとCSS -->
<script src="https://cdn.jsdelivr.net/npm/ol@v10.4.0/dist/ol.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v10.4.0/ol.css">
<script>
function init_map() {
const map = new ol.Map({
target: 'mapcontainer',
layers: [
new ol.layer.Tile({
source: new ol.source.XYZ({
attributions: "<a href='https://maps.gsi.go.jp/development/ichiran.html' target='_blank'>国土地理院</a>",
url: "https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png"
})
})
],
view: new ol.View({
center: ol.proj.fromLonLat([142.14, 43.65]),
zoom: 6
})
});
}
//ダウンロード時に初期化する
window.addEventListener('DOMContentLoaded', init_map());
</script>
</body>
</html>
実装例
複数のタイルを切り替える方法
次に、複数のマップタイルをプルダウンメニューで切り替える方法について説明します。以前のバージョンの OpenLayers だと LayerSwitcher というのがあり、比較的簡単に実装できたみたいなのですが、現在のバージョン(ver 10.4.0)にはないので、外部のプルダウンメニューからマップタイルを切り替えていきます。
まず、removeLayer() で現在設定しているタイルレイヤーを削除します。
map.removeLayer(mapTile[currentTile]);
次に、addLayer() で設定したいタイルレイヤーをマップに貼りなおします。
map.addLayer(mapTile[currentTile]);
以上のようにして、プルダウンメニューからマップタイルを切り替えられるようにしてみました。このとき全体のソースコードは次のようになります。
<!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タグ。マップサイズはwidth(幅)とheight(高さ)で決まる -->
<div id='mapcontainer' style='width:100%; height:300px; z-index:0;'></div>
<!-- プルダウンメニュー -->
<select id="tileSelect">
<option value="0" selected>OpenStreetMap</option>
<option value="1">Humanitarian map style</option>
<option value="2">OpenTopoMap</option>
</select>
<!-- 以下OpenLayersのJavaScriptとCSS -->
<script src="https://cdn.jsdelivr.net/npm/ol@v10.4.0/dist/ol.js"></script>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ol@v10.4.0/ol.css">
<script>
function init_map() {
//タイル情報を格納した配列
const mapTile = [
OSMtile = new ol.layer.Tile({
source: new ol.source.XYZ({
attributions: "© <a href='https://www.openstreetmap.org/copyright' target='_blank'>OpenStreetMap</a> contributors",
url: "https://a.tile.openstreetmap.org/{z}/{x}/{y}.png"
})
}),
HOTtile = new ol.layer.Tile({
source: new ol.source.XYZ({
attributions: "© <a href='https://www.openstreetmap.org/copyright' target='_blank'>OpenStreetMap</a> contributors, Tiles: © <a href='http://map.hotosm.org/' target='_blank'>HOT</a>",
url: "https://a.tile.openstreetmap.fr/hot/{z}/{x}/{y}.png"
})
}),
OTMtile = new ol.layer.Tile({
source: new ol.source.XYZ({
attributions: "© <a href='<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>",
url: "https://a.tile.opentopomap.org/{z}/{x}/{y}.png"
})
})
];
let currentTile = 0;
map = new ol.Map({
target: 'mapcontainer',
layers: [mapTile[currentTile]],
view: new ol.View({
center: ol.proj.fromLonLat([142.14, 43.65]), //初期の中心位置 [経度, 緯度]
zoom: 6 //ズームレベル
})
});
//セレクトボックスに onchange イベントを追加
document.getElementById('tileSelect').onchange = function() {
map.removeLayer(mapTile[currentTile]);
currentTile = document.getElementById("tileSelect").value;
map.addLayer(mapTile[currentTile]);
}
}
//ダウンロード時に初期化する
window.addEventListener('DOMContentLoaded', init_map());
</script>
</body>
</html>
実装例
ちょっと宣伝
当サイトは Web 地図を積極的に用いた海外旅ブログまとめサイトとなっています。トップページに地図がありますが、地名を押すと画像が開き、画像を押すと関連記事一覧(クリック数順)が開きます。記事数が多い国ほど赤く、地名もその国で記事が多い都市の文字が大きくなるようにしています。ぜひ覗いてみてください。
当サイトで海外旅ブログを執筆することも可能です(もちろん無料です)! また既にブログをお持ちの方も、当サイトからリンクを貼ることができるようになっています。パントレ開発部までお気軽にお問い合わせください。
このページが皆様のプログラミングの一助となりますことをお祈りいたします
パントレ開発部