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

使用 OpenLayers + 高德瓦片源实现旅游足迹地图

作为一个热爱旅行的开发者,我一直想要一个能够记录和展示自己旅游足迹的功能。市面上虽然有很多地图应用,但大多功能复杂,而我只需要一个简单直观的方式来标记去过的地方和想去的地方。

于是我决定在自己的个人网站上实现一个旅游足迹地图功能。这个功能的核心需求很简单:

  • 在地图上标记去过的地方(绿色标记)
  • 标记想去的地方(橙色标记)
  • 支持点击查看详细信息
  • 适配网站的亮色/暗色主题
  • 在移动端也能良好展示

经过技术调研,我选择了 OpenLayers + 高德地图瓦片源的方案,既能满足功能需求,又能保证在国内的访问速度。

演示

旅游足迹地图演示

我的主页:https://fastcar.fun

你可以在我的关于页面看到这个旅游足迹地图的实际效果,地图上标记了我去过的城市和想去的地方。
地图演示

功能点详解

技术选型考虑

在实现这个功能时,我面临几个技术选型的问题:

地图库选择:

  • Google Maps API:需要翻墙,在国内访问不稳定
  • 百度地图 API:需要申请 key,有使用限制
  • 高德地图 API:同样需要申请 key
  • OpenLayers + 开放瓦片源:免费、灵活、无需 key

最终选择 OpenLayers 是因为它是一个功能强大的开源地图库,支持多种瓦片源,而且可以直接使用高德地图的公开瓦片服务,无需申请 API key。

瓦片源选择:
高德地图提供了公开的瓦片服务,支持多种样式:

  • 标准地图:style=8(亮色主题)
  • 暗色地图:style=7(暗色主题)
  • 卫星图:style=6
  • 路网图:style=1

这些瓦片源都支持中文标注,非常适合国内用户使用。

核心功能实现

1. 地图初始化
使用 OpenLayers 创建地图实例,配置高德瓦片源,设置合适的中心点和缩放级别。

2. 双主题支持
创建亮色和暗色两个图层,根据网站主题动态切换显示。

3. 标记系统
使用矢量图层添加标记点,区分"去过"和"想去"两种类型,使用不同的颜色和图标。

4. 交互功能
实现点击标记显示详细信息的弹窗,包括地点名称、描述、访问时间等。

5. 响应式设计
适配移动端显示,调整地图高度和弹窗样式。

架构图解

整体架构图

Astro 组件
TravelMap.astro
travel-map.json 数据
OpenLayers 地图库
高德瓦片源
矢量图层
已访问标记
愿望清单标记
主题检测系统
亮色主题图层
暗色主题图层
交互系统
点击事件处理
弹窗显示

数据流图

JSON 数据文件
组件加载
解析数据结构
创建地图实例
添加瓦片图层
创建矢量图层
遍历数据添加标记
绑定交互事件
地图渲染完成

主题切换时序图

用户站点主题系统MutationObserverTravelMap组件地图图层切换主题更新 DOM class检测到 DOM 变化触发主题检测判断当前主题隐藏亮色图层显示暗色图层显示亮色图层隐藏暗色图层alt[暗色主题][亮色主题]地图主题更新完成用户站点主题系统MutationObserverTravelMap组件地图图层

交互流程图

用户点击地图
点击位置有标记?
获取标记数据
无操作
创建弹窗内容
计算弹窗位置
显示弹窗
用户查看信息
用户点击关闭?
移除弹窗
保持显示

代码实现

地图初始化核心代码

function initMap() {// 亮色主题图层 - 高德地图标准地图lightLayer = new ol.layer.Tile({source: new ol.source.XYZ({url: 'https://webrd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}',attributions: '© <a href="https://www.amap.com/">高德地图</a>',maxZoom: 18})})// 暗色主题图层 - 高德地图暗色标准地图darkLayer = new ol.layer.Tile({source: new ol.source.XYZ({url: 'https://webrd0{1-4}.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}',attributions: '© <a href="https://www.amap.com/">高德地图</a>',maxZoom: 18}),visible: false})// 创建地图map = new ol.Map({target: 'travel-map',layers: [lightLayer, darkLayer],view: new ol.View({center: ol.proj.fromLonLat([105.0, 35.0]), // 中国中心zoom: 4,maxZoom: 18,minZoom: 2})})
}

