腾讯地图绘制电子围栏

腾讯地图在弹框中绘制电子围栏 vue3+elementPlus

参考腾讯地图官方示例:https://lbs.qq.com/webDemoCenter/glAPI/glEditor/toolDraw
https://lbs.qq.com/webApi/javascriptGL/glGuide/glGeometry
效果图
父组件中通过点击按钮打开弹框,配置相关表单信息及地图选点、围栏绘制
父组件

<el-button type="primary" plain @click="openForm('create')">
	新增
</el-button>
/** 添加/修改操作 */
const formRef = ref()
const openForm = (type: string, id?: number) => {
  formRef.value.open(type, id)
}

子组件弹框

<Dialog v-model="dialogVisible" :title="dialogTitle" width="940">
	<el-row>
		<el-col :span="8">
			<el-form ref="formRef" v-loading="formLoading" :model="formData" :rules="formRules" label-width="110px">
				<el-form-item label="名称" prop="name">
					<el-input v-model="formData.name" placeholder="请输入" />
				</el-form-item>
			</el-form>
		</el-col>
		<el-col :span="15" :offset="1">
			<!-- 地图渲染的容器 -->
			<div id="container" ref="mapbox"></div>
			<!-- 地图编辑的控件 -->
			<div id="toolControl">
				<div class="toolItem active" id="marker" title="点标记"></div>
				<div class="toolItem" id="polygon" title="多边形"></div>
				<div class="toolItem" id="circle" title="圆形"></div>
				<div class="toolItem" id="rectangle" title="矩形"></div>
				<div class="toolItem" id="ellipse" title="椭圆"></div>
			</div>
			<div class="btn-operation">	
				<el-radio-group v-model="editorStatus" @change="editorStatusChange">
					<el-radio label="draw" value="draw">绘制状态</el-radio>
					<el-radio label="edit" value="edit">编辑状态</el-radio>
				</el-radio-group>
				<el-button type="primary" plain id="delete" size="small" @click="editor.delete()" v-show="isShowDelete">删除</el-button>
			</div>
			<div class="tip custom-block" v-if="!isShowDelete">
				<p>绘制:鼠标左键点击及移动即可绘制图形</p>
				<p>结束绘制:鼠标左键双击即可结束绘制折线、多边形会自动闭合;圆形、矩形、椭圆单击即可结束</p>
				<p>中断:绘制过程中按下esc键可中断该过程</p>
			</div>
			<div class="tip custom-block" v-else>
				<p>编辑:鼠标单击选中驻点或围栏进入编辑状态</p>
				<p>结束编辑:点击绘制状态即可结束</p>
				<p>删除:选中驻点或围栏后点击删除按钮,即可进行删除</p>
			</div>
		</el-col>
	</el-row>
	<template #footer>
		<el-button :disabled="formLoading" type="primary" @click="submitForm">确 定</el-button>
		<el-button @click="handleOff">取 消</el-button>
	</template>
</Dialog>

在子组件中定义open打开弹窗的方法。
注意:因为Dialog弹窗组件不打开时不会加载dom结构,此处必须等地图渲染的容器container加载出来后再进行地图初始化。所以地图的初始化不能放在onMounted生命周期中进行,因为在onMounted中无法获取到容器container

/** 打开弹窗 */
const open = async (type: string, id?: number) => {
	dialogVisible.value = true
	dialogTitle.value = t('action.' + type)
	formType.value = type
	resetForm()
	// 切换激活图层
	document.getElementById('toolControl').addEventListener('click', (e) => {
		var id = e.target.id;
		if (id !== 'toolControl') {
			document.getElementById(activeType).className = 'toolItem';
			document.getElementById(id).className = 'toolItem active';
			activeType = id;

			editor.setActiveOverlay(id);
		}
	});

	setTimeout(()=>{
		// 初始化地图
		initMap();
	}, 10)
}
defineExpose({ open }) // 提供 open 方法,用于打开弹窗

