LanternD +

AllTrails 导出格式一览

 

引子

 最近在思考怎么把这几年来徒步的各种路线添加到地图上做可视化和分析。这个项目的第一步是选择一种合适的导出格式,既要有全面的信息,又能便于处理。这里导出的路线只是第一步,我的目标是进一步处理导出成 CSV。

 我打开 AllTrails,找了一条路线想导出,结果一看这列表我就懵了。总共 30 几种格式可以导出。我也知道市面上做 GPS 路径的厂家、设备非常多,但是到现在居然格式还没有大一统而且千差万别,这是出乎我意料的。

 下面就是 AllTrails 支持的导出格式。

img 所有可选的导出格式

 本文的重心就是,在这个列表里面找一种靠谱的格式,导出我之前 Hiking 走过的一百多条路线。而且由于程序只开发一次,最好一步到位,不要中间切换格式。

 开始之前总该设定一些目标,这样才能快速筛选。

 我的需求:

 推荐度按我个人需求来打分。其他需求可自行参考。

格式对比

 下面是所有格式的概览。

 如果想看各个文件的样例,这里有一个 33 种格式的合订本。

 【Afternoon-Hike-AllTrails-Exported-Files.zip】(点击会直接下载)

 推荐度:

 注:Elevation = Altitude = 海拔

文件类型 有 Elevation 有元数据 有时间戳 简介 推荐度 ❌🆗✅
GPX Track XML 格式;最流行的文件类型;支持 Bound 属性,画图的时候可以直接确定框的大小,在只画单条线路的时候非常方便;每个点都有时间戳,但是 UTC0 时区;同一经纬度的点,Elevation 和其他文件不一样,差了十几米,据考证这个和网上的高程数据库比较接近
Google Earth KML XML 格式;路径部分是 CSV 格式;元信息比较多(大部分没啥用);没有任何时间信息;可以当作 CSV 的进阶版本
Garmin Course TCX XML 格式;有一个 Distance 属性,记录离出发地的累计距离,可能是从两个点的距离算出来的,如果不用自己算倒也挺好;文件相对比较大,很多冗余信息
Garmin Course CRS 和上面的 Garmin Course TCX 几乎没有区别;应该是旧版本的格式,有前者就不推荐这个了 🆗
CSV 格式简单;没有时间信息
Garmin Fit (ANT+) 二进制,没法读,直接 Pass。应该是 Garmin 设备专用格式
GPX Route 和 GPX Track 比少了 Bound,其他没什么特色 🆗
Google Earth KMZ 二进制,没法读,直接 Pass
Google Earth Timeline 元数据比较齐全;时间戳和位置点是两个单独的列表,处理起来有点奇怪(但是不难)
Google Earth Tour 和 Google Earth KML 有点像,不过多了一个 FlyTo 属性,就是打开 Google Earth 的时候能从高空逐渐放大直到目标点;我可能用不上,但是算个加分项。可以认为这个比 Google Earth KML 更齐全一些;没有任何时间信息 🆗
OVL (ASCII) 格式简单;没有 Elevation,直接 Pass
Fugawi 🆗 约等于更详细一点的 CSV;时间戳只有年月日(UTC+0 时区);没有别的优势,Pass 了
KOMPASS Verlag 和 CSV 一模一样,Pass
PCX5 Track 信息齐全;格式有些复杂, 可能不好处理 🆗
GeoRSS Track 数据格式奇怪,难处理;没有 Elevation
MS Excel 和 CSV 一模一样;不易处理,没有额外的价值
Ozi Explorer 🆗 Elevation 单位是 feet,不靠谱;有很多冗余数据
MagicMaps IKT 导出语言是德语;没有 Elevation
Falk IBEX Tour 格式有点复杂且冗余,经纬度是我看不懂的数据,比如 (4666806, -13632462);没有 Elevation
GeoJSON Track 有 Bounding Box(方便画单张图片);没时间戳
JSON 普通,和 CSV 区别不大
PathAway 有详细时间戳,没有元数据
Navigon RTE 5.x 奇怪的格式,有点像 Markdown Table;没有元数据,没有 Elevation
Navigon RTE 6.x 和上面 5.x 差不多;没有元数据,没有 Elevation
Navigon Freshroute 没有 Elevation 和时间戳
Magellan Track 有点像 NMEA Protocol;元数据不齐全,时间戳有时分秒但没有年月日
O-synce Track 和 GPX Route/Track 几乎没有区别;鉴于前两个比较通用,这个就列为 OK 吧 🆗
CompeGPS Track 信息齐全;有很多冗余的列;单位是「ºN」和「ºW」,有点奇怪 🆗
qpeGPS Track 🆗 Elevation 单位是 feet,不靠谱;有冗余的一列
TomTom ITN 用竖线「|」分割列;经纬度没有小数点
Garmin Logbook XML 格式;信息齐全;没什么亮点 🆗
SQL Inserts Track 给 SQL 数据库用的,很多冗余字符;缺少元信息
BDD (Bait Dropping) 格式奇怪;时间戳全是「00:00:00,00.00.00」(没有时间戳)

