1. 定义点聚合对象
cluster: null, // 点聚合
2. 初始化
在map初始化后执行:
this.cluster = new AMap.MarkerClusterer(this.map, [], {
gridSize: 40,
maxZoom: 15,
renderClusterMarker: _renderClusterMarker,
renderMarker: this._renderMarker
})
灵活setData(坐标系转换会在之后讲):
this.cluster.setData(
//数据数组,你需要提供lnglat
tempData.map(point => {
return {
lnglat: point.lng, point.lat,
extData: point//将数据额外放入点中
}
})
)
设置聚合点样式,在script里面定义即可:
// 聚合点样式设置
function _renderClusterMarker ({ count, marker }) {
let size = 24 + (count + '').length * 8
let div = document.createElement('div')
let divbg = document.createElement('div')
div.className = 'cluster-item'
divbg.className = 'cluster-bg'
div.style.width = div.style.height = div.style.lineHeight = size / 100 + 'rem'
divbg.style.width = divbg.style.height = divbg.style.lineHeight = size / 100 + 'rem'
div.innerHTML = count
div.appendChild(divbg)
marker.setOffset(new AMap.Pixel(-size / 2, -size / 2))
marker.setContent(div)
}
设置点的一写属性,可以放入div,getMarkerContent方法返回一个模板字符串,在methods里面定义,用来设置不同点的图标等属性:
_renderMarker ({ data, marker }) {
const extData = data[0].extData
marker.setContent(
getMarkerContent(...)
)
marker.setOffset(new AMap.Pixel(-25, -46))
},
3. 点击事件(重点)
由于高德2.0升级后取消了之前的默认点击散开事件,所以需要自己写点击事件,当然还是根据百度改的,百度上很多人根据clusterData来判断是否为聚合点,但是实际情况可能不尽如意,我们可以换成上面显示的数
// 点标记绑定点击事件
this.cluster.on('click', (e) => {
let { clusterData, marker } = e
// 此处通过判断聚合点的innerText是否有内容来判断是否为单个点
if (!marker.dom.innerText) {
return
}
// 这里是计算所有聚合点的中心点
let [alllng, alllat] = [0, 0]
for (const mo of clusterData) {
alllng += mo.lnglat.lng
alllat += mo.lnglat.lat
}
const lat = alllat / clusterData.length
const lng = alllng / clusterData.length
// console.log(lng, lat)
// 这里是放大地图,此处写死了每次点击放大的级别,可以根据点的数量和当前大小适应放大
this.map.setZoomAndCenter(
this.map.getZoom() + 3,
[lng, lat],
false,
500
)
})