You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于时序GPS坐标检测铁路轨道直线路段与左右弯道

基于时序GPS数据的铁路轨道弯道检测方案

你当前采用的样条插值残差判定思路存在本质问题:插值残差仅能反映拟合曲线与原始点位的偏离程度,既无法区分弯道转向,也会受GPS噪声、重复点位、经纬度球面坐标畸变的干扰,完全不具备普适性。从你给出的测试结果也能看出问题:直线路段的计算残差(0.038)甚至高于2号弯道的残差(0.019),说明这个指标本身就无法区分直道和弯道。

你提供的弯道样例数据如下:

latitude longitude altitude
1  43.46724 -5.823470    145.0
2  43.46726 -5.823653    145.2
3  43.46728 -5.823837    145.4
4  43.46730 -5.824022    145.6
5  43.46730 -5.824022    145.6
6  43.46734 -5.824394    146.0
7  43.46738 -5.824768    146.3
8  43.46738 -5.824768    146.3
9  43.46742 -5.825146    146.7
10 43.46742 -5.825146    146.7
11 43.46746 -5.825527    147.1
12 43.46746 -5.825527    147.1
13 43.46750 -5.825910    147.3
14 43.46751 -5.826103    147.4
15 43.46753 -5.826295    147.6
16 43.46753 -5.826489    147.8
17 43.46753 -5.826685    148.1
18 43.46753 -5.826878    148.2
19 43.46752 -5.827073    148.4
20 43.46750 -5.827266    148.6
21 43.46748 -5.827458    148.9
22 43.46744 -5.827650    149.2
23 43.46741 -5.827839    149.5
24 43.46736 -5.828029    149.7
25 43.46731 -5.828212    150.1
26 43.46726 -5.828393    150.4
27 43.46720 -5.828572    150.5
28 43.46713 -5.828746    150.8
29 43.46706 -5.828914    151.0
30 43.46698 -5.829078    151.2
31 43.46690 -5.829237    151.4
32 43.46681 -5.829392    151.6
33 43.46671 -5.829540    151.8
34 43.46661 -5.829680    152.0
35 43.46650 -5.829816    152.2
36 43.46639 -5.829945    152.4
37 43.46628 -5.830066    152.4
38 43.46616 -5.830180    152.4
39 43.46604 -5.830287    152.5
40 43.46591 -5.830384    152.6
41 43.46579 -5.830472    152.8
42 43.46566 -5.830552    152.9
43 43.46552 -5.830623    153.2
44 43.46539 -5.830687    153.4
45 43.46526 -5.830745    153.6
46 43.46512 -5.830795    153.8
47 43.46499 -5.830838    153.9
48 43.46485 -5.830871    153.9
49 43.46471 -5.830895    154.0
50 43.46458 -5.830911    154.2
51 43.46445 -5.830919    154.3
52 43.46432 -5.830914    154.7
53 43.46418 -5.830896    155.1
54 43.46406 -5.830874    155.6
55 43.46393 -5.830842    155.9
56 43.46381 -5.830803    156.0
57 43.46368 -5.830755    155.5
58 43.46356 -5.830700    155.3
59 43.46332 -5.830575    155.1

你之前编写的样条插值测试代码如下:

from scipy.interpolate import make_interp_spline

## read csv file with pandas
df = pd.read_csv("Curvas/Curva_2.csv")
   
# take latitude and longitude columns
df['latitude'].fillna(method='ffill',inplace=True)
df['longitude'].fillna(method='ffill',inplace=True)

# plot the data
# df.plot(x='longitude', y='latitude', style='o')
# plt.show()

# using longitude and latitude data, use spline interpolation to create a new curve
x = df['longitude']
y = df['latitude']
xnew = np.linspace(x.min(), x.max(), x.shape[0])

ynew = make_interp_spline(xnew, y)(x)
plt.plot(xnew, ynew, zorder=2)
plt.show()

