tkrajina / gpxpy

gpx-py is a python GPX parser. GPX (GPS eXchange Format) is an XML based file format for GPS tracks.
Apache License 2.0
987 stars 223 forks source link

Generate a gpx file: How to add extensions ?!? #139

Closed jedie closed 5 years ago

jedie commented 5 years ago

I have made something like this:

def generate_gpx(data):
    gpx_instance = GPX()

    # Create first track in our GPX:
    gpx_track = GPXTrack()
    gpx_instance.tracks.append(gpx_track)

    # Create first segment in our GPX track:
    gpx_segment = GPXTrackSegment()
    gpx_track.segments.append(gpx_segment)

    for dt, data in sorted(data.items()):
        point = gpxpy.gpx.GPXTrackPoint(
            time=dt,
            latitude=data["latitude"],
            longitude=data["longitude"],
            elevation=data["altitude"],
        )
        point.extensions = [
            GPXExtensionsField(name="ns3") # <<-- FIXME
        ]
        gpx_segment.points.append(point)

    return gpx_instance

But adding point.extensions is not the right way...

I would like to add head-rate and cadence data. Maybe as the same extension as garmin, e.g.:

<?xml version="1.0" encoding="UTF-8"?>
<gpx creator="Garmin Connect" version="1.1"
  xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/11.xsd"
  xmlns:ns3="http://www.garmin.com/xmlschemas/TrackPointExtension/v1"
  xmlns="http://www.topografix.com/GPX/1/1"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:ns2="http://www.garmin.com/xmlschemas/GpxExtensions/v3">
  <metadata>
    <link href="connect.garmin.com">
      <text>Garmin Connect</text>
    </link>
    <time>2018-02-21T14:30:50.000Z</time>
  </metadata>
  <trk>
    <name>Foo Bar</name>
    <type>running</type>
    <trkseg>
      <trkpt lat="51.43788929097354412078857421875" lon="6.617012657225131988525390625">
        <ele>23.6000003814697265625</ele>
        <time>2018-02-21T14:30:50.000Z</time>
        <extensions>
          <ns3:TrackPointExtension>
            <ns3:hr>120</ns3:hr>
            <ns3:cad>70</ns3:cad>
          </ns3:TrackPointExtension>
        </extensions>
      </trkpt>
      <trkpt lat="51.43786800093948841094970703125" lon="6.6170061193406581878662109375">
        <ele>23.6000003814697265625</ele>
        <time>2018-02-21T14:30:51.000Z</time>
        <extensions>
          <ns3:TrackPointExtension>
            <ns3:hr>125</ns3:hr>
            <ns3:cad>75</ns3:cad>
          </ns3:TrackPointExtension>
        </extensions>
      </trkpt>
    </trkseg>
  </trk>
</gpx>

Or is there a common format to add head-rate and cadence data?!?

jedie commented 5 years ago

Found a way. Sorry.

ethanzh commented 5 years ago

Jedie, would you mind explaining how you solved this?

askielboe commented 4 years ago

I managed to do it like this:

import gpxpy
from xml.etree import ElementTree

gpx = gpxpy.gpx.GPX()

# Add TrackPointExtension namespace
gpx.nsmap["gpxtpx"] = "http://www.garmin.com/xmlschemas/TrackPointExtension/v1"

# Create track
gpx_track = gpxpy.gpx.GPXTrack()
gpx.tracks.append(gpx_track)

# Create segment
gpx_segment = gpxpy.gpx.GPXTrackSegment()
gpx_track.segments.append(gpx_segment)

# Create point:
gpx_point = gpxpy.gpx.GPXTrackPoint(2.1234, 5.1234, time=time())
gpx_segment.points.append(gpx_point)

# Create extension (hr)
hr = 123
gpx_extension_hr = ElementTree.fromstring(f"""<gpxtpx:TrackPointExtension xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1">
    <gpxtpx:hr>{hr}</gpxtpx:hr>
    </gpxtpx:TrackPointExtension>
""")
gpx_point.extensions.append(gpx_extension_hr)

# Print XML
print(gpx.to_xml())

Result:

<?xml version="1.0" encoding="UTF-8"?>
<gpx xmlns="http://www.topografix.com/GPX/1/1" xmlns:gpxtpx="http://www.garmin.com/xmlschemas/TrackPointExtension/v1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.topografix.com/GPX/1/1 http://www.topografix.com/GPX/1/1/gpx.xsd" version="1.1" creator="gpx.py -- https://github.com/tkrajina/gpxpy">
  <trk>
    <trkseg>
      <trkpt lat="2.1234" lon="5.1234">
        <time>1900-01-01T00:00:00Z</time>
        <extensions>
          <gpxtpx:TrackPointExtension>
            <gpxtpx:hr>123</gpxtpx:hr>
          </gpxtpx:TrackPointExtension>
        </extensions>
      </trkpt>
    </trkseg>
  </trk>
</gpx>