@tomtom-org/maps-sdk 0.47.0 → 0.47.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -54,8 +54,10 @@ import { SourceSpecification } from 'maplibre-gl';
54
54
  import { StyleSpecification } from 'maplibre-gl';
55
55
  import { SymbolLayerSpecification } from 'maplibre-gl';
56
56
  import { TrafficAreaAnalytics } from '@tomtom-org/maps-sdk/core';
57
+ import { TrafficIncident } from '@tomtom-org/maps-sdk/core';
57
58
  import { TrafficIncidentBaseProperties } from '@tomtom-org/maps-sdk/core';
58
59
  import { TrafficIncidentCategory } from '@tomtom-org/maps-sdk/core';
60
+ import { TrafficIncidentDetails } from '@tomtom-org/maps-sdk/core';
59
61
  import { TrafficIncidentTimeValidity } from '@tomtom-org/maps-sdk/core';
60
62
  import { TrafficSectionProps } from '@tomtom-org/maps-sdk/core';
61
63
  import { Waypoint } from '@tomtom-org/maps-sdk/core';
@@ -1204,6 +1206,7 @@ export declare class BaseMapModule extends AbstractMapModule<BaseSourceAndLayers
1204
1206
  setVisible(visible: boolean, options?: {
1205
1207
  layerGroups?: BaseMapLayerGroups;
1206
1208
  }): void;
1209
+ private _setVisible;
1207
1210
  /**
1208
1211
  * Gets the unified events interface for this module, covering both user interactions
1209
1212
  * and module lifecycle events.
@@ -1379,6 +1382,18 @@ export declare type BaseMapModuleInitConfig = BaseMapModuleConfig & {
1379
1382
  layerGroupsFilter?: BaseMapLayerGroups;
1380
1383
  };
1381
1384
 
1385
+ /**
1386
+ * The deduplicated set of base-map POI categories — the right-hand side of
1387
+ * {@link completeMapDisplayPoiCategoryMappings}. Each value names the
1388
+ * `poi-<value>` sprite the base-map style ships, so this set is what callers
1389
+ * (e.g., the `pin-clustered` cluster pin's `match` expression) statically
1390
+ * enumerate when they need MapLibre to pre-load every possible sprite into
1391
+ * the atlas.
1392
+ *
1393
+ * @ignore
1394
+ */
1395
+ export declare const baseMapPOICategoryValues: readonly string[];
1396
+
1382
1397
  declare type BaseSourceAndLayers = {
1383
1398
  vectorTiles: StyleSourceWithLayers;
1384
1399
  };
@@ -1903,6 +1918,22 @@ export declare class CombinedEvents<T, CFG, TShown = never> {
1903
1918
  off(type: EventType | 'config-change' | 'shown-features'): void;
1904
1919
  }
1905
1920
 
1921
+ /**
1922
+ * @ignore
1923
+ */
1924
+ declare type ConnectionFeatureCollection = FeatureCollection<LineString, ConnectionFeatureProps>;
1925
+
1926
+ /**
1927
+ * Properties carried by each connection feature once it is on the map.
1928
+ * @ignore
1929
+ */
1930
+ declare type ConnectionFeatureProps = {
1931
+ id: string;
1932
+ fromId?: string;
1933
+ toId?: string;
1934
+ label: string;
1935
+ };
1936
+
1906
1937
  /**
1907
1938
  * Allowed CSS cursor styles for map interactions.
1908
1939
  *
@@ -2971,12 +3002,19 @@ export declare type FlowConfig = MapModuleCommonConfig & {
2971
3002
  filters?: TrafficFlowFilters;
2972
3003
  };
2973
3004
 
3005
+ /**
3006
+ * Subset of {@link GeoJSONSourceSpecification} fields that {@link GeoJSONSourceWithLayers}
3007
+ * can be configured with at construction time. Forwarded verbatim to MapLibre.
3008
+ * @ignore
3009
+ */
3010
+ export declare type GeoJSONSourceClusterOptions = Pick<GeoJSONSourceSpecification, 'cluster' | 'clusterRadius' | 'clusterMaxZoom' | 'clusterMinPoints' | 'clusterProperties'>;
3011
+
2974
3012
  /**
2975
3013
  * @ignore
2976
3014
  */
2977
3015
  export declare class GeoJSONSourceWithLayers<T extends FeatureCollection = FeatureCollection> extends AddedSourceWithLayers<GeoJSONSourceSpecification, GeoJSONSource> {
2978
3016
  shownFeatures: T;
2979
- constructor(map: Map_2, sourceId: string, layerSpecs: ToBeAddedLayerSpecWithoutSource[], addLayersToMap?: boolean);
3017
+ constructor(map: Map_2, sourceId: string, layerSpecs: ToBeAddedLayerSpecWithoutSource[], addLayersToMap?: boolean, clusterOptions?: GeoJSONSourceClusterOptions);
2980
3018
  show(featureCollection: T, { automaticVisibility }?: ShowOptions): void;
2981
3019
  clear(): void;
2982
3020
  private findFeature;
@@ -3204,6 +3242,7 @@ export declare class GeometriesModule extends AbstractMapModule<GeometrySourcesW
3204
3242
  * ```
3205
3243
  */
3206
3244
  moveBeforeLayer(layerConfig: GeometryBeforeLayerConfig): void;
3245
+ private _moveBeforeLayer;
3207
3246
  /**
3208
3247
  * Updates the text/label configuration for displayed geometries.
3209
3248
  *
@@ -4098,6 +4137,7 @@ export declare class HillshadeModule extends AbstractMapModule<HillshadeSourcesW
4098
4137
  * ```
4099
4138
  */
4100
4139
  setVisible(visible: boolean): void;
4140
+ private _setVisible;
4101
4141
  /**
4102
4142
  * Checks if the hillshade layer is currently visible.
4103
4143
  *
@@ -4205,6 +4245,24 @@ declare type HillshadeSourcesWithLayers = {
4205
4245
  */
4206
4246
  export declare type HoverEventType = 'hover' | 'hover-move' | 'long-hover';
4207
4247
 
4248
+ /**
4249
+ * Visual treatment applied to the focused subset by
4250
+ * {@link TrafficIncidentOverlayModule.setFocus}.
4251
+ *
4252
+ * @group Traffic
4253
+ */
4254
+ export declare type IncidentFocusStyle = {
4255
+ /**
4256
+ * Colour of the outline painted beneath the focused stripe. Defaults to `#000`.
4257
+ */
4258
+ outlineColor?: string;
4259
+ /**
4260
+ * Multiplier applied to the line width of focused features. Defaults to `1.6`.
4261
+ * `1` disables the width pop while keeping the outline.
4262
+ */
4263
+ widthScale?: number;
4264
+ };
4265
+
4208
4266
  /**
4209
4267
  * Common configuration for traffic incident visualization components.
4210
4268
  *
@@ -4250,6 +4308,12 @@ export declare type IncidentsConfig = MapModuleCommonConfig & IncidentsCommonCon
4250
4308
  icons?: IncidentsCommonConfig;
4251
4309
  };
4252
4310
 
4311
+ /**
4312
+ * Dashed-line color for `magnitudeOfDelay === 'indefinite'` (rendered as a gray dashed overlay).
4313
+ * @ignore
4314
+ */
4315
+ export declare const INDEFINITE_DELAY_DASH_COLOR = "rgba(137, 150, 168, 1)";
4316
+
4253
4317
  /**
4254
4318
  * @ignore
4255
4319
  */
@@ -4775,6 +4839,11 @@ export declare type MapStylePOICategory = keyof typeof mapDisplayPoiCategoryMapp
4775
4839
  */
4776
4840
  export declare const MIDDLE_INDEX = "middle";
4777
4841
 
4842
+ /**
4843
+ * @ignore
4844
+ */
4845
+ export declare const MINOR_DELAY_COLOR = "#FFC105";
4846
+
4778
4847
  /**
4779
4848
  * @ignore
4780
4849
  */
@@ -4900,6 +4969,114 @@ export declare type MultiSyntaxFilter = {
4900
4969
  legacy: LegacyFilterSpecification;
4901
4970
  };
4902
4971
 
4972
+ /**
4973
+ * Describes a single connection between two places, to be rendered as a line on the map.
4974
+ *
4975
+ * @remarks
4976
+ * Each endpoint can be given either as a full {@link Place} object or as the `id` of a
4977
+ * place that is currently displayed by the {@link PlacesModule} (via `show()`). When an
4978
+ * id is given, the module resolves it against its currently shown places to obtain the
4979
+ * coordinates; connections referencing unknown ids are silently skipped.
4980
+ *
4981
+ * Extra arbitrary properties are preserved on the connection and passed to the optional
4982
+ * label function, making it easy to render metadata such as distance or travel time
4983
+ * along the line.
4984
+ *
4985
+ * @example
4986
+ * ```typescript
4987
+ * const connection: PlaceConnectionDisplay = {
4988
+ * from: stationPlace, // full Place object
4989
+ * to: 'cafe-id-123', // or a shown place's id
4990
+ * distanceMeters: 420 // extra metadata available to the label function
4991
+ * };
4992
+ * ```
4993
+ *
4994
+ * @group Places
4995
+ */
4996
+ export declare type PlaceConnectionDisplay = {
4997
+ /**
4998
+ * The first endpoint of the connection. Either a Place object or the id of a
4999
+ * place currently shown by the module.
5000
+ */
5001
+ from: Place | string;
5002
+ /**
5003
+ * The second endpoint of the connection. Either a Place object or the id of a
5004
+ * place currently shown by the module.
5005
+ */
5006
+ to: Place | string;
5007
+ /**
5008
+ * Optional stable id for this connection. When omitted, an id is generated.
5009
+ */
5010
+ id?: string;
5011
+ /**
5012
+ * Arbitrary extra metadata, preserved on the connection and passed to the label
5013
+ * function.
5014
+ */
5015
+ [key: string]: unknown;
5016
+ };
5017
+
5018
+ /**
5019
+ * @group Places
5020
+ */
5021
+ export declare type PlaceConnectionLayerName = keyof PlaceConnectionsLayersConfig;
5022
+
5023
+ /**
5024
+ * Configuration for rendering connection lines between places.
5025
+ *
5026
+ * @remarks
5027
+ * Controls the appearance of connection lines, the optional label drawn along each
5028
+ * line, and MapLibre layer overrides.
5029
+ *
5030
+ * @example
5031
+ * ```typescript
5032
+ * const config: PlacesModuleConfig = {
5033
+ * connections: {
5034
+ * label: (connection) => `${connection.distanceMeters} m`,
5035
+ * layers: {
5036
+ * line: { paint: { 'line-color': '#3f9cd9' } }
5037
+ * }
5038
+ * }
5039
+ * };
5040
+ * ```
5041
+ *
5042
+ * @group Places
5043
+ */
5044
+ export declare type PlaceConnectionsConfig = {
5045
+ /**
5046
+ * Function returning the text to display along the connection line.
5047
+ *
5048
+ * @remarks
5049
+ * Receives the original {@link PlaceConnectionDisplay} (including any custom
5050
+ * metadata). When omitted, no label is rendered.
5051
+ */
5052
+ label?: (connection: PlaceConnectionDisplay) => string;
5053
+ /**
5054
+ * Custom MapLibre layer specifications for connection line and label.
5055
+ */
5056
+ layers?: PlaceConnectionsLayersConfig;
5057
+ };
5058
+
5059
+ /**
5060
+ * MapLibre layer customization for connection lines and labels.
5061
+ *
5062
+ * @remarks
5063
+ * The layer IDs are derived from the PlacesModule instance prefix plus the key suffix:
5064
+ * - `line`: the connection line (default: dashed)
5065
+ * - `label`: the text label placed along the line
5066
+ *
5067
+ * @group Places
5068
+ */
5069
+ export declare type PlaceConnectionsLayersConfig = {
5070
+ /**
5071
+ * Connection line layer specification.
5072
+ */
5073
+ line?: Partial<ToBeAddedLayerSpecTemplate<LineLayerSpecification>>;
5074
+ /**
5075
+ * Connection label layer specification.
5076
+ */
5077
+ label?: Partial<ToBeAddedLayerSpecTemplate<SymbolLayerSpecification>>;
5078
+ };
5079
+
4903
5080
  /**
4904
5081
  * Properties attached to a place feature for rendering on the map.
4905
5082
  *
@@ -5165,95 +5342,69 @@ export declare type PlaceLayersConfig = {
5165
5342
  * This layer reacts to 'hover' and 'click' event states.
5166
5343
  */
5167
5344
  selected?: Partial<ToBeAddedLayerSpecTemplate<SymbolLayerSpecification>>;
5345
+ /**
5346
+ * Cluster pin layer specification.
5347
+ *
5348
+ * @remarks
5349
+ * Always registered and stacked above `selected`, but only renders under the
5350
+ * `pin-clustered` theme and only for single-category clusters — every leaf in
5351
+ * the cluster shares the same base-map sprite, picked via a `match` over the
5352
+ * aggregated `clusterBaseMapIconIDs` property. Mixed-category clusters fall
5353
+ * through to {@link clusterMixedBadge} + {@link clusterMixedCount} instead.
5354
+ * For other themes the layer is hidden via `layout.visibility = 'none'`.
5355
+ */
5356
+ cluster?: Partial<ToBeAddedLayerSpecTemplate<SymbolLayerSpecification>>;
5357
+ /**
5358
+ * Cluster count badge background layer specification.
5359
+ *
5360
+ * @remarks
5361
+ * Black circle drawn at the top-right of each single-category cluster pin.
5362
+ * Acts as the background for {@link clusterCount}. Only visible under the
5363
+ * `pin-clustered` theme and gated to single-category clusters; mixed
5364
+ * clusters use {@link clusterMixedBadge} instead.
5365
+ */
5366
+ clusterBadge?: Partial<ToBeAddedLayerSpecTemplate<CircleLayerSpecification>>;
5367
+ /**
5368
+ * Cluster count text layer specification.
5369
+ *
5370
+ * @remarks
5371
+ * White count rendered on top of {@link clusterBadge} for single-category
5372
+ * clusters. Reads the `point_count_abbreviated` property MapLibre sets on
5373
+ * every cluster feature. Only visible under the `pin-clustered` theme;
5374
+ * mixed clusters use {@link clusterMixedCount} instead.
5375
+ */
5376
+ clusterCount?: Partial<ToBeAddedLayerSpecTemplate<SymbolLayerSpecification>>;
5377
+ /**
5378
+ * Centred count badge for mixed-category clusters under the
5379
+ * `pin-clustered` theme.
5380
+ *
5381
+ * @remarks
5382
+ * Replaces the cluster icon entirely when a cluster spans multiple POI
5383
+ * categories — the count circle takes the centre with
5384
+ * {@link clusterMixedCount} rendered on top. Filter is an "all clusters
5385
+ * with a mixed dedup-concat" check so single-category clusters fall
5386
+ * through to {@link cluster} + {@link clusterBadge} instead.
5387
+ */
5388
+ clusterMixedBadge?: Partial<ToBeAddedLayerSpecTemplate<CircleLayerSpecification>>;
5389
+ /**
5390
+ * Cluster count text on top of {@link clusterMixedBadge}.
5391
+ *
5392
+ * @remarks
5393
+ * Centred count for mixed-category clusters; mirrors
5394
+ * {@link clusterCount} but with no translate so it lands inside the
5395
+ * centred badge.
5396
+ */
5397
+ clusterMixedCount?: Partial<ToBeAddedLayerSpecTemplate<SymbolLayerSpecification>>;
5168
5398
  } & HasAdditionalLayersConfig;
