This is the documentation of version 1.0.0-rc.1. Go to the latest version, 1.0.0-rc.5.

Traffic incident details module

TrafficIncidentDetailsModule draws exactly the incidents a trafficIncidentDetails call returned, and highlights a subset of them. Use it when your app also holds the typed incidents, for popups, lists or route correlation, and decides when they render.

The module owns the incident lines and icons it draws from your fetched details, and their look, including the focus treatment below. The live incident tiles and their colours belong to the Traffic Incidents Module. This module borrows those colours, so that module's colors.* knobs recolour it too (Borrowed looks). No other knob reaches it. See Who owns what.

When to use the details module vs TrafficIncidentsModule

You need… Use
Live, full-coverage incidents with no fetch TrafficIncidentsModule
Typed incident objects in your app code TrafficIncidentDetailsModule
Render exactly the result of a single REST call TrafficIncidentDetailsModule
Per-feature focus / highlight a subset TrafficIncidentDetailsModule
Maximum visual fidelity (per-road-class styling, declutter) TrafficIncidentsModule

The tile incidents are hidden until shown, so by default the two don't collide. If your app shows TrafficIncidentsModule, hide it while this module draws, or each incident renders twice.

Initialization

import { TomTomMap, TrafficIncidentDetailsModule } from '@tomtom-org/maps-sdk/map';

const map = new TomTomMap({ mapLibre: { container: 'map' } });
const incidentDetailsModule = await TrafficIncidentDetailsModule.create(map);

It is data-owned, so every create() returns a new, independent instance.

Rendering incidents

Pass the service result to show():

import { trafficIncidentDetails } from '@tomtom-org/maps-sdk/services';

const result = await trafficIncidentDetails({ bbox: map.getBBox() });
await incidentDetailsModule.show(result);

Focusing a subset

setFocus(ids) marks the incidents with those ids through MapLibre feature state. setFocus(null) or setFocus([]) clears the focus:

incidentDetailsModule.setFocus([result.features[0].properties.id]);
incidentDetailsModule.setFocus(null);

Customising or disabling the highlight

highlight takes an IncidentHighlightConfig. Unset fields keep their defaults:

const incidentDetailsModule = await TrafficIncidentDetailsModule.create(map, {
    highlight: { outline: { color: '#1976d2' }, line: { widthFactor: 1.8 } },
});
incidentDetailsModule.updateConfig({ highlight: { outline: { color: '#c2185b' }, line: { widthFactor: 1.2 } } });
incidentDetailsModule.updateConfig({ highlight: false });

Events

The handlers of click, hover and the other user events receive the typed TrafficIncident, with its Date and array properties intact:

incidentDetailsModule.events.on('click', (incident) => {
    incidentDetailsModule.setFocus([incident.properties.id]);
});

The handler's third argument, allEventFeatures, holds every incident under the pointer once, however many of its layers were hit.

Visibility and layer ordering

isVisible() reports the visible setting, true by default, not whether any incident is drawn. While hidden, show() updates the data without drawing it.

incidentDetailsModule.setVisible(false);
incidentDetailsModule.getShown().incidents.features.length > 0; // whether there are incidents to draw

// Above every other layer (default: below the labels, 'lowestLabel')
incidentDetailsModule.updateConfig({ beforeLayerConfig: 'top' });

beforeLayerConfig takes one target for every layer of the module, 'top' or a key of mapStyleLayerIDs (Layer position). You can't position parts separately.

Layer overrides

Beyond the settings above, layers (TrafficIncidentDetailsLayersConfig) takes a partial MapLibre layer for each layer the module draws. Bottom to top, they are highlightHalo, outline, innerSolid, innerChevron, innerPattern, then the incidentMarker, jamMarker and closedRoadMarker icons.

incidentDetailsModule.updateConfig({
    layers: {
        incidentMarker: { minzoom: 11 },                  // the category icons from zoom 11
        jamMarker: { layout: { 'text-field': '' } },      // jam icons without their delay
        innerChevron: { layout: { visibility: 'none' } }, // no direction chevrons
    },
});

Every setting as data

trafficIncidentDetailsKnobCatalogue lists the module's plain-valued settings with their kind, range and any default that holds everywhere. It is readable with no map loaded:

import { knobEntryOf, trafficIncidentDetailsKnobCatalogue } from '@tomtom-org/maps-sdk/map';

const widthFactor = knobEntryOf(trafficIncidentDetailsKnobCatalogue, 'highlight.line.widthFactor');
// { id: 'highlight.line.widthFactor', kind: 'factor', description: '…', range: { min: 1, max: 1.8, step: 0.1, bounds: 'hard' }, default: 1.6 }
Id Kind
visible toggle, true by default
highlight.outline.color colour, following the map's light/dark theme if unset
highlight.line.widthFactor factor 1–1.8, 1.6 by default

Limitations

The Incident Details API returns a feature list, not rendering-ready tiles, so it lacks the tags the tile pipeline adds per feature:

For full visual fidelity, use TrafficIncidentsModule.

Where incidents share a point or stack along one road, MapLibre's symbol collision keeps only the highest-sort-key icon, and queryRenderedFeatures can't reach the culled ones. To surface every incident at a location, read the FeatureCollection you passed to show().

API reference

TrafficIncidentDetailsModule, TrafficIncidentDetailsModuleConfig and IncidentHighlightConfig.

Related guides and examples

Related guides

Related examples