feat(roadtrip): draw the last bit to a place the road does not reach

A router snaps every waypoint to the nearest road before it starts, and OSRM
does it with no distance limit at all. A viewpoint above a valley, a farmhouse
down a track, a marina at the end of a pier: the drive to it really begins
somewhere else, and the line said nothing about that. It either stopped short
for no visible reason or appeared to cut across open ground.

OSRM reports the snap position and its distance in every single answer, and
this client has thrown both away since the first route was drawn. Reading them
costs no request and no key.

The gap is drawn as a dashed spur in the route's own blue, over the route
rather than under it, because it is the one piece of the line that is not
driving. Thirty metres is the floor, which is about a dual carriageway and its
verge, so a place pinned off an aerial photo does not earn a dash. From a
quarter of a kilometre the rail prints the distance too, because that is where
"the car park is over there" turns into luggage, a gate, or a track a hire car
should not be on.

Vias are deliberately left out: a via is a shape handle, not a destination, and
a dash hanging off one reads as a fault.
This commit is contained in:
Maurice
2026-09-04 21:35:37 +02:00
committed by Maurice
parent d6eac772aa
commit 11f4c740e1
33 changed files with 342 additions and 8 deletions
+19
View File
@@ -188,6 +188,23 @@ export interface RouteVia {
dwellSeconds?: number
}
/**
* Where the router put a waypoint we asked about, and how far that is from where we asked.
*
* Every routing engine snaps a coordinate to the nearest road before it starts, and OSRM
* does it with no distance limit at all. A place set back from the road — a viewpoint, a
* farmhouse, a marina — is therefore driven to from somewhere else entirely, and the drawn
* line starts at that somewhere else without saying so.
*/
export interface SnappedWaypoint {
/** The coordinate that was asked for, unchanged. */
asked: [number, number]
/** The point on the road network the router actually used. */
at: [number, number]
/** Straight-line metres between the two. */
meters: number
}
export interface RouteWithLegs {
coordinates: [number, number][]
distance: number
@@ -195,6 +212,8 @@ export interface RouteWithLegs {
legs: RouteSegment[]
/** Present on plugin-provided routes only. */
vias?: RouteVia[]
/** One entry per REQUESTED waypoint, in request order. Absent on plugin routes. */
snapped?: SnappedWaypoint[]
}
export interface RouteResult {