【整理一下vue3+ts+openlayer+plot实现多边形绘制的功能代码,有关openlayer的引入、创建图层、加载地图等基础方法在此不做详述】
一、安装依赖
1、ol
npm install ol
2、plot
npm install plot-ol
!Tips!
可以在控制台输入命令安装,也可以通过vue项目管理可视化页面进行安装,个人倾向于用可视化页面安装,具体方法为:
(1)win+r 打开控制台
(2)输入 vue ui
(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();
}
}