vue3+天地图。添加标注和点击当前去掉其他的标注
场景:我希望默认显示所有的医院。当我点击某一个医院之后。只显示当前这个医院下的小区。其他的医院的标注都去掉。
解决思路是。把所有的医院的标注mark都保存起来。点击了某个标注。再点击事件中写个循环遍历。把除了当前的mark之后的其他标注去掉。
我是vue3+vite项目中使用的天地图
在index.html里面引入天地图
<script type="text/javascript" src="http://api.tianditu.gov.cn/api?v=4.0&tk=天地图key值" />
没有key值可以自己去天地图官网申请后在这里拿到:天地图 登录
然后tiandiMap.vue
<template>
<!-- 地图区域--><div id="mapDiv" ref='mapDivRef' style="position:relative;" v-if='!loading' :style="containerStyle"></div></template>
import customMarkerIcon from "@/assets/imgs/mark.png";
const map = ref(null); // 地图组件
const allHosMark=ref([]);//所有的医院的图标标记 const allHosLabel=ref([]);//所有的的医院文字标签
const hospitalData=ref( [
{name: "郑州大学第一附属医院", lng: 113.662, lat: 34.763, type: "hospital"},
{name: "河南省人民医院", lng: 113.680, lat: 34.768, type: "hospital"},
{name: "郑州市中心医院", lng: 113.615, lat: 34.758, type: "hospital"},
{name: "郑州儿童医院", lng: 113.640, lat: 34.752, type: "hospital"},
{name: "郑州人民医院", lng: 113.625, lat: 34.735, type: "hospital"}
]);
onMounted(async() => {loading.value=true;try {await initMap(); // 确保API加载完成后再初始化地图
addMarkers(hospitalData.value)
} catch (error) {console.error("天地图API加载失败", error);
}
//初始化地图
const initMap=async()=>{if (!window.T) return;map.value = new T.Map('mapDiv', {key: 天地图key值,projection: 'EPSG:4326',inertia: false, // 禁用惯性移动zoomAnimation: false, // 禁用缩放动画panAnimation: false, // 禁用平移动画doubleClickZoom: false, // 禁用双击缩放optimizePanAnimation: true, // 启用平移优化// maxTilesLoading: 16, // 限制并发加载的瓦片数量// tileZoom: 14, // 限制最大缩放级别,减少瓦片请求量reuseTiles: true // 启用瓦片复用});map.value.addControl(new T.Control.MapType({types: ['vec', 'cva'] // 矢量+注记}));// 设置地图主题色蓝色// map.value.setStyle('indigo')// // 设置地图主题色黑色// map.value.setStyle('black')loading.value=false;// 错误处理map.value.on('tileerror', (e) => {console.warn('瓦片加载失败:', e.tile.img.src);e.tile.img.style.opacity = '0.5'; // 半透明显示失败瓦片});}
// 添加多个标记到地图
const addMarkers=(data)=> {// console.log("添加标记到地图data",data)data.forEach(function(item) {var icon = new T.Icon({iconUrl:customMarkerIcon ,});let marker= new T.Marker(new T.LngLat(item.longitude, item.latitude), {icon: icon,} as any);map.value.addOverLay(marker);// console.log("marker",marker);
let style=type=='hospital'?"font-size:12px;padding:6px;background:linear-gradient(90deg, #3191FF 0%, #1D5799 100%);border:1px solid #40F2FF;color:#fff;":"font-size:12px;background-color:#fff;padding:5px;";
let length=item.name.length*6;//希望label的文字居中。这里计算文字的长度//添加标注文字let label = new T.Label({text: `<b style='${style}'>${item.name}</b>`,position: new T.LngLat(item.longitude, item.latitude),offset: new T.Point(-length, -15)});map.value.addOverLay(label);//把医院的所有图标和文字信息保存起来allHosMark.value.push(marker);allHosLabel.value.push(label)
// 添加点击事件marker.addEventListener("click", (e)=> {const currentZoom = map.value.getZoom();setCenter(item.longitude,item.latitude,currentZoom+1);//地图层级放大一级clearHosOthers(marker,label);//清除非点击的医院的标记图标和文字内容})}});});
}
//清除点击以外的医院。根据经纬度确定清除。因为mark每次都是new T.Marker的。都是最新的。所以要找他的经纬度。根据经纬度删除
const clearHosOthers = (nowMarker,nowLabel) =>{const currentPos = nowMarker.getLngLat();// 清除标注图标allHosMark.value.forEach(function(mark) {const markerPos = mark.getLngLat();if(Math.abs(markerPos.lng - currentPos.lng) > 0.0001 ||Math.abs(markerPos.lat - currentPos.lat) > 0.0001){map.value.removeOverLay(mark);}});
//清除文字allHosLabel.value.forEach(function(label) {const markerPos = label.getLngLat();if(Math.abs(markerPos.lng - currentPos.lng) > 0.0001 ||Math.abs(markerPos.lat - currentPos.lat) > 0.0001){map.value.removeOverLay(label);}});
}
