uniapp+騰訊地圖map 實現附近點吸附
思路
uniapp的map組件與騰訊地圖微信小程序sdk均未提供點位吸附,因此思路為,通過地圖拖動事件監聽地圖中心點,再計算該點與所有Markers點的距離,獲取距離最短的marker對象,然后將地圖中心設置為該marker即可
uniapp Map:
https://uniapp.dcloud.net.cn/component/map.html#map
騰訊地圖微信小程序SDK
https://lbs.qq.com/miniProgram/jsSdk/jsSdkGuide/jsSdkOverview
效果:

下載sdk并引入

import QQMapWX from '@/static/qqmap/qqmap-wx-jssdk.min.js'
初始化map對象
this.qqmap = new QQMapWX({ key: ‘yourKey’ });
初始化markers,過程省略,markers參數格式見官方文檔https://uniapp.dcloud.net.cn/component/map.html#marker
this.markers = [{ customCallout: { anchorX: -10 anchorY: 10 display: "ALWAYS" }, callout { anchorX: 0 anchorY: -10 bgColor: "#FFFFFF" borderColor: "#198DFF" borderRadius: "10" borderWidth: 10 content: "xxxxx" display: "BYCLICK" fontSize: 15 } height: "30px" iconPath: "../icon.png" id: 0 latitude: "19.982247" longitude: "110.343734" name: "xxxxx" width: "30px" }, { customCallout: {...}, callout {...} height: "30px" iconPath: "../icon.png" id: 0 latitude: "19.982247" longitude: "110.343734" name: "xxxxx" width: "30px" }, ...... ......]
渲染地圖并添加移動監視
<map class="map" :markers="markers" :scale="13" :latitude="centerLat" :longitude="centerLng" :show-location="true" id="map" ref="map" @markertap="markertap" @regionchange="changeRegiion" @end="functionName" @begin="functionName" >
注:map組件的regionchange 事件直接在組件上寫成 @regionchange,同時這個事件也非常特殊,它的 event type 有 begin 和 end 兩個,導致我們無法在handleProxy 中區分到底是什么事件,所以你在監聽此類事件的時候同時監聽事件名和事件類型既 <map @regionchange="functionName" @end="functionName" @begin="functionName"><map>
"centerLat、centerLng"為當前的中心點坐標
監聽地圖中心點移動,重新設置中心點到距離最近的點
注:僅在事件為拖動(drag)和拖動結束(end)時執行
changeRegiion(e) { if (e.type == 'end' && e.causedBy == 'drag') { let point = { latitude: e.detail.centerLocation.latitude, longitude: e.detail.centerLocation.longitude, } let _self = this; let distanceList = [] //1.計算中心離每個點的距離 let vmarkers = _self.markers vmarkers.forEach((item, index, ) => { let distance = _self.calculateDistance(item.latitude, item.longitude, point.latitude, point .longitude); distanceList.push({ name: item.name, index: item.id, distance: distance }) }) //2.找出距離最近的點 let sortedList = distanceList.sort((a, b) => a.distance - b.distance) //3.重新設置中心點到該點 let markerIndex = sortedList[0].index; _self.centerLng = _self.markers[markerIndex].longitude; _self.centerLat = _self.markers[markerIndex].latitude; } }
計算兩個經緯度之間的距離函數:
//計算兩個經緯度距離 calculateDistance(lat1, lon1, lat2, lon2) { const radians = Math.PI / 180; const R = 6371; // 地球半徑,單位為千米 const deltaLat = (lat2 - lat1) * radians; const deltaLon = (lon2 - lon1) * radians; lat1 = lat1 * radians; lat2 = lat2 * radians; const a = Math.sin(deltaLat / 2) * Math.sin(deltaLat / 2) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(deltaLon / 2) * Math.sin(deltaLon / 2); const c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); const distance = R * c; return distance; }
PS:上面這樣寫的話,是不論移動到多遠,都會有一個最近的點,即沒有一個吸附距離的設置,如果需要設置吸附距離(距離小于多少才吸附),在計算完畢的距離列表中篩選即可,以2公里為例:
//小于2公里
if(sortedList[0].distance<=2){ _self.centerLng = _self.markers[markerIndex].longitude; _self.centerLat = _self.markers[markerIndex].latitude; _self.changeSelectStr(markerIndex); }
完整的:
changeRegiion(e) { if (e.type == 'end' && e.causedBy == 'drag') { let point = { latitude: e.detail.centerLocation.latitude, longitude: e.detail.centerLocation.longitude, } let _self = this; let distanceList = [] //1.計算中心離每個點的距離 let vmarkers = _self.markers vmarkers.forEach((item, index, ) => { let distance = _self.calculateDistance(item.latitude, item.longitude, point.latitude, point .longitude); distanceList.push({ name: item.name, index: item.id, distance: distance }) }) //2.找出距離最近的點 let sortedList = distanceList.sort((a, b) => a.distance - b.distance) //3.重新設置中心點到該點(小于2公里時) if(sortedList[0].distance<=2){ _self.centerLng = _self.markers[markerIndex].longitude; _self.centerLat = _self.markers[markerIndex].latitude; _self.changeSelectStr(markerIndex); } } }
完畢

浙公網安備 33010602011771號