看過的知識不等于學會。唯有用心總結、系統記錄,并通過溫故知新反復實踐,才能真正掌握一二
作為一名摸爬滾打三年的前端開發,開源社區給了我飯碗,我也將所學的知識體系回饋給大家,助你少走彎路!
OpenLayers、Leaflet 快速入門 ,每周保持更新 2 個案例
Cesium 快速入門,每周保持更新 4 個案例
Leaflet 綜合案例-聚類圖層控制
Vue 3 + Leaflet 實現的 WebGIS 應用提供了完整的聚類圖層控制功能
主要功能
MP4效果動畫鏈接地址
技術棧
該環境下代碼即拿即用
Vue 3.5.13+
Leaflet 1.9.4
Vite 6.3.5+
插件
使用 Leaflet 插件 Leaflet.markercluster 實現聚類圖層
npm install leaflet.markercluster
<template><div class="map-wrapper"><div id="map-cluster" class="map-container"></div></div>
</template><script setup>
import { onMounted, onUnmounted } from "vue";
import "leaflet/dist/leaflet.css";
import "leaflet.markercluster/dist/MarkerCluster.css"; // 聚合插件的CSS
import "leaflet.markercluster/dist/MarkerCluster.Default.css"; // 聚合插件默認主題CSS
import L from "leaflet";
import "leaflet.markercluster"; // 引入聚合插件JSlet map = null;
let markers = null;const initialView = [39.909186, 116.397479];
const initialZoom = 10; // 初始縮放級別稍微小一點,更容易看到聚合效果onMounted(() => {map = L.map("map-cluster").setView(initialView, initialZoom);L.tileLayer("https://webrd01.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}",{maxZoom: 18,minZoom: 3,attribution: '© <a href="https://www.amap.com/">高德地圖</a>',}).addTo(map);// 創建一個標記點聚合圖層markers = L.markerClusterGroup();// 隨機生成1000個標記點const dummyMarkers = [];for (let i = 0; i < 1000; i++) {const lat = 39.909186 + (Math.random() - 0.5) * 0.5; // 在中心點附近隨機生成const lng = 116.397479 + (Math.random() - 0.5) * 0.5;const marker = L.marker([lat, lng]).bindPopup(`標記點 ${i + 1}`);dummyMarkers.push(marker);}// 將所有標記點添加到聚合圖層markers.addLayers(dummyMarkers);map.addLayer(markers);// 調整地圖視圖以適應所有標記點(可選,如果標記點范圍很大)// map.fitBounds(markers.getBounds());
});onUnmounted(() => {if (map) {map.remove();map = null;markers = null;}
});const resetMapView = () => {if (map) {map.setView(initialView, initialZoom);}
};
</script><style scoped>
/* 樣式與上一個案例類似,確保布局一致 */
.map-wrapper {display: flex;flex-direction: column;height: 100vh;width: 100vw;font-family: sans-serif;box-sizing: border-box;
}@media (min-width: 768px) {.map-wrapper {flex-direction: row;}
}.map-container {flex-grow: 1;height: 100%;min-height: 300px;background-color: #e0e0e0;
}
</style>