What CRS does the python sdk decode to (eg, 'position_lat': 485072248, 'position_long': -882385675)?

I am trying to get positional data into epsg:4326. I don't see any indication of what the data decodes to with Python, and I cannot seem to convert it using GeoPandas, nor get it to display inside a Jupyter Notebook. Specifically, I am referring to `position_lat` and `position_long` ( 'position_lat': 485072248, 'position_long': -882385675).

>>> from garmin_fit_sdk import Decoder, Stream
>>> from shapely.geometry import LineString, Point
>>> import geopandas as gpd
>>> stream = Stream.from_file("<my email>_70372402860.fit"
... )
>>> decoder = Decoder(stream)
>>> messages, errors = decoder.read()
>>> record_mesgs = messages["record_mesgs"]
>>> record_mesgs[-1] # First item does not contain Lat,Long data
{'timestamp': datetime.datetime(2020, 10, 16, 11, 17, 33, tzinfo=datetime.timezone.utc), 'position_lat': 485072248, 'position_long': -882385675, 'distance': 693.57, 'altitude': 15.799999999999955, 'speed': 0.0, 88: 300, 'heart_rate': 121, 'temperature': 27, 'enhanced_speed': 0.0, 'enhanced_altitude': 15.799999999999955}

  • In a FIT file latitude and longitude values are stored as semicircles. The formulas to convert between semicircles and degrees are:

    degrees = semicircles * ( 180 / 2^31 )
    semicircles = degrees * ( 2^31 / 180 )

  • Thank you. Could you elaborate on why they are stored as semicircles?

  • Semicircles allows the lat/lon values to be stored as 32 bit integers versus 64 bit doubles and still have ~1cm resolution at the equator. This helps keep file sizes in check.

    An unsigned integer has a range of 0 to 4294967295. aka 2^32, and the circumference of the Earth at the equator is 4007500000 cm.

    4294967295 / 4007500000 = 1.07 semicircles per centimeter at the equator.

    A signed integer has a range of -2,147,483,648 to -2,147,483,647. aka -2^31 to 2^31, which is where the math in the solution above comes from, and the data type used to store semicircles in FIT files.