1. 程式人生 > 實用技巧 >Vue利用百度地圖畫圓並且獲取圓心座標和半徑

Vue利用百度地圖畫圓並且獲取圓心座標和半徑

Vue利用百度地圖畫圓並且獲取圓心座標和半徑

這個東西不好整,既要使用Vue接入百度地圖,又要畫圓。

Vue接入百度地圖

Vue 接入百度地圖其實是有外掛的,vue-baidu-map 這個外掛有官網,直接 npm install 就可以。

vue-baidu-map API介面 : https://dafrok.github.io/vue-baidu-map/#/

然後教程啥的都寫的很清晰,包括安裝和使用,自己就接進去了,但是畫圓獲取圓心座標和半徑有點問題,可能不滿足這個需求,所以說就得用百度地圖官網的API介面,看一眼:


在最後的 “輔助工具” 裡面的 “滑鼠繪製功能(GL)” 就可以繪製圓形。

所以說我們首先得在Vue專案中引入原生的百度API介面。

引入原生的百度地圖API

在 index.html 檔案中引入百度地圖API連線

<script type="text/javascript" src="//api.map.baidu.com/api?type=webgl&v=3.0&ak=這裡填寫你申請的key值"></script>

在使用地圖的元件裡面建立一個div用來展示地圖,記住,一定要給這個div設定寬和高,不然顯示不出來,不要太相信100%的方式設定寬高。

<div id="container" style="height:500px;width=700px"></div>

然後寫一個方法來初始化百度地圖,建立的方法在 created 裡面呼叫

 mounted() {
    this.init();
  },
  methods: {
    init() {
      this.map = new window.BMapGL.Map("container", { enableMapClick: false }); // 建立Map例項,GL版名稱空間為BMapGL(滑鼠右鍵控制傾斜角度)
      this.map.centerAndZoom(new window.BMapGL.Point(116.404, 39.915), 11); // 初始化地圖,設定中心點座標和地圖級別
      this.map.enableScrollWheelZoom(true); // 開啟滑鼠滾輪縮放
	}
}

注意哈,BMap可能找不到,也許是一定找不到,會說沒有找到方法之類的錯,記住,在BMap這些百度自帶的物件前面加 window. 就可以了,就像上面一樣。

好了,按照上面的樣子,百度地圖就引進來了,但是哈,不建議這樣用,用外掛就可以,特別好,但是呢,因為這個專案需求不能使用外掛,因為外掛不支援畫圓獲取座標的功能,只能這樣湊合著用。

畫圓獲取中心點座標和半徑

然後就是畫圓了,這個東西不好整,官網給的demo就是單純的畫一個圓,沒有說怎麼拿到中心點座標和半徑,儘管給你展示出來了,但好像沒有給提供介面拿資料,也是做了很多的準備,查閱了很多的資料才整理出來一個小的demo,但是有瑕疵,一會再說問題出在哪裡。

先看官網案例: http://lbsyun.baidu.com/jsdemo.htm#gl_tool_2

首先在 index.html 檔案中引入需要的 js 檔案,就寫在上一個需要你填key值得那句程式碼下面就行:

<link href="//mapopen.cdn.bcebos.com/github/BMapGLLib/DrawingManager/src/DrawingManager.min.css" rel="stylesheet">
<script type="text/javascript" src="//mapopen.cdn.bcebos.com/github/BMapGLLib/DrawingManager/src/DrawingManager.min.js"></script>

然後在需要使用地圖畫圈的元件寫成下面這樣,我懶得一點一點的弄了,直接粘全部的程式碼:

<template>
  <div>
    <ul style="soild 1px yellow" class="drawing-panel">
      <li class="bmap-btn bmap-circle" id="circle" @click="draw($event)"></li>
    </ul>
    <div id="container"></div>
  </div>
</template>

