141.在 Vue 3 中使用 OpenLayers Link 交互:把地图中心点 / 缩放级别 / 旋转角度实时写进 URL,并同步解析显示

本文分享一个前端小技巧:借助 OpenLayers 的 Link 交互 在浏览器地址栏实时记录地图状态,同时把这些参数解析出来展示在页面上。

  • 双向同步:拖动、缩放、旋转地图时,URL 自动更新;手动修改 URL 或后退 / 前进,也能把地图状态恢复。

  • Vue 3 + Composition API 全家桶写法,代码易拆易扩展。

  • ✨ 无需后端,纯前端即可玩转「场景定位」功能,适合 DEMO 分享、地图书签、协同定位等场景。


1️⃣ 效果演示

功能
地图操作 → URL 更新
改变 URL → 地图跳转
同步参数面板实时展示

2️⃣ 技术栈 & 版本

依赖版本说明
Vue^3.xComposition API
Vite^5.x构建工具,CLI 同理
OpenLayers^7.x地图渲染
MapTiler可选底图瓦片服务
TypeScript非必需文中示例使用原生 JS

3️⃣ 原理概述

  1. Link 交互

    import Link from 'ol/interaction/Link'
    map.addInteraction(new Link())
    
    • 监听 moveendrotateend 等事件,把 中心坐标(经纬度)、缩放级别、旋转角 写入 URL(?x=...&y=...&z=...&r=...)。

    • 支持浏览器前进 / 后退,自动恢复地图状态。

  2. window.addEventListener('popstate', …)

    • 捕捉地址栏变动(包括用户手动编辑 / 点击历史栈按钮)。

    • 调用自定义 parseUrlParams() 更新页面侧栏信息。

  3. 解析展示
    使用 URLSearchParams + 可选哈希解析,将参数列表渲染到 <div class="url-info"> 中,实时可视化。


4️⃣ 完整代码

4.1 目录结构建议

src/assets/components/pages/MapLinkDemo.vue   <- 本文示例main.js

4.2 MapLinkDemo.vue

一口气粘贴即可跑通(若使用 TS,把 refmap 类型补上即可)。

<!--* @Author: 彭麒* @Date: 2025/7/1* @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中使用Link在URL地址栏上显示地图中心点、zoom level、旋转角度信息</div></div><!-- 添加URL参数显示区域 --><div class="url-info"><h3>URL 参数信息:</h3><div v-if="urlParams.length > 0"><div v-for="(param, index) in urlParams" :key="index" class="param-item"><span class="param-name">{{ param.name }}:</span><span class="param-value">{{ param.value }}</span></div></div><div v-else>无参数</div></div><div id="vue-openlayers" ref="mapEl"></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 TileJSON from 'ol/source/TileJSON'
import Link from 'ol/interaction/Link' // 核心交互
import { DragRotateAndZoom, defaults as defaultInteractions } from 'ol/interaction'const mapEl = ref(null)
const urlParams = ref([])
let map = null// 解析 URL 参数
function parseUrlParams() {const searchParams = new URLSearchParams(window.location.search)const params = []searchParams.forEach((value, key) => {params.push({ name: key, value: value })})// 也可以提取哈希部分的参数const hash = window.location.hash.substring(1)if (hash) {const hashParams = new URLSearchParams(hash)hashParams.forEach((value, key) => {params.push({ name: `hash:${key}`, value: value })})}urlParams.value = params
}// 初始化底图
function loadMapTiler(type = 'streets') {// 清空原有图层map.getLayers().getArray().forEach((layer) => {if (layer) map.removeLayer(layer)})const url = `https://api.maptiler.com/maps/${type}/tiles.json?key=RbTrJIUQMw0c6xtn6kZr`const source = new TileJSON({url: url,tileSize: 512,crossOrigin: 'anonymous'})const tileLayer = new Tile({ source })map.addLayer(tileLayer)
}// 初始化地图
function initMap() {map = new Map({target: mapEl.value,layers: [],view: new View({center: [13247019.404399557, 4721671.572580107],zoom: 3}),interactions: defaultInteractions().extend([new DragRotateAndZoom()])})// 添加 Link 交互:将地图状态同步到 URLmap.addInteraction(new Link())// 加载默认地图图层loadMapTiler('streets')// 初始解析URL参数parseUrlParams()// 添加URL变化监听window.addEventListener('popstate', parseUrlParams)// 监听地图移动事件,以便在地图变化时更新URL参数显示map.on('moveend', parseUrlParams)
}onMounted(() => {initMap()
})
</script><style scoped>
.container {width: 840px;margin: 50px auto;border: 1px solid #42B983;
}#vue-openlayers {width: 800px;height: 470px;margin: 0 auto;border: 1px solid #42B983;position: relative;
}.url-info {width: 800px;margin: 10px auto;padding: 10px;border: 1px dashed #42B983;background-color: #f5f5f5;
}.param-item {margin: 5px 0;
}.param-name {font-weight: bold;margin-right: 5px;
}.param-value {color: #1976d2;
}
</style>

