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]) return

  mask = 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]) return

  crop = 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

📚 参考资料


✅ 总结

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

  • 🖌 绘制任意形状区域;

  • ✏️ 对区域编辑修改;

  • 🟥 地图遮罩显示;

  • ✂️ 地图裁剪显示;

  • ♻️ 功能复原与清除。

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


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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

吉檀迦俐

你的鼓励奖是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值