Traffic incidents module

TrafficIncidentsModule controls the style’s live traffic-incident layers across the whole map. They draw a line coloured by delay along each affected stretch of road and a category icon per incident, such as accidents, closures, roadworks and weather.

The module owns the visibility, filters and look of the style’s incident layers and icons, including the colour of each severity and the line width, and whether it shows the incidents under way, the planned ones or both. The Traffic Incident Details Module draws incidents you fetched yourself. See Who owns what.

To show every live incident in view, call get with visible: true:

import { TomTomMap, TrafficIncidentsModule } from '@tomtom-org/maps-sdk/map';
const map = new TomTomMap({ mapLibre: { container: 'map', center: [2.34281, 48.85639], zoom: 12 } });
await TrafficIncidentsModule.get(map, { visible: true });

The demo below runs this code over Paris:

Initialization

import { TomTomMap, TrafficIncidentsModule } from '@tomtom-org/maps-sdk/map';
const map = new TomTomMap({ mapLibre: { container: 'map' } });
const trafficIncidentsModule = await TrafficIncidentsModule.get(map);
  • If the style lacks the trafficIncidents style part, get() adds it and reloads the style.
  • It is style-owned, so every get() on one map returns the same instance.

Visibility

Incidents are hidden until you show them. isVisible() returns the visible setting, false by default.

const trafficIncidentsModule = await TrafficIncidentsModule.get(map, { visible: true });
trafficIncidentsModule.setVisible(false);
trafficIncidentsModule.isVisible(); // false

Icon visibility

You can hide the icons and the lines separately, but the filters narrow both to the same incidents.

  • icons.visible, which setIconsVisible sets, overrides visible for the icons. isIconsVisible() returns it, or isVisible() while it is unset.
  • setVisible clears icons.visible, so the icons follow visible again. To show icons alone, pass { visible: false, icons: { visible: true } }, or call setVisible(false) and then setIconsVisible(true). In the other order, the icons hide again.
// Lines without icons
const trafficIncidentsModule = await TrafficIncidentsModule.get(map, { visible: true, icons: { visible: false } });
trafficIncidentsModule.isIconsVisible(); // false
// Icons alone
trafficIncidentsModule.setVisible(false);
trafficIncidentsModule.setIconsVisible(true);
trafficIncidentsModule.isIconsVisible(); // true
// setVisible clears icons.visible: the icons follow visible again
trafficIncidentsModule.setVisible(true);
trafficIncidentsModule.getConfig(); // { visible: true }

isIconsVisible() reports the setting. To check whether a style layer itself is shown, call map.mapLibreMap.getLayoutProperty(layerId, 'visibility').

Planned incidents

timeValidity picks which incidents the tiles bring. present ones are under way, and future ones are planned, such as scheduled roadworks and closures. If you leave it unset or empty, only the present ones show.

// Planned incidents alongside the ones under way
trafficIncidentsModule.updateConfig({ timeValidity: ['present', 'future'] });
// Planned ones only
trafficIncidentsModule.updateConfig({ timeValidity: ['future'] });
  • It changes the tile request, so a change reloads the incident tiles. It survives a style switch.
  • Each incident’s timeValidity property says which kind it is, so the filters, events and getRenderedFeatures() treat planned incidents like live ones.
  • To fetch planned incidents as data rather than draw them, trafficIncidentDetails takes the same choice as timeValidityFilter.

Filtering

Set filters at get() or later through updateConfig to narrow which incidents show, lines and icons alike. Like the flow filters, the fields form one filter. Every field you set must match, and each entry of its any list is an alternative.

Incident category

// Accidents and road closures only
trafficIncidentsModule.updateConfig({
filters: { incidentCategories: { show: 'only', values: ['accident', 'road-closed'] } },
});
// Every incident but the weather
trafficIncidentsModule.updateConfig({
filters: { incidentCategories: { show: 'all-except', values: ['rain', 'fog', 'frost', 'wind', 'flooding'] } },
});

The values are the incident categories of fullTrafficIncidentCategories, including the tile-only animals-on-road and narrow-lanes.

Severity

The playground below filters by delay magnitude with checkboxes:

trafficIncidentsModule.updateConfig({
filters: { magnitudes: { show: 'only', values: ['major', 'moderate'] } },
});

The values are the delay magnitudes: unknown, minor, moderate, major and indefinite.

Delay duration

// At least 5 minutes of delay; incidents reporting no delay drop out too
trafficIncidentsModule.updateConfig({
filters: { delays: { required: true, minMinutes: 5 } },
});
  • required drops the incidents that report no delay.
  • minMinutes drops those delaying traffic by less. Without required, incidents with no delay stay.

Road category

roadCategories and roadSubCategories take the road categories and subcategories of the flow filters:

