-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathgpx.go
96 lines (75 loc) · 2.26 KB
/
gpx.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
// gpx functions
//
package main
import (
"errors"
"os"
"time"
"github.com/tkrajina/gpxgo/gpx"
)
func getMetadataFromGPX(timestamp time.Time, gpxFilename string) (float64, float64, float64, error) {
// get lat, long, altitude from gpx
//
gpxBytes, err := os.ReadFile(gpxFilename)
if err != nil {
return 0.0, 0.0, 0.0, err
}
gpxFile, err := gpx.ParseBytes(gpxBytes)
if err != nil {
return 0.0, 0.0, 0.0, err
}
var lastPoint gpx.GPXPoint
for _, track := range gpxFile.Tracks {
for _, segment := range track.Segments {
for _, point := range segment.Points {
if (timestamp.Equal(lastPoint.Timestamp) || timestamp.After(lastPoint.Timestamp)) &&
(timestamp.Equal(point.Timestamp) || timestamp.Before(point.Timestamp)) {
// two points in the same place could result in / 0 , but can't happen
//
// get distance between the points
//
x, y := getDisplament(lastPoint.Latitude, lastPoint.Longitude, point.Latitude, point.Longitude)
// proportion distance base on time difference
//
diff := float64(timestamp.Unix()-lastPoint.Timestamp.Unix()) / float64(point.Timestamp.Unix()-lastPoint.Timestamp.Unix())
lat, lon := getLocation(lastPoint.Latitude, lastPoint.Longitude, x*diff, y*diff)
alt := 0.0
if lastPoint.Elevation.NotNull() && point.Elevation.NotNull() {
alt = lastPoint.Elevation.Value() + (point.Elevation.Value()-lastPoint.Elevation.Value())*diff
}
return lat, lon, alt, nil
}
lastPoint = point
}
}
}
// not found
//
return 0.0, 0.0, 0.0, errors.New("Timestamp " + timestamp.String() + " not found in GPX")
}
func mergeGPX(gpxFilenames []string, gpxOutputFilename string) error {
outputGpxFile := new(gpx.GPX)
for _, gpxFilename := range gpxFilenames {
gpxBytes, err := os.ReadFile(gpxFilename)
if err != nil {
return err
}
gpxFile, err := gpx.ParseBytes(gpxBytes)
if err != nil {
return err
}
outputGpxFile.Tracks = append(outputGpxFile.Tracks, gpxFile.Tracks...)
}
output, err := os.Create(gpxOutputFilename)
if err != nil {
return err
}
defer output.Close()
xmlBytes, err := outputGpxFile.ToXml(gpx.ToXmlParams{Version: "1.1", Indent: true})
if err != nil {
// not sure how this can fail
return err
}
output.Write(xmlBytes)
return nil
}