diff options
| -rw-r--r-- | README.md | 3 | ||||
| -rw-r--r-- | cli/cli.go | 10 | ||||
| -rw-r--r-- | geo/geo.go | 2 | ||||
| -rw-r--r-- | go.mod | 5 | ||||
| -rw-r--r-- | go.sum | 2 | ||||
| -rw-r--r-- | mise.toml | 2 | ||||
| -rw-r--r-- | mountain_pass/extract.go | 2 | ||||
| -rw-r--r-- | strava/sync.go | 6 | ||||
| -rw-r--r-- | web/ride-filters.go | 6 |
9 files changed, 14 insertions, 24 deletions
@@ -60,7 +60,7 @@ Standard apps are rate-limited to 100 calls per 15 minutes and 1,000 per day. ## Architecture -- Go 1.23; SQLite via `mattn/go-sqlite3` +- Go 1.27; SQLite via `mattn/go-sqlite3` - `ride` — GPX parsing, climb detection, difficulty scores (KOM + Cotacol), similarity index - `mountain_pass` — OSM PBF extraction (`mountain_pass=yes` / `natural=mountain_pass` nodes), pass storage and querying, and crossings/climb matching - `strava` — OAuth2 client returning activity metadata and GPX data @@ -108,7 +108,6 @@ TypeScript checks can also be run directly with `npm run check`, covering format ## TODO -- go 1.27 - bug: Ride details > header > 2 lines - Compute estimated power, speed - Plot speed and slope per segment, colored by heart rate @@ -106,10 +106,7 @@ func runBacktest(db *sql.DB) error { }) w := tabwriter.NewWriter(os.Stdout, 0, 0, 2, ' ', 0) fmt.Fprintln(w, "computed\treference\terr %\tride") - limit := 10 - if len(samples) < limit { - limit = len(samples) - } + limit := min(len(samples), 10) for _, s := range samples[:limit] { fmt.Fprintf(w, "%s\t%s\t%+.1f\t%s (%s)\n", s.computed.Round(time.Second), s.reference.Round(time.Second), s.relErrorPct, s.name, s.externalID) } @@ -162,10 +159,7 @@ func errorDistribution(absErrors []float64, percentiles []float64) map[float64]f sort.Float64s(sorted) distribution := map[float64]float64{} for _, p := range percentiles { - index := int(math.Ceil(p/100*float64(len(sorted))) - 1) - if index < 0 { - index = 0 - } + index := max(int(math.Ceil(p/100*float64(len(sorted)))-1), 0) if index >= len(sorted) { index = len(sorted) - 1 } @@ -14,7 +14,7 @@ func DistanceM(a, b geodist.Coord) float64 { func Nearest(coords []geodist.Coord, target geodist.Coord) (int, float64) { bestIndex := 0 bestDistance := math.Inf(1) - for index := 0; index < len(coords); index++ { + for index := range coords { distance := DistanceM(coords[index], target) if distance < bestDistance { bestIndex = index @@ -1,10 +1,9 @@ module github.com/martinlehoux/biking_home -go 1.25.0 +go 1.27 require ( github.com/a-h/templ v0.2.793 - github.com/bradleyjkemp/cupaloy v1.3.0 github.com/jftuga/geodist v1.0.0 github.com/martinlehoux/kagamigo v0.4.1 github.com/mattn/go-sqlite3 v1.14.16 @@ -12,7 +11,6 @@ require ( github.com/schollz/progressbar/v3 v3.18.0 github.com/stretchr/testify v1.10.0 github.com/tkrajina/gpxgo v1.4.0 - golang.org/x/text v0.34.0 gopkg.in/yaml.v3 v3.0.1 ) @@ -64,6 +62,7 @@ require ( golang.org/x/sync v0.19.0 // indirect golang.org/x/sys v0.41.0 // indirect golang.org/x/term v0.40.0 // indirect + golang.org/x/text v0.34.0 // indirect golang.org/x/tools v0.41.0 // indirect google.golang.org/protobuf v1.36.10 // indirect gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect @@ -20,8 +20,6 @@ github.com/andybalholm/cascadia v1.3.1 h1:nhxRkql1kdYCc8Snf7D5/D3spOX+dBgjA6u8x0 github.com/andybalholm/cascadia v1.3.1/go.mod h1:R4bJ1UQfqADjvDa4P6HZHLh/3OxWWEqc0Sk8XGwHqvA= github.com/bkaradzic/go-lz4 v1.0.0 h1:RXc4wYsyz985CkXXeX04y4VnZFGG8Rd43pRaHsOXAKk= github.com/bkaradzic/go-lz4 v1.0.0/go.mod h1:0YdlkowM3VswSROI7qDxhRvJ3sLhlFrRRwjwegp5jy4= -github.com/bradleyjkemp/cupaloy v1.3.0 h1:UJ0YJuhkMXEQcaoQNSCmK8og6GEVW/eDhAZuizvcpOY= -github.com/bradleyjkemp/cupaloy v1.3.0/go.mod h1:Au1Xw1sgaJ5iSFktEhYsS0dbQiS1B0/XMXl+42y9Ilk= github.com/cenkalti/backoff/v4 v4.3.0 h1:MyRJ/UdXutAwSAT+s3wNd7MfTIcy71VQueUuFK343L8= github.com/cenkalti/backoff/v4 v4.3.0/go.mod h1:Y3VNntkOUPxTVeUxJ/G5vcM//AlwfmyYozVcomhLiZE= github.com/chengxilo/virtualterm v1.0.4 h1:Z6IpERbRVlfB8WkOmtbHiDbBANU7cimRIof7mk9/PwM= @@ -1,6 +1,6 @@ [tools] "github:boyter/dcd" = "1.1.0" -go = "1.25.12" +go = "1.27" node = "26.6.0" watchexec = "latest" diff --git a/mountain_pass/extract.go b/mountain_pass/extract.go index 81bed68..705dbd3 100644 --- a/mountain_pass/extract.go +++ b/mountain_pass/extract.go @@ -86,7 +86,7 @@ func parseElevation(ele string) (int, bool) { if ele == "" { return 0, false } - for _, candidate := range strings.Fields(ele) { + for candidate := range strings.FieldsSeq(ele) { if value, err := strconv.Atoi(candidate); err == nil { return value, true } diff --git a/strava/sync.go b/strava/sync.go index 28ba925..a492a47 100644 --- a/strava/sync.go +++ b/strava/sync.go @@ -145,9 +145,9 @@ func activityGPX(activity Activity, streams activityStreams) ([]byte, error) { } points := make([]gpx.GPXPoint, len(streams.LatLng)) for i := range streams.LatLng { - point := gpx.GPXPoint{} - point.Latitude = streams.LatLng[i][0] - point.Longitude = streams.LatLng[i][1] + point := gpx.GPXPoint{ + Latitude: streams.LatLng[i][0], + Longitude: streams.LatLng[i][1]} if i < len(streams.Altitude) { point.Elevation = *gpx.NewNullableFloat64(streams.Altitude[i]) } diff --git a/web/ride-filters.go b/web/ride-filters.go index 3b567f5..888d6bc 100644 --- a/web/ride-filters.go +++ b/web/ride-filters.go @@ -74,9 +74,9 @@ func parseRideFilters(query url.Values) RideFilters { CotacolMinPoints: parseRideFilterInt(query.Get(rideFilterCotacolMinParam), rideFilterCotacolMinPoints, rideFilterCotacolMaxPoints, rideFilterCotacolStepPoints), CotacolMaxPoints: parseRideFilterInt(query.Get(rideFilterCotacolMaxParam), rideFilterCotacolMinPoints, rideFilterCotacolMaxPoints, rideFilterCotacolStepPoints), Route: parseRideRouteFilter(query.Get(rideFilterRouteParam)), - } - filters.DateFrom = parseRideFilterDate(query.Get(rideFilterDateFromParam), false) - filters.DateToExclusive = parseRideFilterDate(query.Get(rideFilterDateToParam), true) + + DateFrom: parseRideFilterDate(query.Get(rideFilterDateFromParam), false), + DateToExclusive: parseRideFilterDate(query.Get(rideFilterDateToParam), true)} filters.DistanceMinKm = clearRideFilterBound(filters.DistanceMinKm, rideFilterDistanceMinKm) filters.DistanceMaxKm = clearRideFilterBound(filters.DistanceMaxKm, rideFilterDistanceMaxKm) filters.DurationMinMinutes = clearRideFilterBound(filters.DurationMinMinutes, rideFilterDurationMinMinutes) |
