Vue使用高德地圖實現(xiàn)點聚合+點擊點坐標(biāo)顯示點信息的功能
業(yè)務(wù)場景
拿目前做的這個項目來說前联,需要完成這樣的一個場景:讀取數(shù)據(jù)庫將樹木的位置標(biāo)在地圖上秸脱,由于點比較多罗珍,要用點聚合的形式,點擊地圖上的點梆掸,會在右側(cè)的信息欄中獲取該樹木的所有信息瘪贱。demo圖如下(接口數(shù)據(jù)因為是真實數(shù)據(jù)纱控,遂隱藏):
分析
這里先簡單列一下實現(xiàn)的思路:
- 初始化地圖
- 訪問接口拿到點的數(shù)據(jù)
- 用點聚合的形式將數(shù)據(jù)渲染在地圖上
- 給每個點綁定點擊事件
- 點擊地圖上點的時候拿到里面的key值辆毡,查該點的信息
- 用vue的雙向綁定菜秦,將信息渲染到右邊的單元格中
- 在使用篩選功能時,先重置數(shù)據(jù)舶掖,刪除聚合點球昨,然后重新再調(diào)用查詢接口并重新繪制聚合點
解決思路有了之后,那么開始coding
實現(xiàn)
1.初始化地圖
initMap () {
map = new AMap.Map('map', {
// 放大級別
zoom: 13,
// 放大縮小
resizeEnable: true,
// 位置
center: [117.094923,36.246692],
// 是否顯示地圖文字標(biāo)記
showLabel: false,
ayers: [
// 衛(wèi)星圖
new AMap.TileLayer.Satellite(),
// 路書
new AMap.TileLayer.RoadNet()
]
})
}
2.訪問業(yè)務(wù)接口拿到點的經(jīng)緯度信息坐標(biāo)
由于這里要查詢點的所有相關(guān)信息眨攘,這里接口設(shè)計時主慰,不僅只拿到lng,lat的值鲫售,還要有個數(shù)據(jù)的key值共螺,這里的接口返回格式為:
data: [
{
keyid: '1001',
lnglat: [117.21564564, 36.3145486]
},{
keyid: '1002',
lnglat: [117.21564564, 36.3145486]
},{
keyid: '1003',
lnglat: [117.21564564, 36.3145486]
},
......
]
查詢該數(shù)據(jù)接口,在查詢成功后調(diào)用初始化點聚合的功能情竹,具體實現(xiàn)如下:
// 獲取點聚合數(shù)據(jù)
getPoints () {
axios.get(apiurl.getPointsList, {
// 這里是查詢參數(shù)
starttime: this.searchForm.starttime,
endtime: this.searchForm.endtime,
worked: this.searchForm.worked
}).then(({data}) => {
// 解構(gòu)賦值
this.pointsList = data
// 在查詢成功后藐不,調(diào)用點聚合的初始化功能
this.initMarkers()
}).catch((error) => {
console.log(error)
})
}
3.實現(xiàn)點聚合功能
調(diào)用initMarkers()函數(shù),將數(shù)據(jù)點以點聚合的形式渲染在地圖上,在添加點的同時雏蛮,給每個點賦予新的屬性涎嚼,及前面提到的keyid值,以便點擊該點時挑秉,將該keyid值傳入接口來實現(xiàn)查詢功能法梯。在這里,使用marker.setExtData()函數(shù)來實現(xiàn)添加額外屬性的功能犀概,這里需要傳入需要添加的屬性和屬性值立哑,使用marker.on()來綁定點擊事件。這里圈一下是重點姻灶,具體實現(xiàn)如下:
// 添加點聚合
initMarkers () {
// 初始化聚合列表和點的列表
let cluster, markers = [];
// 循環(huán)讀取每一個點的經(jīng)緯度信息
for (let i = 0; i < this.pointsList.length; i += 1) {
// 添加點坐標(biāo)
let marker = new AMap.Marker({
position: this.pointsList[i]['lnglat'],
content: '<div style="background-color: hsla(180, 100%, 50%, 0.7); height: 24px; width: 24px; border: 1px solid hsl(180, 100%, 40%); border-radius: 12px; box-shadow: hsl(180, 100%, 50%) 0px 0px 1px;"></div>',
offset: new AMap.Pixel(-15, -15)
})
// 給marker點坐標(biāo)添加額外的屬性和對應(yīng)的屬性值刁憋,圈重點這里是關(guān)鍵
marker.setExtData(this.pointsList[i]['treeId'])
// 給每個點坐標(biāo)綁定click事件,這里是實現(xiàn)點擊功能的重點
marker.on('click', this.markerClick)
markers.push(marker)
}
let count = markers.length;
// 設(shè)置聚合樣式木蹬,這里都是聚合樣式的配置
let _renderClusterMarker = function (context) {
let factor = Math.pow(context.count / count, 1 / 18);
let div = document.createElement('div');
let Hue = 180 - factor * 180;
let bgColor = 'hsla(' + Hue + ',100%,50%,0.7)';
let fontColor = 'hsla(' + Hue + ',100%,20%,1)';
let borderColor = 'hsla(' + Hue + ',100%,40%,1)';
let shadowColor = 'hsla(' + Hue + ',100%,50%,1)';
div.style.backgroundColor = bgColor;
let size = Math.round(30 + Math.pow(context.count / count, 1 / 5) * 20);
div.style.width = div.style.height = size + 'px';
div.style.border = 'solid 1px ' + borderColor;
div.style.borderRadius = size / 2 + 'px';
div.style.boxShadow = '0 0 1px ' + shadowColor;
div.innerHTML = context.count;
div.style.lineHeight = size + 'px';
div.style.color = fontColor;
div.style.fontSize = '14px';
div.style.textAlign = 'center';
context.marker.setOffset(new AMap.Pixel(-size / 2, -size / 2));
context.marker.setContent(div)
};
// 調(diào)用函數(shù)添加點聚合功能
addCluster();
function addCluster() {
if (cluster) {
cluster.setMap(null);
} else {
// 如果不設(shè)置renderClusterMarker至耻,聚合點為默認樣式
cluster = new AMap.MarkerClusterer(map, markers, {
gridSize: 50,
// 使用上面設(shè)置的點聚合樣式
renderClusterMarker: _renderClusterMarker
});
}
}
}
這里提一下,在使用點聚合功能時镊叁,在html頁面上添加地圖key值的地方尘颓,需要引入點聚合的插件:&plugin=AMap.MarkerClusterer 。
<script type="text/javascript" src="https://webapi.amap.com/maps?v=1.4.15&key=你的key值&plugin=AMap.MarkerClusterer"></script>
4.實現(xiàn)點坐標(biāo)的點擊事件
在前面已經(jīng)給每個marker點綁定點擊事件了晦譬,這里需要我們寫個函數(shù)加以實現(xiàn)疤苹。
// 點坐標(biāo)點擊事件,在點聚合功能中以完成綁定
markerClick (e) {
console.log(e.target.getExtData())
// 拿到之前賦予的keyid值敛腌,將該值傳入獲取詳細信息的函數(shù)
const keyId = e.target.getExtData()
// 調(diào)用獲取詳細信息的函數(shù)
this.getDesMessage(keyId)
}
5.根據(jù)keyId獲取該點的詳細信息并渲染
這里就沒啥好說的了卧土,前面拿到了keyId值,用此值查詢數(shù)據(jù)庫像樊,將返回結(jié)果在頁面上進行渲染尤莺。
// 獲取列表值
getDesMessage (keyId) {
axios.get(apiurl.desMessage, {
// 查詢需要傳入的參數(shù)
keyId: keyId,
}).then(({data}) => {
// 將查詢結(jié)果賦值給desMessage,然后利用vue的雙向綁定渲染到頁面上
this.desMessage = data
}).catch((error) => {
console.log(error)
})
}
6.完善
由于上面有篩選重置按鈕生棍,這里需要完善這兩個功能颤霎,在提交查詢時,先重置下頁面數(shù)據(jù)再調(diào)用點聚合的功能涂滴,重置也亦如此友酱。
// 提交查詢
onSubmit () {
// 重置頁面數(shù)據(jù)
// 刪除所有的聚合點
this.removeMarkers()
// 將點的結(jié)果集置空
this.pointsList = []
// 重新調(diào)用接口獲取數(shù)據(jù)
this.getPoints()
},
// 重置
resetForm () {
// 重置頁面數(shù)據(jù)
// 刪除所有的聚合點
this.removeMarkers()
// 查詢表單置空
this.searchForm = {}
// 將點的結(jié)果集置空
this.pointsList = []
// 重新調(diào)用接口獲取數(shù)據(jù)
this.getPoints()
},
// 刪除點聚合
removeMarkers () {
map.clearMap()
}
到這里,點的聚合效果和點擊效果就全部完成柔纵。
所有代碼都為部分代碼缔杉,這里只是提供一個實現(xiàn)的思路。
如需轉(zhuǎn)載搁料,請加上本文的鏈接并標(biāo)明出處
一條愛吃屎的狗的博客