5169
5399
 
5170
- /**
5171
- * Map module for displaying and managing place markers.
5172
- *
5173
- * The PlacesModule provides functionality to display location markers (pins) on the map
5174
- * for points of interest, search results, or custom locations. It supports various marker
5175
- * styles, custom icons, text labels, and interactive events.
5176
- *
5177
- * @remarks
5178
- * **Features:**
5179
- * - Multiple marker styles (pin, circle-icon, base-map POI-like)
5180
- * - Custom icons per POI category
5181
- * - Text labels with styling options
5182
- * - Data-driven styling via MapLibre expressions
5183
- * - Interactive events (click, hover, etc.)
5184
- * - Support for custom feature properties
5185
- * - EV charging station availability display (opt-in)
5186
- *
5187
- * **Marker Styles:**
5188
- * - `pin`: Traditional teardrop-shaped map pins
5189
- * - `circle-icon`: Simple circular markers (previously named `circle`)
5190
- * - `base-map`: Mimics the map's built-in POI layer styling (combines `main`, `selected`, and `micro` layers). For micro-only rendering, hide the `main` layer via `layers.main.layout.visibility = 'none'`.
5191
- *
5192
- * **EV Charging Station Availability:**
5193
- * When displaying EV charging stations with availability data from
5194
- * {@link getPlacesWithEVAvailability}, the module can:
5195
- * - Show available/total charging points (e.g., "3/10")
5196
- * - Color-code availability (green = good, orange = limited, red = none/low)
5197
- * - Display as formatted text within the station's label
5198
- *
5199
- * This feature is disabled by default. To enable it, set `evAvailability.enabled` to `true`
5200
- * in the configuration.
5201
- *
5202
- * **Common Use Cases:**
5203
- * - Search result visualization
5204
- * - Custom location markers
5205
- * - Store locators
5206
- * - EV charging station maps with real-time availability
5207
- * - Delivery/pickup points
5208
- * - Saved locations display
5209
- *
5210
- * @example
5211
- * ```typescript
5212
- * // Create places module with pin markers
5213
- * const placesModule = await PlacesModule.get(map, {
5214
- * icon: {
5215
- * categoryIcons: []
5216
- * },
5217
- * text: {
5218
- * field: (place) => place.properties.poi?.name || 'Unknown'
5219
- * },
5220
- * theme: 'pin'
5221
- * });
5222
- *
5223
- * // Display places from search
5224
- * await placesModule.show(searchResults);
5225
- *
5226
- * // EV Charging Stations - Opt-in to availability display
5227
- * const evStations = await PlacesModule.get(map, {
5228
- * evAvailability: { enabled: true }
5229
- * });
5230
- * const results = await search({ poiCategories: ['ELECTRIC_VEHICLE_STATION'] });
5231
- * evStations.show(await getPlacesWithEVAvailability(results)); // Shows availability
5232
- *
5233
- * // Granular control: Enable for searched stations only, background stations without
5234
- * const bgStations = await PlacesModule.get(map); // EV availability disabled
5235
- * const searched = await PlacesModule.get(map, {
5236
- * evAvailability: { enabled: true }
5237
- * });
5238
- *
5239
- * // Handle clicks
5240
- * placesModule.events.on('click', (feature) => {
5241
- * console.log('Clicked:', feature.properties);
5242
- * });
5243
- *
5244
- * placesModule.events.on('hover', (feature) => {
5245
- * showTooltip(feature.properties.poi?.name);
5246
- * });
5247
- * ```
5248
- *
5249
- * @see [Places Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/places)
5250
- *
5251
- * @group Places
5252
- */
5253
5400
  export declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLayers, PlacesModuleConfig> {
5254
5401
  private static lastInstanceIndex;
5255
5402
  private layerSpecs;
5403
+ private connectionLayerSpecs;
5404
+ private currentClusterMode;
5256
5405
  private sourceID;
5406
+ private unclusteredSourceID;
5407
+ private connectionSourceID;
5257
5408
  private layerIDPrefix;
5258
5409
  /**
5259
5410
  * The index of this instance, to generate unique source and layer IDs.
@@ -5262,6 +5413,7 @@ export declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLaye
5262
5413
  */
5263
5414
  private instanceIndex;
5264
5415
  private defaultPlaceIconID;
5416
+ private shownConnections;
5265
5417
  private readonly shownFeaturesHandlers;
5266
5418
  /**
5267
5419
  * Make sure the map is ready before create an instance of the module and any other interaction with the map
@@ -5275,7 +5427,10 @@ export declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLaye
5275
5427
  * @ignore
5276
5428
  */
5277
5429
  protected _initSourcesWithLayers(config?: PlacesModuleConfig, restore?: boolean): PlacesSourcesAndLayers;
5430
+ private partitionSpecsForSources;
5278
5431
  private buildLayerSpecs;
5432
+ private buildClusterOptions;
5433
+ private buildConnectionLayerSpecs;
5279
5434
  /**
5280
5435
  * @ignore
5281
5436
  */
@@ -5377,6 +5532,9 @@ export declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLaye
5377
5532
  [key: string]: any;
5378
5533
  }): void;