trafficIncidentsModule.updateConfig({
filters: { roadCategories: { show: 'only', values: ['motorway', 'trunk'] } },
});

Multiple filters

// Major accidents, or a road closure of any magnitude
trafficIncidentsModule.updateConfig({
filters: {
incidentCategories: { show: 'only', values: ['accident'] },
magnitudes: { show: 'only', values: ['major'] },
any: [{ incidentCategories: { show: 'only', values: ['road-closed'] } }],
},
});

Reset filters

trafficIncidentsModule.updateConfig({ filters: undefined });

Appearance

colors recolours the incident lines per delay severity, widthFactor (0.5 to 2) multiplies their width, and opacityFactor (0 to 1) their opacity.

  • Each restyles the style’s own incident layers. By default, the style’s value applies, and a factor multiplies it, so the style’s zoom ramp keeps its shape.
  • opacityFactor fades the lines and their outlines. The incident icons stay opaque.
  • A severity’s outline follows its colour.
  • The severities are minor, moderate and major, plus closed for the outline of closed roads.
import { setKnob, TrafficIncidentsModule, trafficIncidentsKnobCatalogue } from '@tomtom-org/maps-sdk/map';
const trafficIncidentsModule = await TrafficIncidentsModule.get(map, {
visible: true,
colors: { major: '#b91c1c', closed: '#111827' },
widthFactor: 1.5,
});
setKnob(trafficIncidentsModule, trafficIncidentsKnobCatalogue, 'colors.minor', '#facc15');
setKnob(trafficIncidentsModule, trafficIncidentsKnobCatalogue, 'opacityFactor', 0.5);

Events

events.on takes click, hover, long-hover and the other user events. The handler receives the incident as a TrafficIncidentsModuleFeature.

const unsubscribe = trafficIncidentsModule.events.on('click', (incident, lngLat) => {
const { id, category, magnitudeOfDelay, delayInSeconds, description } = incident.properties;
});
  • on returns the function that removes the handler. events.off('click') removes every click handler of the module (Cleanup).
  • A tile feature carries the properties both incident sources share, plus tile fields such as description, roadCategory and averageSpeedKmph. roadSubcategory is only present on street and service roads. To look up the full record, pass its id to trafficIncidentDetails({ ids: [id] }) (query by IDs).
  • description is in the map’s language, or the nearest one the traffic service has (pt-PT for pt-BR). Otherwise, it is in English. When that changes, map.setLanguage reloads the incident tiles.

Querying visible features

getRenderedFeatures() returns the incident lines and icons rendered in the current viewport:

const { trafficIncidents } = trafficIncidentsModule.getRenderedFeatures();
const accidents = trafficIncidents.filter((incident) => incident.properties.category === 'accident');

Every setting as data

trafficIncidentsKnobCatalogue lists the module’s plain-valued settings with their kind, range or options, and their default where one value holds everywhere. You can read it with no map loaded:

import { trafficIncidentsKnobCatalogue } from '@tomtom-org/maps-sdk/map';
// [{ id: 'visible', kind: 'toggle', description: '…', default: false },
// { id: 'icons.visible', kind: 'toggle', description: '…' }, …,
// { id: 'filters.magnitudes.values', kind: 'enums', description: '…', options: ['unknown', 'minor', 'moderate', 'major', 'indefinite'] }, …]
IdKind
visibletoggle, false by default
icons.visibletoggle. If unset, the icons follow visible
timeValidityenums: present, future. ['present'] by default
filters.roadCategories.show, filters.roadSubCategories.show, filters.incidentCategories.show, filters.magnitudes.showenum: only or all-except
filters.roadCategories.valuesenums: the road categories
filters.roadSubCategories.valuesenums: the street, then the service road subcategories
filters.incidentCategories.valuesenums: fullTrafficIncidentCategories
filters.magnitudes.valuesenums: the delay magnitudes
filters.delays.requiredtoggle, false by default
filters.delays.minMinutesnumber, 0 to 120 minutes
colors.minor, colors.moderate, colors.major, colors.closedcolour, the style’s own while unset
widthFactorfactor 0.5–2, 1 by default
opacityFactorfactor 0–1, 1 by default
  • The filters knobs set the fields of the filter. The any list of filters is config only. Each show knob goes with its values knob. If you leave them unset, nothing is filtered.
  • trafficIncidentsKnobIds lists the ids, TrafficIncidentsKnobId is their union, and TrafficIncidentsKnobValueOf<ID> is the plain value one takes. The modules guide describes the entry shape and its kinds.
  • It leaves out events.
  • The traffic config playground builds its flow and incidents controls from the two catalogues and sets each with setKnob.

API reference

TrafficIncidentsModule, TrafficIncidentsModuleConfig and TrafficIncidentsModuleFeature.