快速地图匹配(FMM)的开源工具与代码示例
- 常用开源工具
FMM 官方库:https://github.com/cyang-kth/fmm(C++ 实现,支持 Python 绑定,专为大规模轨迹匹配设计);
OSMnx:Python 库,可加载 OSM 路网,结合简单匹配算法实现轻量化轨迹匹配;
PostGIS:空间数据库,通过 ST_Snap 等函数实现轨迹与路网的匹配。 - 轻量化 Python 示例(基于 OSMnx + 简单匹配)
python
运行
import osmnx as ox
import matplotlib.pyplot as plt
import geopandas as gpd
from shapely.geometry import LineString
---------------------- 步骤1:加载路网和原始轨迹 ----------------------
加载北京市某区域的路网(OSM数据)
G = ox.graph_from_place("Dongcheng District, Beijing, China", network_type="drive")
原始GPS轨迹(模拟漂移数据)
raw_trajectory = [(116.403874, 39.914885), (116.404562, 39.915234), (116.405123, 39.915876)]
raw_line = LineString(raw_trajectory)
---------------------- 步骤2:轨迹匹配到路网(简化版) ----------------------
将轨迹点匹配到最近的道路边
matched_points = []
for point in raw_trajectory:
找到距离该点最近的道路边
nearest_edge = ox.distance.nearest_edges(G, point[0], point[1])
获取道路边的几何形状
u, v, key = nearest_edge
edge_geom = G.edges[u, v, key]["geometry"]
计算点在道路边上的投影点
proj_point = edge_geom.interpolate(edge_geom.project(ox.geometry.Point(point)))
matched_points.append((proj_point.x, proj_point.y))
matched_line = LineString(matched_points)
---------------------- 步骤3:可视化 ----------------------
fig, ax = plt.subplots(figsize=(10, 10))
渲染路网底图
ox.plot_graph(G, ax=ax, node_size=0, edge_color="gray", edge_linewidth=1)
渲染原始轨迹(红色虚线,带漂移)
ax.plot(*raw_line.xy, color="red", linestyle="--", linewidth=2, label="Raw Trajectory (GPS Drift)")
渲染匹配后轨迹(蓝色实线,贴合路网)
ax.plot(*matched_line.xy, color="blue", linewidth=3, label="Matched Trajectory (FMM)")
标注起点终点
ax.scatter(raw_trajectory[0][0], raw_trajectory[0][1], color="green", s=100, marker="o", label="Start")
ax.scatter(raw_trajectory[-1][0], raw_trajectory[-1][1], color="orange", s=100, marker="s", label="End")
ax.legend()
plt.title("Fast Map Matching (FMM) Trajectory Visualization")
plt.show()
总结
"快速地图匹配(FMM)" 才是轨迹可视化中针对真实采集轨迹的核心技术,作用是矫正 GPS 漂移、让轨迹贴合路网;
而 "快速行进法(FMM)" 是针对虚拟轨迹生成的算法,作用是在代价场中生成最优路径。
两者都可用于轨迹可视化,但适用场景完全不同:
若有真实 GPS 轨迹数据 → 用 快速地图匹配(FMM) 做轨迹矫正后可视化;
若需要生成虚拟最优路径 → 用 快速行进法(FMM) 生成轨迹后可视化。