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

Posted 黑胡子大叔的小屋

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了封装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://webrd0s.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)

以上是关于封装leaflet pm 地图打点标记组件的主要内容,如果未能解决你的问题,请参考以下文章

React-Leaflet将绘图列表映射到标记

从 API 加载 geoJSON 标记 - React Leaflet

Leaflet.js 将地图集中在一组标记上

在 Openstreet 地图上移动标记 - Leaflet API

React-Leaflet在地图上绘制圆圈标记

R语言在线地图神器:Leaflet for R包 符号标记