插件载入
"leaflet": "^1.8.0",
"leaflet-canvas-markers": "^1.0.7",
"leaflet-markers-canvas": "^0.2.2",
"geojson": "^0.5.0",
封装代码
<template>
<div class="main">
<div ref="mapRef" class="map"></div>
</div>
</template>
<script setup name="retailMap">
import Leaflet, { LatLng, Layer, LayerGroup } from "leaflet";
import "leaflet/dist/leaflet.css";
import "@geoman-io/leaflet-geoman-free";
import "@geoman-io/leaflet-geoman-free/dist/leaflet-geoman.css";
import "leaflet-markers-canvas";
const { proxy } = getCurrentInstance();
/**
* @desc latlng传递{lat:30.123,lng:120.321}经纬对象
*/
const props = defineProps({
latlng:{
type:Object,
default:null
}
});
watch(props,(newV,oldV)=>{
if(newV.latlng && newV.latlng.lat && newV.latlng.lng)
setMarker(newV.latlng.lat,newV.latlng.lng);
else
setMarker(null,null);
})
const marker = ref(null);
const setMarker = (lat,lng)=>{
if(lat && lng){
if(marker.value)
map.value.removeLayer(marker.value);
map.value.setView([lat, lng]);
marker.value = Leaflet.marker([lat, lng]).addTo(map.value)
map.value.pm.disableDraw('Marker')
} else {
map.value.removeLayer(marker.value);
}
}
const emits = defineEmits(["update:latlng"]);
const mapRef = ref(null);
const mapLayers = {
gridLayer:Leaflet.layerGroup(),
}
const map = ref(null);
const initMap = () => {
if (!mapRef.value) {
throw new Error("元素不存在");
}
let center = [37.515611,121.227439]
if(props.latlng && props.latlng.lat && props.latlng.lng){
center = [props.latlng.lat,props.latlng.lng];
}
map.value = Leaflet.map(mapRef.value, {
center: center,
zoom: 12,
zoomControl: false,
}).setMaxBounds([
[-90, 0],
[90, 360],
]);
if(props.latlng && props.latlng.lat && props.latlng.lng){
setMarker(props.latlng.lat,props.latlng.lng);
}
map.value.pm.addControls({
position: "topleft",
drawPolygon: false, // 绘制多边形
drawMarker: true, //绘制标记点
drawCircleMarker: false, //绘制圆形标记
drawPolyline: false, //绘制线条
drawRectangle: false, //绘制矩形
drawCircle: false, //绘制圆圈
drawText:false, // 绘制文本
editMode: false, //编辑多边形
dragMode: false, //拖动多边形
cutPolygon: false, // 添加一个按钮以删除多边形里面的部分内容
removalMode: false // 清除多边形
})
map.value.pm.setLang('zh')
map.value.on('pm:create', e => {
proxy.$modal.confirm('确认当前标记点?').then(res=>{
if(marker.value){
map.value.removeLayer(marker.value)
}
// if (e.shape == 'Marker') { //返回的e中有其边框经纬度,形状等信息
// }
marker.value = e.marker
emits('update:latlng',e.layer._latlng)
})
})
map.value.attributionControl.setPrefix(false);
// 加入地图底图控制
const layers = {
高德街道地图: Leaflet.tileLayer(
"https://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scl=1&style=8&x={x}&y={y}&z={z}",
{
maxZoom: 20,
maxNativeZoom: 18,
minZoom: 7,
attribution: "高德街道地图",
subdomains: "1234",
}
).addTo(map.value),
// 谷歌高德杂交/卫星
谷歌卫星地图: Leaflet.layerGroup([
// lyrs=y为底图+路图混合,lyrs=s为底图,lyrs=t为地形图,lyrs=m为矢量图
Leaflet.tileLayer(
"https://map1.aikenong.com.cn/maps/vt/lyrs=y&hl=zh-CN&gl=cn&scale=2&src=app&x={x}&y={y}&z={z}&s=Galil",
{
maxZoom: 20,
minZoom: 3,
attribution: "谷歌卫星地图",
}
),
]),
};
// 加入图层控制器
Leaflet.control
.layers(
layers,
{},
{
position: "bottomright",
collapsed: true,
}
)
.addTo(map.value);
// 加入缩放控制器
Leaflet.control
.zoom({
zoomInTitle: "放大",
zoomOutTitle: "缩小",
})
.addTo(map.value);
map.value.addEventListener("dragend", handleMapMove);
map.value.addEventListener("zoomend", handleMapMove);
mapLayers.gridLayer.addTo(map.value);
};
const handleMapMove = ()=>{
proxy.debounce(()=>{
console.log('处理地图移动')
},1000)
}
onMounted(()=>{
setTimeout(() => {
initMap();
}, 200);
})
</script>
<style lang='scss' scoped>
.main{
height:100%;
width:100%;
.map{
width:100%;
height:100%;
.map-search{
position: absolute;
z-index: 999;
top: 10px;
left: 55px;
}
.map-filter{
position: absolute;
z-index: 999;
top: 10px;
right: 10px;
}
}
}
::v-deep .el-input__wrapper{
border:1px solid #ccc;
}
</style>
proxy封装的防抖方法
// 防抖函数
let timer
export function debounce (fn, delay) {
if (timer) {
clearTimeout(timer)
}
timer = setTimeout(() => {
fn()
}, delay)
}