地図にマーカーを100件、200件と表示していくと、次のような問題が発生します。
- ピンが密集して視認性が悪い
- ズームやスクロールで重くなる
- 目的地が探しづらい
Leaflet.markercluster は以下を自動で行い、これらを解決します。
- 近いマーカーを「ひとまとまり(クラスタ)」にする
- ズームインすると自動で細かく分解
- 大量マーカーでも高速でスムーズに動く
Contents
CDN版の導入手順
ここではCDN版の導入手順をご紹介します。
head要素にCDNを追加
HTML の <head> に以下を追加します。
HTML
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster/dist/MarkerCluster.css" />
<link rel="stylesheet" href="https://unpkg.com/leaflet.markercluster/dist/MarkerCluster.Default.css" />
<script src="https://unpkg.com/leaflet.markercluster/dist/leaflet.markercluster.js"></script>地図の初期化
JavaScript
const map = L.map("map", {
center: [35.68, 139.76],
zoom: 11,
});
L.tileLayer("https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png", {
attribution: "© OpenStreetMap contributors",
}).addTo(map);クラスタレイヤーの作成
JavaScript
const markerClusterGroup = L.markerClusterGroup();
map.addLayer(markerClusterGroup);マーカーをクラスタに追加する
JavaScript
const ALL_PARKS = [
{ id: 1, name: "中央公園", lat: 35.689, lng: 139.700 },
{ id: 2, name: "西公園", lat: 35.665, lng: 139.730 },
// ... 最大数千件まで対応
];
const MAX_MARKERS = 1000; // 任意
const parksForMap = ALL_PARKS.slice(0, MAX_MARKERS);
parksForMap.forEach((park) => {
if (!park.lat || !park.lng) return;
const marker = L.marker([park.lat, park.lng]);
marker.bindPopup(
"<strong>" + park.name + "</strong><br>" +
'<a href="/park/' + park.id + '/">詳細を見る</a>'
);
markerClusterGroup.addLayer(marker);
});MarkerClusterを使ってみてわかったこと
クラスタリング導入で得られたメリット
- 地図が重くならずサクサク動く
- ピンの密集がクラスタとして見えるので視認性向上
- 既存コードにほぼ手を加えず導入可能
- APIアクセスが増えずバックエンドに優しい
導入時の注意点
- 初期表示はややズームアウトしてクラスタが見える状態にする
- パフォーマンスのために最大マーカー数を設定することも可能
- カード連動(クリック・フォーカス)はID管理で簡単に実現可能
- データが非常に増えたら「地図範囲絞り API」方式へ移行もできる
まとめ
Leaflet.markercluster を使えば、大量のマーカーを美しく・高速に・ストレスなく表示できます。
- 完全無料
- 高速
- 見やすい
- 導入が簡単
- API負荷なし
地図アプリを作るなら、絶対に押さえておきたい強力なテクニックです。
コメント