5379
5534
  private updateLayersAndData;
5535
+ private rebuildSourcesAndLayers;
5536
+ private updateConnectionLayersAndData;
5537
+ private updateConnectionsData;
5380
5538
  private applyPlacesVisibility;
5381
5539
  private setupImages;
5382
5540
  private updateData;
@@ -5441,6 +5599,52 @@ export declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLaye
5441
5599
  * ```
5442
5600
  */
5443
5601
  clear(): Promise<void>;
5602
+ /**
5603
+ * Displays connection lines between pairs of places on the map.
5604
+ *
5605
+ * @param connections - List of connections to render. Each connection has a `from`
5606
+ * and `to` endpoint, expressed either as a {@link Place} or as the id of a place
5607
+ * currently shown by this module.
5608
+ *
5609
+ * @remarks
5610
+ * **Behavior:**
5611
+ * - Replaces any previously shown connections
5612
+ * - Connections whose id reference cannot be resolved against the currently shown
5613
+ * places are silently skipped
5614
+ * - When {@link PlaceConnectionsConfig.label} is set on the module config, the
5615
+ * returned string is rendered as a label along each line, slightly offset to
5616
+ * the side. Without a label function, no label is shown.
5617
+ * - Calling `show()` or `clear()` pre-clears connections, since their endpoints
5618
+ * may no longer be on the map.
5619
+ *
5620
+ * @example
5621
+ * ```typescript
5622
+ * const places = await PlacesModule.get(map, {
5623
+ * connections: {
5624
+ * label: (c) => `${c.distanceMeters} m`
5625
+ * }
5626
+ * });
5627
+ * await places.show([station, ...cafes]);
5628
+ * await places.showConnections(
5629
+ * cafes.features.map((cafe) => ({
5630
+ * from: station.id,
5631
+ * to: cafe.id,
5632
+ * distanceMeters: Math.round(cafe.properties.dist ?? 0),
5633
+ * })),
5634
+ * );
5635
+ * ```
5636
+ */
5637
+ showConnections(connections: PlaceConnectionDisplay[]): Promise<void>;
5638
+ /**
5639
+ * Removes all connection lines from the map, leaving displayed places intact.
5640
+ *
5641
+ * @example
5642
+ * ```typescript
5643
+ * await placesModule.clearConnections();
5644
+ * ```
5645
+ */
5646
+ clearConnections(): Promise<void>;
5647
+ private clearConnectionsSync;
5444
5648
  /**
5445
5649
  * Returns the currently shown places.
5446
5650
  *
@@ -5457,6 +5661,7 @@ export declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLaye
5457
5661
  */
5458
5662
  getShown(): {
5459
5663
  places: Places<DisplayPlaceProps>;
5664
+ connections: PlaceConnectionDisplay[];
5460
5665
  };
5461
5666
  /**
5462
5667
  * Programmatically sets an event state on a specific place.
@@ -5591,6 +5796,15 @@ export declare type PlacesModuleConfig = MapModuleCommonConfig & {
5591
5796
  * @default undefined (disabled)
5592
5797
  */
5593
5798
  evAvailability?: EVAvailabilityConfig;
5799
+ /**
5800
+ * Configuration for connection lines drawn between places via
5801
+ * {@link PlacesModule.showConnections}.
5802
+ *
5803
+ * @remarks
5804
+ * When omitted, connections rendered via `showConnections` use default styling
5805
+ * (a dashed line) and no label.
5806
+ */
5807
+ connections?: PlaceConnectionsConfig;
5594
5808
  /**
5595
5809
  * Additional properties to compute for each place feature.
5596
5810
  *
@@ -5629,9 +5843,24 @@ export declare type PlacesModuleConfig = MapModuleCommonConfig & {
5629
5843
 
5630
5844
  declare type PlacesSourcesAndLayers = {
5631
5845
  /**
5632
- * Places source id with corresponding layers ids.
5846
+ * Places source id with corresponding layers ids. Carries every layer the
5847
+ * module owns under non-clustered themes; under `pin-clustered` it carries
5848
+ * everything except `micro` and is configured with `cluster: true` so the
5849
+ * pin / cluster pin / cluster-badge / cluster-count / mixed-cluster
5850
+ * badge + count layers all see aggregated cluster features.
5633
5851
  */
5634
5852
  places: GeoJSONSourceWithLayers<Places<DisplayPlaceProps>>;
5853
+ /**
5854
+ * Companion source — only created under `pin-clustered`. Feeds the `micro`
5855
+ * layer with the same place features but **without** clustering, so the
5856
+ * tiny base-map-style POI dots render on every place individually
5857
+ * regardless of how the larger pins above them get aggregated.
5858
+ */
5859
+ placesUnclustered?: GeoJSONSourceWithLayers<Places<DisplayPlaceProps>>;
5860
+ /**
5861
+ * Connections source id with corresponding layers ids (line + label).
5862
+ */
5863
+ connections: GeoJSONSourceWithLayers<ConnectionFeatureCollection>;
5635
5864
  };
5636
5865
 
5637
5866
  /**
@@ -5642,10 +5871,15 @@ declare type PlacesSourcesAndLayers = {
5642
5871
  * - `pin`: Traditional map pin markers (teardrop shape)
5643
5872
  * - `circle-icon`: Simple circular markers (previously named `circle`)
5644
5873
  * - `base-map`: Mimics the map's built-in POI layer style with category icons (combines `main`, `selected`, and `micro` layers). For micro-only rendering, hide the `main` layer via `layers.main.layout.visibility = 'none'`.
5874
+ * - `pin-clustered`: Same teardrop pins as `pin` for un-clustered places, with nearby
5875
+ * places aggregated into a single icon. Single-category clusters render the matching
5876
+ * base-map POI sprite with a small black count badge in the top-right; mixed-category
5877
+ * clusters render a larger centred count circle in place of the icon. Cluster features
5878
+ * expose `clusterBaseMapIconIDs` (comma-separated, deduplicated) on their properties.
5645
5879
  *
5646
5880
  * @group Places
5647
5881
  */
5648
- export declare type PlacesTheme = 'pin' | 'circle-icon' | 'base-map';
5882
+ export declare type PlacesTheme = 'pin' | 'circle-icon' | 'base-map' | 'pin-clustered';
5649
5883
 
5650
5884
  /**
5651
5885
  * Configuration for place text labels.
@@ -6102,6 +6336,7 @@ export declare class POIsModule extends AbstractMapModule<PoIsSourcesAndLayers,
6102
6336
  * ```
