astray.to

the scenery model · 7 min read

What counts as scenic, and who decides.

One driver's favorite road is another driver's nightmare. Switchbacks thrill some people and make others carsick; some want coastline, some want redwoods, some mainly want a road they have never driven. So astray refuses to decide what "scenic" means. It measures ingredients and lets every request mix its own.

in plain words

Ingredients, not verdicts.

Prior work on pleasant routing usually optimizes one quality at a time: beautiful, quiet, or happy1. The tempting shortcut is to compute one final "scenic score" per road and bake it into the data. We did not, because that would freeze one person's taste into the map forever. The driver who hates what the score-author loved has no recourse.

Instead, every road in the graph carries fourteen small, independent measurements, computed at bake time from OpenStreetMap and elevation data, each stored in a single byte. None of them is a verdict; each is a fact about the road or its surroundings. Opinions arrive later, at request time, as weights. The interesting design work was choosing which fourteen facts, and above all which distinctions were worth keeping apart.

the road itself

Six measurements of the pavement.

signalwhat it measureswhy it is its own number
bend_frequencyDistinct bends per kilometer.A river road with many gentle curves and a mountain grade with three brutal switchbacks are different drives. Frequency captures "winding" without judging severity.
bend_sharpnessHow hard the average bend turns.The severity half of the split. Kept separate so a motion-sensitive driver can punish sharpness alone and still enjoy a gently winding road.
signal_densityTraffic lights, stop signs, and yields per kilometer.The texture of stop-and-go. This is the number that separates a flowing back road from an arterial with a light every block.
junction_densityAll intersections per kilometer, controlled or not.Almost the opposite meaning: lots of junctions means lots of choices. The "Back roads" mood weights this up because it is the texture of an interesting street grid.
road_classThe road's place in the hierarchy, small track high, motorway low.An intrinsic quiet-road preference that works even where the map has little else to say about a road.
gradientAverage steepness, from the elevation model.Climbs and descents are part of a drive's character. Grades under two percent are treated as flat, because at that scale the elevation data is more noise than terrain.
the landscape around it

Eight measurements of everything else.

signalwhat it measureswhy it is its own number
water_coastCloseness to ocean, bay, and other salt water.Coastal driving is its own mood. Kept apart from fresh water so "take me along the ocean" does not get satisfied by a drainage canal.
water_freshCloseness to lakes and rivers.Lake loops and river roads, weightable independently of the coast.
forestHow much of the road runs through woodland.Measured as actual overlap with forest polygons, not distance to the nearest tree.
pastoralFarmland, meadows, orchards, vineyards.Deliberately excludes city parks. You drive to a park; you drive through countryside. Counting parks made suburban arterials score like wine country.
elevation_prominenceHow far the road stands above its surroundings.The feeling of being up high with a view. Computed against the average terrain in a ring around the road rather than sea level, so a valley floor in the mountains does not score as a summit.
peak_proximityCloseness to named mountain peaks.Different from prominence: the road that winds beneath dramatic summits may itself sit low. Both feelings are real; they get separate numbers.
industrial_proximityCloseness to industrial land, quarries, military sites.A disamenity kept independent instead of subtracted at bake time. A bayside road next to a refinery genuinely is both "coastal" and "industrial," and only your weights should decide which wins.
remotenessDistance from built-up areas, capped at 20 km.The empty-road feeling. Motorways are forced to zero: a freeway through nowhere moves you fast but never feels remote.

The pattern across both tables is the same: wherever two feelings could be confused, they got separate numbers. Merging any of those pairs would have made some real preference inexpressible.

how they combine

Opinions are arithmetic at request time.

When a route is requested, the engine multiplies each measurement by the selected preference weight and adds the results. Linear algebra calls this a dot product; operationally it is a small fixed amount of arithmetic per road. Named moods such as "Back roads," "Cruise," and "Gentle" are versioned JSON weight sets, so we can tune a mood without rebuilding the graph or recompiling the engine.

The SF Peninsula to Santa Cruz validation trip makes the effect concrete. With scenery disabled, the engine takes the Highway 17 corridor like everyone else. Give forest real weight and it abandons that slog for Highway 9, climbing over Saratoga Gap and dropping through the San Lorenzo Valley redwoods, trading exactly the budgeted minutes for it. The graph never changes; only the arithmetic on top of it does.

Negative weights need no extra machinery. "Avoid industry" is just a minus sign. The available combination rules are deliberately few and have outputs whose ranges can be proven: weighted sums, thresholds, products, and minimums. That restriction is what lets the routing engine clamp the combined score into a reliable range before any search runs.

How weights are set in practice: the factory moods, the fifteen-band equalizer, and the one mood that uses a hard veto instead of a weight. Moods and the equalizer
the fifteenth

One measurement never leaves your phone.

One signal is personal and never enters the shared graph. familiarity is calculated on your device from trips you explicitly saved or handed off to navigation. There are no GPS traces and no background tracking. Recent trips count more than old ones, with a 90-day half-life, and repeated travel eventually stops increasing the score. The "Avoid roads I've driven" switch gives familiar roads strong negative weight, so the router starts steering you down roads you have not driven yet.

The server rejects any request carrying this overlay, in code, so no policy document has to be trusted for that boundary to hold. Familiarity-weighted routing only works where the data lives: on your device.

prior work

References.

  1. D. Quercia, R. Schifanella, L. M. Aiello. "The Shortest Path to Happiness: Recommending Beautiful, Quiet, and Happy Routes in the City." ACM Hypertext 2014. The closest published relative on the scoring side: crowdsourced beauty, quiet, and happiness scores over urban walks, one objective at a time.

The best way to evaluate a router is to drive it.

There is no account and no tracking. Open it, pick somewhere you've been meaning to go, and give it twenty spare minutes.