#osm-pbf #pbf #routing #osm #routes #xml

bin+lib osmgraphing

通过解析OpenStreetMap数据创建的图形进行实验

27个版本 (1个稳定版)

1.1.1 2020年10月11日
1.0.0 2020年1月26日
0.13.0 2020年4月28日
0.12.1 2020年3月28日
0.6.0 2019年9月22日

#7 in #route

Apache-2.0 和可能 GPL-3.0-or-later

8.5MB
13K SLoC

Rust 10K SLoC // 0.1% comments C++ 2K SLoC // 0.1% comments Python 1K SLoC // 0.2% comments Shell 38 SLoC // 0.2% comments BASH 35 SLoC // 0.2% comments

osmgraphing

Build Status nightly

Tag Crates.io Docs

Changelog Last commit

License

Balancing Saarland

这个GIF显示了,如何通过平衡改进在德国萨尔州网络中10,000条路径的分布。从s到t的新路径保证不会比s到t的最优路径差25%,考虑到旅行时间(所以55分钟在最坏情况下变为不到1小时10分钟)。

欢迎使用osmgraphing仓库!:) 本仓库的目标是解析openstreetmap数据来计算交通路线和与之相关的各种用例。本仓库涉及处理自私路由和用于在街道网络中平衡负载的度量学习分析。有关更多详细信息,请参阅我的硕士论文。然而,如果存在自定义解析模块,则可以使用此模块支持的任何地图格式(例如,自己的csv-like格式),而不必是街道网络。

所有计算都将针对单个桌面而不是更昂贵的集群进行优化。当前机器(2020年8月)使用的是AMD Ryzen 7 3700X 8-核处理器,并拥有32 GB的RAM。

version above 1.0.0的原因

这个存储库是我的第一个 Rust 项目。一些接口决策可能需要讨论(比如公共的 helpers 模块),并且图构建器有一些相当长的函数。由于图和路由文件(大约 20 MB 的新克隆),资源消耗了太多的内存。然而,代码非常稳定。在大规模设计决策方面,我在我的 硕士论文 中进行了很好的描述,该论文基于这个存储库。这是一个学生项目、硕士论文、学习项目,并且完美地实现了这些目标。因此,版本 1.1.12020 年 10 月 发布,没有进行太多的重构。

有关详细信息,请参阅 LICENSE.md。版权所有者是 Parga Cacheiro, Dominic。简而言之,只要您不使用 cargo-feature gpl,此存储库和生成的二进制文件均根据 Apache-2.0-许可协议许可。使用此 cargo-feature 会添加一些代码和二进制文件,这些代码和二进制文件依赖于根据 GPL-3.0 许可的代码。因此,生成的二进制文件根据 GPL-3.0 许可。

目录

  1. 版本号大于 1.0.0 的原因
  2. 版权和许可
  3. 目录
  4. 设置和使用
    1. 长话短说
    2. 下载和生成地图
    3. 编辑配置
    4. 内联度量
    5. 大型地图(例如国家)的要求
    6. 收缩层次结构
  5. 平衡
  6. 致谢

设置和使用

以下为说明和相关信息。

长话短说

执行以下命令以进行(详细)路由示例。

# Further execution-info
cargo run --release --bin osmgraphing -- --help

# Build the binary for parsing maps and do routing
# and parse isle-of-man.
cargo run --release --bin osmgraphing -- --config resources/isle_of_man_2020-03-14/osm.pbf.yaml --routing

您可以从 geofabrik 下载 pbf 文件并将它们转换为其他格式。在编辑配置时,请以 resources/blueprint.yaml 为指南。

要使用平衡器,将 clonemulti-ch-constructor-repo 用作子模块,该子模块是用 c++ 编写的。此 osmgraphing 存储库作为 Rust 模块包装子模块,使用配置来设置其执行参数。要运行它,请根据 工作流程文件August 2020 成功运行)安装依赖项。请注意,平衡器基于根据 GPL-3.0 许可的代码。因此,您必须启用功能(通过 cargo)。

# Update git-submodules, because they are used in the balancer
git submodule update --init --recursive

