高德地图添加海量点标记和创建自定义信息窗体的封装
假设已经正确引入了高德地图。那后面就直接看代码
<template>
<div class="amap" id="amap"></div>
</template>
<script>
import mapFile from '../../../assets/images/map-filling.png'
import mapInfoWindow from "./info-window/info-window";
import reqMapList from '../../../api'
export default{
data(){
return {
center:[12.32652,20.99399]
}
},
mounted(){
//由于高德地图加载会有延迟,因此需要判断高德地图是否已经加载,若没有加载,则延迟500毫秒加载。
this.$nextTick(()=>{
if(!window.Amap){
setTimeout(()=>{
this.loadMap()
this.initInfoWindow()
},500)
return
}else{
this.loadMap()
}
this.initInfoWindow()
})
},
methods:{
initInfoWindow(){
// //添加供应商点击事件和关闭点击事件
window.closeInfoWindow=this.closeInfoWindow
// //将信息窗体的样式添加到页面
this.$nextTick(()=>{
let mapInfoWindowBox=this.$refs.mapInfoWindowBox
let mapInfoWindowStyle=mapInfoWindowBox.querySelector('#mapInfoWindowStyle')
if(!mapInfoWindowStyle){
let style=document.createElement('style')
style.setAttribute('id','mapInfoWindowStyle')
style.innerHTML=mapInfoWindow.style
mapInfoWindowBox.appendChild(style)
}
})
},
async loadMap() { // 加载地图 需要在挂载后
let map = new AMap.Map('amap', {
center: this.center,
zoom: 16,
})
let {geoJsonData,mapAllList}=await reqMapList()
// //默认加载项目的经纬度图标
this.addMark(map,{geoJsonData,mapAllList})
// //创建信息窗体
this.createInfoWindow()
map.on('click',(event)=>{
// console.log(event)
})
this.map=map
},
//添加标记
addMark({geoJsonData,mapAllList}){
let style=mapAllList.reduce((prev,current)=>{
let {province,city,strictName}=current
prev.push({
url:mapFile, // 图标地址
size: new AMap.Size(30,30), // 图标大小
anchor: new AMap.Pixel(15,25), // 图标显示位置偏移量,基准点为图标左上角
title:province+city+strictName
})
return prev
},[])
let massMarks = new AMap.MassMarks(null,{
zIndex: 50000, // 海量点图层叠加的顺序
zooms: [3, 19], // 在指定地图缩放级别范围内展示海量点图层
style // 设置样式对象
})
console.log(geoJsonData)
massMarks.setData(geoJsonData)
// 将海量点添加至地图实例
massMarks.setMap(map)
massMarks.on('click',e=>{
this.infoWindow.setContent(mapInfoWindow.template(markEvent.data))
this.infoWindow.open(map,markEvent.data.lnglat)
})
},
//创建信息窗体
createInfoWindow(){
this.infoWindow=new AMap.InfoWindow({
content:'', //传入 dom 对象,或者 html 字符串
isCustom: true, //使用自定义窗体
autoMove:true,
anchor:'bottom-right',
offset:new AMap.Pixel(-20,-20),
})
},
//关闭信息窗体
closeInfoWindow(){
this.infoWindow.close()
},
}
</script>
这里说下geoJsonData的数据格式,数据结构如下:
[
{
lnglat:[lon,lat],
style:index,
}
]
这是基本的数据结构,至于是否需要其他数据,可以视情况自己添加。创建海量点标记可以单独给每个点标记创建样式,style用来指定使用使用哪一个点标记,因此值index就是数组下标。lnglat是经纬度数组。
然后看下对Infowindow的封装。
export default {
template:(data)=>{
let {lnglat,name,fullAddress,area,amount,phone,type}=data
return `<div class="infoWindowBox">
<div class="rowStart itemBox">
<i class="iconfont iconjianzhu1"></i>
<span>${name}</span>
</div>
<div class="rowStart itemBox">
<div class="childItemBox rowStart">
<i class="iconfont iconpingfangmi"></i>
<span class="itemText">${area} ㎡</span>
</div>
<div class="childItemBox rowStart">
<i class="iconfont iconjine"></i>
<span class="itemText">${amount} 万元</span>
</div>
</div>
<div class="rowStart itemBox">
<div class="childItemBox rowStart">
<i class="iconfont mapWidowIcon icongangcai"></i>
<span class="itemText">${type || ''}</span>
</div>
<div class="childItemBox rowStart">
<i class="iconfont iconkefudianhua"></i>
<span class="itemText">${phone}</span>
</div>
</div>
<div class="rowStart itemBox">
<i class="iconfont icondizhi"></i>
<span class="itemText">${fullAddress}</span>
</div>
<i class="el-icon-close" id="infoWindowClose" onclick="closeInfoWindow()"></i>
</div>`
},
style:`
.infoWindowBox{
background: rgba(255, 255, 255, 0.9);
box-shadow: 2px 3px 8px 0px rgba(0, 0, 0, 0.35);
border-radius: 4px;
padding:40px 40px 30px 40px;
position: relative;
box-sizing: border-box;
}
.itemBox{
margin-bottom: 10px;
align-items:flex-start;
}
.childItemBox{
flex:1;
align-items:stretch;
}
.mapWidowIcon{
font-size: 16px;
margin-right: 10px;
}
.itemText{
font-size: 14px;
}
.infoWindowBox #infoWindowClose{
position: absolute;
right:10px;
top:10px;
font-size: 28px;
cursor:pointer;
color:#666666;
}
`
}
其实就是吧传入infowindow的content属性html抽成js组件而已,只是为了方便复用。
网友评论