欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 健康 > 美食 > 84.在 Vue 3 中使用 OpenLayers 实现列表与图层互相提示信息功能

84.在 Vue 3 中使用 OpenLayers 实现列表与图层互相提示信息功能

2025/6/8 23:26:26 来源:https://blog.csdn.net/Miller777_/article/details/145609386  浏览:    关键词:84.在 Vue 3 中使用 OpenLayers 实现列表与图层互相提示信息功能

在 Web GIS 开发中,我们经常需要实现 列表与地图图层的联动,例如当鼠标悬停在列表项时,高亮对应的地图区域,或者鼠标移动到地图区域时,列表项也同步变化。在 Vue 3 中,我们可以使用 OpenLayers 轻松实现这个功能。

本文将详细介绍如何使用 Vue 3 的 Composition API 结合 OpenLayers,实现 列表与图层互相提示的功能,包括:

  • 实现 Vue 3 组件化开发
  • 使用 OpenLayers 绘制区域
  • 鼠标悬停列表项时高亮地图区域
  • 鼠标移动到地图区域时同步列表高亮

最终效果如下:

当鼠标悬停在列表项时,地图上会高亮对应的区域;当鼠标移动到地图上的某个区域时,列表项也会同步高亮。


1. 项目初始化与依赖安装

如果你的 Vue 3 项目还没有安装 OpenLayers,可以使用以下命令进行安装:

npm install ol

或者使用 yarn

yarn add ol

2. 代码实现

2.1 组件结构

在 Vue 3 组件中,我们主要使用:

  • Vue 3 Composition API
  • OpenLayers 创建地图
  • OpenLayers 绘制区域
  • 鼠标交互事件
<!--* @Author: 彭麒* @Date: 2025/2/13* @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><span v-for="(item, index) in list" :key="index" style="margin: 0 10px;"><el-link :type="item.show ? 'primary' : 'danger'"@mouseover="showTip(index, item.area)"@mouseleave="closeTip(index)">{{ item.descName }}</el-link></span></h4><div id="vue-openlayers"></div></div>
</template><script setup>
import 'ol/ol.css';
import {onMounted, ref} from "vue";
import {Map, View} from "ol";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import OSM from "ol/source/OSM";
import Feature from "ol/Feature";
import {Polygon} from "ol/geom";
import Style from "ol/style/Style";
import Fill from "ol/style/Fill";
import Stroke from "ol/style/Stroke";const map = ref(null);
const tipSource = ref(new VectorSource({wrapX: false}));
const list = ref([{layerName: "moni1",descName: "模拟区块1",show: true,area: [[139.6485790340825, 35.27194604343114],[139.6769740340825, 35.27194604343114],[139.6769740340825, 35.29464604343114],[139.6485790340825, 35.29464604343114],[139.6485790340825, 35.27194604343114]]},{layerName: "moni2",descName: "模拟板块2",show: true,area: [[139.6485790340825, 35.26013604343114],[139.6769740340825, 35.26013604343114],[139.6769740340825, 35.27294604343114],[139.6485790340825, 35.27294604343114],[139.6485790340825, 35.26013604343114]]}
]);const closeTip = (index) => {tipSource.value.clear();list.value[index].show = !list.value[index].show;
};const showTip = (index) => {list.value[index].show = !list.value[index].show;showTipLayer(index);
};const showTipLayer = (index) => {tipSource.value.clear();const tipFeature = new Feature({geometry: new Polygon([list.value[index].area]),});const tipStyle = new Style({stroke: new Stroke({color: "#f00",width: 3}),fill: new Fill({color: "rgba(255,0,0,0.1)"})});tipFeature.setStyle(tipStyle);tipSource.value.addFeature(tipFeature);
};const addVectorLayers = () => {const features = list.value.map((item, i) => {const feature = new Feature({geometry: new Polygon([item.area]),name: item.layerName,listindex: i});feature.setStyle(new Style({stroke: new Stroke({color: "#409eff", width: 2}),fill: new Fill({color: "rgba(255,0,0,0.1)"})}));return feature;});const vectorSource = new VectorSource({features});const vectorLayer = new VectorLayer({source: vectorSource, zIndex: 3});map.value.addLayer(vectorLayer);
};const hoverFeature = () => {map.value.on("pointermove", (e) => {if (e.dragging) return;const feature = map.value.forEachFeatureAtPixel(e.pixel, (feature) => feature);map.value.getTargetElement().style.cursor = feature ? "pointer" : "auto";if (feature) {const index = feature.get("listindex");list.value.forEach((item, i) => (item.show = i !== index));} else {list.value.forEach((item) => (item.show = true));}});
};const initMap = () => {const OSM_Layer = new TileLayer({source: new OSM()});const tipLayer = new VectorLayer({source: tipSource.value, zIndex: 10000});map.value = new Map({target: "vue-openlayers",layers: [OSM_Layer, tipLayer],view: new View({projection: "EPSG:4326",center: [139.6485790340825, 35.27194604343114],zoom: 14})});addVectorLayers();hoverFeature();
};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>

3. 总结

本文介绍了如何使用 Vue 3 + OpenLayers 实现 列表与地图图层的联动效果。核心思路:

  1. 使用 OpenLayers 绘制多边形区域
  2. 监听鼠标事件,实现列表和地图的交互
  3. 使用 Vue 3 Composition API 进行状态管理

希望本文能对你有所帮助!如果有任何问题,欢迎交流 😊

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词