diff options
| author | Daniel Schadt <kingdread@gmx.de> | 2023-05-31 21:17:03 +0200 | 
|---|---|---|
| committer | Daniel Schadt <kingdread@gmx.de> | 2023-05-31 21:17:03 +0200 | 
| commit | b1e9c0556eab7faf03ea9d398c2df58f66193220 (patch) | |
| tree | e59796dc02c04a9feaf276d33a42903aebaac5bf /fietsboek/convert.py | |
| parent | 45f2f09be40aa9f8baa822a6c2502354d27b15d7 (diff) | |
| parent | 5db0d6b2f09beed78035cbcc87a6a537f6735673 (diff) | |
| download | fietsboek-b1e9c0556eab7faf03ea9d398c2df58f66193220.tar.gz fietsboek-b1e9c0556eab7faf03ea9d398c2df58f66193220.tar.bz2 fietsboek-b1e9c0556eab7faf03ea9d398c2df58f66193220.zip | |
Merge branch 'fit-import'
Diffstat (limited to 'fietsboek/convert.py')
| -rw-r--r-- | fietsboek/convert.py | 51 | 
1 files changed, 51 insertions, 0 deletions
| diff --git a/fietsboek/convert.py b/fietsboek/convert.py new file mode 100644 index 0000000..bf0664a --- /dev/null +++ b/fietsboek/convert.py @@ -0,0 +1,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"] | 