6103
6337
  */
6104
6338
  setVisible(visible: boolean): void;
6339
+ private _setVisible;
6105
6340
  /**
6106
6341
  * Filters POIs by category or category group.
6107
6342
  *
@@ -6157,6 +6392,7 @@ export declare class POIsModule extends AbstractMapModule<PoIsSourcesAndLayers,
6157
6392
  * ```
6158
6393
  */
6159
6394
  filterCategories(categoriesFilter?: ValuesFilter<FilterablePOICategory> | undefined): void;
6395
+ private _filterCategories;
6160
6396
  /**
6161
6397
  * Returns features currently visible in the viewport.
6162
6398
  *
@@ -7611,6 +7847,10 @@ declare type SourceEventTypeHandler = {
7611
7847
  config?: EventHandlerConfig;
7612
7848
  };
7613
7849
 
7850
+ declare type Sources = {
7851
+ incidents: GeoJSONSourceWithLayers<TrafficIncidentDetails>;
7852
+ };
7853
+
7614
7854
  /**
7615
7855
  * @ignore
7616
7856
  */
@@ -9080,6 +9320,7 @@ export declare class TrafficAreaAnalyticsModule extends AbstractMapModule<AreaAn
9080
9320
  * @param layerConfig - Per-layer-type positioning config. Each value is `'top'` or a `MapStyleLayerID`.
