封装leaflet pm 地图打点标记组件

插件载入

    "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)
}

猜你喜欢

转载自blog.csdn.net/lzl980111/article/details/128591673
今日推荐