Skip to content

Trips, legs & maps

PlanResult.trips[] contains TripPattern objects. Each trip has legs[]; each leg contains one of four detail objects.

LegStart / end labelsUseful details
transitLegfromEstimatedCall.quay / toEstimatedCall.quayLine, destination, platforms, intermediate stops, realtime, alerts
nonTransitLegfromPlace / toPlaceWALK, BICYCLE, CAR or rental mode; rental station/vehicle data
waitingLegSurrounding travel legsWaiting start and end time
flexibleLegfromPlace / toPlaceBooking arrangement, uncertain times, line, operator

Use leg.duration in minutes and leg.distance in metres. Trip-level duration, walking time and waiting time are minutes too.

Leg summary — enums normalized to strings
function describeLeg(leg) {
if (leg.transitLeg) {
const t = leg.transitLeg;
const label = t.line?.publicCode || t.line?.name || t.mode;
const from = t.fromEstimatedCall?.quay?.name || 'Board';
const to = t.toEstimatedCall?.quay?.name || 'Alight';
return `${label}: ${from} → ${to}`;
}
if (leg.flexibleLeg) {
const f = leg.flexibleLeg;
return `Flexible: ${f.fromPlace?.name ?? ''} → ${f.toPlace?.name ?? ''}`;
}
if (leg.nonTransitLeg) {
return `${leg.nonTransitLeg.mode}: ${(leg.distance / 1000).toFixed(1)} km`;
}
if (leg.waitingLeg) return `Wait ${leg.duration} min`;
return 'Journey segment';
}

Use line.publicCode for the line badge, destinationDisplay.frontText for its destination and line.branding for a passenger-facing brand. operator identifies the service operator.

Use returned line presentation colors where available, with a readable fallback. Render notices and names as text.

Show boarding/alighting calls, expand intermediateEstimatedCalls, and display cancelled calls as unavailable. Show staySeated as “Stay on board” and use returned waiting legs in the timeline.

If pricing supplies transferInstruction, use its full-array leg indices. Walking and waiting legs may exist between the two referenced transit legs.

leg.pointsOnLink.points is an encoded polyline. Decode it to coordinate pairs, then adapt coordinate order for your map library. A typical polyline decoder returns [latitude, longitude], while GeoJSON uses [longitude, latitude].

Install the decoder with npm install @mapbox/polyline.

Using @mapbox/polyline
import polyline from '@mapbox/polyline';
function legFeature(leg) {
const encoded = leg.pointsOnLink?.points;
if (!encoded) return null;
const coordinates = polyline.decode(encoded).map(([lat, lon]) => [lon, lat]);
if (coordinates.length < 2) return null;
return {
type: 'Feature', properties: { legId: leg.id },
geometry: { type: 'LineString', coordinates }
};
}

Draw the geometry where it is available. Rental stations and vehicles use their own place coordinates and may include availability or range information when supplied by the source.

Tram 20 through Utrecht, with intermediate stops and the selected route on the map.
A complete journey, leg by leg

Tram 20 through Utrecht, with intermediate stops and the selected route on the map.