9081
9321
  */
9082
9322
  moveBeforeLayer(layerConfig: AreaAnalyticsBeforeLayerConfig): void;
9323
+ private _moveBeforeLayer;
9083
9324
  /**
9084
9325
  * Event interface for the hexgrid and square layers.
9085
9326
  *
@@ -9426,6 +9667,7 @@ export declare class TrafficFlowModule extends AbstractMapModule<TrafficFlowSour
9426
9667
  * ```
9427
9668
  */
9428
9669
  setVisible(visible: boolean): void;
9670
+ private _setVisible;
9429
9671
  /**
9430
9672
  * Returns if any layer for traffic flow is visible or not.
9431
9673
  */
@@ -9524,6 +9766,195 @@ declare type TrafficFlowSourcesWithLayers = {
9524
9766
  trafficFlow: StyleSourceWithLayers;
9525
9767
  };
9526
9768
 
9769
+ /**
9770
+ * Configuration for {@link TrafficIncidentOverlayModule}.
9771
+ *
9772
+ * @group Traffic
9773
+ */
9774
+ export declare type TrafficIncidentOverlayConfig = MapModuleCommonConfig & {
9775
+ /**
9776
+ * Initial visibility of all incident layers. Defaults to `true`.
9777
+ * `show()` never flips this flag — if `false`, the module loads data but
9778
+ * keeps layers hidden until `setVisible(true)` is called.
9779
+ */
9780
+ visible?: boolean;
9781
+ /**
9782
+ * Position incident layers before this map-style layer. Pass `'top'` to
9783
+ * pin them above every other layer. Defaults to `'lowestLabel'`, which
9784
+ * keeps incidents below map labels (roads, places, POIs) so labels stay
9785
+ * readable — the same default the routing, analytics, and geometries
9786
+ * modules use.
9787
+ */
9788
+ beforeLayerConfig?: BeforeLayerConfig;
9789
+ /**
9790
+ * Visual treatment for {@link TrafficIncidentOverlayModule.setFocus}.
9791
+ *
9792
+ * - Omit (or `undefined`) — use the SDK default treatment: a black outline
9793
+ * beneath the focused stripe and a `1.6×` width pop.
9794
+ * - `false` — disable the visual treatment. `setFocus(ids)` still writes
9795
+ * MapLibre `feature-state.focused`, so callers can drive their own
9796
+ * styling (extra layers, sidebar overlays, …) off that state.
9797
+ * - `{ outlineColor?, widthScale? }` — override individual fields of the
9798
+ * default treatment.
9799
+ */
9800
+ focus?: false | IncidentFocusStyle;
9801
+ };
9802
+
9803
+ /**
9804
+ * Renders traffic incidents returned by `trafficIncidentDetails()` on the map.
9805
+ *
9806
+ * Use this module when you fetch incidents via the Incident Details service and want
9807
+ * to display them as a developer-controlled overlay. {@link TrafficIncidentsModule} is
9808
+ * the vector-tile alternative — hidden in the default style, so the overlay renders
9809
+ * on its own without collision; if you've enabled it elsewhere in your app, hide it
9810
+ * again before using the overlay to avoid double-rendering.
9811
+ *
9812
+ * ## Rendering approach
9813
+ *
9814
+ * 7–8 layers — 4 to 5 line (optional focus-halo, outline, solid inner, direction chevron,
9815
+ * pattern inner) and 3 symbol (incident marker, jam marker with delay text, closed-road
9816
+ * marker). Per-magnitude styling uses match expressions on `magnitudeOfDelay` inside a
9817
+ * single layer instead of one layer per magnitude. Colours are read from the loaded style
9818
+ * at init (see {@link ./util/readIncidentPalette}), falling back to built-in defaults when
9819
+ * absent. Direction is rendered as a tiled `line-pattern` (chevron sprite registered at
9820
+ * init) instead of the vector-tile module's per-feature `roads-arrow` symbol — the
9821
+ * pattern is continuous, so it reads on short jams and at planning zooms (z12+) where
9822
+ * the per-feature symbol only activates at z15+.
9823
+ *
9824
+ * ## Focus
9825
+ *
9826
+ * {@link setFocus} writes MapLibre feature-state `focused=true|false` on each rendered
9827
+ * incident. The default visual treatment widens the focused subset and paints a black
9828
+ * outline beneath it; unfocused incidents are unchanged. Override or disable the visual
9829
+ * treatment via the `focus` config — `focus: false` keeps `setFocus` writing feature-state
9830
+ * but emits no halo layer and no width pop, leaving callers free to drive their own
9831
+ * styling off `feature-state.focused`.
9832
+ *
9833
+ * ## API limitations
9834
+ *
9835
+ * The Incident Details REST API returns a feature list, not a rendering-ready tile.
9836
+ * Several tags that the vector-tile pipeline injects per-feature are absent:
9837
+ *
9838
+ * - **Road classification** (`road_category`, `road_subcategory`) — the vector-tile
9839
+ * pipeline scales line width and offset by road class (motorway wider than street,
9840
+ * stripe placed alongside the road on one carriageway). Without it, per-road-class
9841
+ * geometry becomes a guess: we render every incident as a uniform stripe centred on
9842
+ * the road, no offset.
9843
+ * - **Traffic-direction side** (`left_hand_traffic`) — only meaningful when paired with
9844
+ * road-class-driven offset; irrelevant here.
9845
+ * - **Declutter priority** (`display_class`) — the vector-tile pipeline hides
9846
+ * low-priority incidents at low zooms; we show everything above the layer minzoom.
9847
+ * - **Endpoint restriction** (`point_type`) — the vector-tile pipeline limits jam and
9848
+ * closed-road icons to line endpoints; we render on every matching feature.
9849
+ * - **Secondary cause** (`icon_category_1`) — the vector-tile pipeline layers a cause
9850
+ * icon (e.g. accident) over the jam icon; we show only the primary category.
9851
+ *
9852
+ * Callers wanting full per-road-class visual fidelity should use
9853
+ * {@link TrafficIncidentsModule} instead.
9854
+ *
9855
+ * ## Known limitations
9856
+ *
9857
+ * - **Overlapping incidents** — when multiple incidents share the same point or stack
9858
+ * along the same road segment, MapLibre's symbol collision culling keeps only the
9859
+ * highest-sort-key feature. Culled features are also invisible to
9860
+ * `queryRenderedFeatures`, so hover and click cannot reach them. If you need to
9861
+ * surface multiple incidents at one location, query the source data directly
9862
+ * (the `FeatureCollection` you passed to {@link show}) rather than relying on
9863
+ * render-time hit-testing.
9864
+ *
9865
+ * @example
9866
+ * Fetch and render incidents for Amsterdam:
9867
+ * ```typescript
9868
+ * import { TomTomConfig } from '@tomtom-org/maps-sdk/core';
9869
+ * import { TomTomMap, TrafficIncidentOverlayModule } from '@tomtom-org/maps-sdk/map';
9870
+ * import { trafficIncidentDetails } from '@tomtom-org/maps-sdk/services';
9871
+ *
9872
+ * TomTomConfig.instance.put({ apiKey: '<API_KEY>' });
9873
+ *
9874
+ * const map = new TomTomMap({ mapLibre: { container: 'map', center: [4.9, 52.37], zoom: 13 } });
9875
+ *
9876
+ * const overlay = await TrafficIncidentOverlayModule.get(map);
9877
+ * const result = await trafficIncidentDetails({
9878
+ * bbox: [4.85, 52.34, 4.95, 52.40],
9879
+ * timeValidityFilter: ['present'],
9880
+ * });
9881
+ * await overlay.show(result);
9882
+ *
9883
+ * // Highlight a subset.
9884
+ * overlay.setFocus([result.features[0].id as string]);
9885
+ * ```
9886
+ *
9887
+ * @see {@link TrafficIncidentsModule} — the vector-tile alternative. Hidden in the
9888
+ * default style; if you've enabled it explicitly elsewhere in your app, hide it again
9889
+ * before using the overlay to avoid double-rendering.
9890
+ * @see [Traffic Incident Overlay Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/traffic-incident-overlay)
9891
+ * @see [Traffic Incident Details Service](https://docs.tomtom.com/maps-sdk-js/guides/services/traffic/traffic-incident-details)
9892
+ *
9893
+ * @group Traffic
9894
+ */
9895
+ export declare class TrafficIncidentOverlayModule extends AbstractMapModule<Sources, TrafficIncidentOverlayConfig> {
9896
+ private static lastInstanceIndex;
9897
+ private lastResult;
9898
+ private lastFeatureIds;
9899
+ private lastFocusIds;
9900
+ private readonly shownFeaturesHandlers;
9901
+ static get(tomtomMap: TomTomMap, config?: TrafficIncidentOverlayConfig): Promise<TrafficIncidentOverlayModule>;
9902
+ private constructor();
9903
+ /** @ignore */
9904
+ protected _initSourcesWithLayers(config?: TrafficIncidentOverlayConfig): Sources;
9905
+ /** @ignore */
9906
+ protected _applyConfig(config: TrafficIncidentOverlayConfig | undefined): TrafficIncidentOverlayConfig | undefined;
9907
+ private applyBeforeLayer;
9908
+ /** @ignore */
9909
+ protected restoreDataAndConfigImpl(): void;
9910
+ /**
9911
+ * Render the service result. Replaces any previously shown snapshot.
9912
+ */
9913
+ show(result: TrafficIncidentDetails): Promise<void>;
9914
+ /**
9915
+ * Remove all rendered incidents (source kept, data emptied).
9916
+ */
9917
+ clear(): Promise<void>;
9918
+ /**
9919
+ * Show or hide all incident layers.
9920
+ */
9921
+ setVisible(visible: boolean): void;
9922
+ /**
9923
+ * Whether any incident layer is currently visible.
9924
+ */
9925
+ isVisible(): boolean;
9926
+ /**
9927
+ * Move incident layers before the given map-style layer, or to the top.
9928
+ */
9929
+ moveBeforeLayer(beforeLayerConfig: BeforeLayerConfig): void;
9930
+ /**
9931
+ * Incidents currently rendered in the viewport.
9932
+ */
9933
+ getShown(): {
9934
+ incidents: TrafficIncident[];
9935
+ };
9936
+ /**
9937
+ * Reduce a hit-test result (typically the `features` argument in a click handler) to the
9938
+ * distinct incidents drawn at that point. Each incident renders across multiple layers
9939
+ * (outline + inner + symbol), so `queryRenderedFeatures` returns several entries per
9940
+ * incident — this de-duplicates by feature id.
9941
+ */
9942
+ distinctIncidents(features: readonly MapGeoJSONFeature[]): TrafficIncident[];
9943
+ get events(): CombinedEvents<TrafficIncident, TrafficIncidentOverlayConfig, TrafficIncidentDetails>;
9944
+ /**
9945
+ * Mark a subset of currently-rendered incidents as "focused" via MapLibre
9946
+ * feature-state. `null` clears the state. Paint expressions in
9947
+ * `incidentDetailsLayers.ts` read `['feature-state', 'focused']` and pop the
9948
+ * focused subset (wider stripe + black outline). Unfocused features are
9949
+ * unchanged — the focus treatment adds emphasis, it does not dim the rest.
9950
+ *
9951
+ * No effect if called before `show()`.
9952
+ */
9953
+ setFocus(ids: readonly string[] | null): void;
9954
+ private clearFeatureState;
9955
+ private findSourceFeature;
9956
+ }
9957
+
9527
9958
  /**
9528
9959
  * Filter configuration for traffic incidents visualization.
9529
9960
  *
@@ -9723,6 +10154,10 @@ export declare type TrafficIncidentsFilters = {
9723
10154
  *
9724
10155
  * @see [Traffic Incidents Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/traffic-incidents)
9725
10156
  * @see [Traffic Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/traffic)
10157
+ * @see {@link TrafficIncidentOverlayModule} — for rendering incidents fetched via the
10158
+ * `trafficIncidentDetails()` REST service as a developer-controlled overlay (use the
10159
+ * overlay when you need typed incident objects in app code; this vector-tile module
10160
+ * remains the recommended default for visual fidelity).
9726
10161
  *
9727
10162
  * @group Traffic Incidents
9728
10163
  */