重点在于地图的初始化

/* 地图初始化 */
const initMap = async () => {
	// 定义地图中心点坐标
	center.value = new TMap.LatLng(34.762115, 113.681975)

	// 1-定义map变量,调用 TMap.Map() 构造函数创建地图
	map = new TMap.Map(document.getElementById('container'), {
		center: center.value,//设置地图中心点坐标
		zoom: 14, //设置地图缩放级别
	});
	
	// 2-初始化几何图形及编辑器
	marker = new TMap.MultiMarker({
		map: map
	});
	polygon = new TMap.MultiPolygon({
		map: map,
		styles: {
			// 定义编辑状态下选中的样式
			highlight: new TMap.PolygonStyle({
				color: 'rgba(255, 255, 0, 0.6)'
			})
		}
	});
	circle = new TMap.MultiCircle({
		map: map,
		styles: {
			highlight: new TMap.CircleStyle({
				color: 'rgba(255, 255, 0, 0.6)'
			})
		}
	});
	rectangle = new TMap.MultiRectangle({
		map: map,
		styles: {
			highlight: new TMap.RectangleStyle({
				color: 'rgba(255, 255, 0, 0.6)'
			})
		}
	});
	ellipse = new TMap.MultiEllipse({
		map: map,
		styles: {
			highlight: new TMap.EllipseStyle({
				color: 'rgba(255, 255, 0, 0.6)'
			})
		}
	});
	
	editor = new TMap.tools.GeometryEditor({
		map: map, // 编辑器绑定的地图对象
		// 可编辑的图层
		overlayList: [
			{
				overlay: marker,
				id: 'marker',
			},
			{
				overlay: polygon,
				id: 'polygon',
				selectedStyleId: 'highlight',
			},
			{
				overlay: circle,
				id: 'circle',
				selectedStyleId: 'highlight'
			},
			{
				overlay: rectangle,
				id: 'rectangle',
				selectedStyleId: 'highlight'
			},
			{
				overlay: ellipse,
				id: 'ellipse',
				selectedStyleId: 'highlight'
			},
		],
		actionMode: TMap.tools.constants.EDITOR_ACTION.DRAW, // 编辑器的工作模式 DRAW INTERACT
		activeOverlayId: 'marker', // 激活图层
		snappable: true, // 开启吸附
		selectable: true,// 开启点选功能
	});
	// 监听绘制结束事件,获取绘制几何图形
	editor.on('draw_complete', (geometry) => {
		var id = geometry.id;
		if (editor.getActiveOverlay().id === 'marker') {
			// 获取标记坐标
			var geo = marker.geometries.filter(function (item) {
				return item.id === id;
			});
			marker.setGeometries([]); // 清空标记点
			// 更新标记点
			marker.updateGeometries({
				id: 'marker',
				position: geo[0].position
			});
		}
	});
	// 监听编辑事件
	editor.on('adjust_complete', evtResult => {});
	// 监听删除事件
	editor.on('delete_complete', evtResult => {
		if (evtResult[0].id == "marker") {}
	});
}
/* 单选按钮组改变 切换绘制和编辑状态 */
const editorStatusChange = (val)=>{
	if(val == 'draw'){
		// 绘制状态
		editor.setActionMode(2);
		isShowDelete.value = false;
	}else{
		// 编辑状态
		editor.setActionMode(1);
		isShowDelete.value = true;
	}
}
/* 绘制围栏 */
const drawFence = () => {
	editor.setActionMode(2)
}

/* 编辑围栏 */
const editFence = () => {
	editor.setActionMode(1)
}

获取标记点及围栏的数据

判断点是否在围栏中

提交表单时需要根据需求对围栏数据或标记点进行相应处理

