# vue接入高德地圖繪製扇形
阿新 • • 發佈:2022-03-17
vue接入高德地圖繪製扇形
為什麼又寫這一篇呢,主要是因為這個功能高德不支援,只能自己實現,但是呢,我估計很多人會用到這玩意兒。所以說呢,就簡單的實現一下,如果有需要的話直接超過去就行,之前寫過天地圖繪製扇形區域的,如果使用天地圖的話可以翻一下我之前的部落格,百度地圖和這個方法類似,可能就是使用的類不同,這樣的話只要原理流程理解的差不多,直接把各個地圖的類名替換一下就可以了。
需求
需求簡單說一下,就是有一個列表,列表的資料就是一個基站資訊,包含基站的經緯度資訊和名字,基站下面又分扇區,比如有兩個扇區或者一個扇區,扇區的覆蓋範圍是多少,也就是圍繞基站的半徑長度,以及扇形的角度,這個案例我角度是寫死的哈,預設30度做的,如果需要動態設定的話,可以根據自己的需求稍作修改。
下面是基站列表的資料格式:
let sectorList = [{ name: '第一個基站', // 基站名稱 x: 116.3470390, // 基站經度 y: 40.481888, // 基站緯度 data: [{ // 基站包含扇區列表 msg: '第一個基站的第一個扇區', // 扇區名稱 r: 0 // 基站初始角度 }] }, { name: '第二個基站', x: 117.3470, y: 39.48188, data: [{ msg: '第二個基站的第一個扇區', r: 0 }, { msg: '第二個基站的第二個扇區', r: 120 }] }]
預想效果
最後想要實現的效果就是這個樣子的哈!
就是扇區直接覆蓋在地圖上,和標註點不一樣,這個繪製的扇區會根據地圖的縮放進行等比例縮放,不想標註點一樣大小不變,但是呢,我在基站的頂點還是是用了一個圓形標註點,主要是怕地圖縮小到全國找不到那些地方有扇區展示,所以說用來覆蓋物和標註點配合展示,然後呢,這個程式碼沒有優化,僅僅作為實現用,具體根據自己專案需求進行優化處理。
程式碼實現
繪製基站第一步
drawSite(mapPoint) { let point = new AMap.LngLat(mapPoint.x, mapPoint.y); for (var i = 0; i < mapPoint.data.length; i++) { let radian1 = 90 - mapPoint.data[i].r - 30 let radian2 = 90 - mapPoint.data[i].r let oval = new AMap.Polygon({ path: this.sector(point, 500, radian1, radian2), strokeColor: '#ff8400', strokeOpacity: '1', strokeWeight: 1, fillColor: '#ff8400', fillOpacity: '0.3', }) let info = []; info.push("<b>基站名稱:</b>" + mapPoint.name); info.push("<b>扇區名稱:</b>" + mapPoint.data[i].msg); let content = info.join("<br/>"); oval.content = content oval.on('click', this.polygonClick); map.add(oval); } let marker = new AMap.CircleMarker({ center: point, radius: 7, strokeWeight: 0, fillColor: "#ff8400", fillOpacity: 1, }); marker.on('click', this.markerClick); map.add(marker); },
繪製基站第二步 - 計算扇形形狀
sector(center, len, radian1, radian2) {
let points = [];
let step = ((radian2 - radian1) / 10) || 10; //根據扇形的總夾角確定每步夾角度數,最大為10
points.push(center);
for (let i = radian1; i < radian2 + 0.001; i += step) { //迴圈獲取每步的圓弧上點的座標,存入點陣列
points.push(this.eOffsetBearing(center, len, i));
}
points.push(center);
return points;
},
計算扇形座標
eOffsetBearing(center, len, bearing) {
let lngConv = center.distance(new AMap.LngLat(center.getLng() + 0.1, center.getLat())) * 10
let latConv = center.distance(new AMap.LngLat(center.getLng(), center.getLat() + 0.1)) * 10 //計算1緯度與原點的距離
let lat = len * Math.sin(bearing * Math.PI / 180) / latConv; //正弦計算待獲取的點的緯度與原點緯度差
let lng = len * Math.cos(bearing * Math.PI / 180) / lngConv; //餘弦計算待獲取的點的經度與原點經度差
return new AMap.LngLat(center.getLng() + lng, center.getLat() + lat);
},
扇區點選事件
polygonClick(e) {
infoWindow.setContent(e.target.content);
infoWindow.open(map, [e.lnglat.getLng(), e.lnglat.getLat()]);
},
原點點選事件
markerClick(e) {
infoWindow.setContent(e.target.content);
map.setZoomAndCenter(17, e.target.getCenter());
infoWindow.open(map, e.target.getCenter());
},
然後就可以了。