# Build also features licensed under the `GPL-3.0`.
# Build with GRAPH_DIM=6.
GRAPH_DIM=6 cargo run --release --features='gpl' --bin osmgraphing -- --config resources/isle_of_man_2020-03-14/balancing/config.yaml --balancing

# After finishing, you may visualize the data
# (the results-dir, excluding the utc-stamp, is specified in the config)
py ./scripts/balancing/visualizer --results-dir 'custom/results/<map-name>/utc_<date_and_time>

如上所述,您可以在resources/目录中找到一个详细的配置蓝图,以及在resources/isle_of_man/目录中找到一个平衡示例。根据config.yaml的定义,结果可以在custom/results/isle_of_man中找到,并且可以使用scripts/目录中的Python模块进行可视化。Python工具有一个帮助信息,但平衡器在完成后会打印相应的命令。

注意reources/blueprint.yaml是正确且完整的。由于缺少或过时的关键字,地图配置可能略有损坏,因为它们并不常用。由于这个存储库只有少数人使用,因此这些配置仍然保留作为辅助示例。

所有功能的概述

以下表格显示了此存储库的所有功能。需要cargo-features来构建相应的功能。一些cargo-features对于该功能是可选的,这意味着cargo-feature添加了额外的功能。您可以使用以下命令使用cargo-features进行构建:cargo build --features='F0,F1,...'cargo run隐式构建)。

cargo-feature 备注
'gpl' 此功能对于所有许可为GPL-3.0的代码部分都是必需的。即使您使用了此cargo-feature,它也不会强迫您使用GPL-3.0许可数据,这些数据是用gpl代码创建的。
'custom' 此存储库包含一些小型地图,如手工地图或Isle-of-Man,但更大的地图,如德国的Saarland,德国部分地区如Stuttgart-Regierungsbezirk或国家如Germany,需要多个100 MB甚至更多的内存。尽管如此,一些测试使用了这些地图和配置,这可能是有用的,这也是为什么有这个cargo-feature的原因。要使此功能工作,只需下载地图,将它们移动到resources/中的相应地图目录中,并按照其他地图目录命名。

下载和生成地图

下载的osm数据以xml(osm)或二进制(pbf)格式提供,其中节点与纬度和经度相关的位置相关。从openstreetmap下载时,问题将是大小限制,但还有其他osm数据提供者,例如geofabrik。目前,没有针对osm数据的解析模块,因此仅支持二进制osm.pbf数据。

为了测试,使用了一些简单的基于文本的格式 fmi。由于它们是为特定任务手动创建的,因此解析它们——一般来说——是不稳定的。然而,这个存储库有一个生成器,可以根据配置从 pbf 或其他 fmi 文件(例如,用于不同的度量顺序)创建这样的 fmi 文件。

用于创建包含通过收缩层次结构收缩的图的 fmi-地图文件的工具是 multi-ch-constructor,它用于平衡器,因此是这个存储库的一个子模块。此外,这个存储库还有一个用于子模块的包装二进制文件 multi-ch-constructor,它也使用配置。

编辑配置

配置的每个可能选项都在 resources/blueprint.yaml 中进行了描述。二进制文件(osmgraphingmulti-ch-constructor)(在发布构建后,二进制文件位于 target/release)使用配置用于不同的用例。

内联度量

度量使用 SmallVec 内联。这提高了性能,并且可以节省几个 GBRAM。如果您配置使用的度量少于您编译的度量,您将收到一个警告。此外,如果编译的内联度量数少于配置的度量数,则无法有效地使用图并抛出错误。在这种情况下,您必须根据您的需求更改内联度量数,并重新构建。命令 cargo build 简单地变为 GRAPH_DIM=6 cargo build。默认值相当小(~4),但可能会随时间变化。

大型地图(例如,国家)的要求

