【Vue3+ts+OL+Plot】地图绘制多边形、还原多边形等

【整理一下vue3+ts+openlayer+plot实现多边形绘制的功能代码,有关openlayer的引入、创建图层、加载地图等基础方法在此不做详述】

一、安装依赖

1、ol

npm install ol

2、plot

npm install plot-ol

!Tips!

可以在控制台输入命令安装,也可以通过vue项目管理可视化页面进行安装,个人倾向于用可视化页面安装,具体方法为:

(1)win+r 打开控制台
(2)输入 vue ui

启动后访问8000

(3)导入项目,选择依赖,进行安装

在这里插入图片描述在这里插入图片描述

二、plot介绍

由于我对该组件使用频率不高,在此仅对我了解的功能进行介绍,其他的后续用到了再补充

1、文件目录

在这里插入图片描述

由于plot组件是js开发的,我要在ts项目使用,加上考虑到后期可能会修改源码实现自定义需求,所以我把src文件夹下的内容拷贝出来放在项目中,目录结构如下图

在这里插入图片描述

2、js转ts并引入项目

复制index.js文件,改名为index.d.ts,就把plot由js转ts了

在这里插入图片描述

3、使用

(1)vue页面引入plot
import POL from '@/utils/draw/index';
(2)在创建地图时实例化POL图层
a. 引入ol时记得改成plot内的OL,否则页面会有2个地图,plot图层展示不出来
b. 声明g_pol_layer的时候要用reactive,g_pol_layer本质是个VectorLayer,用ref的话会改变g_pol_layer类型为Proxy,会无法使用ol.layer.Vector的方法(如setZIndex等)
c. 地图双击事件会和绘制结束事件冲突,因此建议禁用(若实在有双击事件,那么可以加个绘制状态,根据该flag判断双击处理逻辑)
//引入plot内的OL,否则页面会有2个地图,plot图层展示不出来,如有疑问,直接把
let ol = POL.OL;
/**
 * 初始化地图
 */
function initMap() {
	thresholdMapView = new View({
		center: proj.fromLonLat([121.51, 31.25]), // 默认加载全国
		projection: 'EPSG:3857', //3857:web球面墨卡托投影  4326:经纬度投影  同属于WGS84地理坐标系
		zoom: 8.5,
		minZoom: 4
	});
	thresholdMap = new Map({
		target: 'threshold-map',
		controls: defaults({ attribution: false, zoom: false, rotate: false }),
		view: thresholdMapView,
		//禁用双击地图缩放事件(会和绘制多边形确定事件冲突)
		interactions: new ol.interaction.defaults({
			doubleClickZoom: false
		})
	});
	initPlot(thresholdMap);
	initMapLayer(thresholdMap);
	initMapEvent(thresholdMap);
}

//必须用reactive声明,g_pol_layer本质是个layer,用ref的话会改变g_pol_layer类型为Proxy
let g_pol_layer: any = reactive({});
/**
 * 初始化plot图层
 */
function initPlot(map: any) {
	g_pol_layer = new POL.PlottingLayer(map);
	g_pol_layer.showLayer.setZIndex(5);
	let g_op_feature = null;
	//激活绘制
	g_pol_layer.on(POL.FeatureOperatorEvent.ACTIVATE, function(e: any) {
		g_op_feature = e.feature_operator;

		let fill_color = fillColor.value ? fillColor.value : 'rgba(17, 0, 0, 0)';
		let border_color = borderColor.value ? borderColor.value : 'rgba(0,0,255,100)';
		let strStyle = `{"fill":{"color":"` + fill_color + `"},"stroke":{"color":"` + border_color + `","width":2}}`;
		let strValue = JSON.parse(strStyle);
		if (g_op_feature) {
			g_op_feature.setStyle(strValue);
		}
		g_op_feature.disable(); //设置绘制的要素不可点击
	});
	//关闭绘制
	g_pol_layer.on(POL.FeatureOperatorEvent.DEACTIVATE, function(e: any) {
		g_op_feature = null;
		// clearPolygons();
	});
}
(3)开始绘制多边形
function drawPolygon() {
	g_pol_layer.addFeature(POL.PlotTypes.CLOSED_CURVE); //绘制闭合曲线多边形
}

在这里插入图片描述

(4)还原多边形到地图上
/**
 * 还原图形
 * @param layer  eg.g_pol_layer.showLayer
 * @param saveGraphicInfo eg.'[{"type":"closedcurve","points":[[13472416.929994777,3634563.6944394354],[13509106.703571662,3698431.0863672197],[13579089.057762261,3628448.732176621]],"fill":{"color_":"rgba(0,255,0,0.2)"},"stroke":{"color_":"rgba(255, 0, 0, 1)","lineDash_":null,"width_":1}}]',
 */
function restoreGraphic(layer: any, saveGraphicInfo: any) {
	if (saveGraphicInfo.length > 0) {
		for (let i = 0; i < saveGraphicInfo.length; i++) {
			let curVo = saveGraphicInfo[i];
			let style = new ol.style.Style({
				fill: new Fill({ color: curVo.fill?.color_ !== undefined ? curVo.fill.color_ : fillColor.value }),
				stroke: new Stroke({
					color: curVo.stroke?.color_ !== undefined ? curVo.stroke.color_ : borderColor.value,
					width: curVo.stroke?.width_ !== undefined ? curVo.stroke.width_ : 2
				}),
				zIndex: 14
			});
			let plotGraphic = POL.PlotFactory.createPlot(curVo.type, curVo.points);
			let newFeature = new ol.Feature(plotGraphic);
			newFeature.setStyle(style);
			layer.getSource().addFeature(newFeature);
		}
	}
}
(5)清空图层要素

/**
 * 清除图形
 */
function clearPolygons() { 
	let drawLayer = g_pol_layer.showLayer;
	//全部清空
	if (drawLayer) {
		if (drawLayer.getSource()) {
			let vectorSource = new ol.source.Vector({
				features: []
			});
			drawLayer.setSource(vectorSource);
		}
		g_pol_layer.plotEdit.deactivate();
	}
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值