MapBox GL のサンプルにカスタムマーカーがあるので、それを参考に「ラベル付きのマーカー」を実現してみた。
動作するサンプルはこちら。
ソースコード
index.html
<!DOCTYPE html>
<html>
<head>
<meta charset='utf-8' />
<title></title>
<meta name='viewport' content='initial-scale=1,maximum-scale=1,user-scalable=no' />
<link href="https://fonts.googleapis.com/css?family=Open+Sans" rel="stylesheet">
<script src='https://api.tiles.mapbox.com/mapbox-gl-js/v1.8.0/mapbox-gl.js'></script>
<link href='https://api.tiles.mapbox.com/mapbox-gl-js/v1.8.0/mapbox-gl.css' rel='stylesheet' />
<link rel="stylesheet" type="text/css" href="./index.css" media="screen">
<style>
</style>
</head>
<body>
<div id='map'></div>
<template id="marker">
<div class="marker-container">
<span id="title" class="marker-title"></span>
<img id="marker-icon" src="https://img.icons8.com/ios-filled/40/0000FF/marker.png">
</div>>
</template>
<script src="./index.js"></script>
</body>
</html>
index.css
body {
margin: 0;
padding: 0;
}
#map {
position: absolute;
top: 0;
bottom: 0;
width: 100%;
}
.marker-container {
display: flex;
flex-direction: column;
align-items: center;
cursor: pointer;
}
.marker-title {
max-width: 100px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.marker-icon {
height: 30px;
width: auto;
background-size: cover;
}
.mapboxgl-popup {
max-width: 200px;
}
.mapboxgl-popup-content {
text-align: center;
font-family: 'Open Sans', sans-serif;
}
index.js
const geojson = {
type: 'FeatureCollection',
features: [{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-77.032, 38.913]
},
properties: {
title: 'Mapbox',
description: 'Washington, D.C.'
}
},
{
type: 'Feature',
geometry: {
type: 'Point',
coordinates: [-122.414, 37.776]
},
properties: {
title: 'Mapbox',
description: 'San Francisco, California'
}
}]
};
const map = new mapboxgl.Map({
container: 'map',
center: [-96, 37.8],
zoom: 3,
style: {
"version": 8,
"sources": {
"OSM": {
"type": "raster",
"tiles": ['http://a.tile.openstreetmap.org/{z}/{x}/{y}.png'],
"tileSize": 256
}
},
"layers": [{
"id": "OSM",
"type": "raster",
"source": "OSM"
}]
}
});
geojson.features.forEach(marker => {
// Create element for marker from template
const template = document.getElementById('marker');
const clone = document.importNode(template.content, true);
const el = clone.firstElementChild;
clone.getElementById('title').innerHTML = marker.properties.description;
new mapboxgl.Marker(el, { anchor: 'bottom' })
.setLngLat(marker.geometry.coordinates)
.setPopup(new mapboxgl.Popup({ offset: 60, anchor: 'bottom' }) // add popups
.setHTML('<h3>' + marker.properties.title + '</h3><p>' + marker.properties.description + '</p>'))
.addTo(map);
});
- マーカーとして使用する HTML 要素を
template
タグで用意しておきます。 - マーカーごとに
template
から要素を生成(importNode
で複製しないと同じ要素が使い回されるので注意)してラベルを設定、その要素から MapBox の Marker を生成します。
※地図を OpenStreetMaps にしているのは、MapBox の地図を表示するには AccessToken を設定する必要があるためです。