## Error results using different coordinates/routes
## Curve_1 → Left (e = 0.04818886515888465)
## Curve_2 → Left (e = 0.019459215874292113)    
## Straight_1 → Straight (e = 0.03839597167971931)

具体实现步骤

1. 数据预处理

  • 首先剔除经纬度完全重复的点位,避免后续向量计算出现除零错误
  • 将WGS84经纬度坐标投影到对应区域的平面投影坐标系(你提供的点位位于西班牙区域,可采用EPSG:25829 UTM投影),将角度单位的经纬度转换为米为单位的平面x/y坐标,禁止直接用经纬度角度值做几何计算
  • 对投影后的坐标做3-5个点的滑动窗口均值平滑,抵消GPS的随机测量噪声

2. 转向判定核心逻辑

轨迹转向检测的通用高效方案是连续三点叉乘判别法,不需要复杂插值,计算逻辑简单可靠:
将轨迹点按时间顺序排列,取任意连续三个点$P_{i-1}、P_i、P_{i+1}$,计算两个相邻段的向量:

  • 前一段向量:$\vec{a} = (x_i - x_{i-1}, y_i - y_{i-1})$
  • 后一段向量:$\vec{b} = (x_{i+1} - x_i, y_{i+1} - y_i)$
    计算两个向量的二维叉乘值:cross = a_x * b_y - a_y * b_x
    叉乘值的符号直接对应转向方向:
  • 若cross > 判定阈值:当前点位于左转弯路段
  • 若cross < -判定阈值:当前点位于右转弯路段
  • 若abs(cross) ≤ 判定阈值:当前点位于直线路段

3. 阈值标定与结果优化

  • 阈值不需要硬编码:取你提前标注的直线路段上叉乘值的3倍标准差作为判定阈值即可,可自动适配你的GPS设备精度
  • 对逐点得到的转向标签做滑动窗口投票:例如取20个点的窗口(对应铁路上约30-50米长度),窗口内超过70%的点判定为同一转向,就将整个窗口标记为对应路段,避免零星噪声点把连续弯道切割成碎片
  • 长度小于10个点的短转向片段直接合并到相邻长路段,排除GPS跳点导致的误检

可直接运行的参考代码

import pandas as pd
import numpy as np
import pyproj

# 初始化坐标转换器:WGS84经纬度转研究区域平面UTM坐标
transformer = pyproj.Transformer.from_crs("EPSG:4326", "EPSG:25829", always_xy=True)

# 读取数据
df = pd.read_csv("Curvas/Curva_2.csv")
# 缺失值填充+重复点位去除
df = df[['latitude', 'longitude', 'altitude']].ffill().drop_duplicates(subset=['latitude', 'longitude'])
# 坐标投影,注意转换器输入顺序为经度、纬度
df['x'], df['y'] = transformer.transform(df['longitude'].values, df['latitude'].values)

# 计算连续相邻点的坐标差
df['dx1'] = df['x'].diff()
df['dy1'] = df['y'].diff()
df['dx2'] = df['dx1'].shift(-1)
df['dy2'] = df['dy1'].shift(-1)

# 计算叉乘值
df['cross'] = df['dx1'] * df['dy2'] - df['dy1'] * df['dx2']

# 转向判定,经验阈值10(单位:平方米,适配1-2米间隔的GPS采样点)
# 正式使用时请用自有直线路段数据重新标定阈值
turn_threshold = 10
df['turn_type'] = np.where(
    df['cross'] > turn_threshold, 'left_curve',
    np.where(df['cross'] < -turn_threshold, 'right_curve', 'straight')
)

补充说明:铁路轨道曲率变化平缓,如果需要更高的检测精度,可以在平滑后的平面坐标上用滑动窗口拟合圆弧,计算连续曲率值与曲率方向,结果会比单点叉乘更稳定,但转向方向的核心判定逻辑依然基于叉乘符号。

弯道示例2


内容的提问来源于stack exchange,提问作者Yassin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.28 21:06:34