news 2026/10/10 1:27:33

Valhalla 入门指南:OpenStreetMap 开源路由引擎的核心特性与架构解析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Valhalla 入门指南:OpenStreetMap 开源路由引擎的核心特性与架构解析
  • 后端

【免费下载链接】valhalla

Open Source Routing Engine for OpenStreetMap

项目地址:https://gitcode.com/gh_mirrors/va/valhalla
点击查看免费下载

Valhalla 是一个基于 OpenStreetMap 数据的开源路由引擎,本文以官方入门文档为主体,梳理其公共演示服务器、多模式路由、瓦片化层级数据、动态成本模型与导航叙事生成五大核心设计,并结合仓库源码与架构文档展开实现级解读。读完本文,你将掌握 Valhalla 的设计哲学、各核心模块(LOKI/THOR/SIF/BALDR/ODIN/TYR)的分工与协作方式,以及从体验公共服务器到理解自建路由服务的技术路径。

公共演示服务器:零成本体验完整功能

Valhalla 由 FOSSGIS e.V. 托管了一个功能完整的公共演示服务器,对公众开放,并内置了完整的全球路网数据(full planet graph)以及一个开源 Web 应用。入口地址为:

  • Web 演示应用:https://valhalla.openstreetmap.de
  • HTTP API:位于略有不同的子域,例如 https://valhalla1.openstreetmap.de/status

公共演示服务器的使用遵循与 OSRM、Nominatim 演示服务器相同的合理使用政策(fair-usage policy),并在一定程度上通过速率限制来执行。

需要注意的是:如果你的应用(无论是移动端、Web 端还是桌面端)要向公共演示服务器发起请求并发布给最终用户,官方希望你先通过 Github Discussions 告知,并在请求中带上可识别的X-Client-Id请求头,例如:

X-Client-Id: newroutingapp.io

这一约定既帮助维护方了解公共资源的使用情况,也为接入方提供了与维护团队建立沟通的渠道。对开发者而言,这意味着在正式自建服务之前,可以用公共服务器快速验证 API 行为与路由效果;而对生产级应用,则应基于下文所述的自建瓦片与服务方案搭建独立环境。

设计理念:把属性留给图数据,把决策留给运行时成本模型

Valhalla 与许多源于学术研究的既有开源路由引擎不同:后者的优势在于算法在大型图/路网上的速度,但大量道路属性需要被折叠进固定的成本模型(baked costing model)中。Valhalla 的选择恰恰相反——将大部分属性添加到图数据中,并允许动态、运行时的成本计算(dynamic, run-time costing)。

这一设计带来两个直接收益:

  1. 社区可贡献:任何人都可以贡献并应用自己的成本模型;
  2. 灵活生成不同特征的路线:通过替换或组合成本模型,在同一份数据上产出具有不同特征的路线,而无需重新生成数据集。

从源码结构看,这一理念落实为 src/sif 下的多个成本模型实现,例如 autocost.cc(汽车)、pedestriancost.cc(步行)、bicyclecost.cc(自行车)、transitcost.cc(公共交通)与 truckcost.cc(卡车)。这些模型在路由引擎 THOR 遍历图时被动态调用,从而让“同一份瓦片数据、多种出行方式”成为可能。

多模态与时间相关路由:同一路线里混排多种出行方式

Valhalla 最初的开发阶段聚焦于单模式出行,但设计目标是快速支持在同一条路线中混合汽车、步行、自行车与公共交通。官方文档明确指出:从第一天起,Valhalla 的设计就受到多模态考量的影响。

支持公共交通意味着必须实现时间与时刻表相关的路由(time and schedule dependent routing)——路由过程需要沿路径跟踪时间,并且能够支持“必须在某个时间点到达某地”的约束(即给定到达时间)。

这一能力在 THOR 路由引擎的算法家族中得到落实。根据 THOR 架构文档,所有路径计算算法均继承自基类PathAlgorithm:

  • AStar:正向 A* 算法,目前仅用于“平凡路径”(起点与终点在同一条边或相邻相连的边上);
  • TimeDepForward:正向 A*,用于指定出发时间的时间相关路由;
  • TimeDepReverse:反向 A*,用于指定到达时间的时间相关路由;
  • BidirectionalAStar:双向 A*,用于非时间相关且非平凡的路由;
  • MultiModal:带公交时刻表查询的正向 A*,包含步行与公交之间的模式切换逻辑,因公交时刻表本质上是时间相关的。

