利用 Osmium Tool 提取 OSM 历史时点与公共交通标签数据

2 阅读10分钟

利用 Osmium Tool 提取 OSM 历史时点与公共交通标签数据

📝 摘要: 本文演示如何从 OpenStreetMap 全历史数据中提取指定时点快照,再按公交站、轻轨站、铁路站和轮渡码头等标签筛选要素,最终在 QGIS 中加载并导出为 Shapefile。适合需要开展历史 POI、交通设施演变或时空 GIS 分析的读者。

关键词: OpenStreetMap、Osmium Tool、历史数据、标签过滤、公共交通、QGIS
适合对象: GIS 学习者、空间数据工程师、城市交通研究人员

[TOC]

01 为什么需要提取 OSM 历史标签数据?

OpenStreetMap(OSM)不仅保存当前地图状态,还维护对象的历史版本。对于城市交通设施演变、兴趣点更新、道路网络扩张和地图贡献行为分析,仅使用最新快照往往无法回答“某一年当时是什么样”的问题。

本文采用一条清晰的数据处理链:

graph LR
  A[OSM 全历史 PBF] --> B[time-filter 时点快照]
  B --> C[tags-filter 标签筛选]
  C --> D[PBF 转 OSM 或直接导出]
  D --> E[QGIS 加载]
  E --> F[导出 Shapefile / GeoPackage]

本案例以 2020 年末公共交通设施快照 为例,提取以下四类标签:

设施类别OSM 标签表达式典型含义
公交站点highway=bus_stop公交车辆常规停靠点
有轨电车站railway=tram_stop有轨电车停靠点
铁路/轨道站点railway=station铁路、地铁或其他轨道交通车站,需结合附加标签进一步判别
轮渡码头amenity=ferry_terminal旅客上下轮渡的码头或终端设施

[!IMPORTANT] railway=station 的语义范围较宽,并不天然等同于“地铁站”。若研究对象只包括地铁,应结合 station=subwaysubway=yesnetwork=* 等标签进一步过滤或复核。

OSM 数据资源与 Osmium Tool 帮助文档

02 数据与软件准备

2.1 数据来源

本流程需要的是 OSM 全历史文件,而不是普通的当前快照文件。全历史数据包含同一对象在不同时间的多个版本,文件通常很大。

常用资料入口:

::: warning 存储与计算资源 全球全历史数据体量非常大。实际项目宜先确认磁盘空间、内存和处理时间;若研究区域较小,可优先使用区域历史数据或先做空间裁剪。 :::

2.2 软件环境

草案采用以下组合:

  • Windows 主机;
  • VMware 中的 Ubuntu Linux 虚拟机;
  • osmium-tool
  • osmconvert
  • QGIS。

建议先检查命令是否可用:

osmium --version
osmconvert --help | head

Ubuntu/Debian 系统可尝试:

sudo apt update
sudo apt install osmium-tool osmctools

[!NOTE] 软件包名称会因 Linux 发行版与软件源而异。安装后应以 osmium --versionosmconvert --help 的实际输出为准。

03 在虚拟机中挂载 Windows 共享文件夹

3.1 打开终端

在 Ubuntu 桌面按下 Ctrl + Alt + T,打开终端。

3.2 创建挂载目录并挂载共享文件夹

sudo mkdir -p /mnt/hgfs
sudo vmhgfs-fuse .host:/ /mnt/hgfs/ \
  -o allow_other \
  -o uid=1000

输入当前 Linux 用户密码后,可在 /mnt/hgfs/ 下访问 VMware 已配置的 Windows 共享目录。

VMware 共享文件夹挂载结果

[!TIP] 若 uid 不是 1000,可先运行 id -u 获取当前用户 ID,再替换命令中的参数值。

04 将历史 PBF 文件复制到工作目录

为减少路径输入错误,建议建立独立工作目录:

mkdir -p ~/work/osmium-tool
cd ~/work/osmium-tool

