diff options
| author | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-08-01 23:35:55 +0200 |
|---|---|---|
| committer | Martin Kagamino Lehoux <martin@lehoux.net> | 2026-08-01 23:35:55 +0200 |
| commit | f06a10982ab9d5aaa7d31cea31964431fa75f253 (patch) | |
| tree | 806b18928748987ab4d371dab80b814ece28e252 /README.md | |
| parent | ab0b68a2b6bebfccd8ab5c3c7d0420f4ae0cb885 (diff) | |
docs: Reformat README to project conventions
Diffstat (limited to 'README.md')
| -rw-r--r-- | README.md | 114 |
1 files changed, 68 insertions, 46 deletions
@@ -1,54 +1,76 @@ -# Bike software +# biking_home — cycling ride analysis + +A Go toolkit for analyzing cycling rides from GPX exports: parse rides, detect climbs, score their difficulty, match the same climb across rides, and download French mountain passes into SQLite. ## Features -- [ ] Detect similar climbs + PRs -- Compute a ride difficulty score (Cotacol method): split into 100m segments, each scores 0.1km × slope² -- On this climb (examples/activity_18679866717.gpx), the climb algo should detect several possible climbs and let you choose -- Once you have chosen, new activities should have remembered the choice (looking into the index should be enough) -- Handling my historical data -- Blog with pictures and markdown -- Storing GPX -- Export mountain pass from OSM and auto detect when pass is crossed - - https://www.jmspae.se/write-ups/kebabs-train-stations/ -- Download French mountain passes from centcols.org into a SQLite database (`go run . -download`, resume with `-resume`) -- Auto detect climbs from GPX -- Compute estimated power -- Export data from Strava, Garmin - - Garmin GPX exports has elevation, time, temp, heart rate, cadence - - Garmin TCX export has stats (cal, heart rate, time, cadence), time, pos, alt, distance, hr, cadence, speed - - Garmin Fit export has (time, sport, lap/split, gps, sensor, events)? - - KML ? -- Strava seems the simpler to use -- in a single chart, plot (speed, slope) for all segments. color with heartbeat - -## Implementation - -- Golang for showcase -- Keep improving personal lib (+ documentation) -- Get back what is interesting in previous projects - - Go bike: - - Only tooling for golang, project is different - - Django bike -- https://github.com/paulmach/osm -- https://github.com/tkrajina/gpxgo -- https://github.com/tormoder/fit -- https://github.com/brendangregg/FlameGraph -- `go tool pprof -http=":8081"` -- https://developer.garmin.com/gc-developer-program/activity-api/ -- https://github.com/matin/garth -- https://developers.strava.com/docs/webhooks/ -- https://developers.strava.com/docs/getting-started/ -- https://connect.garmin.com/modern/activities to CSV -- https://github.com/SamR1/FitTrackee -- https://github.com/jovandeginste/workout-tracker +- **GPX parsing** — reads elevation-tracked rides from Garmin/Strava GPX exports into a `Ride` model +- **Climb detection** — automatically finds climbs within a ride, each scored and categorized (Cat 4 … HC) +- **Difficulty score (Cotacol)** — scores any ride or climb by splitting it into 100 m segments and summing `0.1 km × slope²` per segment +- **Similar-climb matching** — finds the same climb across rides by matching start/end coordinates, so times can be compared +- **Mountain pass download** — imports French mountain passes from centcols.org into a SQLite database +- **Plots** — renders elevation and score-profile charts as PNG + +## Getting started + +```bash +go build -o biking_home . +``` + +## Usage + +```bash +# Download French mountain passes into biking_home.db (SQLite) +./biking_home -download + +# Resume an interrupted download, reusing departments already cached on disk +./biking_home -download -resume + +# Run the climb-similarity and difficulty-score demo on the example rides +./biking_home -demo + +# Profile the demo with Go's CPU profiler +./biking_home -demo -cpuprofile /tmp/cpu.prof +``` + +## Options / Configuration + +| Flag | Description | Default | +| --- | --- | --- | +| `-download` | Download mountain passes into the database | `false` | +| `-resume` | Skip departments already cached on disk | `false` | +| `-demo` | Run the climb-similarity demo | `false` | +| `-cpuprofile` | Write a CPU profile to file | `""` | + +## Architecture + +- Go 1.23; SQLite via `mattn/go-sqlite3`; charts via `gonum.org/v1/plot` +- `ride` — GPX parsing, climb detection, difficulty scores (KOM + Cotacol), similarity index +- `mountain_pass` — centcols.org department CSV download into SQLite, with disk caching and retries +- **Notable choices** — the difficulty score follows the Cotacol method: the ride is split into fixed 100 m segments and each scores `distance_km × slope²`, so steep sections weigh exponentially more than long flat ones + +## Development + +```bash +go vet ./... +go test ./... +``` ## TODO -- CI / Tooling -- Tests -- linter for calls to `make([]..., n)` that then use append +- Compute estimated power +- Export data from Strava / Garmin (GPX, TCX, FIT) +- Auto-detect when a mountain pass is crossed +- Plot speed and slope per segment, colored by heart rate +- Persist the chosen climb variant across activities +- Handle historical data +- Blog with pictures and markdown +- Store GPX files -## Examples +## Resources -**[Pogacar 21 july 2022](https://www.strava.com/activities/7505784085)** +- [Climbfinder: difficulty points](https://climbfinder.com/en/difficulty-points) — the Cotacol formula behind the difficulty score +- [centcols.org](https://www.centcols.org) — French mountain pass reference used for the SQLite data +- [Pogacar 21 July 2022](https://www.strava.com/activities/7505784085) — example ride used for climb detection +- [gpxgo](https://github.com/tkrajina/gpxgo) — GPX parsing library +- [geodist](https://github.com/jftuga/geodist) — haversine distance used for climb matching |