点聚合
使用 Leaflet.markercluster
插件实现,仓库地址。
示例
安装依赖
shell
pnpm install leaflet.markercluster
# ts 项目需要安装类型文件
pnpm install @types/leaflet.markercluster
在项目中引入
js
import "leaflet.markercluster";
import "leaflet.markercluster/dist/MarkerCluster.Default.css";
import "leaflet.markercluster/dist/MarkerCluster.css";
代码实现
vue
<script setup>
import { ref, defineAsyncComponent } from 'vue';
import 'leaflet'
import 'leaflet.markercluster';
import 'leaflet.markercluster/dist/MarkerCluster.Default.css';
import 'leaflet.markercluster/dist/MarkerCluster.css';
const InitMap = defineAsyncComponent(() =>
import('../../components/InitMapTianditu.vue')
);
const mapObj = ref();
const markerLayerGroup = ref();
// 清除图层组图层
const clearMarkerLayerGroup = () => {
if (markerLayerGroup.value) {
mapObj.value.removeLayer(markerLayerGroup.value);
markerLayerGroup.value = null;
}
};
// 创建多个 marker
const createMarkers = () => {
// 加载前先清除
clearMarkerLayerGroup();
// 创建点聚合图层
markerLayerGroup.value = L.markerClusterGroup();
const points = [
[32.0148855, 118.8276675],
[32.0138855, 118.8477675],
[32.0138855, 118.8678675],
[32.0138855, 118.8979675],
[32.0148855, 118.8989675],
[32.0148855, 118.8969675],
[32.0148855, 118.8979675],
[32.0148855, 118.8989675]
];
points.forEach((item) => {
// 创建自定义图标
const icon = L.icon({
iconUrl: '/logo.png',
iconSize: [30, 30]
});
const marker = L.marker(item, { icon });
// 添加
markerLayerGroup.value.addLayers(marker);
});
// 为每个 marker 绑定 popup
markerLayerGroup.value.bindPopup('<b>Hello world!</b><br />marker');
// 绑定 marker 点击事件
markerLayerGroup.value.on('click', (e) => {
console.log('marker 触发点击事件', e);
});
// 绑定聚合点点击事件
markerLayerGroup.value.on('clusterclick', (e) => {
console.log('点击聚合点触发点击事件', e);
});
// 将图层组加载到地图
markerLayerGroup.value.addTo(mapObj.value);
};
const mapLoad = (map) => {
mapObj.value = map;
createMarkers();
};
</script>
<template>
<init-map @map-load="mapLoad"></init-map>
</template>
<style scoped></style>
vue
<script setup>
import { onMounted, onUnmounted, ref } from 'vue';
import L from 'leaflet';
const props = defineProps({
center: {
type: Array,
default: [32.0237855, 118.8075675]
}
})
const emit = defineEmits(['mapLoad']);
const mapRef = ref();
const initMap = () => {
const map = L.map(mapRef.value, {
center: props.center,
zoom: 11,
minZoom: 1,
maxZoom: 18
});
const mapType = 'vec';
L.tileLayer(
'https://t{s}.tianditu.gov.cn/' +
mapType +
'_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=' +
mapType +
'&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=b72aa81ac2b3cae941d1eb213499e15e',
{
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
attribution:
'© <a href="http://lbs.tianditu.gov.cn/home.html">天地图 GS(2022)3124号 - 甲测资字1100471</a>'
}
).addTo(map);
const mapLabelType = 'cva';
L.tileLayer(
'https://t{s}.tianditu.gov.cn/' +
mapLabelType +
'_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=' +
mapLabelType +
'&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILECOL={x}&TILEROW={y}&TILEMATRIX={z}&tk=b72aa81ac2b3cae941d1eb213499e15e',
{
subdomains: ['0', '1', '2', '3', '4', '5', '6', '7']
}
).addTo(map);
// 地图初始化完成发送事件
emit('mapLoad', map);
return map;
};
const mapObj = ref();
// 在 onMounted 中初始化地图
onMounted(() => {
mapObj.value = initMap();
});
const removeMap = () => {
if (mapObj.value) {
mapObj.value.remove();
}
};
// 在组件卸载时删除地图
onUnmounted(() => {
removeMap();
});
</script>
<template>
<div ref="mapRef" class="map"></div>
</template>
<style scoped>
.map {
height: 40vh;
z-index: 0;
}
</style>