summaryrefslogtreecommitdiff
path: root/ride
diff options
context:
space:
mode:
Diffstat (limited to 'ride')
-rw-r--r--ride/parser_test.go46
-rw-r--r--ride/ride.go30
2 files changed, 68 insertions, 8 deletions
diff --git a/ride/parser_test.go b/ride/parser_test.go
new file mode 100644
index 0000000..db4907d
--- /dev/null
+++ b/ride/parser_test.go
@@ -0,0 +1,46 @@
+package ride_test
+
+import (
+ "strings"
+ "testing"
+
+ "github.com/martinlehoux/biking_home/ride"
+ "github.com/stretchr/testify/assert"
+ "github.com/stretchr/testify/require"
+)
+
+const parserTestGPXPrefix = `<?xml version="1.0"?><gpx xmlns="http://www.topografix.com/GPX/1/1" version="1.1"><trk><trkseg>`
+const parserTestGPXSuffix = `</trkseg></trk></gpx>`
+
+func TestGPXRideParserSkipsStationaryPoints(t *testing.T) {
+ data := parserTestGPXPrefix +
+ `<trkpt lat="43.0" lon="5.0"><ele>100</ele></trkpt>` +
+ `<trkpt lat="43.0" lon="5.0"><ele>101</ele></trkpt>` +
+ `<trkpt lat="43.0" lon="5.0"><ele>102</ele></trkpt>` +
+ `<trkpt lat="43.001" lon="5.001"><ele>103</ele></trkpt>` +
+ parserTestGPXSuffix
+
+ parsed, err := (ride.GPXRideParser{}).Parse(strings.NewReader(data))
+ require.NoError(t, err)
+ assert.Len(t, parsed.Points(), 2)
+ assert.Greater(t, parsed.Points()[1].DistanceM, 0.0)
+}
+
+func TestGPXRideParserRejectsStationaryRide(t *testing.T) {
+ data := parserTestGPXPrefix +
+ `<trkpt lat="43.0" lon="5.0"><ele>100</ele></trkpt>` +
+ `<trkpt lat="43.0" lon="5.0"><ele>101</ele></trkpt>` +
+ parserTestGPXSuffix
+
+ _, err := (ride.GPXRideParser{}).Parse(strings.NewReader(data))
+ require.Error(t, err)
+ assert.Equal(t, "zero distance", err.Error())
+}
+
+func TestGPXRideParserRejectsEmptyTrack(t *testing.T) {
+ data := parserTestGPXPrefix + parserTestGPXSuffix
+
+ _, err := (ride.GPXRideParser{}).Parse(strings.NewReader(data))
+ require.Error(t, err)
+ assert.Equal(t, "ride has no track points", err.Error())
+}
diff --git a/ride/ride.go b/ride/ride.go
index df5560b..9ba644e 100644
--- a/ride/ride.go
+++ b/ride/ride.go
@@ -55,20 +55,34 @@ func (p GPXRideParser) Parse(reader io.Reader) (Ride, error) {
if err != nil {
return Ride{}, err
}
+ if len(content.Tracks) == 0 || len(content.Tracks[0].Segments) == 0 {
+ return Ride{}, errors.New("ride has no track segment")
+ }
segment := content.Tracks[0].Segments[0]
- points := make([]Point, len(segment.Points))
+ if len(segment.Points) == 0 {
+ return Ride{}, errors.New("ride has no track points")
+ }
+ points := make([]Point, 0, len(segment.Points))
distance := 0.0
- for i, p := range segment.Points {
- if i != 0 {
- distance += p.Distance2D(&segment.Points[i-1])
- }
- if i != 0 && distance == 0 {
- return Ride{}, errors.New("zero distance")
+ previous := segment.Points[0]
+ if previous.Elevation.Null() {
+ return Ride{}, errors.New("points without elevation")
+ }
+ points = append(points, Point{DistanceM: 0, ElevationM: previous.Elevation.Value(), Coord: geodist.Coord{Lat: previous.Latitude, Lon: previous.Longitude}, Timestamp: previous.Timestamp})
+ for i := 1; i < len(segment.Points); i++ {
+ p := segment.Points[i]
+ distance += p.Distance2D(&previous)
+ previous = p
+ if distance == 0 {
+ continue
}
if p.Elevation.Null() {
return Ride{}, errors.New("points without elevation")
}
- points[i] = Point{DistanceM: distance, ElevationM: p.Elevation.Value(), Coord: geodist.Coord{Lat: p.Latitude, Lon: p.Longitude}, Timestamp: p.Timestamp}
+ points = append(points, Point{DistanceM: distance, ElevationM: p.Elevation.Value(), Coord: geodist.Coord{Lat: p.Latitude, Lon: p.Longitude}, Timestamp: p.Timestamp})
+ }
+ if len(points) < 2 {
+ return Ride{}, errors.New("zero distance")
}
ride := Ride{points}
ride.check()