由于百度地图后端接口某些东西开始收费,地图组件就换成了天地图。
和使用百度地图实现差别不是太大,就是api接口需要改变,一开始没找到最佳显示区域的api,我以为会消耗很长的时间,今天找了找 发现有这个api
<template>
<div class="contain">
<div id="allmap">
</div>
<div class="legendBox" v-show="props.showLegend">
<template v-for="item in addressMap" :key="item.value">
<div class="legendBox-item" v-if="!item.hidden">
<img :src="item.icon" :alt="item.label" />
<span class="legendBox-item-word">{{ item.label }}</span>
</div>
</template>
</div>
</div>
</template>
<script setup>
import bluePeople from "@/assets/blue-robot.png";
import houseIcon from "@/assets/map/house.png";
import peperIcon from "@/assets/map/peper.png";
import projectIcon from "@/assets/map/project.png";
import connectIcon from "@/assets/map/connect.png";
import shadowIcon from "@/assets/map/shadow.png";
import gasIcon from "@/assets/map/gas.png";
import chooseIcon from "@/assets/map/isChoose.png";
const addressMap = [];//图例
const props = defineProps({
heat: {
type: Array,
default: () => [],
},
maker: {
type: Array,
default: () => [],
},
seMarker: {
type: Number,
default: 0,
},
showLegend: {
type: Boolean,
default: true,
},
zoom: {
type: Number,
default: 0,
}
});
let map = null;
// 初始化地图
const initMap = () => {
nextTick(() => {
map = new T.Map("allmap",{ // allmap必须和dom上的id一直
minZoom: 3,
maxZoom: 20
});
// map.centerAndZoom(new T.LngLat(116.40769, 39.89945), 4);
//创建缩放平移控件对象
var control = new T.Control.Zoom();
//添加缩放平移控件
map.addControl(control);
})
};
onMounted(initMap);
const makerList = ref([]);
const infoWindowList = ref([]);
const createIcon = (type) => {
return new T.Icon({
iconUrl: addressMap.find((c) => c.value === type)?.icon || peperIcon,
iconSize: new T.Point(30, 30),
})
};
const createMaker = (val) => {
if (makerList.value.length) {
map.clearOverLays();
makerList.value = [];
infoWindowList.value = [];
}
val.forEach((item) => {
const label = item.condition.split("_").join("<br />");
var pt = new T.LngLat(item.position[0], item.position[1]);
var infoWindow = new T.InfoWindow(label,{
offset: new T.Point(0, -16) //解决mouseover - mouseout事件 信息窗口闪动问题
});
infoWindowList.value.push(infoWindow)
// 图标序号标记
if (item.num) {
const numLabel = new T.Label({
text: `<div class='numLabel'>${item.num}</div>`,
position: pt,
offset: new T.Point(-20, 5)
});
const wordTip = new T.Icon({
iconUrl: peperIcon,
iconSize: new T.Point(30, 30),
})
const wordMarker = new T.Marker(pt, { icon: wordTip })
makerList.value.push(wordMarker);
map.addOverLay(wordMarker);
map.addOverLay(numLabel);
numLabel.addEventListener("mouseover", function(){
wordMarker.openInfoWindow(infoWindow, pt);
});
numLabel.addEventListener("mouseout", function(){
wordMarker.closeInfoWindow(infoWindow, pt);
});
} else {
// 图标标记
const icon = createIcon(item.type);
const marker = new T.Marker(pt, { icon });
makerList.value.push(marker);
map.addOverLay(marker);
marker.addEventListener("mouseover", function(){
marker.openInfoWindow(infoWindow, pt);
});
marker.addEventListener("mouseout", function(){
marker.closeInfoWindow(infoWindow, pt);
});
}
});
setViewport(makerList.value)
};
watch(() => props.maker, createMaker);
/**
* 使用BMap.Viewport来获取这些点的最佳显示视图
* @param {*} markers 标点集合
*/
const setViewport = (markers) => {
if(markers.length == 0) return; //这个地方会加载两次 不清楚为啥,所以使用if过滤掉空的情况
var points = markers.map(function(marker) {
return marker.getLngLat(); // 此处获取每个标记的地理位置点
});
var view = map.getViewport(points); // 计算这些点的最佳视图
var mapZoom = view.zoom;
var centerPoint = view.center;
if(props.zoom != 0) {//单点标记时候展示地标
mapZoom = props.zoom
}
map.centerAndZoom(centerPoint,mapZoom); // 动态更新地图的中心点和Zoom级别
}
/**
* @param {*} seq 序号,表格单击选择和取消选择的infowindow展示和关闭
*/
const dispatchMarker = (seq) => {
if (makerList.value.length) {
// 关闭所有信息窗口
makerList.value.forEach((marker,idx) => marker.closeInfoWindow(infoWindowList.value[idx]));
// 打开选定的信息窗口
if(seq > 0) {
const selectedMarker = makerList.value[seq - 1];
selectedMarker.openInfoWindow(infoWindowList.value[seq - 1],selectedMarker.getLngLat());
}
}
};
watch(() => props.seMarker, dispatchMarker);
</script>
<style lang="scss" scoped>
.contain {
width: 100%;
height: 100%;
position: relative;
#allmap {
width: 100%;
height: 100%;
position: relative;
:deep(.tdt-control-copyright.tdt-control) {
display: none !important;
}
:deep(.tdt-overlay-pane) {
z-index: 620;
cursor: pointer;
.tdt-label {
width: 0;
padding: 0;
border: none;
}
.numLabel {
width: 16px;
height: 16px;
line-height: 16px;
text-align: center;
border-radius: 50%;
background-color: #fff;
}
}
}
.legendBox {
width: 150px;
padding: 10px;
font-size: 14px;
background: rgba(255, 255, 255, 0.8);
position: absolute;
right: 10px;
bottom: 10px;
z-index: 1002;
border-radius: 11px;
&-item {
height: 30px;
display: flex;
align-items: center;
margin-bottom: 10px;
img {
height: 100%;
}
}
}
}
</style>