vue3+element-plus 高德地图电子围栏
<template>
<div style="width: 100%;height: 100vh;position: relative">
<div
style="position: absolute;left: 10px;top: 10px;z-index: 9;display: flex;flex-direction: row;align-items: center;">
<div style="margin-right: 10px;">
<el-button type="info" color='#5f5f5f'>返回上层</el-button>
</div>
<div style="width: 350px;">
<el-input ref="pointStart" v-model="formData.address" placeholder="请输入地名或点击地图选点">
<template #prepend>请输入关键词</template>
</el-input>
</div>
<div style="margin-left: 10px;">
<el-button type="info" color="#eaeaea">卫星模式</el-button>
</div>
</div>
<el-row>
<el-col :span="24">
<div style="height: 100vh" id="container" ref="map"></div>
</el-col>
</el-row>
<div style="position: absolute;top: 0;right: 0;bottom: 0;background: #fff;padding: 20px 10px;width: 250px;">
<div style="">
<el-form label-position="top" :model="formData">
<el-form-item label="围栏名称" prop="name" required
:rules="[{required: true,message: '请输入围栏名称',trigger: 'blur',}]">
<el-input v-model="formData.name" placeholder="请输入围栏名称" />
</el-form-item>
<el-form-item label="围栏形状">
<el-select v-model="formData.type" style="width: 100%;" @change="typeChange">
<el-option v-for="(item,index) in data.drivingOptions" :key="index" :label="item.title"
:value="item.type" />
</el-select>
</el-form-item>
<el-form-item label="圆形围栏半径(米)" v-if="formData.type=='圆形'">
<el-input-number style="width: 100%;" v-model="formData.radius" :min="1" @change="numChange" />
</el-form-item>
<el-form-item label="状态">
<el-switch v-model="formData.status" inline-prompt active-text="开启" active-value="开启"
inactive-text="关闭" inactive-value="关闭" />
</el-form-item>
<el-form-item label="权重" prop="weigh">
<el-input v-model="formData.weigh" placeholder="请输入权重" />
</el-form-item>
</el-form>
<el-button style="width: 100%;" type="primary" @click="save">保存</el-button>
</div>
</div>
</div>
</template>
<script setup>
import {
reactive,
computed,
ref,
watch,
getCurrentInstance
} from 'vue';
import {
ElMessage
} from 'element-plus'
const {
proxy
} = getCurrentInstance()
import {
useRouter
} from 'vue-router'
const router = useRouter();
const pointStart = ref(null);
const data = reactive({
map: null,
loading: false,
drivingOptions: [{
type: '圆形',
title: '圆形',
}, {
type: '多边形',
title: '多边形',
},
],
routeList: null,
polygon: null,
polyEditor: null,
circle: null,
circleEditor: null
});
const formData = reactive({
id:'',
address: '',
name: '',
type: '多边形',
radius: 1000,
status: '开启',
weigh: '',
pointStart: {
point: [],
address: '',
name: '',
longitude: '',
latitude: '',
}
})
watch([() => formData.pointStart.point], ([newProp1], [oldProp1]) => {
if (newProp1.length > 0) {
data.map.setCenter(newProp1);
initWei(newProp1[0], newProp1[1])
}
console.log('属性 prop1 变化了:', oldProp1, '=>', newProp1);
});
window.AMapLoader.load({
"key": "",
"version": "2.0",
"plugins": ['AMap.Scale', 'AMap.Driving', 'AMap.PlaceSearch',
'AMap.AutoComplete', 'AMap.PolygonEditor', 'AMap.CircleEditor'
],
"AMapUI": {
"version": '1.1',
"plugins": [],
},
"Loca": {
"version": '2.0'
},
}).then((AMap) => {
data.map = new AMap.Map("container", {
resizeEnable: true,
center: [116.397428, 39.90923],
zoom: 13
});
data.map.addControl(new AMap.Scale());
setPolygon()
}).catch((e) => {});
function typeChange(e) {
if (data.polygon) {
console.log(data.marker)
data.map.remove(data.polygon);
data.polyEditor.close();
}
if (data.circle) {
data.map.remove(data.circle);
data.circleEditor.close();
}
}
function numChange(e) {
console.log(e)
if (data.circle) {
data.circle.setRadius(e);
}
}
function setPolygon() {
const pointStartEl = pointStart.value.$el.querySelector('input')
setInput(pointStartEl, 'pointStart')
data.map.on('click', function(e) {
formData.pointStart = {
point: [e.lnglat.getLng(), e.lnglat.getLat()],
address: '',
name: '',
longitude: e.lnglat.getLng(),
latitude: e.lnglat.getLat()
}
initWei(e.lnglat.getLng(), e.lnglat.getLat())
});
if (router.currentRoute.value.query) {
proxy.$api.post('/api/carman/Electric_Fence/detail', router.currentRoute.value.query).then(response => {
const result = response.data
if (result.code) {
formData.id = result.data.id
formData.type=result.data.type
formData.name = result.data.name
formData.status = result.data.status
formData.weigh = result.data.weigh
formData.radius = result.data.radius
if(formData.type=='多边形'&&result.data.range.length>0){
const path=result.data.range.map(item=>{
return new window.AMap.LngLat(item.longitude, item.latitude)
})
initPolygon(path)
console.log(path)
}else if(formData.type=='圆形'&&result.data.centre_lat&&result.data.centre_lon&&result.data.radius){
formData.pointStart = {
point: [result.data.centre_lon, result.data.centre_lat],
address: '',
name: '',
longitude: result.data.centre_lon,
latitude: result.data.centre_lat
}
initWei(result.data.centre_lon,result.data.centre_lat)
}
}
})
}
}
function initPolygon(path){
if (data.polygon) {
console.log(data.marker)
data.map.remove(data.polygon);
data.polyEditor.close();
}
data.polygon = new window.AMap.Polygon({
path: path,
strokeWeight: 6,
strokeOpacity: 0.2,
fillOpacity: 0.4,
fillColor: '#1791fc',
zIndex: 50,
bubble: true,
});
data.map.add(data.polygon);
data.polyEditor = new window.AMap.PolygonEditor(data.map, data.polygon);
data.polyEditor.open();
}
function initWei(centerLng, centerLat) {
if (formData.type == '多边形') {
var radius = 0.01;
var lng1 = centerLng;
var lat1 = centerLat + radius / 2 / Math.sqrt(3);
var lng2 = centerLng - radius / 2;
var lat2 = centerLat - radius / 2 / Math.sqrt(3);
var lng3 = centerLng + radius / 2;
var lat3 = centerLat - radius / 2 / Math.sqrt(3);
let path=[
new window.AMap.LngLat(lng1, lat1),
new window.AMap.LngLat(lng2, lat2),
new window.AMap.LngLat(lng3, lat3)
]
initPolygon(path)
} else if (formData.type == '圆形') {
if (data.circle) {
console.log(data.marker)
data.map.remove(data.circle);
data.circleEditor.close();
}
data.circle = new window.AMap.Circle({
center: [centerLng, centerLat],
radius: formData.radius,
borderWeight: 3,
fillOpacity: 0.4,
strokeStyle: 'dashed',
strokeDasharray: [10, 10],
fillColor: '#1791fc',
zIndex: 50,
})
data.map.add(data.circle);
data.circleEditor = new window.AMap.CircleEditor(data.map, data.circle)
data.circleEditor.open();
data.circleEditor.on('adjust', function(event) {
var newRadius = event.target.getRadius();
console.log("圆形半径变化为:" + newRadius);
formData.radius = newRadius
});
data.circleEditor.on('move', function(event) {
var newCenter = event.target.getCenter();
console.log('新的圆心坐标:' + newCenter);
});
}
}
function setInput(point, pointArr, index = -1) {
var autoPoint = new window.AMap.AutoComplete({
input: point
});
autoPoint.on("select", select);
function select(e) {
if (e.poi && e.poi.location == '') {
var placeSearch = new window.AMap.PlaceSearch({
city: e.poi.adcode
})
placeSearch.search(e.poi.name, function(status, result) {
if (result.poiList) {
formData[pointArr] = {
point: [result.poiList.pois[0].location.lng, result.poiList.pois[0].location
.lat
],
address: result.poiList.pois[0].name,
name: result.poiList.pois[0].name,
longitude: result.poiList.pois[0].location.lng,
latitude: result.poiList.pois[0].location.lat
}
}
})
} else {
formData[pointArr] = {
point: [e.poi.location.lng, e.poi.location.lat],
address: e.poi.name,
name: e.poi.name,
longitude: e.poi.location.lng,
latitude: e.poi.location.lat
}
}
}
}
function save() {
let range = []
let centre_lon=''
let centre_lat=''
if (data.polyEditor && formData.type == '多边形') {
const path = data.polyEditor.getTarget().getPath()
if (path.length > 0) {
for (let i = 0; i < path.length; i++) {
console.log(path[i].getLng())
range.push({
longitude: path[i].getLng(),
latitude: path[i].getLat()
});
}
}
}else if(data.circleEditor && formData.type == '圆形'){
const center = data.circleEditor.getTarget().getCenter()
centre_lon=center.getLng()
centre_lat=center.getLat()
}
let params = {
name: formData.name,
range: range,
type: formData.type,
status: formData.status,
weigh: formData.weigh,
centre_lon:centre_lon,
centre_lat:centre_lat,
radius:formData.radius
}
}
</script>
<style scoped>
</style>