I have started working on mapping activities to common routes to track progress over routes, automatically name activities, flag commutes and so on. The first version of this is live for supporters who have enabled beta features (see bottom of /settings page).
New activities and those you re-analyse are matched against existing routes. Activities with a route get a route tab:
I am especially interested in how well the route matching works. Do similar activities get the same route? Are there activities on the route that shouldn’t have matched?
I have done a lot of testing with my data (rides, GPS via cycle computer) and my wife’s data (more runs than rides, GPS via watch) and tweaked things so it works well for us. Activities don’t need to match the route exactly.
It is easy to see how it works for you. Re-analyse a set of activities, sort the table by distance, use the map column to check that activities with the same route did in fact match and those with different routes were distinct.
The orange line on the map shows the route and you can use the “Route” checkbox to toggle it on/off:
Does the whole ride have to be the same to match? Example: I do a ~50k chaingang ride which is embedded in a slightly longer (80k) ride but the ride to and from the starting point can be different.
Hi @david , fantastic feature…
I did a quick test on varies routes with same name , but with small differences:
If the analysis concerns identical route , it seems to work well, route that have the same “track”, but slightly different are seen as different paths as ID
However, matching isn’t working as expected yet it seems. In my screenshot, those Backcountry Skiing Tours should match only 2-3 different routes (with 1-2 small variations each), but it’s returning a few dozen matches. Could you maybe have a look into this?
Thanks David,
Does this mean that you will find a solution USING THE SEGMENTS CREATED IN INTERVALS (NOT STRAVA SEGMENTS) or will there not be an implementation on the segments in intervals?
I analyzed all my runs from May 1 2024 until now, as I have a fairly consistent training route. It’s interesting to see which ones do and which don’t trigger as the same.
The one that didn’t and was most interesting to me was a duathlon race where the two run legs were nearly identical, but the race start was about 30m away from transition. (id 2548 & 2549) Intervals.icu & Intervals.icu
Also interesting is how my id 2501 and 2504 are so close in route, but different length. Intervals.icu and Intervals.icu as examples. Or possibly I ran the turnarounds opposite direction?
Just tested a couple so far and looks good for me, but then my training is extremely boring and similar. It did pick up on a hill rep session that I regularly do although didn’t match one of them where the warm up was a fraction shorter so didn’t meet the overall 2% distance threshold.
Great work. Now can you just add the functionality to export a route as a FIT file like courses in Garmin
I had a look and I think the route matching could be fuzzier. However if I do that some of mine match that shouldn’t have. I have some ideas on how to improve this that I will implement. Unfortunately then I will have to wipe the route data to get rid of the bad routes.
@david When it comes to geospatial programming, I’m unfortunately not an expert… but a few approaches/ideas that come to mind regarding this are:
Data Preprocessing: Simplify routes with downsampling (e.g., Douglas-Peucker algorithm) to remove unnecessary points and smooth them using a moving average to reduce GPS noise.
Tolerance Handling: Define a distance threshold (e.g., 10–20 meters) to ignore small deviations, or use a spatial grid where nearby points are considered equal.
Additional Techniques: Implement geohashing for efficient spatial comparison, clustering algorithms like DBSCAN to group similar routes, or resample routes to standardize point density.
Maybe one of these ideas can help you tackle the problem!
Thanks for your tireless work here,
greetings from snowy Tyrol!
Andy
ps) Here are some potentially useful libraries for identifying similar GPS tracks. While many focus on matching to road networks, they might still be adaptable for comparing recorded tracks:
most likely those problems could also be tacked by AI these days …
pps) It’s definitely better to flush the route database a few times now and focus on building the most robust implementation possible rather than dealing with issues after deployment.
ppps) It would be great to have a “Re-analyze for Routes” option that allows adding new routes to existing tracks without fully reprocessing them. This way, manually adjusted intervals on certain tracks remain untouched, and only new data gets analyzed.
Tx for all this info, quite a few things are new to me and I will investigate. I am also new to all of this and it is trickier than I imagined when I started (as always …)
The route is created using Douglas-Peucker to simplify the GPS track from the activity. I am using Google’s S2 library for tiling points, finding nearest points etc etc… The matching algorithm has a distance threshold and also allows a percentage of missed points.
I will definitely be iterating on this a bit more. I turned it on for everyone with beta enabled instead of creating a separate flag because the db queries need to be fast and I need a decent amount of route data to test that.
I do a lot of my intervals on the Zwift - Ven-Top route, but seldom make it to the very top. I noticed it created a different route ID, which I can assume is due to the distance being different, eg. 11Km, 12Km, 15Km, 17Km and the very top at 22Km.
Likewise, outside, I would ride to a route know my the locals, or to a local race.
How would it handle riding on part of a route, like this where these examples are part of a route?
Very nice feature to experiment with. Here’s my use case, but perhaps there is a simpler way to achieve what I want? I basically want to mark all rides between work and home as commutes, as long as they sort of follow the shortest path. The problem is that the street network allows for > 20 variations which are all within 10% of the distance covered. Can I use Route feature with a very coarse simplification to discover and automatically mark all these commutes as such? Before experimenting with Routes I just created a list view filtering all rides around the commute distance (with some margin) and manually marked them as commutes.
Routes are matched on distance first within 2% or 200m whichever is larger. I haven’t deployed the 200m change yet. Also the start and end points need to be fairly close (within approx 100m). So it is complete routes, not partial matches.
How far is your commute? I have made some changes to make the matching less fussy which should reduce the number of routes you end up with.
If you have analysed or looked at the activity in the last 30 days then finding the routes is quick.
I have made a bunch of improvements to the route matching algorithm and it is working a lot better. It is less fussy now which I think is a more important use-case than exactly matching previous routes.
@Andreas_Schnederle-W Those backcountry skis of yours end up on just a few routes as you suggested.
The new algorithm gives them separate routes.
I am going to wipe the current routes on Thursday AM and deploy the changes. Will post here when that is done.
My commute is between 4.8km and 5.8km depending on the route. Most variants are between 4.8km and 5.2km and then there is a separate route of 5.8km which is longer but takes the same time because it follows a bicycle highway (yes we have those in the Netherlands).
The half way points of the different variations may be more than 1km apart.
If this is extreme, I can live with a couple of routes which I give the same name.
The new routes stuff is live. You should reload the app before re-detecting routes etc to avoid issues with stale data. Oops forgot to deploy the routes only analyse option. Doing that now.