高德地图添加海量点标记和创建自定义信息窗体的封装

假设已经正确引入了高德地图。那后面就直接看代码

<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" οnclick="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组件而已,只是为了方便复用。

Logo

前往低代码交流专区

更多推荐