Skip to content

🚴 Refactor App into Route-Based Simulation (GPX First Step) #5

Description

@simonech

🎯 Goal

Change the goal of the app.

Instead of converting power to velocity, the application should evolve into a simulation engine based on real-world routes.

First step: implement GPX parsing and route segmentation.


1️⃣ Remove Legacy Code

  • Remove the old inline TCX parser.
  • Remove any TCX-specific logic.
  • Keep existing physics code unchanged for now.

2️⃣ Implement GPX Parsing

Create a GPX parser that:

  • Accepts a GPX file path.
  • Parses the first <trk> and first <trkseg> only.
  • Extracts all <trkpt> elements.
  • Reads:
    • Latitude
    • Longitude
    • Elevation (<ele>)
    • Timestamp (<time>, optional)

Ignore:

  • Extensions
  • Heart rate
  • Power
  • Cadence
  • Multiple tracks
  • Metadata

Model

public record TrackPoint(
    double Latitude,
    double Longitude,
    double ElevationMeters,
    DateTime? Timestamp
);

Put the model in a model folder

3️⃣ Implement Route Builder

Create a RouteBuilder service that:
• Accepts IEnumerable
• Sorts points by timestamp (if timestamps exist)
• Computes cumulative distance between consecutive points
• Builds fixed-length segments (default: 100 meters)

Distance Calculation

Use the Haversine formula to compute distance between consecutive track points.

Distance is required for:
• Cumulative distance
• Segment length
• Segment aggregation

Segment model

public record RouteSegment(
double StartDistanceMeters,
double LengthMeters,
double StartElevationMeters,
double EndElevationMeters,
double AverageGradient
);

Also in model folder

Segment Construction Rules
• Aggregate distance between track points until segment length ≥ configured segment size (default 100m).
• Interpolate elevation if necessary at the segment boundary.
• Compute:

AverageGradient = (EndElevation - StartElevation) / Length

Store gradient as decimal (e.g. 0.03 for 3%).
• Continue until route ends.
• The final segment may be shorter than configured segment size.

6️⃣ Folder Structure

Organize project into:

Model/
TrackPoint.cs
RouteSegment.cs

Services/
GpxParser.cs
RouteBuilder.cs

7️⃣ Update Command Line Interface

Update CLI so that:

app.exe --gpx route.gpx

Will:
1. Parse GPX
2. Build route
3. Print:
• Total distance
• Total elevation gain
• List of segments (distance start, length, avg gradient)

Example output:

Total Distance: 12430 m
Total Elevation Gain: 180 m

Segments:
0m - 100m | Gradient: 2.3%
100m - 200m | Gradient: 1.8%
...

Replace the sample tcx into a sample gpx

Simple Test Route Test Track
  <trkpt lat="50.8503" lon="4.3517">
    <ele>50.0</ele>
    <time>2026-02-18T10:00:00Z</time>
  </trkpt>

  <trkpt lat="50.8508" lon="4.3522">
    <ele>52.0</ele>
    <time>2026-02-18T10:01:00Z</time>
  </trkpt>

  <trkpt lat="50.8513" lon="4.3527">
    <ele>55.0</ele>
    <time>2026-02-18T10:02:00Z</time>
  </trkpt>

  <trkpt lat="50.8518" lon="4.3532">
    <ele>53.0</ele>
    <time>2026-02-18T10:03:00Z</time>
  </trkpt>

  <trkpt lat="50.8523" lon="4.3537">
    <ele>56.0</ele>
    <time>2026-02-18T10:04:00Z</time>
  </trkpt>

  <trkpt lat="50.8528" lon="4.3542">
    <ele>54.0</ele>
    <time>2026-02-18T10:05:00Z</time>
  </trkpt>

</trkseg>

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions