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

106.在 Vue3 中使用 OpenLayers 动态添加 Layer 到 LayerGroup,并动态删除

一、前言

在 Web GIS(地理信息系统)开发中,OpenLayers 作为一款强大的开源地图库,广泛应用于二维地图的渲染、交互和分析。在 Vue3 结合 OpenLayers 的开发过程中,我们经常需要动态管理图层(Layer),比如按需添加或删除某些图层。

本篇文章将介绍如何在 Vue3 中使用 OpenLayers 以 Composition API 的方式实现动态管理 LayerGroup,包括添加、删除 Layer,并进行代码优化。

二、技术栈

  • Vue 3 + Composition API

  • OpenLayers

  • Element Plus(用于 UI 交互)

  • Vite(开发环境)

三、实现效果

我们将实现如下功能:

  1. 地图加载:初始化 OpenLayers 地图。

  2. LayerGroup 管理:创建 LayerGroup,并动态管理图层。

  3. 添加图层:点击按钮,向 LayerGroup 中添加图层。

  4. 删除图层:点击按钮,动态从 LayerGroup 中移除图层。

最终的效果如下:


四、完整代码

1. 项目初始化

如果你还没有 Vue 3 项目,可以使用 Vite 快速创建一个 Vue 3 项目:

npm create vite@latest vue3-openlayers-demo --template vue
cd vue3-openlayers-demo
npm install

安装 OpenLayers 依赖:

npm install ol

安装 Element Plus(可选):

npm install element-plus

2. 代码实现

2.1 App.vue 代码
<!--
 * @Author: 彭麒
 * @Date: 2025/3/25
 * @Email: 1062470959@qq.com
 * @Description: 此源码版权归吉檀迦俐所有,可供学习和借鉴或商用。
 -->  
<template>
  <div class="container">
    <div class="w-full flex justify-center">
      <div class="font-bold text-[24px]">在Vue3中使用OpenLayers动态添加layer到layerGroup,并动态删除</div>
    </div>
    <h4>
			<span v-for="(item, index) in pointData" :key="index">
				<el-button type="danger" v-show="item.isShow" size="small" @click="removegpLayer(item)">
					删除{{ item.myname }}
				</el-button>
				<el-button type="primary" v-show="!item.isShow" size="small" @click="addgpLayer(item)">
					添加{{ item.myname }}
				</el-button>
			</span>
    </h4>
    <div id="vue-openlayers"></div>
  </div>
</template>

<script setup>
import { ref, onMounted } from "vue";
import "ol/ol.css";
import { Map, View } from "ol";
import Tile from "ol/layer/Tile";
import GroupLayer from "ol/layer/Group";
import OSM from "ol/source/OSM";
import LayerVector from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import Feature from "ol/Feature";
import Point from "ol/geom/Point";
import Fill from "ol/style/Fill";
import Stroke from "ol/style/Stroke";
import Style from "ol/style/Style";
import Circle from "ol/style/Circle";

const pointData = ref([
  {
    myname: "layer1",
    point: [114.064839, 22.548857],
    isShow: false,
  },
  {
    myname: "layer2",
    point: [114.074839, 22.548857],
    isShow: false,
  },
]);

const map = ref(null);
const geoGroupLayer = new GroupLayer({
  layers: [],
  zIndex: 3,
  myname: "geoGroupLayer",
});

const removegpLayer = (data) => {
  data.isShow = !data.isShow;
  const layers = geoGroupLayer.getLayers().getArray();
  for (let i = layers.length - 1; i >= 0; i--) {
    if (layers[i].get("myname") === data.myname) {
      layers.splice(i, 1);
    }
  }
  map.value.removeLayer(geoGroupLayer);
  map.value.addLayer(geoGroupLayer);
};

const addgpLayer = (data) => {
  map.value.removeLayer(geoGroupLayer);
  let pointFeature = new Feature({
    geometry: new Point(data.point),
  });
  let pointsource = new VectorSource({
    wrapX: false,
  });
  pointsource.addFeature(pointFeature);
  let vector = new LayerVector({
    myname: data.myname,
    source: pointsource,
    style: new Style({
      fill: new Fill({
        color: [255, 255, 255, 0.00001],
      }),
      stroke: new Stroke({
        width: 2,
        color: "#00f",
      }),
      image: new Circle({
        radius: 10,
        fill: new Fill({
          color: "#ff00ff",
        }),
      }),
    }),
  });
  geoGroupLayer.getLayers().getArray().push(vector);
  data.isShow = !data.isShow;
  map.value.addLayer(geoGroupLayer);
};

const initMap = () => {
  let raster = new Tile({
    source: new OSM(),
    myname: "OSM",
  });
  map.value = new Map({
    target: "vue-openlayers",
    layers: [raster],
    view: new View({
      projection: "EPSG:4326",
      center: [114.064839, 22.548857],
      zoom: 13,
    }),
  });
};

onMounted(() => {
  initMap();
});
</script>

<style scoped>
.container {
  width: 840px;
  height: 590px;
  margin: 50px auto;
  border: 1px solid #42B983;
}

#vue-openlayers {
  width: 800px;
  height: 400px;
  margin: 0 auto;
  border: 1px solid #42B983;
  position: relative;
}
</style>

五、总结

在本篇文章中,我们介绍了 Vue3 结合 OpenLayers 动态管理 LayerGroup 的方法,并优化了代码结构,主要包括:

  1. 使用 Composition API 组织代码,使逻辑更清晰

  2. 优化 LayerGroup 操作,减少 removeLayer/addLayer 频率,提高性能

  3. 使用 OpenLayers 提供的 layers.remove(layer) 代替数组 splice,避免引用问题

希望本篇文章对你的 Vue3 + OpenLayers 项目有所帮助!欢迎点赞、收藏、评论交流!🎉


http://www.kler.cn/a/600821.html

相关文章:

  • 第 5 章 | Solidity 合约中的整数溢出与精度陷阱全解析
  • 笔记整理三
  • 开源模型应用落地-语音转文本-whisper模型-AIGC应用探索(五)
  • 最大连续子序列和(动态规划 -- 经典Kadane算法)
  • 可视化工程项目管理软件:让复杂工程数据一目了然
  • rabbitmq承接MES客户端服务器
  • sourcetree中的“master“,“origin/master“,“origin/HEAD“这三个图标都是什么意思?GIT 超详细➕通俗易懂版本
  • influxdb在centOS stream 9安装教程
  • 3、孪生网络/连体网络(Siamese Network)
  • <KeepAlive>和<keep-alive>有什么区别
  • 基于51单片机的多点位水位监测proteus仿真
  • Java学习总结-Stream流
  • 微信小程序中使用WebSocket通信
  • 使用Python爬虫获取1688商品(按图搜索)接口
  • 状态空间模型解析 (State-Space Model, SS)
  • 人工智能与区块链融合:开启数字信任新时代
  • (一)LeetCode热题100——哈希
  • 家庭网络结构之局域网通信
  • 监控告警+webhook一键部署
  • PAT乙级1007