@@ -9880,6 +10315,7 @@ export declare class TrafficIncidentsModule extends AbstractMapModule<TrafficInc
9880
10315
  * ```
9881
10316
  */
9882
10317
  setIconsVisible(visible: boolean): void;
10318
+ private _setIconsVisible;
9883
10319
  /**
9884
10320
  * Sets the visibility of all traffic incident layers.
9885
10321
  *
@@ -10013,11 +10449,22 @@ declare type TrafficIncidentsSourcesWithLayers = {
10013
10449
  trafficIncidents: StyleSourceWithLayers;
10014
10450
  };
10015
10451
 
10452
+ /**
10453
+ * @ignore
10454
+ */
10455
+ export declare const UNKNOWN_DELAY_BG_COLOR = "#C7D2D8";
10456
+
10016
10457
  /**
10017
10458
  * @ignore
10018
10459
  */
10019
10460
  export declare const UNKNOWN_DELAY_COLOR = "#000000";
10020
10461
 
10462
+ /**
10463
+ * Dashed-line color for `magnitudeOfDelay === 'unknown'` (rendered as a red dashed overlay).
10464
+ * @ignore
10465
+ */
10466
+ export declare const UNKNOWN_DELAY_DASH_COLOR = "rgba(190, 39, 27, 1)";
10467
+
10021
10468
  /**
10022
10469
  * Handler function for user interaction events on map features.
10023
10470
  *