将共享目录中的历史文件复制到工作目录。以下文件名沿用草案示例:

cp /mnt/hgfs/<共享目录>/history-210802.osm.pbf \
  ~/work/osmium-tool/history-210802.osm.pbf

检查文件是否存在及其大小:

ls -lh ~/work/osmium-tool/history-210802.osm.pbf
osmium fileinfo ~/work/osmium-tool/history-210802.osm.pbf

历史 PBF 文件已复制到 Osmium 工作目录

::: tip 文件扩展名说明 Osmium 手册常以 .osh.pbf 表示历史 PBF,以 .osm.pbf 表示普通快照。草案文件使用 .osm.pbf 命名,但真正能否执行 time-filter 取决于文件内容是否包含历史版本。建议用 osmium fileinfo 核验,而不要只依据扩展名判断。 :::

05 从全历史数据提取指定时点快照

5.1 时间过滤的含义

osmium time-filter 可从历史文件中还原某个时间点有效的 OSM 对象。单一时间参数表示“该时刻地图应呈现的状态”,输出为普通 OSM 快照,不再包含完整版本历史。

本文选择 2020 年最后一秒

2020-12-31T23:59:59Z

其中 Z 表示 UTC。该时间点可理解为“2020 年末快照”,而不是“2020 年期间所有曾经出现过的对象集合”。

5.2 执行时点提取

osmium time-filter \
  history-210802.osm.pbf \
  2020-12-31T23:59:59Z \
  -o 2020.osm.pbf \
  --progress

使用绝对路径时:

osmium time-filter \
  /path/to/input/history-210802.osm.pbf \
  2020-12-31T23:59:59Z \
  -o /path/to/output/2020.osm.pbf \
  --progress

若输出文件已存在,可在确认允许覆盖后加入 -O

osmium time-filter -O \
  history-210802.osm.pbf \
  2020-12-31T23:59:59Z \
  -o 2020.osm.pbf

Osmium time-filter 执行进度

5.3 校验输出

ls -lh 2020.osm.pbf
osmium fileinfo 2020.osm.pbf

[!WARNING] 草案文字与截图中分别出现了 2020-12-31T23:59:59Z2020-01-01T00:00:00Z。二者代表不同快照:前者接近 2020 年末,后者是 2020 年初。正式分析必须统一时间定义,并在论文或报告中写明采用 UTC 还是本地时间。

06 按 OSM 标签提取公共交通设施

6.1 单标签提取

以公交站为例:

osmium tags-filter \
  2020.osm.pbf \
  highway=bus_stop \
  -o bus_stop.pbf \
  --progress

使用绝对路径时:

osmium tags-filter \
  /path/to/output/2020.osm.pbf \
  highway=bus_stop \
  -o /path/to/output/bus_stop.pbf \
  --progress

6.2 批量提取四类设施

osmium tags-filter 2020.osm.pbf highway=bus_stop \
  -o bus_stop.pbf --progress

osmium tags-filter 2020.osm.pbf railway=tram_stop \
  -o tram_stop.pbf --progress

osmium tags-filter 2020.osm.pbf railway=station \
  -o railway_station.pbf --progress

osmium tags-filter 2020.osm.pbf amenity=ferry_terminal \
  -o ferry_terminal.pbf --progress

Osmium tags-filter 批量筛选公共交通标签

6.3 一次输出多个标签

若后续分析不要求四类设施分别存成文件,也可以在同一命令中写入多个表达式。tags-filter 对多个表达式采用“至少匹配一个”的逻辑:

osmium tags-filter 2020.osm.pbf \
  highway=bus_stop \
  railway=tram_stop \
  railway=station \
  amenity=ferry_terminal \
  -o public_transport_2020.osm.pbf \
  --progress

[!IMPORTANT] tags-filter 默认会加入匹配要素所引用的节点或关系成员,以维持几何引用完整性。因此,输出文件中可能包含一些本身不带目标标签的辅助对象。这属于正常现象。