/* 创建时驻点及围栏数据处理 */
const submitPoint = () => {
	// let resList = editor.getOverlayList();
	// 标记点数据处理
	let mRes = marker.getGeometries();
	// 多边形数据-0
	let pRes = polygon.getGeometries();
	// 圆形数据处理-1
	// let cRes = circle.getGeometries();
	let cRes = circle.geometries;
	// 矩形数据处理-2
	let rectRes = rectangle.geometries;
	// 椭圆数据处理-3
	let eRes = ellipse.getGeometries();
	
	// 判断驻点是否在围栏内
	var is = TMap.geometry.isPointInPolygon(point: LatLng, polygon: LatLng[]);
}

css样式

#container {
	/*地图(容器)显示大小*/
	width: 100%;
	height: 400px;
}

#toolControl {
	position: absolute;
	top: 40px;
	left: 300px;
	right: 0px;
	margin: auto;
	width: 252px;
	z-index: 1001;
}

.toolItem {
	width: 30px;
	height: 30px;
	float: left;
	margin: 1px;
	padding: 4px;
	border-radius: 3px;
	background-size: 30px 30px;
	background-position: 4px 4px;
	background-repeat: no-repeat;
	box-shadow: 0 1px 2px 0 #e4e7ef;
	background-color: #ffffff;
	border: 1px solid #ffffff;
}

.toolItem:hover {
	border-color: #789cff;
}

.active {
	border-color: #d5dff2;
	background-color: #d5dff2;
}

#marker {
	background-image: url('https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/marker_editor.png');
}

#polygon {
	background-image: url('https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/polygon.png');
}

#circle {
	background-image: url('https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/circle.png');
}

#rectangle {
	background-image: url('https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/rectangle.png');
}

#ellipse {
	background-image: url('https://mapapi.qq.com/web/lbs/javascriptGL/demo/img/ellipse.png');
}
  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要在微信小程序中使用腾讯地图绘制电子围栏,可以按照以下步骤操作: 1. 在小程序中引入腾讯地图 SDK,并在页面中创建地图实例。 2. 使用腾讯地图提供的 `createCircle` 方法创建一个圆形覆盖物,并设置覆盖物的中心点坐标、半径、线条颜色、填充颜色等属性。 3. 将圆形覆盖物添加到地图中,即可在地图上显示电子围栏。 4. 如果需要动态更新电子围栏的位置或半径,可以通过修改圆形覆盖物的属性实现。例如,调用 `setCenter` 方法更新中心点坐标,调用 `setRadius` 方法更新半径。 下面是一个简单的代码示例,可以在小程序的地图页面中使用: ```javascript // 引入腾讯地图 SDK const QQMapWX = require('../../libs/qqmap-wx-jssdk.min.js'); Page({ data: { map: null, // 地图实例 fence: null, // 电子围栏覆盖物 fenceCenter: { // 电子围栏中心点坐标 latitude: 39.908823, longitude: 116.397470 }, fenceRadius: 500 // 电子围栏半径 }, onLoad: function () { // 创建地图实例 const map = new QQMapWX({ key: 'your_map_api_key' }); // 在页面中创建地图实例 this.setData({ map: map }, () => { // 创建电子围栏覆盖物 const fence = this.data.map.createCircle({ latitude: this.data.fenceCenter.latitude, longitude: this.data.fenceCenter.longitude, radius: this.data.fenceRadius, strokeWidth: 2, strokeColor: '#FF0000', fillColor: '#FF000033' }); // 将电子围栏覆盖物添加到地图中 this.data.map.addOverlay(fence); // 保存电子围栏覆盖物对象 this.setData({ fence: fence }); }); }, // 更新电子围栏的位置和半径 updateFence: function () { // 修改电子围栏覆盖物的属性 this.data.fence.setCenter({ latitude: this.data.fenceCenter.latitude, longitude: this.data.fenceCenter.longitude }); this.data.fence.setRadius(this.data.fenceRadius); } }); ``` 需要注意的是,上述代码中的 `your_map_api_key` 需要替换为你自己的腾讯地图 API 密钥。另外,由于腾讯地图 SDK 的使用方式可能会有所变化,请参考腾讯地图官方文档进行开发。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值