パントレ開発部

【MapLibre】マーカーをクリックすると画像付きポップアップが開くようにする

Map

 当サイトは海外旅ブログまとめサイトです。トップページをご覧になるとお分かりになるかと思いますが、地図上の地名をクリックすると画像付きポップアップが開くようになっています。このページではそんな風に、MapLibre を用いて画像付きポップアップを実装する方法について説明したいと思います。
 MapLibre の基本的な使い方はこちら。

実装例

 以下の地図では、マーカーをクリックすると画像付きポップアップが開きます。

 

実装方法

 全体の流れは、配列かオブジェクトでマーカー座標や画像URLなどのデータを定義して(地理データなので GeoJSON が良いでしょう)、foreach 文でループしながら、マーカーと画像付きポップアップを地図に登録していく感じになります。

 地図へのマーカーの登録は、以下の一文だけでできます。

const marker = new maplibregl.Marker().setLngLat([経度, 緯度]).addTo(map);

 マーカーの色も簡単に変えられます。

const marker = new maplibregl.Marker({color:'#337ab7'}).setLngLat([経度, 緯度]).addTo(map);

 マーカーにポップアップをつけるには、まずポップアップを定義して、次に setPopup() でマーカーにセットします。

const popup = new maplibregl.Popup().setLngLat([経度, 緯度]);
marker.setPopup(popup);

 setHTML() も使えるので、それで画像の HTML を埋め込んであげる感じになります。a タグで img タグを囲めば、画像にリンクを貼ることもできます。

const popup = new maplibregl.Popup().setLngLat([経度, 緯度]).setHTML('<img src="画像のURL"/>');
marker.setPopup(popup);

 

ソースコード

 全体のソースコードは以下のようになります。

<html>
<head>
<title>htmlMap</title>
<meta http-equiv='content-type' charset='utf-8'>
<meta name='viewport' content='width=device-width'>

<!-- 以下 MapLibre のJavaScriptとCSS -->
<link rel='stylesheet' href='https://unpkg.com/maplibre-gl/dist/maplibre-gl.css'/>
<script src='https://unpkg.com/maplibre-gl/dist/maplibre-gl.js'></script>

<!-- 以下 ポップアップの見た目調整用 -->
<style>
.maplibregl-popup {
	box-sizing: content-box;
	margin: 0px; 
}
.maplibregl-popup-content {
	width: 234px;
	height: 136px;
	padding: 5px 5px !important;
}
.maplibregl-popup-close-button{
	background-color: #fff;
}
.maplibregl-popup-close-button:hover {
	background-color: #ddd;
}
.popup_comment{
	background-color:rgba(0,0,0,0.7);
	color:#fff;
	position: absolute;
	bottom: 0px;
	left: 0px; 
	box-sizing:content-box; 
	margin:0px; 
	padding: 5px; 
	max-width: 100%; 
	text-align:left; 
	font-size:12px;
}
.popup_container{
	position: relative; 
	width:100%; 
	height:100%;
}
.popup_image{
	width:100%;
	height:100%;
	border-radius: 0;
	border: none;
	object-fit: cover;
}

</style>
</head>
<body>

<!-- 埋め込みマップのdivタグ。マップサイズはwidth(幅)とheight(高さ)で決まる -->
<div id='mapcontainer' style='width:100%; height:300px; z-index:0;'></div>

<script>
function init_map() {

    // GeoJSON の読み込み
    const places = {
        "type":"FeatureCollection",
        "features":[{
            "type":"Feature",
            "properties":{
                "description":"東京",
                "image":"https:\/\/pancake-trail.site\/wp-content\/uploads\/2023\/11\/すみだソラマチ_190505_0002-e1699772537354.jpg"
            },
            "geometry":{
                "type":"Point",
                "coordinates":[139.767136,35.681243]
            }
        }]
    };

    // ラスタタイル(OpenStreetMap)の読み込み
    const map =  new maplibregl.Map({
        container: 'mapcontainer',
        style: {
            version: 8,
            sources: {
                rtile: {
                    type: 'raster',
                    tiles: [
                       'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
                    ],
                    tileSize: 256,
                    attribution: '©<a href="https://www.openstreetmap.org/copyright/ja">OpenStreetMap</a> contributors',
                },
            },
            layers: [{
                id: "raster-tiles",
                type: "raster",
                source: "rtile",
                minzoom: 0,
                maxzoom: 18,
            }]
        },
        center: [136, 39], 
        zoom:  3, 
        pitch: 0 
    });

    // GeoJSON の features でループを回して、マーカーとポップアップを描画
    places.features.forEach((feature) => {
        const marker = new maplibregl.Marker({color:'#337ab7'}).setLngLat(feature.geometry.coordinates).addTo(map);
        const popup = new maplibregl.Popup().setLngLat(feature.geometry.coordinates).setHTML('<div class="popup_container"><img src=' + feature.properties.image + ' class="popup_image" style="border-radius:0; border: none;"/><div class="popup_comment">'+ feature.properties.description +'</div></div>');
        marker.setPopup(popup);
    });
}

//ダウンロード時に初期化する
window.addEventListener('DOMContentLoaded', init_map());

</script>
</body>
</html>

 

少し宣伝

 当サイトは MapLibre を積極的に用いた海外旅ブログまとめサイトとなっています。トップページに地図がありますが、地名を押すと画像が開き、画像を押すと関連記事一覧(クリック数順)が開きます。記事数が多い国ほど赤く、地名もその国で記事が多い都市の文字が大きくなるようにしています。ぜひ覗いてみてください。
 当サイトで海外旅ブログを執筆することも可能です(もちろん無料です)! また既にブログをお持ちの方も、当サイトからリンクを貼ることができるようになっています。パントレ開発部までお気軽にお問い合わせください。


 このページが皆様のプログラミングの一助となりますことをお祈りいたします

パントレ開発部