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

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.lryc.cn/news/2395127.html

相关文章:

  • 4.8.4 利用Spark SQL实现分组排行榜
  • 40. 自动化异步测试开发之编写异步业务函数、测试函数和测试类(类写法)
  • 【五子棋在线对战】一.前置知识的了解
  • 历年中国科学技术大学计算机保研上机真题
  • 内联盒模型基本概念?——前端面试中的隐形考点剖析
  • HackMyVM-Art
  • 网页前端开发(基础进阶1)
  • const ‘不可变’到底是值不变还是地址不变
  • 如何找到一条适合自己企业的发展之路?
  • Vue-数据监听
  • 当前用户的Git全局配置情况:git config --global --list
  • AI生态警报:MCP协议风险与应对指南(中)——MCP Server运行时安全​​
  • day15 leetcode-hot100-29(链表8)
  • DeepSeek 赋能文化遗产数字化修复:AI 重构千年文明密码
  • MonitorSDK_性能监控(从Web Vital性能指标、PerformanceObserver API和具体代码实现)
  • Spring Boot整合JWT实现认证与授权
  • 在 Linux 系统上连接 GitHub 的方法 (适用2025年)
  • 解决matlab两个库文件名冲突的问题
  • PHP 垃圾回收机制解析与应用案例
  • es6 函数解构
  • offset三大家族
  • RSTP介绍加实操
  • Elasticsearch父子关系解析
  • 33、请求处理【源码分析】Servlet API参数解析原理
  • 基于深度学习的三维图像生成项目开发方案
  • 面试题——计算机网络:HTTP和HTTPS的区别?
  • Flutter 包依赖升级指南:让项目保持最新状态
  • LeeCode 98. 验证二叉搜索树
  • JVM类加载高阶实战:从双亲委派到弹性架构的设计进化
  • [网页五子棋][用户模块]数据库设计和配置(MyBatis)、约定前后端交互接口、服务器开发