效果展示:
功能点:
- 搜索地点定位
- 绘制多边形(可删除、二次编辑形状)
- 定位到已绘制好的图形
- 一键清除所有图形
- 确认保存图形数据
因为做的项目很多都会涉及到一些位置的记录或者项目范围的记录,所以经常需要做类似的功能,一般我都是使用百度地图的鼠标绘制工具,这里做个记录,也希望能帮到有需要的朋友们~
第一步肯定是引入百度地图,这一部分下次有时间专门写一篇。
项目需求:是点击按钮后进入到绘制项目范围的页面。
<!-- 项目弹窗 -->
<el-dialog
:title="dialogType_Project === 'edit' ? '修改项目' : '新建项目'"
:visible.sync="dialogVisible_Project"
width="600px"
:close-on-press-escape="false"
:close-on-click-modal="false"
:show-close="false"
class="dialog-box"
>
<el-form
ref="createForm_Project"
:model="createForm_Project"
label-width="120px"
>
<el-form-item label="项目名称" prop="projectName">
<el-input v-model="createForm_Project.projectName" clearable></el-input>
</el-form-item>
<el-form-item label="项目方案范围" prop="projectBoundary">
<el-button :type="overlays.length?'success':'primary'" @click="setMap()" size="small">
<!-- 选择项目方案范围 -->
<span>{{overlays.length?'查看项目方案范围':'绘制项目方案范围'}}</span>
</el-button>
<!-- <el-input v-model="createForm_Project.projectBoundary" clearable></el-input> -->
</el-form-item>
<el-form-item>
<el-button type="primary" @click="confirmCreate">提交</el-button>
<el-button @click="handleClose">取消</el-button>
</el-form-item>
</el-form>
</el-dialog>
<!-- 项目方案范围弹窗 -->
<el-dialog
:visible.sync="boundaryMapVisible"
:fullscreen="true"
width="600px"
:close-on-click-modal="false"
class="dialog-box"
title="绘制项目方案范围"
>
<el-form ref="boundaryForm" :model="boundaryForm">
<el-row class="searchform">
<el-col :span="5" id="r-result">
<el-form-item>
<el-input v-model.trim="address_detail" placeholder="请输入地点描述关键字" clearable id="suggestId">
<el-button slot="append" icon="el-icon-search" @click="setPlace"></el-button>
</el-input>
<div id="searchResultPanel" style="border:1px solid #C0C0C0;width:150px;height:auto; display:none;"></div>
</el-form-item>
</el-col>
<el-col :span="7" :offset="1">
<!-- <el-button @click="overlaysLength" type="primary">定位</el-button> -->
<el-button @click="clearAll" type="danger">清除</el-button>
<el-button type="success" @click="closeMap()">确定</el-button>
</el-col>
</el-row>
</el-form>
<div class="mymap-box">
<div id="mymap" ></div>
<!-- 地图容器 -->
</div>
</el-dialog>
JS部分
export default {
data(){
return{
//项目
dialogType_Project:'add',
dialogVisible_Project:false,
createForm_Project:{
projectName:'',
projectBoundary:[], //项目方案范围
},
//项目方案范围
boundaryMapVisible:false,
address_detail: null,
serachMarker: null,
editMarker: null,
removeMarker: null,
boundaryForm:{},
mymap:null,
overlays:[],
}
},
methods:{
// 项目编辑=》项目方案范围
/**地图弹窗 */
setMap() {
this.address_detail = "";
this.boundaryMapVisible = true;
// 在这里使用$nextTick初始化地图插件即可
if (this.mymap == null) {
this.$nextTick(async () => {
this.mapInit();
this.showOverlays();
});
} else {
// this.mymap.clearOverlays()
this.showOverlays()
if (this.serachMarker) {
this.mymap.removeOverlay(this.serachMarker);
}
this.overlaysLength();
}
},
/**地图初始化(加载百度地图)*/
mapInit() {
const that = this;
that.mymap = this.$mapUtils.bdMapInnit("mymap");
//实例化鼠标绘制工具
let drawingManager = new BMapLib.DrawingManager(that.mymap, {
isOpen: false, //是否开启绘制模式
enableDrawingTool: true, //是否显示工具栏
drawingMode: BMAP_DRAWING_POLYGON, //绘制模式 多边形
drawingToolOptions: {
anchor: BMAP_ANCHOR_TOP_RIGHT, //位置
offset: new BMap.Size(100, 5), //偏离值
drawingModes: [
BMAP_DRAWING_POLYGON //仅支持多边形
]
},
polygonOptions: this.$polygonStyleOptions //设置多边形的样式
});
//添加鼠标绘制工具监听事件,用于获取绘制结果
drawingManager.addEventListener("overlaycomplete", function(e) {
let points = e.overlay.getPath();
//创建右键菜单
let markerMenu = new BMap.ContextMenu();
markerMenu.addItem(
new BMap.MenuItem("删除", removeMarker.bind(e.overlay))
);
markerMenu.addItem(
new BMap.MenuItem("编辑", editMarker.bind(e.overlay))
);
e.overlay.addContextMenu(markerMenu);
e.overlay.disableMassClear();
//将多边形保存到数组
that.overlays.push(e.overlay);
});
//修复画多边形过程中如果误点‘手指’后出现的bug
document.getElementsByClassName(
"BMapLib_Drawing_panel"
)[0].childNodes[0].onclick = function(e) {
// that.overlays.map(v=>{
// v.disableMassClear()
// })
that.mymap.clearOverlays();
};
// 创建双击事件
that.mymap.addEventListener("dblclick", function(e) {
that.mymap.disableDoubleClickZoom();
if (that.overlays.length != 0) {
for (let j = 0; j < that.overlays.length; j++) {
that.overlays[j].disableEditing();
}
}
});
//删除多边形
let removeMarker = function(e, ee, marker) {
that.mymap.removeOverlay(marker);
for (let i = 0; i < that.overlays.length; i++) {
if (that.overlays[i] == marker) {
that.overlays.splice(i, 1);
}
}
};
that.removeMarker = removeMarker;
//编辑多边形
let editMarker = function(e, ee, marker) {
marker.enableEditing();
};
that.editMarker = editMarker;
//按照路名智能查询道路
//建立一个自动完成的对象
var ac = new BMap.Autocomplete({
input: "suggestId",
location: that.mymap
});
},
// 查询关键字搜索
setPlace() {
const that = this;
that.mymap.removeOverlay(that.serachMarker);
//智能搜索
var local = new BMap.LocalSearch(that.mymap, {
onSearchComplete: () => {
//获取第一个智能搜索的结果
let userlocation = local.getResults().getPoi(0).point;
that.mymap.centerAndZoom(userlocation, 18);
//添加标注
that.serachMarker = new BMap.Marker(userlocation);
that.mymap.addOverlay(that.serachMarker);
}
});
local.search(that.address_detail);
},
/**定位到绘制区域 */
overlaysLength() {
if (this.overlays.length > 0) {
this.$mapUtils.polygonsLocationMap(this.overlays, this.mymap);
} else {
// this.$mapUtils.polygonsLocationMap([this.regionPolygon], this.mymap);
}
},
/**清除所有绘制的多边形 */
clearAll() {
for (let i = 0; i < this.overlays.length; i++) {
this.mymap.removeOverlay(this.overlays[i]);
}
this.overlays = [];
this.createForm_Project.projectBoundary = [];
},
/**保存地图 */
saveMap() {
const that = this;
let arr = [];
if (that.overlays.length == 0) {
return [];
} else {
for (let j = 0; j < that.overlays.length; j++) {
that.overlays[j].disableEditing();
let s = [];
let overlays = that.overlays[j].getPath();
for (let i = 0; i < overlays.length; i++) {
s.push([overlays[i].lng, overlays[i].lat]);
}
s.push([overlays[0].lng, overlays[0].lat]); //形成闭环
arr.push(s);
}
let roadArea = arr;
return roadArea;
}
},
/**刷新overlays数据 */
showOverlays() {
this.overlaysLength();
// 加载overlayers到地图上
for (let i = 0; i < this.overlays.length; i++) {
this.mymap.addOverlay(this.overlays[i]);
//创建右键菜单
let markerMenu1 = new BMap.ContextMenu();
markerMenu1.addItem(
new BMap.MenuItem("删除", this.removeMarker.bind(this.overlays[i]))
);
markerMenu1.addItem(
new BMap.MenuItem("编辑", this.editMarker.bind(this.overlays[i]))
);
this.overlays[i].addContextMenu(markerMenu1);
}
},
//关闭地图弹窗
closeMap(){
this.boundaryMapVisible=false
for (let i = 0; i < this.overlays.length; i++) {
this.mymap.removeOverlay(this.overlays[i]);
}
},
//在获取项目信息时,对获取到的项目范围点位数据进行处理,方便回显已绘制地区
pointsArr2Overlays(data) {
// let myOverlay = [];
let overlays = [];
if (data && data != "") {
let pointsArr = JSON.parse(data);
// console.log(pointsArr);
if (pointsArr && pointsArr.length > 0) {
pointsArr.forEach((item, i) => {
// console.log(item)
let myOverlay = [];
item.forEach((arr, j) => {
let point = new BMap.Point(arr[0], arr[1]);
myOverlay.push(point);
});
let myPolygon = new BMap.Polygon(
myOverlay,
this.$polygonStyleOptions
);
myPolygon.disableMassClear();
// //将加载的多边形保存到数组里面
overlays.push(myPolygon);
});
}
return overlays;
} else {
return overlays;
}
},
//编辑项目(外层弹窗)
editForm(id){
programEval.getProjectInfo(id).then((data ) => {
this.createForm_Project = JSON.parse(JSON.stringify(data.data));
//处理项目范围数据
this.overlays = this.pointsArr2Overlays(this.createForm_Project.projectBoundary);
});
this.dialogVisible_Project = true;
},
},
mounted(){
}
}
CSS部分
<style scoped lang="scss">
.searchform {
height: 52px;
z-index: 3500;
width: 100%;
min-width: 1390px;
}
.mymap-box {
min-width: 1400px;
position: absolute;
top: 70px;
bottom: 30px;
left: 25px;
right: 25px;
/*地图样式*/
#mymap {
position: absolute;
top: 60px;
bottom: 0px;
width: 100%;
border: 1px solid #1b86b9;
/* height: 100%; */
overflow: hidden;
z-index: 1;
}
/*地图结果查询*/
#result {
border-left: 1px dotted #999;
background: #fff;
/* height: 100%; */
width: 400px;
position: absolute;
top: 65px;
left: 20px;
font-size: 12px;
}
}
</style>
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。