FMM 笔记:st-matching(colab上执行)【官方案例解读】

本文介绍了如何在GoogleColab环境中安装和使用FMM库进行地图匹配,包括加载路网数据、创建STMATCH模型、配置参数以及对单条和带timestamp的GPS轨迹进行匹配。详细步骤包括数据加载、模型构建和匹配结果的解读。
摘要由CSDN通过智能技术生成

在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)
k

候选数,即每个GPS点考虑的最大候选路网节点数。默认值为8,意味着每个GPS点在匹配过程中会考虑其周围最近的8个路网节点作为可能的匹配点。

增加此值可以提高匹配的灵活性,但同时也会增加计算复杂度和时间。

r 搜索半径(单位:地图单位),即在每个GPS点周围搜索候选路网节点的半径范围。默认值为300,单位通常是米或者其他地图单位。

设置一个合理的搜索半径可以帮助在GPS点周围找到合适的路网节点,太小可能找不到节点,太大则增加不必要的计算负担。
gps_errorGPS传感器误差(单位:地图单位),表示GPS数据的精度或误差范围。默认值为50。
vmax最大车速(单位:地图单位),仅适用于stmatch算法。默认值为30
  •  地图单位
    • 当GPS数据和路网数据都以地理坐标系统(经纬度)存储时,它们是未投影的,意味着它们直接表示地球表面上的角度。
      • 在这种情况下,距离和速度的计算需要考虑地球的曲率,通常需要通过地理距离公式(如Haversine公式)将角度差转换为实际的线性距离。
      • 由于纬度每变化1度大约等于地球表面上的111公里(具体数值略有不同,取决于具体位置的纬度),因此如果搜索半径设置为0.003度,实际上代表了大约300米的搜索半径。
    • 如果GPS数据和路网数据都被投影到某个线性单位的坐标系统中(如米),这种情况下单位直接对应实际的距离,使得计算更直接、更简单。
      • 在这种情况下,如果搜索半径设置为300,那么它直接表示300米。

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 输入文件设置

输入文件长这样:(注:有一个小细节需要注意:这边csv文件需要以分号分隔)

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=';')

  • 5
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
中文分词是自然语言处理领域的一个重要问题。以下是几个常用的简易中文分词算法及其实现方式: 1. FMM 算法(正向最大匹配算法) FMM 算法是最早的一种中文分词算法,其基本思想是从前向后扫描文本,按照词典中最长词的长度进行匹配。如果匹配成功,则将该词切分出来,继续扫描后面的文本。如果匹配不成功,则将当前字符作为单字切分出来,继续扫描后面的文本。 以下是 FMM 算法的简单实现方式: ```python def fmm(text, dictionary): result = [] i = 0 while i < len(text): for j in range(len(dictionary), 0, -1): if text[i:i+j] in dictionary: result.append(text[i:i+j]) i += j break else: result.append(text[i]) i += 1 return result ``` 其中,text 表示待分词的文本,dictionary 表示词典。该算法的时间复杂度为 O(n^2),在处理长度较长的文本时速度较慢。 2. pymmseg-cpp pymmseg-cpp 是一个基于 C++ 实现的中文分词库,可以通过 Python 调用其提供的接口进行分词。 以下是使用 pymmseg-cpp 进行中文分词的示例代码: ```python import mmseg def seg(text): algor = mmseg.Algorithm(text) result = [] for tok in algor: result.append(tok.text) return result ``` 3. smallseg smallseg 是一个简单的中文分词库,其实现方式类似于 FMM 算法。 以下是使用 smallseg 进行中文分词的示例代码: ```python from smallseg import SEG def seg(text): seg = SEG() result = [] for word in seg.cut(text): result.append(word) return result ``` 4. judou 句读 judou 句读是一个基于规则和机器学习的中文分词库,可以识别并切分一些特殊结构的短语,如时间、地点、人名、机构名等。 以下是使用 judou 进行中文分词的示例代码: ```python from judou import JudouTokenizer def seg(text): tokenizer = JudouTokenizer() result = tokenizer.tokenize(text, 'list') return result ``` 5. BECer-GAE BECer-GAE 是一个基于神经网络的中文分词库,可以识别出新词和未登录词。 以下是使用 BECer-GAE 进行中文分词的示例代码: ```python import becer def seg(text): model = becer.load_model() result = model.segment(text) return result ``` 以上是几种常用的简易中文分词算法及其实现方式,每种算法都有其优缺点,具体使用时需要根据实际情况进行选择。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

UQI-LIUWJ

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值