gpxpy: 如何从 gpx 文件中提取心率数据

3

这个提交到gpxpy库的代码包括对Garmin 1.1扩展的额外解析。但是自此提交以来,代码已经发生了很大变化,看起来现在扩展已经被自动解析了。

然而,我无法弄清楚如何使用gpxpy从gpx文件中提取心率数据或其他扩展数据。有人用gpxpy做过吗?如何操作?


修改以避免关闭此问题:

如果您查看我上面链接的提交中的代码添加,它修改了TrackPoint类以添加“atemp”和“hr”

 class GPXTrackPoint(mod_geo.Location):
     def __init__(self, latitude, longitude, elevation=None, time=None, symbol=None, comment=None,
             horizontal_dilution=None, vertical_dilution=None, position_dilution=None, speed=None,
             name=None, atemp = None, hr = None):

稍后在parser.py中,您会看到添加了这个程序。
def __parse_track_point_extension(self, node):
+        atemp_node = self.xml_parser.get_first_child(node, 'atemp')
+        atemp = mod_utils.to_number(self.xml_parser.get_node_data(atemp_node))
+
+        hr_node = self.xml_parser.get_first_child(node, 'hr')
+        hr = mod_utils.to_number(self.xml_parser.get_node_data(hr_node))

+        extensions = {"atemp":atemp, "hr":hr}
+        return extensions

然而,在当前代码中,该结构与最初提交时非常不同,但似乎可以更通用地解析扩展。但我对Python的掌握程度不够,不理解如何使其解析这些标签。我的问题是为了理解我在新代码中缺失了什么。我的直觉是在the gpx.py code的第74行左右添加一行类似于此的内容。
mod_gpxfield.GPXField('heart_rate', 'hr', type=mod_gpxfield.FLOAT_TYPE),

然而,我希望有经验的人可以查看代码,看看是否有我遗漏的东西,比如指定一个列表扩展名=[hr,atemp]并在读取数据时通用解析它们。看起来这个提交是过去做的,但现在这个功能已经丢失了,所以我认为我可能遗漏了什么。
心率xml的部分在trkpt中看起来像这样 与他们的测试模式相比
 <trkpt lat="1.6685718186199665069580078125" lon="-101.03414486162364482879638671875">
        <time>2018-02-10T19:24:06.000Z</time>
        <extensions>
          <ns3:TrackPointExtension>
            <ns3:hr>106</ns3:hr>
          </ns3:TrackPointExtension>
        </extensions>
      </trkpt>

在他们的 test.py 中,您可以看到他们在其gpx测试文件中测试其测试扩展功能:

            <trkpt lat="10.1" lon="-20.2">
                <ele>11.1</ele>
                <time>2013-01-01T12:00:04</time>
                <extensions>
                    <last>true</last>
                </extensions>

正在测试标签:

self.assertEquals('true',gpx.tracks[0].segments[0].points[0].extensions['last'])

虽然我不理解它是如何解析的,但这是否意味着要像这样做:

hr=gpx.tracks[0].segments[0].points[0].extensions['hr']

使用Python调试器,我看不到这些数据加载到gpx.tracks数据结构中。那么会返回这些数据吗?
2个回答

3
似乎如果DOM中的扩展扩展任何一个是复杂的,则子节点不会被解析。
这显然是代码中存在已久的问题: https://github.com/tkrajina/gpxpy/issues/73 编辑: 下面是一个实际的例子,但它有点取决于您的结构。
heart_rate = gpx.tracks[0].segments[0].points[0].extensions[0]['hr']

1
表达式.extensions[0]['hr']似乎无法在最新版本的gpxpy中使用最近的Garmin GPX文件:不能使用标签作为键来查询.extensions[0] - 它呈现一个子列表,您可以迭代或使用.find()查询。

例如,hr的标记名称很糟糕:

{http://www.garmin.com/xmlschemas/TrackPointExtension/v1}hr

然而,您可以使用子字符串查询进行迭代,并获取所需的hr元素,无论扩展标记以何种顺序出现,具体为:

In [10]: [el.text for el in gpx.tracks[0].segments[0].points[2].extensions[0] if 'hr' in el.tag][0]
Out[10]: ['122']

如果轨迹点中缺少hr数据,您将得到一个空列表,因此请进行健全性检查并提取数字。另一种方法是使用Element.find()
In [11]: gpx.tracks[0].segments[0].points[2].extensions[0].find('{http://www.garmin.com/xmlschemas/TrackPointExtension/v1}hr')
Out[11]: <Element '{http://www.garmin.com/xmlschemas/TrackPointExtension/v1}hr' at 0x11b0424a0>
In [12]: _11.text
Out[12]: '122'

使用这种技术,健全性检查将在第11行和第12行之间进行,确保_11不为None。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接