一般来说,这些需求取决于解析的地图的大小(也是不同日期的同一地图)以及您的机器。以下数字基于一个 8-核心-CPU 以及在 archlinux 上运行的 pbf-地图(2020314 日)和 16 GB RAM 上运行。以下数字为根据以下数字,不进行进一步的详细基准测试,内存使用量与图大小成线性关系,增长因子为 0.5。因此,您可以预期 4x 图大小的 RAM 使用量约为 2x(意味着 4x 节点和 4x 边的数量)。

  • 解析 Germany.pbf4 个指标,~51 百万 个节点,~106 百万 个边)需要大约 14 GBRAM 在峰值。解析后,由于优化的图结构,内存需求大大降低。
  • 预处理 Germany.pbf(包括解析)需要不到 4 分钟
  • Germany.pbf 的距离约为 600 公里22 进行路由查询,使用 bidirectional Dijkstra,高度依赖于具体的源-目标对(及其搜索空间)。这可以通过删除中间节点(如 a->b->c 中的 b)来改进,但它们目前被保留。也许,它们对于精确/现实交通模拟(例如可视化)是必需的。不再使用 Astar,因为它的唯一目的是减少搜索空间,这可以通过 Contraction Hierarchies 减少更多。此外,Astar 在处理多个或自定义指标时存在问题,因为指标具有启发式算法。

小型地图,如 Isle_of_Man.pbf~50_000 个节点,~107_000 个边),在每台机器上运行,解析时间不到一秒。

德国州 Baden-Württemberg.pbf~900 万 个节点,~1800 万 个边)在峰值时需要不到 5 GBRAM,解析时间约为 30

收缩层次结构

为了加速,此存储库使用并支持由子模块 lesstat/multi-ch-constructor 通过收缩层次结构收缩的图。此子模块从特定格式的 fmi 文件生成收缩图(见下文)。此子模块通过此 osmgraphing 存储库中的薄包装器调用,构建和调用 multi-ch-constructor。此包装器使用构建和执行的配置,这使得可重复性更容易。在阅读以下说明时请记住这一点。有关配置的详细信息,请参阅 resources/blueprint.yaml

首先,工具 multi-ch 需要特定格式的 fmi 地图文件作为输入。要生成正确格式的此类 fmi 地图文件,可以使用配置遵循 定义要求 的二进制文件 osmgraphing

配置文件中的ignored(忽略项)和占位符(例如ch-level)非常重要,因为multi-ch-constructor需要它们。除此之外,multi-ch-constructor使用节点索引作为ID,如果映射node -> indices [0; n]不是满射的,会导致错误。因此,建议使用src-idxdst-idx来导出图的边,而不是使用srd-iddst-idmulti-ch-constructor的标志(可以在配置中设置)允许在打印边时导出相应的节点ID(而不是它们的索引)。

multi-ch工具在文件开始处需要3个计数:度量计数(维度)、节点计数、边计数。osmgraphing二进制文件按此顺序添加了这些计数。

在可以使用multi-ch工具之前,需要构建它。为了优化,您需要将度量计数设置为维度,类似于osmgraphing中的GRAPH_DIM。根据先前生成的fmi文件(c++-子模块通过cmake允许这样做)中的维度,在配置文件中设置此维度。请参阅其README以获取更多信息。

请注意,多通道构造函数不是确定性的(2020年3月12日)。使用它可以加快查询速度,但由于优先级不同的结果顺序或舍入误差,可能会导致相同权重的不同路径。

平衡

请参阅cargo run --features='gpl' --release --bin osmgraphing -- --help

鸣谢

该项目于2019年中期作为一个学生项目开始。本节向该项目的工作人员和助手致敬,按姓氏排序。

Florian Barth
自项目开始以来一直担任项目总监,并总是立即利用他的经验和建议提供帮助。

Dominic Parga Cacheiro
在项目的前几周参与了项目规划和学习Rust,那时项目规划和学习Rust是项目的一部分。他从2020年10月开始继续工作,并改进和扩展了模拟。他扩展的最大部分是给定网络到度量生成,以改善提供的源目标对集的分布。

Jena Satkunarajan
在项目的前几周参与了项目规划和学习Rust,那时项目规划和学习Rust是项目的一部分。他实现了第一个(并正在运行)的A*算法的方法。

依赖项

~12–23MB
~318K SLoC