5️⃣ 关键点拆解

玩法说明
Link()内置于 OpenLayers,自动将视图状态序列化到 URL,格式默认 ?x={lon}&y={lat}&z={zoom}&r={rotation}
浏览器历史栈popstate 事件可捕获前进 / 后退;利用 URL -> 地图状态的反向解析能力(Link 已帮你处理)
双向可视化解析函数既能给侧栏,也可用于调试 —— 一眼看到经纬度与缩放

6️⃣ 常见问题 & 解决方案

问题可能原因处理建议
地址栏参数是 EPSG:3857 值,看不懂默认投影为 Web Mercator 米制坐标修改 Link({ projection: 'EPSG:4326' }) 或手动转换
刷新后回到初始视图你手动把 center/zoom/rotation 写到组件初始化了,覆盖了历史initMap 前检测 URL,若含有效参数则省略初始视图
地址超长可自定义 Linkparams 过滤,只保留关键字段例:new Link({ params: ['x','y','z'] })

7️⃣ 延伸玩法

  1. 地图书签分享
    把当前 URL 发给同事 / 客户,打开即定位到同一视角。

  2. 集成后台数据
    后端记录重要坐标 → 前端读取 URL → 打开地图直达目标区域。

  3. 批量截图脚本
    借助无头浏览器 + URL 参数,批量生成不同视角的静态地图图片。


8️⃣ 结语

一行 new Link(),即可为地图加上「自带 GPS」的能力。
如果本文对你有帮助,别忘了 点赞 👍、收藏 ⭐、评论 💬 —— 你的支持是我持续分享的最大动力!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/87128.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/87128.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

数字人的形象与内容,虚拟形象背后的权益暗战

&#xff08;首席数据官高鹏律师数字经济团队创作&#xff0c;AI辅助&#xff09; 当某科技公司的虚拟偶像在直播间收获百万打赏时&#xff0c;当某品牌的数字代言人形象被篡改成表情包全网传播时&#xff0c;当网红博主的AI分身开始替代真人直播带货时&#xff0c;一场关于数…

【python】pdf拆成图片,加中文,再合成pdf

前期搞了个pdf加页脚&#xff0c;但是搞了半天中文加不了&#xff0c;就换了个思路。 直接说结论&#xff0c;pdf拆成图片&#xff0c;加中文&#xff0c;再合成pdf&#xff0c;会导致pdf模糊。 import os import fitz # PyMuPDF from PIL import Image, ImageDraw, ImageFon…

分布式爬虫数据存储开发实战

分布式爬虫存储的核心矛盾在于&#xff1a;既要高吞吐又要强一致性&#xff0c;还要避免重复。比如Kafka虽然吞吐高但无法去重&#xff0c;Redis去重快但容量有限。所以我们可能低估了状态同步的复杂度——比如暂停爬虫时如何保证内存中的URL状态不丢失。 分布式爬虫的数据存储…

探秘阿里云Alibaba Cloud Linux:云时代的操作系统新宠

引言&#xff1a;云时代的操作系统变革 在云计算技术蓬勃发展的当下&#xff0c;企业的数字化转型进程被极大地加速&#xff0c;而作为云计算底层支撑的操作系统&#xff0c;也迎来了前所未有的变革与挑战。传统操作系统在应对云计算环境中的大规模资源调度、高弹性扩展以及安…

使用pyflink进行kafka实时数据消费

目录 背景 代码demo 踩坑记录 1、kafka连接器&#xff0c;kafka客户端jar包找不到 2、java模块系统访问限制 3、执行demo任务&#xff0c;一直报错连接kafka topic超时 总结 背景 实际项目中经常遇到source是kafka&#xff0c;需要实时消费kafka某个topic中的数据&#x…

软件测试理论框架与发展:分类、原则与质量保障策略

第一章 一、计算机软件的发展分类 早期软件开发的特点&#xff1a; 软件规模小、复杂程度低、开发过程不规范 测试的情况&#xff1a; 测试等同于调试 目的纠正软件的已经知道的故障 投入少&#xff0c;介入晚 成为一种发现软件的活动&#xff08;1957&#xff09; 测试不等于…

未知威胁攻击原理和架构

大家读完觉得有帮助记得关注和点赞&#xff01;&#xff01;&#xff01; 未知威胁&#xff08;Unknown Threats&#xff09;指利用零日漏洞、合法工具滥用、高级逃逸技术等**绕过传统特征检测**的攻击&#xff0c;其核心在于**动态对抗防御体系的认知盲区**。以下从攻击原理、…

基于Netty-WebSocket构建高性能实时通信服务

引言&#xff1a;WebSocket在现代应用中的重要性 在当今实时交互应用盛行的时代&#xff0c;WebSocket协议已成为实现双向通信的核心技术。相比传统的HTTP轮询&#xff0c;WebSocket提供了&#xff1a; 真正的全双工通信极低的延迟&#xff08;毫秒级&#xff09;高效的连接管…

