vue3封装leaflet并使用高德底图

该组件配置了高德和腾讯地图的底图。具有新建图层和打点(使用leaflet中的方法),打点分为单个和多个。经纬度和详细地址的互相转换由高德api完成。

<template>
  <div class="container">
    <!-- 搜索框 -->
    <div class="module-top">
      <el-input  v-model="modelValue" placeholder="" style="width: 100%;" @input="onInput"/> 
    </div>
    <!-- 工具栏 -->
    <div class="module-tools">
      <div class='tools-box'>
        <button @click="onClickMark(1)">打点-单个</button>
        <button @click="onClickMark(2)">打点-多个</button>
        <button @click="onClearLayer">清空</button>
      </div>
    </div>

    <div ref="mapLeafletRef" class="map"></div>
  </div>
  <!-- <button @click="onClearLayer">btn</button> -->
</template>
<script setup>
import L from 'leaflet';
import AMapLoader from '@amap/amap-jsapi-loader';
import { onMounted, onUnmounted, ref, getCurrentInstance, watch } from 'vue';
window._AMapSecurityConfig = {  // 高德安全密钥
  securityJsCode: '申请的高德安全密钥',
};
const props = defineProps({
  mapType: {  // 地图底图,高德、腾讯
    type: String,
    default: () => {
      return 'gaode';
    }
  }
});
watch(() => props, (newV, oldV) => {
  console.log(newV, 'new', oldV, 'old');
}, {
  immediate: true
});
const emits = defineEmits(['doRefreshMap']);
const mapObj = ref(); // leaflet对象
const mapLeafletRef = ref(null); //
const mapGaode = ref(null); // 高德
const modelValue = ref('');
const geocoder = ref(null); // 经纬度解析obj
const layerGroup = ref(null);
const autocomplete = ref(null);
const gaodeMapOption = ref({
  url: 'http://webrd0{s}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',
  option: {
    subdomains: '1234'
  }
});
const tencentMapOption = ref({
  url: 'http://rt{s}.map.gtimg.com/realtimerender?z={z}&x={x}&y={y}&type=vector&style=0',
  option: {
    subdomains: '0123',
    tms: true
  }
});
// 初始化地图:leaflet
const initMap = () => {
  let mapOption = {};
  if (props.mapType === 'gaode') {
    mapOption = gaodeMapOption.value;
  } else if (props.mapType === 'tengxun') {
    mapOption = tencentMapOption.value;
  }
  const map = L.map(mapLeafletRef.value, {
    center: [39.90887, 116.397435],
    zoom: 11,
    minZoom: 6,
    maxZoom: 20,
    zoomControl: true,  //是否启用地图缩放控件
    attributionControl: false,  是否启用地图属性控件
  });
  L.tileLayer(  // 给leaflet添加瓦片底图
    mapOption.url, mapOption.option
  ).addTo(map);
  // 绑定leaflet的click点击事件
  map.on('click', (evt) => {
    mapClick([evt.latlng.lat, evt.latlng.lng]);
  });
  // 创建图层并添加至地图
  layerGroup.value = L.layerGroup();
  layerGroup.value.addTo(map);
  return map;
};
const initMapGaode = () => {
  AMapLoader.load({
    key: '申请的高德key', // 申请好的Web端开发者Key,首次调用 load 时必填
    plugins: ['AMap.Scale', 'AMap.Autocomplete', 'AMap.PlaceSearch'], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
    AMapUI: {
      version: '1.1',
    },
  }).then((AMap) => {
    mapGaode.value = AMap;
    geocoder.value = new AMap.Geocoder({  // 经纬度解析
      city: '010', // 城市设为北京,默认:“全国”
      radius: 1000, // 范围,默认:500
    });
    const autoOptions = {
      city: '全国'
    };
    autocomplete.value = new AMap.Autocomplete(autoOptions);
  }).catch((e) => {
    console.log(e, 'catch');
  });
};
const marker = ref([]);
const mapClick = (e) => { // leaflet的点击方法
  // onClearLayer();
  marker.value = L.marker(e);
  layerGroup.value.addLayer(marker.value);
  regeoCode([e[1], e[0]]);
};
const regeoCode = (e) => {  // 经纬度转换成详细地址
  geocoder.value.getAddress(e, (status, result) => {
    if (status === 'complete' && result.regeocode) {
      let address = result.regeocode.formattedAddress;
      console.log(address, '---address');
      emits('doRefreshMap', address);
    } else {
      console.log('根据经纬度查询地址失败');
    }
  });
};
const onClearLayer = () => {  // 清除全部图层上的内容
  layerGroup.value.clearLayers();
};
const onInput = (e) => {  //input监听输入
  //console.log(e, '--e');
  autocomplete.value.search(e, (status, result) => {
    // 搜索成功时,result即是对应的匹配数据
    console.log(result, '---result');
  });
};

const removeMap = () => {
  if (mapObj.value) {
    mapObj.value.remove();
  }
};
const show = (e) => {
  console.log('111');
};
const markNumSingle = ref(true);
const onClickMark = (e) => {
  if (e === 1) {
    markNumSingle.value = true;
  } else {
    markNumSingle.value = false;
  }
};
defineExpose({
  onClearLayer
});
onMounted(() => {
  mapObj.value = initMap();
  initMapGaode();
});


// 在组件卸载时删除地图
onUnmounted(() => {
  removeMap();
});
</script>


<style scoped lang="scss">
.map {
  height: 100%;
  width: 100%;
  z-index: 0;
}
.map2 {
  height: 40vh;
  z-index: 0;
}
.container {
  height: 50vh;
  position: relative;
  .module-top{
    position: absolute;
width: 200px;
height: 50px;
top: 20px;
left: 80px;
z-index: 10;
  }
  .module-tools {
    width:500px;
    height:50px;
    position: absolute;
    bottom:0;
    left:30%;
    z-index: 10;
    background:pink;
    .tools-box {
      display:flex;
      align-items:center;
      justify-content:center;
    }
  }
}

</style>

使用leaflet新建一底图的简写方式

let map = L.map('map').setView([39.90887, 116.397435], 17);

复杂icon标点

// latlngs是标点坐标,格式同初始化地图时的中心坐标
let marker = L.marker(latlngs, {
	icon: L.divIcon({
		className: "dIcon", //标点icon的容器类名
		html:`标点icon的html字段内容`, //可以添加标点名字之类的自定义内容
		// iconSize: [60, 24] //标点icon的容器大小,也可以直接用className类名写css样式
	})
}).addTo(map); //添加到地图中

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值