1. 程式人生 > 其它 ># vue接入高德地圖繪製扇形

# vue接入高德地圖繪製扇形

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());
      },

然後就可以了。