天地图在vue中多点位信息窗口优化
需求:大屏展示多点位点并且点击会有信息窗展示,有tab栏切换不同的多点位展示
分析:点位展示有一定数量并且需要信息窗,就不可以使用聚合点,需要使用多点位信息窗展示
1、先看官网代码示例
ini
<script>
var map;
var zoom = 15;
function onLoad() {
var data_info = [
[ 116.417854,39.921988,"地址:北京市东城区王府井大街88号乐天银泰百货八层"],
[116.406605, 39.921585, "地址:北京市东城区东华门大街"],
[116.412222, 39.912345, "地址:北京市东城区正义路甲5号"],
];
//初始化地图对象
map = new T.Map("mapDiv");
//设置显示地图的中心点和级别
map.centerAndZoom(new T.LngLat(116.41593, 39.92313), zoom);
for (var i = 0; i < data_info.length; i++) {
var marker = new T.Marker(new T.LngLat(data_info[i][0], data_info[i][1])); // 创建标注
var content = data_info[i][2];
map.addOverLay(marker); // 将标注添加到地图中
addClickHandler(content, marker);
}
function addClickHandler(content, marker) {
marker.addEventListener("click", function (e) {
openInfo(content, e);
});
}
function openInfo(content, e) {
var point = e.lnglat;
marker = new T.Marker(point); // 创建标注
var markerInfoWin = new T.InfoWindow(content, {
offset: new T.Point(0, -30),
}); // 创建信息窗口对象
map.openInfoWindow(markerInfoWin, point); //开启信息窗口
}
}
</script>
官网为原生的使用方法,在vue中使用基本相同,找到渲染点位与点击点位展示的关键函数。
可以看出点位的渲染通过对点位信息数组data_info
进行for循环后通过T.Marker
对象进行实例化,再通过map.addOverLay(marker)
方法将点位添加到map中。
信息窗口的展示是通过openInfo
方法进行渲染,在此之前先通过addClickHandler
方法监听点位的点击时间在对应点位渲染。
2、vue中初始化地图方法
typescript
// 全局T
const T = (window as any).T
// 定义地图
let map: any = ref(null)
// 地图中心
let center = new T.LngLat(116.41939, 40.11548)
// 地图缩放
let zoom = 12
// 初始化地图
const initMap = () => {
console.log('初始化')
//初始化地图对象
map.value = new T.Map('mapContainera')
//设置显示地图的中心点和级别
map.value.centerAndZoom(center, zoom)
// 改变地图底色
map.value.setStyle('indigo')
//允许鼠标滚轮缩放地图
map.value.enableScrollWheelZoom()
//允许双击地图放大
map.value.enableDoubleClickZoom()
}
在天地图官网中渲染点位方法实在onLoad函数中,对应vue就是在初始化地图方法中,由于实际业务中点位数量庞大放在初始化方法中会导致每次map渲染会调用后端接口拿到全部点位信息后才能进行渲染完成增加了页面的响应速度,并且根据需求进行tab切换展示其他点位信息时会重新走一次初始化方法,造成体验感较差。
3、页面响应优化
通过查找官网的类方法
我们可以根据对应方法进行业务代码的封装
typescript
// 添加地图marker覆盖物方法
let addMarker = (e: any, list: any) => {
// 添加点位提出方法
let addMarkerPoint = (e: any, gIcon: any) => {
let id: any
markersPoint.value = list.forEach((item: any) => {
//此处为判断tab点击对应的点位信息切换
if (e == 'structure') {
id = item.building_id
} else if (e == 'chargingPile') {
id = item.devices_id
} else if (e == 'site') {
id = item.site_id
}
let marker = new T.Marker(new T.LngLat(item.position[0], item.position[1]), { icon: gIcon, id, type: e })
map.value.addOverLay(marker)
// 信息窗
openInforWindow(marker)
})
}
//此处为判断不同tab对应点位图标的样式
if (e == 'structure') {
let gIcon = new T.Icon({
iconUrl: buildingImg, // buildingImg为从静态资源引入的icon图片
iconSize: new T.Point(35, 35), //设置图标大小
iconAnchor: new T.Point(10, 25)
})
addMarkerPoint(e, gIcon)
} else if (e == 'chargingPile') {
// 充电端口
let gIcon = new T.Icon({
iconUrl: chargingPileImg,
iconSize: new T.Point(35, 35),
iconAnchor: new T.Point(10, 25)
})
addMarkerPoint(e, gIcon)
} else if (e == 'site') {
// 场地
let gIcon = new T.Icon({
iconUrl: siteImg,
iconSize: new T.Point(35, 35),
iconAnchor: new T.Point(10, 25)
})
addMarkerPoint(e, gIcon)
}
}
点击点位弹出信息窗方法
python
// 点击坐标 信息窗弹出
let openInforWindow = (marker: any) => {
marker.addEventListener('click', (e: any) => {
if (e.target.options.type == 'structure') {
//此处为对应接口方法,接口获取到信息后展示点位窗口信息
getBuildInfor(marker, e.target.options.id)
} else if (e.target.options.type == 'chargingPile') {
getchargingInfor(marker, e.target.options.id)
} else if (e.target.options.type == 'site') {
getSiteInfor(marker, e.target.options.id)
}
})
}
接口方法例
typescript
// 信息窗请求接口
const getBuildInfor = (marker: any, id: any) => {
const params = {
conditionValues: [id],
keyword: 'selectBuildingById'
}
commonService
.useSqlCache(params)
.then((res: any) => {
// console.log('防护建筑信息窗', res.data.list)
let list = [...res.data.list]
changeBuildWindow(list)
let BuildInfoWin = new T.InfoWindow()
marker.openInfoWindow(BuildInfoWin)
BuildInfoWin.setContent(buildContent)
BuildInfoWin.update()
})
.catch((err: unknown) => {
console.log('错误信息', err)
})
}
通过以上方式就可以完成不在初始化方法中完成对多点位展示与信息窗的优化