小总结

 把所有格式都看过以后我有一些观察:

最后的筛选

 从表格里面可知,最终角逐进入最终候选名单的有以下三种格式:

 后面就要仔细分析它们的优劣了。

GPX Track

格式样例:

<?xml version="1.0"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="1.1" creator="AllTrails.com" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd">
  <metadata>
    <name><![CDATA [Afternoon hike]]></name>
    <desc><![CDATA []]></desc>
    <link href="http://www.alltrails.com">
      <text>AllTrails, LLC</text>
    </link>
    <bounds minlat="38.6505" minlon="-122.63361" maxlat="38.67092" maxlon="-122.59959"/>
  </metadata>
  <trk>
    <name><![CDATA [Afternoon hike]]></name>
    <src>AllTrails</src>
    <trkseg>
      <trkpt lat="38.65262" lon="-122.59967">
        <ele>689.64</ele>
        <time>2023-08-05T21:24:46Z</time>
      </trkpt>
      <trkpt lat="38.65262" lon="-122.5997">
        <ele>689.51</ele>
        <time>2023-08-05T21:24:53Z</time>
      </trkpt>
      <trkpt lat="38.65262" lon="-122.59974">
        <ele>689.6</ele>
        <time>2023-08-05T21:25:01Z</time>
      </trkpt>    
      </trkseg>
  </trk>
</gpx>

 基本上是目前认可度最高的一种格式,不管什么平台都能支持。这个格式里面的 Elevation 也是准确映射到相应的地理位置的高度的,避免了后期的 API 查询。

 其实我一开始就觉得 GPX Track 挺好的。它也是列表里面的第一项。我抱着「万一有更好的格式呢」的心态,把别的都试了一圈,最后也没几个能打败 GPX Track 的,也是令人唏嘘了。

Garmin Course TCX

 格式样例:

<?xml version="1.0"encoding="UTF-8"?>
<TrainingCenterDatabase xmlns="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.garmin.com/xmlschemas/TrainingCenterDatabase/v2 http://www8.garmin.com/xmlschemas/TrainingCenterDatabasev2.xsd">
  <Folders>
    <Courses>
      <CourseFolder Name="AllTrails">
        <CourseNameRef>
          <Id>Afternoon hike</Id>
        </CourseNameRef>
      </CourseFolder>
    </Courses>
  </Folders>
  <Courses>
    <Course>
      <Name>Afternoon hike</Name>
      <Lap>
        <TotalTimeSeconds>12271.0</TotalTimeSeconds>
        <DistanceMeters>16195.097833376125</DistanceMeters>
        <BeginPosition>
          <LatitudeDegrees>38.65262000</LatitudeDegrees>
          <LongitudeDegrees>-122.599670</LongitudeDegrees>
        </BeginPosition>
        <EndPosition>
          <LatitudeDegrees>38.65259000</LatitudeDegrees>
          <LongitudeDegrees>-122.599620</LongitudeDegrees>
        </EndPosition>
        <Intensity>Active</Intensity>
      </Lap>
      <Track>
        <Trackpoint>
          <Time>2023-08-05T21:24:46Z</Time>
          <Position>
            <LatitudeDegrees>38.65262000</LatitudeDegrees>
            <LongitudeDegrees>-122.599670</LongitudeDegrees>
          </Position>
          <AltitudeMeters>707.00000</AltitudeMeters>
          <DistanceMeters>0.000</DistanceMeters>
        </Trackpoint>
        <Trackpoint>
          <Time>2023-08-05T21:24:53Z</Time>
          <Position>
            <LatitudeDegrees>38.65262000</LatitudeDegrees>
            <LongitudeDegrees>-122.599700</LongitudeDegrees>
          </Position>
          <AltitudeMeters>706.00000</AltitudeMeters>
          <DistanceMeters>2.605</DistanceMeters>
        </Trackpoint>
        <Trackpoint>
          <Time>2023-08-05T21:25:01Z</Time>
          <Position>
            <LatitudeDegrees>38.65262000</LatitudeDegrees>
            <LongitudeDegrees>-122.599740</LongitudeDegrees>
          </Position>
          <AltitudeMeters>706.00000</AltitudeMeters>
          <DistanceMeters>6.079</DistanceMeters>
        </Trackpoint>
        <Trackpoint>
          <Time>2023-08-05T21:25:07Z</Time>
          <Position>
            <LatitudeDegrees>38.65262000</LatitudeDegrees>
            <LongitudeDegrees>-122.599780</LongitudeDegrees>
          </Position>
          <AltitudeMeters>707.00000</AltitudeMeters>
          <DistanceMeters>9.553</DistanceMeters>
        </Trackpoint>
          </Track>
    </Course>
  </Courses>
