vue+vant高德地图点聚合和点标记切换功能
2021-12-08 本文已影响0人
巴比卜
image
image
image image
1、首先引入高德地图api地址,key要去高德开发平台去申请。
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=''&plugin=AMap.MarkerClusterer"></script>
申请步骤:点击控制台——点击我的应用创建一个应用就会得到key。
image image
2、在页面引入 import AMap from 'AMap' 如果不引用new AMap会报红
3、在vue.config文件中写入
configureWebpack: () => {
const configNew = {}
configNew.externals = {
AMap: 'AMap' // 高德地图配置
}
return configNew
},
4、我们要去实现我们的功能了
<template>
<div>
<div id="mapView" style="width:100%; height:calc(100vh - 306px);"> </div>
<div class="tabs">
<div class="tabs-view" v-for="item in tabsList" :key="item.name" @click="tabsClick(item.name)">
<img :src="tabsActive==item.name?item.active:item.normal"/>
<p :class="tabsActive==item.name?'tabs-p':''">{{item.title}}</p>
</div>
</div>
</div>
</template>
<script>
import AMap from 'AMap'
export default {
name: 'index',
data () {
return {
// 中心点
areaCenterPoint: [120.149147,30.292936],
// 地图
map: '',
zoom:16,
//地图-标点
marker:[],
//地图-聚合
markers:[],
cluster:{},
selectedIds:[],
//切换
tabsActive:0,
tabsList:[
{
'title': '任务',
'normal': require('assets/img/index/icon-task.png'),
'active': require('assets/img/index/icon-task-active.png'),
'name': 0
},
{
'title': '楼房',
'normal': require('assets/img/index/icon-floor.png'),
'active': require('assets/img/index/icon-floor-active.png'),
'name': 1
}
]
}
},
async mounted() {
try {
this.$toast.loading({
message: '加载中...',
forbidClick: true,
loadingType: 'spinner'
})
await this.initMap()
} catch (e) {
console.log(e)
} finally {
this.$toast.clear()
}
},
methods: {
/**
* 任务/楼房切换
* **/
tabsClick(num){
this.tabsActive = num
if(num){
//楼房
//清除点聚合
this.map.remove(this.markers)
this.cluster.setMap(null)
this.getMarker()
}else{
//任务
this.map.remove(this.marker) //清除点标记
this.getMarkerClusterer()
}
},
/**
* 初始化
* **/
async initMap() {
this.map = new AMap.Map('mapView', {
resizeEnable: true,
center: this.areaCenterPoint,
zoom: this.zoom
})
await this.getMarkerClusterer()
},
/**
* 点标记
* **/
getMarker(){
const list=[
{
"buildingName": "1幢",
"centerPoint": "[120.150746,30.29166]",
},
{
"buildingName": "2幢",
"centerPoint": "[120.150295,30.291442]",
},
{
"buildingName": "3幢",
"centerPoint": "[120.150509,30.291863]",
}
]
list.map((v, i) => {
if(v.centerPoint!=''){
const lngLat=JSON.parse(v.centerPoint)
const marker=new AMap.Marker({
position: new AMap.LngLat(lngLat[0], lngLat[1]),
offset: new AMap.Pixel(0, 0),
content: `<div class="floor floor-mr"></div>`,
extData: v,
clickable:true
})
this.marker.push(marker)
marker.on('click', this.resetMap)
}
});
// 创建覆盖物群组,并将 marker 传给 OverlayGroup
var overlayGroups = new AMap.OverlayGroup(this.marker)
// 添加覆盖物群组
this.map.add(overlayGroups)
// 点击地图事件
this.map.on("click", (ev) => {
for (var i = 0; i < this.marker.length; i++) {
this.marker[i].setContent('<div class="floor floor-mr"></div>')
}
})
},
/**
* 点聚合
* **/
getMarkerClusterer() {
const list=[
{
"incidentLevel": "3",
"jwd": "120.146143,30.291471",
},
{
"incidentLevel": "2",
"jwd": "120.148035,30.291725",
},
{
"incidentLevel": "2",
"jwd": "120.145837,30.291309",
}
]
this.markers = []
list.map((v, i) => {
if(v.jwd.includes(',')){
const lng=v.jwd.split(',')[0]
const lat=v.jwd.split(',')[1]
const marker=new AMap.Marker({
position: new AMap.LngLat(lng, lat),
offset: new AMap.Pixel(0, 0),
content: v.incidentLevel=='3'?'<div class="container container-gj"></div>':v.incidentLevel=='2'?'<div class="container container-zj"></div>':'<div class="container container-dj"></div>',
extData: v
})
this.markers.push(marker)
marker.on('click', resetMap)
}
});
// 地图放大最大点标记事件
function resetMap(e){
console.log(e.target.w.extData,4566)
}
this.selectedIds = new Set();
this.cluster = new AMap.MarkerClusterer(this.map, [], {
gridSize: 80,
renderClusterMarker: this._renderClusterMarker,
minClusterSize: 1,
zoomOnClick: false
});
this.setMarkers(this.markers, this.selectedIds)
// 点聚合点击事件
this.cluster.on("click", (ev) => {
this.selectedIds.clear();
const taskList=[]
ev.markers.forEach((v) => {
taskList.push(v.getExtData())
this.selectedIds.add(v.getExtData())
})
if(taskList.length>1){
//多个聚合
console.log(taskList)
}else{
//单个聚合
console.log(taskList)
}
this.setMarkers(this.markers, this.selectedIds);
});
// 点击地图事件
this.map.on("click", (ev) => {
if (this.selectedIds.size > 0) {
this.selectedIds.clear();
this.setMarkers(this.markers, this.selectedIds);
this.taskPopupVisible=false
}
})
},
/**
* 进行点聚合显示的点标记集合
* **/
setMarkers(markers, selectedIds) {
this.cluster.setMarkers(markers);
},
_renderClusterMarker(context) {
let isSelected = false;
let clusterData=[]
context.markers.forEach((v) => {
clusterData.push(v.getExtData())
if (this.selectedIds.has(v.getExtData())) {
isSelected = true;
}
});
context.marker.setOffset(new AMap.Pixel(-36 / 2, -39 / 2));
if (isSelected) {
if(clusterData.length>1){
if (_.some(clusterData, ['incidentLevel', '3'])) {
// 高级
context.marker.setContent(
`<div class="container container-gj-selected">${context.count}</div>`
);
} else if (_.some(clusterData, ['incidentLevel', '2'])) {
// 中级
context.marker.setContent(
`<div class="container container-zj-selected">${context.count}</div>`
);
} else {
// 低级
context.marker.setContent(
`<div class="container container-dj-selected">${context.count}</div>`
);
}
}else{
if (_.some(clusterData, ['incidentLevel', '3'])) {
// 高级
context.marker.setContent(`<div class="container container-gj"></div>`);
} else if (_.some(clusterData, ['incidentLevel', '2'])) {
// 中级
context.marker.setContent(`<div class="container container-zj"></div>`);
} else {
// 低级
context.marker.setContent(`<div class="container container-dj"></div>`);
}
}
} else {
if(clusterData.length>1){
if (_.some(clusterData, ['incidentLevel', '3'])) {
// 高级
context.marker.setContent(`<div class="container container-gj-mr">${context.count}</div>`);
} else if (_.some(clusterData, ['incidentLevel', '2'])) {
// 中级
context.marker.setContent(`<div class="container container-zj-mr">${context.count}</div>`);
} else {
// 低级
context.marker.setContent(`<div class="container container-dj-mr">${context.count}</div>`);
}
}else{
if (_.some(clusterData, ['incidentLevel', '3'])) {
// 高级
context.marker.setContent(`<div class="container container-gj"></div>`);
} else if (_.some(clusterData, ['incidentLevel', '2'])) {
// 中级
context.marker.setContent(`<div class="container container-zj"></div>`);
} else {
// 低级
context.marker.setContent(`<div class="container container-dj"></div>`);
}
}
}
}
}
}
</script>
<style lang="scss" scoped>
::v-deep #mapView{
.container {
width: 36px;
height: 39px;
color: #fff;
font-size: 12px;
text-align: center;
line-height: 32px;
transition: all 0.5s;
background-size: 100% 100%;
}
.container-gj{
width: 28px;
height: 31px;
background-image: url('~assets/img/index/icon-gj.png');
}
.container-zj{
width: 28px;
height: 31px;
background-image: url('~assets/img/index/icon-zj.png');
}
.container-dj{
width: 28px;
height: 31px;
background-image: url('~assets/img/index/icon-dj.png');
}
.container-gj-mr{
background-image: url('~assets/img/index/icon-gj-mr.png');
}
.container-zj-mr{
background-image: url('~assets/img/index/icon-zj-mr.png');
}
.container-dj-mr{
background-image: url('~assets/img/index/icon-dj-mr.png');
}
.container-gj-selected{
background-image: url('~assets/img/index/icon-gj-xz.png');
}
.container-zj-selected{
background-image: url('~assets/img/index/icon-zj-xz.png');
}
.container-dj-selected{
background-image: url('~assets/img/index/icon-dj-xz.png');
}
.floor{
width: 20px;
height: 22px;
background-size: 100% 100%;
}
.floor-mr{
background-image: url('~assets/img/index/icon-house.png');
}
.floor-xz{
background-image: url('~assets/img/index/icon-house-xz.png');
}
}
.tabs{
background: #fff;
border-radius:nth($radius,1);
position: absolute;
top:12px;
right: 10px;
text-align: center;
.tabs-view{
padding: 7px 6px;
position: relative;
img{
width: 15px;
margin-bottom: 2px;
}
p{
font-size: 9px;
}
.tabs-p{
color: nth($color, 4);
}
}
.tabs-view:first-child{
&::after{
position: absolute;
content: '';
width: 20px;
height: 1px;
background: #EBEDF0;
bottom:0;
left: 50%;
margin-left: -10px;
}
}
}
</style>