1. 效果图
2. 用到的工具和组件
请先下载下面js部分用到的工具和组件,css也放在这里,如有需要可以自行下载
百度地图下载:https://pan.baidu.com/s/1IUaissSB_xV0JZ2JSWhIiw 提取码:5l1u
3. 区域划分功能实现代码
3.1 html部分
<template>
<div>
<div class="division_main">
<div class="nav" v-if="isCollapse">
<h3>区划图层</h3>
<el-divider></el-divider>
<div class="content">
<ul>
<li ref="li" v-for="(item, index) in areaArr" :key="index" tabindex="1" @click="getArea(item)">
<span>{{ item.name }}</span>
</li>
</ul>
</div>
</div>
<div class="map" ref="map">
<div class="collapseBtn" @click="isCollapse = !isCollapse">
<img src="../../../assets/img/map/collapse.png" class="collapseImg" alt="" srcset="" />
</div>
<init-map @mapObj="mapObj"></init-map>
</div>
<el-card class="options" v-if="isOptions">
<div slot="header">
<h4>属性设置</h4>
</div>
<div class="content">
<div>
区域名称:
<el-input v-model="options.name" size="mini"></el-input>
</div>
<div>
填充色:
<el-color-picker v-model="options.fillColor" size="medium"></el-color-picker>
</div>
<div v-if="isUpdate">
操作:
<i class="el-icon-delete" @click="doDelete"></i>
</div>
<div>
<el-button size="mini" @click="doCancle">取消</el-button>
<el-button size="mini" @click="doSavePolygon">保存</el-button>
</div>
</div>
</el-card>
</div>
<div class="save">
<el-button type="primary" v-show="isConfirm" size="mini" :disabled="disabled" @click="drawPolygon">划分区域</el-button>
<div v-show="!isConfirm">
<el-button type="primary" size="mini" @click="clearAll">清除</el-button>
<el-button type="primary" size="mini" @click="finishPolygon">完成</el-button>
</div>
</div>
</div>
</template>
3.2 js部分
思路:
1. 把创建marker,polygon的函数封装在一个单独的utils.js文件中,方便维护
2. 把加载地图封装在一个单独的initMap.vue组建中,可以在多个页面中调用,减少代码冗余
3. 画多边形:
①点击页面右上角按钮,开始监听鼠标的getLngLat事件,根据用户点击的地方生成marker
②点击清除按钮,清除地图上用户创建的polygon;点击完成按钮保存用户创建的polygon,通过isOptions控制弹出设置名称和颜色的部分
③点击取消,清除用户地图上创建的polygon;点击保存,保存用户创建的polygon到左侧的列表中
<script>
import initMap from './initMap.vue'
import { createMarker, createPolygon } from './utils'
export default {
name: 'division',
components: {
initMap
},
data() {
return {
map: undefined,
tempMarkerArr: [], // 新增polygon时的marker数据
isCollapse: true,
isConfirm: true, // 是否确认画的多边形
isOptions: false, // polygon配置信息面板
isUpdate: false,
disabled: false, // 划分区域按钮
// polygon的配置信息
options: {
polygon: undefined,
name: '区域',
fillColor: '#409EFF',
polygonArr: []
},
// 模拟polygon数组
areaArr: [
{
polygon: undefined,
name: '区域一',
fillColor: '#409EFF',
polygonArr: [
new window.BMap.Point(117.158469, 31.781578),
new window.BMap.Point(117.15236, 31.779982),
new window.BMap.Point(117.15272, 31.778201),
new window.BMap.Point(117.152756, 31.775316),
new window.BMap.Point(117.15908, 31.774917),
new window.BMap.Point(117.162637, 31.778662)
]
},
{
polygon: undefined,
name: '区域二',
fillColor: '#ea969c',
polygonArr: [
new window.BMap.Point(117.174207, 31.790448),
new window.BMap.Point(117.179848, 31.790141),
new window.BMap.Point(117.180855, 31.78655),
new window.BMap.Point(117.178303, 31.783174),
new window.BMap.Point(117.173524, 31.784095),
new window.BMap.Point(117.169105, 31.788668)
]
}
]
}
},
created() {
// 获取初始化地图map对象
this.mapObj()
},
methods: {
mapObj(data) {
this.map = data
},
clearAll() {
this.tempMarkerArr.forEach(item => {
this.map.removeOverlay(item)
})
this.map.setDefaultCursor('pointer')
this.map.removeEventListener('click', this.getLngLat)
this.isConfirm = true
this.disabled = false
},
// 开始绘制多边形
drawPolygon() {
this.map.setDefaultCursor('crosshair')
this.map.addEventListener('click', this.getLngLat)
this.disabled = true // 防止创建多个addEventListener
this.isConfirm = false
this.isOptions = false
this.options = {
polygon: undefined,
name: '区域',
fillColor: '#409EFF',
polygonArr: []
}
},
// 完成绘制多边形
finishPolygon() {
this.options.polygon = createPolygon(this.map, this.options.polygonArr)
this.map.removeEventListener('click', this.getLngLat)
this.map.setDefaultCursor('pointer')
this.isOptions = true
this.isUpdate = false
this.isConfirm = true
},
// 取消
doCancle() {
if (!this.isUpdate) {
this.map.removeOverlay(this.options.polygon)
this.tempMarkerArr.forEach(item => {
this.map.removeOverlay(item)
})
}
this.isOptions = false
this.disabled = false
},
// 删除
doDelete() {
this.map.removeOverlay(this.options.polygon)
this.areaArr.forEach((item, index) => {
if (item.name === this.options.name) {
this.areaArr.splice(index, 1)
}
})
this.isOptions = false
this.disabled = false
},
// 保存
doSavePolygon() {
if (this.isUpdate) {
this.areaArr.forEach(item => {
if (item.name === this.options.name) {
item.polygon.setFillColor(this.options.fillColor)
}
})
} else {
this.tempMarkerArr.forEach(item => {
this.map.removeOverlay(item)
})
this.options.polygon.setFillColor(this.options.fillColor)
this.areaArr.push(this.options)
}
this.isOptions = false
this.isConfirm = true
this.disabled = false
},
// 点击导航
getArea(data) {
if (data.polygon === undefined) {
data.polygon = createPolygon(this.map, data.polygonArr)
data.polygon.setFillColor(data.fillColor)
}
this.map.panTo(data.polygonArr[2])
this.options = data
this.isOptions = true
this.isUpdate = true
},
// 根据用户点击的经纬度标点
getLngLat(e) {
const point = new window.BMap.Point(e.point.lng, e.point.lat)
const markerIcon = require('../../../assets/img/map/square.png')
const marker = createMarker(this.map, markerIcon, point)
this.tempMarkerArr.push(marker)
this.options.polygonArr.push(point)
}
}
}
</script>