实现要点:

  1. 使用高德地图的公开瓦片服务,URL 中的 {1-4} 表示负载均衡的服务器
  2. style=8 是标准地图,style=7 是暗色地图
  3. lang=zh_cn 确保中文标注
  4. 初始时暗色图层设置为不可见

标记添加核心代码

function addMarkers() {const vectorSource = new ol.source.Vector()// 添加已去过的地方data.visited.forEach(location => {const feature = new ol.Feature({geometry: new ol.geom.Point(ol.proj.fromLonLat([location.coordinates[1], location.coordinates[0]])),type: 'visited',data: location})vectorSource.addFeature(feature)})// 添加想去的地方data.wishlist.forEach(location => {const feature = new ol.Feature({geometry: new ol.geom.Point(ol.proj.fromLonLat([location.coordinates[1], location.coordinates[0]])),type: 'wishlist',data: location})vectorSource.addFeature(feature)})const vectorLayer = new ol.layer.Vector({source: vectorSource,style: function(feature) {const type = feature.get('type')return new ol.style.Style({image: new ol.style.Circle({radius: 15,fill: new ol.style.Fill({color: type === 'visited' ? '#22c55e' : '#f59e0b'}),stroke: new ol.style.Stroke({color: type === 'visited' ? '#16a34a' : '#d97706',width: 3})}),text: new ol.style.Text({text: type === 'visited' ? '✓' : '♡',fill: new ol.style.Fill({ color: 'white' }),font: 'bold 16px sans-serif'})})}})map.addLayer(vectorLayer)
}

实现要点:

  1. 注意坐标转换:ol.proj.fromLonLat([经度, 纬度])
  2. 使用不同颜色区分标记类型:绿色表示已访问,橙色表示愿望清单
  3. 添加文字图标:✓ 和 ♡ 增强视觉识别

主题切换核心代码

