vue3+element-plus 高德地图电子围栏

本文介绍了如何在Vue3项目中集成ElementPlus库,实现基于高德地图的电子围栏功能,包括地址输入、地图点击事件、形状选择(圆形或多边形)、以及围栏状态和权重的设置。
摘要由CSDN通过智能技术生成

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: '多边形',
			},
			// {
			// 	type: 2,
			// 	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": "", // 申请好的Web端开发者Key,首次调用 load 时必填
		"version": "2.0", // 指定要加载的 JS API 的版本,缺省时默认为 1.4.15
		"plugins": ['AMap.Scale', 'AMap.Driving', 'AMap.PlaceSearch',
			'AMap.AutoComplete', 'AMap.PolygonEditor', 'AMap.CircleEditor'
		], // 需要使用的的插件列表,如比例尺'AMap.Scale'等
		"AMapUI": { // 是否加载 AMapUI,缺省不加载
			"version": '1.1', // AMapUI 版本
			"plugins": [], // 需要加载的 AMapUI ui插件
		},
		"Loca": { // 是否加载 Loca, 缺省不加载
			"version": '2.0' // Loca 版本
		},
	}).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.map.remove(data.polyEditor)
			data.polyEditor.close();
		}
		if (data.circle) {
			data.map.remove(data.circle);
			// data.map.remove(data.polyEditor)
			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.map.remove(data.polyEditor)
			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) {
		// var centerLng = e.lnglat.getLng();
		// var centerLat = e.lnglat.getLat();
		if (formData.type == '多边形') {
			var radius = 0.01; // 假设三角形的边长为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.map.remove(data.polyEditor)
				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],
				// 线样式还支持 'dashed'
				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);
			});

			// 定义拖动起始点的偏移量
			// var offsetX = 0;
			// var offsetY = 0;

			// data.circle.on('mousedown', function(event) {
			// 	console.log(1112222)
			//   // 计算鼠标按下的点相对于圆心的偏移量
			//   offsetX = event.pixel.x - event.target.getCenter().x;
			//   offsetY = event.pixel.y - event.target.getCenter().y;

			//   // 监听鼠标移动事件
			//   data.map.on('mousemove', moveCircle);
			// });

			// // 监听地图的鼠标抬起事件
			// data.map.on('mouseup', function() {
			//   // 停止监听鼠标移动事件
			//   data.map.off('mousemove', moveCircle);
			// });


			// // 定义拖动圆形的函数
			// function moveCircle(event) {
			//   // 计算新的圆心坐标
			//   var newCenter = data.map.containerToLngLat(new window.AMap.Pixel(event.pixel.x - offsetX, event.pixel.y - offsetY));

			//   // 更新圆形的位置
			//   data.circle.setCenter(newCenter);
			// }

		}
	}

	function setInput(point, pointArr, index = -1) {
		var autoPoint = new window.AMap.AutoComplete({
			input: point // 使用 $refs 来获取 el-input 对应的 DOM 元素
		});
		autoPoint.on("select", select); //注册监听,当选中某条记录时会触发
		function select(e) {
			if (e.poi && e.poi.location == '') {
				var placeSearch = new window.AMap.PlaceSearch({
					// city 指定搜索所在城市,支持传入格式有:城市名、citycode和adcode
					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>
  • 10
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Vue 3.0+Element-Plus开发后台管理系统的步骤: 1.首先,确保你已经安装了Node.js和npm包管理器。 2.使用以下命令安装Vue CLI 4: ```shell npm install -g @vue/cli ``` 3.使用Vue CLI创建一个新项目: ```shell vue create my-project ``` 4.在创建项目时,选择使用Vue 3.0版本,并启用class-style component语法: ```shell ? Please pick a preset: Manually select features ? Check the features needed for your project: Choose Vue version, Babel, Router, Vuex, CSS Pre-processors, Linter, Unit ? Choose a version of Vue.js that you want to start the project with 3.x (Preview) ? Use class-style component syntax? Yes ? Use Babel alongside TypeScript (required for modern mode, auto-detected polyfills, transpiling JSX)? No ? Use history mode for router? (Requires proper server setup for index fallback in production) Yes ? Pick a CSS pre-processor (PostCSS, Autoprefixer and CSS Modules are supported by default): Sass/SCSS (with dart-sass) ? Pick a linter / formatter config: ESLint with error prevention only ? Pick additional lint features: Lint on save ? Where do you prefer placing config for Babel, ESLint, etc.? In dedicated config files ``` 5.安装Element-Plus和Echarts 5.0: ```shell npm install element-plus echarts@5.0 ``` 6.在main.js中引入Element-Plus和Echarts: ```javascript import { createApp } from 'vue' import App from './App.vue' import router from './router' import store from './store' import ElementPlus from 'element-plus' import 'element-plus/lib/theme-chalk/index.css' import echarts from 'echarts' const app = createApp(App) app.use(store) app.use(router) app.use(ElementPlus) app.config.globalProperties.$echarts = echarts app.mount('#app') ``` 7.现在你可以开始使用Element-Plus和Echarts来开发你的后台管理系统了。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值