<script>
export default {
  data() {
    return {
      map: "", // 地圖物件
      drawingManager: "", // 繪製管理器
      centerPoint: null, // 中心點
      label: null,
      polyline: null
    };
  },
  mounted() {
    this.init();
  },
  methods: {
    init() {
      this.map = new window.BMapGL.Map("container", { enableMapClick: false }); // 建立Map例項,GL版名稱空間為BMapGL(滑鼠右鍵控制傾斜角度)
      this.map.centerAndZoom(new window.BMapGL.Point(116.404, 39.915), 11); // 初始化地圖,設定中心點座標和地圖級別
      this.map.enableScrollWheelZoom(true); // 開啟滑鼠滾輪縮放

      var styleOptions = {
        strokeColor: "#5E87DB", // 邊線顏色
        fillColor: "#5E87DB", // 填充顏色。當引數為空時,圓形沒有填充顏色
        strokeWeight: 2, // 邊線寬度,以畫素為單位
        strokeOpacity: 1, // 邊線透明度,取值範圍0-1
        fillOpacity: 0.2 // 填充透明度,取值範圍0-1
      };
      var labelOptions = {
        borderRadius: "2px",
        background: "#FFFBCC",
        border: "1px solid #E1E1E1",
        color: "#703A04",
        fontSize: "12px",
        letterSpacing: "0",
        padding: "5px"
      };

      // 例項化滑鼠繪製工具
      this.drawingManager = new window.BMapGLLib.DrawingManager(this.map, {
        // isOpen: true,        // 是否開啟繪製模式
        enableCalculate: true, // 繪製是否進行測距測面
        enableSorption: TextTrackCue, // 是否開啟邊界吸附功能
        sorptiondistance: 20, // 邊界吸附距離
        circleOptions: styleOptions, // 圓的樣式
        labelOptions: labelOptions // label樣式
      });

      //新增滑鼠繪製工具監聽事件,用於獲取繪製結果
      this.drawingManager.addEventListener(
        "overlaycomplete",
        this.overlaycomplete
      );
      // 給地圖新增滑鼠移動監聽事件
      this.map.addEventListener("mousemove", () => {
        if (this.drawingManager._mask != null) {
          this.drawingManager._mask.addEventListener("mousedown", this.showCirle);
          this.map.removeEventListener("mousemove", this.showCirle);
        }
      });
    },

    /**
     * 畫圓
     */
    draw(event) {
      this.centerPoint = null; // 中心點
      this.label = null;
      this.polyline = null;
      var arr = document.getElementsByClassName("bmap-btn");
      for (var i = 0; i < arr.length; i++) {
        arr[i].style.backgroundPositionY = "0";
      }
      event.target.style.backgroundPositionY = "-52px";
      switch (event.target.id) {
        case "marker": {
          var drawingType = BMAP_DRAWING_MARKER;
          break;
        }
        case "polyline": {
          var drawingType = BMAP_DRAWING_POLYLINE;
          break;
        }
        case "rectangle": {
          var drawingType = BMAP_DRAWING_RECTANGLE;
          break;
        }
        case "polygon": {
          var drawingType = BMAP_DRAWING_POLYGON;
          break;
        }
        case "circle": {
          var drawingType = BMAP_DRAWING_CIRCLE;
          break;
        }
      }
      // 進行繪製
      if (
        this.drawingManager._isOpen &&
        this.drawingManager.getDrawingMode() === drawingType
      ) {
        this.drawingManager.close();
      } else {
        this.drawingManager.setDrawingMode(drawingType);
        this.drawingManager.open();
      }
    },

    overlaycomplete(event) {
      console.log("完成繪製:------> ", event)
      console.log(this.centerPoint);
      console.log(this.label);
      console.log(this.polyline);
      this.centerPoint = null; // 中心點
      this.label = null;
      this.polyline = null;
    },

    showCirle(event) {
      // 如果中心點是null
      if (this.centerPoint == null) {
        this.centerPoint = event.point; // 給中心點設定新的值
        this.drawingManager._mask.addEventListener("mousemove", this.showRadis);
        // var maker = new window.BMapGL.Marker(event.point);
        // this.map.addOverlay(maker);
      }
    },

    /**
     * 花半徑
     */
    showRadis(event) {
      var radius = this.drawingManager._map.getDistance(
        this.centerPoint,
        event.point
      );
      if (!isNaN(radius)) {
        this.map.removeOverlay(this.label); //清除上一個顯示半徑的label標註
        this.map.removeOverlay(this.polyline); //清除上一個圓的半徑直線
        //新增文字標籤
        var opts = {
          position: event.point, // 指定文字標註所在的地理位置(當前滑鼠的位置)
          offset: new window.BMapGL.Size(5, -15) //設定文字偏移量
        };
        this.label = new window.BMapGL.Label(
          (radius / 1000).toFixed(2) + "公里",
          opts
        ); // 建立文字標註物件
        //文字標註樣式
        this.label.setStyle({
          color: "#438eff",
          //fontSize:'14px',
          fontWeight: "bold",
          border: "0px solid #ccc",
          backgroundColor: "" //#2267AD
        });
        //從圓心畫半徑
        this.polyline = new window.BMapGL.Polyline(
          [this.centerPoint, event.point],
          {
            strokeColor: "red",
            strokeWeight: 2,
            strokeOpacity: 0.5
          }
        ); //後面引數為劃線的樣式
        this.map.addOverlay(this.polyline); //新增半徑直線
        this.map.addOverlay(this.label); //新增label
      }
    }
  }
};
</script>