6.4 可选:限制对象类型

如果只想匹配节点,可在表达式前加入 n/

osmium tags-filter 2020.osm.pbf \
  n/highway=bus_stop \
  n/railway=tram_stop \
  n/railway=station \
  n/amenity=ferry_terminal \
  -o public_transport_nodes_2020.osm.pbf

但在真实 OSM 数据中,车站或轮渡设施也可能被建模为面或关系。是否限制为节点,应由研究目的决定。

07 将 PBF 转换为 QGIS 可读数据

7.1 按草案方式转换为 .osm

osmconvert bus_stop.pbf --out-osm -o=bus_stop.osm
osmconvert tram_stop.pbf --out-osm -o=tram_stop.osm
osmconvert railway_station.pbf --out-osm -o=railway_station.osm
osmconvert ferry_terminal.pbf --out-osm -o=ferry_terminal.osm

使用 osmconvert 将 PBF 转换为 OSM XML

7.2 推荐的 Osmium 等价写法

若不希望额外安装 osmconvert,可使用 Osmium 自身进行格式转换:

osmium cat bus_stop.pbf -o bus_stop.osm
osmium cat tram_stop.pbf -o tram_stop.osm
osmium cat railway_station.pbf -o railway_station.osm
osmium cat ferry_terminal.pbf -o ferry_terminal.osm

[!TIP] 对于大数据,XML 格式的 .osm 通常比 PBF 占用更多磁盘空间、读取也更慢。若 QGIS/插件能够直接读取 .osm.pbf,可优先保留 PBF;用于长期 GIS 项目时,也可考虑导出为 GeoPackage。

08 将结果传回 Windows 并在 QGIS 中加载

8.1 复制到共享目录

cp *.osm /mnt/hgfs/<共享目录>/

8.2 在 QGIS 中打开 OSM 文件

在 QGIS 中通过“数据源管理器”或直接拖拽方式添加 .osm 文件。QGIS 通常会列出以下子图层:

  • points
  • lines
  • multilinestrings
  • multipolygons
  • other_relations

对于公交站等点状设施,一般选择 points 图层;对于以面建模的站场或码头,还需检查 multipolygons

QGIS 选择并加载 OSM 子图层

[!NOTE] 截图展示的是较早版本 QGIS 界面。不同版本的菜单名称和按钮位置可能略有差异,但核心步骤仍是:加载 OSM 数据、选择几何子图层、检查属性字段。

09 导出为 Shapefile 或 GeoPackage

在目标图层上右键,选择:

导出另存为要素……

主要参数建议如下:

参数建议设置说明
格式ESRI ShapefileGeoPackageGeoPackage 对字段名、编码和多图层支持更好
文件编码UTF-8减少中文属性乱码
坐标参考系根据项目需求设置OSM 原始经纬度通常采用 WGS 84(EPSG:4326)
几何类型与当前子图层一致点、线、面不可混用
仅保存选中要素按需用于二次筛选后的输出

QGIS 将结果图层导出为 Shapefile

::: warning Shapefile 的限制 Shapefile 字段名较短、字段类型受限,并由多个同名文件共同组成。若没有兼容性要求,推荐优先使用 GeoPackage(.gpkg)保存结果。 :::

10 结果检查与效果展示

完成导出后,应至少检查以下内容:

  • 输出图层能够正常加载;
  • 要素数量不是 0;
  • 几何类型符合预期;
  • 属性表中保留了目标标签;
  • 中文名称没有乱码;
  • 数据时间点与研究设计一致;
  • 不同交通类型没有因宽泛标签而大量混淆;
  • 抽样核对若干点位与 OSM 地图或历史页面是否一致。

公交站、轻轨站、铁路站与轮渡码头提取效果

11 一键批处理脚本

以下 Bash 脚本将“时点快照—标签提取—格式转换”串联起来。运行前只需修改输入文件和时间参数。