对应实现可在 src/thor 中查看,如 bidirectional_astar.cc、unidirectional_astar.cc 与 multimodal_astar.cc。时间相关路径的验证逻辑则可参考 test/timedep_paths.cc。

瓦片化层级数据:像矢量地图一样管理路由数据

从 OSM 构建路由数据集并非易事。Valhalla 的核心疑问是:为什么路由数据不能像矢量地图数据一样处理?答案是采用瓦片数据结构(tiled data structure),从而允许轻松下载和更新区域数据。

图(路由数据结构)瓦片可以被下载,用于客户端路由应用,或供不想经历数据创建痛苦的主机托管服务直接使用。同时,结构化的图层级(例如高速公路、主干道、支路、公交)配合捷径边(shortcut edges),确保路由的高性能。THOR 正是 "Tiled Hierarchical Open Routing"(瓦片化层级开放路由)的缩写,是整个 Valhalla 组织及其北欧神话命名主题的奠基思想。

这一特性在 BALDR 架构文档 中有更细致的描述:BALDR(Base ALgorithms and Data Resource)提供路由专用数据结构,负责路由数据瓦片、瓦片缓存、层级瓦片布局以及瓦片数据成员(节点、边、出口)等。其核心类型GraphId是瓦片化层级图内节点/边的唯一标识,内部以 64 位无符号整数表示,包含 3 位层级(level)、22 位瓦片索引(tileid)与 21 位节点/边索引(id)。具体实现可参考 graphid.cc 与头文件 valhalla/baldr/graphid.h。

瓦片化带来另一个连锁优势:LOKI 定位引擎可以借助瓦片的规则网格与层级结构,把坐标关联搜索限制在靠近输入点的少量瓦片上。根据 LOKI 架构文档,LOKI 只关心最详细的层级(因为它拥有图中所有边),并利用每个瓦片内 5x5 的边索引分箱(bins)实现“按距离最近优先”的迭代搜索——实测(文档数据)中位耗时从初版的 130ms(纽约)降到 4ms(纽约),而全球瓦片集的数据体积增幅小于 5%。

取走你的路线(TYR):为移动端与离线场景而生的服务层

TYR 是 Valhalla 的服务层,接收地点与选项作为输入,返回路线与机动操作(maneuvers)作为输出,本质上将 Valhalla 组织下的所有其他项目串联起来。TYR 是 "Take Your Route"(取走你的路线)的回文缩写,对应北欧神话中战神提尔之名。

TYR 最初定位为路由服务,用户可以借此为移动端或 Web 端生成路线。官方规划的扩展方向包括:

  • 提供下载瓦片路由数据的方法,支持无连接、客户端侧的离线路由;
  • 用户在路上“取走你的路线”(Take Your Route),或为某一区域下载图瓦片,在没有网络连接的地方继续使用设备;
  • 客户端侧“返回路线”(return to route)与离线路由等功能均因此成为可能。

从实现角度看,TYR 的核心职责是数据编组(data marshalling)、HTTP、请求解析、响应序列化与进程间通信。仓库中的对应实现包括 src/tyr/actor.cc 与 src/valhalla_service.cc,而序列化层则体现在 route_serializer_valhalla.cc、route_serializer_osrm.cc(OSRM 兼容输出)等文件中。

灵活性与可扩展性:动态成本与可定制叙事

Valhalla 鼓励社区贡献各自国家和地区的专业知识与本地知识。其核心支撑点是:

动态成本(dynamic costing)。一个地区的好路线在另一地区未必成立,因此可动态、可扩展的“插件式”成本/权重代码具有重要意义。动态成本还带来两个实际收益:

  1. 运行时生成替代路线——无需生成不同数据集即可在运行期为同一请求产出备选路径;
  2. 支持专业化场景的新成本方法——例如卡车路由、绿色/环保路由,以及未来可能的低成本(least cost)路由。

