业务需要参考很多文章最后实现的功能 仍有缺陷 先展示
1.根据所在区域自动绘制范围
2.切换区域自动切换所画范围
3.回显其他人绘制的范围(业务需求绘制范围不可以重复)
4.绘制的区域可编辑 可删除
(删除功能仍有瑕疵 实现了部分删除功能 都是比较傻瓜试的操作 不喜勿喷)
编辑的时候白色点是可以取消掉的
高德地图开放平台https://lbs.amap.com/api/javascript-api-v2/summary/
要在控制台见一个key才可以运行高德地图插件 要选web服务的才行
下载插件
npm i @amap/amap-jsapi-loader --save
上代码
我的是弹窗的形式 主页面
<el-dialog
title="绘制区域"
width="80%"
top="8vh"
:visible.sync="dialogVisible"
:before-close="hideDialog"
:close-on-click-modal="false"
class="dialogPa"
>
<div class="dialog-body" >
//centerDrop: [123.455551,41.798729]地图中心点 allCoordinates其他人绘制的区域数据 address当前区域文字areaCode当前区域code isUpdateBtn是否显示编辑按钮 updateId可修改数据的id isaddBtn是否是新增 mapIdDiv地图画布id
<seeAddIndex v-if="dialogVisible" :center="centerDrop" :allCoordinates="alllist" :address="dataForm.address" :areaCode="dataForm.areaCode" :isUpdateBtn="true" @mapList="mapList" :updateId="updateId" :isaddBtn="isaddBtnMap" :mapIdDiv="'mapIdDiv'+updateId"></seeAddIndex>
</div>
</el-dialog>
js部分
import seeAddIndex from "@/components/AMapLoader/seeAddIndex.vue"; //自定义高德地图绘制区域
components: {seeAddIndex },
//组件点击确定或取消 istype确定/取消 date点集合数据 mapname切换后的区域数据
mapList(istype,date,mapname) {
var that = this;
if(istype){// 确定
that.newlatlng = date;
console.log("---", date);
//...调用保存接口
}else{//取消
that.newlatlng = [];
that.dialogVisible = false;
}
}
组件代码
<template>
<div class="container">
<div class="input-card mapNewCss">
<div class="input-item">
<div class="input-item-prepend">
<span class="input-item-text">省市区:</span>
</div>
<el-select
style="width: 70%;"
v-model="province"
@change="searchNew('province')"
>
<el-option
v-for="item in provinceList"
:key="item.adcode"
:label="item.name"
:value="item.adcode"
@click.native="getName('province',item)"
>
</el-option>
</el-select>
</div>
<div class="input-item">
<div class="input-item-prepend">
<span class="input-item-text">地级市:</span>
</div>
<el-select
style="width: 70%;"
v-model="city"
@change="searchNew('city')"
>
<el-option
v-for="item in cityList"
:key="item.adcode"
:label="item.name"
:value="item.adcode"
@click.native="getName('city',item)"
>
</el-option>
</el-select>
</div>
<div class="input-item">
<div class="input-item-prepend">
<span class="input-item-text">区县:</span>
</div>
<el-select
style="width: 70%;"
v-model="district2"
@change="searchNew('district')"
>
<el-option
v-for="item in districtList"
:key="item.adcode"
:label="item.name"
:value="item.adcode"
@click.native="getName('district2',item)"
>
</el-option>
</el-select>
</div>
</div>
<div :id="mapIdDiv" style="width: 100%;height: 65vh;"></div>
//两个编辑方法 一个是新增的编辑 一个是修改的编辑 获取到的绘制区域图层不一样 数据格式对不上就不会显示 所以就很笨拙的实现基本功能 希望有大神可以优化
<div class="input-card">
<el-button v-if="isaddBtnOne"
class="filter-item"
type="primary"
@click="upPolygon"
:disabled="isDisabled"
>编辑</el-button
>
<el-button
v-if="!isaddBtnOne"
class="filter-item"
type="primary"
@click="getPoly"
:disabled="isDisabled"
>编辑</el-button
>
//删除功能部分数据实现了
<el-button
v-if="isClear"
class="filter-item"
type="primary"
@click="clearPolygon"
:disabled="isDisabled"
>删除</el-button
>
<div style="float: right;" v-if="isUpdateBtn">
<el-button @click="hideDialog">取 消</el-button>
<el-button type="primary" @click="getOk" :disabled="isDisabled">确 定</el-button>
</div>
</div>
</div>
</template>
<script>
import AMapLoader from "@amap/amap-jsapi-loader";
export default {
name: "AreaMapSee",
props: {
//地图id
mapIdDiv: {
type: '',
default: 'container'
},
//中心点
center: {
type: '',
default: null
},
//所有数据
allCoordinates:{
type: '',
default: null
},
//回显区域数据
// coordinates: {
// type: Object / Array,
// default: []
// },
address:{
type: "",
default: null
},
areaCode:{
type: "",
default: null
},
//编辑按钮
isUpdateBtn: {
type: Boolean,
default: false
},
//待修改的id
updateId: {
type: '',
default: null
},
// 新增按钮
isaddBtn: {
type: Boolean,
default: false
},
},
data() {
return {
map: null,
polyEditor: null,
polyEditorNew: null,
addNumber:0,
updatePolygon:null,
updateCoordinates:[],
isaddBtnOne: false,
isDisabled: false,
district: null,
polygonArea: [],
serviceList: [],
province: "",
provinceName:'',
provinceList: [],
city: "",
cityName: "",
cityList: [],
district2: "",
district2Name: "",
districtList: [],
street: "",
streetList: [],
addOne:false,
mapSeeA:0,//第一次进入页面
mapAreaCode:'',
mapAreaName:'',
newMap:false,
isClear:true,
};
},
mounted() {
console.log("mounted",this.address,this.areaCode);
//对当时接口返回参数的处理
if (this.address) {
let address = this.address.split(",");
this.province=address[0]
this.provinceName=address[0]
this.city=address[1]
this.cityName=address[1]
this.district2=address[2]
this.district2Name=address[2]
this.mapAreaCode=this.areaCode
}
this.isaddBtnOne = this.isaddBtn;
this.echart();
},
methods: {
echart() {
let that=this
AMapLoader.reset()
AMapLoader.load({
key: "", // 申请好的Web端开发者Key,首次调用 load 时必填
version: "2.0", // 指定要加载的 JSAPI 的版本,缺省时默认为 1.4.15
plugins: [
"AMap.ToolBar",
"AMap.Driving",
"AMap.PolygonEditor",
"AMap.PlaceSearch",
"AMap.ControlBar",
"AMap.Scale",
"AMap.Geocoder",
"AMap.DistrictSearch"//区域查询
], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
})
.then((AMap) => {
that.map = new AMap.Map(that.mapIdDiv, {
resizeEnable: true,
// viewMode: '3D',
pitch: 45,
zoom: 13, // 初始化地图级别
center:that.center, // 初始化地图中心点位置
});
const ControlBar = new AMap.ControlBar({
position: { top: '0', right: '10px' }
})
that.map.addControl(ControlBar);
// //数据格式化;
let allList=that.allCoordinates//列表所有数据
let data=[]
for (var i = 0; i < allList.length; i++) {
if (allList[i].serviceRange) {
let data2 = JSON.parse(allList[i].serviceRange);
if(data2.coordinates[0]){
let list=data2.coordinates[0]
if(allList[i].id!=that.updateId){
console.log('allList[i].id',allList[i].id,that.updateId)
data.push({list:list,name:allList[i].name,id:allList[i].id})
// data.push(list)
}else{
//可编辑数据
console.log('that.updateId',that.updateId)
that.updateCoordinates={list:list,name:allList[i].name,id:allList[i].id}
}
}
}
}
console.log('data',data)
let lengthaaa=data.length
that.polygonList=[]
for (var j = 0; j < data.length; j++) {
var points
var name
//循环遍历添加多边形;
points = data[j].list;
name=data[j].name
let polygon1 = new AMap.Polygon({
path: points,
strokeColor: "#FF0000",
strokeWeight: 1,
strokeOpacity: 0.2,
fillOpacity: 0.24,
fillColor: "#FF0000",
zIndex: 20,
});
that.polygonList.push(polygon1);
that.map.add([polygon1]);
let marker = new AMap.Marker({
position: points[0],
offset: new AMap.Pixel(0, 0),
direction:'right',
})
marker.setLabel({
position: points[0],
icon: "//a.amap.com/jsapi_demos/static/demo-center/icons/poi-marker-default.png",
direction:'right',
offset: new AMap.Pixel(0, 0), //设置文本标注偏移量
content: "<div style='background-color: #D9EAFF;color:#333;padding:3px;'>"+name+"</div>", //设置文本标注内容
});
that.map.add(marker)
}
//可编辑数据
that.updatePolygon = new AMap.Polygon({
path: that.updateCoordinates.list,
strokeColor: "#0075FF",
strokeWeight: 1,
strokeOpacity: 0.2,
fillOpacity: 0.24,
fillColor: "#0075FF",
zIndex: 20,
extData:{
id:that.updateCoordinates.id
}
});
that.polygonList.push(that.updatePolygon);
that.map.add([that.updatePolygon]);
that.map.setFitView();
that.polyEditor = new AMap.PolygonEditor(that.map,that.updatePolygon);//编辑数据
//行政区划查询
var opts = {
subdistrict: 1, //返回下一级行政区
showbiz: false //最后一级返回街道信息
};
that.district = new AMap.DistrictSearch(opts);
that.district.search("中国", function(status, result) {
if (status == "complete") {
that.getData(result.districtList[0], "province");
that.searchNew("province","no",1); //默认城市
}
});
})
.catch((e) => {
console.log("---",e);
});
},
//删除当前编辑区域
clearPolygon(){
let that=this
that.polyEditor.close()
if(that.isaddBtnOne){//新增
let polygonDiv = that.map.getAllOverlays("polygon"); //获取所有的polygon
let number=polygonDiv.length
console.log('polygonDiv',polygonDiv)
that.map.remove(polygonDiv[number-1]) // 移除覆盖物
}else{//编辑
let overlaysList=that.polygonList
for(var i = 0; i < overlaysList.length; i++){
// 获取存在每个 extData 中的 id
var id = overlaysList[i].getExtData().id;
console.log('that.updateId',that.updateId)
if(id === that.updateCoordinates.id){//可编辑的id区域
that.map.remove(overlaysList[i]) // 移除覆盖物
console.log('id',id)
break;
}
}
}
that.isClear=false
that.isDisabled=true
},
getPoly() {
this.polyEditor.open();
},
showInfoClick(e) {
console.log("**", e.lnglat.getLng() + "," + e.lnglat.getLat());
this.isDisabled = false;
},
getOk(){
let overlaysList = this.map.getAllOverlays('polygon'); //获取所有的polygon
let pathList=[]
for(let i=0;i<overlaysList.length;i++){
let path=overlaysList[i]._opts.path
if(path&&path.length>0){
pathList.push(path)
}
};
let number=pathList.length
console.log('==all',pathList)
var mapname={
provinceName:this.provinceName,
cityName:this.cityName,
district2Name:this.district2Name,
mapAreaCode:this.mapAreaCode
}
console.log("mapname",mapname)
if(this.newMap||this.isaddBtn){//新增
console.log('==2',[pathList[number-1]])
this.$emit("mapList",true,[pathList[number-1]],mapname);
}else{//编辑
console.log('==1',[pathList[number-2]])
this.$emit("mapList",true,[pathList[number-2]],mapname);
}
},
hideDialog() {
this.$emit("mapList", false);
},
getData(data, level,numbera) {
var that = this;
var bounds = data.boundaries;
console.log("bounds", bounds);
if (bounds) {
for (var i = 0, l = bounds.length; i < l; i++) {
var polygon = new AMap.Polygon({
map: that.map,
strokeWeight: 1,
strokeColor: "#0091ea",
fillColor: "#80d8ff",
fillOpacity: 0.2,
path: bounds[i]
});
that.polygonArea.push(polygon);
}
that.map.setFitView(); //地图自适应
}
console.log(numbera,'that.polygonArea',that.polygonArea)
let newList=that.polygonArea
let polygonAreaList=[]
var subList = data.districtList;
if (subList) {
if (level === "province") {
that.provinceList = subList;
} else if (level === "city") {
that.cityList = subList;
} else if (level === "district") {
that.districtList = subList;
console.log('that.districtList',that.districtList)
} else if (level === "street") {
for (var i = 0, l = subList.length; i < l; i++) {
subList[i].adcodeKey = i + "key" + subList[i].adcode;
}
that.streetList = subList;
console.log('that.streetList')
that.isDisabled=false
console.log('that.isDisabled',that.isDisabled)
}
console.log("curList", level, subList);
if(that.mapSeeA==0){
that.setCenter(that.center);
that.mapSeeA++
}
}
if(numbera==1){
that.searchNew("city","no",2); //默认城市
}else if(numbera==2){
that.district2=that.areaCode
that.searchNew("district","no",3); //默认城市
}
},
getName(type,data){
var that=this
if(type=='province'){
that.provinceName=data.name
}
if(type=='city'){
that.cityName=data.name
}
if(type=='district2'){
that.isaddBtnOne=true
that.newMap=true
that.district2Name=data.name
}
},
//选择type no不清空加载默认数据
searchNew(type,clearType,numbera) {
var that = this;
that.polyEditor.close();
that.$forceUpdate();
//清除地图上所有覆盖物
for (var i = 0, l = that.polygonArea.length; i < l; i++) {
that.polygonArea[i].setMap(null);
}
var adcode = "";
var typeNext = "";
if (type == "province") {
adcode = that.province;
typeNext = "city";
//清空下一级别的下拉列表
if(clearType!='no'){
that.city = "";
that.cityList = [];
that.district2 = "";
that.districtList = [];
}
}
if (type == "city") {
adcode = that.city;
typeNext = "district";
//清空下一级别的下拉列表
if(clearType!='no'){
that.district2 = "";
that.districtList = [];
}
}
if (type == "district") {
adcode = that.district2;
typeNext = "street";
}
that.district.setLevel(type); //行政区级别
that.district.setExtensions("all");
//行政区查询
//按照adcode进行查询可以保证数据返回的唯一性
this.mapAreaCode=adcode
console.log('this.mapAreaCode',this.mapAreaCode)
that.district.search(adcode, function(status, result) {
if (status === "complete") {
that.getData(result.districtList[0], typeNext,numbera);
}
});
},
setCenter(obj) {
this.map.setCenter(obj);
console.log('obj',obj)
},
upPolygon(){
let that=this
let overlaysList = this.map.getAllOverlays('polygon'); //获取所有的polygon
let pathList=[]
for(let i=0;i<overlaysList.length;i++){
let path=overlaysList[i]._opts.path
if(path&&path.length>0){
pathList.push(path)
}
};
let number=pathList.length
console.log('==all',pathList)
console.log('==ADD',[pathList[number-1]])
var pathLista=[pathList[number-1]]
//可编辑数据
that.updatePolygon = new AMap.Polygon({
path: pathLista,
strokeColor: "#0075FF",
strokeWeight: 1,
strokeOpacity: 0.2,
fillOpacity: 0.24,
fillColor: "#0075FF",
zIndex: 20,
extData:{
id:''
}
});
that.polygonList.push(that.updatePolygon);
that.map.add([that.updatePolygon]);
that.map.setFitView();
that.polyEditor = new AMap.PolygonEditor(that.map,that.updatePolygon);//编辑数据
that.polyEditor.open();
},
//编辑区域数据
upPolygon2(){
var that=this
let polygonAreaList=[]
let newList=that.polygonArea
console.log('this.polygonArea',that.polygonArea)
for (var j = 0; j < newList.length; j++){
//可编辑数据
let path=newList[j]._opts.path
let updatePolygon = new AMap.Polygon({
path:path,
strokeColor: "#0075FF",
strokeWeight: 1,
strokeOpacity: 0.2,
fillOpacity: 0.24,
fillColor: "#0075FF",
zIndex: 20,
});
polygonAreaList.push(updatePolygon)
that.map.add([updatePolygon]);
}
console.log('polygonAreaList',polygonAreaList)
//可编辑数据
// that.updatePolygon = new AMap.Polygon({
// path: that.updateCoordinates.list,
// strokeColor: "#0075FF",
// strokeWeight: 1,
// strokeOpacity: 0.2,
// fillOpacity: 0.24,
// fillColor: "#0075FF",
// zIndex: 20,
// extData:{
// id:that.updateCoordinates.id
// }
// });
// that.polygonList.push(that.updatePolygon);
// that.map.add([that.updatePolygon]);
that.polyEditorNew = new AMap.PolygonEditor(that.map,polygonAreaList);//编辑数据
that.polyEditorNew.open();
// that.polyEditorNew.close();
// this.polyEditorNew.setTarget();
// this.polyEditorNew.open();
}
},
};
</script>
<style lang="scss" scoped>
.input-card{
margin-top: 10px;
}
/deep/ .amap-marker-label{
border: 1px solid #D9EAFF;
padding: 0;
border-radius: 6px;
}
.cityListCss {
display: inline-block;
min-width: 50px;
color: #333;
cursor: pointer;
padding: 4px 10px;
}
.activeCss {
color: #1d6bff;
}
/* 行政查询样式 */
.mapNewCss{
margin-top: -40px !important;
margin-bottom: 10px;
}
.mapNewCss .input-item {
display: inline-block;
width: 30%;
text-align: right;
}
.mapNewCss .input-item .input-item-text{
display: inline-block;
text-align: right;
}
.mapNewCss .input-item .input-item-prepend {
display: inline-block;
width: 20%;
}
</style>