<style>
body,
html,
#container {
  width: 100%;
  height: 500px;
  margin: 0;
  font-family: "微軟雅黑";
}
ul li {
  list-style: none;
}
.info {
  z-index: 999;
  width: auto;
  min-width: 22rem;
  padding: 0.75rem 1.25rem;
  margin-left: 1.25rem;
  position: fixed;
  top: 1rem;
  background-color: #fff;
  border-radius: 0.25rem;
  font-size: 14px;
  color: #666;
  box-shadow: 0 2px 6px 0 rgba(27, 142, 236, 0.5);
}
.drawing-panel {
  z-index: 999;
  position: fixed;
  bottom: 3.5rem;
  margin-left: 2.5rem;
  padding-left: 0;
  border-radius: 0.25rem;
  height: 47px;
  box-shadow: 0 2px 6px 0 rgba(27, 142, 236, 0.5);
}
.bmap-btn {
  border-right: 1px solid #d2d2d2;
  float: left;
  width: 64px;
  height: 100%;
  background-image: url(//api.map.baidu.com/library/DrawingManager/1.4/src/bg_drawing_tool.png);
  cursor: pointer;
}
.drawing-panel .bmap-marker {
  background-position: -65px 0;
}
.drawing-panel .bmap-polyline {
  background-position: -195px 0;
}
.drawing-panel .bmap-rectangle {
  background-position: -325px 0;
}
.drawing-panel .bmap-polygon {
  background-position: -260px 0;
}
.drawing-panel .bmap-circle {
  background-position: -130px 0;
}
</style>

最後的效果

存在問題

有些問題我不好解決,就一直留著在這裡總結一下,有需要的大佬看一下能不能幫忙修改一下。

  1. 點選對號之後效果是對的,但是點選叉號之後,那個自己繪製的半徑和xx公里一直存在,而且在畫圖會受影響,但是隻要點選了對號就不影響,就是因為資料沒有初始化,我想獲取一下點選叉號的點選事件,然後初始化一下就可以,但是不會。
  2. 滑鼠把圓拖出來之後,如果在拖動圓的按鍵來繼續擴大或減小圓的大小,這個程式碼就沒治了,因為程式碼裡面沒有監聽,關鍵是不知道怎麼監聽,真他媽的尷尬。

【參考原始碼】:https://gitee.com/wjw1014/vue_learning_vuex/blob/master/src/components/map.vue