</TrainingCenterDatabase>

 本质上来说,TCX 在 GPX 基础上多了「从起点到当前点的累积距离」这个数据,其实还是有点用的。此外还有起止点坐标,路线总耗时等等元数据。TCX 在元数据方面是比别的详细很多的。

 如果知道了所有的点的 GPS 坐标,算累计距离好像也不难,但是那也是额外的活。而且似乎它的计算还挺标准,与其自己发明个算法,不如直接拿现成的。

 Elevation 这个倒是可以直接调用网上的 API(比如 Google Maps Platform 的 Elevation API),给个经纬度返回对应的海拔。

Google Earth Timeline

 格式样例:

<?xml version="1.0"encoding="UTF-8"?>
<kml xmlns="http://www.opengis.net/kml/2.2" xmlns:gx="http://www.google.com/kml/ext/2.2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/kml/2.2 http://schemas.opengis.net/kml/2.2.0/ogckml22.xsd http://www.google.com/kml/ext/2.2 http://code.google.com/apis/kml/schema/kml22gx.xsd">
  <Document>
    <name>Afternoon hike</name>
    <description><![CDATA [https://www.gpsies.com/map.do?fileId=null]]></description>
    <Style id="multiTrack_n">
      <IconStyle>
        <scale>1.2</scale>
        <Icon>
          <href>https://earth.google.com/images/kml-icons/track-directional/track-0.png</href>
        </Icon>
      </IconStyle>
      <LineStyle>
        <color>be3887a0</color>
        <width>6</width>
      </LineStyle>
    </Style>
    <Style id="multiTrack_h">
      <IconStyle>
        <scale>1.2</scale>
        <Icon>
          <href>https://earth.google.com/images/kml-icons/track-directional/track-0.png</href>
        </Icon>
      </IconStyle>
      <LineStyle>
        <color>beabb7f5</color>
        <width>6</width>
      </LineStyle>
    </Style>
    <StyleMap id="multiTrack">
      <Pair>
        <key>normal</key>
        <styleUrl>#multiTrack_n</styleUrl>
      </Pair>
      <Pair>
        <key>highlight</key>
        <styleUrl>#multiTrack_h</styleUrl>
      </Pair>
    </StyleMap>
    <Placemark>
      <name>Afternoon hike</name>
      <styleUrl>#multiTrack</styleUrl>
      <gx:MultiTrack>
        <gx:Track>
          <when>2023-08-05T21:24:46Z</when>
          <when>2023-08-05T21:24:53Z</when>
          <when>2023-08-05T21:25:01Z</when>
          <when>2023-08-05T21:25:07Z</when>
          <when>2023-08-05T21:25:33Z</when>
          <when>2023-08-05T21:25:35Z</when>
          <when>2023-08-05T21:25:36Z</when>
          <when>2023-08-05T21:25:37Z</when>
          <when>2023-08-05T21:25:39Z</when>
          <when>2023-08-05T21:25:42Z</when>
          <gx:coord>-122.599670 38.65262000 707</gx:coord>
          <gx:coord>-122.599700 38.65262000 706</gx:coord>
          <gx:coord>-122.599740 38.65262000 706</gx:coord>
          <gx:coord>-122.599780 38.65262000 707</gx:coord>
          <gx:coord>-122.599810 38.65264000 706</gx:coord>
          <gx:coord>-122.599860 38.65264000 707</gx:coord>
          <gx:coord>-122.599900 38.65264000 707</gx:coord>
          <gx:coord>-122.599940 38.65264000 707</gx:coord>
          <gx:coord>-122.599980 38.65264000 707</gx:coord>
          <gx:coord>-122.600020 38.65262000 709</gx:coord>
        </gx:Track>
      </gx:MultiTrack>
    </Placemark>
  </Document>
</kml>

 Google 的这个 KML 格式也很普及。它的特点是时间戳放一段,数据点放另外单独一段。这个倒是很合适用 Pandas 之类的直接转成 DataFrame。

 不过我总担心这两者长度不一致,导致转换出现异常。从数据安全角度看,这个并不优化。反之,每个数据点都应该自成一体,如果出问题了也是一个数据点出问题,不会连累其他的数据点。因为这点,我决定将 Google Earth Timeline 格式的优先级下降一些。

最终选择

 最后的赢家是:「 Garmin Course TCX 」!

 我决定还是留下「从起点的累积距离」这样一个参数。至于真实海拔,我打算用 Google Elevation API 批量查询添加。

  1. 2023-10-03 Update

    Garmin Cource TCX 格式里面的 Trail 元信息有长度限制。比如一次 Hiking 的名称叫 「Morning hike in Alum Rock Park」,导出的 TCX 只能保留「Morning hike in」这一部分。相比之下 GPX Track 格式可以保留所有名称信息。在这点上还是 GPX Track 有优势一些。不过我有别的办法搞定这一项,所以就暂时维持决定不变。

尾记

 后面就是研究怎么批量下载 AllTrails 上的轨迹并且搞定后续的数据处理了。工程量不大不小,期待最后能搞出漂亮的可视化结果。

LanternD
LanternD_Logo






订阅

RSS订阅 微信公众号

文以类聚

更多『hitech』分类的文章