在 SIF 架构文档 中,SIF 被描述为“为边以及边之间的转换(转弯成本)提供动态、可扩展的计费”,其主要用途是在路由引擎 THOR 形成最优路径时发挥作用。仓库中 src/sif/dynamiccost.cc 与 src/sif/recost.cc 进一步体现了运行时重新计费的机制,而各出行方式的成本参数则在 proto/options.proto 中定义(如costing、costing_options等字段),供请求时动态指定。

在叙事与引导生成方面,Valhalla 同样希望提供添加自定义叙事短语的途径,以及扩展或添加自定义插件的其他方式,以便按用户需求定制输出。

开放方向与改进叙事(ODIN):把路径变成能听懂的方向

一条高质量的路线结果,远不止一条路径形状和“左转/右转/继续直行”的简单列表。ODIN(Open Directions and Improved Narrative)负责将路径信息转换为易于理解、实用、能在旅途中真正帮助用户的引导与叙事方向。高速公路的出口信息与方向信息将帮助消除沿途关键决策点的歧义。例如:

从51B出口靠右驶入I 81 North,前往I 78/Hazleton/Allentown。

ODIN 使用常见基础路名合并机动操作(collapse maneuvers),并简化复杂交叉路口的转换;地标(landmarks)及其他相关信息也在规划之中。由于引导与路线说明必须能适配不同语言和不同使用场景,可扩展性与社区贡献是这一模块的关键。

根据 ODIN 架构文档,ODIN 包含一组数据结构和算法,负责机动操作生成、路名匹配与叙事生成。仓库中的对应实现包括 maneuversbuilder.cc、narrativebuilder.cc 与 directionsbuilder.cc;多语言文案资源位于 locales 目录(如 en-US.json、de-DE.json),而发音与路名格式化逻辑则见 verbal_text_formatter.cc。

从体验者到构建者:下一步可以做什么

入门文档之后,你可以沿着以下路径继续深入:

  • 阅读架构文档:了解 LOKI(定位)、THOR(路由)、SIF(成本)、BALDR(瓦片数据)、ODIN(导航)、TYR(服务) 以及地理/数学基础库 MIDGARD 和海拔数据模块 SKADI 的完整分工;
  • 查看构建工具:仓库 scripts 目录提供了 valhalla_build_config 等配置生成脚本,src/mjolnir 下则有 valhalla_build_tiles.cc、valhalla_build_admins.cc 等瓦片构建命令行工具;
  • 体验测试:test 目录包含大量可运行的单元测试与 gurka 集成测试框架,可用于验证路由、成本与叙事行为;
  • 了解 API:访问 docs/docs/api 下的 API 文档(含 JSON 示例与参数定义),掌握 route、matrix、isochrone、trace 等端点的请求格式。

概括而言,Valhalla 的入门价值在于:它把“高质量的路线”拆解为可独立演进的数据层(BALDR)、定位层(LOKI)、成本层(SIF)、算法层(THOR)、叙事层(ODIN)与服务层(TYR),并通过动态成本与插件机制,让社区能够在共享同一份全球瓦片数据的前提下,按地区、按场景定制属于自己的路由体验。

  • 后端

【免费下载链接】valhalla

Open Source Routing Engine for OpenStreetMap

项目地址:https://gitcode.com/gh_mirrors/va/valhalla
点击查看免费下载

相关推荐

上一篇:从构建到性能剖析:Ceph Crimson 开发者实战指南
下一篇:Table Transformer项目实战:表格检测与结构识别全流程指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/10 1:25:07

深度解析微信小程序及公众号获取code的方法与技巧

在微信小程序和公众号的开发过程中,获取code是进行用户身份验证的关键步骤。本文将详细介绍如何获取code,包括微信小程序和公众号两种场景下的获取方法,以及相关技巧。 一、微信小程序获取code 获取微信提供的用户身份标识,从而使…

作者头像 李华
网站建设 2026/10/10 1:20:12

8 步把文档变成知识库——一次企业知识库流程的工程化尝试

## 背景先说结论:企业文档散落各处、找人问半天这类重复劳动,值得用工具兜住。## 核心能力- 全程本地运行,原始文档与知识数据不出电脑- 8 步流水线自动化:解析→结构化→质检→复核→分片→向量库→验收- 内置本地大模型&#xf…

作者头像 李华