@@ 67,19 67,29 @@ def from_gpx_bytes(content: BinaryIO):
return Track(positions=np.array(positions), hr=np.array(hr_vals))
-def from_fit_bytes(content: BinaryIO):
+def from_fit_bytes(content: BinaryIO) -> Track:
fit = FitFile(content)
positions = []
hr_vals = []
for record in fit.get_messages('record'):
-
timestamp = record.get('timestamp')
- if timestamp is not None:
- record_time = np.datetime64(timestamp.value, 'ms')
+ if timestamp is None:
+ continue
+
+ record_time = np.datetime64(timestamp.value, 'ms')
+
+ # special agreement with "GpsLogger II" to be able to get sub-second
+ # timestamp information:
+ # the fractional part of the timestamp is stored in FIT "field number
+ # 252" in milliseconds
+ timestamp_ms = record.get_value(252)
+ if isinstance(timestamp_ms, int) and (0 <= timestamp_ms < 1000):
+ record_time += np.timedelta64(timestamp_ms, 'ms')
+
lat = record.get('position_lat')
lng = record.get('position_long')
- if timestamp and lat and lng is not None:
+ if (lat is not None) and (lng is not None):
lat_deg = field_to_deg(lat)
lng_deg = field_to_deg(lng)
value_tuple = (record_time,
@@ 89,7 99,7 @@ def from_fit_bytes(content: BinaryIO):
positions.append(value_tuple)
hr = record.get('heart_rate')
- if timestamp and hr is not None:
+ if hr is not None:
hr_vals.append((record_time,
field_to_bpm(hr)))