vue+leaflet示例:聚合图功能(附源码下载)
demo源码运行环境以及配置
- 运行环境:依赖Node安装环境,demo本地Node版本:14.19.1。
- 运行工具:vscode或者其他工具。
- 配置方式:下载demo源码,vscode打开,然后顺序执行以下命令:
(1)下载demo环境依赖包命令:npm i
(2)启动demo命令:npm run dev
(3)打包demo命令: npm run build:release
示例效果


本篇实现的思路:参考leaflet官网聚合效果插件Leaflet.markercluster:https://github.com/Leaflet/Leaflet.markercluster
这个聚合插件具体使用看github地址,那里有详细说明以及例子。
- 核心源码
<template>
<div id="map" ref="mapDiv"></div>
<div class="titleContainer center">
<span>vue+leaflet示例:聚合图功能</span>
</div>
</template>
<script setup>
import { onMounted, reactive, ref } from "vue";
import L from "leaflet";
import "leaflet.markercluster/dist/MarkerCluster.css";
import "leaflet.markercluster/dist/MarkerCluster.Default.css";
import "leaflet.markercluster";
import hgxPic from "@/assets/projectPoint_HGX.png";
import jsztPic from "@/assets/projectPoint_JSZT.png";
import xmxzPic from "@/assets/projectPoint_XMXZ.png";
import xmzsPic from "@/assets/projectPoint_XMZS.png";
// import config from "../config";
// import { useRouter } from "vue-router";
// const router = useRouter();
// const mapDiv = ref(null);
let map = null;
const geojson = {
type: "FeatureCollection",
features: [
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [113.16305738210656, 23.13667404697526],
},
properties: { Name_CHN: "赤岗塔", StationNum: 1, Status: 1 },
},
{
type: "Feature",
geometry: {
type: "Point",
coordinates: [113.10861400100009, 22.993978000000084],
},
properties: { Name_CHN: "魁奇路", StationNum: 14, Status: 2 },
},
……
……
],
};
onMounted(() => {
initMap();
});
const initMap = () => {
// 创建地图对象
map = L.map("map", {
attributionControl: false,
}).setView(L.latLng(22.95186415, 113.90271877), 9);
//创建底图切换数据源
const baseLayer = L.tileLayer(
"http://map.geoq.cn/ArcGIS/rest/services/ChinaOnlineStreetPurplishBlue/MapServer/tile/{z}/{y}/{x}",
{ crossOrigin: true }
);
map.addLayer(baseLayer); //地图默认加载的底图
//聚合图
const projectPointLayer = L.markerClusterGroup({
showCoverageOnHover: false,
zoomToBoundsOnClick: true,
chunkedLoading: true,
maxClusterRadius: 40, //默认80
}).addTo(map);
if (geojson) {
addProjectClusterLayers(geojson, projectPointLayer);
projectPointLayer.on("click", function (e) {
e.layer.unbindPopup();
const elements = getProjectPopupContent(e.layer.options.properties);
e.layer.bindPopup(elements).openPopup(e.latlng);
});
}
};
/*
* 点单击内容函数
*/
const getProjectPopupContent = (item) => {
// 内容及单击事件
const elements = `<div>
${toPopupItemStr("名称", item.Name_CHN)}
${toPopupItemStr("站口个数", item.StationNum)}
</div>`;
return elements;
};
const toPopupItemStr = (name, value) => {
return value ? `<b>${name}:</b>${value}<br>` : "";
};
/*
* 加载聚合图层
*/
const addProjectClusterLayers = async (geojson, clusterlayer) => {
let markerList = [];
if (geojson.features.length > 0) {
for (let i = 0; i < geojson.features.length; i++) {
if (geojson.features[i].geometry) {
const properties = geojson.features[i].properties;
const coordinate = geojson.features[i].geometry.coordinates;
//根据Status类型不同加载不同图标
let img = hgxPic;
switch (properties.Status) {
case 1:
img = hgxPic;
break;
case 2:
img = jsztPic;
break;
case 3:
img = xmxzPic;
break;
case 4:
img = xmzsPic;
break;
}
const myIcon = L.icon({
iconUrl: img,
iconSize: [25, 25],
});
const marker = L.marker(new L.LatLng(coordinate[1], coordinate[0]), {
properties: properties,
icon: myIcon,
});
markerList.push(marker);
}
}
}
clusterlayer.addLayers(markerList);
};
</script>
<style scoped>
#map {
width: 100vw;
height: 100vh;
}
.titleContainer {
position: absolute;
top: 0;
background: rgba(0, 0, 0, 0.45);
height: 50px;
width: 100vw;
z-index: 999;
font-size: 14px;
color: #fff;
font-size: 28px;
}
.center {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
}
</style>
下载源码:GIS之家的学习交流圈
GIS之家作品店铺:GIS之家作品店铺
GIS之家源码咨询:GIS之家webgis入门开发系列demo源代码咨询
扫码关注GIS之家微信公众号,回复“gis”可免费获取地图数据以及arcgis系列安装包等资源
GIS之家源码咨询:GIS之家webgis入门开发系列demo源代码咨询
扫码关注GIS之家微信公众号,回复“gis”可免费获取地图数据以及arcgis系列安装包等资源

浙公网安备 33010602011771号