title: gpxpy: How to extract heart rate data from gpx file
body: <p><a href="https://github.com/tkrajina/gpxpy/pull/22/commits/35b1083394f82a366a2640e7de563f8a7642614c" rel="nofollow noreferrer">This commit to gpxpy library</a> includes additional parsing for Garmin 1.1 extensions.  However it appears the code has changed a lot since this commit and it appears that extensions are parsed automatically now.</p>
  
  <p>However I've been unable to figure out how to extract heart rate data or other extension data from a gpx file using <a href="https://github.com/tkrajina/gpxpy" rel="nofollow noreferrer">gpxpy</a>.  Has anyone done this with gpxpy?  How is it done?</p>
  
  <hr>
  
  <p>Edit to avoid closing this question:</p>
  
  <p>If you look at the code additions in the commit I linked above, it modifies the TrackPoint class to add "atemp" and "hr" </p>
  
  <pre><code> 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):
  </code></pre>
  
  <p>Then later in the parser.py you see this routine added</p>
  
  <pre><code>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
  </code></pre>
  
  <p>However in the current code the structure appears very different from when that original commit was made, but it seems to allow for parsing extensions in a more generic way.  But I'm not proficient enough with python to understand how to get it to parse these tags.  My question is an attempt to understand what I'm missing in how the new code works.  My instinct is to just add a line like this into <a href="https://github.com/tkrajina/gpxpy/blob/master/gpxpy/gpx.py" rel="nofollow noreferrer">the gpx.py code</a> around line 74.</p>
  
  <pre><code>mod_gpxfield.GPXField('heart_rate', 'hr', type=mod_gpxfield.FLOAT_TYPE),
  </code></pre>
  
  <p>However I'm hoping someone experienced can look through the code and see if there's something I'm missing like specifying a list extensions=[hr, atemp] and have them parsed generically when reading the data.  It seems odd that this commit was made in the past, but now the feature has been lost, so I assume I'm missing something.</p>
  
  <p>The portion of the heart rate xml look like this inside the trkpt as <a href="https://github.com/tkrajina/gpxpy/blob/master/test_files/gpx1.1_with_all_fields.gpx" rel="nofollow noreferrer">compared to their test schema</a></p>
  
  <pre><code> &lt;trkpt lat="1.6685718186199665069580078125" lon="-101.03414486162364482879638671875"&gt;
          &lt;time&gt;2018-02-10T19:24:06.000Z&lt;/time&gt;
          &lt;extensions&gt;
            &lt;ns3:TrackPointExtension&gt;
              &lt;ns3:hr&gt;106&lt;/ns3:hr&gt;
            &lt;/ns3:TrackPointExtension&gt;
          &lt;/extensions&gt;
        &lt;/trkpt&gt;
  </code></pre>
  
  <p>And in their <a href="https://github.com/tkrajina/gpxpy/blob/master/test.py" rel="nofollow noreferrer">test.py</a> you can see them testing their test extensions in their gpx test file:</p>
  
  <pre><code>            &lt;trkpt lat="10.1" lon="-20.2"&gt;
                  &lt;ele&gt;11.1&lt;/ele&gt;
                  &lt;time&gt;2013-01-01T12:00:04&lt;/time&gt;
                  &lt;extensions&gt;
                      &lt;last&gt;true&lt;/last&gt;
                  &lt;/extensions&gt;
  </code></pre>
  
  <p>Which is testing for the  tag:</p>
  
  <pre><code>self.assertEquals('true',gpx.tracks[0].segments[0].points[0].extensions['last'])
  </code></pre>
  
  <p>And while I don't understand how it was parsed does this mean doing something like this:</p>
  
  <pre><code>hr=gpx.tracks[0].segments[0].points[0].extensions['hr']
  </code></pre>
  
  <p>Would return the data?  Using python debugger, I can't see these loaded into the gpx.tracks data structure.</p>