#!/usr/bin/env bash

set -euo pipefail

HISTORY_FILE="history-210802.osm.pbf"
SNAPSHOT_TIME="2020-12-31T23:59:59Z"
SNAPSHOT_FILE="2020.osm.pbf"

# 1. 从全历史文件恢复指定时点快照。
osmium time-filter \
  "$HISTORY_FILE" \
  "$SNAPSHOT_TIME" \
  -o "$SNAPSHOT_FILE" \
  --progress

# 2. 定义“输出文件名:OSM 标签表达式”。
declare -A FILTERS=(
  [bus_stop]="highway=bus_stop"
  [tram_stop]="railway=tram_stop"
  [railway_station]="railway=station"
  [ferry_terminal]="amenity=ferry_terminal"
)

# 3. 分别提取,并转换为 OSM XML。
for name in "${!FILTERS[@]}"; do
  expression="${FILTERS[$name]}"

  osmium tags-filter \
    "$SNAPSHOT_FILE" \
    "$expression" \
    -o "${name}.pbf" \
    --progress

  osmium cat "${name}.pbf" -o "${name}.osm"
done

echo "处理完成。"

保存为 extract_public_transport.sh 后执行:

chmod +x extract_public_transport.sh
./extract_public_transport.sh

[!WARNING] 脚本默认不覆盖已有文件。重复运行前,应备份或删除旧输出;也可在明确了解后果时,为相关 Osmium 命令加入 -O

12 常见问题排查

12.1 time-filter 报错或输出为空

可能原因:

  1. 输入文件不是全历史数据;
  2. 时间早于数据覆盖范围;
  3. 文件损坏或下载不完整;
  4. 磁盘剩余空间不足。

排查命令:

osmium fileinfo history-210802.osm.pbf
ls -lh history-210802.osm.pbf
df -h

12.2 输出文件已存在

Osmium 默认拒绝覆盖。确认无误后使用 -O

osmium tags-filter -O 2020.osm.pbf \
  highway=bus_stop \
  -o bus_stop.pbf

12.3 QGIS 中出现多个子图层

.osm 是包含多种几何对象的容器。公交站通常位于 points,但车站与码头可能同时出现在点或面图层。应根据标签字段和研究需求选择或合并。

12.4 标签结果与预期不一致

OSM 使用社区协作标注,同类设施可能存在多种标注方案。建议:

  • 在 OpenStreetMap Wiki 和 Taginfo 中核对标签语义与使用量;
  • 同时考虑 public_transport=* 新式公共交通标签;
  • 对宽泛标签加入二级条件;
  • 对研究区进行抽样人工核查。

13 方法边界与研究建议

本文流程恢复的是 指定时点的 OSM 地图状态。它反映该时刻 OSM 数据库中已记录的对象,而不必然等同于现实世界中设施的真实建成或启用日期。

因此,在学术研究中应区分:

  1. OSM 首次出现时间:对象首次被贡献者写入数据库;
  2. OSM 时点状态:对象在某一时间点是否有效存在;
  3. 现实建设时间:设施真实建成、启用或撤销的日期。

三者可能并不一致。若用于严谨的城市演变研究,宜结合政府开放数据、历史影像、运营资料或实地记录进行交叉验证。

14 总结

整个流程可以概括为四个核心动作:

  1. 使用 osmium time-filter 从全历史文件恢复目标时点;
  2. 使用 osmium tags-filter 按 OSM 标签筛选目标设施;
  3. 使用 osmconvertosmium cat 完成格式转换;
  4. 在 QGIS 中加载、检查并导出为 Shapefile 或 GeoPackage。

真正决定结果质量的,不只是命令能否运行,还包括 时间点定义、标签语义、几何类型和结果校验。这些环节应在正式分析前统一设计。


参考资料:

#OpenStreetMap #OsmiumTool #OSM历史数据 #标签过滤 #公共交通 #QGIS #GIS数据处理