【Leaflet】HTML/CSS をつかってマーカーを描画する

はじめに
Leaflet ではデフォルトでマーカーの画像が登録されていますが、HTML や CSS を使ってマーカーを描画をすることも可能です。そこで今回は、HTML/CSS を使ったマーカーの描画方法について説明したいと思います。
パントレ
なお、この記事は「【Leaflet入門】地図を表示する方法と基本的な使い方」の続きです。
HTML(Font Awesome)をつかう
HTML/CSS を使ってマーカーを描画するには、divIcon を使います。
L.marker([緯度,経度], {
icon: L.divIcon({
html: 'HTMLタグ',
className:'適用クラス名',
iconSize: [0, 0]
}),
}).addTo(map);
ここでは、HTML 要素として Font Awesome を指定してみましょう。Font Awesome とは、数千個ものアイコンが登録してある、特に有名なウェブフォントです。
例えば、以下のようにマーカーの設定をします。なお、iconSize をゼロにしていますが、このようにすることで疑似要素(before や after)で指示した範囲のみをマーカーとして機能させることができます。
L.marker([緯度, 経度], {
icon: L.divIcon({
//Font Awesomeの埋め込みコード
html:'<i class="fas fa-plane-departure fa-2x"></i>',
//アイコンの色と位置を設定するためのCSS
className:'color_palette solid_icon',
iconSize: [0, 0]
}),
}).addTo(map);
html の部分に Font Awesome の埋め込みコードを記述しており、また className に2つのクラス color_palette と solid_icon を使って、マーカーの色と位置を設定できるように、CSS を定義しておきます。
.color_palette{
background-color:#333333;
color:#333333;
border-color:#333333;
}
.solid_icon{
position:absolute;
background-color:none;
color:none;
}
.solid_icon > i{
position:absolute;
top:-0.5em;
left:-0.5em;
}
全体のソースコードと実装例は以下の通りです。
<!DOCTYPE html>
<html>
<head>
<title>htmlMap</title>
<meta http-equiv='content-type' charset='utf-8'>
<meta name='viewport' content='width=device-width'>
<style>
.color_palette{background-color:#333333; color:#333333; border-color:#333333;}
.solid_icon{position:absolute; background-color:none; color:none;}
.solid_icon > i{position:absolute; top:-0.5em; left:-0.5em;}
</style>
</head>
<body>
<!-- 埋め込みマップのdivタグ。マップサイズはwidth(幅)とheight(高さ)で決まる -->
<div id='mapcontainer' style='width:100%; height:300px; z-index:0;'></div>
<!-- 以下LeafletのJavaScriptとCSS -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<!-- ダウンロードしたFont Awesomeへのファイルパス -->
<link href="css/font-awesome.min.css" rel="stylesheet">
<script>
function init_map() {
const map = L.map('mapcontainer');
//初期の中心位置とズームレベルを設定
map.setView([39.198, 138.603], 3);
//マップタイルを読み込み、引用元を記載する
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{attribution: "<a href='http://osm.org/copyright'> ©OpenStreetMap </a>"}
).addTo(map);
//マーカーの配置
L.marker([35.301, 136.138], {
icon: L.divIcon({
//Font Awesomeの埋め込みコード
html:'<i class="fas fa-plane-departure fa-2x"></i>',
//アイコンの色と位置を設定するためのCSS
className:'color_palette solid_icon',
iconSize: [0, 0]
}),
}).addTo(map);
}
//ダウンロード時に初期化する
window.addEventListener('DOMContentLoaded', init_map());
</script>
</body>
</html>
実装例
CSS をつかう
独自の CSS のみを使ってマーカーを描画するには、divIcon の html 欄を空にするだけです。
L.marker([緯度,経度], {
icon: L.divIcon({
html: '',
className:'color_palette solid_marker_icon',
iconSize: [0, 0]
}),
}).addTo(map);
CSS のクラス、solid_marker_icon は以下のように設定しています。color_palette は前項と同じものなので割愛します。
.solid_marker_icon{
position:absolute;
}
.solid_marker_icon:before{
content:'';
position:absolute;
width:18px;
height:18px;
left:-9px;
top:-22px;
border:solid 1px;
background:currentColor;
border-radius:10px 10px 10px 0;
-webkit-transform:rotate(-45deg);
-ms-transform:rotate(-45deg);
transform:rotate(-45deg);
box-sizing:content-box;
}
.solid_marker_icon:after{
content:'';
position:absolute;
left:-3px;
top:-16px;
width:8px;
height:8px;
background-color:rgba(255, 255, 255, 0.7);
border-radius:4px;
}
全体のソースコードと実装例は以下の通りです。
<!DOCTYPE html>
<html>
<head>
<title>htmlMap</title>
<meta http-equiv='content-type' charset='utf-8'>
<meta name='viewport' content='width=device-width'>
<style>
.solid_marker_icon{position:absolute;}
.solid_marker_icon:before{content:''; position:absolute; width:18px; height:18px; left:-9px; top:-22px; border:solid 1px; background:currentColor; border-radius:10px 10px 10px 0; -webkit-transform:rotate(-45deg); -ms-transform:rotate(-45deg); transform:rotate(-45deg); box-sizing:content-box;}
.solid_marker_icon:after{content:''; position:absolute; left:-3px; top:-16px; width:8px; height:8px; background-color:rgba(255, 255, 255, 0.7); border-radius:4px;}
.color_palette{background-color:#333333; color:#333333; border-color:#333333;}
</style>
</head>
<body>
<!-- 埋め込みマップのdivタグ。マップサイズはwidth(幅)とheight(高さ)で決まる -->
<div id='mapcontainer' style='width:100%; height:300px; z-index:0;'></div>
<!-- 以下LeafletのJavaScriptとCSS -->
<link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" integrity="sha256-p4NxAoJBhIIN+hmNHrzRCf9tD/miZyoHS5obTRR9BMY=" crossorigin=""/>
<script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" integrity="sha256-20nQCchB9co0qIjJZRGuk2/Z9VM+kNiyxNV1lvTlZBo=" crossorigin=""></script>
<script>
function init_map() {
const map = L.map('mapcontainer');
//初期の中心位置とズームレベルを設定
map.setView([35.8623, 139.9218], 6);
//マップタイルを読み込み、引用元を記載する
L.tileLayer('http://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
{attribution: "<a href='http://osm.org/copyright'> ©OpenStreetMap </a>"}
).addTo(map);
//マーカーの配置
L.marker([35.6807,139.7671], {
icon: L.divIcon({
html: '',
className:'color_palette solid_marker_icon',
iconSize: [0, 0]}),
}
).on('contextmenu', function(e){
/*右クリック(もしくは長押し)で Google Maps を起動する*/
window.open( "https://www.google.co.jp/maps/place/"+e.latlng.lat+","+e.latlng.lng+"/@"+e.latlng.lat+","+e.latlng.lng+",15z/data");
}).addTo(map);
}
//ダウンロード時に初期化する
window.addEventListener('DOMContentLoaded', init_map());
</script>
</body>
</html>
実装例
関連記事
GUI で Leaflet の HTML/JavaScript を生成するツールはこちら。コード書くのがめんどくさいな~って人は使ってみてください。WordPress の場合、生成されたコードをカスタム HTML に貼り付ければ動きます。今回の記事の CSS アイコン、Font Awesome にも対応しています。
Leaflet、MapLibre、OpenLayers の比較はこちら。
MapLibre についてはこちら。
ちょっと宣伝
当サイトは Web 地図を積極的に用いた海外旅ブログまとめサイトとなっています。トップページに地図がありますが、地名を押すと画像が開き、画像を押すと関連記事一覧(クリック数順)が開きます。記事数が多い国ほど赤く、地名もその国で記事が多い都市の文字が大きくなるようにしています。ぜひ覗いてみてください。
当サイトで海外旅ブログを執筆することも可能です(もちろん無料です)! また既にブログをお持ちの方も、当サイトからリンクを貼ることができるようになっています。パントレ開発部までお気軽にお問い合わせください。
このページが皆様のプログラミングの一助となりますことをお祈りいたします
パントレ開発部