##はじめに
地図ライブラリ「Leaflet」のマーカー(アイコン)を標準のマーカーからカスタムのものに変更するのに Canvas API を使う例を紹介します。
※Firefox Quantum 68 と Gooogle Chrome 71 で検証しました。
##Canvas API を使おうと考えた背景
「Leaflet」のマーカーを変更する方法を検索すると、およそ、
- アイコンの画像ファイルを用意する方法
- プラグインを使用する方法
- CSS を使用する方法
がヒットします。
私は手元の1個の html ファイルだけを編集してマーカーを変更する方法を模索していて、上記の中では 3. が該当します。
しかし、Canvas API を使えば 1. の方法の応用としても目的を果たせるのではないかと考えました。
##表示例
See the Pen qedbEV by HideakiAnnaka (@HideakiAnnaka) on CodePen.
##コード例
要点としては、
- Canvas API でマーカーとなるアイコンの画像を描画
- HTMLCanvasElement.toDataURL() メソッドで 1. の画像を表す DataURL を取得
- Leaflet で地図を表示し、2. の DataURL をマーカーのアイコンの画像として指定
の 3 点になります。
sample.htm
<!DOCTYPE html>
<html>
<head>
<meta charset='UTF-8'>
<title>地図ライブラリ「Leaflet」のマーカー(アイコン)を変更するのに Canvas API を使う</title>
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.5.1/dist/leaflet.css"
integrity="sha512-xwE/Az9zrjBIphAcBb3F6JVqxf46+CDLwfLMHloNu6KEQCAWi6HcDUbeOfBIptF7tcCzusKFjFw2yuvEpDL9wQ=="
crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.5.1/dist/leaflet.js"
integrity="sha512-GffPMF3RvMeYyc1LWMHtK8EbPv0iNZ8/oTtHPx9/cc2ILxQ+u905qIwdpULaqDkyBKgOaB57QTMg7ztg8Jm2Og=="
crossorigin=""></script>
<style>
#canvas {
display:none;
}
#mapid {
width: 90vw;
height: 90vh;
}
</style>
</head>
<body>
<canvas id='canvas' width='25' height='41'></canvas>
<div id="mapid"></div>
</body>
<script>
{
window.addEventListener('load', (event) => {
init();
});
const init = () => {
let canvasIconUrl = getCanvasIconUrl();
let mymap = L.map('mapid').setView([35.360628, 138.727365], 12);
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>"
}).addTo(mymap);
const myIcon= L.icon({
iconUrl: canvasIconUrl,
shadowUrl: 'https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/images/marker-shadow.png',
iconSize: [25, 41],
shadowSize: [41, 41],
iconAnchor: [12.5, 41],
popupAnchor: [0, -50],
});
L.marker([35.360628, 138.727365], {icon: myIcon}).addTo(mymap)
.bindPopup('Canvas で描画したマーカーです。');
}
const getCanvasIconUrl = () => {
const canvas = document.getElementById('canvas');
if (canvas.getContext) {
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(12.5, 12.5, 12.5, (Math.PI / 180) * 30, (Math.PI / 180) * 150, true);
ctx.lineTo(12.5, 41);
ctx.closePath();
ctx.fillStyle = 'rgb(255, 102, 102)';
ctx.fill();
ctx.beginPath();
ctx.arc(12.5, 12.5, 12, (Math.PI / 180) * 30, (Math.PI / 180) * 150, true);
ctx.lineTo(12.5, 40.5);
ctx.closePath();
ctx.strokeStyle = 'rgb(102, 0, 51)';
ctx.lineWidth = '1';
ctx.stroke();
ctx.beginPath();
ctx.arc(12.5, 12.5, 5, (Math.PI / 180) * 0, (Math.PI / 180) * 360, true);
ctx.closePath();
ctx.fillStyle = 'rgb(102, 0, 51)';
ctx.fill();
return canvas.toDataURL();
}
else {
return "https://cdnjs.cloudflare.com/ajax/libs/leaflet/1.5.1/images/marker-icon.png";
}
}
}
</script>
</html>
##参考記事
- [公式]Quick Start Guide - Leaflet - a JavaScript library for interactive maps
- [公式]Markers With Custom Icons - Leaflet - a JavaScript library for interactive maps
- canvas に図形を描く - 開発者ガイド | MDN
- HTMLCanvasElement.toDataURL() - Web APIs | MDN
- Leafletの使い方|オープンソースWeb地図ライブラリ|谷謙二研究室
- Leafletのマーカーを変更する - Qiita
- 自作地図: leafletで使えるおすすめプラグインまとめ - Qiita
- Leaflet.js:マーカーのデザインをCSSで変える - データを追いかけるイヌ