Skip to main content

1,266,642 trails

· 4 min read
Massimo Di Stefano
FastGIS author

That is not a rounded number. That is how many mountain-bike trails, routes and trail POIs across Europe are now in the catalogue, extracted from OpenStreetMap, scored, tiled and searchable from the map.

MTB, the full arc in one week

It went from pipeline to product in six phases: the EU extraction, the /mtb API, access-by-car and lift scoring with faceted search, a mobile trail overlay and browse screen, offline trail tiles, and an on-map search library that behaves exactly like the curvy-roads search — same gestures, same filters, same scroll-to-card on a map tap. A rider who has learned one search should not have to learn another.

The access scoring is the part we would defend hardest. A trail you cannot reach is not a trail you can ride, so the catalogue knows whether you can get there by car and whether there is a lift, and lets you filter on it.

Then performances: segment timing that records as you ride, with GPS auto-start and auto-stop so there is no button to remember at the top of a descent. Afterwards you get a detail screen, a chart, and an elevation-and-surface bar — how much of that climb was gravel is a more interesting question than how fast you did it.

Friluftsliv, with its licences attached

43,048 Norwegian outdoor-recreation points from four sources — and, unusually, the API tells you the licence of every single one. Two sources are NLOD 2.0, one is share-alike ODbL, and one is open with no named licence at all, which is not the same thing as public domain however much you would like it to be.

GET /friluft/sources returns that per source, with the attribution string you owe and whether share-alike propagates to whatever you build. Most APIs put this in a footer nobody reads. We put it in the response.

Loops that weave

The loop generator can now weave curvy roads and beaches into the loop it generates. Ask for 200 km and it threads the good roads through the middle, rather than handing you a circle that happens to have nice bits somewhere near it.

We also taught it to detect and repair geometry-level dangles. Norway is full of roads that run out to the end of a fjord and stop; a loop generator that does not know this will cheerfully route you out and back down the same 40 km and call it a circuit. It now spots that shape in the geometry and repairs it.

The travelling motorcyclist

Optimised routing shipped — the travelling-salesman problem, on a motorcycle. Give it a set of stops and it orders them properly, both on the server and on the device, so re-optimising after you add a stop works with no signal.

Multi-day trip planning stopped being an exercise in dragging list items around and squinting at the total. It needed Valhalla's matrix distance ceiling raised to cope, which is the sort of limit you only discover by hitting it.

Smarter search, three rungs deeper

Category and spatial context in Phase 1, a deterministic CPU spell corrector in Phase 2, and a warmed local LLM in Phase 3 so the rare hard query does not pay an eight-second cold start.

Also: profiles, and locking the doors

User profiles with avatars, a garage and riding styles. And two security passes — eleven launch-blocker findings in one, a fourteen-point desktop audit in the other — plus per-tenant Postgres isolation, off by default until it has earned its confidence.

Ten languages

Three became ten, with a first-run safety acknowledgment. Europe is not an English-speaking continent and we would rather not pretend otherwise.


Dig deeper: data products covers MTB, friluftsliv, beaches and curvy roads, licences included.