当前位置: 首页 > java >正文

133.在 Vue3 中使用 OpenLayers 实现画多边形、任意编辑、遮罩与剪切处理功能

🎬 效果演示截图(先睹为快)

✨ 功能概览:

  • ✅ 鼠标画任意形状多边形;

  • ✏️ 点击“修改边界”可拖动顶点;

  • 🟥 点击“遮罩”后地图除多边形区域外变红;

  • ✂️ 点击“剪切”后仅显示选中区域;

  • ❌ 点击“取消”按钮恢复地图。

📸 示例截图如下(运行后效果类似):


🧭 项目背景

在地图可视化开发中,我们常常需要:

  • 用户绘制特定区域(如选区、高亮区);

  • 支持图形的交互编辑;

  • 结合遮罩或剪切来突出或限制显示区域。

本篇教程将通过 Vue3 + OpenLayers + ol-ext 来实现这套完整功能,适合用于城市规划、环境监控、园区展示等场景。


🧱 技术栈介绍

技术说明
Vue 3使用 Composition API 编写组件
OpenLayers地图渲染与交互处理
ol-extOpenLayers 的扩展库,支持遮罩/剪切等高级效果
Element PlusUI 组件库,支持按钮操作


📦 初始化项目

安装必要依赖:

npm install ol ol-ext element-plus

💻 核心功能组件源码(DrawMaskCrop.vue)

以下是完整的组件代码,使用 Vue Composition API 编写,实现画图、编辑、遮罩、剪切、清除等功能。

<!--* @Author: 彭麒* @Date: 2025/5/29* @Email: 1062470959@qq.com* @Description: 此源码版权归吉檀迦俐所有,可供学习和借鉴或商用。-->
<template><div class="container"><div class="w-full flex justify-center flex-wrap"><div class="font-bold text-[24px]">在Vue3中使用OpenLayers画多边形,任意编辑,并做遮罩剪切处理</div></div><h4><el-button type="primary" size="small" @click="drawPolygon">画多边形</el-button><el-button type="warning" size="small" @click="startModify">修改边界</el-button><el-button type="warning" size="small" @click="endModify">停止编辑</el-button><el-button type="success" size="small" @click="mapmask">遮罩</el-button><el-button type="success" size="small" @click="mapcrop">剪切</el-button><el-button type="danger" size="small" @click="cancelMaskCrop">取消</el-button></h4><div id="vue-openlayers"></div></div>
</template><script setup>
import {onMounted } from 'vue'
import 'ol/ol.css'
import 'ol-ext/dist/ol-ext.min.css'
import { Map, View } from 'ol'
import OSM from 'ol/source/OSM'
import TileLayer from 'ol/layer/Tile'
import LayerVector from 'ol/layer/Vector'
import SourceVector from 'ol/source/Vector'
import Fill from 'ol/style/Fill'
import Stroke from 'ol/style/Stroke'
import Style from 'ol/style/Style'
import Mask from 'ol-ext/filter/Mask'
import Crop from 'ol-ext/filter/Crop'
import Draw from 'ol/interaction/Draw'
import Modify from 'ol/interaction/Modify'
let map,osmLayer,mask,crop,draw,modify = null
const source = new SourceVector({ wrapX: false })
const initMap = () => {osmLayer = new TileLayer({source: new OSM()})const vectorLayer = new LayerVector({source,style: new Style({fill: new Fill({ color: 'transparent' }),stroke: new Stroke({ width: 2, color: 'blue' })})})map = new Map({layers: [osmLayer, vectorLayer],view: new View({center: [116, 39.5],zoom: 8,projection: 'EPSG:4326'}),target: 'vue-openlayers'})
}const drawPolygon = () => {source.clear()if (draw) map.removeInteraction(draw)draw = new Draw({source,type: 'Polygon'})map.addInteraction(draw)draw.on('drawend', () => {map.removeInteraction(draw)})
}const startModify = () => {modify = new Modify({ source })map.addInteraction(modify)
}const endModify = () => {if (modify) {map.removeInteraction(modify)}
}const cancelMaskCrop = () => {if (mask) mask.set('active', false)if (crop) crop.set('active', false)
}const mapmask = () => {cancelMaskCrop()const features = source.getFeatures()if (!features[0]) returnmask = new Mask({feature: features[0],wrapX: true,inner: false,fill: new Fill({ color: [255, 0, 0, 0.5] })})osmLayer.addFilter(mask)
}const mapcrop = () => {cancelMaskCrop()const features = source.getFeatures()if (!features[0]) returncrop = new Crop({feature: features[0],wrapX: true,inner: false})osmLayer.addFilter(crop)
}onMounted(() => {initMap()
})
</script><style scoped>
.container {width: 840px;height: 570px;margin: 50px auto;border: 1px solid #42B983;
}#vue-openlayers {width: 800px;height: 400px;margin: 0 auto;border: 1px solid #42B983;position: relative;
}
</style>

