aboutsummaryrefslogtreecommitdiff
path: root/ride/fit.go
diff options
context:
space:
mode:
Diffstat (limited to 'ride/fit.go')
-rw-r--r--ride/fit.go32
1 files changed, 27 insertions, 5 deletions
diff --git a/ride/fit.go b/ride/fit.go
index db9c0b6..61d0a7b 100644
--- a/ride/fit.go
+++ b/ride/fit.go
@@ -4,6 +4,7 @@ import (
"bytes"
"encoding/binary"
"errors"
+ "fmt"
"io"
"math"
"time"
@@ -13,8 +14,9 @@ import (
"github.com/tormoder/fit"
)
-// FITRideParser parses FIT files into Ride values. It is the FIT counterpart
-// to GPXRideParser and keeps the same invariants.
+// FITRideParser parses FIT Activity and Course files into Ride values. Both
+// types store their track as Record messages. It is the FIT counterpart to
+// GPXRideParser and keeps the same invariants.
type FITRideParser struct{}
func (p FITRideParser) Parse(reader io.Reader) (Ride, error) {
@@ -26,17 +28,16 @@ func (p FITRideParser) Parse(reader io.Reader) (Ride, error) {
if err != nil {
return Ride{}, err
}
- activity, err := file.Activity()
+ records, err := fitRecords(file)
if err != nil {
return Ride{}, err
}
- if len(activity.Records) == 0 {
+ if len(records) == 0 {
return Ride{}, ErrNoTrackPoints
}
// Collect points discarding invalid positions — FIT encodes missing lat/lon
// as 0x7FFFFFFF (Invalid). We also require altitude.
- records := activity.Records
distances := make([]float64, 0, len(records))
elevations := make([]float64, 0, len(records))
coords := make([]geodist.Coord, 0, len(records))
@@ -123,6 +124,27 @@ func (p FITRideParser) Parse(reader io.Reader) (Ride, error) {
return fromColumns(distances, elevations, coords, timestamps, heartRatesColumn, cadencesColumn, powersColumn), nil
}
+// fitRecords returns the track points of an Activity or Course FIT file; both
+// store them as Record messages.
+func fitRecords(file *fit.File) ([]*fit.RecordMsg, error) {
+ switch file.Type() {
+ case fit.FileTypeActivity:
+ activity, err := file.Activity()
+ if err != nil {
+ return nil, err
+ }
+ return activity.Records, nil
+ case fit.FileTypeCourse:
+ course, err := file.Course()
+ if err != nil {
+ return nil, err
+ }
+ return course.Records, nil
+ default:
+ return nil, fmt.Errorf("fit file type is %v, not Activity or Course", file.Type())
+ }
+}
+
// EncodeFIT writes the ride as a minimal FIT Activity file. It stores only the
// fields consumed by Ride (lat/lon, altitude, time, heart rate, cadence, power)
// as Record messages.