代码之家  ›  专栏  ›  技术社区  ›  probot

如果没有给出速度标记本身,如何从gpx文件计算速度?

  •  -1
  • probot  · 技术社区  · 7 年前

    例如,我可能有以下信息:

    <trkpt lat="-33.8161780" lon="150.8710320">
     <ele>73.0</ele>
     <time>2017-07-08T22:05:45Z</time>
     <extensions>
      <power>0</power>
      <gpxtpx:TrackPointExtension>
        <gpxtpx:atemp>7</gpxtpx:atemp>
        <gpxtpx:hr>115</gpxtpx:hr>
        <gpxtpx:cad>27</gpxtpx:cad>
      </gpxtpx:TrackPointExtension>
     </extensions>
    </trkpt>
    

    有人提到,我可能应该显示熊猫数据帧。它看起来像这样:

                         longitude   latitude   ele   temp
    time                
    2017-07-08 22:05:45 150.8710320 -33.8161780 73.0    7
    2017-07-08 22:05:46 150.8710350 -33.8161500 73.0    7
    2017-07-08 22:05:47 150.8710440 -33.8161170 73.0    7
    2017-07-08 22:05:48 150.8710540 -33.8160820 73.0    7
    2017-07-08 22:05:49 150.8710690 -33.8160430 73.0    7
    

    1 回复  |  直到 7 年前
        1
  •  3
  •   unutbu    7 年前

    speed distance / time . 这个 longitude latitude 大概代表地球表面的位置。如果我们接受一个半径为6371公里的球体作为地球的近似值,那么我们可以很容易地转换 xyz

    r = 6371000 # meters
    df['theta'] = np.deg2rad(df['longitude'])
    df['phi'] = np.deg2rad(df['latitude'])
    df['x'] = r*np.cos(df['theta'])*np.sin(df['phi'])
    df['y'] = r*np.sin(df['theta'])*np.sin(df['phi'])
    df['z'] = r*np.cos(df['phi'])
    

    df['x2'] = df['x'].shift()
    df['y2'] = df['y'].shift()
    df['z2'] = df['z'].shift()
    df['distance'] = np.sqrt((df['x2']-df['x'])**2 + (df['y2']-df['y'])**2 + (df['z2']-df['z'])**2)
    

    arclength

    df['central angle'] = np.arccos((df['x']*df['x2'] + df['y']*df['y2'] + df['z']*df['z2'])/r**2)
    df['arclength'] = df['central angle']*r
    

    dot product formula .

    在计算弧长(距离)之后,我们现在还必须计算 time 连续观察之间的间隔(即数据帧的行):

    df['time'] = (df.index.to_series().diff() / pd.Timedelta(seconds=1))
    

    所以使用 speed = distance / time :

    df['speed'] = df['arclength'] / df['time']  # in meters/second
    

    import numpy as np
    import pandas as pd
    
    df = pd.DataFrame({'ele': [73.0, 73.0, 73.0, 73.0, 73.0], 'latitude': [-33.816178, -33.81615, -33.816117, -33.816082, -33.816043], 'longitude': [150.871032, 150.871035, 150.87104399999998, 150.87105400000002, 150.871069], 'temp': [7, 7, 7, 7, 7], 'time': ['2017-07-08 22:05:45', '2017-07-08 22:05:46', '2017-07-08 22:05:47', '2017-07-08 22:05:48', '2017-07-08 22:05:49']})
    df['time'] = pd.to_datetime(df['time'])
    df = df.set_index('time')
    columns = df.columns.tolist()
    
    r = 6371000 # radius of the Earth in meters
    df['theta'] = np.deg2rad(df['longitude'])
    df['phi'] = np.deg2rad(df['latitude'])
    df['x'] = r*np.cos(df['theta'])*np.sin(df['phi'])
    df['y'] = r*np.sin(df['theta'])*np.sin(df['phi'])
    df['z'] = r*np.cos(df['phi'])
    df['distance'] = np.sqrt((df['x2']-df['x'])**2 + (df['y2']-df['y'])**2 + (df['z2']-df['z'])**2)
    
    df['x2'] = df['x'].shift()
    df['y2'] = df['y'].shift()
    df['z2'] = df['z'].shift()
    df['central angle'] = np.arccos((df['x']*df['x2'] + df['y']*df['y2'] + df['z']*df['z2'])/r**2)
    df['arclength'] = df['central angle']*r
    
    df['time'] = (df.index.to_series().diff() / pd.Timedelta(seconds=1))
    df['speed'] = df['arclength'] / df['time']  # in meters/second
    df = df[columns + ['speed']]
    print(df)
    

                          ele   latitude   longitude  temp     speed
    time                                                            
    2017-07-08 22:05:45  73.0 -33.816178  150.871032     7       NaN
    2017-07-08 22:05:46  73.0 -33.816150  150.871035     7  3.119892
    2017-07-08 22:05:47  73.0 -33.816117  150.871044     7  3.712201
    2017-07-08 22:05:48  73.0 -33.816082  150.871054     7  3.940673
    2017-07-08 22:05:49  73.0 -33.816043  150.871069     7  4.433590
    

    如果你发表评论

    df = df[columns + ['speed']]
    

    然后重新运行脚本,您将看到所有中间计算。你会 请注意 df['distance'] df['arclength'] . 自 点在地球表面相距不远,弦长为 弧长的良好近似值。那么对于你发布的数据

    df['speed'] = df['distance'] / df['time'] 
    

    arclength