🔍 核心功能说明

功能实现方式
多边形绘制使用 ol/interaction/Draw
图形编辑使用 ol/interaction/Modify
遮罩效果使用 ol-ext/filter/Mask
剪切效果使用 ol-ext/filter/Crop
功能取消设置遮罩与剪切 filter 的 active=false

📚 参考资料

  • 🔗 OpenLayers 官网

  • 🔗 ol-ext 官方 Demo

  • 🔗 Element Plus 组件库

  • 📖 EPSG:4326 vs EPSG:3857 坐标系介绍


✅ 总结

本文通过 Vue 3 + OpenLayers + ol-ext 完整实现了:

  • 🖌 绘制任意形状区域;

  • ✏️ 对区域编辑修改;

  • 🟥 地图遮罩显示;

  • ✂️ 地图裁剪显示;

  • ♻️ 功能复原与清除。

以上能力在城市管理、规划分析、地图可视化等场景中有广泛应用,值得收藏并实践!


如果你觉得本篇内容对你有帮助,欢迎点赞、收藏、评论支持一下!
后续我将继续分享 Vue + OpenLayers 的实战经验与技巧,如图层控制、热力图、轨迹动画等,欢迎关注!

http://www.xdnf.cn/news/9802.html

相关文章:

  • 算法题(158):牛栏预定
  • 【Java orm框架对比】十四新增gaarason/database-all框架对比
  • 解释滚动更新的过程,如何通过`kubectl set image`命令触发更新? 版本回滚的命令是什么?如何查看Deployment的更新历史?
  • 打印机无法远程打印?可以本地打印,本地网络打印机设置给异地使用
  • LangChain【1】之认识框架和简单体验
  • LeetCode Hot100(多维动态规划)
  • vmware虚拟机固定IP
  • const 用法总结
  • TortoiseSVN账号切换
  • 动态规划-152.乘积最大子数组-力扣(LeetCode)
  • Python训练营打卡 Day38
  • 信奥赛-刷题笔记-二分篇-T2-P1918保龄球0529
  • 纵览网丨新视角下的黑洞探索:传统奇点理论的挑战与未来观测的可能性
  • 进程控制与调度下
  • React 编译器 RC
  • Typescript学习教程,从入门到精通,TypeScript 泛型与类型操作详解(二)(17)
  • 数字取证-E01转vmdk
  • 区间DP概述(JAVA)
  • 若依框架 账户管理 用户分配界面解读
  • 纤维组织效应偏斜如何影响您的高速设计
  • 资产生命周期管理:动态监控 + 精准管理
  • 爬虫框架:scrapy使用心得
  • PABD 2025:大数据与智慧城市管理的融合之道
  • 数字孪生技术赋能西门子安贝格工厂:全球智能制造标杆的数字化重构实践
  • Linux -- 进程地址空间
  • 高速连接器设计的真相
  • $3 #12阶段三小结Java se
  • 【经验】Ubuntu中设置terminator的滚动行数、从Virtualbox复制到Windows时每行后多一空行
  • android studio debug调试出现 IOException异常
  • 智能厨房系统—御控物联网IoT平台