Routing module
The Routing module draws the routes calculateRoute returns, with their
waypoints, guidance and traffic along the way, and handles their interactions.
The module owns the route lines, waypoints, section overlays, instruction arrows and summary bubbles it draws, and how they look (Route styling). It never restyles the roads underneath, which belong to the Styling Foundations module. Two looks reach it from outside:
- A route without a
colortakes the map's accent. - Its traffic sections follow the Traffic Incidents module's
colors.*knobs (Borrowed looks).
No other knob reaches route layers. See Who owns what.
The code below geocodes four stops, calculates the route through them and draws both. The response goes to showRoutes unchanged. Change an address to re-plan it:
Two features of the module have a guide of their own:
| Guide | Covers |
|---|---|
| Route styling | Colour, width, waypoint size, layers, the knob catalogue and layer positioning |
| Route sections | The overlays drawn per stretch of road: tunnels, ferries, traffic, speed limit signs, border crossings and the rest |
Initialization
import { TomTomMap, RoutingModule } from '@tomtom-org/maps-sdk/map';
const map = new TomTomMap({ mapLibre: { container: 'map' } });
const routingModule = await RoutingModule.create(map, {
displayUnits: { distance: { type: 'metric' } }, // optional
waypoints: { entryPoints: 'main-when-available' } // optional
});
- Without
displayUnits, the labels use the global units (TomTomConfig.instance.put({ displayUnits })) in force when they are drawn. Shown routes pick up a change on their nextshowRoutesor configuration change. getConfig()returns only what you passed, never the global units.
Displaying routes
import { calculateRoute } from '@tomtom-org/maps-sdk/services';
const locations = [
[4.9041, 52.3676], // Amsterdam
[4.4777, 51.9244] // Rotterdam
];
const routes = await calculateRoute({ locations });
await routingModule.showRoutes(routes);
await routingModule.showWaypoints(locations); // showRoutes draws no pins
showRoutes draws the lines, sections, guidance and summary bubbles, but no pins.
showWaypoints draws the start, stop and destination pins.
Locations describes what locations takes.
Route planning parameters covers every other request option.
Displaying guidance on map
A route calculated with guidance: { type: 'coded' } draws its instruction
lines and arrows with no extra configuration:
const route = await calculateRoute({ locations, guidance: { type: 'coded' } });
await routingModule.showRoutes(route);
Route selection
With alternatives, the module draws one route as selected, the first by default:
const routes = await calculateRoute({ locations, maxAlternatives: 2 });
await routingModule.showRoutes(routes, { selectedIndex: 1 });
await routingModule.selectRoute(0); // re-marks the shown routes, no recalculation
Waypoints
showWaypoints draws the pins, and clearWaypoints removes them. Neither touches the routes, and
clearRoutes leaves the pins.
A stop's pin shows its name. If the stop has a pauseDurationSeconds, the pin also shows how long the route
waits there, in the SDK's display units:
const locations = [
[2.1734, 41.3851],
{
type: 'Feature',
geometry: { type: 'Point', coordinates: [2.4467, 41.5381] },
properties: { pauseDurationSeconds: 30 * 60 } // the pin reads "30 min" under the stop name
},
[2.8214, 41.9794]
];
await routingModule.showRoutes(await calculateRoute({ locations }));
await routingModule.showWaypoints(locations);
Waypoints or places
- A waypoint is any location a route is calculated through.
showWaypointsdraws it with its role (start, stop or finish), its stop mark and the module'swaypointsevents. - A place the user is still choosing among, such as a search result or a candidate stop, belongs to the
Places module. Once it joins the route, clear it there and pass it to
showWaypoints, so no location is drawn twice:
places.events.on('click', async (place) => {
const locations = [origin, place, destination];
await places.clear();
await routingModule.showRoutes(await calculateRoute({ locations }));
await routingModule.showWaypoints(locations);
});
If several routing modules share a location, such as the one destination of routes from several origins, you can mark it once with a Places module instead.
When you change any setting below through applyConfig, the waypoints already shown update and keep their
ids and event states. Try it all on the waypoints playground:
Pins per role
waypoints.icon.style styles every pin. waypoints.icon.start, middle and finish each style one role on
top of it. A pin without a fillColor takes the route's color:
const routingModule = await RoutingModule.create(map, {
waypoints: {
icon: {
style: { outlineColor: '#FFFFFF' },
start: { style: { fillColor: '#1B7A3E' } },
finish: { style: { fillColor: '#C0392B' } }
}
}
});
Stop marks
- A stop's pin carries its number among the stops, starting at 1.
waypoints.stopNumberingcan also be'letters'(A to Z, then AA) or'none'. - The count includes stops that a mapping draws its own icon for, so the marks keep
matching the stop order. Those icons and a
middle.imagecarry no mark. - The start and finish pins draw their own glyph instead.
- The mark is the waypoint's
stopDisplayLabelproperty, whichevents.waypointshandlers receive.
Labels
Each pin's label shows its POI name, otherwise its address, and its wait. waypoints.label.visible: false drops
the labels. To write your own, set waypoints.label.title to a function of the waypoint or a
MapLibre expression, like label.title for places:
import { buildWaypointTitle } from '@tomtom-org/maps-sdk/map';
routingModule.applyConfig({
waypoints: {
label: {
title: (waypoint) => (waypoint.properties.indexType === 'finish' ? 'Home' : buildWaypointTitle(waypoint) ?? '')
}
}
});
Route styling covers the label's colour, halo and size.
Hover and click
Once a handler covers the waypoints, a hovered or clicked pin and its stop mark grow by
waypoints.highlight.sizeFactor. It defaults to 1.2 and is clamped to 1 to 1.5, and 1 draws the pin like any
other. The waypoints scope has the event state methods to set that state from your
own UI:
routingModule.events.waypoints.on('hover', (waypoint) => showStopCard(waypoint.properties));
routingModule.events.waypoints.setEventState({ index: 1, state: 'click' });
Icons of your own
A role's image replaces its pin, and waypoints.icon.mapping picks a pin per waypoint from its data, as
icon.mapping does for places:
to: 'poiCategory'draws the SDK's pin for the categoryfnreturns, so a stop that came from search shows what kind of place it is.to: 'imageID'draws the imagefnnames, from the style's sprite or fromwaypoints.icon.customIcons.- If
fnreturnsundefinedfor a waypoint, it keeps its role's pin and stop mark.
const routingModule = await RoutingModule.create(map, {
waypoints: {
icon: {
finish: { image: { image: chequeredFlagSVG } },
mapping: { to: 'poiCategory', fn: (waypoint) => waypoint.properties.poi?.categories?.[0] }
}
}
});
- The module draws an image at pixel ratio 2 unless it sets
pixelRatio. It stands on the waypoint by its bottom middle, like the SDK's 120 × 140 pixel pins. RoutingModuleSerializableConfigkeeps the styles, the stop numbering and images given as a URL, data URI or SVG text. It leaves outmapping, a functiontitleand anHTMLImageElementimage.
Showing and hiding
setVisible(false) hides everything the module draws (route lines, waypoints, sections, guidance, charging
stops, summary bubbles and border crossings) and keeps what it shows:
const routingModule = await RoutingModule.create(map, { visible: false }); // starts hidden
await routingModule.showRoutes(route); // kept, not drawn
routingModule.setVisible(true); // draws the route
routingModule.isVisible(); // true
showRoutes,showWaypoints, the clear methods and a style change leave a hidden module hidden.- It sets the config's
visible, soisVisible()reads the setting back andconfig-changereports it. - While the module is shown, each part's own
visible(sections.<type>.visible,summaryBubbles.visible, …) still decides whether that part draws.
Events
Each part of a route has its own scope on the user events surface:
routingModule.events.mainLines.on('click', (route, lngLat) => console.log(route.properties));
routingModule.events.waypoints.on('click', (waypoint) => console.log(waypoint.properties.indexType));
routingModule.events.incidents.on('hover', (section) => console.log(section.properties.delayInSeconds));
routingModule.events.instructionLines.on('click', (instruction) => console.log(instruction.properties));
routingModule.events.summaryBubbles.on('click', (summary) => console.log(summary.properties));
// Removes every click handler of the scope; `on` returns an unsubscribe for one handler
routingModule.events.mainLines.off('click');
- Route sections covers the section scopes:
ferries,tollRoads,tunnels,vehicleRestricted,countryCrossingsand one<type>Sectionsper generated type. - The instruction arrows have no scope. A click on one is a click on its instruction.
Once a handler covers the routes, a hovered or clicked route draws its outline wider, selected or not. The
module's event state methods act on the routes, and each named scope has
them for its own features. A click marks the route, and selectRoute makes it the selected one:
routingModule.events.mainLines.on('click', (route) => routingModule.selectRoute(route.properties.index));
routingModule.setEventState({ index: 1, state: 'hover' });
const { click: [clickedRouteID] = [] } = routingModule.getEventStates();
highlight.outline.widthFactor sets how much wider. It defaults to 1.2 and is clamped to 1 to 1.25, so the outline
never covers a section halo beneath the route. 1 draws a hovered route like
any other. An outline width you set through layers.mainLines.routeOutline stays as you set it, in every
state.
routingModule.applyConfig({ highlight: { outline: { widthFactor: 1.25 } } });
Multiple module instances
Each instance has its own sources, layers, configuration and events, for comparing route types or showing routes for several users:
const carRoutes = await RoutingModule.create(map, { color: '#2ECC71' });
const truckRoutes = await RoutingModule.create(map, { color: '#E67E22' });
await carRoutes.showRoutes(carRoute);
await truckRoutes.showRoutes(truckRoute);
Reading shown data
getShown() returns what the module draws, as prepared for display, split by what draws it:
const shown = routingModule.getShown();
if (shown.mainLines.features.length > 0) {
console.log(`Showing ${shown.mainLines.features.length} routes, ${shown.waypoints.features.length} waypoints`);
}
Its entries are mainLines, waypoints, incidents, ferries, tollRoads, tunnels,
vehicleRestricted, instructionLines, instructionArrows, summaryBubbles, countryCrossings and
sectionFocus, plus one <type>Sections per
generated section type, such as urbanSections and
motorwaySections.
API reference
RoutingModule lists every method, and
RoutingModuleConfig every setting.
Related guides and examples
Services integration
- Route planning parameters - Every option of
calculateRoute - Locations - Specifying route planning locations
- Guidance - The turn-by-turn instructions the module draws
- Geocoding - Addresses to coordinates for waypoints and destinations
Related examples
- Route - Basic route calculation and display on the map
- Route with alternatives - Display multiple route options for comparison
- Waypoints - Multi-stop route visualization with interactive waypoints
- Map route reconstruction playground - Interactive route building and editing
- Route stop wait playground - A stop's wait on its pin, and in the journey time
- Route style playground - The route's colour, width, waypoint size, waypoint label colour and clicked outline on knobs, and a toggle that hides it
- Route sections playground - Every section type on one set of knobs, and the speed-limit sign controls
- Route waypoints playground - Per-role pins, stop numbering, labels, hover growth, a category pin per stop and a finish image of your own
- Speed limit signs by country - A section's number posted as the road sign its country uses
- Borrowed looks - A route's traffic sections recoloured live by the incident colour knobs
Related map modules
- Route styling - The route's own look and its knob catalogue
- Route sections - The overlays drawn per stretch of road
- Places module - The places a user is still choosing among, before one joins the route as a waypoint
- User interaction events - Handle user interactions with routes and route segments