在colab上运行,所以如何在colab上安装fmm,可见FMM 笔记:在colab上执行FMM-CSDN博客
st-matching见论文笔记:Map-Matching for low-sampling-rate GPS trajectories(ST-matching)-CSDN博客
0 导入库
from fmm import Network,NetworkGraph,STMATCH,STMATCHConfig
1 加载数据(边的shp文件)
import geopandas as gpd
shp_path = "../data/edges.shp"
gdf = gpd.read_file(shp_path)
gdf
2 提取路网信息
network = Network("../data/edges.shp")
#通过Network类加载路网数据(edges.shp)
print("Nodes {} edges {}".format(network.get_node_count(),network.get_edge_count()))
#Nodes 17 edges 30
graph = NetworkGraph(network)
#使用NetworkGraph类基于这个网络创建一个图形(Graph)对象
3 创建ST-matching模型
model = STMATCH(network,graph)
#传入之前创建的网络和图形对象
3.1 定义st-matching模型的配置
k = 4
#candidate 数量
gps_error = 0.5
#gps定位误差
radius = 0.4
#搜索半径
vmax = 30
#速度上限
factor = 1.5
stmatch_config = STMATCHConfig(k, radius, gps_error, vmax, factor)
4 单条数据的地图匹配
4.0 输入数据
输入数据是wkt格式的数据
地理笔记:WKT,WKB,GeoJSON-CSDN博客
wkt ='LINESTRING(0.200812146892656 2.14088983050848,1.44262005649717 2.14879943502825,3.06408898305084 2.16066384180791,3.06408898305084 2.7103813559322,3.70872175141242 2.97930790960452,4.11606638418078 2.62337570621469)'
4.1 进行地图匹配
result = model.match_wkt(wkt,stmatch_config)
print("Matched path: ", list(result.cpath))
#Matched path: [8, 11, 13, 18, 20, 24]
'''
这个输出显示的是整个轨迹匹配后形成的路径上的边的序列。
它代表了轨迹匹配算法认为GPS轨迹所经过的路网中的边的集合。
如果轨迹沿着某些边连续移动,这些边会在Matched path中按顺序出现。
但重要的是,Matched path中不会重复相同的边,即使实际的GPS轨迹在同一条边上有多个点。
它更侧重于表示轨迹的整体路线,而不是每个点的具体匹配情况。
'''
cpath 联想为continuous path ,即“连续路径”
print("Matched edge for each point: ", list(result.opath))
#Matched edge for each point: [8, 11, 18, 18, 20, 24]
'''
这个输出则提供了轨迹中每个单独点匹配到的边的详细信息。
即使多个连续的点匹配到了同一条边,这里也会为每个点重复显示那条边的ID
'''
opath, 联想为Original Path,即“原始路径”
print("Matched edge index ",list(result.indices))
#Matched edge index [0, 1, 3, 3, 4, 5]
'''
这是匹配到的边的索引列表,表示每个匹配点在匹配路径中的位置
(和Matched edge for each point 表示的是一个意思)
例如,如果输出是[0, 1, 3, 3, 4, 5],这意味着第一个点匹配到了cpath中第一个边(索引0),
第二个点匹配到了第二个边(索引1),接下来两个点都匹配到了第四个边(索引3),依此类推
'''
print("Matched geometry: ",result.mgeom.export_wkt())
#Matched geometry: LINESTRING(0.20081215 2,1 2,2 2,3 2,3 3,4 3,4 2.6233757)
'''
匹配得到的路径的几何形状,以WKT(Well-Known Text)格式表示
'''
print("Matched point ", result.pgeom.export_wkt())
#Matched point LINESTRING(0.20081215 2,1.4426201 2,3 2.1606638,3 2.7103814,3.7087218 3,4 2.6233757)
'''
表示的是输入的GPS轨迹上的点如何被匹配到了道路网络上
'''
mgeom——matched geometry
pgeom——projected geometry
5 带timestamp的数据的地图匹配
from fmm import Trajectory,wkt2linestring
5.1 获得轨迹 & 轨迹的timestamp
5.1.1 轨迹wkt转化成LineString
还是之前的那条轨迹的wkt,先转换为Linestring
line = wkt2linestring(wkt)
line
#<fmm.LineString; proxy of <Swig Object of type 'FMM::CORE::LineString *' at 0x7f9f5fe0fa50> >
5.1.2 为轨迹每一个点添加时刻
traj_id = 1
timestamps = []
for i in range(line.get_num_points()):
timestamps.append(i)
traj = Trajectory(traj_id,line,timestamps)
traj
#<fmm.Trajectory; proxy of <Swig Object of type 'FMM::CORE::Trajectory *' at 0x7f9f98e0fa80> >
5.2 进行匹配
可以说前面虽然设置了stmatch的vmax,但是那个限制其实是用不上的
result = model.match_traj(traj,stmatch_config)
print("Matched path: ", list(result.cpath))
print("Matched edge for each point: ", list(result.opath))
print("Matched edge index ",list(result.indices))
print("Matched geometry: ",result.mgeom.export_wkt())
'''
Matched path: [8, 11, 13, 18, 20, 24]
Matched edge for each point: [8, 11, 18, 18, 20, 24]
Matched edge index [0, 1, 3, 3, 4, 5]
Matched geometry: LINESTRING(0.20081215 2,1 2,2 2,3 2,3 3,4 3,4 2.6233757)
'''
6 将一个文件中的轨迹分别进行匹配,并输出到另一个文件中
from fmm import GPSConfig,ResultConfig
6.1 输入文件设置
输入文件长这样:
gpd.read_file("../data/trips.csv")
# Define input data configuration
input_config = GPSConfig()
input_config.file = "../data/trips.csv"
input_config.id = "id"
print(input_config.to_string())
'''
[40]
0 秒
print(input_config.to_string())
gps file : ../data/trips.csv
id column : id
geom column : geom
timestamp column : timestamp
x column : x
y column : y
GPS point : false
'''
6.2 输出文件信息
result_config = ResultConfig()
result_config.file = "../data/mr.txt"
result_config.output_config.write_opath = True
#结果文件将包含匹配的路径信息(每个单独点匹配到的边的信息)
print(result_config.to_string())
'''
Result file : ../data/mr.txt
Output fields: opath cpath mgeom
'''
6.3 路网匹配
status = model.match_gps_file(input_config, result_config, stmatch_config)
print(status)
'''
Status: success
Time takes 0.003 seconds
Total points 17 matched 17
Map match speed 5666.67 points/s
'''
6.4 查看匹配结果
import pandas as pd
pd.read_csv("../data/mr.txt",delimiter=';')