咸虾米项目总结1--const用法

在 UniApp&#xff08;或 Vue 3&#xff09;中&#xff0c;声明一个空对象可使用下面这2种写法&#xff1a; // 写法1 const a ref(null);// 写法2 const a ref({}); 在UniApp中&#xff0c;const a ref()用法概述&#xff1a; 用途&#xff1a; 创建一个响应式引用&#x…

在mac下手动编译迁移的android版webrtc组件

我原先使用的android版webrtc是在linux下编译的&#xff0c;现在因为某些原因需要把整个库迁移到mac下编译。 把代码迁移完后&#xff0c;正常是需要通过gclient sync 重新构建编译环境&#xff0c;但是由于网络限制等方面原因&#xff0c;会导致完成的比较慢。 在摸索一阵后…

Linux 命令:mkdir

Linux mkdir 命令详细教程 一、mkdir 命令的基本功能 mkdir&#xff08;Make Directory&#xff09;是 Linux 系统中用于创建新目录&#xff08;文件夹&#xff09;的基础命令。它支持一次性创建单个或多个目录&#xff0c;以及递归创建多层目录结构&#xff0c;是文件系统操…

Django 数据迁移全解析:makemigrations migrate 常见错误与解决方案

1. 迁移机制与底层原理 在 Django 中&#xff0c;ORM&#xff08;Object-Relational Mapping&#xff09;是连接模型&#xff08;Model&#xff09;和数据库结构的桥梁。Django 鼓励开发者通过编写 Python 类&#xff08;模型&#xff09;来定义业务数据结构&#xff0c;而不是…

SuperGlue:使用图神经网络学习特征匹配

摘要 本文提出了 SuperGlue&#xff0c;一种神经网络&#xff0c;用于通过联合寻找对应关系并排除不可匹配点来匹配两组局部特征。匹配结果通过求解一个可微的最优传输问题来估计&#xff0c;该问题的代价由一个图神经网络预测。我们引入了一种基于注意力的灵活上下文聚合机制…

ssh -T git@github.com失败后解决方案

这个错误表示你的 SSH 连接无法到达 GitHub 服务器。以下是详细解决方案&#xff0c;按照优先级排序&#xff1a; 首选解决方案&#xff1a;使用 SSH over HTTPS&#xff08;端口 443&#xff09; 这是最有效的解决方案&#xff0c;因为许多网络会阻止 22 端口&#xff1a; …

从苹果事件看 ARM PC市场的未来走向

最近&#xff0c;苹果宣布部分搭载 Intel 处理器的 Mac 不再支持最新的 macOS 系统更新&#xff0c;这一消息犹如一颗石子投入平静湖面&#xff0c;激起层层涟漪。它不仅让 Intel 芯片在 Mac 产品线上彻底成为历史&#xff0c;也促使我们重新审视 PC 行业的发展脉络&#xff0c…

vue + element ui 实现超出宽度展示..,鼠标移入显示完整内容

vue element ui 实现超出宽度展示…&#xff0c;鼠标移入显示完整内容 代码理念&#xff1a; 当高度大于对应行数的高度 则说明需要展示"…" 子组件 <template><div class"tooltip"><div ref"tooltipRef" :class"[tooltip…

HarmonyOSNext应用无响应全解析:从机制到实战的卡死问题排查

HarmonyOSNext应用无响应全解析&#xff1a;从机制到实战的卡死问题排查 ##Harmony OS Next ##Ark Ts ##教育 本文适用于教育科普行业进行学习&#xff0c;有错误之处请指出我会修改。 喂喂喂&#xff01;应用卡成PPT了&#xff1f;点啥都没反应&#xff1f;别慌&#xff01…

git 迁移之获取原库所有分支

以下是一个安全的 Bash 脚本&#xff0c;用于将远程 Git 仓库的所有分支检出到本地&#xff08;自动跳过已存在的分支&#xff09;&#xff1a; #!/bin/bash# 获取所有远程分支&#xff08;排除 HEAD&#xff09; remote_branches$(git branch -r | grep -v HEAD\|->)# 循环…

设计模式 | 适配器模式

适配器模式&#xff08;Adapter Pattern&#xff09; 是结构型设计模式中的连接器大师&#xff0c;它允许不兼容接口的类能够协同工作。本文将深入探索适配器模式的核心思想、实现技巧以及在C中的高效实践&#xff0c;解决现实开发中的接口兼容性问题。 为什么需要适配器模式 …

RTL 级机器人电机控制器的 FPGA 设计

借助Verilog&#xff0c;在FPGA中实现了带编码器的两台电机的电机控制系统的RTL级设计。 介绍 借助硬件描述语言 (HDL) Verilog 和 AMD Vivado 设计套件&#xff0c;在 AMD Spartan-7 FPGA 中实现带编码器的两个电机的控制器系统的 RTL 设计。 在这个项目中&#xff0c;使用了搭…