function detectSiteTheme() {// 检测站点当前主题const isDark = document.documentElement.classList.contains('dark') ||document.body.classList.contains('dark') ||document.documentElement.getAttribute('data-theme') === 'dark'currentTheme = isDark ? 'dark' : 'light'switchTheme(currentTheme)
}function switchTheme(theme) {if (theme === 'dark') {// 暗色主题:显示高德暗色地图lightLayer.setVisible(false)darkLayer.setVisible(true)} else {// 亮色主题:显示高德标准地图lightLayer.setVisible(true)darkLayer.setVisible(false)}
}function watchSiteThemeChanges() {// 使用MutationObserver监听站点主题变化const observer = new MutationObserver(function(mutations) {mutations.forEach(function(mutation) {if (mutation.type === 'attributes' &&(mutation.attributeName === 'class' || mutation.attributeName === 'data-theme')) {detectSiteTheme()}})})observer.observe(document.documentElement, {attributes: true,attributeFilter: ['class', 'data-theme']})
}

实现要点:

  1. 支持多种主题检测方式,兼容不同的主题切换实现
  2. 使用 MutationObserver 监听 DOM 变化,实现主题自动切换
  3. 通过图层的 setVisible() 方法控制显示/隐藏

数据结构设计

{"visited": [{"id": "beijing","name": "北京","nameEn": "Beijing","coordinates": [39.9042, 116.4074],"description": "中国首都","visitDate": "2023-05"}],"wishlist": [{"id": "xian","name": "西安","nameEn": "Xi'an","coordinates": [34.3416, 108.9398],"description": "古都西安,兵马俑故乡","priority": "high"}]
}

设计要点:

  1. 分离已访问和愿望清单数据
  2. 坐标使用 [纬度, 经度] 格式
  3. 支持中英文名称
  4. 可扩展字段:访问时间、优先级等

简单总结

通过使用 OpenLayers + 高德瓦片源,我成功实现了一个功能完整的旅游足迹地图。这个方案的主要优势:

技术优势:

  • 无需申请 API key,降低使用门槛
  • 支持自定义样式和交互
  • 高德地图在国内访问速度快,中文支持好
  • OpenLayers 功能强大,扩展性好

功能特色:

  • 双主题自动切换,与网站整体风格保持一致
  • 直观的标记系统,清晰区分已访问和愿望清单
  • 响应式设计,移动端体验良好
  • 交互弹窗提供详细信息展示

后续改进方向:

  1. 添加路线规划功能,连接相邻的旅游点
  2. 支持照片上传,为每个地点添加旅游照片
  3. 增加统计功能,显示旅游里程、访问城市数量等
  4. 支持数据导入导出,方便备份和分享
  5. 添加搜索功能,快速定位特定地点
  6. 集成天气信息,显示各地实时天气

这个旅游足迹地图不仅满足了我个人记录旅游经历的需求,也为网站访客提供了一个了解我旅游足迹的有趣方式。通过开源的技术栈实现,也为其他开发者提供了一个可参考的实现方案。


文章转载自:

http://abqJX5ZM.sftpg.cn
http://4Vp7v8JK.sftpg.cn
http://bIvjKoHw.sftpg.cn
http://bf7ZnbYc.sftpg.cn
http://rNSkTOPQ.sftpg.cn
http://gEvhMGzA.sftpg.cn
http://fbMfN2bM.sftpg.cn
http://EH2Bamtl.sftpg.cn
http://MTlJD5Co.sftpg.cn
http://cOkI0pS3.sftpg.cn
http://rphGqr9I.sftpg.cn
http://qYhsA1ph.sftpg.cn
http://UmxPhfvu.sftpg.cn
http://4yOn4go0.sftpg.cn
http://lMgraauL.sftpg.cn
http://J7i929Qy.sftpg.cn
http://HGAE41Dd.sftpg.cn
http://tezS7UEm.sftpg.cn
http://TtbqCLqR.sftpg.cn
http://5Sy57Lvx.sftpg.cn
http://RKxToV4i.sftpg.cn
http://60h2Z01I.sftpg.cn
http://wFjyWbNj.sftpg.cn
http://uXPTEZba.sftpg.cn
http://ZGFRpyZe.sftpg.cn
http://N14pOzOX.sftpg.cn
http://uxApxHI5.sftpg.cn
http://TQxzUzGk.sftpg.cn
http://FVY5bpRG.sftpg.cn
http://apWzZCx4.sftpg.cn
http://www.dtcms.com/a/373091.html

相关文章:

  • 2025年体制内职业发展相关资格认证参考指南
  • window显示驱动开发—监视筛选器驱动程序(三)
  • 计算机网络:数据链路层--数据链路层基本功能
  • 第二课、熟悉Cocos Creator 编辑器界面
  • [Wit]CnOCR模型训练全流程简化记录(包括排除BUG)
  • JavaEE 进阶第四期:开启前端入门之旅(四)
  • TFS-2004《Input Selection for Nonlinear Regression Models》
  • esp下载器使用流程
  • 3dtiles 加载问题
  • 3D地球可视化教程 - 第1篇:基础地球渲染系统
  • 单片机开发
  • LLMs之REFRAG:《REFRAG: Rethinking RAG based Decoding》的翻译与解读
  • MATLAB的数值计算(二)线性方程求解
  • Java基础(十一):关键字final详解
  • Java全栈开发面试实录:从基础到微服务的实战经验分享
  • Matlab机器人工具箱使用1 简单的描述类函数
  • 自动捕鱼器设计cad+设计说明书+三维图
  • 深入理解 MyBatis-Plus 的 `ServiceImpl`
  • 软件可靠性定量核心指标与关系深入解析
  • Android音频学习(十七)——音频数据流转
  • 如何一次性将多个PPT幻灯片批量转换成PDF文档
  • Vue响应式底层原理:深入解析依赖追踪机制
  • 抖音批量上传视频怎么弄?抖音矩阵账号管理的专业指南
  • 数学知识--行向量与矩阵相乘,和矩阵与行向量相乘的区别
  • 【硬件-笔试面试题-70】硬件/电子工程师,笔试面试题(知识点:过压保护电路)
  • PostgreSQL打印实时查询语句(监控PostgreSQL监控)(未成功)
  • “代练护航”小程序API源码搭建:高并发接单系统的技术突破与实战,多端适配与跨平台开发 如何覆盖微信、H5、APP全场景?
  • 从航空FACE的一个落地方案漫谈汽车HPC软件架构的思维转变(1/3)FACE基础概念与落地案例
  • Docker多共享网络配置策略(Docker多网络、Docker networks、Docker Compose网络、Docker网络、Docker共享网络)
  • Terraform 从入门到实战:历史、原理、功能与阿里云/Azure 上手指南