Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FIT waypoints with no elevation data converted to NaN but should be 0 #15

Open
mbacchi opened this issue Aug 6, 2024 · 3 comments · May be fixed by #16
Open

FIT waypoints with no elevation data converted to NaN but should be 0 #15

mbacchi opened this issue Aug 6, 2024 · 3 comments · May be fixed by #16

Comments

@mbacchi
Copy link

mbacchi commented Aug 6, 2024

My Wahoo Elemnt Roam frequently takes a long time to calculate elevation. This is probably because they indicate that using barometric pressure to calculate elevation is impacted by riding near large bodies of water [0]. I live on an isthmus surrounded by water and it can sometimes take up to 15 minutes to calculate my elevation. Thus the elevation data on my rides may contain waypoints with no elevation data when I start riding.

In these situations, the empty waypoint elevation data in the FIT file unfortunately becomes nan when fit2gpx converts it to GPX. This is not supported in the schema, which says <ele></ele> should be a decimal [1]. An example of a waypoint elevation showing nan:

        <ele>nan</ele>
        <time>2024-07-30T22:34:24Z</time>

I think fit2gpx should instead represent these unknown elevation points with 0 rather than nan.

I'll open a PR to resolve.

@dodo-saba
Copy link
Owner

Hi Matt - thanks for raising this!

I was not aware the schema did not support nan, although this makes sense.

Aware that the way you've solved the issue may be appropriate for your needs and when riding at sea level, however I fear hard coding NaN elevations to zero could really screw up some ride data (e.g. elevation totals calculated on Strava, Garmin Connect, and other platforms) if this issue were to occur at altitude.

For example, if a device mistakenly records NaN elevation for a point at altitude (e.g. 2000m), but the points around it capture the altitude, then hardcoding the NaN to zero could artificially create 2000m elevation gain from one point to another.

Do you think there are other ways to solve this? For example, not coding an elevation field to the specific track point (rather than coding a NaN value).

@dodo-saba dodo-saba reopened this Aug 26, 2024
@mbacchi
Copy link
Author

mbacchi commented Aug 27, 2024

Hi, thanks for responding.

Do you think there are other ways to solve this? For example, not coding an elevation field to the specific track point (rather than coding a NaN value).

I think you make a valid point. I didn't realize the elevation parameter was optional. But looking now I see in your function docstring that the df_points at minimum must have lat and long info points. So it sounds to me that the elevation param is indeed optional.

What do you think about this patch to my PR. I interpret what you're suggesting to be something like this. Basically I only provide the elevation param if it's a valid number and not nan.

diff --git a/src/fit2gpx.py b/src/fit2gpx.py
index 2b46d6a..47ee54e 100644
--- a/src/fit2gpx.py
+++ b/src/fit2gpx.py
@@ -176,15 +176,20 @@ class Converter:
 
         # Step 3: Add points from dataframe to GPX track:
         for idx in df_points.index:
-            if isnan(df_points.loc[idx, col_alt]):
-                df_points.loc[idx, col_alt] = 0
             # Create trackpoint:
-            track_point = gpxpy.gpx.GPXTrackPoint(
-                latitude=df_points.loc[idx, col_lat],
-                longitude=df_points.loc[idx, col_long],
-                time=pd.Timestamp(df_points.loc[idx, col_time]) if col_time else None,
-                elevation=df_points.loc[idx, col_alt] if col_alt else None
-            )
+            if isnan(df_points.loc[idx, col_alt]):
+                track_point = gpxpy.gpx.GPXTrackPoint(
+                    latitude=df_points.loc[idx, col_lat],
+                    longitude=df_points.loc[idx, col_long],
+                    time=pd.Timestamp(df_points.loc[idx, col_time]) if col_time else None,
+                    # Do not include elevation if nan
+                )
+            else:
+                track_point = gpxpy.gpx.GPXTrackPoint(
+                    latitude=df_points.loc[idx, col_lat],
+                    longitude=df_points.loc[idx, col_long],
+                    time=pd.Timestamp(df_points.loc[idx, col_time]) if col_time else None,
+                    elevation=df_points.loc[idx, col_alt] if col_alt else None,
+                )
 

Thanks.

@mbacchi
Copy link
Author

mbacchi commented Sep 5, 2024

I've verified this works @dodo-saba. It doesn't add <ele></ele> params to the waypoint unless it is not nan. Example here shows many waypoints with no <ele></ele> params until the last waypoint here does have one. I'll update my PR.

      <trkpt lat="LAT" lon="LON">
        <time>2024-09-04T21:04:58Z</time>
      </trkpt>
      <trkpt lat="LAT" lon="LON">
        <time>2024-09-04T21:04:59Z</time>
      </trkpt>
      <trkpt lat="LAT" lon="LON">
        <time>2024-09-04T21:05:00Z</time>
      </trkpt>
      <trkpt lat="LAT" lon="LON">
        <ele>8.399999999999977</ele>
        <time>2024-09-04T21:05:01Z</time>
     </trkpt>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants