@tomtom-org/maps-sdk 0.51.5 → 0.53.0

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.
@@ -1,4 +1,4 @@
1
- import { BackgroundLayerSpecification, CircleLayerSpecification, DataDrivenPropertyValueSpecification, ExpressionFilterSpecification, ExpressionSpecification, GeoJSONSource, GeoJSONSourceSpecification, LayerSpecification, LegacyFilterSpecification, LineLayerSpecification, LngLat, Map, MapGeoJSONFeature, MapOptions, Source, SourceSpecification, StyleImageInterface, StyleImageMetadata, StyleSpecification, SymbolLayerSpecification } from "maplibre-gl";
1
+ import { BackgroundLayerSpecification, CircleLayerSpecification, DataDrivenPropertyValueSpecification, ExpressionSpecification, GeoJSONSource, GeoJSONSourceSpecification, LayerSpecification, LineLayerSpecification, LngLat, Map, MapGeoJSONFeature, MapOptions, Source, SourceSpecification, StyleImageInterface, StyleImageMetadata, StyleSpecification, SymbolLayerSpecification } from "maplibre-gl";
2
2
  import { Anything, AreaAnalyticsMetricKey, AreaAnalyticsMetrics, BBox, ChargingSpeed, ChargingStop, CommonPlaceProps, DelayMagnitude, DisplayUnits, GetPositionEntryPointOption, GlobalConfig, Instruction, Language, POICategory, Place, Places, PolygonFeature, PolygonFeatures, Route, RouteProps, Routes, SectionProps, TrafficAreaAnalytics, TrafficIncident, TrafficIncidentBaseProperties, TrafficIncidentCategory, TrafficIncidentDetails, TrafficIncidentTimeValidity, TrafficSectionProps, Waypoint, WaypointLike, Waypoints } from "@tomtom-org/maps-sdk/core";
3
3
  //#region src/init/types/mapEventsConfig.d.ts
4
4
  /**
@@ -192,6 +192,15 @@ type MapEventsConfig = EventHandlerCursorConfig & {
192
192
  longHoverDelayOnStillMapMS?: number;
193
193
  };
194
194
  //#endregion
195
+ //#region src/shared/types/style.d.ts
196
+ /**
197
+ * Indicator of a light or dark theme.
198
+ * * Can be used to classify a map style as light or dark, or to apply light or dark configurations to map modules if they support it.
199
+ *
200
+ * @group Map Style
201
+ */
202
+ type LightDark = 'light' | 'dark';
203
+ //#endregion
195
204
  //#region src/init/types/mapInit.d.ts
196
205
  /**
197
206
  * Array of all available standard style identifiers.
@@ -230,7 +239,7 @@ type MapEventsConfig = EventHandlerCursorConfig & {
230
239
  *
231
240
  * @group Map Style
232
241
  */
233
- declare const standardStyleIDs: readonly ["standardLight", "standardDark", "drivingLight", "drivingDark", "monoLight", "monoDark", "satellite"];
242
+ export declare const standardStyleIDs: readonly ["standardLight", "standardDark", "drivingLight", "drivingDark", "monoLight", "monoDark", "satellite"];
234
243
  /**
235
244
  * Identifier for a TomTom-hosted standard map style.
236
245
  *
@@ -254,7 +263,7 @@ declare const standardStyleIDs: readonly ["standardLight", "standardDark", "driv
254
263
  *
255
264
  * @group Map Style
256
265
  */
257
- type StandardStyleID = (typeof standardStyleIDs)[number];
266
+ export type StandardStyleID = (typeof standardStyleIDs)[number];
258
267
  /**
259
268
  * Configuration for a TomTom standard map style.
260
269
  *
@@ -282,7 +291,7 @@ type StandardStyleID = (typeof standardStyleIDs)[number];
282
291
  *
283
292
  * @group Map Style
284
293
  */
285
- type StandardStyle = {
294
+ export type StandardStyle = {
286
295
  /**
287
296
  * Standard style identifier.
288
297
  *
@@ -362,7 +371,7 @@ type StandardStyle = {
362
371
  *
363
372
  * @group Map Style
364
373
  */
365
- type CustomStyle = {
374
+ export type CustomStyle = {
366
375
  /**
367
376
  * URL to a MapLibre/Mapbox style JSON.
368
377
  *
@@ -397,13 +406,34 @@ type CustomStyle = {
397
406
  * ```
398
407
  */
399
408
  json?: StyleSpecification;
409
+ /**
410
+ * Whether the style draws a light or a dark map.
411
+ *
412
+ * Overlays that are drawn on top of the style — places, routes, waypoint labels, the pin
413
+ * sprite — pick their colours from this, so that their text stays legible on the canvas
414
+ * underneath. {@link TomTomMap.styleLightDarkTheme} reports the value in effect.
415
+ *
416
+ * Leave it out and the SDK reads the theme off the loaded style, from the colour its
417
+ * `background` layer paints the canvas with. Set it when that guess is wrong or when you
418
+ * would rather not depend on a guess: a style whose canvas is hidden behind full-coverage
419
+ * imagery, or one whose background colour does not represent what the map ends up looking
420
+ * like.
421
+ *
422
+ * @default Read from the background colour of the loaded style, falling back to `'light'`
423
+ *
424
+ * @example
425
+ * ```typescript
426
+ * style: { type: 'custom', url: 'https://example.com/midnight.json', lightDarkTheme: 'dark' }
427
+ * ```
428
+ */
429
+ lightDarkTheme?: LightDark;
400
430
  };
401
431
  /**
402
432
  * Array of all available style modules.
403
433
  *
404
434
  * @group Map Style
405
435
  */
406
- declare const styleModules: readonly ["trafficIncidents", "trafficFlow", "hillshade"];
436
+ export declare const styleModules: readonly ["trafficIncidents", "trafficFlow", "hillshade"];
407
437
  /**
408
438
  * Optional map modules that can be included with a style.
409
439
  *
@@ -414,7 +444,7 @@ declare const styleModules: readonly ["trafficIncidents", "trafficFlow", "hillsh
414
444
  *
415
445
  * @group Map Style
416
446
  */
417
- type StyleModule = (typeof styleModules)[number];
447
+ export type StyleModule = (typeof styleModules)[number];
418
448
  /**
419
449
  * Map style specification for initialization.
420
450
  *
@@ -454,7 +484,7 @@ type StyleModule = (typeof styleModules)[number];
454
484
  *
455
485
  * @group Map Style
456
486
  */
457
- type StyleInput = StandardStyleID | (StandardStyle & {
487
+ export type StyleInput = StandardStyleID | (StandardStyle & {
458
488
  type: 'standard';
459
489
  }) | (CustomStyle & {
460
490
  type: 'custom';
@@ -476,7 +506,7 @@ type StyleInput = StandardStyleID | (StandardStyle & {
476
506
  *
477
507
  * @group Map
478
508
  */
479
- type MapLibreOptions = Omit<MapOptions, 'style' | 'attributionControl'>;
509
+ export type MapLibreOptions = Omit<MapOptions, 'style' | 'attributionControl'>;
480
510
  /**
481
511
  * Parameters for initializing a TomTom map instance.
482
512
  *
@@ -502,7 +532,7 @@ type MapLibreOptions = Omit<MapOptions, 'style' | 'attributionControl'>;
502
532
  *
503
533
  * @group Map
504
534
  */
505
- type TomTomMapParams = Partial<GlobalConfig> & {
535
+ export type TomTomMapParams = Partial<GlobalConfig> & {
506
536
  /**
507
537
  * Map style to load.
508
538
  *
@@ -569,7 +599,7 @@ type TomTomMapParams = Partial<GlobalConfig> & {
569
599
  *
570
600
  * @ignore
571
601
  */
572
- type InternalTomTomMapParams = GlobalConfig & TomTomMapParams;
602
+ export type InternalTomTomMapParams = GlobalConfig & TomTomMapParams;
573
603
  //#endregion
574
604
  //#region src/TomTomMap.d.ts
575
605
  /**
@@ -612,27 +642,83 @@ type InternalTomTomMapParams = GlobalConfig & TomTomMapParams;
612
642
  *
613
643
  * @group Map Style
614
644
  */
615
- type StyleChangeHandler = {
645
+ export type StyleChangeHandler = {
616
646
  /**
617
647
  * Callback invoked immediately before a style change begins.
618
648
  *
619
649
  * @remarks
620
650
  * Use this to perform cleanup or save state before the current style is removed.
621
- * This method can be synchronous or asynchronous.
651
+ * This method can be synchronous or asynchronous: the SDK awaits it before handing the new
652
+ * style to MapLibre, so nothing of the old style is torn down while it runs.
622
653
  *
654
+ * @param context - What kind of switch is happening; see {@link StyleChangeContext}.
623
655
  * @returns void or a Promise that resolves when preparation is complete
624
656
  */
625
- onStyleAboutToChange?: () => void | Promise<void>;
657
+ onStyleAboutToChange?: (context: StyleChangeContext) => void | Promise<void>;
626
658
  /**
627
659
  * Callback invoked after a new style has been fully loaded.
628
660
  *
629
661
  * @remarks
630
662
  * Use this to restore state, reinitialize layers, or perform other setup
631
- * that depends on the new style being ready. This method can be synchronous or asynchronous.
663
+ * that depends on the new style being ready. This method can be synchronous or asynchronous:
664
+ * handlers run one after the other, in registration order, and the promise returned by
665
+ * {@link TomTomMap.setStyle} resolves only once the last one has finished.
632
666
  *
667
+ * @param context - What kind of switch is happening; see {@link StyleChangeContext}.
633
668
  * @returns void or a Promise that resolves when reinitialization is complete
634
669
  */
635
- onStyleChanged?: () => void | Promise<void>;
670
+ onStyleChanged?: (context: StyleChangeContext) => void | Promise<void>;
671
+ };
672
+ /**
673
+ * What a {@link StyleChangeHandler} is told about the style switch it is reacting to.
674
+ *
675
+ * @remarks
676
+ * The SDK's own modules read `resetState` to decide between restoring themselves (data, config,
677
+ * filters) onto the new style, or re-binding to it with defaults and nothing shown. Your handlers
678
+ * get the same information, so a custom overlay can make the same choice.
679
+ *
680
+ * @example
681
+ * ```typescript
682
+ * map.addStyleChangeHandler({
683
+ * onStyleChanged: ({ resetState }) => {
684
+ * if (resetState) dropCustomLayers();
685
+ * else reattachCustomLayers();
686
+ * },
687
+ * });
688
+ * ```
689
+ *
690
+ * @group Map Style
691
+ */
692
+ export type StyleChangeContext = {
693
+ /**
694
+ * `true` for a clean switch (`setStyle(style, { resetState: true })`), `false` when the switch
695
+ * carries SDK state over (`setStyle(style)` or `setStyle(style, { resetState: false })`).
696
+ */
697
+ resetState: boolean;
698
+ };
699
+ /**
700
+ * Options accepted by {@link TomTomMap.setStyle}.
701
+ *
702
+ * @group Map Style
703
+ */
704
+ export type SetStyleOptions = {
705
+ /**
706
+ * Whether to drop the SDK state instead of carrying it over to the new style.
707
+ *
708
+ * - `false` (default): module data and configuration, filters and the style parts of the
709
+ * previous style (traffic, hillshade) are restored onto the new style.
710
+ * - `true`: a clean switch. Modules re-bind to the new style with default configuration and
711
+ * nothing shown, and only the style parts named in the new style input are loaded.
712
+ *
713
+ * The map language is not SDK state: it is re-applied in both cases, and only
714
+ * {@link TomTomMap.setLanguage} changes it.
715
+ *
716
+ * Registered {@link StyleChangeHandler}s run in both cases and receive the value in their
717
+ * {@link StyleChangeContext}.
718
+ *
719
+ * @default false
720
+ */
721
+ resetState?: boolean;
636
722
  };
637
723
  /**
638
724
  * Main TomTom Map class for displaying interactive maps in web applications.
@@ -699,7 +785,7 @@ type StyleChangeHandler = {
699
785
  *
700
786
  * @group Map
701
787
  */
702
- declare class TomTomMap {
788
+ export declare class TomTomMap {
703
789
  /**
704
790
  * Indicates whether the map style has been fully loaded and is ready for interaction.
705
791
  *
@@ -754,7 +840,7 @@ declare class TomTomMap {
754
840
  * });
755
841
  * ```
756
842
  *
757
- * @see {@link https://maplibre.org/maplibre-gl-js-docs/api/map/ | MapLibre Map Documentation}
843
+ * @see {@link https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/ | MapLibre Map Documentation}
758
844
  */
759
845
  readonly mapLibreMap: Map;
760
846
  /**
@@ -765,8 +851,32 @@ declare class TomTomMap {
765
851
  * @ignore
766
852
  */
767
853
  _params: InternalTomTomMapParams;
768
- styleLightDarkTheme: LightDark;
854
+ /**
855
+ * Whether the loaded style draws a light or a dark map.
856
+ *
857
+ * @remarks
858
+ * The SDK's own overlays read it to pick text and halo colours that stay legible over the
859
+ * base map, and it is the property to bind your own UI to rather than parsing the style ID.
860
+ *
861
+ * A standard style is classified from its ID. A custom style reads `'light'` until it has
862
+ * loaded — nothing about it is known before that — and is then classified from the colour its
863
+ * `background` layer paints the canvas with; a custom style with no readable background colour
864
+ * stays `'light'`. So read it inside an
865
+ * {@link TomTomMap.addStyleChangeHandler | onStyleChanged} handler, or after awaiting
866
+ * {@link setStyle}, rather than right after calling it.
867
+ *
868
+ * @example
869
+ * ```typescript
870
+ * await map.setStyle({ type: 'custom', url: 'https://example.com/my-style.json' });
871
+ * document.body.classList.toggle('dark-mode', map.styleLightDarkTheme === 'dark');
872
+ * ```
873
+ */
874
+ get styleLightDarkTheme(): LightDark;
875
+ private _styleLightDarkTheme;
769
876
  private readonly styleChangeHandlers;
877
+ private styleGivenToMapLibre;
878
+ private styleRequestSequence;
879
+ private styleLoadInFlight;
770
880
  /**
771
881
  * Constructs a new TomTom Map instance and attaches it to a DOM element.
772
882
  *
@@ -830,9 +940,9 @@ declare class TomTomMap {
830
940
  *
831
941
  * @see {@link MapLibreOptions}
832
942
  * @see {@link TomTomMapParams}
833
- * @see {@link https://maplibre.org/maplibre-gl-js-docs/api/map/ | MapLibre Map Parameters}
943
+ * @see {@link https://maplibre.org/maplibre-gl-js/docs/API/classes/Map/ | MapLibre Map Parameters}
834
944
  * @see [Map Quickstart Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/quickstart)
835
- * @see [Map Styles Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/map-styles)
945
+ * @see [Map Styles Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/styles)
836
946
  * @see [User Interaction Events Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/user-events)
837
947
  */
838
948
  constructor(mapParams: TomTomMapParams);
@@ -845,27 +955,35 @@ declare class TomTomMap {
845
955
  * Changes the map style dynamically without reloading the entire map.
846
956
  *
847
957
  * @param style - The new style to apply. Can be a string ID or a detailed style configuration.
848
- * @param options - Configuration options for the style change behavior.
849
- * @param options.keepState - Whether to preserve SDK-rendered items and configurations when changing styles.
850
- * When `true` (default), maintains traffic layers, routes, markers, and other SDK features.
851
- * When `false`, performs a clean style switch without preserving previous state.
958
+ * @param options - Configuration options for the style change behavior, see {@link SetStyleOptions}.
959
+ * @returns A promise that resolves once the new style is loaded and every registered
960
+ * {@link StyleChangeHandler} has finished — including the SDK modules restoring themselves.
961
+ * Awaiting it is optional; it is the moment after which the map is safe to read and draw on again.
962
+ * @throws If the style itself fails to load, leaving {@link mapReady} `false` and the map on
963
+ * the style it had. A tile or source that fails to load does not fail the switch.
852
964
  *
853
965
  * @remarks
854
- * **Behavior:**
855
- * - Temporarily sets {@link mapReady} to `false` during the transition
856
- * - Triggers all registered {@link StyleChangeHandler} callbacks
857
- * - Resets {@link mapReady} to `true` when the new style is fully loaded
858
- *
859
- * **State Preservation (keepState: true):**
966
+ * **Carried-over state (the default):**
860
967
  * - Merges style parts from the previous style with the new one
861
- * - Maintains SDK module layers (traffic, routes, POIs, etc.)
862
- * - Preserves language settings
968
+ * - Restores SDK module data and configuration (traffic, routes, POIs, etc.)
863
969
  *
864
- * **Clean Switch (keepState: false):**
865
- * - Applies the new style without merging previous configuration
866
- * - Removes all SDK module layers
970
+ * **Clean switch (resetState: true):**
971
+ * - Applies exactly the style you passed, without merging previous style parts
972
+ * - SDK modules re-bind to the new style with default configuration and nothing shown
867
973
  * - Useful for complete style resets
868
974
  *
975
+ * Both keep the map language: it is configuration, not state, and it survives every style
976
+ * change until {@link setLanguage} changes it.
977
+ *
978
+ * **Behavior:**
979
+ * - Sets {@link mapReady} to `false` for the duration of the transition
980
+ * - Awaits every `onStyleAboutToChange` handler, then hands the new style to MapLibre
981
+ * - Once the style has loaded, sets {@link mapReady} back to `true` and awaits every
982
+ * `onStyleChanged` handler in registration order
983
+ * - A `setStyle` call made while another one is still in flight supersedes it: the older
984
+ * call's style is never applied and its promise resolves as soon as that is known
985
+ * - Passing the style already loaded runs the whole lifecycle without reloading it, which is
986
+ * how `resetState: true` doubles as a reset of the SDK modules over the current style
869
987
  * @example
870
988
  * Simple style change:
871
989
  * ```typescript
@@ -874,6 +992,13 @@ declare class TomTomMap {
874
992
  * ```
875
993
  *
876
994
  * @example
995
+ * Wait for the switch to complete before drawing on the map:
996
+ * ```typescript
997
+ * await map.setStyle('standardDark');
998
+ * // modules have restored themselves; map.mapReady is true again
999
+ * ```
1000
+ *
1001
+ * @example
877
1002
  * Style change with detailed configuration:
878
1003
  * ```typescript
879
1004
  * map.setStyle({
@@ -887,7 +1012,7 @@ declare class TomTomMap {
887
1012
  * Clean style switch without state preservation:
888
1013
  * ```typescript
889
1014
  * // Complete reset - removes all SDK layers and modules
890
- * map.setStyle('standardDark', { keepState: false });
1015
+ * map.setStyle('standardDark', { resetState: true });
891
1016
  * ```
892
1017
  *
893
1018
  * @example
@@ -908,11 +1033,13 @@ declare class TomTomMap {
908
1033
  * @see {@link TomTomMapParams.style} - For setting style during initialization
909
1034
  * @see {@link StyleChangeHandler} - For handling style change events
910
1035
  * @see {@link getStyle} - For retrieving the current style
911
- * @see [Map Styles Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/map-styles)
1036
+ * @see [Map Styles Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/styles)
912
1037
  */
913
- setStyle: (style: StyleInput, options?: {
914
- keepState?: boolean;
915
- }) => void;
1038
+ setStyle: (style: StyleInput, options?: SetStyleOptions) => Promise<void>;
1039
+ private applyStyle;
1040
+ private loadIntoMapLibre;
1041
+ private isSuperseded;
1042
+ private notifyHandlers;
916
1043
  /**
917
1044
  * Retrieves the current style configuration of the map.
918
1045
  *
@@ -986,7 +1113,9 @@ declare class TomTomMap {
986
1113
  * - When using locale codes (with `-`), only the language portion is used for labels
987
1114
  *
988
1115
  * **Persistence:**
989
- * - Language setting persists across style changes (when `keepState: true`)
1116
+ * - The language persists across every style change, a clean switch
1117
+ * ({@link SetStyleOptions.resetState}) included: it is map configuration rather than SDK
1118
+ * state, and this method is the only thing that changes it
990
1119
  * - Set during initialization via {@link TomTomMapParams.language} for immediate application
991
1120
  *
992
1121
  * @example
@@ -1022,7 +1151,7 @@ declare class TomTomMap {
1022
1151
  /**
1023
1152
  * Retrieves the current visible map area as a GeoJSON bounding box.
1024
1153
  *
1025
- * @returns A {@link https://tools.ietf.org/html/rfc7946#section-5 | GeoJSON BBox} array
1154
+ * @returns A {@link https://datatracker.ietf.org/doc/html/rfc7946#section-5 | GeoJSON BBox} array
1026
1155
  * in the format `[west, south, east, north]` representing the map's current viewport bounds.
1027
1156
  *
1028
1157
  * @remarks
@@ -1063,8 +1192,8 @@ declare class TomTomMap {
1063
1192
  * map.mapLibreMap.fitBounds([[west, south], [east, north]]);
1064
1193
  * ```
1065
1194
  *
1066
- * @see {@link https://tools.ietf.org/html/rfc7946#section-5 | GeoJSON BBox Specification}
1067
- * @see {@link https://maplibre.org/maplibre-gl-js-docs/api/geography/#lnglatbounds | MapLibre LngLatBounds}
1195
+ * @see {@link https://datatracker.ietf.org/doc/html/rfc7946#section-5 | GeoJSON BBox Specification}
1196
+ * @see {@link https://maplibre.org/maplibre-gl-js/docs/API/classes/LngLatBounds/ | MapLibre LngLatBounds}
1068
1197
  */
1069
1198
  getBBox(): BBox;
1070
1199
  private handleStyleData;
@@ -1092,13 +1221,16 @@ declare class TomTomMap {
1092
1221
  *
1093
1222
  * **Multiple Handlers:**
1094
1223
  * - Multiple handlers can be registered and will all be called in registration order
1224
+ * - Async callbacks are awaited one after the other; the promise returned by {@link setStyle}
1225
+ * resolves once the last one has finished
1095
1226
  * - Each handler's errors are caught independently and logged to the console
1096
1227
  * - One failing handler won't prevent others from executing
1097
1228
  *
1098
1229
  * **Important Notes:**
1099
1230
  * - Handlers are only triggered by {@link setStyle} calls, not initial map construction
1100
- * - Only called when `keepState: true` in {@link setStyle} options
1101
- * - Handlers persist for the lifetime of the TomTomMap instance
1231
+ * - Handlers run for a clean switch as well as for one that carries state over, and receive
1232
+ * which one it is in their {@link StyleChangeContext}
1233
+ * - Handlers persist for the lifetime of the TomTomMap instance unless unsubscribed
1102
1234
  *
1103
1235
  * @example
1104
1236
  * Basic usage:
@@ -1219,22 +1351,22 @@ declare class TomTomMap {
1219
1351
  * **RoutingModule** - Positions route visualizations below labels for readability:
1220
1352
  * ```typescript
1221
1353
  * // Routes appear below labels but above the base map
1222
- * const routingModule = await RoutingModule.get(map);
1354
+ * const routingModule = await RoutingModule.create(map);
1223
1355
  * // Uses mapStyleLayerIDs.lowestLabel by default
1224
1356
  * ```
1225
1357
  *
1226
1358
  * **GeometriesModule** - Configurable layer positioning for polygon areas:
1227
1359
  * ```typescript
1228
1360
  * // Default: below labels
1229
- * const geometriesModule = await GeometriesModule.get(map);
1361
+ * const geometriesModule = await GeometriesModule.create(map);
1230
1362
  *
1231
1363
  * // Custom: below buildings to show at ground level
1232
- * const geometriesModule = await GeometriesModule.get(map, {
1364
+ * const geometriesModule = await GeometriesModule.create(map, {
1233
1365
  * beforeLayerConfig: 'lowestBuilding'
1234
1366
  * });
1235
1367
  *
1236
1368
  * // On top of everything
1237
- * const geometriesModule = await GeometriesModule.get(map, {
1369
+ * const geometriesModule = await GeometriesModule.create(map, {
1238
1370
  * beforeLayerConfig: 'top'
1239
1371
  * });
1240
1372
  * ```
@@ -1257,8 +1389,10 @@ declare class TomTomMap {
1257
1389
  * the corresponding reference layers in the new style, maintaining the intended visual hierarchy.
1258
1390
  *
1259
1391
  * **Important Notes:**
1260
- * - `lowestBuilding` is not available in the Satellite style
1261
- * - If a reference layer doesn't exist, custom layers will be added on top of the style
1392
+ * - `lowestRoadLine` and `lowestBuilding` are not available in the Satellite style
1393
+ * - If a reference layer doesn't exist, a module repositioning its layers puts them on top of the
1394
+ * style instead. A layer added with a `beforeID` that never appears is reported through
1395
+ * `console.error` and skipped, since a missing anchor there is usually a typo.
1262
1396
  * - Both RoutingModule and GeometriesModule default to `lowestLabel` for optimal visibility
1263
1397
  *
1264
1398
  * @see {@link GeometryBeforeLayerConfig} for GeometriesModule layer positioning options
@@ -1266,7 +1400,7 @@ declare class TomTomMap {
1266
1400
  *
1267
1401
  * @group Map Style
1268
1402
  */
1269
- declare const mapStyleLayerIDs: {
1403
+ export declare const mapStyleLayerIDs: {
1270
1404
  /**
1271
1405
  * Country name label layer.
1272
1406
  *
@@ -1312,6 +1446,8 @@ declare const mapStyleLayerIDs: {
1312
1446
  * Represents tunnel railway outlines. Use to position content below the road network,
1313
1447
  * useful for showing base layers or features that should appear beneath transportation
1314
1448
  * infrastructure.
1449
+ *
1450
+ * **Note:** Not available in the Satellite style.
1315
1451
  */
1316
1452
  readonly lowestRoadLine: "Tunnel - Railway outline";
1317
1453
  /**
@@ -1509,14 +1645,14 @@ interface FeatureCollection<G extends Geometry | null = Geometry, P = GeoJsonPro
1509
1645
  * MapLibre `MapGeoJSONFeature`s, plain GeoJSON `Feature`s, and cached originals alike.
1510
1646
  */
1511
1647
  /** Minimal shape needed to look a feature up by id. @ignore */
1512
- type RenderedRef = {
1648
+ export type RenderedRef = {
1513
1649
  id?: string | number;
1514
1650
  properties?: {
1515
1651
  id?: unknown;
1516
1652
  } | null;
1517
1653
  };
1518
1654
  /** A feature together with its index in the array it was found in. @ignore */
1519
- type IndexedFeature<F> = {
1655
+ export type IndexedFeature<F> = {
1520
1656
  feature: F;
1521
1657
  index: number;
1522
1658
  };
@@ -1532,13 +1668,13 @@ type IndexedFeature<F> = {
1532
1668
  * features that only carry a top-level id). Returns `undefined` when neither is set.
1533
1669
  * @ignore
1534
1670
  */
1535
- declare const renderedRefId: (rendered: RenderedRef) => string | number | undefined;
1671
+ export declare const renderedRefId: (rendered: RenderedRef) => string | number | undefined;
1536
1672
  /**
1537
1673
  * Find the first feature whose {@link renderedRefId} equals `id`, with its index, or
1538
1674
  * `undefined` (also for a nullish `id`).
1539
1675
  * @ignore
1540
1676
  */
1541
- declare const findFeatureByRefId: <F extends RenderedRef>(features: readonly F[], id: string | number | undefined) => IndexedFeature<F> | undefined;
1677
+ export declare const findFeatureByRefId: <F extends RenderedRef>(features: readonly F[], id: string | number | undefined) => IndexedFeature<F> | undefined;
1542
1678
  //#endregion
1543
1679
  //#region src/shared/TomTomMapSource.d.ts
1544
1680
  /**
@@ -1546,7 +1682,7 @@ declare const findFeatureByRefId: <F extends RenderedRef>(features: readonly F[]
1546
1682
  * * The source might already be initialized from the map style, or it might be initialized here.
1547
1683
  * @ignore
1548
1684
  */
1549
- declare class TomTomMapSource<SOURCE_SPEC extends SourceSpecification = SourceSpecification, RUNTIME_SOURCE extends Source = Source> {
1685
+ export declare class TomTomMapSource<SOURCE_SPEC extends SourceSpecification = SourceSpecification, RUNTIME_SOURCE extends Source = Source> {
1550
1686
  readonly id: string;
1551
1687
  readonly spec?: SOURCE_SPEC | undefined;
1552
1688
  runtimeSource?: RUNTIME_SOURCE | undefined;
@@ -1559,7 +1695,7 @@ declare class TomTomMapSource<SOURCE_SPEC extends SourceSpecification = SourceSp
1559
1695
  * Contains a source and the layers to render its data.
1560
1696
  * @ignore
1561
1697
  */
1562
- declare abstract class AbstractSourceWithLayers<SOURCE_SPEC extends SourceSpecification = SourceSpecification, RUNTIME_SOURCE extends Source = Source, LAYER_SPEC extends LayerSpecification = LayerSpecification> {
1698
+ export declare abstract class AbstractSourceWithLayers<SOURCE_SPEC extends SourceSpecification = SourceSpecification, RUNTIME_SOURCE extends Source = Source, LAYER_SPEC extends LayerSpecification = LayerSpecification> {
1563
1699
  readonly map: Map;
1564
1700
  readonly source: TomTomMapSource<SOURCE_SPEC, RUNTIME_SOURCE>;
1565
1701
  readonly _layerSpecs: LAYER_SPEC[];
@@ -1578,27 +1714,26 @@ declare abstract class AbstractSourceWithLayers<SOURCE_SPEC extends SourceSpecif
1578
1714
  private isLayerVisible;
1579
1715
  setLayersVisible(visible: boolean, filter?: LayerSpecFilter): void;
1580
1716
  get sourceAndLayerIDs(): SourceWithLayerIDs;
1581
- equalSourceAndLayerIDs(other: SourceWithLayers): boolean;
1582
1717
  }
1583
1718
  /**
1584
1719
  * @ignore
1585
1720
  * @param loadedMap
1586
1721
  * @param sourceIDs
1587
1722
  */
1588
- declare const filterLayersBySources: (loadedMap: Map, sourceIDs: string[]) => LayerSpecWithSource[];
1723
+ export declare const filterLayersBySources: (loadedMap: Map, sourceIDs: string[]) => LayerSpecWithSource[];
1589
1724
  /**
1590
1725
  * Source with layers which are coming from the downloaded TT map style.
1591
1726
  * * Examples are parts of the base map, traffic, pois, and hillshade.
1592
1727
  * @ignore
1593
1728
  */
1594
- declare class StyleSourceWithLayers<SOURCE_SPEC extends SourceSpecification = SourceSpecification, RUNTIME_SOURCE extends Source = Source> extends AbstractSourceWithLayers<SourceSpecification, RUNTIME_SOURCE> {
1729
+ export declare class StyleSourceWithLayers<SOURCE_SPEC extends SourceSpecification = SourceSpecification, RUNTIME_SOURCE extends Source = Source> extends AbstractSourceWithLayers<SourceSpecification, RUNTIME_SOURCE> {
1595
1730
  constructor(map: Map, runtimeSource: RUNTIME_SOURCE, filter?: LayerSpecFilter);
1596
1731
  }
1597
1732
  /**
1598
1733
  * Source with layers which originally is not in the map style, but it's to be added after the map is initialized.
1599
1734
  * @ignore
1600
1735
  */
1601
- declare class AddedSourceWithLayers<SOURCE_SPEC extends SourceSpecification = SourceSpecification, RUNTIME_SOURCE extends Source = Source> extends AbstractSourceWithLayers<SOURCE_SPEC, RUNTIME_SOURCE, ToBeAddedLayerSpec> {
1736
+ export declare class AddedSourceWithLayers<SOURCE_SPEC extends SourceSpecification = SourceSpecification, RUNTIME_SOURCE extends Source = Source> extends AbstractSourceWithLayers<SOURCE_SPEC, RUNTIME_SOURCE, ToBeAddedLayerSpec> {
1602
1737
  constructor(map: Map, sourceId: string, sourceSpec: SOURCE_SPEC, layerSpecs: ToBeAddedLayerSpecWithoutSource[]);
1603
1738
  private ensureLayersAddedToMap;
1604
1739
  ensureAddedToMapWithVisibility(visible: boolean, addLayersToMap: boolean): void;
@@ -1607,7 +1742,7 @@ declare class AddedSourceWithLayers<SOURCE_SPEC extends SourceSpecification = So
1607
1742
  * Options for the {@link GeoJSONSourceWithLayers.show} method.
1608
1743
  * @ignore
1609
1744
  */
1610
- type ShowOptions = {
1745
+ export type ShowOptions = {
1611
1746
  /**
1612
1747
  * When `true` (default), layer visibility is automatically set based on whether
1613
1748
  * the feature collection is non-empty. Pass `false` from state-update calls
@@ -1623,11 +1758,11 @@ type ShowOptions = {
1623
1758
  * can be configured with at construction time. Forwarded verbatim to MapLibre.
1624
1759
  * @ignore
1625
1760
  */
1626
- type GeoJSONSourceClusterOptions = Pick<GeoJSONSourceSpecification, 'cluster' | 'clusterRadius' | 'clusterMaxZoom' | 'clusterMinPoints' | 'clusterProperties'>;
1761
+ export type GeoJSONSourceClusterOptions = Pick<GeoJSONSourceSpecification, 'cluster' | 'clusterRadius' | 'clusterMaxZoom' | 'clusterMinPoints' | 'clusterProperties'>;
1627
1762
  /**
1628
1763
  * @ignore
1629
1764
  */
1630
- declare class GeoJSONSourceWithLayers<T extends FeatureCollection = FeatureCollection> extends AddedSourceWithLayers<GeoJSONSourceSpecification, GeoJSONSource> {
1765
+ export declare class GeoJSONSourceWithLayers<T extends FeatureCollection = FeatureCollection> extends AddedSourceWithLayers<GeoJSONSourceSpecification, GeoJSONSource> {
1631
1766
  shownFeatures: T;
1632
1767
  constructor(map: Map, sourceId: string, layerSpecs: ToBeAddedLayerSpecWithoutSource[], addLayersToMap?: boolean, clusterOptions?: GeoJSONSourceClusterOptions);
1633
1768
  show(featureCollection: T, { automaticVisibility }?: ShowOptions): void;
@@ -1716,6 +1851,20 @@ type SourceWithLayers = StyleSourceWithLayers | GeoJSONSourceWithLayers;
1716
1851
  type SourcesWithLayers = {
1717
1852
  [name: string]: SourceWithLayers;
1718
1853
  };
1854
+ /**
1855
+ * The sources a style-owned module controls, keyed by the name the module gives them.
1856
+ * @ignore
1857
+ */
1858
+ type StyleSourcesWithLayers = {
1859
+ [name: string]: StyleSourceWithLayers;
1860
+ };
1861
+ /**
1862
+ * The sources a data-owned module adds and owns, keyed by the name the module gives them.
1863
+ * @ignore
1864
+ */
1865
+ type GeoJSONSourcesWithLayers = {
1866
+ [name: string]: GeoJSONSourceWithLayers;
1867
+ };
1719
1868
  /**
1720
1869
  * Contains the IDs of a source and its related layers.
1721
1870
  *
@@ -2485,25 +2634,6 @@ type SVGIconStyleOptions = {
2485
2634
  outlineOpacity?: number;
2486
2635
  };
2487
2636
  //#endregion
2488
- //#region src/shared/types/mapLibreUtils.d.ts
2489
- /**
2490
- * @ignore
2491
- */
2492
- type FilterSyntaxVersion = 'expression' | 'legacy';
2493
- /**
2494
- * @ignore
2495
- */
2496
- type MultiSyntaxFilter = {
2497
- /**
2498
- * Filter expression following the new expression syntax.
2499
- */
2500
- expression: ExpressionFilterSpecification;
2501
- /**
2502
- * Filter expression following the legacy syntax.
2503
- */
2504
- legacy: LegacyFilterSpecification;
2505
- };
2506
- //#endregion
2507
2637
  //#region src/shared/types/mapModule.d.ts
2508
2638
  /**
2509
2639
  * Contains configuration options common to all map modules.
@@ -2517,438 +2647,120 @@ type MapModuleCommonConfig = {
2517
2647
  events?: EventHandlerConfig;
2518
2648
  };
2519
2649
  //#endregion
2520
- //#region src/shared/types/style.d.ts
2650
+ //#region src/shared/eventScope.d.ts
2521
2651
  /**
2522
- * Indicator of a light or dark theme.
2523
- * * Can be used to classify a map style as light or dark, or to apply light or dark configurations to map modules if they support it.
2652
+ * What `where()` accepts: a predicate over the feature type this surface exposes, or — where the
2653
+ * module defines one — its own scope object. {@link UserEvents.where} turns either into a
2654
+ * {@link ResolvedEventScope}.
2524
2655
  *
2525
- * @group Map Style
2656
+ * @typeParam T - Feature type this surface exposes, which a predicate therefore receives.
2657
+ * @typeParam WHERE_SCOPE - The module's own scope object, such as {@link BaseMapEventScope}.
2658
+ * `never` on a module that only supports predicates, leaving just the predicate arm.
2659
+ *
2660
+ * @ignore
2526
2661
  */
2527
- type LightDark = 'light' | 'dark';
2528
- //#endregion
2529
- //#region src/shared/AbstractEventProxy.d.ts
2530
- type SourceEventTypeHandler = {
2531
- sourceWithLayers: SourceWithLayers;
2532
- layerIDs: string[];
2533
- fn: UserEventHandler<any>;
2534
- config?: EventHandlerConfig;
2535
- };
2536
- type SourceEventHandlers = Partial<Record<EventType, SourceEventTypeHandler[]>>;
2537
- type EventHandlers = Record<string, SourceEventHandlers>;
2662
+ export type EventScope<T, WHERE_SCOPE> = ((feature: T) => boolean) | WHERE_SCOPE;
2538
2663
  /**
2664
+ * A scope narrowed down to the two things the event proxy can act on.
2665
+ *
2666
+ * Every public way of expressing a scope — a feature predicate, `{ layerGroups }` on
2667
+ * {@link BaseMapModule}, a module's named scope — resolves to one of these before it reaches
2668
+ * {@link AbstractEventProxy}. Both parts are optional: an unscoped handler carries neither.
2669
+ *
2539
2670
  * @ignore
2540
2671
  */
2541
- declare abstract class AbstractEventProxy {
2542
- protected interactiveLayerIDs: string[];
2543
- protected handlers: EventHandlers;
2544
- /**
2545
- * Adds the given layers as interactive, so we'll listen to them for hover and click.
2546
- * @param sourceWithLayers The sources and layers to listen to.
2547
- */
2548
- private ensureInteractiveLayerIDsAdded;
2549
- /**
2550
- * Register an event listener to the list.
2551
- * @param sourceWithLayers The sources and layers to added.
2552
- * @param handlerFn Function that will handle the event.
2553
- * @param type Type of event to listen to.
2554
- * @param config Optional configuration for the event handler.
2555
- */
2556
- addEventHandler<T = MapGeoJSONFeature>(sourceWithLayers: SourceWithLayers, handlerFn: UserEventHandler<T>, type: EventType, config: EventHandlerConfig | undefined): void;
2557
- /**
2558
- * Removes a single handler function for the given source and event type.
2559
- * Other handlers registered for the same source and type are not affected.
2560
- * Unlike {@link remove}, this does not remove the source from the interactive layer list —
2561
- * other handlers may still depend on it.
2562
- * @param sourceWithLayers The source whose handler should be removed.
2563
- * @param type The event type.
2564
- * @param handlerFn The exact function reference to remove.
2565
- */
2566
- removeHandler(sourceWithLayers: SourceWithLayers, type: EventType, handlerFn: UserEventHandler<any>): void;
2567
- /**
2568
- * Removes the given sources and layers from the interactive list. When not present, nothing happens.
2569
- * @param type The event type to be removed.
2570
- * @param sourceWithLayers The sources and layers to remove, matched by source and layer IDs.
2571
- */
2572
- remove(sourceWithLayers: SourceWithLayers, type: EventType): void;
2573
- /**
2574
- * Removes all interactive sources and layers.
2575
- */
2576
- removeAll(): void;
2672
+ export type ResolvedEventScope = {
2577
2673
  /**
2578
- * Returns whether this source is registered for events (has handlers attached).
2579
- * @param sourceId The source id (should be linked to a SourceWithLayers instance).
2674
+ * Selects which of the source's layers the handler listens to. Applied fresh whenever the
2675
+ * layer set changes, so a scope keeps meaning the same thing across style changes.
2580
2676
  */
2581
- hasSourceID(sourceId: string): boolean;
2677
+ layerFilter?: LayerSpecFilter;
2582
2678
  /**
2583
- * Look up the {@link SourceWithLayers} registered for the given source ID, if any.
2584
- *
2585
- * The SDK assumes at most one `SourceWithLayers` per MapLibre source ID — each
2586
- * module creates its own source — so any non-empty handler bucket gives us the
2587
- * right reference. We iterate event-type buckets defensively to skip transient
2588
- * empty arrays left mid-`removeHandler` before the bucket itself is deleted.
2589
- *
2590
- * NOTE: if two modules ever register against the same source ID with overlapping
2591
- * layers, this returns the first one we encounter.
2592
- */
2593
- protected sourceWithLayersFor(sourceId: string | undefined): SourceWithLayers | undefined;
2594
- /**
2595
- * Updates the given sourcesWithLayers, if they have any handlers.
2596
- * * (This is typically called to refresh any registered, stale sourceWithLayers references after a map style has changed).
2597
- * @param sourcesWithLayers The new sources with layers to replace existing ones.
2679
+ * Decides whether a rendered feature belongs to this scope. Receives the raw MapLibre
2680
+ * feature — a module's `mapping` is composed into this function at `where()` time, so the
2681
+ * caller's predicate still sees the module's own feature type.
2598
2682
  */
2599
- updateIfRegistered(sourcesWithLayers: SourcesWithLayers): void;
2600
- protected findHandlers: (types: EventType[], sourceId: string | undefined, layerId: string | undefined) => SourceEventTypeHandler[];
2601
- }
2602
- //#endregion
2603
- //#region src/shared/EventsProxy.d.ts
2683
+ featureMatches?: (feature: MapGeoJSONFeature) => boolean;
2684
+ };
2604
2685
  /**
2605
- * This is the place where we handle the user events on the map (mousemove/hover and click mostly).
2606
- * To have full control on hovers and clicks when multiple overlapping layers are present, that logic must be centralized here.
2686
+ * Combines an existing scope with a narrower one, so `where(a).where(b)` means "a and b".
2687
+ * Both axes intersect independently.
2688
+ *
2689
+ * Chaining is not a feature to reach for — two predicates read better as one `a(f) && b(f)`, and
2690
+ * layer plus feature narrowing is a single {@link BaseMapEventScope}. It exists because `where()`
2691
+ * returns a `UserEvents`, which has a `where()` of its own: without intersecting here, a second
2692
+ * call would silently replace the first and *widen* the scope.
2607
2693
  * @ignore
2608
2694
  */
2609
- declare class EventsProxy extends AbstractEventProxy {
2610
- private readonly map;
2611
- private readonly mapCanvas;
2612
- private enabled;
2613
- private hoveringLngLat?;
2614
- private hoveringPoint?;
2615
- private hoveringFeature?;
2616
- private hoveringFeatures?;
2617
- private hoveringSourceWithLayers?;
2618
- private longHoverTimeoutHandlerID?;
2619
- private firstDelayedHoverSinceMapMove;
2620
- private lastClickedFeature?;
2621
- private lastClickedSourceWithLayers?;
2622
- private lastCursorStyle;
2623
- private readonly config;
2624
- constructor(map: Map, config?: MapEventsConfig);
2625
- private listenToEvents;
2626
- enable(enabled: boolean): void;
2627
- private toPaddedBounds;
2628
- private isEnabled;
2629
- /**
2630
- * Build the consumer-facing `allEventFeatures`: scope to the firing source, dedupe, then
2631
- * substitute cached typed originals. Scope and dedupe run on the raw features, since
2632
- * `.source` and the rendered id survive only before substitution; the top hit stays first.
2633
- *
2634
- * Scoping leaves only `firingSource`'s hits, so its {@link SourceWithLayers} is resolved once
2635
- * here rather than per feature. For GeoJSON-backed sources we substitute the cached typed
2636
- * original (un-stringified properties, real Dates, nested objects); for everything else — vector
2637
- * tiles, unregistered sources — the MapLibre-rendered feature passes through (`MapGeoJSONFeature
2638
- * extends Feature`).
2639
- */
2640
- private toCallerFeatures;
2641
- private getRenderedFeatures;
2642
- private clearLongHoverTimeout;
2643
- private restartLongHoverTimeout;
2644
- private handleLongHoverTimeout;
2645
- private onMouseStart;
2646
- private onMouseOut;
2647
- private onMouseDown;
2648
- private onMouseUp;
2649
- private onMouseMove;
2650
- private updateHoverCursor;
2651
- private onMapClick;
2652
- }
2653
- //#endregion
2654
- //#region src/shared/AbstractMapModule.d.ts
2695
+ export declare const combineEventScopes: (outer: ResolvedEventScope | undefined, inner: ResolvedEventScope | undefined) => ResolvedEventScope | undefined;
2696
+ /**
2697
+ * The layer specs a scope selects out of a source, resolved against the source's *current*
2698
+ * layers. Called again on every style change so a scope never holds stale layer IDs.
2699
+ * @ignore
2700
+ */
2701
+ export declare const scopedLayerSpecs: (sourceWithLayers: SourceWithLayers, scope: ResolvedEventScope | undefined) => LayerSpecification[];
2655
2702
  /**
2656
- * Whether a map module is based on a map style or on added GeoJSON data.
2703
+ * Names a module cannot use for a named event scope, because a scope is attached as a property
2704
+ * onto the module-wide events object and would shadow one of its methods.
2705
+ * @ignore
2657
2706
  */
2658
- type MapModuleSource = 'style' | 'geojson';
2707
+ export declare const reservedScopeNames: readonly string[];
2659
2708
  /**
2660
- * Base class for all Maps SDK map modules.
2709
+ * Guards {@link reservedScopeNames}. SDK-authored scope names are covered by a unit test, but
2710
+ * {@link CustomGeoJSONModule} takes its scope names from the caller's own `sources`, so this
2711
+ * has to hold at runtime too.
2712
+ * @ignore
2713
+ */
2714
+ export declare const assertNoReservedScopeNames: (names: string[], context: string) => void;
2715
+ //#endregion
2716
+ //#region src/shared/ModuleEvents.d.ts
2717
+ /**
2718
+ * Lifecycle event module for map modules.
2661
2719
  *
2662
- * This abstract class provides the foundation for creating map modules that can display
2663
- * and manage various types of data on a TomTom map. It handles module lifecycle management,
2664
- * including initialization, configuration updates, and automatic restoration after map style changes.
2720
+ * Provides a unified API for subscribing to module-level events that are not tied
2721
+ * to user interaction with map features. Two event types are supported:
2665
2722
  *
2666
- * @remarks
2667
- * All map modules extend this class to ensure consistent behavior across the SDK.
2668
- * The class manages the module's sources, layers, and configuration, automatically
2669
- * handling map style changes by restoring the module's state when needed.
2723
+ * - `config-change`: emitted whenever the module's configuration is updated
2724
+ * (via `applyConfig`, `resetConfig`, or any module-specific setter that mutates config).
2725
+ * - `shown-features`: emitted by modules that have a `show` method, immediately after
2726
+ * features are displayed on the map.
2670
2727
  *
2671
- * @typeParam SOURCES_WITH_LAYERS - The type defining the sources and layers used by this module
2672
- * @typeParam CFG - The configuration type for this module, or undefined if no configuration is needed. When defined, must extend MapModuleCommonConfig.
2728
+ * Each `on()` call returns an unsubscribe function so individual handlers can be
2729
+ * removed without clearing the entire listener list.
2730
+ *
2731
+ * @typeParam TConfig - The module's configuration type.
2732
+ * @typeParam TShownFeatures - The type of data passed to `show()`. Use `never` for
2733
+ * modules that have no `show` method.
2673
2734
  *
2674
2735
  * @example
2675
2736
  * ```typescript
2676
- * class CustomModule extends AbstractMapModule<MySourcesWithLayers, MyConfig> {
2677
- * constructor(tomtomMap: TomTomMap, config?: MyConfig) {
2678
- * super('geojson', tomtomMap, config);
2679
- * }
2680
- * // Implement abstract methods...
2681
- * }
2737
+ * const unsubscribeConfig = trafficFlow.events.on('config-change', (config) => {
2738
+ * console.log('New config:', config);
2739
+ * });
2740
+ *
2741
+ * const unsubscribeShown = places.events.on('shown-features', (features) => {
2742
+ * console.log('Shown:', features);
2743
+ * });
2744
+ *
2745
+ * // Later:
2746
+ * unsubscribeConfig();
2747
+ * unsubscribeShown();
2682
2748
  * ```
2683
2749
  *
2684
- * @group Shared
2750
+ * @group Events
2685
2751
  */
2686
- declare abstract class AbstractMapModule<SOURCES_WITH_LAYERS extends SourcesWithLayers, CFG extends MapModuleCommonConfig | undefined = undefined> {
2687
- private readonly sourceType;
2688
- /**
2689
- * @ignore
2690
- */
2691
- protected readonly tomtomMap: TomTomMap;
2692
- /**
2693
- * @ignore
2694
- */
2695
- protected readonly eventsProxy: EventsProxy;
2696
- /**
2697
- * @ignore
2698
- */
2699
- protected readonly mapLibreMap: Map;
2700
- /**
2701
- * @ignore
2702
- */
2703
- protected sourcesWithLayers: SOURCES_WITH_LAYERS;
2704
- /**
2705
- * @ignore
2706
- */
2707
- protected _sourceAndLayerIDs: Record<keyof SOURCES_WITH_LAYERS, SourceWithLayerIDs>;
2708
- /**
2709
- * @ignore
2710
- */
2711
- protected config?: CFG;
2712
- /**
2713
- * @ignore
2714
- */
2715
- protected _initializing: boolean;
2716
- /**
2717
- * Handlers registered via events.on('config-change', …).
2718
- * Stored here so the array reference stays stable across multiple events getter calls.
2719
- * @ignore
2720
- */
2721
- protected readonly configChangeHandlers: ((config: CFG | undefined) => void)[];
2722
- /**
2723
- * Monotonically increasing index unique to this instance within its concrete module
2724
- * class. Auto-assigned in the constructor based on `new.target`, so each subclass
2725
- * has its own counter without per-subclass boilerplate. Use as a suffix on
2726
- * auto-generated source and layer IDs to keep them stable across style changes and
2727
- * unique across module instances.
2728
- * @ignore
2729
- */
2730
- protected readonly instanceIndex: number;
2731
- /**
2732
- * Per-concrete-class instance counter. WeakMap-keyed so unloaded classes can be GC'd.
2733
- * @ignore
2734
- */
2735
- private static readonly instanceCounters;
2736
- /**
2737
- * Indicates that this module is currently adding its sources and layers to the map, so during this time it might not function properly.
2738
- * @see waitUntilModuleReady
2739
- * @private
2740
- */
2741
- private moduleReady;
2742
- /**
2743
- * Builds this module based on a given Maps SDK map.
2744
- * @param tomtomMap The map. It may or may not be initialized at this stage,
2745
- * but the module ensures to initialize itself once it is.
2746
- * @param sourceType Whether the module is based on a map style or on added GeoJSON data.
2747
- * @param config Optional configuration to initialize directly as soon as the map is ready.
2748
- */
2749
- protected constructor(sourceType: MapModuleSource, tomtomMap: TomTomMap, config?: CFG);
2750
- /**
2751
- * Initializes the sources with layers of this module.
2752
- * @param config The optional configuration for the module.
2753
- * @param restore Whether we are restoring an existing module after the map style got reloaded.
2754
- * @protected
2755
- * @ignore
2756
- */
2757
- protected initSourcesWithLayers(config?: CFG, restore?: boolean): void;
2758
- /**
2759
- * Initializes the sources with layers for the specific module.
2760
- * @protected
2761
- * @ignore
2762
- */
2763
- protected abstract _initSourcesWithLayers(config?: CFG, restore?: boolean): SOURCES_WITH_LAYERS;
2764
- protected waitUntilModuleReady(): Promise<void>;
2765
- /**
2766
- * Applies a configuration to this module.
2767
- *
2768
- * This method updates the module's behavior and appearance based on the provided configuration.
2769
- * The configuration is stored internally and will be automatically reapplied if the map style changes.
2770
- *
2771
- * @param config - The configuration object to apply to the module. Pass `undefined` to reset
2772
- * the configuration to default values.
2773
- *
2774
- * @remarks
2775
- * When a configuration is applied, the module updates its visual representation and behavior
2776
- * accordingly. The configuration persists across map style changes, ensuring consistent
2777
- * module behavior even when the map's base style is modified.
2778
- *
2779
- * @example
2780
- * ```typescript
2781
- * // Apply a new configuration
2782
- * myModule.applyConfig({ visible: true, opacity: 0.8 });
2783
- *
2784
- * // Reset to default configuration
2785
- * myModule.applyConfig(undefined);
2786
- * ```
2787
- *
2788
- * @see {@link resetConfig} for a convenience method to reset configuration
2789
- * @see {@link getConfig} to retrieve the current configuration
2790
- */
2791
- applyConfig(config: CFG | undefined): void;
2792
- /**
2793
- * Emits a `config-change` event to all registered handlers.
2794
- * Skipped during module initialisation to avoid spurious events.
2795
- * @ignore
2796
- */
2797
- protected emitConfigChange(): void;
2798
- /**
2799
- * Internal implementation to apply config for the specific module.
2800
- * @param config The config to apply. this.config contains the previous configuration (if any).
2801
- * Once the method returns config, it will be assigned to this.config.
2802
- * @protected
2803
- * @ignore
2804
- */
2805
- protected abstract _applyConfig(config: CFG | undefined): CFG | undefined;
2806
- /**
2807
- * Resets the configuration of this module to its default values.
2808
- *
2809
- * This is a convenience method that clears any previously applied configuration
2810
- * and restores the module to its initial state. This is equivalent to calling
2811
- * `applyConfig(undefined)`.
2812
- *
2813
- * @remarks
2814
- * After calling this method, the module will behave as if no configuration was ever applied.
2815
- * Any custom settings, styling, or behavior modifications will be removed and replaced
2816
- * with default values.
2817
- *
2818
- * @example
2819
- * ```typescript
2820
- * // Apply some configuration
2821
- * myModule.applyConfig({ visible: true, opacity: 0.5 });
2822
- *
2823
- * // Later, reset to defaults
2824
- * myModule.resetConfig();
2825
- * ```
2826
- *
2827
- * @see {@link applyConfig} to apply a new configuration
2828
- * @see {@link getConfig} to retrieve the current configuration before resetting
2829
- */
2830
- resetConfig(): void;
2831
- private restoreDataAndConfig;
2832
- /**
2833
- * implementation needed to restore the module state (data and config applied to the module).
2834
- * to be used to restore module state after map style change
2835
- * @protected
2836
- * @ignore
2837
- */
2838
- protected restoreDataAndConfigImpl(): void;
2839
- /**
2840
- * Retrieves a copy of the current module configuration.
2841
- *
2842
- * This method returns a shallow copy of the configuration object that is currently
2843
- * applied to the module. If no configuration has been applied, it returns `undefined`.
2844
- *
2845
- * @returns A shallow copy of the current configuration object, or `undefined` if no
2846
- * configuration is currently applied. The returned object is a copy to prevent
2847
- * unintended modifications to the internal state.
2848
- *
2849
- * @remarks
2850
- * The returned configuration object is a shallow copy, which means that while the
2851
- * top-level properties are copied, any nested objects or arrays are still referenced
2852
- * from the original configuration. This is sufficient for most use cases but should
2853
- * be kept in mind when dealing with complex configurations.
2854
- *
2855
- * @example
2856
- * ```typescript
2857
- * // Apply a configuration
2858
- * myModule.applyConfig({ visible: true, opacity: 0.8 });
2859
- *
2860
- * // Later, retrieve the current configuration
2861
- * const currentConfig = myModule.getConfig();
2862
- * console.log(currentConfig); // { visible: true, opacity: 0.8 }
2863
- *
2864
- * // When no config is applied
2865
- * myModule.resetConfig();
2866
- * console.log(myModule.getConfig()); // undefined
2867
- * ```
2868
- *
2869
- * @see {@link applyConfig} to modify the configuration
2870
- * @see {@link resetConfig} to clear the configuration
2871
- */
2872
- getConfig(): NonNullable<CFG> | undefined;
2873
- /**
2874
- * Gets the source and layer identifiers for all sources managed by this module.
2875
- *
2876
- * This property provides access to the MapLibre source and layer IDs that were created
2877
- * and are managed by this module. These IDs can be used to interact directly with
2878
- * MapLibre's API or to identify which layers belong to this module.
2879
- *
2880
- * @returns A record mapping each source name to its corresponding source ID and layer IDs.
2881
- * Each entry contains the MapLibre source identifier and an array of layer identifiers
2882
- * associated with that source.
2883
- *
2884
- * @remarks
2885
- * The returned IDs are useful when you need to:
2886
- * - Directly manipulate layers using MapLibre's native API
2887
- * - Identify which layers on the map belong to this module
2888
- * - Set layer ordering or positioning relative to other layers
2889
- * - Access source or layer properties through MapLibre methods
2890
- *
2891
- * @example
2892
- * ```typescript
2893
- * const ids = myModule.sourceAndLayerIDs;
2894
- * console.log(ids);
2895
- * // {
2896
- * // mySource: {
2897
- * // sourceID: 'my-source-id',
2898
- * // layerIDs: ['layer-1', 'layer-2']
2899
- * // }
2900
- * // }
2901
- *
2902
- * // Use with MapLibre API
2903
- * const map = myModule.mapLibreMap;
2904
- * ids.mySource.layerIDs.forEach(layerId => {
2905
- * map.setLayoutProperty(layerId, 'visibility', 'visible');
2906
- * });
2907
- * ```
2908
- */
2909
- get sourceAndLayerIDs(): Record<keyof SOURCES_WITH_LAYERS, SourceWithLayerIDs>;
2910
- }
2911
- //#endregion
2912
- //#region src/shared/ModuleEvents.d.ts
2913
- /**
2914
- * Lifecycle event module for map modules.
2915
- *
2916
- * Provides a unified API for subscribing to module-level events that are not tied
2917
- * to user interaction with map features. Two event types are supported:
2918
- *
2919
- * - `config-change`: emitted whenever the module's configuration is updated
2920
- * (via `applyConfig`, `resetConfig`, or any module-specific setter that mutates config).
2921
- * - `shown-features`: emitted by modules that have a `show` method, immediately after
2922
- * features are displayed on the map.
2923
- *
2924
- * Each `on()` call returns an unsubscribe function so individual handlers can be
2925
- * removed without clearing the entire listener list.
2926
- *
2927
- * @typeParam TConfig - The module's configuration type.
2928
- * @typeParam TShownFeatures - The type of data passed to `show()`. Use `never` for
2929
- * modules that have no `show` method.
2930
- *
2931
- * @example
2932
- * ```typescript
2933
- * const unsubscribeConfig = trafficFlow.events.on('config-change', (config) => {
2934
- * console.log('New config:', config);
2935
- * });
2936
- *
2937
- * const unsubscribeShown = places.events.on('shown-features', (features) => {
2938
- * console.log('Shown:', features);
2939
- * });
2940
- *
2941
- * // Later:
2942
- * unsubscribeConfig();
2943
- * unsubscribeShown();
2944
- * ```
2945
- *
2946
- * @group Events
2947
- */
2948
- declare class ModuleEvents<TConfig, TShownFeatures = never> {
2949
- private readonly configChangeHandlers;
2950
- private readonly shownFeaturesHandlers;
2951
- constructor(configChangeHandlers: ((config: TConfig | undefined) => void)[], shownFeaturesHandlers: ((features: TShownFeatures) => void)[]);
2752
+ /**
2753
+ * `'shown-features'`, except on a module with no `show` — where `TShownFeatures` is `never` and
2754
+ * this collapses to `never`, making the overload uncallable. Without it a handler could be
2755
+ * registered for an event the module can never emit.
2756
+ *
2757
+ * @group Events
2758
+ */
2759
+ export type ShownFeaturesType<TShownFeatures> = [TShownFeatures] extends [never] ? never : 'shown-features';
2760
+ export declare class ModuleEvents<TConfig, TShownFeatures = never> {
2761
+ private readonly configChangeHandlers;
2762
+ private readonly shownFeaturesHandlers;
2763
+ constructor(configChangeHandlers: ((config: TConfig | undefined) => void)[], shownFeaturesHandlers: ((features: TShownFeatures) => void)[]);
2952
2764
  /**
2953
2765
  * Subscribe to config-change events.
2954
2766
  *
@@ -2992,7 +2804,7 @@ declare class ModuleEvents<TConfig, TShownFeatures = never> {
2992
2804
  * unsub();
2993
2805
  * ```
2994
2806
  */
2995
- on(type: 'shown-features', handler: (features: TShownFeatures) => void): () => void;
2807
+ on(type: ShownFeaturesType<TShownFeatures>, handler: (features: TShownFeatures) => void): () => void;
2996
2808
  /**
2997
2809
  * Remove **all** handlers for the given event type at once.
2998
2810
  *
@@ -3011,15 +2823,323 @@ declare class ModuleEvents<TConfig, TShownFeatures = never> {
3011
2823
  off(type: 'config-change' | 'shown-features'): void;
3012
2824
  }
3013
2825
  //#endregion
3014
- //#region src/shared/UserEvents.d.ts
2826
+ //#region src/shared/AbstractEventProxy.d.ts
3015
2827
  /**
3016
- * Event handling interface for map features.
3017
- *
3018
- * Provides a simple API for attaching and removing event handlers for user interactions
3019
- * with map features such as clicks, hovers, and context menus. Each map module (POIs, Routing,
3020
- * Places, etc.) exposes an `events` property that returns a `UserEvents` instance.
2828
+ * Any map module, whatever its sources and config. The event proxy only ever compares owners by
2829
+ * identity, so it needs no more than "some module" — but naming the class says who may own a
2830
+ * handler, which a bare `object` did not. The two type parameters are irrelevant to identity, and
2831
+ * pinning them would drag every module's concrete types through this file.
3021
2832
  *
3022
- * @typeParam T - The feature type returned in event handlers (extends MapGeoJSONFeature)
2833
+ * @ignore
2834
+ */
2835
+ type AnyMapModule = AbstractMapModule<any, any>;
2836
+ /**
2837
+ * One entry in the handler index: the caller's function plus everything dispatch needs to decide
2838
+ * whether it should fire. A caller supplies a {@link HandlerRegistration}; the proxy files this.
2839
+ *
2840
+ * Repeated `on()` calls append rather than replace, so several entries can listen to one layer and
2841
+ * all of them fire.
2842
+ *
2843
+ * @ignore
2844
+ */
2845
+ type HandlerEntry = {
2846
+ /**
2847
+ * The source the handler was registered against — **all** of its layers, not just the ones
2848
+ * this entry listens to; `layerIDs` is that narrowing.
2849
+ *
2850
+ * Kept because the handler receives it as its last argument, because a GeoJSON source can
2851
+ * substitute the caller's typed original back in for the rendered feature, and because
2852
+ * dropping by source needs its ID. Replaced wholesale on a style change.
2853
+ */
2854
+ sourceWithLayers: SourceWithLayers;
2855
+ /**
2856
+ * The layers this entry actually listens to: `sourceWithLayers`' layers narrowed by `scope`,
2857
+ * so a scoped handler holds a subset and an unscoped one holds the lot.
2858
+ *
2859
+ * It is also *where the entry is filed* — it appears in `handlers[type][layerID]` under each
2860
+ * of these — which is why a style change re-files the entry rather than just overwriting the
2861
+ * set. A Set rather than a list because a layer-scoped handler tests membership per dispatch
2862
+ * to narrow the features its caller sees, and the base map contributes ~90 layers to test
2863
+ * against.
2864
+ */
2865
+ layerIDs: Set<string>;
2866
+ /**
2867
+ * The handler to call, already wrapped by {@link UserEvents} with the module's feature mapping
2868
+ * and any `where()` predicate — so by the time dispatch reaches it, it takes the module's own
2869
+ * feature type and has already declined features outside its scope.
2870
+ */
2871
+ fn: UserEventHandler<any>;
2872
+ /** Event configuration this entry registered with — its hover cursor, chiefly. */
2873
+ config?: EventHandlerConfig;
2874
+ /**
2875
+ * The module that registered this handler. Two modules can share one MapLibre source ID —
2876
+ * POIs and the base map both use `vectorTiles` — so a style-change refresh has to tell their
2877
+ * handlers apart by owner rather than by source ID alone.
2878
+ */
2879
+ owner: AnyMapModule;
2880
+ /**
2881
+ * How the registration was narrowed, if at all. Kept alongside `layerIDs` rather than being
2882
+ * spent when it is resolved: `layerFilter` has to run again over the new layer set after a
2883
+ * style change, and `featureMatches` decides per dispatch whether this entry claims the
2884
+ * hover cursor for the feature under the pointer.
2885
+ */
2886
+ scope?: ResolvedEventScope;
2887
+ };
2888
+ /**
2889
+ * How a handler was registered: the parts of a {@link HandlerEntry} a caller supplies, as opposed
2890
+ * to the layers and source the proxy resolves for it. Grouped rather than passed as three trailing
2891
+ * arguments, so a call site names what it means instead of positioning an `undefined` config
2892
+ * before an owner.
2893
+ *
2894
+ * @ignore
2895
+ */
2896
+ type HandlerRegistration = Pick<HandlerEntry, 'config' | 'owner' | 'scope'>;
2897
+ /**
2898
+ * One event type's handlers, bucketed by the layer they listen to. Each bucket is in registration
2899
+ * order — `findHandlers()[0]` is the first one registered, which is what claims the hover cursor.
2900
+ *
2901
+ * @ignore
2902
+ */
2903
+ type HandlersByLayer = Record<string, HandlerEntry[]>;
2904
+ /**
2905
+ * Every registered handler, indexed by event type and then by the layer it listens to. A handler
2906
+ * scoped to several layers appears under each of them, so dispatch is a lookup rather than a scan:
2907
+ * a hit on `layerId` fires exactly `handlers[type][layerId]`.
2908
+ *
2909
+ * Keyed this way, the interactive-layer list is local information — a layer is interactive while
2910
+ * some type still holds a non-empty bucket for it, so releasing one costs five lookups instead of
2911
+ * a walk over every registered handler.
2912
+ *
2913
+ * @example
2914
+ * ```typescript
2915
+ * const handlers = {
2916
+ * click: {
2917
+ * 'Buildings': [{ sourceWithLayers, layerIDs: Set { 'Buildings', 'Roads' }, fn, … }],
2918
+ * 'Roads': [ …the same handler again, plus any other listening to Roads ],
2919
+ * },
2920
+ * hover: { 'Water': [ … ] },
2921
+ * contextmenu: {},
2922
+ * 'hover-move': {},
2923
+ * 'long-hover': {},
2924
+ * };
2925
+ * ```
2926
+ *
2927
+ * @ignore
2928
+ */
2929
+ type EventHandlers = Record<EventType, HandlersByLayer>;
2930
+ /**
2931
+ * @ignore
2932
+ */
2933
+ declare abstract class AbstractEventProxy {
2934
+ protected interactiveLayerIDs: string[];
2935
+ protected handlers: EventHandlers;
2936
+ /**
2937
+ * Adds the given layers as interactive, so we'll listen to them for hover and click.
2938
+ *
2939
+ * Only the layers a handler's scope actually selects are added. Marking the whole source
2940
+ * interactive would let an out-of-scope feature rendered on top shadow an in-scope one, since
2941
+ * dispatch matches on the topmost hit.
2942
+ * @param layerIDs The scoped layers to listen to.
2943
+ */
2944
+ private ensureInteractiveLayerIDsAdded;
2945
+ private releaseUnusedInteractiveLayerIDs;
2946
+ private indexHandler;
2947
+ private unindexHandlers;
2948
+ /**
2949
+ * Detaches this source's handlers that the predicate matches, then stops listening to any
2950
+ * layer none of the survivors still covers.
2951
+ *
2952
+ * The source has to be part of the match: `UserEvents.on` registers one handler function
2953
+ * across several sources and unsubscribes them one at a time, so the function alone does not
2954
+ * identify which registration to drop.
2955
+ */
2956
+ private dropHandlers;
2957
+ /**
2958
+ * Register an event listener to the list.
2959
+ * @param sourceWithLayers The sources and layers to added.
2960
+ * @param handlerFn Function that will handle the event.
2961
+ * @param type Type of event to listen to.
2962
+ * @param registration How the handler was registered — see {@link HandlerRegistration}.
2963
+ */
2964
+ addEventHandler<T = MapGeoJSONFeature>(sourceWithLayers: SourceWithLayers, handlerFn: UserEventHandler<T>, type: EventType, registration: HandlerRegistration): void;
2965
+ /**
2966
+ * Removes a single handler function for the given source and event type.
2967
+ * Other handlers registered for the same source and type are not affected.
2968
+ * @param sourceWithLayers The source whose handler should be removed.
2969
+ * @param type The event type.
2970
+ * @param handlerFn The exact function reference to remove.
2971
+ */
2972
+ removeHandler(sourceWithLayers: SourceWithLayers, type: EventType, handlerFn: UserEventHandler<any>): void;
2973
+ /**
2974
+ * Removes every handler this owner registered for the given source and event type — what
2975
+ * `events.off(type)` means. Scoped handlers go with the rest: a scope is a way of registering,
2976
+ * not a separate surface to tear down.
2977
+ *
2978
+ * Matching is by owner rather than by layer set, because two modules can share one MapLibre
2979
+ * source ID (POIs and the base map both use `vectorTiles`) and neither may drop the other's
2980
+ * handlers.
2981
+ * @param sourceWithLayers The source whose handlers should go.
2982
+ * @param type The event type to be removed.
2983
+ * @param owner The module that registered them.
2984
+ */
2985
+ remove(sourceWithLayers: SourceWithLayers, type: EventType, owner: AnyMapModule): void;
2986
+ /**
2987
+ * Removes all interactive sources and layers.
2988
+ */
2989
+ removeAll(): void;
2990
+ /**
2991
+ * Whether any handler, of any event type, listens to this layer.
2992
+ * @param layerId The layer id a rendered feature was drawn from.
2993
+ */
2994
+ hasHandlerForLayer(layerId: string): boolean;
2995
+ /**
2996
+ * Look up the {@link SourceWithLayers} a layer's handlers were registered against, if any.
2997
+ *
2998
+ * The SDK assumes at most one `SourceWithLayers` per MapLibre source ID — each module creates
2999
+ * its own source — and a layer belongs to exactly one source, so any handler listening to the
3000
+ * layer carries the right reference.
3001
+ */
3002
+ protected sourceWithLayersFor(layerId: string | undefined): SourceWithLayers | undefined;
3003
+ /**
3004
+ * Updates the given sourcesWithLayers, if they have any handlers.
3005
+ * * (This is typically called to refresh any registered, stale sourceWithLayers references after a map style has changed).
3006
+ * @param sourcesWithLayers The new sources with layers to replace existing ones.
3007
+ * @param owner The module whose sources these are. Only its own handlers are refreshed: two
3008
+ * modules can share one MapLibre source ID, so the ID alone cannot tell them apart.
3009
+ */
3010
+ updateIfRegistered(sourcesWithLayers: SourcesWithLayers, owner: AnyMapModule): void;
3011
+ /**
3012
+ * The handlers that should fire for a hit on `layerId`.
3013
+ *
3014
+ * The bucket *is* the layer, so no layer matching is needed here: a handler is filed under
3015
+ * exactly the layers its scope selects, which is what keeps a click on a POI out of the base
3016
+ * map's handler even though both register against the `vectorTiles` source.
3017
+ *
3018
+ * When a feature is supplied, handlers whose scope rejects it are dropped too — that is what
3019
+ * lets a feature-scoped handler drive its own hover cursor.
3020
+ */
3021
+ protected findHandlers: (types: EventType[], layerId: string | undefined, feature?: MapGeoJSONFeature) => HandlerEntry[];
3022
+ }
3023
+ //#endregion
3024
+ //#region src/shared/EventsProxy.d.ts
3025
+ /**
3026
+ * This is the place where we handle the user events on the map (mousemove/hover and click mostly).
3027
+ * To have full control on hovers and clicks when multiple overlapping layers are present, that logic must be centralized here.
3028
+ * @ignore
3029
+ */
3030
+ export declare class EventsProxy extends AbstractEventProxy {
3031
+ private readonly map;
3032
+ private readonly mapCanvas;
3033
+ private enabled;
3034
+ private hoveringLngLat?;
3035
+ private hoveringPoint?;
3036
+ private hoveringFeature?;
3037
+ private hoveringFeatures?;
3038
+ private hoveringSourceWithLayers?;
3039
+ private longHoverTimeoutHandlerID?;
3040
+ private firstDelayedHoverSinceMapMove;
3041
+ private lastClickedFeature?;
3042
+ private lastClickedSourceWithLayers?;
3043
+ private lastCursorStyle;
3044
+ private pendingMouseMove?;
3045
+ private mouseMoveFrameRequested;
3046
+ private readonly config;
3047
+ constructor(map: Map, config?: MapEventsConfig);
3048
+ private listenToEvents;
3049
+ enable(enabled: boolean): void;
3050
+ private toPaddedBounds;
3051
+ private isEnabled;
3052
+ /**
3053
+ * Build the consumer-facing `allEventFeatures`: scope to the firing source, dedupe, then
3054
+ * substitute cached typed originals. Scope and dedupe run on the raw features, since
3055
+ * `.source` and the rendered id survive only before substitution; the top hit stays first.
3056
+ *
3057
+ * Scoping leaves only `firingSource`'s hits, so its {@link SourceWithLayers} is resolved once
3058
+ * here rather than per feature. For GeoJSON-backed sources we substitute the cached typed
3059
+ * original (un-stringified properties, real Dates, nested objects); for everything else — vector
3060
+ * tiles, unregistered sources — the MapLibre-rendered feature passes through (`MapGeoJSONFeature
3061
+ * extends Feature`).
3062
+ */
3063
+ private toCallerFeatures;
3064
+ private callerFeaturesFor;
3065
+ private getRenderedFeatures;
3066
+ private clearLongHoverTimeout;
3067
+ private restartLongHoverTimeout;
3068
+ private handleLongHoverTimeout;
3069
+ private onMouseStart;
3070
+ private onMouseOut;
3071
+ private onMouseDown;
3072
+ private onMouseUp;
3073
+ /**
3074
+ * Mouse movement arrives far more often than the browser paints, and each pass runs a
3075
+ * `queryRenderedFeatures` — by a wide margin the most expensive thing this proxy does. Only
3076
+ * the newest position matters by the time anything is drawn, so moves are coalesced into one
3077
+ * pass per animation frame and the intermediate ones are dropped.
3078
+ *
3079
+ * Hover semantics are unaffected: `detectHoverState` compares against the previously handled
3080
+ * position, so a coalesced move is indistinguishable from the pointer having travelled
3081
+ * straight there.
3082
+ */
3083
+ private onMouseMove;
3084
+ private handleMouseMove;
3085
+ /**
3086
+ * Handles the pointer arriving on a different feature: cursor, `eventState` marker, and the
3087
+ * `hover` handlers themselves.
3088
+ * @returns the caller-facing features, if they had to be built, so `hover-move` can reuse them.
3089
+ */
3090
+ private dispatchHoverEnter;
3091
+ private dispatchHoverMove;
3092
+ private dispatchToHandlers;
3093
+ private updateHoverCursor;
3094
+ private onMapClick;
3095
+ }
3096
+ //#endregion
3097
+ //#region src/shared/UserEvents.d.ts
3098
+ /**
3099
+ * Everything {@link UserEvents} needs to register handlers for one scope of one module.
3100
+ * @ignore
3101
+ */
3102
+ export type UserEventsOptions<T, WHERE_SCOPE> = {
3103
+ eventProxy: EventsProxy;
3104
+ /**
3105
+ * The source(s) whose features this scope handles events for. Several sources back one scope
3106
+ * when they carry the same data in different display modes — hexgrid, square and heatmap in
3107
+ * {@link TrafficAreaAnalyticsModule}, clustered and unclustered places in {@link PlacesModule}.
3108
+ */
3109
+ sourcesWithLayers: SourceWithLayers[];
3110
+ /**
3111
+ * The module that owns these sources. Kept with every handler so a style-change restore can
3112
+ * tell handlers apart when two modules share one MapLibre source ID.
3113
+ */
3114
+ owner: AnyMapModule;
3115
+ /**
3116
+ * Event configuration for every handler registered through this instance — the hover cursor,
3117
+ * chiefly. A scope built by {@link UserEvents.where} inherits the module's unless `where` is
3118
+ * given one of its own, which is how two parts of one module get different cursors.
3119
+ */
3120
+ config?: EventHandlerConfig;
3121
+ /**
3122
+ * Transforms a raw {@link MapGeoJSONFeature} into the feature type `T` this scope exposes, so
3123
+ * callers receive the module's own feature shape. Applied before handlers and before any
3124
+ * {@link UserEvents.where} predicate, so a predicate also sees `T`.
3125
+ */
3126
+ mapping?: (feature: MapGeoJSONFeature) => T;
3127
+ /** The scope already applied to this instance, if it came from {@link UserEvents.where}. */
3128
+ scope?: ResolvedEventScope;
3129
+ /**
3130
+ * Turns a module-specific scope object into a {@link ResolvedEventScope}. Only modules with a
3131
+ * typed layer vocabulary supply one — today that is {@link BaseMapModule} and its layer groups.
3132
+ */
3133
+ scopeResolver?: (scope: WHERE_SCOPE) => ResolvedEventScope;
3134
+ };
3135
+ /**
3136
+ * Event handling interface for map features.
3137
+ *
3138
+ * Provides a simple API for attaching and removing event handlers for user interactions
3139
+ * with map features such as clicks, hovers, and context menus. Each map module (POIs, Routing,
3140
+ * Places, etc.) exposes an `events` property that returns a `UserEvents` instance.
3141
+ *
3142
+ * @typeParam T - The feature type returned in event handlers (extends MapGeoJSONFeature)
3023
3143
  *
3024
3144
  * @remarks
3025
3145
  * **Supported Event Types:**
@@ -3105,38 +3225,52 @@ declare class ModuleEvents<TConfig, TShownFeatures = never> {
3105
3225
  *
3106
3226
  * @group Events
3107
3227
  */
3108
- declare class UserEvents<T = MapGeoJSONFeature> {
3109
- private readonly eventProxy;
3110
- private readonly config;
3111
- /**
3112
- * Optional function that transforms a raw {@link MapGeoJSONFeature} into the
3113
- * feature type `T` exposed by the module. When provided, every feature passed (fired)
3114
- * to event handlers is first run through this function, so callers receive the
3115
- * module's own feature shape instead of the underlying MapLibre feature.
3116
- *
3117
- * When omitted, `T` defaults to `MapGeoJSONFeature` and features are forwarded
3118
- * as-is.
3119
- */
3120
- private readonly mapping?;
3228
+ export declare class UserEvents<T = MapGeoJSONFeature, WHERE_SCOPE = never> {
3121
3229
  private readonly sources;
3122
- constructor(eventProxy: EventsProxy,
3123
- /**
3124
- * The source(s) whose features this module handles events for.
3125
- * Pass an array to register handlers across multiple sources representing similar data in different display modes (e.g. hexgrid + square
3126
- * in {@link TrafficAreaAnalyticsModule}). A single value is also accepted for
3127
- * backwards compatibility.
3128
- */
3129
- sourcesWithLayers: SourceWithLayers | SourceWithLayers[], config: EventHandlerConfig | undefined,
3230
+ private readonly options;
3231
+ constructor(options: UserEventsOptions<T, WHERE_SCOPE>);
3130
3232
  /**
3131
- * Optional function that transforms a raw {@link MapGeoJSONFeature} into the
3132
- * feature type `T` exposed by the module. When provided, every feature passed (fired)
3133
- * to event handlers is first run through this function, so callers receive the
3134
- * module's own feature shape instead of the underlying MapLibre feature.
3233
+ * Narrows these events to part of what they cover, returning a {@link UserEvents} over just
3234
+ * that part.
3235
+ *
3236
+ * Two things can be narrowed. A **feature predicate** keeps only the features you care about —
3237
+ * available on every module, since only the module's own data can tell a major incident from a
3238
+ * minor one. A **layer scope** keeps only part of the map's layers; the SDK offers this where
3239
+ * a stable, typed vocabulary for those layers exists, which today means
3240
+ * {@link BaseMapModule}'s layer groups.
3241
+ *
3242
+ * A new instance, rather than this one narrowed in place: callers hold `events` and narrow it
3243
+ * more than once, and mutating would make the second `where()` mean "first AND second" while
3244
+ * leaving the surface it came from silently scoped — and its `config` overridden.
3245
+ *
3246
+ * Narrowing on both axes is one call, not two — {@link BaseMapModule}'s scope object takes a
3247
+ * `features` predicate alongside its `layerGroups`. A further `where()` does intersect with
3248
+ * this one, but two feature predicates read better as a single `a(f) && b(f)`.
3249
+ *
3250
+ * @param scope See {@link EventScope} — a predicate over this scope's feature type, or, where
3251
+ * the module supports one, a scope object such as `{ layerGroups }`.
3252
+ * @param config Event configuration for handlers registered through the returned instance.
3253
+ * Each scope can carry its own, which is how two parts of one module get different hover
3254
+ * cursors. Defaults to the configuration this instance already uses.
3255
+ *
3256
+ * @example
3257
+ * ```typescript
3258
+ * // Feature scope: only major incidents are clickable.
3259
+ * trafficIncidents.events.where((incident) => incident.properties.magnitude === 'major')
3260
+ * .on('click', showIncidentDetails);
3135
3261
  *
3136
- * When omitted, `T` defaults to `MapGeoJSONFeature` and features are forwarded
3137
- * as-is.
3262
+ * // Layer scope with its own cursor, on the base map.
3263
+ * baseMap.events
3264
+ * .where({ layerGroups: { mode: 'include', names: ['roadLabels'] } }, { cursorOnHover: 'pointer' })
3265
+ * .on('click', showRoadName);
3266
+ *
3267
+ * // A named scope, narrowed by a predicate.
3268
+ * routing.events.tunnels.where((section) => section.properties.lengthInMeters > 500)
3269
+ * .on('click', showLongTunnel);
3270
+ * ```
3138
3271
  */
3139
- mapping?: ((feature: MapGeoJSONFeature) => T) | undefined);
3272
+ where(scope: EventScope<T, WHERE_SCOPE>, config?: EventHandlerConfig): UserEvents<T, WHERE_SCOPE>;
3273
+ private resolveScope;
3140
3274
  /**
3141
3275
  * Register an event handler for user interactions with map features.
3142
3276
  *
@@ -3216,6 +3350,7 @@ declare class UserEvents<T = MapGeoJSONFeature> {
3216
3350
  * ```
3217
3351
  */
3218
3352
  on(type: EventType, handler: UserEventHandler<T>): () => void;
3353
+ private toRegisteredHandler;
3219
3354
  /**
3220
3355
  * Remove all event handlers for a specific event type.
3221
3356
  *
@@ -3302,10 +3437,18 @@ declare class UserEvents<T = MapGeoJSONFeature> {
3302
3437
  * underlying {@link ModuleEvents} instance. Each `on` call returns an unsubscribe function.
3303
3438
  * Both user and module event types are also removable in bulk via {@link off}.
3304
3439
  *
3440
+ * Named scopes, where a module has them, hang off this object as properties and are themselves
3441
+ * `CombinedEvents` — so a scope carries the lifecycle events that module actually scopes.
3442
+ * {@link where} narrows ad hoc instead, and returns a plain {@link UserEvents}: a filter you build
3443
+ * on the spot has no lifecycle of its own.
3444
+ *
3305
3445
  * @typeParam T - Feature type surfaced by user interaction handlers.
3306
3446
  * @typeParam CFG - Module configuration type passed to `config-change` handlers.
3307
3447
  * @typeParam TShown - Data type passed to `shown-features` handlers. Use `never` for
3308
3448
  * modules that have no `show` method.
3449
+ * @typeParam WHERE_SCOPE - Module-specific scope object accepted by {@link where}, in addition to a
3450
+ * feature predicate. `never` for modules that only support predicates. Unrelated to a module's
3451
+ * *named* scopes, which are properties on this object rather than an argument to it.
3309
3452
  *
3310
3453
  * @example
3311
3454
  * ```typescript
@@ -3332,10 +3475,27 @@ declare class UserEvents<T = MapGeoJSONFeature> {
3332
3475
  *
3333
3476
  * @group Events
3334
3477
  */
3335
- declare class CombinedEvents<T, CFG, TShown = never> {
3478
+ export declare class CombinedEvents<T, CFG, TShown = never, WHERE_SCOPE = never> {
3336
3479
  private readonly userEventsInstance;
3337
3480
  private readonly moduleEventsInstance;
3338
- constructor(userEventsInstance: UserEvents<T>, moduleEventsInstance: ModuleEvents<CFG, TShown>);
3481
+ constructor(userEventsInstance: UserEvents<T, WHERE_SCOPE>, moduleEventsInstance: ModuleEvents<CFG, TShown>);
3482
+ /**
3483
+ * Narrows these events to part of what they cover — see {@link UserEvents.where}.
3484
+ *
3485
+ * @param scope See {@link EventScope} — a predicate over this module's feature type, or, where
3486
+ * the module supports one, a scope object such as `{ layerGroups }` on {@link BaseMapModule}.
3487
+ * @param config Event configuration for handlers registered through the returned instance, so
3488
+ * each scope can have its own hover cursor.
3489
+ * @returns A {@link UserEvents} covering only the narrowed set. Lifecycle events stay on the
3490
+ * module (or named scope) they belong to.
3491
+ *
3492
+ * @example
3493
+ * ```typescript
3494
+ * trafficIncidents.events.where((incident) => incident.properties.magnitude === 'major')
3495
+ * .on('click', showIncidentDetails);
3496
+ * ```
3497
+ */
3498
+ where(scope: EventScope<T, WHERE_SCOPE>, config?: EventHandlerConfig): UserEvents<T, WHERE_SCOPE>;
3339
3499
  /**
3340
3500
  * Subscribe to a user interaction event (`click`, `contextmenu`, `hover`, `long-hover`).
3341
3501
  *
@@ -3390,7 +3550,7 @@ declare class CombinedEvents<T, CFG, TShown = never> {
3390
3550
  * unsub();
3391
3551
  * ```
3392
3552
  */
3393
- on(type: 'shown-features', handler: (features: TShown) => void): () => void;
3553
+ on(type: ShownFeaturesType<TShown>, handler: (features: TShown) => void): () => void;
3394
3554
  /**
3395
3555
  * Remove **all** handlers for the given event type at once.
3396
3556
  *
@@ -3412,7 +3572,506 @@ declare class CombinedEvents<T, CFG, TShown = never> {
3412
3572
  off(type: EventType | 'config-change' | 'shown-features'): void;
3413
3573
  }
3414
3574
  //#endregion
3415
- //#region src/shared/layers/commonLayerProps.d.ts
3575
+ //#region src/shared/AbstractMapModule.d.ts
3576
+ /**
3577
+ * How a module builds user events over some of its sources.
3578
+ * @ignore
3579
+ */
3580
+ type EventScopeOptions<T, WHERE_SCOPE> = {
3581
+ /** Turns a raw MapLibre feature into the feature type this scope exposes. */
3582
+ mapping?: (feature: MapGeoJSONFeature) => T;
3583
+ /** Resolves a module-specific scope object, such as BaseMapModule's `{ layerGroups }`. */
3584
+ scopeResolver?: (scope: WHERE_SCOPE) => ResolvedEventScope;
3585
+ };
3586
+ /**
3587
+ * Base class for all Maps SDK map modules.
3588
+ *
3589
+ * This abstract class provides the foundation for creating map modules that can display
3590
+ * and manage various types of data on a TomTom map. It handles module lifecycle management,
3591
+ * including initialization, configuration updates, and automatic restoration after map style changes.
3592
+ *
3593
+ * @remarks
3594
+ * All map modules extend this class to ensure consistent behavior across the SDK.
3595
+ * The class manages the module's sources, layers, and configuration, automatically
3596
+ * handling map style changes by restoring the module's state when needed.
3597
+ *
3598
+ * No module extends this class directly. Each one extends the subclass that says who owns the
3599
+ * sources and layers it controls, and therefore how its instances behave:
3600
+ *
3601
+ * - {@link AbstractDataOwnedMapModule} — the module adds and owns its own sources, layers and
3602
+ * images, suffixed per instance. Multi-instance, built with `create(map, config?)`.
3603
+ * - {@link AbstractStyleOwnedMapModule} — the module controls sources and layers the map style
3604
+ * already provides, under fixed global IDs. A shared controller, obtained with
3605
+ * `get(map, config?)`.
3606
+ *
3607
+ * @typeParam SOURCES_WITH_LAYERS - The type defining the sources and layers used by this module
3608
+ * @typeParam CFG - The configuration type for this module, or undefined if no configuration is needed. When defined, must extend MapModuleCommonConfig.
3609
+ *
3610
+ * @example
3611
+ * ```typescript
3612
+ * class CustomModule extends AbstractDataOwnedMapModule<MySourcesWithLayers, MyConfig> {
3613
+ * constructor(tomtomMap: TomTomMap, config?: MyConfig) {
3614
+ * super(tomtomMap, config);
3615
+ * }
3616
+ * // Implement abstract methods...
3617
+ * }
3618
+ * ```
3619
+ *
3620
+ * @group Shared
3621
+ */
3622
+ export declare abstract class AbstractMapModule<SOURCES_WITH_LAYERS extends SourcesWithLayers, CFG extends MapModuleCommonConfig | undefined = undefined> {
3623
+ /**
3624
+ * @ignore
3625
+ */
3626
+ protected readonly tomtomMap: TomTomMap;
3627
+ /**
3628
+ * @ignore
3629
+ */
3630
+ protected readonly eventsProxy: EventsProxy;
3631
+ /**
3632
+ * @ignore
3633
+ */
3634
+ protected readonly mapLibreMap: Map;
3635
+ /**
3636
+ * @ignore
3637
+ */
3638
+ protected sourcesWithLayers: SOURCES_WITH_LAYERS;
3639
+ /**
3640
+ * @ignore
3641
+ */
3642
+ protected _sourceAndLayerIDs: Record<keyof SOURCES_WITH_LAYERS, SourceWithLayerIDs>;
3643
+ /**
3644
+ * @ignore
3645
+ */
3646
+ protected config?: CFG;
3647
+ /**
3648
+ * @ignore
3649
+ */
3650
+ protected _initializing: boolean;
3651
+ /**
3652
+ * Handlers registered via events.on('config-change', …).
3653
+ * Stored here so the array reference stays stable across multiple events getter calls.
3654
+ * @ignore
3655
+ */
3656
+ protected readonly configChangeHandlers: ((config: CFG | undefined) => void)[];
3657
+ /**
3658
+ * Monotonically increasing index unique to this instance within its concrete module
3659
+ * class. Auto-assigned in the constructor based on `new.target`, so each subclass
3660
+ * has its own counter without per-subclass boilerplate. Use as a suffix on
3661
+ * auto-generated source and layer IDs to keep them stable across style changes and
3662
+ * unique across module instances.
3663
+ *
3664
+ * Only the data-owned modules need it, because the style-owned ones work under fixed global
3665
+ * IDs. It is assigned here all the same: this constructor already runs
3666
+ * `_initSourcesWithLayers`, which reads it, so a subclass field would be assigned too late.
3667
+ * @ignore
3668
+ */
3669
+ protected readonly instanceIndex: number;
3670
+ /**
3671
+ * Per-concrete-class instance counter. WeakMap-keyed so unloaded classes can be GC'd.
3672
+ * @ignore
3673
+ */
3674
+ private static readonly instanceCounters;
3675
+ /**
3676
+ * Indicates that this module is currently adding its sources and layers to the map, so during this time it might not function properly.
3677
+ * @see waitUntilModuleReady
3678
+ * @private
3679
+ */
3680
+ private moduleReady;
3681
+ /**
3682
+ * Builds this module based on a given Maps SDK map.
3683
+ * @param tomtomMap The map. It may or may not be initialized at this stage,
3684
+ * but the module ensures to initialize itself once it is.
3685
+ * @param config Optional configuration to initialize directly as soon as the map is ready.
3686
+ */
3687
+ protected constructor(tomtomMap: TomTomMap, config?: CFG);
3688
+ /**
3689
+ * Initializes the sources with layers of this module.
3690
+ * @param config The optional configuration for the module.
3691
+ * @param restore Whether we are restoring an existing module after the map style got reloaded.
3692
+ * @protected
3693
+ * @ignore
3694
+ */
3695
+ protected initSourcesWithLayers(config?: CFG, restore?: boolean): void;
3696
+ /**
3697
+ * Initializes the sources with layers for the specific module.
3698
+ * @protected
3699
+ * @ignore
3700
+ */
3701
+ protected abstract _initSourcesWithLayers(config?: CFG, restore?: boolean): SOURCES_WITH_LAYERS;
3702
+ protected waitUntilModuleReady(): Promise<void>;
3703
+ /**
3704
+ * Applies a configuration to this module.
3705
+ *
3706
+ * This method updates the module's behavior and appearance based on the provided configuration.
3707
+ * The configuration is stored internally and will be automatically reapplied if the map style changes.
3708
+ *
3709
+ * @param config - The configuration object to apply to the module. Pass `undefined` to reset
3710
+ * the configuration to default values.
3711
+ *
3712
+ * @remarks
3713
+ * When a configuration is applied, the module updates its visual representation and behavior
3714
+ * accordingly. The configuration persists across map style changes, ensuring consistent
3715
+ * module behavior even when the map's base style is modified.
3716
+ *
3717
+ * Unless a module documents otherwise, the given configuration **replaces** the current one
3718
+ * rather than being merged into it. To change one part of it, spread the current
3719
+ * configuration into the new one: `myModule.applyConfig({ ...myModule.getConfig(), theme })`.
3720
+ *
3721
+ * @example
3722
+ * ```typescript
3723
+ * // Apply a new configuration
3724
+ * myModule.applyConfig({ visible: true, opacity: 0.8 });
3725
+ *
3726
+ * // Reset to default configuration
3727
+ * myModule.applyConfig(undefined);
3728
+ * ```
3729
+ *
3730
+ * @see {@link resetConfig} for a convenience method to reset configuration
3731
+ * @see {@link getConfig} to retrieve the current configuration
3732
+ */
3733
+ applyConfig(config: CFG | undefined): void;
3734
+ /**
3735
+ * Emits a `config-change` event to all registered handlers.
3736
+ * Skipped during module initialisation to avoid spurious events.
3737
+ * @ignore
3738
+ */
3739
+ protected emitConfigChange(): void;
3740
+ /**
3741
+ * Internal implementation to apply config for the specific module.
3742
+ * @param config The config to apply. this.config contains the previous configuration (if any).
3743
+ * Once the method returns config, it will be assigned to this.config.
3744
+ * @protected
3745
+ * @ignore
3746
+ */
3747
+ protected abstract _applyConfig(config: CFG | undefined): CFG | undefined;
3748
+ /**
3749
+ * Resets the configuration of this module to its default values.
3750
+ *
3751
+ * This is a convenience method that clears any previously applied configuration
3752
+ * and restores the module to its initial state. This is equivalent to calling
3753
+ * `applyConfig(undefined)`.
3754
+ *
3755
+ * @remarks
3756
+ * After calling this method, the module will behave as if no configuration was ever applied.
3757
+ * Any custom settings, styling, or behavior modifications will be removed and replaced
3758
+ * with default values.
3759
+ *
3760
+ * @example
3761
+ * ```typescript
3762
+ * // Apply some configuration
3763
+ * myModule.applyConfig({ visible: true, opacity: 0.5 });
3764
+ *
3765
+ * // Later, reset to defaults
3766
+ * myModule.resetConfig();
3767
+ * ```
3768
+ *
3769
+ * @see {@link applyConfig} to apply a new configuration
3770
+ * @see {@link getConfig} to retrieve the current configuration before resetting
3771
+ */
3772
+ resetConfig(): void;
3773
+ private restoreDataAndConfig;
3774
+ private resetOnNewStyle;
3775
+ /**
3776
+ * Forgets whatever this module remembers beyond its configuration, so that a clean style
3777
+ * switch does not bring it back. The sources are rebuilt empty right after, so there is
3778
+ * nothing to clear on the map.
3779
+ *
3780
+ * A data-owned module always remembers something, so {@link AbstractDataOwnedMapModule} makes
3781
+ * this abstract. A style-owned module overrides it only when it keeps state of its own, such
3782
+ * as raw layer edits.
3783
+ * @protected
3784
+ * @ignore
3785
+ */
3786
+ protected discardShownData(): void;
3787
+ /**
3788
+ * implementation needed to restore the module state (data and config applied to the module).
3789
+ * to be used to restore module state after map style change
3790
+ * @protected
3791
+ * @ignore
3792
+ */
3793
+ protected restoreDataAndConfigImpl(): void;
3794
+ /**
3795
+ * Retrieves a copy of the current module configuration.
3796
+ *
3797
+ * This method returns a shallow copy of the configuration object that is currently
3798
+ * applied to the module. If no configuration has been applied, it returns `undefined`.
3799
+ *
3800
+ * @returns A shallow copy of the current configuration object, or `undefined` if no
3801
+ * configuration is currently applied. The returned object is a copy to prevent
3802
+ * unintended modifications to the internal state.
3803
+ *
3804
+ * @remarks
3805
+ * The returned configuration object is a shallow copy, which means that while the
3806
+ * top-level properties are copied, any nested objects or arrays are still referenced
3807
+ * from the original configuration. This is sufficient for most use cases but should
3808
+ * be kept in mind when dealing with complex configurations.
3809
+ *
3810
+ * @example
3811
+ * ```typescript
3812
+ * // Apply a configuration
3813
+ * myModule.applyConfig({ visible: true, opacity: 0.8 });
3814
+ *
3815
+ * // Later, retrieve the current configuration
3816
+ * const currentConfig = myModule.getConfig();
3817
+ * console.log(currentConfig); // { visible: true, opacity: 0.8 }
3818
+ *
3819
+ * // When no config is applied
3820
+ * myModule.resetConfig();
3821
+ * console.log(myModule.getConfig()); // undefined
3822
+ * ```
3823
+ *
3824
+ * @see {@link applyConfig} to modify the configuration
3825
+ * @see {@link resetConfig} to clear the configuration
3826
+ */
3827
+ getConfig(): NonNullable<CFG> | undefined;
3828
+ /**
3829
+ * Gets the source and layer identifiers for all sources managed by this module.
3830
+ *
3831
+ * This property provides access to the MapLibre source and layer IDs that were created
3832
+ * and are managed by this module. These IDs can be used to interact directly with
3833
+ * MapLibre's API or to identify which layers belong to this module.
3834
+ *
3835
+ * @returns A record mapping each source name to its corresponding source ID and layer IDs.
3836
+ * Each entry contains the MapLibre source identifier and an array of layer identifiers
3837
+ * associated with that source.
3838
+ *
3839
+ * @remarks
3840
+ * The returned IDs are useful when you need to:
3841
+ * - Directly manipulate layers using MapLibre's native API
3842
+ * - Identify which layers on the map belong to this module
3843
+ * - Set layer ordering or positioning relative to other layers
3844
+ * - Access source or layer properties through MapLibre methods
3845
+ *
3846
+ * @example
3847
+ * ```typescript
3848
+ * const ids = myModule.sourceAndLayerIDs;
3849
+ * console.log(ids);
3850
+ * // {
3851
+ * // mySource: {
3852
+ * // sourceID: 'my-source-id',
3853
+ * // layerIDs: ['layer-1', 'layer-2']
3854
+ * // }
3855
+ * // }
3856
+ *
3857
+ * // Use with MapLibre API
3858
+ * const map = myModule.mapLibreMap;
3859
+ * ids.mySource.layerIDs.forEach(layerId => {
3860
+ * map.setLayoutProperty(layerId, 'visibility', 'visible');
3861
+ * });
3862
+ * ```
3863
+ */
3864
+ get sourceAndLayerIDs(): Record<keyof SOURCES_WITH_LAYERS, SourceWithLayerIDs>;
3865
+ /**
3866
+ * User events over the named sources of this module — what every named scope is.
3867
+ *
3868
+ * `sourceNames` may list several sources when they carry the same data in different display
3869
+ * modes — clustered and unclustered places, or the hexgrid/square/heatmap trio — and missing
3870
+ * ones are skipped, so an optional source costs the caller nothing.
3871
+ *
3872
+ * A scope carries no lifecycle events: a module has one configuration and one `show` stream,
3873
+ * neither of which a scope narrows. Both live on the module's own `events`.
3874
+ * @ignore
3875
+ */
3876
+ protected userEvents<T = MapGeoJSONFeature, WHERE_SCOPE = never>(sourceNames: (keyof SOURCES_WITH_LAYERS)[], options?: EventScopeOptions<T, WHERE_SCOPE>): UserEvents<T, WHERE_SCOPE>;
3877
+ /**
3878
+ * The event surface of a module with no `show`: user events over the named sources, plus
3879
+ * `config-change`. `shown-features` is not subscribable here — `TShown` is `never`, which
3880
+ * makes the overload uncallable.
3881
+ * @ignore
3882
+ */
3883
+ protected moduleEvents<T = MapGeoJSONFeature, WHERE_SCOPE = never>(sourceNames: (keyof SOURCES_WITH_LAYERS)[], options?: EventScopeOptions<T, WHERE_SCOPE>): CombinedEvents<T, CFG, never, WHERE_SCOPE>;
3884
+ /**
3885
+ * The event surface of a module that has a `show`. `shownFeaturesHandlers` is passed
3886
+ * positionally, and must be the very array `show` iterates: handing over a throwaway would
3887
+ * accept subscriptions that can never fire.
3888
+ * @ignore
3889
+ */
3890
+ protected moduleEventsWithShown<T, TShown, WHERE_SCOPE = never>(sourceNames: (keyof SOURCES_WITH_LAYERS)[], shownFeaturesHandlers: ((features: TShown) => void)[], options?: EventScopeOptions<T, WHERE_SCOPE>): CombinedEvents<T, CFG, TShown, WHERE_SCOPE>;
3891
+ /**
3892
+ * Attaches named scopes to the module's event surface, so `events.on(...)` and
3893
+ * `events.<scope>.on(...)` live on one object.
3894
+ *
3895
+ * A module only declares scopes where it manages more than one surface; with a single source,
3896
+ * `events` already is that scope and a named alias would just duplicate it.
3897
+ *
3898
+ * The two scope type parameters are unrelated, and a module typically has one or the other:
3899
+ * `NAMED_SCOPES` is the object of scopes hung off `events` as properties (RoutingModule's
3900
+ * `mainLines`, `waypoints`, …), while `WHERE_SCOPE` is the scope object `events.where(…)`
3901
+ * accepts as an argument (BaseMapModule's `{ layerGroups }`).
3902
+ * @ignore
3903
+ */
3904
+ protected buildEvents<T, TShown, WHERE_SCOPE, NAMED_SCOPES extends object>(moduleWide: CombinedEvents<T, CFG, TShown, WHERE_SCOPE>, scopes: NAMED_SCOPES): CombinedEvents<T, CFG, TShown, WHERE_SCOPE> & NAMED_SCOPES;
3905
+ }
3906
+ //#endregion
3907
+ //#region src/shared/AbstractDataOwnedMapModule.d.ts
3908
+ /**
3909
+ * Base class for the map modules that add and own their own GeoJSON sources, layers and images:
3910
+ * places, routes, geometries, the traffic overlays and bring-your-own-data.
3911
+ *
3912
+ * @remarks
3913
+ * The module owns the data it draws. Its generated IDs therefore carry a per-instance suffix
3914
+ * (see `instanceIndex`), and the module is safely multi-instance: every `create(map, config?)`
3915
+ * call returns another module with its own sources and layers.
3916
+ *
3917
+ * Owning the data brings the duty this class states: a clean style switch must forget the data
3918
+ * the module remembers having shown, through {@link discardShownData}.
3919
+ *
3920
+ * @typeParam SOURCES_WITH_LAYERS - The GeoJSON sources, with their layers, this module owns
3921
+ * @typeParam CFG - The configuration type for this module, or undefined if no configuration is needed
3922
+ *
3923
+ * @group Shared
3924
+ */
3925
+ export declare abstract class AbstractDataOwnedMapModule<SOURCES_WITH_LAYERS extends GeoJSONSourcesWithLayers, CFG extends MapModuleCommonConfig | undefined = undefined> extends AbstractMapModule<SOURCES_WITH_LAYERS, CFG> {
3926
+ /**
3927
+ * Owning the data it draws, such a module always remembers something a clean style switch must
3928
+ * forget, so the inherited no-op becomes a duty here. A module that remembers nothing
3929
+ * implements this as a no-op, and says why.
3930
+ * @protected
3931
+ * @ignore
3932
+ */
3933
+ protected abstract discardShownData(): void;
3934
+ }
3935
+ //#endregion
3936
+ //#region src/shared/AbstractStyleOwnedMapModule.d.ts
3937
+ /**
3938
+ * Base class for the map modules that control sources and layers the loaded map style already
3939
+ * provides, under fixed global IDs: the base map, POIs, the traffic tiles and hillshade.
3940
+ *
3941
+ * @remarks
3942
+ * The style owns the data, so such a module adds no sources of its own and shows nothing by
3943
+ * itself. It changes how the parts the style provides are drawn, filtered and made visible.
3944
+ * The SDK memoizes one instance per map, obtained with `get(map, config?)`, so every handle on it
3945
+ * sees the same state.
3946
+ *
3947
+ * Because those sources and layers arrive with the style, they are in place as soon as the new
3948
+ * style is loaded, and the module re-binds to them in the same tick. That is what the base class
3949
+ * already does, so this class adds no behaviour: it names the kind, and it narrows the sources a
3950
+ * module of this kind can hold.
3951
+ *
3952
+ * @typeParam SOURCES_WITH_LAYERS - The style sources, with their layers, this module controls
3953
+ * @typeParam CFG - The configuration type for this module, or undefined if no configuration is needed
3954
+ *
3955
+ * @group Shared
3956
+ */
3957
+ export declare abstract class AbstractStyleOwnedMapModule<SOURCES_WITH_LAYERS extends StyleSourcesWithLayers, CFG extends MapModuleCommonConfig | undefined = undefined> extends AbstractMapModule<SOURCES_WITH_LAYERS, CFG> {}
3958
+ //#endregion
3959
+ //#region src/shared/layers/commonLayerProps.d.ts
3960
+ /**
3961
+ * Bold font face used in the TomTom map style.
3962
+ *
3963
+ * @remarks
3964
+ * This is the primary bold font used for prominent labels and headings in the map.
3965
+ * Use this constant when creating custom layers to maintain visual consistency with the map style.
3966
+ *
3967
+ * @example
3968
+ * ```typescript
3969
+ * import { MAP_BOLD_FONT } from '@tomtom-org/maps-sdk/map';
3970
+ *
3971
+ * const textLayer = {
3972
+ * type: 'symbol',
3973
+ * layout: {
3974
+ * 'text-font': [MAP_BOLD_FONT],
3975
+ * 'text-field': ['get', 'name']
3976
+ * }
3977
+ * };
3978
+ * ```
3979
+ *
3980
+ * @group Map Style
3981
+ */
3982
+ export declare const MAP_BOLD_FONT = "Noto-Bold";
3983
+ /**
3984
+ * Regular font face used in the TomTom map style.
3985
+ *
3986
+ * @remarks
3987
+ * This is the standard font used for most text labels on the map.
3988
+ * Use this constant when creating custom layers to maintain visual consistency with the map style.
3989
+ *
3990
+ * @example
3991
+ * ```typescript
3992
+ * import { MAP_REGULAR_FONT } from '@tomtom-org/maps-sdk/map';
3993
+ *
3994
+ * const textLayer = {
3995
+ * type: 'symbol',
3996
+ * layout: {
3997
+ * 'text-font': [MAP_REGULAR_FONT],
3998
+ * 'text-field': ['get', 'description']
3999
+ * }
4000
+ * };
4001
+ * ```
4002
+ *
4003
+ * @group Map Style
4004
+ */
4005
+ export declare const MAP_REGULAR_FONT = "Noto-Regular";
4006
+ /**
4007
+ * Medium weight font face used in the TomTom map style.
4008
+ *
4009
+ * @remarks
4010
+ * This font provides a middle ground between regular and bold weights.
4011
+ * Use this constant when creating custom layers to maintain visual consistency with the map style.
4012
+ *
4013
+ * @example
4014
+ * ```typescript
4015
+ * import { MAP_MEDIUM_FONT } from '@tomtom-org/maps-sdk/map';
4016
+ *
4017
+ * const textLayer = {
4018
+ * type: 'symbol',
4019
+ * layout: {
4020
+ * 'text-font': [MAP_MEDIUM_FONT],
4021
+ * 'text-field': ['get', 'title']
4022
+ * }
4023
+ * };
4024
+ * ```
4025
+ *
4026
+ * @group Map Style
4027
+ */
4028
+ export declare const MAP_MEDIUM_FONT = "Noto-Medium";
4029
+ /**
4030
+ * Italic font face used in the TomTom map style.
4031
+ *
4032
+ * @remarks
4033
+ * This is the italic variant used for emphasized or secondary text labels.
4034
+ * Use this constant when creating custom layers to maintain visual consistency with the map style.
4035
+ *
4036
+ * @example
4037
+ * ```typescript
4038
+ * import { MAP_ITALIC_FONT } from '@tomtom-org/maps-sdk/map';
4039
+ *
4040
+ * const textLayer = {
4041
+ * type: 'symbol',
4042
+ * layout: {
4043
+ * 'text-font': [MAP_ITALIC_FONT],
4044
+ * 'text-field': ['get', 'subtitle']
4045
+ * }
4046
+ * };
4047
+ * ```
4048
+ *
4049
+ * @group Map Style
4050
+ */
4051
+ export declare const MAP_ITALIC_FONT = "NotoSans-MediumItalic";
4052
+ /**
4053
+ * Default text size expression used in the TomTom map style.
4054
+ *
4055
+ * @remarks
4056
+ * This MapLibre expression defines zoom-dependent text sizing that scales from 12px at zoom 10
4057
+ * to 14px at zoom 16. Use this for consistent text sizing across zoom levels.
4058
+ *
4059
+ * @example
4060
+ * ```typescript
4061
+ * import { DEFAULT_TEXT_SIZE } from '@tomtom-org/maps-sdk/map';
4062
+ *
4063
+ * const textLayer = {
4064
+ * type: 'symbol',
4065
+ * layout: {
4066
+ * 'text-size': DEFAULT_TEXT_SIZE,
4067
+ * 'text-field': ['get', 'name']
4068
+ * }
4069
+ * };
4070
+ * ```
4071
+ *
4072
+ * @group Map Style
4073
+ */
4074
+ export declare const DEFAULT_TEXT_SIZE: ExpressionSpecification;
3416
4075
  /**
3417
4076
  * Array of all available font faces in the TomTom map style.
3418
4077
  *
@@ -3440,7 +4099,7 @@ declare class CombinedEvents<T, CFG, TShown = never> {
3440
4099
  *
3441
4100
  * @group Map Style
3442
4101
  */
3443
- declare const mapFonts: readonly ["Noto-Regular", "NotoSans-MediumItalic", "Noto-Bold", "Noto-Medium"];
4102
+ export declare const mapFonts: readonly ["Noto-Regular", "NotoSans-MediumItalic", "Noto-Bold", "Noto-Medium"];
3444
4103
  /**
3445
4104
  * Type representing valid font faces available in the TomTom map style.
3446
4105
  *
@@ -3480,7 +4139,7 @@ type MapFont = (typeof mapFonts)[number];
3480
4139
  *
3481
4140
  * @group POIs
3482
4141
  */
3483
- declare const POI_SOURCE_ID = "vectorTiles";
4142
+ export declare const POI_SOURCE_ID = "vectorTiles";
3484
4143
  /**
3485
4144
  * Source identifier for hillshade terrain visualization.
3486
4145
  *
@@ -3490,7 +4149,7 @@ declare const POI_SOURCE_ID = "vectorTiles";
3490
4149
  *
3491
4150
  * @group Hillshade
3492
4151
  */
3493
- declare const HILLSHADE_SOURCE_ID = "hillshade";
4152
+ export declare const HILLSHADE_SOURCE_ID = "hillshade";
3494
4153
  /**
3495
4154
  * Source identifier for base map vector tiles.
3496
4155
  *
@@ -3500,7 +4159,7 @@ declare const HILLSHADE_SOURCE_ID = "hillshade";
3500
4159
  *
3501
4160
  * @group Base Map
3502
4161
  */
3503
- declare const BASE_MAP_SOURCE_ID = "vectorTiles";
4162
+ export declare const BASE_MAP_SOURCE_ID = "vectorTiles";
3504
4163
  /**
3505
4164
  * Source identifier for traffic incidents vector tiles.
3506
4165
  *
@@ -3510,7 +4169,7 @@ declare const BASE_MAP_SOURCE_ID = "vectorTiles";
3510
4169
  *
3511
4170
  * @group Traffic Incidents
3512
4171
  */
3513
- declare const TRAFFIC_INCIDENTS_SOURCE_ID = "vectorTilesIncidents";
4172
+ export declare const TRAFFIC_INCIDENTS_SOURCE_ID = "vectorTilesIncidents";
3514
4173
  /**
3515
4174
  * Source identifier for traffic flow vector tiles.
3516
4175
  *
@@ -3520,7 +4179,27 @@ declare const TRAFFIC_INCIDENTS_SOURCE_ID = "vectorTilesIncidents";
3520
4179
  *
3521
4180
  * @group Traffic Flow
3522
4181
  */
3523
- declare const TRAFFIC_FLOW_SOURCE_ID = "vectorTilesFlow";
4182
+ export declare const TRAFFIC_FLOW_SOURCE_ID = "vectorTilesFlow";
4183
+ //#endregion
4184
+ //#region src/shared/sharedInstance.d.ts
4185
+ /**
4186
+ * Returns the shared instance of a style-owned module for this map, building it on first use.
4187
+ *
4188
+ * Style-owned modules control sources and layers the map style already provides, under fixed
4189
+ * global IDs, so a second instance would be a second controller over one piece of shared state.
4190
+ * Callers get the same instance instead — two components each asking for hillshade is reasonable
4191
+ * code, and making them hoist a shared reference would be work pushed onto them for no benefit.
4192
+ *
4193
+ * @param map The map the module belongs to.
4194
+ * @param moduleClass The concrete module class, which together with the map identifies the instance.
4195
+ * @param construct Builds the instance. Called at most once per map and class.
4196
+ * @param applyToExisting Applies the caller's configuration to an instance that already exists.
4197
+ * Omit it when the caller passed no configuration: `get(map)` is a plain accessor and must not
4198
+ * re-apply defaults over settings someone else already made.
4199
+ *
4200
+ * @ignore
4201
+ */
4202
+ export declare const sharedInstance: <MODULE>(map: TomTomMap, moduleClass: Function, construct: () => MODULE, applyToExisting?: (existing: MODULE) => void) => Promise<MODULE>;
3524
4203
  //#endregion
3525
4204
  //#region src/base/types/baseMapModuleConfig.d.ts
3526
4205
  /**
@@ -3534,11 +4213,10 @@ declare const TRAFFIC_FLOW_SOURCE_ID = "vectorTilesFlow";
3534
4213
  * style's own draw order rather than the settlement hierarchy.
3535
4214
  *
3536
4215
  * @see {@link BaseMapLayerGroupName}
3537
- * @see {@link BaseMapModuleInitConfig.layerGroupsFilter}
3538
4216
  *
3539
4217
  * @group Base Map
3540
4218
  */
3541
- declare const baseMapLayerGroupNames: readonly ["land", "water", "buildings2D", "roads", "railways", "ferries", "borders", "buildings3D", "natureLabels", "roadLabels", "roadShields", "houseNumbers", "smallerTownLabels", "stateLabels", "cityLabels", "allPlaceLabels", "capitalLabels", "countryLabels"];
4219
+ export declare const baseMapLayerGroupNames: readonly ["land", "water", "buildings2D", "roads", "railways", "ferries", "borders", "buildings3D", "natureLabels", "roadLabels", "roadShields", "houseNumbers", "smallerTownLabels", "stateLabels", "cityLabels", "allPlaceLabels", "capitalLabels", "countryLabels"];
3542
4220
  /**
3543
4221
  * Name of a base map layer group.
3544
4222
  *
@@ -3587,7 +4265,7 @@ declare const baseMapLayerGroupNames: readonly ["land", "water", "buildings2D",
3587
4265
  *
3588
4266
  * @group Base Map
3589
4267
  */
3590
- type BaseMapLayerGroupName = (typeof baseMapLayerGroupNames)[number];
4268
+ export type BaseMapLayerGroupName = (typeof baseMapLayerGroupNames)[number];
3591
4269
  /**
3592
4270
  * Layer group visibility configuration with explicit visible state.
3593
4271
  *
@@ -3613,7 +4291,7 @@ type BaseMapLayerGroupName = (typeof baseMapLayerGroupNames)[number];
3613
4291
  *
3614
4292
  * @group Base Map
3615
4293
  */
3616
- type BaseMapLayerGroupsVisibility = BaseMapLayerGroups & {
4294
+ export type BaseMapLayerGroupsVisibility = BaseMapLayerGroups & {
3617
4295
  visible: boolean;
3618
4296
  };
3619
4297
  /**
@@ -3657,7 +4335,7 @@ type BaseMapLayerGroupsVisibility = BaseMapLayerGroups & {
3657
4335
  *
3658
4336
  * @group Base Map
3659
4337
  */
3660
- type BaseMapLayerGroups = {
4338
+ export type BaseMapLayerGroups = {
3661
4339
  /**
3662
4340
  * Filter mode determining whether groups are included or excluded.
3663
4341
  *
@@ -3726,7 +4404,7 @@ type BaseMapLayerGroups = {
3726
4404
  *
3727
4405
  * @group Base Map
3728
4406
  */
3729
- type BaseMapModuleConfig = MapModuleCommonConfig & {
4407
+ export type BaseMapModuleConfig = MapModuleCommonConfig & {
3730
4408
  /**
3731
4409
  * Controls the visibility of all layers associated with this module.
3732
4410
  *
@@ -3737,9 +4415,6 @@ type BaseMapModuleConfig = MapModuleCommonConfig & {
3737
4415
  * Optional visibility configuration for specific layer groups.
3738
4416
  *
3739
4417
  * @remarks
3740
- * **Important:** The layer groups specified here must be included in the
3741
- * module (not excluded by `layerGroupsFilter` during initialization).
3742
- *
3743
4418
  * Use this to control visibility of layer groups at runtime without
3744
4419
  * reinitializing the module.
3745
4420
  *
@@ -3762,90 +4437,41 @@ type BaseMapModuleConfig = MapModuleCommonConfig & {
3762
4437
  */
3763
4438
  layerGroupsVisibility?: BaseMapLayerGroupsVisibility;
3764
4439
  };
4440
+ //#endregion
4441
+ //#region src/base/BaseMapModule.d.ts
4442
+ type BaseSourceAndLayers = {
4443
+ vectorTiles: StyleSourceWithLayers;
4444
+ };
3765
4445
  /**
3766
- * Initialization configuration for the BaseMapModule.
4446
+ * Scope accepted by `baseMap.events.where(...)`, in addition to a plain feature predicate.
3767
4447
  *
3768
- * Extends {@link BaseMapModuleConfig} with additional options available only
3769
- * during module initialization.
3770
- *
3771
- * @remarks
3772
- * **Initialization vs Runtime:**
3773
- * - `layerGroupsFilter`: Only available at init - determines which groups to load
3774
- * - `layerGroupsVisibility`: Available at init and runtime - controls visibility
3775
- *
3776
- * **Use Cases:**
3777
- * - Create minimal maps with only essential layers
3778
- * - Build custom map styles by excluding certain features
3779
- * - Optimize performance by not loading unnecessary layers
4448
+ * `layerGroups` narrows to part of the map — road labels, water, buildings — using the same
4449
+ * {@link BaseMapLayerGroupName} vocabulary as `setVisible`. `features` narrows within those
4450
+ * layers, and the two combine.
3780
4451
  *
3781
4452
  * @example
3782
4453
  * ```typescript
3783
- * // Initialize with only roads and water
3784
- * const initConfig: BaseMapModuleInitConfig = {
3785
- * layerGroupsFilter: {
3786
- * mode: 'include',
3787
- * names: ['roads', 'roadLabels', 'water', 'land']
3788
- * },
3789
- * visible: true
3790
- * };
3791
- *
3792
- * // Exclude buildings from initialization
3793
- * const noBuildingsConfig: BaseMapModuleInitConfig = {
3794
- * layerGroupsFilter: {
3795
- * mode: 'exclude',
3796
- * names: ['buildings2D', 'buildings3D', 'houseNumbers']
3797
- * }
3798
- * };
3799
- *
3800
- * // Minimal map for data overlay
3801
- * const overlayBaseConfig: BaseMapModuleInitConfig = {
3802
- * layerGroupsFilter: {
3803
- * mode: 'include',
3804
- * names: ['water', 'land', 'borders']
3805
- * },
3806
- * visible: true
3807
- * };
4454
+ * baseMap.events
4455
+ * .where({ layerGroups: { mode: 'include', names: ['roadLabels', 'roadShields'] } },
4456
+ * { cursorOnHover: 'pointer' })
4457
+ * .on('click', (feature) => showRoadName(feature.properties.name));
3808
4458
  * ```
3809
4459
  *
3810
4460
  * @group Base Map
3811
4461
  */
3812
- type BaseMapModuleInitConfig = BaseMapModuleConfig & {
3813
- /**
3814
- * Layer groups to include/exclude during module initialization.
3815
- *
3816
- * @remarks
3817
- * **One-time configuration:** This can only be set during initialization.
3818
- * Once the module is created, you cannot change which groups are loaded,
3819
- * only their visibility via `layerGroupsVisibility`.
3820
- *
3821
- * @example
3822
- * ```typescript
3823
- * // Load only essential layers
3824
- * layerGroupsFilter: {
3825
- * mode: 'include',
3826
- * names: ['land', 'water', 'roads', 'borders']
3827
- * }
3828
- *
3829
- * // Load everything except 3D buildings
3830
- * layerGroupsFilter: {
3831
- * mode: 'exclude',
3832
- * names: ['buildings3D']
3833
- * }
3834
- *
3835
- * // Minimal overlay map
3836
- * layerGroupsFilter: {
3837
- * mode: 'include',
3838
- * names: ['water', 'land']
3839
- * }
3840
- * ```
3841
- */
3842
- layerGroupsFilter?: BaseMapLayerGroups;
3843
- };
3844
- //#endregion
3845
- //#region src/base/BaseMapModule.d.ts
3846
- type BaseSourceAndLayers = {
3847
- vectorTiles: StyleSourceWithLayers;
4462
+ export type BaseMapEventScope = {
4463
+ /** Which layer groups this scope covers. */
4464
+ layerGroups: BaseMapLayerGroups;
4465
+ /** Optional further narrowing to particular features within those layers. */
4466
+ features?: (feature: MapGeoJSONFeature) => boolean;
3848
4467
  };
4468
+ /**
4469
+ * Event surface of {@link BaseMapModule}. The base map manages one source, so it has no named
4470
+ * scopes — `events` is that scope, narrowed on demand with `where()`.
4471
+ *
4472
+ * @group Base Map
4473
+ */
4474
+ export type BaseMapEvents = CombinedEvents<MapGeoJSONFeature, BaseMapModuleConfig, never, BaseMapEventScope>;
3849
4475
  /**
3850
4476
  * Base Map Module for controlling standard map layers and their visibility.
3851
4477
  *
@@ -3892,13 +4518,7 @@ type BaseSourceAndLayers = {
3892
4518
  * @example
3893
4519
  * Working with layer groups:
3894
4520
  * ```typescript
3895
- * // Show only roads and borders
3896
- * const baseMap = await BaseMapModule.get(map, {
3897
- * layerGroupsFilter: {
3898
- * mode: 'include',
3899
- * names: ['roads', 'roadLabels', 'borders']
3900
- * }
3901
- * });
4521
+ * const baseMap = await BaseMapModule.get(map);
3902
4522
  *
3903
4523
  * // Hide buildings and labels
3904
4524
  * baseMap.setVisible(false, {
@@ -3932,11 +4552,11 @@ type BaseSourceAndLayers = {
3932
4552
  * ```
3933
4553
  *
3934
4554
  * @see [Base Map Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/base-map)
3935
- * @see [Map Styles Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/map-styles)
4555
+ * @see [Map Styles Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/styles)
3936
4556
  *
3937
4557
  * @group Base Map
3938
4558
  */
3939
- declare class BaseMapModule extends AbstractMapModule<BaseSourceAndLayers, BaseMapModuleConfig> {
4559
+ export declare class BaseMapModule extends AbstractStyleOwnedMapModule<BaseSourceAndLayers, BaseMapModuleConfig> {
3940
4560
  private layersByGroup?;
3941
4561
  /**
3942
4562
  * Asynchronously retrieves a BaseMapModule instance for the given map.
@@ -3950,6 +4570,12 @@ declare class BaseMapModule extends AbstractMapModule<BaseSourceAndLayers, BaseM
3950
4570
  * @returns A promise that resolves to the initialized BaseMapModule.
3951
4571
  *
3952
4572
  * @remarks
4573
+ * **Instances:**
4574
+ * `BaseMapModule` controls the base-map source and layers the map style already provides, under
4575
+ * fixed global IDs, so every map has exactly one — a second `get()` returns the same instance.
4576
+ * To work with part of the map, name the layer groups per call: `setVisible(false, {
4577
+ * layerGroups })` for visibility, `events.where({ layerGroups })` for events.
4578
+ *
3953
4579
  * **Initialization:**
3954
4580
  * - Waits for map to be ready before creating module
3955
4581
  * - Validates that required sources exist in the map style
@@ -3957,7 +4583,6 @@ declare class BaseMapModule extends AbstractMapModule<BaseSourceAndLayers, BaseM
3957
4583
  *
3958
4584
  * **Configuration Options:**
3959
4585
  * - `visible`: Initial visibility state
3960
- * - `layerGroupsFilter`: Which layer groups to include/exclude
3961
4586
  * - `layerGroupsVisibility`: Fine-grained visibility per group
3962
4587
  *
3963
4588
  * @throws Error if the base map source is not found in the style
@@ -3973,31 +4598,20 @@ declare class BaseMapModule extends AbstractMapModule<BaseSourceAndLayers, BaseM
3973
4598
  * ```typescript
3974
4599
  * const baseMap = await BaseMapModule.get(map, {
3975
4600
  * visible: true,
3976
- * layerGroupsFilter: {
3977
- * mode: 'exclude',
3978
- * names: ['buildings3D', 'houseNumbers']
3979
- * }
3980
- * });
3981
- * ```
3982
- *
3983
- * @example
3984
- * Show only specific groups:
3985
- * ```typescript
3986
- * const baseMap = await BaseMapModule.get(map, {
3987
- * layerGroupsFilter: {
4601
+ * layerGroupsVisibility: {
3988
4602
  * mode: 'include',
3989
- * names: ['water', 'land', 'borders']
3990
- * },
3991
- * visible: true
4603
+ * names: ['buildings3D', 'houseNumbers'],
4604
+ * visible: false
4605
+ * }
3992
4606
  * });
3993
4607
  * ```
3994
4608
  */
3995
- static get(tomtomMap: TomTomMap, config?: BaseMapModuleInitConfig): Promise<BaseMapModule>;
4609
+ static get(tomtomMap: TomTomMap, config?: BaseMapModuleConfig): Promise<BaseMapModule>;
3996
4610
  private constructor();
3997
4611
  /**
3998
4612
  * @ignore
3999
4613
  */
4000
- protected _initSourcesWithLayers(config: BaseMapModuleInitConfig | undefined): {
4614
+ protected _initSourcesWithLayers(): {
4001
4615
  vectorTiles: StyleSourceWithLayers<import("maplibre-gl").SourceSpecification, import("maplibre-gl").Source>;
4002
4616
  };
4003
4617
  /**
@@ -4011,12 +4625,19 @@ declare class BaseMapModule extends AbstractMapModule<BaseSourceAndLayers, BaseM
4011
4625
  /**
4012
4626
  * Checks if any base map layers are currently visible.
4013
4627
  *
4014
- * @returns `true` if at least one base map layer is visible, `false` if all are hidden.
4628
+ * @param options - Optional settings for fine-grained control.
4629
+ * @param options.layerGroups - Ask about specific layer groups instead of all layers.
4630
+ *
4631
+ * @returns `true` if at least one of the layers asked about is visible, `false` if all are
4632
+ * hidden.
4015
4633
  *
4016
4634
  * @remarks
4017
4635
  * This checks the actual visibility state of layers in the map, not just the
4018
4636
  * module's configuration setting.
4019
4637
  *
4638
+ * Mirrors {@link setVisible}, so a group toggled through one can be read back through the
4639
+ * other — which is how a per-group control reflects the state the style actually starts in.
4640
+ *
4020
4641
  * @example
4021
4642
  * ```typescript
4022
4643
  * if (baseMap.isVisible()) {
@@ -4025,8 +4646,17 @@ declare class BaseMapModule extends AbstractMapModule<BaseSourceAndLayers, BaseM
4025
4646
  * console.log('Base map is hidden');
4026
4647
  * }
4027
4648
  * ```
4649
+ *
4650
+ * @example
4651
+ * Ask about one group:
4652
+ * ```typescript
4653
+ * // buildings3D ships hidden in most styles
4654
+ * const shown = baseMap.isVisible({ layerGroups: { mode: 'include', names: ['buildings3D'] } });
4655
+ * ```
4028
4656
  */
4029
- isVisible(): boolean;
4657
+ isVisible(options?: {
4658
+ layerGroups?: BaseMapLayerGroups;
4659
+ }): boolean;
4030
4660
  /**
4031
4661
  * Sets the visibility of base map layers.
4032
4662
  *
@@ -4142,7 +4772,7 @@ declare class BaseMapModule extends AbstractMapModule<BaseSourceAndLayers, BaseM
4142
4772
  * unsub(); // remove by returned function
4143
4773
  * ```
4144
4774
  */
4145
- get events(): CombinedEvents<MapGeoJSONFeature, BaseMapModuleConfig, never>;
4775
+ get events(): BaseMapEvents;
4146
4776
  }
4147
4777
  //#endregion
4148
4778
  //#region src/custom/types/customGeoJSONModuleConfig.d.ts
@@ -4153,7 +4783,7 @@ type DistributiveOmit<T, K extends string> = T extends unknown ? Omit<T, K> : ne
4153
4783
  *
4154
4784
  * @group Custom
4155
4785
  */
4156
- type CustomGeoJSONImageData = HTMLImageElement | ImageBitmap | ImageData | StyleImageInterface | {
4786
+ export type CustomGeoJSONImageData = HTMLImageElement | ImageBitmap | ImageData | StyleImageInterface | {
4157
4787
  width: number;
4158
4788
  height: number;
4159
4789
  data: Uint8Array | Uint8ClampedArray;
@@ -4166,7 +4796,7 @@ type CustomGeoJSONImageData = HTMLImageElement | ImageBitmap | ImageData | Style
4166
4796
  *
4167
4797
  * @group Custom
4168
4798
  */
4169
- type CustomGeoJSONImageSpec = {
4799
+ export type CustomGeoJSONImageSpec = {
4170
4800
  /**
4171
4801
  * The image data, in any format accepted by MapLibre's `addImage`. Asynchronous
4172
4802
  * sources (URLs, SVG strings) are not supported here — pre-load them and pass an
@@ -4197,7 +4827,7 @@ type CustomGeoJSONImageSpec = {
4197
4827
  *
4198
4828
  * @group Custom
4199
4829
  */
4200
- type CustomGeoJSONLayerSpec = DistributiveOmit<LayerSpecWithSource, 'source' | 'id'> & {
4830
+ export type CustomGeoJSONLayerSpec = DistributiveOmit<LayerSpecWithSource, 'source' | 'id'> & {
4201
4831
  id?: string;
4202
4832
  beforeID?: string;
4203
4833
  };
@@ -4208,7 +4838,7 @@ type CustomGeoJSONLayerSpec = DistributiveOmit<LayerSpecWithSource, 'source' | '
4208
4838
  *
4209
4839
  * @group Custom
4210
4840
  */
4211
- type CustomGeoJSONSourceSpec = {
4841
+ export type CustomGeoJSONSourceSpec = {
4212
4842
  /**
4213
4843
  * Optional MapLibre source ID. Auto-generated as
4214
4844
  * `custom-geojson-${instanceIndex}-${sourceName}` when absent.
@@ -4252,7 +4882,7 @@ type CustomGeoJSONSourceSpec = {
4252
4882
  *
4253
4883
  * @group Custom
4254
4884
  */
4255
- type CustomGeoJSONModuleConfig<TSources extends Record<string, FeatureCollection> = Record<string, FeatureCollection>> = MapModuleCommonConfig & {
4885
+ export type CustomGeoJSONModuleConfig<TSources extends Record<string, FeatureCollection> = Record<string, FeatureCollection>> = MapModuleCommonConfig & {
4256
4886
  /**
4257
4887
  * The sources, keyed by an arbitrary user-defined name, that this module manages.
4258
4888
  *
@@ -4311,7 +4941,17 @@ type CustomGeoJSONSourcesWithLayers<TSources extends Record<string, FeatureColle
4311
4941
  *
4312
4942
  * @group Custom
4313
4943
  */
4314
- type CustomGeoJSONEvents<TSources extends Record<string, FeatureCollection>> = { [K in keyof TSources]: CombinedEvents<MapGeoJSONFeature, CustomGeoJSONModuleConfig<TSources>, TSources[K]>; };
4944
+ /**
4945
+ * What `module.events.on('shown-features', ...)` receives. This module's `show` names the source
4946
+ * it writes, so the event names it too — the one module whose shown data is per source.
4947
+ *
4948
+ * @group Custom
4949
+ */
4950
+ export type CustomGeoJSONShownFeatures<TSources extends Record<string, FeatureCollection>> = { [K in keyof TSources]: {
4951
+ sourceName: K;
4952
+ data: TSources[K];
4953
+ }; }[keyof TSources];
4954
+ export type CustomGeoJSONEvents<TSources extends Record<string, FeatureCollection>> = CombinedEvents<MapGeoJSONFeature, CustomGeoJSONModuleConfig<TSources>, CustomGeoJSONShownFeatures<TSources>> & { [K in keyof TSources]: UserEvents<MapGeoJSONFeature>; };
4315
4955
  /**
4316
4956
  * Module for displaying customer-owned GeoJSON data with TomTom SDK support.
4317
4957
  *
@@ -4324,6 +4964,11 @@ type CustomGeoJSONEvents<TSources extends Record<string, FeatureCollection>> = {
4324
4964
  * this module makes no assumptions about how data is rendered — the caller passes raw
4325
4965
  * MapLibre layer specs (`circle`, `heatmap`, `fill`, `line`, `symbol`, …).
4326
4966
  *
4967
+ * @remarks
4968
+ * Because the sources and layers are caller-supplied, the module has no built-in defaults:
4969
+ * `resetConfig()` (or `applyConfig(undefined)`) returns to the configuration passed to
4970
+ * {@link CustomGeoJSONModule.create | create}, and `getConfig()` never becomes `undefined`.
4971
+ *
4327
4972
  * @typeParam TSources - A record mapping source names to the {@link FeatureCollection}
4328
4973
  * type each source carries. Pass this generic when you want type-safe `show` /
4329
4974
  * `getShown` per source.
@@ -4331,7 +4976,7 @@ type CustomGeoJSONEvents<TSources extends Record<string, FeatureCollection>> = {
4331
4976
  * @example
4332
4977
  * Single source, default generic:
4333
4978
  * ```typescript
4334
- * const module = await CustomGeoJSONModule.get(map, {
4979
+ * const module = await CustomGeoJSONModule.create(map, {
4335
4980
  * sources: {
4336
4981
  * points: {
4337
4982
  * layers: [{ type: 'circle', paint: { 'circle-radius': 4, 'circle-color': '#0a3653' } }],
@@ -4351,7 +4996,7 @@ type CustomGeoJSONEvents<TSources extends Record<string, FeatureCollection>> = {
4351
4996
  * buildings: FeatureCollection<Polygon, { name: string }>;
4352
4997
  * };
4353
4998
  *
4354
- * const module = await CustomGeoJSONModule.get<Sources>(map, {
4999
+ * const module = await CustomGeoJSONModule.create<Sources>(map, {
4355
5000
  * sources: {
4356
5001
  * heatmap: { layers: [{ type: 'heatmap', paint: { 'heatmap-radius': 12 } }] },
4357
5002
  * buildings: { layers: [{ type: 'fill', paint: { 'fill-color': '#5a5' } }] },
@@ -4367,7 +5012,7 @@ type CustomGeoJSONEvents<TSources extends Record<string, FeatureCollection>> = {
4367
5012
  * ```typescript
4368
5013
  * type Buildings = FeatureCollection<Point, { Name: string }>;
4369
5014
  *
4370
- * const module = await CustomGeoJSONModule.get<{ heatmap: Buildings; markers: Buildings }>(map, {
5015
+ * const module = await CustomGeoJSONModule.create<{ heatmap: Buildings; markers: Buildings }>(map, {
4371
5016
  * sources: {
4372
5017
  * heatmap: { layers: heatmapLayers },
4373
5018
  * markers: { layers: markerLayers },
@@ -4379,19 +5024,24 @@ type CustomGeoJSONEvents<TSources extends Record<string, FeatureCollection>> = {
4379
5024
  *
4380
5025
  * @group Custom
4381
5026
  */
4382
- declare class CustomGeoJSONModule<TSources extends Record<string, FeatureCollection> = Record<string, FeatureCollection>> extends AbstractMapModule<CustomGeoJSONSourcesWithLayers<TSources>, CustomGeoJSONModuleConfig<TSources>> {
5027
+ export declare class CustomGeoJSONModule<TSources extends Record<string, FeatureCollection> = Record<string, FeatureCollection>> extends AbstractDataOwnedMapModule<CustomGeoJSONSourcesWithLayers<TSources>, CustomGeoJSONModuleConfig<TSources>> {
4383
5028
  private resolvedSourceIDs;
4384
5029
  private resolvedLayerSpecs;
4385
5030
  private lastShown;
4386
- private shownFeaturesHandlersBySource;
5031
+ private initialConfig;
5032
+ private readonly shownFeaturesHandlers;
4387
5033
  /**
4388
5034
  * Creates a new {@link CustomGeoJSONModule} once the map is ready.
4389
5035
  *
5036
+ * `CustomGeoJSONModule` owns the sources, layers and images it adds, all suffixed per instance.
5037
+ * Every call therefore returns a **new, independent** instance, and stacking several of them on
5038
+ * one map is a supported thing to do.
5039
+ *
4390
5040
  * @param tomtomMap The TomTomMap instance.
4391
5041
  * @param config Module configuration. `sources` is required and must contain at
4392
5042
  * least one entry; each entry must have at least one layer.
4393
5043
  */
4394
- static get<TSources extends Record<string, FeatureCollection> = Record<string, FeatureCollection>>(tomtomMap: TomTomMap, config: CustomGeoJSONModuleConfig<TSources>): Promise<CustomGeoJSONModule<TSources>>;
5044
+ static create<TSources extends Record<string, FeatureCollection> = Record<string, FeatureCollection>>(tomtomMap: TomTomMap, config: CustomGeoJSONModuleConfig<TSources>): Promise<CustomGeoJSONModule<TSources>>;
4395
5045
  private constructor();
4396
5046
  /**
4397
5047
  * @ignore
@@ -4405,6 +5055,10 @@ declare class CustomGeoJSONModule<TSources extends Record<string, FeatureCollect
4405
5055
  protected _applyConfig(config: CustomGeoJSONModuleConfig<TSources> | undefined): CustomGeoJSONModuleConfig<TSources> | undefined;
4406
5056
  private updateLayersForExistingSources;
4407
5057
  private applyVisibility;
5058
+ /**
5059
+ * @ignore
5060
+ */
5061
+ protected discardShownData(): void;
4408
5062
  /**
4409
5063
  * @ignore
4410
5064
  */
@@ -4459,15 +5113,15 @@ declare class CustomGeoJSONModule<TSources extends Record<string, FeatureCollect
4459
5113
  * @example
4460
5114
  * ```typescript
4461
5115
  * module.events.buildings.on('click', (feature, lngLat) => { ... });
4462
- * module.events.heatmap.on('shown-features', (data) => { ... });
4463
- * module.events.buildings.on('config-change', (config) => { ... });
5116
+ * module.events.on('shown-features', ({ sourceName, data }) => { ... });
5117
+ * module.events.on('config-change', (config) => { ... });
4464
5118
  * ```
4465
5119
  */
4466
5120
  get events(): CustomGeoJSONEvents<TSources>;
4467
5121
  }
4468
5122
  //#endregion
4469
5123
  //#region src/geometry/layers/colorPalettes.d.ts
4470
- declare const colorPalettes: {
5124
+ export declare const colorPalettes: {
4471
5125
  warm: string[];
4472
5126
  browns: string[];
4473
5127
  cold: string[];
@@ -4483,8 +5137,15 @@ declare const colorPalettes: {
4483
5137
  fadedRainbow: string[];
4484
5138
  pastelRainbow: string[];
4485
5139
  };
4486
- type ColorPaletteOptions = keyof typeof colorPalettes;
4487
- declare const colorPaletteIDs: ColorPaletteOptions[];
5140
+ export type ColorPaletteOptions = keyof typeof colorPalettes;
5141
+ export declare const colorPaletteIDs: ColorPaletteOptions[];
5142
+ /**
5143
+ * Adapts a fill palette for the active map theme. Light themes pass through unchanged; for dark
5144
+ * themes each colour is nudged toward a mid, saturated tone — pale ramps are deepened so they read
5145
+ * against the dark base map, near-black ramps are lifted so they don't vanish.
5146
+ * @ignore
5147
+ */
5148
+ export declare const adaptPaletteForTheme: (colors: string[], lightDark: LightDark) => string[];
4488
5149
  //#endregion
4489
5150
  //#region src/geometry/types/geometryTheme.d.ts
4490
5151
  /**
@@ -4499,13 +5160,13 @@ declare const colorPaletteIDs: ColorPaletteOptions[];
4499
5160
  *
4500
5161
  * @group Geometries
4501
5162
  */
4502
- type GeometryTheme = 'filled' | 'outline' | 'inverted';
5163
+ export type GeometryTheme = 'filled' | 'outline' | 'inverted';
4503
5164
  /**
4504
5165
  * All valid {@link GeometryTheme} values.
4505
5166
  *
4506
5167
  * @group Geometries
4507
5168
  */
4508
- declare const geometryThemes: readonly ["filled", "outline", "inverted"];
5169
+ export declare const geometryThemes: readonly ["filled", "outline", "inverted"];
4509
5170
  //#endregion
4510
5171
  //#region src/geometry/types/geometriesModuleConfig.d.ts
4511
5172
  /**
@@ -4518,7 +5179,7 @@ declare const geometryThemes: readonly ["filled", "outline", "inverted"];
4518
5179
  * const fill: GeometryFillConfig = { color: '#FF5733', opacity: 0.3 };
4519
5180
  *
4520
5181
  * // Palette name
4521
- * const fill: GeometryFillConfig = { color: 'red', opacity: 0.25 };
5182
+ * const fill: GeometryFillConfig = { color: 'blues', opacity: 0.25 };
4522
5183
  *
4523
5184
  * // Data-driven color based on properties
4524
5185
  * const fill: GeometryFillConfig = {
@@ -4529,11 +5190,15 @@ declare const geometryThemes: readonly ["filled", "outline", "inverted"];
4529
5190
  *
4530
5191
  * @group Geometries
4531
5192
  */
4532
- type GeometryFillConfig = {
5193
+ export type GeometryFillConfig = {
4533
5194
  /**
4534
- * Fill color: a hex string (`'#FF5733'`), a palette name (`'red'`), or a MapLibre expression
5195
+ * Fill color: a hex string (`'#FF5733'`), a palette name (`'blues'`, see {@link colorPaletteIDs}), or a MapLibre expression
4535
5196
  * for data-driven styling (e.g. `['get', 'color']`).
4536
5197
  *
5198
+ * @remarks
5199
+ * When unset the default is theme-adaptive: `'#0A3653'` on light map styles, `'#5FA8D8'` on dark.
5200
+ * Custom styles are treated as light — pass a colour explicitly on a dark custom style.
5201
+ *
4537
5202
  * @default '#0A3653'
4538
5203
  */
4539
5204
  color?: ColorPaletteOptions | DataDrivenPropertyValueSpecification<string>;
@@ -4573,7 +5238,7 @@ type GeometryFillConfig = {
4573
5238
  *
4574
5239
  * @group Geometries
4575
5240
  */
4576
- type GeometryTextConfig = {
5241
+ export type GeometryTextConfig = {
4577
5242
  /**
4578
5243
  * Text content to display as label.
4579
5244
  *
@@ -4619,10 +5284,13 @@ type GeometryTextConfig = {
4619
5284
  *
4620
5285
  * @group Geometries
4621
5286
  */
4622
- type GeometryLineConfig = {
5287
+ export type GeometryLineConfig = {
4623
5288
  /**
4624
5289
  * Border/outline color: a hex string or a MapLibre expression (e.g. `['get', 'borderColor']`).
4625
5290
  *
5291
+ * @remarks
5292
+ * When unset the default is theme-adaptive: `'#0A3653'` on light map styles, `'#5FA8D8'` on dark.
5293
+ *
4626
5294
  * @default '#0A3653'
4627
5295
  */
4628
5296
  color?: DataDrivenPropertyValueSpecification<string>;
@@ -4692,7 +5360,7 @@ type GeometryLineConfig = {
4692
5360
  *
4693
5361
  * @group Geometries
4694
5362
  */
4695
- type GeometryLineLabelConfig = {
5363
+ export type GeometryLineLabelConfig = {
4696
5364
  /**
4697
5365
  * Minimum zoom level at which border labels are visible.
4698
5366
  *
@@ -4715,6 +5383,9 @@ type GeometryLineLabelConfig = {
4715
5383
  /**
4716
5384
  * Color of the border label text.
4717
5385
  *
5386
+ * @remarks
5387
+ * When unset the default is theme-adaptive: `'#333333'` on light map styles, `'#FFFFFF'` on dark.
5388
+ *
4718
5389
  * @default '#333333'
4719
5390
  *
4720
5391
  * @example
@@ -4729,6 +5400,9 @@ type GeometryLineLabelConfig = {
4729
5400
  *
4730
5401
  * The halo improves legibility against complex or dark backgrounds.
4731
5402
  *
5403
+ * @remarks
5404
+ * When unset the default is theme-adaptive: `'#FFFFFF'` on light map styles, `'#333333'` on dark.
5405
+ *
4732
5406
  * @default '#FFFFFF'
4733
5407
  *
4734
5408
  * @example
@@ -4810,7 +5484,7 @@ type GeometryLineLabelConfig = {
4810
5484
  *
4811
5485
  * @group Geometries
4812
5486
  */
4813
- type GeometryBeforeLayerConfig = BeforeLayerConfig | GeometryBeforeLayerTargets;
5487
+ export type GeometryBeforeLayerConfig = BeforeLayerConfig | GeometryBeforeLayerTargets;
4814
5488
  /**
4815
5489
  * Per-layer positioning targets for the object form of {@link GeometryBeforeLayerConfig}.
4816
5490
  *
@@ -4820,7 +5494,7 @@ type GeometryBeforeLayerConfig = BeforeLayerConfig | GeometryBeforeLayerTargets;
4820
5494
  *
4821
5495
  * @group Geometries
4822
5496
  */
4823
- type GeometryBeforeLayerTargets = {
5497
+ export type GeometryBeforeLayerTargets = {
4824
5498
  /** Fallback position for any layer not named by `fill` / `line`. */
4825
5499
  all?: BeforeLayerConfig;
4826
5500
  /** Position for the fill layer. */
@@ -4868,7 +5542,7 @@ type GeometryBeforeLayerTargets = {
4868
5542
  *
4869
5543
  * @group Geometries
4870
5544
  */
4871
- type GeometriesModuleConfig = MapModuleCommonConfig & {
5545
+ export type GeometriesModuleConfig = MapModuleCommonConfig & {
4872
5546
  /**
4873
5547
  * Fill color, opacity, and (optional) fill-layer positioning.
4874
5548
  *
@@ -4925,7 +5599,7 @@ type GeometriesModuleConfig = MapModuleCommonConfig & {
4925
5599
  * @example
4926
5600
  * ```typescript
4927
5601
  * // Show the "rest of the world" outside a country
4928
- * const module = await GeometriesModule.get(map, {
5602
+ * const module = await GeometriesModule.create(map, {
4929
5603
  * theme: 'inverted',
4930
5604
  * fill: { color: 'black', opacity: 0.5 }
4931
5605
  * });
@@ -4970,6 +5644,18 @@ type GeometrySourcesWithLayers = {
4970
5644
  geometry: GeoJSONSourceWithLayers<PolygonFeatures>;
4971
5645
  geometryLabel: GeoJSONSourceWithLayers<FeatureCollection<Point>>;
4972
5646
  };
5647
+ /**
5648
+ * Event surface of {@link GeometriesModule}: the module's own events, plus one named scope per
5649
+ * surface it manages.
5650
+ *
5651
+ * @group Geometries
5652
+ */
5653
+ export type GeometriesEvents = CombinedEvents<MapGeoJSONFeature, GeometriesModuleConfig, PolygonFeatures> & {
5654
+ /** The geometry fills and outlines. */
5655
+ geometry: UserEvents<MapGeoJSONFeature>;
5656
+ /** The labels rendered on top of the geometries. */
5657
+ geometryLabel: UserEvents<MapGeoJSONFeature>;
5658
+ };
4973
5659
  /**
4974
5660
  * Geometries Module for displaying polygon areas with custom styling on the map.
4975
5661
  *
@@ -5003,7 +5689,7 @@ type GeometrySourcesWithLayers = {
5003
5689
  * import { GeometriesModule } from '@tomtom-org/maps-sdk/map';
5004
5690
  *
5005
5691
  * // Initialize module
5006
- * const geometriesModule = await GeometriesModule.get(map);
5692
+ * const geometriesModule = await GeometriesModule.create(map);
5007
5693
  *
5008
5694
  * // Display a polygon
5009
5695
  * await geometriesModule.show({
@@ -5021,7 +5707,7 @@ type GeometrySourcesWithLayers = {
5021
5707
  * @example
5022
5708
  * Custom styling:
5023
5709
  * ```typescript
5024
- * const geometriesModule = await GeometriesModule.get(map, {
5710
+ * const geometriesModule = await GeometriesModule.create(map, {
5025
5711
  * fill: { color: '#FF5733', opacity: 0.3 },
5026
5712
  * line: { color: '#C70039', width: 3 },
5027
5713
  * textConfig: {
@@ -5069,7 +5755,7 @@ type GeometrySourcesWithLayers = {
5069
5755
  *
5070
5756
  * @group Geometries
5071
5757
  */
5072
- declare class GeometriesModule extends AbstractMapModule<GeometrySourcesWithLayers, GeometriesModuleConfig> {
5758
+ export declare class GeometriesModule extends AbstractDataOwnedMapModule<GeometrySourcesWithLayers, GeometriesModuleConfig> {
5073
5759
  private titleLayerSpecs;
5074
5760
  private geometryFillLayerSpecs;
5075
5761
  private geometryOutlineLayerSpecs;
@@ -5096,19 +5782,20 @@ declare class GeometriesModule extends AbstractMapModule<GeometrySourcesWithLaye
5096
5782
  * - `beforeLayerConfig`: Layer ordering — a single target, or `{ all, fill, line }` to split them
5097
5783
  *
5098
5784
  * **Multiple Instances:**
5099
- * You can create multiple GeometriesModule instances on the same map,
5100
- * each managing different sets of geometries with different styles.
5785
+ * `GeometriesModule` owns the sources, layers and images it adds, all suffixed per instance.
5786
+ * Every call therefore returns a **new, independent** instance, so you can put several on the
5787
+ * same map, each managing a different set of geometries with different styles.
5101
5788
  *
5102
5789
  * @example
5103
5790
  * Default initialization:
5104
5791
  * ```typescript
5105
- * const geometriesModule = await GeometriesModule.get(map);
5792
+ * const geometriesModule = await GeometriesModule.create(map);
5106
5793
  * ```
5107
5794
  *
5108
5795
  * @example
5109
5796
  * With custom styling:
5110
5797
  * ```typescript
5111
- * const geometriesModule = await GeometriesModule.get(map, {
5798
+ * const geometriesModule = await GeometriesModule.create(map, {
5112
5799
  * fill: { color: 'blue', opacity: 0.25 },
5113
5800
  * line: { color: 'darkblue', width: 2, opacity: 0.8 },
5114
5801
  * textConfig: {
@@ -5121,7 +5808,7 @@ declare class GeometriesModule extends AbstractMapModule<GeometrySourcesWithLaye
5121
5808
  * @example
5122
5809
  * Data-driven styling:
5123
5810
  * ```typescript
5124
- * const geometriesModule = await GeometriesModule.get(map, {
5811
+ * const geometriesModule = await GeometriesModule.create(map, {
5125
5812
  * fill: {
5126
5813
  * // Color based on feature properties
5127
5814
  * color: [
@@ -5137,8 +5824,16 @@ declare class GeometriesModule extends AbstractMapModule<GeometrySourcesWithLaye
5137
5824
  * });
5138
5825
  * ```
5139
5826
  */
5140
- static get(tomtomMap: TomTomMap, config?: GeometriesModuleConfig): Promise<GeometriesModule>;
5827
+ static create(tomtomMap: TomTomMap, config?: GeometriesModuleConfig): Promise<GeometriesModule>;
5141
5828
  private constructor();
5829
+ /** Current light/dark map theme, re-read on every layer/data build so style switches repaint. */
5830
+ private get lightDark();
5831
+ /**
5832
+ * Default fill / plain-outline colour a feature falls back to when it carries no `color`.
5833
+ * Resolved from the active theme; once the styling module ships this also reads the map's
5834
+ * published accent (`mapAccentColor(this.tomtomMap) ?? …`).
5835
+ */
5836
+ private get defaultColor();
5142
5837
  /**
5143
5838
  * @ignore
5144
5839
  */
@@ -5209,6 +5904,10 @@ declare class GeometriesModule extends AbstractMapModule<GeometrySourcesWithLaye
5209
5904
  */
5210
5905
  applyTextConfig(textConfig: GeometryTextConfig): void;
5211
5906
  private updateLayerAndData;
5907
+ /**
5908
+ * @ignore
5909
+ */
5910
+ protected discardShownData(): void;
5212
5911
  /**
5213
5912
  * @ignore
5214
5913
  */
@@ -5314,7 +6013,7 @@ declare class GeometriesModule extends AbstractMapModule<GeometrySourcesWithLaye
5314
6013
  /**
5315
6014
  * Gets the events interface for handling user interactions with geometries.
5316
6015
  *
5317
- * @returns A `UserEvents` instance for registering event handlers.
6016
+ * @returns The module's events, with `on` / `off` for handlers and `where` for scoping.
5318
6017
  *
5319
6018
  * @remarks
5320
6019
  * **Supported Events:**
@@ -5356,12 +6055,12 @@ declare class GeometriesModule extends AbstractMapModule<GeometrySourcesWithLaye
5356
6055
  * });
5357
6056
  * ```
5358
6057
  */
5359
- get events(): CombinedEvents<import('maplibre-gl').MapGeoJSONFeature, GeometriesModuleConfig, PolygonFeatures>;
6058
+ get events(): GeometriesEvents;
5360
6059
  }
5361
6060
  //#endregion
5362
6061
  //#region src/geometry/prepareReachableRangesForDisplay.d.ts
5363
6062
  /** Custom label generator for reachable range features. */
5364
- type ReachableRangeLabelFn = (feature: PolygonFeature, index: number) => string;
6063
+ export type ReachableRangeLabelFn = (feature: PolygonFeature, index: number) => string;
5365
6064
  /**
5366
6065
  * Attaches labels and applies theme-specific geometry to reachable range polygon features.
5367
6066
  *
@@ -5385,7 +6084,7 @@ type ReachableRangeLabelFn = (feature: PolygonFeature, index: number) => string;
5385
6084
  *
5386
6085
  * @group Geometries
5387
6086
  */
5388
- declare const buildReachableRangeFeatures: (features: PolygonFeature[], labels: string[], theme?: GeometryTheme) => PolygonFeature[];
6087
+ export declare const buildReachableRangeFeatures: (features: PolygonFeature[], labels: string[], theme?: GeometryTheme) => PolygonFeature[];
5389
6088
  /**
5390
6089
  * Prepares the output of `calculateReachableRanges` for display with {@link GeometriesModule}.
5391
6090
  *
@@ -5410,7 +6109,7 @@ declare const buildReachableRangeFeatures: (features: PolygonFeature[], labels:
5410
6109
  *
5411
6110
  * @group Geometries
5412
6111
  */
5413
- declare const prepareReachableRangesForDisplay: (result: PolygonFeatures, theme?: GeometryTheme, label?: ReachableRangeLabelFn) => PolygonFeatures;
6112
+ export declare const prepareReachableRangesForDisplay: (result: PolygonFeatures, theme?: GeometryTheme, label?: ReachableRangeLabelFn) => PolygonFeatures;
5414
6113
  //#endregion
5415
6114
  //#region src/geometry/geometryConfigs.d.ts
5416
6115
  /**
@@ -5427,7 +6126,7 @@ declare const prepareReachableRangesForDisplay: (result: PolygonFeatures, theme?
5427
6126
  *
5428
6127
  * @group Geometries
5429
6128
  */
5430
- declare const themedGeometryConfig: (palette?: ColorPaletteOptions, beforeLayerConfig?: GeometryBeforeLayerConfig) => GeometriesModuleConfig;
6129
+ export declare const themedGeometryConfig: (palette?: ColorPaletteOptions, beforeLayerConfig?: GeometryBeforeLayerConfig) => GeometriesModuleConfig;
5431
6130
  /**
5432
6131
  * Returns a {@link GeometriesModuleConfig} for reachable ranges.
5433
6132
  *
@@ -5442,14 +6141,14 @@ declare const themedGeometryConfig: (palette?: ColorPaletteOptions, beforeLayerC
5442
6141
  *
5443
6142
  * @example
5444
6143
  * ```typescript
5445
- * const module = await GeometriesModule.get(map, reachableRangeGeometryConfig());
6144
+ * const module = await GeometriesModule.create(map, reachableRangeGeometryConfig());
5446
6145
  * const result = await calculateReachableRanges([...]);
5447
6146
  * module.show(result); // labels and theme applied automatically
5448
6147
  * ```
5449
6148
  *
5450
6149
  * @group Geometries
5451
6150
  */
5452
- declare const reachableRangeGeometryConfig: (palette?: ColorPaletteOptions, theme?: GeometryTheme, beforeLayerConfig?: GeometryBeforeLayerConfig, label?: ReachableRangeLabelFn) => GeometriesModuleConfig;
6151
+ export declare const reachableRangeGeometryConfig: (palette?: ColorPaletteOptions, theme?: GeometryTheme, beforeLayerConfig?: GeometryBeforeLayerConfig, label?: ReachableRangeLabelFn) => GeometriesModuleConfig;
5453
6152
  //#endregion
5454
6153
  //#region src/geometry/types/geometryDisplayProps.d.ts
5455
6154
  /**
@@ -5486,7 +6185,7 @@ declare const reachableRangeGeometryConfig: (palette?: ColorPaletteOptions, them
5486
6185
  *
5487
6186
  * @group Geometries
5488
6187
  */
5489
- type ExtraGeometryDisplayProps = {
6188
+ export type ExtraGeometryDisplayProps = {
5490
6189
  /**
5491
6190
  * Display title for the geometry.
5492
6191
  *
@@ -5562,7 +6261,7 @@ type ExtraGeometryDisplayProps = {
5562
6261
  *
5563
6262
  * @group Geometries
5564
6263
  */
5565
- type DisplayGeometryProps = CommonPlaceProps & ExtraGeometryDisplayProps;
6264
+ export type DisplayGeometryProps = CommonPlaceProps & ExtraGeometryDisplayProps;
5566
6265
  //#endregion
5567
6266
  //#region src/hillshade/HillshadeModule.d.ts
5568
6267
  /**
@@ -5612,7 +6311,7 @@ type HillshadeSourcesWithLayers = {
5612
6311
  *
5613
6312
  * @group Hillshade
5614
6313
  */
5615
- declare class HillshadeModule extends AbstractMapModule<HillshadeSourcesWithLayers, HillshadeModuleConfig> {
6314
+ export declare class HillshadeModule extends AbstractStyleOwnedMapModule<HillshadeSourcesWithLayers, HillshadeModuleConfig> {
5616
6315
  /**
5617
6316
  * Retrieves a HillshadeModule instance for the given map.
5618
6317
  *
@@ -5653,6 +6352,12 @@ declare class HillshadeModule extends AbstractMapModule<HillshadeSourcesWithLaye
5653
6352
  * visible: false
5654
6353
  * });
5655
6354
  * ```
6355
+ *
6356
+ * @remarks
6357
+ * **Instances:**
6358
+ * `HillshadeModule` controls the hillshade source and layers the map style already provides,
6359
+ * under fixed global IDs. Every instance is another handle on that same shared state, so
6360
+ * visibility applied through one is visible through all of them.
5656
6361
  */
5657
6362
  static get(map: TomTomMap, config?: HillshadeModuleConfig): Promise<HillshadeModule>;
5658
6363
  private constructor();
@@ -5764,7 +6469,7 @@ type HillshadeModuleConfig = MapModuleCommonConfig & {
5764
6469
  * POI category mappings that have a direct equivalent in Map Display POI categories.
5765
6470
  * @ignore
5766
6471
  */
5767
- declare const mapDisplayPoiCategoryMappings: Partial<Record<POICategory, string>>;
6472
+ export declare const mapDisplayPoiCategoryMappings: Partial<Record<POICategory, string>>;
5768
6473
  /**
5769
6474
  * Map style POI category type.
5770
6475
  *
@@ -5784,11 +6489,11 @@ declare const mapDisplayPoiCategoryMappings: Partial<Record<POICategory, string>
5784
6489
  *
5785
6490
  * @group POIs
5786
6491
  */
5787
- type MapStylePOICategory = keyof typeof mapDisplayPoiCategoryMappings;
6492
+ export type MapStylePOICategory = keyof typeof mapDisplayPoiCategoryMappings;
5788
6493
  /**
5789
6494
  * @ignore
5790
6495
  */
5791
- declare const toBaseMapPOICategory: (category: POICategory) => string;
6496
+ export declare const toBaseMapPOICategory: (category: POICategory) => string;
5792
6497
  /**
5793
6498
  * The deduplicated set of base-map POI categories — the right-hand side of
5794
6499
  * {@link completeMapDisplayPoiCategoryMappings}. Each value names the
@@ -5799,11 +6504,11 @@ declare const toBaseMapPOICategory: (category: POICategory) => string;
5799
6504
  *
5800
6505
  * @ignore
5801
6506
  */
5802
- declare const baseMapPOICategoryValues: readonly string[];
6507
+ export declare const baseMapPOICategoryValues: readonly string[];
5803
6508
  /**
5804
6509
  * @ignore
5805
6510
  */
5806
- declare const toBaseMapPOIGroup: (category: POICategory) => string | undefined;
6511
+ export declare const toBaseMapPOIGroup: (category: POICategory) => string | undefined;
5807
6512
  //#endregion
5808
6513
  //#region src/places/types/placeDisplayProps.d.ts
5809
6514
  /**
@@ -5844,7 +6549,7 @@ declare const toBaseMapPOIGroup: (category: POICategory) => string | undefined;
5844
6549
  *
5845
6550
  * @group Places
5846
6551
  */
5847
- type PlaceDisplayProps = {
6552
+ export type PlaceDisplayProps = {
5848
6553
  /**
5849
6554
  * Unique identifier for the place feature.
5850
6555
  *
@@ -5954,7 +6659,7 @@ type PlaceDisplayProps = {
5954
6659
  *
5955
6660
  * @group Places
5956
6661
  */
5957
- type DisplayPlaceProps = CommonPlaceProps & PlaceDisplayProps;
6662
+ export type DisplayPlaceProps = CommonPlaceProps & PlaceDisplayProps;
5958
6663
  //#endregion
5959
6664
  //#region src/places/types/placesModuleConfig.d.ts
5960
6665
  /**
@@ -5973,7 +6678,13 @@ type DisplayPlaceProps = CommonPlaceProps & PlaceDisplayProps;
5973
6678
  *
5974
6679
  * @group Places
5975
6680
  */
5976
- type PlacesTheme = 'pin' | 'circle-icon' | 'base-map' | 'pin-clustered';
6681
+ type PlacesTheme = (typeof placesThemes)[number];
6682
+ /**
6683
+ * All valid {@link PlacesTheme} values.
6684
+ *
6685
+ * @group Places
6686
+ */
6687
+ export declare const placesThemes: readonly ["pin", "circle-icon", "base-map", "pin-clustered"];
5977
6688
  /**
5978
6689
  * Configuration for EV charging station availability display.
5979
6690
  *
@@ -5989,14 +6700,14 @@ type PlacesTheme = 'pin' | 'circle-icon' | 'base-map' | 'pin-clustered';
5989
6700
  * @example
5990
6701
  * ```typescript
5991
6702
  * // Enable with defaults
5992
- * const places = await PlacesModule.get(map, {
6703
+ * const places = await PlacesModule.create(map, {
5993
6704
  * evAvailability: { enabled: true }
5994
6705
  * });
5995
6706
  * const stations = await search({ poiCategories: ['ELECTRIC_VEHICLE_STATION'] });
5996
6707
  * places.show(await getPlacesWithEVAvailability(stations));
5997
6708
  *
5998
6709
  * // Custom threshold and format
5999
- * const places = await PlacesModule.get(map, {
6710
+ * const places = await PlacesModule.create(map, {
6000
6711
  * evAvailability: {
6001
6712
  * enabled: true,
6002
6713
  * threshold: 0.5,
@@ -6005,7 +6716,7 @@ type PlacesTheme = 'pin' | 'circle-icon' | 'base-map' | 'pin-clustered';
6005
6716
  * });
6006
6717
  *
6007
6718
  * // Combine with custom icon
6008
- * const places = await PlacesModule.get(map, {
6719
+ * const places = await PlacesModule.create(map, {
6009
6720
  * icon: {
6010
6721
  * categoryIcons: [{
6011
6722
  * id: 'ELECTRIC_VEHICLE_STATION',
@@ -6675,7 +7386,119 @@ type PlacesSourcesAndLayers = {
6675
7386
  */
6676
7387
  connections: GeoJSONSourceWithLayers<ConnectionFeatureCollection>;
6677
7388
  };
6678
- declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLayers, PlacesModuleConfig> {
7389
+ /**
7390
+ * What {@link PlacesModule.show} accepts, and what `shown-features` handlers receive back.
7391
+ *
7392
+ * @group Places
7393
+ */
7394
+ export type ShownPlaces = Place | Place[] | Places;
7395
+ /**
7396
+ * What `places.events.on('shown-features', ...)` receives: whichever of places or connections was
7397
+ * just rendered.
7398
+ *
7399
+ * @group Places
7400
+ */
7401
+ export type PlacesShownFeatures = {
7402
+ places: ShownPlaces;
7403
+ } | {
7404
+ connections: PlaceConnectionDisplay[];
7405
+ };
7406
+ /**
7407
+ * Event surface of {@link PlacesModule}: the module's own events, plus one named scope per
7408
+ * surface it manages.
7409
+ *
7410
+ * @group Places
7411
+ */
7412
+ export type PlacesEvents = CombinedEvents<MapGeoJSONFeature, PlacesModuleConfig, PlacesShownFeatures> & {
7413
+ /** The place pins themselves, clustered or not. */
7414
+ places: UserEvents<Place<DisplayPlaceProps>>;
7415
+ /** The lines and labels connecting places to their parent, when connections are shown. */
7416
+ connections: UserEvents<MapGeoJSONFeature>;
7417
+ };
7418
+ /**
7419
+ * Map module for displaying and managing place markers.
7420
+ *
7421
+ * The PlacesModule provides functionality to display location markers (pins) on the map
7422
+ * for points of interest, search results, or custom locations. It supports various marker
7423
+ * styles, custom icons, text labels, and interactive events.
7424
+ *
7425
+ * @remarks
7426
+ * **Features:**
7427
+ * - Multiple marker styles (pin, circle-icon, base-map POI-like)
7428
+ * - Custom icons per POI category
7429
+ * - Text labels with styling options
7430
+ * - Data-driven styling via MapLibre expressions
7431
+ * - Interactive events (click, hover, etc.)
7432
+ * - Support for custom feature properties
7433
+ * - EV charging station availability display (opt-in)
7434
+ *
7435
+ * **Marker Styles:**
7436
+ * - `pin`: Traditional teardrop-shaped map pins
7437
+ * - `circle-icon`: Simple circular markers (previously named `circle`)
7438
+ * - `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'`.
7439
+ *
7440
+ * **EV Charging Station Availability:**
7441
+ * When displaying EV charging stations with availability data from
7442
+ * {@link getPlacesWithEVAvailability}, the module can:
7443
+ * - Show available/total charging points (e.g., "3/10")
7444
+ * - Color-code availability (green = good, orange = limited, red = none/low)
7445
+ * - Display as formatted text within the station's label
7446
+ *
7447
+ * This feature is disabled by default. To enable it, set `evAvailability.enabled` to `true`
7448
+ * in the configuration.
7449
+ *
7450
+ * **Common Use Cases:**
7451
+ * - Search result visualization
7452
+ * - Custom location markers
7453
+ * - Store locators
7454
+ * - EV charging station maps with real-time availability
7455
+ * - Delivery/pickup points
7456
+ * - Saved locations display
7457
+ *
7458
+ * @example
7459
+ * ```typescript
7460
+ * // Create places module with pin markers
7461
+ * const placesModule = await PlacesModule.create(map, {
7462
+ * icon: {
7463
+ * categoryIcons: []
7464
+ * },
7465
+ * text: {
7466
+ * field: (place) => place.properties.poi?.name || 'Unknown'
7467
+ * },
7468
+ * theme: 'pin'
7469
+ * });
7470
+ *
7471
+ * // Display places from search
7472
+ * await placesModule.show(searchResults);
7473
+ *
7474
+ * // EV Charging Stations - Opt-in to availability display
7475
+ * const evStations = await PlacesModule.create(map, {
7476
+ * evAvailability: { enabled: true }
7477
+ * });
7478
+ * const results = await search({ poiCategories: ['ELECTRIC_VEHICLE_STATION'] });
7479
+ * evStations.show(await getPlacesWithEVAvailability(results)); // Shows availability
7480
+ *
7481
+ * // Granular control: Enable for searched stations only, background stations without
7482
+ * const bgStations = await PlacesModule.create(map); // EV availability disabled
7483
+ * const searched = await PlacesModule.create(map, {
7484
+ * evAvailability: { enabled: true }
7485
+ * });
7486
+ *
7487
+ * // Handle clicks
7488
+ * placesModule.events.on('click', (feature) => {
7489
+ * console.log('Clicked:', feature.properties);
7490
+ * });
7491
+ *
7492
+ * placesModule.events.on('hover', (feature) => {
7493
+ * showTooltip(feature.properties.poi?.name);
7494
+ * });
7495
+ * ```
7496
+ *
7497
+ * @see [Places Guide](https://docs.tomtom.com/maps-sdk-js/guides/map/places)
7498
+ *
7499
+ * @group Places
7500
+ */
7501
+ export declare class PlacesModule extends AbstractDataOwnedMapModule<PlacesSourcesAndLayers, PlacesModuleConfig> {
6679
7502
  private layerSpecs;
6680
7503
  private connectionLayerSpecs;
6681
7504
  private currentClusterMode;
@@ -6687,12 +7510,17 @@ declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLayers, Pla
6687
7510
  private shownConnections;
6688
7511
  private readonly shownFeaturesHandlers;
6689
7512
  /**
6690
- * Make sure the map is ready before create an instance of the module and any other interaction with the map
7513
+ * Creates a new module instance on the given map, waiting until the map is ready first.
7514
+ *
7515
+ * `PlacesModule` owns the sources, layers and images it adds, all suffixed per instance. Every
7516
+ * call therefore returns a **new, independent** instance, and stacking several of them on one
7517
+ * map is a supported thing to do.
7518
+ *
6691
7519
  * @param tomtomMap The TomTomMap instance.
6692
7520
  * @param config The module optional configuration
6693
7521
  * @returns {Promise} Returns a promise with a new instance of this module
6694
7522
  */
6695
- static get(tomtomMap: TomTomMap, config?: PlacesModuleConfig): Promise<PlacesModule>;
7523
+ static create(tomtomMap: TomTomMap, config?: PlacesModuleConfig): Promise<PlacesModule>;
6696
7524
  private constructor();
6697
7525
  /**
6698
7526
  * @ignore
@@ -6706,6 +7534,10 @@ declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLayers, Pla
6706
7534
  * @ignore
6707
7535
  */
6708
7536
  protected _applyConfig(config: PlacesModuleConfig | undefined): PlacesModuleConfig | undefined;
7537
+ /**
7538
+ * @ignore
7539
+ */
7540
+ protected discardShownData(): void;
6709
7541
  /**
6710
7542
  * @ignore
6711
7543
  */
@@ -6855,7 +7687,7 @@ declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLayers, Pla
6855
7687
  * await placesModule.show([place1, place2, place3]);
6856
7688
  * ```
6857
7689
  */
6858
- show(places: Place | Place[] | Places): Promise<void>;
7690
+ show(places: ShownPlaces): Promise<void>;
6859
7691
  /**
6860
7692
  * Removes all places from the map.
6861
7693
  *
@@ -6890,7 +7722,7 @@ declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLayers, Pla
6890
7722
  *
6891
7723
  * @example
6892
7724
  * ```typescript
6893
- * const places = await PlacesModule.get(map, {
7725
+ * const places = await PlacesModule.create(map, {
6894
7726
  * connections: {
6895
7727
  * label: (c) => `${c.distanceMeters} m`
6896
7728
  * }
@@ -6979,7 +7811,7 @@ declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLayers, Pla
6979
7811
  * ```
6980
7812
  */
6981
7813
  cleanEventStates(options?: CleanEventStatesOptions): void;
6982
- get events(): CombinedEvents<Place<DisplayPlaceProps>, PlacesModuleConfig, Place | Place[] | Places>;
7814
+ get events(): PlacesEvents;
6983
7815
  }
6984
7816
  //#endregion
6985
7817
  //#region src/places/utils/preparePlacesForDisplay.d.ts
@@ -6988,40 +7820,40 @@ declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLayers, Pla
6988
7820
  * @param place The place to display.
6989
7821
  * @ignore
6990
7822
  */
6991
- declare const buildPlaceTitle: (place: Place) => string;
7823
+ export declare const buildPlaceTitle: (place: Place) => string;
6992
7824
  /**
6993
7825
  * Gets the map style sprite image ID to display on the map for the give place.
6994
7826
  * @ignore
6995
7827
  */
6996
- declare const getIconIDForPlace: (place: Place, instanceIndex: number, config?: PlacesModuleConfig) => string;
7828
+ export declare const getIconIDForPlace: (place: Place, instanceIndex: number, config?: PlacesModuleConfig) => string;
6997
7829
  /**
6998
7830
  * Maps a Place category to the poi layer one, so the latter's style can apply it.
6999
7831
  * @ignore
7000
7832
  */
7001
- declare const getPOILayerCategoryForPlace: (place: Place, config?: PlacesModuleConfig) => string | undefined;
7833
+ export declare const getPOILayerCategoryForPlace: (place: Place, config?: PlacesModuleConfig) => string | undefined;
7002
7834
  /**
7003
7835
  * Maps a Place to the base map POI group used by the style's `text-color` and
7004
7836
  * `POI - Micro` icon expressions (e.g., `eat_and_drink`, `lodging`, `driving`).
7005
7837
  * @ignore
7006
7838
  */
7007
- declare const getPOIGroupForPlace: (place: Place, config?: PlacesModuleConfig) => string | undefined;
7839
+ export declare const getPOIGroupForPlace: (place: Place, config?: PlacesModuleConfig) => string | undefined;
7008
7840
  /**
7009
7841
  * Transforms the input of a "show" call to FeatureCollection "Places".
7010
7842
  * @ignore
7011
7843
  */
7012
- declare const toPlaces: (places: Place | Place[] | Places) => Places;
7844
+ export declare const toPlaces: (places: Place | Place[] | Places) => Places;
7013
7845
  /**
7014
7846
  * prepare places features to be displayed on map by adding needed properties for title, icon and style
7015
7847
  * @ignore
7016
7848
  */
7017
- declare const preparePlacesForDisplay: (placesInput: Place | Place[] | Places, instanceIndex: number, config?: PlacesModuleConfig) => Places<DisplayPlaceProps>;
7849
+ export declare const preparePlacesForDisplay: (placesInput: Place | Place[] | Places, instanceIndex: number, config?: PlacesModuleConfig) => Places<DisplayPlaceProps>;
7018
7850
  //#endregion
7019
7851
  //#region src/pois/layers/poisLayers.d.ts
7020
7852
  /**
7021
7853
  * Layer IDs for POIs on the map.
7022
7854
  * @ignore
7023
7855
  */
7024
- declare const poiLayerIDs: string[];
7856
+ export declare const poiLayerIDs: string[];
7025
7857
  //#endregion
7026
7858
  //#region src/pois/types/poiCategoryGroups.d.ts
7027
7859
  /**
@@ -7073,7 +7905,7 @@ declare const poiLayerIDs: string[];
7073
7905
  *
7074
7906
  * @group POIs
7075
7907
  */
7076
- declare const poiCategoryGroups: Record<string, MapStylePOICategory[]>;
7908
+ export declare const poiCategoryGroups: Record<string, MapStylePOICategory[]>;
7077
7909
  /**
7078
7910
  * POI category group type.
7079
7911
  *
@@ -7140,7 +7972,7 @@ declare const poiCategoryGroups: Record<string, MapStylePOICategory[]>;
7140
7972
  *
7141
7973
  * @group POIs
7142
7974
  */
7143
- type POICategoryGroup = keyof typeof poiCategoryGroups;
7975
+ export type POICategoryGroup = keyof typeof poiCategoryGroups;
7144
7976
  //#endregion
7145
7977
  //#region src/pois/types/poisModuleConfig.d.ts
7146
7978
  /**
@@ -7347,7 +8179,7 @@ type POIsModuleFeature = Feature<Point, {
7347
8179
  * @param categories list of filtered categories.
7348
8180
  * @ignore
7349
8181
  */
7350
- declare const getStyleCategories: (categories: FilterablePOICategory[]) => string[];
8182
+ export declare const getStyleCategories: (categories: FilterablePOICategory[]) => string[];
7351
8183
  /**
7352
8184
  * IDs of sources and layers for places of interest module.
7353
8185
  */
@@ -7438,7 +8270,7 @@ type PoIsSourcesAndLayers = {
7438
8270
  *
7439
8271
  * @group POIs
7440
8272
  */
7441
- declare class POIsModule extends AbstractMapModule<PoIsSourcesAndLayers, POIsModuleConfig> {
8273
+ export declare class POIsModule extends AbstractStyleOwnedMapModule<PoIsSourcesAndLayers, POIsModuleConfig> {
7442
8274
  private categoriesFilter?;
7443
8275
  private originalFilter?;
7444
8276
  /**
@@ -7475,6 +8307,12 @@ declare class POIsModule extends AbstractMapModule<PoIsSourcesAndLayers, POIsMod
7475
8307
  * }
7476
8308
  * });
7477
8309
  * ```
8310
+ *
8311
+ * @remarks
8312
+ * **Instances:**
8313
+ * `POIsModule` controls the POI sources and layers the map style already provides, under fixed
8314
+ * global IDs. Every instance is another handle on that same shared state, so visibility and
8315
+ * filters applied through one are visible through all of them.
7478
8316
  */
7479
8317
  static get(map: TomTomMap, config?: POIsModuleConfig): Promise<POIsModule>;
7480
8318
  private constructor();
@@ -7593,7 +8431,7 @@ declare class POIsModule extends AbstractMapModule<PoIsSourcesAndLayers, POIsMod
7593
8431
  /**
7594
8432
  * Gets the events interface for handling user interactions with POIs.
7595
8433
  *
7596
- * @returns A `UserEvents` instance for registering event handlers.
8434
+ * @returns The module's events, with `on` / `off` for handlers and `where` for scoping.
7597
8435
  *
7598
8436
  * @remarks
7599
8437
  * **Supported Events:**
@@ -8215,7 +9053,7 @@ type RoutingModuleConfig = MapModuleCommonConfig & {
8215
9053
  * @param instanceIndex - Optional instance index for image ID suffixes.
8216
9054
  * @ignore
8217
9055
  */
8218
- declare const buildRoutingLayers: (config?: RoutingModuleConfig, layerIDPrefix?: string, instanceIndex?: number) => Required<RouteLayersConfig>;
9056
+ export declare const buildRoutingLayers: (config?: RoutingModuleConfig, layerIDPrefix?: string, instanceIndex?: number) => Required<RouteLayersConfig>;
8219
9057
  /**
8220
9058
  * Default routing layers configuration. Calls routingLayers with no parameters.
8221
9059
  *
@@ -8237,38 +9075,38 @@ declare const buildRoutingLayers: (config?: RoutingModuleConfig, layerIDPrefix?:
8237
9075
  *
8238
9076
  * @group Routing
8239
9077
  */
8240
- declare const defaultRoutingLayers: Required<RouteLayersConfig>;
9078
+ export declare const defaultRoutingLayers: Required<RouteLayersConfig>;
8241
9079
  //#endregion
8242
9080
  //#region src/routing/layers/shared.d.ts
8243
9081
  /**
8244
9082
  * Main route line foreground color.
8245
9083
  * @ignore
8246
9084
  */
8247
- declare const ROUTE_LINE_FOREGROUND_COLOR = "#36A8F0";
9085
+ export declare const ROUTE_LINE_FOREGROUND_COLOR = "#36A8F0";
8248
9086
  /**
8249
9087
  * Main route outline color.
8250
9088
  * @ignore
8251
9089
  */
8252
- declare const ROUTE_LINE_OUTLINE_COLOR = "#105287";
9090
+ export declare const ROUTE_LINE_OUTLINE_COLOR = "#105287";
8253
9091
  /**
8254
9092
  * Deselected route line foreground color.
8255
9093
  * @ignore
8256
9094
  */
8257
- declare const DESELECTED_FOREGROUND_COLOR = "#ABAFB3";
9095
+ export declare const DESELECTED_FOREGROUND_COLOR = "#ABAFB3";
8258
9096
  /**
8259
9097
  * Deselected route line outline color.
8260
9098
  * @ignore
8261
9099
  */
8262
- declare const DESELECTED_OUTLINE_COLOR = "#3C4956";
9100
+ export declare const DESELECTED_OUTLINE_COLOR = "#3C4956";
8263
9101
  /**
8264
9102
  * @ignore
8265
9103
  */
8266
- declare const DESELECTED_SECONDARY_COLOR = "#727C85";
9104
+ export declare const DESELECTED_SECONDARY_COLOR = "#727C85";
8267
9105
  /**
8268
9106
  * Main route line width based on zoom level.
8269
9107
  * @ignore
8270
9108
  */
8271
- declare const ROUTE_LINE_FOREGROUND_WIDTH: ExpressionSpecification;
9109
+ export declare const ROUTE_LINE_FOREGROUND_WIDTH: ExpressionSpecification;
8272
9110
  /**
8273
9111
  * Used for showing/hiding layer depending on layer being part of selected route or not.
8274
9112
  *
@@ -8279,7 +9117,7 @@ declare const ROUTE_LINE_FOREGROUND_WIDTH: ExpressionSpecification;
8279
9117
  * filter: SELECTED_ROUTE_FILTER
8280
9118
  * @group Routing
8281
9119
  */
8282
- declare const SELECTED_ROUTE_FILTER: ExpressionSpecification;
9120
+ export declare const SELECTED_ROUTE_FILTER: ExpressionSpecification;
8283
9121
  /**
8284
9122
  * Used for showing/hiding layer depending on layer being part of deselected route or not.
8285
9123
  *
@@ -8290,76 +9128,76 @@ declare const SELECTED_ROUTE_FILTER: ExpressionSpecification;
8290
9128
  * filter: DESELECTED_ROUTE_FILTER
8291
9129
  * @group Routing
8292
9130
  */
8293
- declare const DESELECTED_ROUTE_FILTER: ExpressionSpecification;
9131
+ export declare const DESELECTED_ROUTE_FILTER: ExpressionSpecification;
8294
9132
  /**
8295
9133
  * Main route line outline width (medium) based on zoom level.
8296
9134
  * @ignore
8297
9135
  */
8298
- declare const ROUTE_LINE_OUTLINE_WIDTH: ExpressionSpecification;
9136
+ export declare const ROUTE_LINE_OUTLINE_WIDTH: ExpressionSpecification;
8299
9137
  /**
8300
9138
  * Returns the foreground line width expression for the given size preset.
8301
9139
  * @ignore
8302
9140
  */
8303
- declare const getLineForegroundWidth: (size?: RouteWidth) => ExpressionSpecification;
9141
+ export declare const getLineForegroundWidth: (size?: RouteWidth) => ExpressionSpecification;
8304
9142
  /**
8305
9143
  * Returns the outline line width expression for the given size preset.
8306
9144
  * @ignore
8307
9145
  */
8308
- declare const getLineOutlineWidth: (size?: RouteWidth) => ExpressionSpecification;
9146
+ export declare const getLineOutlineWidth: (size?: RouteWidth) => ExpressionSpecification;
8309
9147
  /**
8310
9148
  * Returns the waypoint icon size expression for the given size preset.
8311
9149
  * @ignore
8312
9150
  */
8313
- declare const getWaypointIconSize: (size?: RouteWaypointSize) => ExpressionSpecification;
9151
+ export declare const getWaypointIconSize: (size?: RouteWaypointSize) => ExpressionSpecification;
8314
9152
  /**
8315
9153
  * Returns the toll road outline width expression for the given size preset.
8316
9154
  * @ignore
8317
9155
  */
8318
- declare const getTollRoadOutlineWidth: (size?: RouteWidth) => ExpressionSpecification;
9156
+ export declare const getTollRoadOutlineWidth: (size?: RouteWidth) => ExpressionSpecification;
8319
9157
  /**
8320
9158
  * Returns the instruction line width expression for the given size preset.
8321
9159
  * @ignore
8322
9160
  */
8323
- declare const getInstructionLineWidth: (size?: RouteWidth) => ExpressionSpecification;
9161
+ export declare const getInstructionLineWidth: (size?: RouteWidth) => ExpressionSpecification;
8324
9162
  /**
8325
9163
  * Returns the instruction outline width expression for the given size preset.
8326
9164
  * @ignore
8327
9165
  */
8328
- declare const getInstructionOutlineWidth: (size?: RouteWidth) => ExpressionSpecification;
9166
+ export declare const getInstructionOutlineWidth: (size?: RouteWidth) => ExpressionSpecification;
8329
9167
  /**
8330
9168
  * @ignore
8331
9169
  */
8332
- declare const MAJOR_DELAY_COLOR = "#AD0000";
9170
+ export declare const MAJOR_DELAY_COLOR = "#AD0000";
8333
9171
  /**
8334
9172
  * @ignore
8335
9173
  */
8336
- declare const MODERATE_DELAY_COLOR = "#FB2D09";
9174
+ export declare const MODERATE_DELAY_COLOR = "#FB2D09";
8337
9175
  /**
8338
9176
  * @ignore
8339
9177
  */
8340
- declare const MINOR_DELAY_COLOR = "#FFC105";
9178
+ export declare const MINOR_DELAY_COLOR = "#FFC105";
8341
9179
  /**
8342
9180
  * @ignore
8343
9181
  */
8344
- declare const MINOR_DELAY_LABEL_COLOR = "#f58240";
9182
+ export declare const MINOR_DELAY_LABEL_COLOR = "#f58240";
8345
9183
  /**
8346
9184
  * @ignore
8347
9185
  */
8348
- declare const UNKNOWN_DELAY_COLOR = "#000000";
9186
+ export declare const UNKNOWN_DELAY_COLOR = "#000000";
8349
9187
  /**
8350
9188
  * @ignore
8351
9189
  */
8352
- declare const UNKNOWN_DELAY_BG_COLOR = "#C7D2D8";
9190
+ export declare const UNKNOWN_DELAY_BG_COLOR = "#C7D2D8";
8353
9191
  /**
8354
9192
  * Dashed-line color for `magnitudeOfDelay === 'unknown'` (rendered as a red dashed overlay).
8355
9193
  * @ignore
8356
9194
  */
8357
- declare const UNKNOWN_DELAY_DASH_COLOR = "rgba(190, 39, 27, 1)";
9195
+ export declare const UNKNOWN_DELAY_DASH_COLOR = "rgba(190, 39, 27, 1)";
8358
9196
  /**
8359
9197
  * Dashed-line color for `magnitudeOfDelay === 'indefinite'` (rendered as a gray dashed overlay).
8360
9198
  * @ignore
8361
9199
  */
8362
- declare const INDEFINITE_DELAY_DASH_COLOR = "rgba(137, 150, 168, 1)";
9200
+ export declare const INDEFINITE_DELAY_DASH_COLOR = "rgba(137, 150, 168, 1)";
8363
9201
  //#endregion
8364
9202
  //#region src/routing/types/displayRoutes.d.ts
8365
9203
  /**
@@ -8853,19 +9691,19 @@ type PlanningWaypoint = WaypointLike | null;
8853
9691
  /**
8854
9692
  * @group Routing
8855
9693
  */
8856
- declare const START_INDEX = "start";
9694
+ export declare const START_INDEX = "start";
8857
9695
  /**
8858
9696
  * @group Routing
8859
9697
  */
8860
- declare const MIDDLE_INDEX = "middle";
9698
+ export declare const MIDDLE_INDEX = "middle";
8861
9699
  /**
8862
9700
  * @group Routing
8863
9701
  */
8864
- declare const FINISH_INDEX = "finish";
9702
+ export declare const FINISH_INDEX = "finish";
8865
9703
  /**
8866
9704
  * @group Routing
8867
9705
  */
8868
- type WaypointIndexType = typeof START_INDEX | typeof MIDDLE_INDEX | typeof FINISH_INDEX;
9706
+ export type WaypointIndexType = typeof START_INDEX | typeof MIDDLE_INDEX | typeof FINISH_INDEX;
8869
9707
  /**
8870
9708
  * Display properties for a waypoint marker on the map.
8871
9709
  *
@@ -8911,7 +9749,7 @@ type WaypointIndexType = typeof START_INDEX | typeof MIDDLE_INDEX | typeof FINIS
8911
9749
  *
8912
9750
  * @group Routing
8913
9751
  */
8914
- type WaypointDisplayProps = PlaceDisplayProps & {
9752
+ export type WaypointDisplayProps = PlaceDisplayProps & {
8915
9753
  /**
8916
9754
  * The index of the waypoint in relation to the other waypoints.
8917
9755
  *
@@ -8943,8 +9781,8 @@ type WaypointDisplayProps = PlaceDisplayProps & {
8943
9781
  * The stop index to be displayed.
8944
9782
  *
8945
9783
  * @remarks
8946
- * Stops are the non-soft waypoints added between origin and destination,
8947
- * numbered starting from 1. Only present for middle waypoints.
9784
+ * Stops are the waypoints between origin and destination, numbered starting from 1.
9785
+ * Only present for middle waypoints.
8948
9786
  *
8949
9787
  * **Display Behavior:**
8950
9788
  * - Start waypoint: undefined
@@ -8962,15 +9800,25 @@ type WaypointDisplayProps = PlaceDisplayProps & {
8962
9800
  * ```
8963
9801
  */
8964
9802
  stopDisplayIndex?: number;
9803
+ /**
9804
+ * How long the route waits at this waypoint, formatted for display.
9805
+ *
9806
+ * @remarks
9807
+ * Taken from {@link WaypointProps.pauseDurationSeconds} and rendered on the stop's label by
9808
+ * default (e.g. `30 min`). Absent when the waypoint carries no wait. Charging-stop pins carry
9809
+ * the same property, so both kinds of pin say how long you are there in the same words.
9810
+ *
9811
+ * @example
9812
+ * ```typescript
9813
+ * stopDuration: '30 min'
9814
+ * ```
9815
+ */
9816
+ stopDuration?: string;
8965
9817
  };
8966
9818
  /**
8967
9819
  * @ignore
8968
9820
  */
8969
- declare const INDEX_TYPE = "indexType";
8970
- /**
8971
- * @ignore
8972
- */
8973
- declare const STOP_DISPLAY_INDEX = "stopDisplayIndex";
9821
+ export declare const STOP_DISPLAY_INDEX = "stopDisplayIndex";
8974
9822
  //#endregion
8975
9823
  //#region src/routing/types/routingSourcesAndLayers.d.ts
8976
9824
  /**
@@ -9042,6 +9890,45 @@ type ShowRoutesOptions = {
9042
9890
  };
9043
9891
  //#endregion
9044
9892
  //#region src/routing/RoutingModule.d.ts
9893
+ /**
9894
+ * What `routing.events.on('shown-features', ...)` receives: whichever of routes or waypoints was
9895
+ * just rendered.
9896
+ *
9897
+ * @group Routing
9898
+ */
9899
+ export type RoutingShownFeatures = {
9900
+ routes: Route | Routes;
9901
+ } | {
9902
+ waypoints: PlanningWaypoint[] | Waypoints;
9903
+ };
9904
+ /**
9905
+ * Event surface of {@link RoutingModule}: the module's own events, plus one named scope per part
9906
+ * of a route it draws.
9907
+ *
9908
+ * @group Routing
9909
+ */
9910
+ export type RoutingEvents = CombinedEvents<MapGeoJSONFeature, RoutingModuleConfig, RoutingShownFeatures> & {
9911
+ /** The route lines themselves. */
9912
+ mainLines: UserEvents<Route<DisplayRouteProps>>;
9913
+ /** Origin, destination and intermediate stops. */
9914
+ waypoints: UserEvents<Waypoint<WaypointDisplayProps>>;
9915
+ /** Charging stops along an EV route. */
9916
+ chargingStops: UserEvents<RouteSection>;
9917
+ /** The summary bubbles shown against each alternative. */
9918
+ summaryBubbles: UserEvents<DisplayRouteSummary>;
9919
+ /** Traffic incidents on the route. */
9920
+ incidents: UserEvents<RouteSection<DisplayTrafficSectionProps>>;
9921
+ /** Sections the vehicle is restricted from. */
9922
+ vehicleRestricted: UserEvents<RouteSection>;
9923
+ /** Ferry sections. */
9924
+ ferries: UserEvents<RouteSection>;
9925
+ /** Toll road sections. */
9926
+ tollRoads: UserEvents<RouteSection>;
9927
+ /** Tunnel sections. */
9928
+ tunnels: UserEvents<RouteSection>;
9929
+ /** The guidance instruction lines. */
9930
+ instructionLines: UserEvents<DisplayInstruction>;
9931
+ };
9045
9932
  /**
9046
9933
  * Map module for displaying and managing route visualizations.
9047
9934
  *
@@ -9069,7 +9956,7 @@ type ShowRoutesOptions = {
9069
9956
  * @example
9070
9957
  * ```typescript
9071
9958
  * // Create the module
9072
- * const routingModule = await RoutingModule.getInstance(map, {
9959
+ * const routingModule = await RoutingModule.create(map, {
9073
9960
  * displayUnits: {
9074
9961
  * distance: { type: 'metric' }
9075
9962
  * }
@@ -9095,7 +9982,7 @@ type ShowRoutesOptions = {
9095
9982
  *
9096
9983
  * @group Routing
9097
9984
  */
9098
- declare class RoutingModule extends AbstractMapModule<RoutingSourcesWithLayers, RoutingModuleConfig> {
9985
+ export declare class RoutingModule extends AbstractDataOwnedMapModule<RoutingSourcesWithLayers, RoutingModuleConfig> {
9099
9986
  private layersSpecs;
9100
9987
  private layerIDPrefix;
9101
9988
  private readonly shownFeaturesHandlers;
@@ -9106,6 +9993,11 @@ declare class RoutingModule extends AbstractMapModule<RoutingSourcesWithLayers,
9106
9993
  * @returns {Promise} Returns a promise with a new instance of this module
9107
9994
  *
9108
9995
  * @remarks
9996
+ * **Instances:**
9997
+ * `RoutingModule` owns the sources, layers and images it adds, all suffixed per instance. Every
9998
+ * call therefore returns a **new, independent** instance, and stacking several of them on one
9999
+ * map is a supported thing to do.
10000
+ *
9109
10001
  * **Configuration Options:**
9110
10002
  * - `displayUnits`: Distance units (metric/imperial)
9111
10003
  * - `waypointsSource`: Waypoint entry point options
@@ -9117,13 +10009,13 @@ declare class RoutingModule extends AbstractMapModule<RoutingSourcesWithLayers,
9117
10009
  * @example
9118
10010
  * Default initialization:
9119
10011
  * ```typescript
9120
- * const routingModule = await RoutingModule.get(map);
10012
+ * const routingModule = await RoutingModule.create(map);
9121
10013
  * ```
9122
10014
  *
9123
10015
  * @example
9124
10016
  * With custom configuration:
9125
10017
  * ```typescript
9126
- * const routingModule = await RoutingModule.get(map, {
10018
+ * const routingModule = await RoutingModule.create(map, {
9127
10019
  * displayUnits: 'imperial',
9128
10020
  * waypointsSource: {
9129
10021
  * entryPoints: 'main-when-available'
@@ -9131,7 +10023,7 @@ declare class RoutingModule extends AbstractMapModule<RoutingSourcesWithLayers,
9131
10023
  * });
9132
10024
  * ```
9133
10025
  */
9134
- static get(tomtomMap: TomTomMap, config?: RoutingModuleConfig): Promise<RoutingModule>;
10026
+ static create(tomtomMap: TomTomMap, config?: RoutingModuleConfig): Promise<RoutingModule>;
9135
10027
  private constructor();
9136
10028
  private createSourcesWithLayers;
9137
10029
  /**
@@ -9142,6 +10034,8 @@ declare class RoutingModule extends AbstractMapModule<RoutingSourcesWithLayers,
9142
10034
  * @ignore
9143
10035
  */
9144
10036
  protected _applyConfig(config?: RoutingModuleConfig): RoutingModuleConfig;
10037
+ /** @ignore */
10038
+ protected discardShownData(): void;
9145
10039
  /**
9146
10040
  * @ignore
9147
10041
  */
@@ -9317,42 +10211,29 @@ declare class RoutingModule extends AbstractMapModule<RoutingSourcesWithLayers,
9317
10211
  summaryBubbles: DisplayRouteSummaries;
9318
10212
  };
9319
10213
  /**
9320
- * Unified events interface for the routing module, split into two namespaces:
10214
+ * Unified events interface for the routing module.
9321
10215
  *
9322
- * **`events.user`** — user interaction events, keyed by source:
9323
- * ```typescript
9324
- * routing.events.user.mainLines.on('click', (route) => { ... });
9325
- * routing.events.user.waypoints.on('hover', (waypoint) => { ... });
9326
- * ```
10216
+ * `events` itself covers every route feature and the module's lifecycle events; the named
10217
+ * scopes below cover one part of a route each, and every one of them can be narrowed further
10218
+ * with `where()`.
9327
10219
  *
9328
- * **`events.module`** — module lifecycle events:
9329
10220
  * ```typescript
9330
- * const unsub = routing.events.module.on('config-change', (config) => { ... });
9331
- * const unsub = routing.events.module.on('shown-features', (features) => {
10221
+ * routing.events.mainLines.on('click', (route) => { ... });
10222
+ * routing.events.waypoints.on('hover', (waypoint) => { ... });
10223
+ *
10224
+ * // Only the long tunnels, with their own hover cursor:
10225
+ * routing.events.tunnels
10226
+ * .where((section) => section.properties.lengthInMeters > 500, { cursorOnHover: 'help' })
10227
+ * .on('click', showTunnel);
10228
+ *
10229
+ * const unsub = routing.events.on('config-change', (config) => { ... });
10230
+ * routing.events.on('shown-features', (features) => {
9332
10231
  * if ('routes' in features) { ... }
9333
10232
  * });
9334
10233
  * unsub();
9335
10234
  * ```
9336
10235
  */
9337
- get events(): {
9338
- user: {
9339
- mainLines: UserEvents<Route<DisplayRouteProps>>;
9340
- waypoints: UserEvents<Waypoint<WaypointDisplayProps>>;
9341
- chargingStops: UserEvents<RouteSection>;
9342
- summaryBubbles: UserEvents<DisplayRouteSummary>;
9343
- incidents: UserEvents<RouteSection<DisplayTrafficSectionProps>>;
9344
- vehicleRestricted: UserEvents<RouteSection>;
9345
- ferries: UserEvents<RouteSection>;
9346
- tollRoads: UserEvents<RouteSection>;
9347
- tunnels: UserEvents<RouteSection>;
9348
- instructionLines: UserEvents<DisplayInstruction>;
9349
- };
9350
- module: ModuleEvents<RoutingModuleConfig, {
9351
- routes: Route | Routes;
9352
- } | {
9353
- waypoints: PlanningWaypoint[] | Waypoints;
9354
- }>;
9355
- };
10236
+ get events(): RoutingEvents;
9356
10237
  /**
9357
10238
  * Returns the map style layer under which route lines are rendered.
9358
10239
  * * Useful if you want to render extra layers just above the route ones but not on top of everything else.
@@ -9600,9 +10481,13 @@ type AreaAnalyticsBeforeLayerConfig = {
9600
10481
  */
9601
10482
  type AreaAnalyticsRegionPolygonConfig = {
9602
10483
  /**
9603
- * Color used for both the fill and outline of the region boundary.
10484
+ * CSS colour used for both the fill and outline of the region boundary.
9604
10485
  *
9605
- * @defaultValue '#000000'
10486
+ * When omitted, a theme-adaptive default is used. Known standard styles are classified as
10487
+ * light or dark; a custom style is treated as light, so set `color` explicitly if a custom
10488
+ * style is dark.
10489
+ *
10490
+ * @defaultValue Black (`#000000`) on light styles, white (`#FFFFFF`) on dark styles
9606
10491
  */
9607
10492
  color?: string;
9608
10493
  /**
@@ -9722,9 +10607,11 @@ declare const AREA_ANALYTICS_DEFAULTS: {
9722
10607
  };
9723
10608
  };
9724
10609
  };
9725
- /** @see {@link AreaAnalyticsRegionPolygonConfig} */
10610
+ /**
10611
+ * @see {@link AreaAnalyticsRegionPolygonConfig}
10612
+ * `color` is omitted — the layer builders apply a theme-adaptive default.
10613
+ */
9726
10614
  regionPolygon: {
9727
- color: string;
9728
10615
  fillOpacity: number;
9729
10616
  outlineOpacity: number;
9730
10617
  outlineWidth: number;
@@ -9808,7 +10695,7 @@ type TrafficAreaAnalyticsConfig = MapModuleCommonConfig & {
9808
10695
  * Resolves the effective color stops for a given color configuration.
9809
10696
  * @ignore
9810
10697
  */
9811
- declare const resolveColorStops: (colorConfig: AreaAnalyticsColorTheme | AreaAnalyticsColorStopsConfig) => AreaAnalyticsColorStop[];
10698
+ export declare const resolveColorStops: (colorConfig: AreaAnalyticsColorTheme | AreaAnalyticsColorStopsConfig) => AreaAnalyticsColorStop[];
9812
10699
  //#endregion
9813
10700
  //#region src/traffic/types/trafficAreaAnalyticsFeature.d.ts
9814
10701
  /**
@@ -9821,7 +10708,7 @@ declare const resolveColorStops: (colorConfig: AreaAnalyticsColorTheme | AreaAna
9821
10708
  *
9822
10709
  * @group Traffic Area Analytics
9823
10710
  */
9824
- type AreaAnalyticsDisplayProperties = AreaAnalyticsMetrics & SupportsEvents & {
10711
+ export type AreaAnalyticsDisplayProperties = AreaAnalyticsMetrics & SupportsEvents & {
9825
10712
  /**
9826
10713
  * Stable feature identifier (typically the tile centre coordinates stringified
9827
10714
  * or the H3 cell index).
@@ -9833,7 +10720,7 @@ type AreaAnalyticsDisplayProperties = AreaAnalyticsMetrics & SupportsEvents & {
9833
10720
  *
9834
10721
  * @group Traffic Area Analytics
9835
10722
  */
9836
- type AreaAnalyticsTileFeature = Feature<Point | Polygon, AreaAnalyticsDisplayProperties>;
10723
+ export type AreaAnalyticsTileFeature = Feature<Point | Polygon, AreaAnalyticsDisplayProperties>;
9837
10724
  //#endregion
9838
10725
  //#region src/traffic/TrafficAreaAnalyticsModule.d.ts
9839
10726
  /**
@@ -9864,7 +10751,7 @@ type AreaAnalyticsSourcesWithLayers = {
9864
10751
  * import { TrafficAreaAnalyticsModule } from '@tomtom-org/maps-sdk/map';
9865
10752
  * import { trafficAreaAnalytics } from '@tomtom-org/maps-sdk/services';
9866
10753
  *
9867
- * const module = await TrafficAreaAnalyticsModule.get(map, {
10754
+ * const module = await TrafficAreaAnalyticsModule.create(map, {
9868
10755
  * displayMode: 'hexgrid-3d',
9869
10756
  * metric: { active: 'congestionLevel' },
9870
10757
  * });
@@ -9874,7 +10761,7 @@ type AreaAnalyticsSourcesWithLayers = {
9874
10761
  *
9875
10762
  * @group Traffic Area Analytics
9876
10763
  */
9877
- declare class TrafficAreaAnalyticsModule extends AbstractMapModule<AreaAnalyticsSourcesWithLayers, TrafficAreaAnalyticsConfig> {
10764
+ export declare class TrafficAreaAnalyticsModule extends AbstractDataOwnedMapModule<AreaAnalyticsSourcesWithLayers, TrafficAreaAnalyticsConfig> {
9878
10765
  private heatmapLayerSpec;
9879
10766
  private hexFillLayerSpec;
9880
10767
  private hexExtrusionLayerSpec;
@@ -9893,10 +10780,14 @@ declare class TrafficAreaAnalyticsModule extends AbstractMapModule<AreaAnalytics
9893
10780
  *
9894
10781
  * All configuration properties are optional. When `config` is omitted (or only
9895
10782
  * partially supplied), built-in defaults are applied for every missing field.
9896
- * After `get()` resolves, {@link TrafficAreaAnalyticsModule.getConfig} always returns a
10783
+ * After `create()` resolves, {@link TrafficAreaAnalyticsModule.getConfig} always returns a
9897
10784
  * fully-populated configuration — there is no need to reference any default
9898
10785
  * values yourself.
9899
10786
  *
10787
+ * `TrafficAreaAnalyticsModule` owns the sources, layers and images it adds, all suffixed per
10788
+ * instance. Every call therefore returns a **new, independent** instance, and stacking several
10789
+ * of them on one map is a supported thing to do.
10790
+ *
9900
10791
  * @param tomtomMap - The TomTomMap instance.
9901
10792
  * @param config - Optional initial configuration. Omit to use all defaults.
9902
10793
  * @returns A promise that resolves with the initialised module.
@@ -9904,11 +10795,11 @@ declare class TrafficAreaAnalyticsModule extends AbstractMapModule<AreaAnalytics
9904
10795
  * @example
9905
10796
  * ```typescript
9906
10797
  * // No config needed — defaults are applied automatically.
9907
- * const module = await TrafficAreaAnalyticsModule.get(map);
10798
+ * const module = await TrafficAreaAnalyticsModule.create(map);
9908
10799
  * await module.show(analytics);
9909
10800
  *
9910
10801
  * // Or override specific properties while keeping everything else at default:
9911
- * const module = await TrafficAreaAnalyticsModule.get(map, {
10802
+ * const module = await TrafficAreaAnalyticsModule.create(map, {
9912
10803
  * displayMode: 'heatmap',
9913
10804
  * metricConfig: {
9914
10805
  * congestionLevel: { color: 'heat' },
@@ -9916,13 +10807,15 @@ declare class TrafficAreaAnalyticsModule extends AbstractMapModule<AreaAnalytics
9916
10807
  * });
9917
10808
  * ```
9918
10809
  */
9919
- static get(tomtomMap: TomTomMap, config?: TrafficAreaAnalyticsConfig): Promise<TrafficAreaAnalyticsModule>;
10810
+ static create(tomtomMap: TomTomMap, config?: TrafficAreaAnalyticsConfig): Promise<TrafficAreaAnalyticsModule>;
9920
10811
  private constructor();
9921
10812
  /** @ignore */
9922
10813
  protected _initSourcesWithLayers(config?: TrafficAreaAnalyticsConfig, _restore?: boolean): AreaAnalyticsSourcesWithLayers;
9923
10814
  /** @ignore */
9924
10815
  protected _applyConfig(config: TrafficAreaAnalyticsConfig | undefined): TrafficAreaAnalyticsConfig | undefined;
9925
10816
  /** @ignore */
10817
+ protected discardShownData(): void;
10818
+ /** @ignore */
9926
10819
  protected restoreDataAndConfigImpl(): void;
9927
10820
  /**
9928
10821
  * Displays area analytics data on the map.
@@ -10084,6 +10977,7 @@ declare class TrafficAreaAnalyticsModule extends AbstractMapModule<AreaAnalytics
10084
10977
  get events(): CombinedEvents<AreaAnalyticsTileFeature, TrafficAreaAnalyticsConfig, TrafficAreaAnalytics>;
10085
10978
  private get mode();
10086
10979
  private get activeMetric();
10980
+ private get lightDark();
10087
10981
  private applyModeVisibility;
10088
10982
  private hideAllDataLayers;
10089
10983
  private addHighlightLayersToMap;
@@ -10104,7 +10998,7 @@ declare class TrafficAreaAnalyticsModule extends AbstractMapModule<AreaAnalytics
10104
10998
  *
10105
10999
  * @group Traffic
10106
11000
  */
10107
- declare const roadCategories: readonly ["motorway", "motorway_link", "trunk", "trunk_link", "primary", "primary_link", "secondary", "secondary_link", "tertiary", "tertiary_link", "street", "service", "track"];
11001
+ export declare const roadCategories: readonly ["motorway", "motorway_link", "trunk", "trunk_link", "primary", "primary_link", "secondary", "secondary_link", "tertiary", "tertiary_link", "street", "service", "track"];
10108
11002
  /**
10109
11003
  * Road hierarchy category type.
10110
11004
  *
@@ -10124,7 +11018,7 @@ declare const roadCategories: readonly ["motorway", "motorway_link", "trunk", "t
10124
11018
  *
10125
11019
  * @group Traffic
10126
11020
  */
10127
- type RoadCategory = (typeof roadCategories)[number];
11021
+ export type RoadCategory = (typeof roadCategories)[number];
10128
11022
  /**
10129
11023
  * Available street road sub-category identifiers.
10130
11024
  *
@@ -10133,7 +11027,7 @@ type RoadCategory = (typeof roadCategories)[number];
10133
11027
  *
10134
11028
  * @group Traffic
10135
11029
  */
10136
- declare const streetRoadSubCategories: readonly ["unclassified", "residential", "living_street"];
11030
+ export declare const streetRoadSubCategories: readonly ["unclassified", "residential", "living_street"];
10137
11031
  /**
10138
11032
  * Street road sub-category type.
10139
11033
  *
@@ -10147,7 +11041,7 @@ declare const streetRoadSubCategories: readonly ["unclassified", "residential",
10147
11041
  *
10148
11042
  * @group Traffic
10149
11043
  */
10150
- type StreetRoadSubCategory = (typeof streetRoadSubCategories)[number];
11044
+ export type StreetRoadSubCategory = (typeof streetRoadSubCategories)[number];
10151
11045
  /**
10152
11046
  * Available service road sub-category identifiers.
10153
11047
  *
@@ -10156,7 +11050,7 @@ type StreetRoadSubCategory = (typeof streetRoadSubCategories)[number];
10156
11050
  *
10157
11051
  * @group Traffic
10158
11052
  */
10159
- declare const serviceRoadSubCategories: readonly ["parking", "driveway", "alley"];
11053
+ export declare const serviceRoadSubCategories: readonly ["parking", "driveway", "alley"];
10160
11054
  /**
10161
11055
  * Service road sub-category type.
10162
11056
  *
@@ -10170,7 +11064,7 @@ declare const serviceRoadSubCategories: readonly ["parking", "driveway", "alley"
10170
11064
  *
10171
11065
  * @group Traffic
10172
11066
  */
10173
- type ServiceRoadSubCategory = (typeof serviceRoadSubCategories)[number];
11067
+ export type ServiceRoadSubCategory = (typeof serviceRoadSubCategories)[number];
10174
11068
  /**
10175
11069
  * Road sub-category type.
10176
11070
  *
@@ -10179,7 +11073,7 @@ type ServiceRoadSubCategory = (typeof serviceRoadSubCategories)[number];
10179
11073
  *
10180
11074
  * @group Traffic
10181
11075
  */
10182
- type RoadSubCategory = StreetRoadSubCategory | ServiceRoadSubCategory;
11076
+ export type RoadSubCategory = StreetRoadSubCategory | ServiceRoadSubCategory;
10183
11077
  /**
10184
11078
  * Common filter configuration shared between traffic incidents and flow visualization.
10185
11079
  *
@@ -10188,7 +11082,7 @@ type RoadSubCategory = StreetRoadSubCategory | ServiceRoadSubCategory;
10188
11082
  *
10189
11083
  * @group Traffic
10190
11084
  */
10191
- type TrafficCommonFilter = {
11085
+ export type TrafficCommonFilter = {
10192
11086
  /**
10193
11087
  * Filters traffic data by road hierarchy categories.
10194
11088
  *
@@ -10229,7 +11123,7 @@ type TrafficCommonFilter = {
10229
11123
  *
10230
11124
  * @group Traffic Flow
10231
11125
  */
10232
- type TrafficFlowFilter = TrafficCommonFilter & {
11126
+ export type TrafficFlowFilter = TrafficCommonFilter & {
10233
11127
  /**
10234
11128
  * Controls road closure display in the traffic flow layer.
10235
11129
  *
@@ -10267,7 +11161,7 @@ type TrafficFlowFilter = TrafficCommonFilter & {
10267
11161
  *
10268
11162
  * @group Traffic Flow
10269
11163
  */
10270
- type TrafficFlowFilters = {
11164
+ export type TrafficFlowFilters = {
10271
11165
  /**
10272
11166
  * Array of flow filters combined with OR logic.
10273
11167
  *
@@ -10285,7 +11179,7 @@ type TrafficFlowFilters = {
10285
11179
  *
10286
11180
  * @group Traffic Flow
10287
11181
  */
10288
- type FlowConfig = MapModuleCommonConfig & {
11182
+ export type FlowConfig = MapModuleCommonConfig & {
10289
11183
  /**
10290
11184
  * Controls the visibility of the traffic flow layers.
10291
11185
  *
@@ -10309,7 +11203,7 @@ type FlowConfig = MapModuleCommonConfig & {
10309
11203
  *
10310
11204
  * @group Traffic Flow
10311
11205
  */
10312
- type TrafficFlowModuleFeature = Feature<LineString, {
11206
+ export type TrafficFlowModuleFeature = Feature<LineString, {
10313
11207
  /**
10314
11208
  * Road hierarchy category type.
10315
11209
  */
@@ -10429,7 +11323,7 @@ type TrafficFlowSourcesWithLayers = {
10429
11323
  *
10430
11324
  * @group Traffic Flow
10431
11325
  */
10432
- declare class TrafficFlowModule extends AbstractMapModule<TrafficFlowSourcesWithLayers, FlowConfig> {
11326
+ export declare class TrafficFlowModule extends AbstractStyleOwnedMapModule<TrafficFlowSourcesWithLayers, FlowConfig> {
10433
11327
  private originalFilters;
10434
11328
  /**
10435
11329
  * Retrieves a TrafficFlowModule instance for the given map.
@@ -10471,6 +11365,12 @@ declare class TrafficFlowModule extends AbstractMapModule<TrafficFlowSourcesWith
10471
11365
  * }
10472
11366
  * });
10473
11367
  * ```
11368
+ *
11369
+ * @remarks
11370
+ * **Instances:**
11371
+ * `TrafficFlowModule` controls the traffic-flow source and layers the map style already
11372
+ * provides, under fixed global IDs. Every instance is another handle on that same shared state,
11373
+ * so visibility and filters applied through one are visible through all of them.
10474
11374
  */
10475
11375
  static get(map: TomTomMap, config?: FlowConfig): Promise<TrafficFlowModule>;
10476
11376
  private constructor();
@@ -10625,7 +11525,9 @@ declare class TrafficFlowModule extends AbstractMapModule<TrafficFlowSourcesWith
10625
11525
  */
10626
11526
  type IncidentFocusStyle = {
10627
11527
  /**
10628
- * Colour of the outline painted beneath the focused stripe. Defaults to `#000`.
11528
+ * Colour of the outline painted beneath the focused stripe.
11529
+ *
11530
+ * @defaultValue `#000` on light map styles, `#FFF` on dark styles
10629
11531
  */
10630
11532
  outlineColor?: string;
10631
11533
  /**
@@ -10657,8 +11559,8 @@ type TrafficIncidentOverlayConfig = MapModuleCommonConfig & {
10657
11559
  /**
10658
11560
  * Visual treatment for {@link TrafficIncidentOverlayModule.setFocus}.
10659
11561
  *
10660
- * - Omit (or `undefined`) — use the SDK default treatment: a black outline
10661
- * beneath the focused stripe and a `1.6×` width pop.
11562
+ * - Omit (or `undefined`) — use the SDK default treatment: an outline beneath
11563
+ * the focused stripe (black on light map styles, white on dark) and a `1.6×` width pop.
10662
11564
  * - `false` — disable the visual treatment. `setFocus(ids)` still writes
10663
11565
  * MapLibre `feature-state.focused`, so callers can drive their own
10664
11566
  * styling (extra layers, sidebar overlays, …) off that state.
@@ -10696,8 +11598,9 @@ type Sources = {
10696
11598
  * ## Focus
10697
11599
  *
10698
11600
  * {@link setFocus} writes MapLibre feature-state `focused=true|false` on each rendered
10699
- * incident. The default visual treatment widens the focused subset and paints a black
10700
- * outline beneath it; unfocused incidents are unchanged. Override or disable the visual
11601
+ * incident. The default visual treatment widens the focused subset and paints an
11602
+ * outline beneath it (black on light map styles, white on dark); unfocused incidents
11603
+ * are unchanged. Override or disable the visual
10701
11604
  * treatment via the `focus` config — `focus: false` keeps `setFocus` writing feature-state
10702
11605
  * but emits no halo layer and no width pop, leaving callers free to drive their own
10703
11606
  * styling off `feature-state.focused`.
@@ -10745,7 +11648,7 @@ type Sources = {
10745
11648
  *
10746
11649
  * const map = new TomTomMap({ mapLibre: { container: 'map', center: [4.9, 52.37], zoom: 13 } });
10747
11650
  *
10748
- * const overlay = await TrafficIncidentOverlayModule.get(map);
11651
+ * const overlay = await TrafficIncidentOverlayModule.create(map);
10749
11652
  * const result = await trafficIncidentDetails({
10750
11653
  * bbox: [4.85, 52.34, 4.95, 52.40],
10751
11654
  * timeValidityFilter: ['present'],
@@ -10764,12 +11667,23 @@ type Sources = {
10764
11667
  *
10765
11668
  * @group Traffic
10766
11669
  */
10767
- declare class TrafficIncidentOverlayModule extends AbstractMapModule<Sources, TrafficIncidentOverlayConfig> {
11670
+ export declare class TrafficIncidentOverlayModule extends AbstractDataOwnedMapModule<Sources, TrafficIncidentOverlayConfig> {
10768
11671
  private lastResult;
10769
11672
  private lastFeatureIds;
10770
11673
  private lastFocusIds;
10771
11674
  private readonly shownFeaturesHandlers;
10772
- static get(tomtomMap: TomTomMap, config?: TrafficIncidentOverlayConfig): Promise<TrafficIncidentOverlayModule>;
11675
+ /**
11676
+ * Creates a new module instance on the given map, waiting until the map is ready first.
11677
+ *
11678
+ * `TrafficIncidentOverlayModule` owns the sources, layers and images it adds, all suffixed per
11679
+ * instance. Every call therefore returns a **new, independent** instance, and stacking several
11680
+ * of them on one map is a supported thing to do.
11681
+ *
11682
+ * @param tomtomMap The TomTomMap instance.
11683
+ * @param config The module optional configuration.
11684
+ * @returns {Promise} Returns a promise with a new instance of this module.
11685
+ */
11686
+ static create(tomtomMap: TomTomMap, config?: TrafficIncidentOverlayConfig): Promise<TrafficIncidentOverlayModule>;
10773
11687
  private constructor();
10774
11688
  /** @ignore */
10775
11689
  protected _initSourcesWithLayers(config?: TrafficIncidentOverlayConfig, _restore?: boolean): Sources;
@@ -10777,6 +11691,8 @@ declare class TrafficIncidentOverlayModule extends AbstractMapModule<Sources, Tr
10777
11691
  protected _applyConfig(config: TrafficIncidentOverlayConfig | undefined): TrafficIncidentOverlayConfig | undefined;
10778
11692
  private applyBeforeLayer;
10779
11693
  /** @ignore */
11694
+ protected discardShownData(): void;
11695
+ /** @ignore */
10780
11696
  protected restoreDataAndConfigImpl(): void;
10781
11697
  /**
10782
11698
  * Render the service result. Replaces any previously shown snapshot.
@@ -10815,7 +11731,7 @@ declare class TrafficIncidentOverlayModule extends AbstractMapModule<Sources, Tr
10815
11731
  * Mark a subset of currently-rendered incidents as "focused" via MapLibre
10816
11732
  * feature-state. `null` clears the state. Paint expressions in
10817
11733
  * `incidentDetailsLayers.ts` read `['feature-state', 'focused']` and pop the
10818
- * focused subset (wider stripe + black outline). Unfocused features are
11734
+ * focused subset (wider stripe + a theme-aware outline). Unfocused features are
10819
11735
  * unchanged — the focus treatment adds emphasis, it does not dim the rest.
10820
11736
  *
10821
11737
  * No effect if called before `show()`.
@@ -10834,7 +11750,7 @@ declare class TrafficIncidentOverlayModule extends AbstractMapModule<Sources, Tr
10834
11750
  *
10835
11751
  * @group Traffic Incidents
10836
11752
  */
10837
- type DelayFilter = {
11753
+ export type DelayFilter = {
10838
11754
  /**
10839
11755
  * Requires incidents to have an associated delay.
10840
11756
  *
@@ -10872,7 +11788,7 @@ type DelayFilter = {
10872
11788
  *
10873
11789
  * @group Traffic Incidents
10874
11790
  */
10875
- type TrafficIncidentsFilter = TrafficCommonFilter & {
11791
+ export type TrafficIncidentsFilter = TrafficCommonFilter & {
10876
11792
  /**
10877
11793
  * Filters incidents by category type.
10878
11794
  *
@@ -10943,7 +11859,7 @@ type TrafficIncidentsFilter = TrafficCommonFilter & {
10943
11859
  *
10944
11860
  * @group Traffic Incidents
10945
11861
  */
10946
- type TrafficIncidentsFilters = {
11862
+ export type TrafficIncidentsFilters = {
10947
11863
  /**
10948
11864
  * Array of incident filters combined with OR logic.
10949
11865
  *
@@ -10961,7 +11877,7 @@ type TrafficIncidentsFilters = {
10961
11877
  *
10962
11878
  * @group Traffic Incidents
10963
11879
  */
10964
- type IncidentsCommonConfig = {
11880
+ export type IncidentsCommonConfig = {
10965
11881
  /**
10966
11882
  * Controls the visibility of the traffic incident layers.
10967
11883
  *
@@ -10985,7 +11901,7 @@ type IncidentsCommonConfig = {
10985
11901
  *
10986
11902
  * @group Traffic Incidents
10987
11903
  */
10988
- type IncidentsConfig = MapModuleCommonConfig & IncidentsCommonConfig & {
11904
+ export type IncidentsConfig = MapModuleCommonConfig & IncidentsCommonConfig & {
10989
11905
  /**
10990
11906
  * Configuration specific to incident icon display.
10991
11907
  *
@@ -11000,7 +11916,7 @@ type IncidentsConfig = MapModuleCommonConfig & IncidentsCommonConfig & {
11000
11916
  /**
11001
11917
  * Defines the structure of a traffic incident feature, which extends the basic GeoJSON feature with specific properties related to traffic incidents. This type is used to represent individual traffic incidents on the map, providing details such as the description of the incident, its severity, and the road category where it is occurring.
11002
11918
  */
11003
- type TrafficIncidentsModuleFeature = Feature<Geometry, TrafficIncidentBaseProperties & {
11919
+ export type TrafficIncidentsModuleFeature = Feature<Geometry, TrafficIncidentBaseProperties & {
11004
11920
  /**
11005
11921
  * Description of the traffic incident, providing details about the nature of the incident.
11006
11922
  */
@@ -11161,7 +12077,7 @@ type TrafficIncidentsSourcesWithLayers = {
11161
12077
  *
11162
12078
  * @group Traffic Incidents
11163
12079
  */
11164
- declare class TrafficIncidentsModule extends AbstractMapModule<TrafficIncidentsSourcesWithLayers, IncidentsConfig> {
12080
+ export declare class TrafficIncidentsModule extends AbstractStyleOwnedMapModule<TrafficIncidentsSourcesWithLayers, IncidentsConfig> {
11165
12081
  private originalFilters;
11166
12082
  /**
11167
12083
  * Retrieves a TrafficIncidentsModule instance for the given map.
@@ -11203,6 +12119,12 @@ declare class TrafficIncidentsModule extends AbstractMapModule<TrafficIncidentsS
11203
12119
  * }
11204
12120
  * });
11205
12121
  * ```
12122
+ *
12123
+ * @remarks
12124
+ * **Instances:**
12125
+ * `TrafficIncidentsModule` controls the traffic-incident source and layers the map style already
12126
+ * provides, under fixed global IDs. Every instance is another handle on that same shared state,
12127
+ * so visibility and filters applied through one are visible through all of them.
11206
12128
  */
11207
12129
  static get(map: TomTomMap, config?: IncidentsConfig): Promise<TrafficIncidentsModule>;
11208
12130
  private constructor();
@@ -11406,7 +12328,7 @@ declare class TrafficIncidentsModule extends AbstractMapModule<TrafficIncidentsS
11406
12328
  *
11407
12329
  * @group Utils
11408
12330
  */
11409
- type CalculateMapCenterOptions = {
12331
+ export type CalculateMapCenterOptions = {
11410
12332
  /** The TomTomMap instance or MapLibre map instance */
11411
12333
  map: TomTomMap | Map;
11412
12334
  /** Array of HTML elements or DOM selector strings that are positioned over the map */
@@ -11417,7 +12339,7 @@ type CalculateMapCenterOptions = {
11417
12339
  *
11418
12340
  * @group Utils
11419
12341
  */
11420
- type CalculateMapBoundsOptions = CalculateMapCenterOptions & {
12342
+ export type CalculateMapBoundsOptions = CalculateMapCenterOptions & {
11421
12343
  /**
11422
12344
  * Additional padding in pixels to apply around the UI elements or map edges. Default is 0.
11423
12345
  */
@@ -11428,7 +12350,7 @@ type CalculateMapBoundsOptions = CalculateMapCenterOptions & {
11428
12350
  *
11429
12351
  * @group Utils
11430
12352
  */
11431
- type CalculateFittingBBoxOptions = CalculateMapBoundsOptions & {
12353
+ export type CalculateFittingBBoxOptions = CalculateMapBoundsOptions & {
11432
12354
  /**
11433
12355
  * The target bounding box [west, south, east, north] that should be contained in the unobscured area
11434
12356
  */
@@ -11448,7 +12370,7 @@ type CalculateFittingBBoxOptions = CalculateMapBoundsOptions & {
11448
12370
  *
11449
12371
  * @group Utils
11450
12372
  */
11451
- declare const calculatePaddedBBox: (options: CalculateMapBoundsOptions) => BBox | null;
12373
+ export declare const calculatePaddedBBox: (options: CalculateMapBoundsOptions) => BBox | null;
11452
12374
  /**
11453
12375
  * Calculates the center point in lng-lat coordinates of the visible map area
11454
12376
  * that does not overlap with the given UI HTML elements.
@@ -11462,7 +12384,7 @@ declare const calculatePaddedBBox: (options: CalculateMapBoundsOptions) => BBox
11462
12384
  *
11463
12385
  * @group Utils
11464
12386
  */
11465
- declare const calculatePaddedCenter: (options: CalculateMapCenterOptions) => Position | null;
12387
+ export declare const calculatePaddedCenter: (options: CalculateMapCenterOptions) => Position | null;
11466
12388
  /**
11467
12389
  * Calculates an expanded bounding box that, when the map is zoomed to it, ensures that the given to-be-contained bounding box
11468
12390
  * is visible within the area not obscured by surrounding UI elements, including optional padding.
@@ -11478,6 +12400,6 @@ declare const calculatePaddedCenter: (options: CalculateMapCenterOptions) => Pos
11478
12400
  *
11479
12401
  * @group Utils
11480
12402
  */
11481
- declare const calculateFittingBBox: (options: CalculateFittingBBoxOptions) => BBox | null;
12403
+ export declare const calculateFittingBBox: (options: CalculateFittingBBoxOptions) => BBox | null;
11482
12404
  //#endregion
11483
- export { type AREA_ANALYTICS_DEFAULTS, AbstractMapModule, AbstractSourceWithLayers, AddedSourceWithLayers, type AreaAnalyticsBeforeLayerConfig, type AreaAnalyticsColorStop, type AreaAnalyticsColorStopsConfig, type AreaAnalyticsColorTheme, type AreaAnalyticsDisplayMode, AreaAnalyticsDisplayProperties, type AreaAnalyticsHeightConfig, type AreaAnalyticsMetricConfig, type AreaAnalyticsMetricFilter, type AreaAnalyticsRegionPolygonConfig, AreaAnalyticsTileFeature, type AreaAnalyticsValueType, type AvailabilityLevel, BASE_MAP_SOURCE_ID, BaseMapLayerGroupName, BaseMapLayerGroups, BaseMapLayerGroupsVisibility, BaseMapModule, BaseMapModuleConfig, BaseMapModuleInitConfig, type BeforeLayerConfig, type ByIdOrIndex, type CSSCursor, CalculateFittingBBoxOptions, CalculateMapBoundsOptions, CalculateMapCenterOptions, type ChargingSpeedIconMapping, type ChargingStopIconConfig, type ChargingStopIconMapping, type ChargingStopTextConfig, type ChargingStopsConfig, type CleanEventStateOptions, type CleanEventStatesOptions, type ClickEventType, ColorPaletteOptions, CombinedEvents, CustomGeoJSONEvents, CustomGeoJSONImageData, CustomGeoJSONImageSpec, CustomGeoJSONLayerSpec, CustomGeoJSONModule, CustomGeoJSONModuleConfig, CustomGeoJSONSourceSpec, type CustomImage, CustomStyle, DESELECTED_FOREGROUND_COLOR, DESELECTED_OUTLINE_COLOR, DESELECTED_ROUTE_FILTER, DESELECTED_SECONDARY_COLOR, type DefaultPlaceIconConfig, DelayFilter, DisplayGeometryProps, DisplayPlaceProps, type DisplayRouteProps, type DisplayRouteRelatedProps, type DisplayRouteSummaries, type DisplayRouteSummary, type DisplayRouteSummaryProps, type EVAvailabilityConfig, type EventHandlerConfig, type EventHandlerCursorConfig, type EventType, EventsProxy, ExtraGeometryDisplayProps, FINISH_INDEX, type FilterShowMode, type FilterSyntaxVersion, type FilterablePOICategory, FlowConfig, GeoJSONSourceClusterOptions, GeoJSONSourceWithLayers, GeometriesModule, GeometriesModuleConfig, GeometryBeforeLayerConfig, GeometryBeforeLayerTargets, GeometryFillConfig, GeometryLineConfig, GeometryLineLabelConfig, GeometryTextConfig, GeometryTheme, HILLSHADE_SOURCE_ID, type HasAdditionalLayersConfig, type HasBeforeID, HillshadeModule, type HillshadeModuleConfig, type HoverEventType, INDEFINITE_DELAY_DASH_COLOR, INDEX_TYPE, type IncidentFocusStyle, IncidentsCommonConfig, IncidentsConfig, IndexedFeature, InternalTomTomMapParams, type LayerSpecFilter, type LayerSpecTemplate, type LayerSpecWithSource, type LightDark, MAJOR_DELAY_COLOR, MIDDLE_INDEX, MINOR_DELAY_COLOR, MINOR_DELAY_LABEL_COLOR, MODERATE_DELAY_COLOR, type MapEventsConfig, type MapFont, MapLibreOptions, type MapModuleCommonConfig, type MapStyleLayerID, MapStylePOICategory, ModuleEvents, type MultiSyntaxFilter, POICategoryGroup, POI_SOURCE_ID, POIsModule, type POIsModuleConfig, type POIsModuleFeature, type PlaceConnectionDisplay, type PlaceConnectionLayerName, type PlaceConnectionsConfig, type PlaceConnectionsLayersConfig, PlaceDisplayProps, type PlaceIconConfig, type PlaceLayerName, type PlaceLayersConfig, type PlaceTextConfig, PlacesModule, type PlacesModuleConfig, type PlacesTheme, type PlanningWaypoint, type PutEventStateOptions, ROUTE_LINE_FOREGROUND_COLOR, ROUTE_LINE_FOREGROUND_WIDTH, ROUTE_LINE_OUTLINE_COLOR, ROUTE_LINE_OUTLINE_WIDTH, ReachableRangeLabelFn, RenderedRef, RoadCategory, RoadSubCategory, type RouteLayersConfig, type RouteStateProps, type RouteTheme, type RouteWaypointSize, type RouteWidth, RoutingModule, type RoutingModuleConfig, SELECTED_ROUTE_FILTER, START_INDEX, STOP_DISPLAY_INDEX, type SVGIconStyleOptions, ServiceRoadSubCategory, ShowOptions, type SourceWithLayerIDs, type SourceWithLayers, type SourcesWithLayers, StandardStyle, StandardStyleID, StreetRoadSubCategory, StyleChangeHandler, StyleInput, StyleModule, StyleSourceWithLayers, type SupportsEvents, type SymbolLayerSpecWithoutSource, TRAFFIC_FLOW_SOURCE_ID, TRAFFIC_INCIDENTS_SOURCE_ID, type ToBeAddedLayerSpec, type ToBeAddedLayerSpecTemplate, type ToBeAddedLayerSpecWithoutSource, TomTomMap, TomTomMapParams, TomTomMapSource, type TrafficAreaAnalyticsConfig, TrafficAreaAnalyticsModule, TrafficCommonFilter, TrafficFlowFilter, TrafficFlowFilters, TrafficFlowModule, TrafficFlowModuleFeature, type TrafficIncidentOverlayConfig, TrafficIncidentOverlayModule, TrafficIncidentsFilter, TrafficIncidentsFilters, TrafficIncidentsModule, TrafficIncidentsModuleFeature, UNKNOWN_DELAY_BG_COLOR, UNKNOWN_DELAY_COLOR, UNKNOWN_DELAY_DASH_COLOR, type UserEventHandler, UserEvents, type ValuesFilter, WaypointDisplayProps, WaypointIndexType, type WaypointsConfig, baseMapLayerGroupNames, baseMapPOICategoryValues, buildPlaceTitle, buildReachableRangeFeatures, buildRoutingLayers, calculateFittingBBox, calculatePaddedBBox, calculatePaddedCenter, colorPaletteIDs, colorPalettes, defaultRoutingLayers, filterLayersBySources, findFeatureByRefId, geometryThemes, getIconIDForPlace, getInstructionLineWidth, getInstructionOutlineWidth, getLineForegroundWidth, getLineOutlineWidth, getPOIGroupForPlace, getPOILayerCategoryForPlace, getStyleCategories, getTollRoadOutlineWidth, getWaypointIconSize, mapDisplayPoiCategoryMappings, mapStyleLayerIDs, poiCategoryGroups, poiLayerIDs, preparePlacesForDisplay, prepareReachableRangesForDisplay, reachableRangeGeometryConfig, renderedRefId, resolveColorStops, roadCategories, serviceRoadSubCategories, standardStyleIDs, streetRoadSubCategories, styleModules, themedGeometryConfig, toBaseMapPOICategory, toBaseMapPOIGroup, toPlaces };
12405
+ export type { AREA_ANALYTICS_DEFAULTS, AreaAnalyticsBeforeLayerConfig, AreaAnalyticsColorStop, AreaAnalyticsColorStopsConfig, AreaAnalyticsColorTheme, AreaAnalyticsDisplayMode, AreaAnalyticsHeightConfig, AreaAnalyticsMetricConfig, AreaAnalyticsMetricFilter, AreaAnalyticsRegionPolygonConfig, AreaAnalyticsValueType, AvailabilityLevel, BeforeLayerConfig, ByIdOrIndex, CSSCursor, ChargingSpeedIconMapping, ChargingStopIconConfig, ChargingStopIconMapping, ChargingStopTextConfig, ChargingStopsConfig, CleanEventStateOptions, CleanEventStatesOptions, ClickEventType, CustomImage, DefaultPlaceIconConfig, DisplayRouteProps, DisplayRouteRelatedProps, DisplayRouteSummaries, DisplayRouteSummary, DisplayRouteSummaryProps, EVAvailabilityConfig, EventHandlerConfig, EventHandlerCursorConfig, EventType, FilterShowMode, FilterablePOICategory, GeoJSONSourcesWithLayers, HasAdditionalLayersConfig, HasBeforeID, HillshadeModuleConfig, HoverEventType, IncidentFocusStyle, LayerSpecFilter, LayerSpecTemplate, LayerSpecWithSource, LightDark, MapEventsConfig, MapFont, MapModuleCommonConfig, MapStyleLayerID, POIsModuleConfig, POIsModuleFeature, PlaceConnectionDisplay, PlaceConnectionLayerName, PlaceConnectionsConfig, PlaceConnectionsLayersConfig, PlaceIconConfig, PlaceLayerName, PlaceLayersConfig, PlaceTextConfig, PlacesModuleConfig, PlacesTheme, PlanningWaypoint, PutEventStateOptions, RouteLayersConfig, RouteStateProps, RouteTheme, RouteWaypointSize, RouteWidth, RoutingModuleConfig, SVGIconStyleOptions, SourceWithLayerIDs, SourceWithLayers, SourcesWithLayers, StyleSourcesWithLayers, SupportsEvents, SymbolLayerSpecWithoutSource, ToBeAddedLayerSpec, ToBeAddedLayerSpecTemplate, ToBeAddedLayerSpecWithoutSource, TrafficAreaAnalyticsConfig, TrafficIncidentOverlayConfig, UserEventHandler, ValuesFilter, WaypointsConfig };