blob: bf0664af191fd58d1be1d42c77aaa31f3d9991fa (
plain)
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
|
"""Conversion functions to convert between various recording formats."""
import fitparse
from gpxpy.gpx import GPX, GPXTrack, GPXTrackPoint, GPXTrackSegment
FIT_RECORD_FIELDS = ["position_lat", "position_long", "altitude", "timestamp"]
def semicircles_to_deg(circles: int) -> float:
"""Convert semicircles coordinate to degree coordinate.
:param circles: The coordinate value in semicircles.
:return: The coordinate in degrees.
"""
return circles * (180 / 2**31)
def from_fit(data: bytes) -> GPX:
"""Reads a .fit as GPX data.
This uses the fitparse_ library under the hood.
.. _fitparse: https://pypi.org/project/fitparse/
:param data: The input bytes.
:return: The converted structure.
"""
fitfile = fitparse.FitFile(data)
points = []
for record in fitfile.get_messages("record"):
values = record.get_values()
try:
if any(values[field] is None for field in FIT_RECORD_FIELDS):
continue
point = GPXTrackPoint(
latitude=semicircles_to_deg(values["position_lat"]),
longitude=semicircles_to_deg(values["position_long"]),
elevation=values["altitude"],
time=values["timestamp"],
)
except KeyError:
pass
else:
points.append(point)
track = GPXTrack()
track.segments = [GPXTrackSegment(points)]
gpx = GPX()
gpx.tracks = [track]
return gpx
__all__ = ["from_fit"]
|