Skip to content

Instantly share code, notes, and snippets.

@grimpy
Last active July 23, 2021 21:13
Show Gist options
  • Save grimpy/eca2240b77a2a4eb9c3b34a79dccc747 to your computer and use it in GitHub Desktop.
Save grimpy/eca2240b77a2a4eb9c3b34a79dccc747 to your computer and use it in GitHub Desktop.
package main
import (
"encoding/xml"
"flag"
"fmt"
"os"
"strings"
"time"
)
type GPXRoot struct {
XMLName xml.Name `xml:"gpx"`
Metadate string `xml:"metadate"`
Track GPXTrack `xml:"trk"`
Version string `xml:"version,attr"`
}
type GPXTrack struct {
XMLName xml.Name `xml:"trk"`
Name string `xml:"name"`
Sequence []GPXTrackSequence `xml:"trkseg"`
}
type GPXTrackSequence struct {
XMLName xml.Name `xml:"trkseg"`
Points []GPXTrackPoint `xml:"trkpt"`
}
type GPXTrackPoint struct {
XMLName xml.Name `xml:"trkpt"`
Altitude string `xml:"ele"`
Time string `xml:"time"`
Latitude string `xml:"lat,attr"`
Longitude string `xml:"lon,attr"`
}
type WatchRoot struct {
XMLName xml.Name `xml:"GH-625_Dataform"`
TrackLapPoints []TrackLapPoint `xml:"trackLapPoints"`
TrackHeader TrackHeader `xml:"trackHeader"`
}
type TrackHeader struct {
XMLName xml.Name `xml:"trackHeader"`
Date string `xml:"TrackName"`
Time string `xml:"StartTime"`
}
type TrackLapPoint struct {
XMLName xml.Name `xml:"trackLapPoints"`
Latitude string `xml:"Latitude"`
Longitude string `xml:"Longitude"`
Altitude string `xml:"Altitude"`
TimeOffset string `xml:"Interval_x0020_Time"`
}
func convert(filename string) {
// Open our xmlFile
destfile := strings.Replace(filename, ".xml", ".gpx", 1)
xmlFile, err := os.Open(filename)
if err != nil {
fmt.Println(err)
return
}
defer xmlFile.Close()
decoder := xml.NewDecoder(xmlFile)
var watchData WatchRoot
err = decoder.Decode(&watchData)
if err != nil {
fmt.Println(err)
return
}
var gpxRoot = GPXRoot{}
var gpxSeq = GPXTrackSequence{}
gpxRoot.Metadate = fmt.Sprintf("%s %s", watchData.TrackHeader.Date, watchData.TrackHeader.Time)
currenttime, err := time.Parse("2006-1-2 15:04:5", gpxRoot.Metadate)
if err != nil {
fmt.Println(err)
currenttime = time.Now()
}
gpxRoot.Track.Name = "track name"
gpxRoot.Version = "1.1"
for _, point := range watchData.TrackLapPoints {
gpxPoint := GPXTrackPoint{}
gpxPoint.Latitude = point.Latitude
gpxPoint.Longitude = point.Longitude
gpxPoint.Altitude = point.Altitude
timeoffset := strings.Replace(point.TimeOffset, ",", ".", 1)
offset, err := time.ParseDuration(fmt.Sprintf("%ss", timeoffset))
if err != nil {
fmt.Println(err)
}
currenttime := currenttime.Add(offset)
gpxPoint.Time = currenttime.Format(time.RFC3339)
gpxSeq.Points = append(gpxSeq.Points, gpxPoint)
}
gpxRoot.Track.Sequence = append(gpxRoot.Track.Sequence, gpxSeq)
outfile, err := os.Create(destfile)
if err != nil {
fmt.Println(err)
return
}
defer outfile.Close()
encoder := xml.NewEncoder(outfile)
err = encoder.Encode(gpxRoot)
if err != nil {
fmt.Println(err)
return
}
}
func main() {
var filename string
flag.StringVar(&filename, "file", "", "Filename to convert")
flag.Parse()
if filename == "" {
fmt.Println("Filename is required pass -file")
} else {
convert(filename)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment