Skip to content

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

@simonech

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>

Metadata

Metadata

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions