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>
最后的效果
存在問題
有些問題我不好解決,就一直留着在這里總結一下,有需要的大佬看一下能不能幫忙修改一下。
- 點擊對號之后效果是對的,但是點擊叉號之后,那個自己繪制的半徑和xx公里一直存在,而且在畫圖會受影響,但是只要點擊了對號就不影響,就是因為數據沒有初始化,我想獲取一下點擊叉號的點擊事件,然后初始化一下就可以,但是不會。
- 鼠標把圓拖出來之后,如果在拖動圓的按鍵來繼續擴大或減小圓的大小,這個代碼就沒治了,因為代碼里面沒有監聽,關鍵是不知道怎么監聽,真他媽的尷尬。
【參考源碼】:https://gitee.com/wjw1014/vue_learning_vuex/blob/master/src/components/map.vue