@tomtom-org/maps-sdk 0.46.9 → 0.46.10

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,7 +1,7 @@
1
1
  import { Anything } from '@tomtom-org/maps-sdk/core';
2
+ import { AreaAnalyticsMetricKey } from '@tomtom-org/maps-sdk/core';
3
+ import { AreaAnalyticsMetricKey as AreaAnalyticsMetricKey_2 } from '@tomtom-org/maps-sdk/core';
2
4
  import { AreaAnalyticsMetrics } from '@tomtom-org/maps-sdk/core';
3
- import { AreaAnalyticsTileEntry } from '@tomtom-org/maps-sdk/core';
4
- import { AreaAnalyticsTimedEntry } from '@tomtom-org/maps-sdk/core';
5
5
  import { BackgroundLayerSpecification } from 'maplibre-gl';
6
6
  import { BBox } from '@tomtom-org/maps-sdk/core';
7
7
  import { BBox as BBox_2 } from '@tomtom-org/maps-sdk/core';
@@ -82,6 +82,16 @@ declare abstract class AbstractEventProxy {
82
82
  * @param config Optional configuration for the event handler.
83
83
  */
84
84
  addEventHandler<T = MapGeoJSONFeature>(sourceWithLayers: SourceWithLayers, handlerFn: UserEventHandler<T>, type: EventType, config: EventHandlerConfig | undefined): void;
85
+ /**
86
+ * Removes a single handler function for the given source and event type.
87
+ * Other handlers registered for the same source and type are not affected.
88
+ * Unlike {@link remove}, this does not remove the source from the interactive layer list —
89
+ * other handlers may still depend on it.
90
+ * @param sourceWithLayers The source whose handler should be removed.
91
+ * @param type The event type.
92
+ * @param handlerFn The exact function reference to remove.
93
+ */
94
+ removeHandler(sourceWithLayers: SourceWithLayers, type: EventType, handlerFn: UserEventHandler<any>): void;
85
95
  /**
86
96
  * Removes the given sources and layers from the interactive list. When not present, nothing happens.
87
97
  * @param type The event type to be removed.
@@ -163,6 +173,12 @@ export declare abstract class AbstractMapModule<SOURCES_WITH_LAYERS extends Sour
163
173
  * @ignore
164
174
  */
165
175
  protected _initializing: boolean;
176
+ /**
177
+ * Handlers registered via events.on('config-change', …).
178
+ * Stored here so the array reference stays stable across multiple events getter calls.
179
+ * @ignore
180
+ */
181
+ protected readonly configChangeHandlers: ((config: CFG | undefined) => void)[];
166
182
  /**
167
183
  * Indicates that this module is currently adding its sources and layers to the map, so during this time it might not function properly.
168
184
  * @see waitUntilModuleReady
@@ -219,6 +235,12 @@ export declare abstract class AbstractMapModule<SOURCES_WITH_LAYERS extends Sour
219
235
  * @see {@link getConfig} to retrieve the current configuration
220
236
  */
221
237
  applyConfig(config: CFG | undefined): void;
238
+ /**
239
+ * Emits a `config-change` event to all registered handlers.
240
+ * Skipped during module initialisation to avoid spurious events.
241
+ * @ignore
242
+ */
243
+ protected emitConfigChange(): void;
222
244
  /**
223
245
  * Internal implementation to apply config for the specific module.
224
246
  * @param config The config to apply. this.config contains the previous configuration (if any).
@@ -364,26 +386,245 @@ export declare class AddedSourceWithLayers<SOURCE_SPEC extends SourceSpecificati
364
386
  }
365
387
 
366
388
  /**
367
- * Preset color scheme for area analytics visualization.
389
+ * Default values for all {@link TrafficAreaAnalyticsConfig} options.
390
+ *
391
+ * Use these as a reference for what the module applies when a property is omitted,
392
+ * or spread them as a base when constructing a config programmatically.
393
+ *
394
+ * @group Traffic Area Analytics
395
+ */
396
+ export declare const AREA_ANALYTICS_DEFAULTS: {
397
+ /** @see {@link TrafficAreaAnalyticsConfig.visible} */
398
+ visible: true;
399
+ /** @see {@link TrafficAreaAnalyticsConfig.displayMode} */
400
+ displayMode: "hexgrid-3d";
401
+ /** @see {@link TrafficAreaAnalyticsConfig.activeMetric} */
402
+ activeMetric: "congestionLevel";
403
+ /** @see {@link TrafficAreaAnalyticsConfig.metricConfig} */
404
+ metricConfig: {
405
+ congestionLevel: {
406
+ color: {
407
+ valueType: "raw";
408
+ stops: {
409
+ value: number;
410
+ color: string;
411
+ }[];
412
+ };
413
+ height: {
414
+ maxHeightMeters: number;
415
+ minHeightMeters: number;
416
+ scaleMode: "predefinedRange";
417
+ };
418
+ };
419
+ speed: {
420
+ color: {
421
+ valueType: "relativeToPredefinedRangePCT";
422
+ stops: {
423
+ value: number;
424
+ color: string;
425
+ }[];
426
+ };
427
+ height: {
428
+ maxHeightMeters: number;
429
+ minHeightMeters: number;
430
+ scaleMode: "predefinedRange";
431
+ };
432
+ };
433
+ travelTime: {
434
+ color: {
435
+ valueType: "relativeToPredefinedRangePCT";
436
+ stops: {
437
+ value: number;
438
+ color: string;
439
+ }[];
440
+ };
441
+ height: {
442
+ maxHeightMeters: number;
443
+ minHeightMeters: number;
444
+ scaleMode: "predefinedRange";
445
+ };
446
+ };
447
+ freeFlowSpeed: {
448
+ color: {
449
+ valueType: "relativeToPredefinedRangePCT";
450
+ stops: {
451
+ value: number;
452
+ color: string;
453
+ }[];
454
+ };
455
+ height: {
456
+ maxHeightMeters: number;
457
+ minHeightMeters: number;
458
+ scaleMode: "predefinedRange";
459
+ };
460
+ };
461
+ networkLength: {
462
+ color: {
463
+ valueType: "relativeToActualRangePCT";
464
+ stops: {
465
+ value: number;
466
+ color: string;
467
+ }[];
468
+ };
469
+ height: {
470
+ maxHeightMeters: number;
471
+ minHeightMeters: number;
472
+ scaleMode: "currentRange";
473
+ };
474
+ };
475
+ };
476
+ /** @see {@link AreaAnalyticsRegionPolygonConfig} */
477
+ regionPolygon: {
478
+ color: string;
479
+ fillOpacity: number;
480
+ outlineOpacity: number;
481
+ outlineWidth: number;
482
+ inverted: false;
483
+ };
484
+ };
485
+
486
+ /**
487
+ * Per-layer-type positioning configuration for area analytics layers.
488
+ *
489
+ * Controls where each analytics layer type sits in the map's layer stack independently.
490
+ * Each property accepts `'top'` (above all layers) or a well-known style layer ID.
491
+ * Omitted properties fall back to their default positions.
492
+ *
493
+ * @example
494
+ * ```typescript
495
+ * // Move all layers below the lowest label
496
+ * const config: TrafficAreaAnalyticsConfig = {
497
+ * beforeLayerConfig: {
498
+ * heatmap: 'lowestLabel',
499
+ * hexgrid: { flat2D: 'lowestLabel', extrusion3D: 'lowestPlaceLabel' },
500
+ * square: { flat2D: 'lowestLabel', extrusion3D: 'lowestPlaceLabel' },
501
+ * },
502
+ * };
503
+ *
504
+ * // Only reposition the heatmap layer
505
+ * const config: TrafficAreaAnalyticsConfig = {
506
+ * beforeLayerConfig: { heatmap: 'top' },
507
+ * };
508
+ * ```
509
+ *
510
+ * @group Traffic Area Analytics
511
+ */
512
+ export declare type AreaAnalyticsBeforeLayerConfig = {
513
+ /** Layer position for the heatmap layer. Defaults to `'lowestLabel'`. */
514
+ heatmap?: BeforeLayerConfig;
515
+ hexgrid?: {
516
+ /** Layer position for the flat hexgrid fill layer. Defaults to `'lowestLabel'`. */
517
+ flat2D?: BeforeLayerConfig;
518
+ /** Layer position for the extruded hexgrid layer. Defaults to `'lowestPlaceLabel'`. */
519
+ extrusion3D?: BeforeLayerConfig;
520
+ };
521
+ square?: {
522
+ /** Layer position for the flat square fill layer. Defaults to `'lowestLabel'`. */
523
+ flat2D?: BeforeLayerConfig;
524
+ /** Layer position for the extruded square layer. Defaults to `'lowestPlaceLabel'`. */
525
+ extrusion3D?: BeforeLayerConfig;
526
+ };
527
+ };
528
+
529
+ /**
530
+ * A single stop in an analytics color ramp.
531
+ *
532
+ * How `value` is interpreted depends on the surrounding `AreaAnalyticsColorStopsConfig.valueType`.
533
+ * `color` is any valid CSS color string.
534
+ *
535
+ * @group Traffic Area Analytics
536
+ */
537
+ export declare type AreaAnalyticsColorStop = {
538
+ value: number;
539
+ color: string;
540
+ };
541
+
542
+ /**
543
+ * Custom color stops configuration with an explicit value-type hint.
544
+ *
545
+ * @example
546
+ * ```typescript
547
+ * // Stops whose values are actual congestion-level values (0–100)
548
+ * const color: AreaAnalyticsColorStopsConfig = {
549
+ * valueType: 'raw',
550
+ * stops: [
551
+ * { value: 0, color: '#2dc653' },
552
+ * { value: 30, color: '#f5a623' },
553
+ * { value: 100, color: '#e03030' },
554
+ * ],
555
+ * };
556
+ *
557
+ * // Stops as 0–100 % of the predefined metric range (speed: 0–120 km/h)
558
+ * const color: AreaAnalyticsColorStopsConfig = {
559
+ * valueType: 'relativeToPredefinedRangePCT',
560
+ * stops: [
561
+ * { value: 0, color: '#e03030' }, // 0 km/h
562
+ * { value: 50, color: '#f5a623' }, // 60 km/h
563
+ * { value: 100, color: '#2dc653' }, // 120 km/h
564
+ * ],
565
+ * };
566
+ *
567
+ * // Stops as 0–100 % of the live data range (maximum contrast regardless of absolute values)
568
+ * const color: AreaAnalyticsColorStopsConfig = {
569
+ * valueType: 'relativeToActualRangePCT',
570
+ * stops: [
571
+ * { value: 0, color: '#2dc653' }, // 0% = loaded minimum
572
+ * { value: 50, color: '#f5a623' }, // 50% = mid
573
+ * { value: 100, color: '#e03030' }, // 100% = loaded maximum
574
+ * ],
575
+ * };
576
+ * ```
577
+ *
578
+ * @group Traffic Area Analytics
579
+ */
580
+ export declare type AreaAnalyticsColorStopsConfig = {
581
+ /**
582
+ * How stop values are interpreted. Defaults to `'raw'`.
583
+ */
584
+ valueType?: AreaAnalyticsValueType;
585
+ /**
586
+ * The color stops array.
587
+ */
588
+ stops: AreaAnalyticsColorStop[];
589
+ };
590
+
591
+ /**
592
+ * Preset color theme for area analytics visualization.
368
593
  *
369
- * - `'congestion'` — Green → amber → red (default, traffic-signal style)
370
- * - `'thermal'` — Blue → orange → red (heat-map style)
594
+ * - `'trafficLight'` — Green → amber → red (default, traffic-signal style)
595
+ * - `'heat'` — Blue → orange → red (heat-map style)
371
596
  * - `'monochrome'` — Light grey → dark grey (print-friendly)
597
+ * - `'viridis'` — Purple → blue → green → yellow (perceptually uniform, colorblind-safe)
598
+ * - `'plasma'` — Purple → magenta → orange → yellow (vivid, perceptually uniform)
599
+ *
600
+ * @group Traffic Area Analytics
601
+ */
602
+ export declare type AreaAnalyticsColorTheme = 'trafficLight' | 'heat' | 'monochrome' | 'viridis' | 'plasma';
603
+
604
+ /**
605
+ * Visualization mode for area analytics data.
606
+ *
607
+ * - `'hexgrid-3d'` — 3D extruded hexagonal cells colored and raised by metric value
608
+ * - `'hexgrid-2d'` — Flat hexagonal cells colored by metric value (no extrusion)
609
+ * - `'square-3d'` — 3D extruded square cells colored and raised by metric value
610
+ * - `'square-2d'` — Flat square cells colored by metric value (no extrusion)
611
+ * - `'heatmap'` — MapLibre density heatmap layer from tile centre points
372
612
  *
373
613
  * @group Traffic Area Analytics
374
614
  */
375
- export declare type AreaAnalyticsColorScheme = 'congestion' | 'thermal' | 'monochrome';
615
+ export declare type AreaAnalyticsDisplayMode = 'heatmap' | 'hexgrid-3d' | 'hexgrid-2d' | 'square-3d' | 'square-2d';
376
616
 
377
617
  /**
378
618
  * Properties attached to each area analytics display feature.
379
619
  *
380
620
  * @remarks
381
621
  * Includes all optional metric fields from the API response plus a
382
- * stable `id` used by MapLibre's `promoteId` for event state tracking.
622
+ * stable `id` used by MapLibre's `promoteId` for event state tracking,
623
+ * and `eventState` (from `SupportsEvents`) used to drive hover/click styling.
383
624
  *
384
625
  * @group Traffic Area Analytics
385
626
  */
386
- export declare type AreaAnalyticsDisplayProperties = AreaAnalyticsMetrics & {
627
+ export declare type AreaAnalyticsDisplayProperties = AreaAnalyticsMetrics & SupportsEvents & {
387
628
  /**
388
629
  * Stable feature identifier (typically the tile centre coordinates stringified
389
630
  * or the H3 cell index).
@@ -392,44 +633,174 @@ export declare type AreaAnalyticsDisplayProperties = AreaAnalyticsMetrics & {
392
633
  };
393
634
 
394
635
  /**
395
- * A single hex polygon feature for the hexgrid visualization.
636
+ * Height (extrusion) configuration for a metric.
637
+ *
638
+ * The shape depends on `scaleMode`:
639
+ * - `'predefinedRange'` / `'currentRange'` (default): use `maxHeightMeters` to set a true visual ceiling.
640
+ * - `'raw'`: use `scaleFactor` to multiply the raw metric value directly.
396
641
  *
397
642
  * @group Traffic Area Analytics
398
643
  */
399
- export declare type AreaAnalyticsHexFeature = Feature<Polygon, AreaAnalyticsDisplayProperties>;
644
+ export declare type AreaAnalyticsHeightConfig = {
645
+ /**
646
+ * Normalised scale mode. The metric is mapped to a known range before computing height,
647
+ * so `maxHeightMeters` equals the actual maximum visual height in meters.
648
+ *
649
+ * @defaultValue 'predefinedRange'
650
+ */
651
+ scaleMode?: 'predefinedRange' | 'currentRange';
652
+ /**
653
+ * True visual maximum extrusion height in meters.
654
+ * The tallest cell reaches exactly this height.
655
+ *
656
+ * @defaultValue 1000
657
+ */
658
+ maxHeightMeters?: number;
659
+ /**
660
+ * Minimum extrusion height in meters.
661
+ *
662
+ * @defaultValue 0
663
+ */
664
+ minHeightMeters?: number;
665
+ } | {
666
+ /** Raw scale mode: `scaleFactor` is multiplied directly with the raw metric value. */
667
+ scaleMode: 'raw';
668
+ /**
669
+ * Multiplier applied to the raw metric value to obtain extrusion height in meters.
670
+ *
671
+ * @defaultValue 1
672
+ */
673
+ scaleFactor?: number;
674
+ /**
675
+ * Minimum extrusion height in meters.
676
+ *
677
+ * @defaultValue 0
678
+ */
679
+ minHeightMeters?: number;
680
+ };
400
681
 
401
682
  /**
402
- * Available metrics for area analytics visualization.
683
+ * Per-metric visualization configuration.
403
684
  *
404
685
  * @group Traffic Area Analytics
405
686
  */
406
- export declare type AreaAnalyticsMetricKey = 'congestionLevel' | 'speed' | 'travelTime';
687
+ export declare type AreaAnalyticsMetricConfig = {
688
+ /**
689
+ * Color for this metric's visualization.
690
+ *
691
+ * Pass a preset theme name (`AreaAnalyticsColorTheme`) or a custom
692
+ * `AreaAnalyticsColorStopsConfig` object with explicit stop values and a
693
+ * value-type hint. For `speed`, the color order is automatically inverted
694
+ * so that slow speeds render as "bad" (red) and fast speeds as "good" (green).
695
+ *
696
+ * @defaultValue `'trafficLight'` theme
697
+ */
698
+ color?: AreaAnalyticsColorTheme | AreaAnalyticsColorStopsConfig;
699
+ /**
700
+ * Extrusion height configuration for this metric.
701
+ */
702
+ height?: AreaAnalyticsHeightConfig;
703
+ /**
704
+ * Filter visible tiles to only those within the given value range for this metric.
705
+ */
706
+ filters?: AreaAnalyticsMetricFilter;
707
+ };
407
708
 
408
709
  /**
409
- * Visualization mode for area analytics data.
410
- *
411
- * - `'hexgrid'` — 3D extruded hexagonal cells colored and raised by metric value
412
- * - `'heatmap'` — MapLibre density heatmap layer from tile centre points
710
+ * Filter for visible tiles based on a metric's value range.
711
+ * Both `min` and `max` are optional; at least one should be provided to have effect.
413
712
  *
414
713
  * @group Traffic Area Analytics
415
714
  */
416
- export declare type AreaAnalyticsMode = 'heatmap' | 'hexgrid';
715
+ export declare type AreaAnalyticsMetricFilter = {
716
+ /** Show only tiles where the metric is ≥ this value. */
717
+ min?: number;
718
+ /** Show only tiles where the metric is ≤ this value. */
719
+ max?: number;
720
+ };
417
721
 
418
722
  /**
419
- * A single point feature for the heatmap visualization.
723
+ * Display configuration for the actual region boundary geometry.
724
+ *
725
+ * When area analytics data is shown, the original region polygon (the area
726
+ * the query was run for) is also rendered. Use this config to control its
727
+ * appearance.
420
728
  *
421
729
  * @group Traffic Area Analytics
422
730
  */
423
- export declare type AreaAnalyticsPointFeature = Feature<Point, AreaAnalyticsDisplayProperties>;
731
+ export declare type AreaAnalyticsRegionPolygonConfig = {
732
+ /**
733
+ * Color used for both the fill and outline of the region boundary.
734
+ *
735
+ * @defaultValue '#000000'
736
+ */
737
+ color?: string;
738
+ /**
739
+ * Opacity of the region fill.
740
+ *
741
+ * @defaultValue 0
742
+ */
743
+ fillOpacity?: number;
744
+ /**
745
+ * Opacity of the region outline.
746
+ *
747
+ * @defaultValue 0.5
748
+ */
749
+ outlineOpacity?: number;
750
+ /**
751
+ * Width of the region outline in pixels.
752
+ *
753
+ * @defaultValue 2
754
+ */
755
+ outlineWidth?: number;
756
+ /**
757
+ * When `true`, renders the region as an overlay covering everything *outside* the polygon
758
+ * boundary, effectively tinting the area outside the analytics region.
759
+ *
760
+ * Uses a world-minus-polygon donut geometry (same technique as the `GeometriesModule`
761
+ * `'inverted'` theme).
762
+ *
763
+ * @defaultValue false
764
+ */
765
+ inverted?: boolean;
766
+ };
424
767
 
425
768
  /**
426
769
  * Sources and layers managed by this module.
770
+ * @ignore
427
771
  */
428
772
  declare type AreaAnalyticsSourcesWithLayers = {
429
773
  heatmap: GeoJSONSourceWithLayers<FeatureCollection<Point, AreaAnalyticsDisplayProperties>>;
430
774
  hexgrid: GeoJSONSourceWithLayers<FeatureCollection<Polygon, AreaAnalyticsDisplayProperties>>;
775
+ square: GeoJSONSourceWithLayers<FeatureCollection<Polygon, AreaAnalyticsDisplayProperties>>;
776
+ region: GeoJSONSourceWithLayers;
431
777
  };
432
778
 
779
+ /**
780
+ * A single area analytics tile feature (point, hexagon, or square cell).
781
+ *
782
+ * @group Traffic Area Analytics
783
+ */
784
+ export declare type AreaAnalyticsTileFeature = Feature<Point | Polygon, AreaAnalyticsDisplayProperties>;
785
+
786
+ /**
787
+ * Determines how numeric `value` fields in color stops are interpreted.
788
+ *
789
+ * - `'raw'` — stop values are actual metric values used directly
790
+ * (e.g. congestion: 0–100, speed: 0–120 km/h, travelTime: 0–20 s/km).
791
+ * - `'relativeToPredefinedRangePCT'` — stop values are 0–100 percentages relative to the SDK's predefined
792
+ * metric ranges (congestion 0–100, speed 0–120 km/h, travelTime 0–20 s/km).
793
+ * Useful for consistent coloring regardless of the current dataset.
794
+ * - `'relativeToActualRangePCT'` — stop values are 0–100 percentages relative to the live data
795
+ * range actually present in the loaded tiles (0 % = loaded minimum, 100 % = loaded maximum).
796
+ * Useful for maximum contrast when exact values are unknown.
797
+ *
798
+ * Defaults to `'raw'`.
799
+ *
800
+ * @group Traffic Area Analytics
801
+ */
802
+ export declare type AreaAnalyticsValueType = 'raw' | 'relativeToPredefinedRangePCT' | 'relativeToActualRangePCT';
803
+
433
804
  /**
434
805
  * Availability level for POI icons with availability indicators.
435
806
  * @group Shared
@@ -834,50 +1205,26 @@ export declare class BaseMapModule extends AbstractMapModule<BaseSourceAndLayers
834
1205
  layerGroups?: BaseMapLayerGroups;
835
1206
  }): void;
836
1207
  /**
837
- * Gets the events interface for this module to handle user interactions.
838
- *
839
- * @returns An EventsModule instance for registering event handlers.
1208
+ * Gets the unified events interface for this module, covering both user interactions
1209
+ * and module lifecycle events.
840
1210
  *
841
- * @remarks
842
- * **Supported Events:**
843
- * - `click`: User clicks on a base map feature
844
- * - `contextmenu`: User right-clicks on a feature
845
- * - `hover`: Mouse enters a feature
846
- * - `long-hover`: Mouse hovers over a feature for extended time
847
- *
848
- * **Event Handler Signature:**
849
- * ```typescript
850
- * (feature: MapGeoJSONFeature, lngLat: LngLat, allFeatures: MapGeoJSONFeature[]) => void
851
- * ```
852
- *
853
- * @example
854
- * Register click handler:
1211
+ * **User interaction events** (`click`, `contextmenu`, `hover`, `long-hover`):
855
1212
  * ```typescript
856
- * baseMap.events.on('click', (feature, lngLat) => {
1213
+ * const unsub = baseMap.events.on('click', (feature, lngLat) => {
857
1214
  * console.log('Clicked on:', feature.properties);
858
- * console.log('At coordinates:', lngLat);
859
1215
  * });
1216
+ * baseMap.events.off('hover'); // remove by type
860
1217
  * ```
861
1218
  *
862
- * @example
863
- * Multiple event types:
1219
+ * **Module lifecycle events** (`config-change`):
864
1220
  * ```typescript
865
- * // Show tooltip on hover
866
- * baseMap.events.on('hover', (feature) => {
867
- * showTooltip(feature.properties.name);
868
- * });
869
- *
870
- * // Handle clicks
871
- * baseMap.events.on('click', (feature) => {
872
- * selectFeature(feature.id);
1221
+ * const unsub = baseMap.events.on('config-change', (config) => {
1222
+ * console.log('Config changed:', config);
873
1223
  * });
874
- *
875
- * // Clean up
876
- * baseMap.events.off('hover');
877
- * baseMap.events.off('click');
1224
+ * unsub(); // remove by returned function
878
1225
  * ```
879
1226
  */
880
- get events(): EventsModule<MapGeoJSONFeature>;
1227
+ get events(): CombinedEvents<MapGeoJSONFeature, BaseMapModuleConfig, never>;
881
1228
  }
882
1229
 
883
1230
  /**
@@ -1036,6 +1383,16 @@ declare type BaseSourceAndLayers = {
1036
1383
  vectorTiles: StyleSourceWithLayers;
1037
1384
  };
1038
1385
 
1386
+ /**
1387
+ * Controls where a module's layers are placed in the map's layer stack.
1388
+ *
1389
+ * - `'top'` — renders above all other layers
1390
+ * - A {@link MapStyleLayerID} — renders below the named style layer
1391
+ *
1392
+ * @group Shared
1393
+ */
1394
+ export declare type BeforeLayerConfig = 'top' | MapStyleLayerID;
1395
+
1039
1396
  /**
1040
1397
  * Builds the title of the place to display it on the map.
1041
1398
  * @param place The place to display.
@@ -1404,9 +1761,6 @@ export declare type CleanEventStatesOptions = {
1404
1761
  */
1405
1762
  export declare type ClickEventType = 'click' | 'contextmenu';
1406
1763
 
1407
- /** @ignore */
1408
- export declare const COLOR_SCHEMES: Record<AreaAnalyticsColorScheme, ColorStops>;
1409
-
1410
1764
  export declare const colorPaletteIDs: ColorPaletteOptions[];
1411
1765
 
1412
1766
  export declare type ColorPaletteOptions = keyof typeof colorPalettes;
@@ -1428,12 +1782,126 @@ export declare const colorPalettes: {
1428
1782
  pastelRainbow: string[];
1429
1783
  };
1430
1784
 
1431
- /** @ignore */
1432
- declare type ColorStops = {
1433
- low: string;
1434
- mid: string;
1435
- high: string;
1436
- };
1785
+ /**
1786
+ * Unified events interface that blends user interaction events and module lifecycle events
1787
+ * under a single `on` / `off` surface.
1788
+ *
1789
+ * User event types (`click`, `contextmenu`, `hover`, `long-hover`) are handled by the
1790
+ * underlying {@link UserEvents} instance and removed with {@link off}.
1791
+ *
1792
+ * Module lifecycle event types (`config-change`, `shown-features`) are handled by the
1793
+ * underlying {@link ModuleEvents} instance. Each `on` call returns an unsubscribe function.
1794
+ * Both user and module event types are also removable in bulk via {@link off}.
1795
+ *
1796
+ * @typeParam T - Feature type surfaced by user interaction handlers.
1797
+ * @typeParam CFG - Module configuration type passed to `config-change` handlers.
1798
+ * @typeParam TShown - Data type passed to `shown-features` handlers. Use `never` for
1799
+ * modules that have no `show` method.
1800
+ *
1801
+ * @example
1802
+ * ```typescript
1803
+ * // User interaction
1804
+ * const unsub = places.events.on('click', (feature, lngLat) => {
1805
+ * console.log('Clicked place:', feature.properties.name);
1806
+ * });
1807
+ *
1808
+ * // Module lifecycle
1809
+ * const unsubConfig = places.events.on('config-change', (config) => {
1810
+ * console.log('Config updated:', config);
1811
+ * });
1812
+ *
1813
+ * const unsubShown = places.events.on('shown-features', (features) => {
1814
+ * console.log('Shown:', features);
1815
+ * });
1816
+ *
1817
+ * // Cleanup
1818
+ * unsub();
1819
+ * unsubConfig();
1820
+ * unsubShown();
1821
+ * places.events.off('click'); // also valid for user events
1822
+ * ```
1823
+ *
1824
+ * @group Events
1825
+ */
1826
+ export declare class CombinedEvents<T, CFG, TShown = never> {
1827
+ private readonly userEventsInstance;
1828
+ private readonly moduleEventsInstance;
1829
+ constructor(userEventsInstance: UserEvents<T>, moduleEventsInstance: ModuleEvents<CFG, TShown>);
1830
+ /**
1831
+ * Subscribe to a user interaction event (`click`, `contextmenu`, `hover`, `long-hover`).
1832
+ *
1833
+ * @param type - The user event type.
1834
+ * @param handler - Called with the feature, click/hover coordinates, all features at the
1835
+ * point, and the source configuration.
1836
+ * @returns An unsubscribe function. Call it to remove **only this handler**.
1837
+ *
1838
+ * @example
1839
+ * ```typescript
1840
+ * const unsub = places.events.on('click', (feature, lngLat) => {
1841
+ * showPlaceDetails(feature.properties);
1842
+ * });
1843
+ * unsub(); // remove only this handler
1844
+ * ```
1845
+ */
1846
+ on(type: EventType, handler: UserEventHandler<T>): () => void;
1847
+ /**
1848
+ * Subscribe to config-change events.
1849
+ *
1850
+ * Fires after any configuration mutation — `applyConfig`, `setVisible`, or any
1851
+ * module-specific setter. The handler receives the module's full updated configuration.
1852
+ *
1853
+ * @param type - `'config-change'`
1854
+ * @param handler - Receives the module's config (or `undefined` when config is cleared).
1855
+ * @returns An unsubscribe function. Call it to remove **only this handler**.
1856
+ *
1857
+ * @example
1858
+ * ```typescript
1859
+ * const unsub = trafficFlow.events.on('config-change', (config) => {
1860
+ * toggle.checked = config?.visible ?? false;
1861
+ * });
1862
+ * unsub();
1863
+ * ```
1864
+ */
1865
+ on(type: 'config-change', handler: (config: CFG | undefined) => void): () => void;
1866
+ /**
1867
+ * Subscribe to shown-features events.
1868
+ *
1869
+ * Fires immediately after the module's `show()` method (or equivalent) has rendered
1870
+ * new data on the map. Only available on modules that have a `show` method.
1871
+ *
1872
+ * @param type - `'shown-features'`
1873
+ * @param handler - Receives the data that was passed to `show()`.
1874
+ * @returns An unsubscribe function. Call it to remove **only this handler**.
1875
+ *
1876
+ * @example
1877
+ * ```typescript
1878
+ * const unsub = places.events.on('shown-features', (features) => {
1879
+ * fitMapToResults(features);
1880
+ * });
1881
+ * unsub();
1882
+ * ```
1883
+ */
1884
+ on(type: 'shown-features', handler: (features: TShown) => void): () => void;
1885
+ /**
1886
+ * Remove **all** handlers for the given event type at once.
1887
+ *
1888
+ * Accepts both user interaction types (`click`, `contextmenu`, `hover`, `long-hover`) and
1889
+ * module lifecycle types (`config-change`, `shown-features`).
1890
+ *
1891
+ * Prefer the unsubscribe function returned by {@link on} when you need to remove a single
1892
+ * handler. Use `off` for bulk teardown — e.g. when unmounting a component that registered
1893
+ * multiple handlers of the same type.
1894
+ *
1895
+ * @param type - The event type whose handlers should all be cleared.
1896
+ *
1897
+ * @example
1898
+ * ```typescript
1899
+ * places.events.off('click'); // clear all click handlers
1900
+ * places.events.off('config-change'); // clear all config-change handlers
1901
+ * ```
1902
+ */
1903
+ off(type: EventType | 'config-change' | 'shown-features'): void;
1904
+ }
1437
1905
 
1438
1906
  /**
1439
1907
  * Allowed CSS cursor styles for map interactions.
@@ -2284,398 +2752,135 @@ export declare type EventHandlerCursorConfig = {
2284
2752
  declare type EventHandlers = Record<string, SourceEventHandlers>;
2285
2753
 
2286
2754
  /**
2287
- * Event handling interface for map features.
2288
- *
2289
- * Provides a simple API for attaching and removing event handlers for user interactions
2290
- * with map features such as clicks, hovers, and context menus. Each map module (POIs, Routing,
2291
- * Places, etc.) exposes an `events` property that returns an EventsModule instance.
2292
- *
2293
- * @typeParam T - The feature type returned in event handlers (extends MapGeoJSONFeature)
2755
+ * This is the place where we handle the user events on the map (mousemove/hover and click mostly).
2756
+ * To have full control on hovers and clicks when multiple overlapping layers are present, that logic must be centralized here.
2757
+ * @ignore
2758
+ */
2759
+ export declare class EventsProxy extends AbstractEventProxy {
2760
+ private readonly map;
2761
+ private readonly mapCanvas;
2762
+ private enabled;
2763
+ private hoveringLngLat?;
2764
+ private hoveringPoint?;
2765
+ private hoveringFeature?;
2766
+ private hoveringFeatures?;
2767
+ private hoveringSourceWithLayers?;
2768
+ private longHoverTimeoutHandlerID?;
2769
+ private firstDelayedHoverSinceMapMove;
2770
+ private lastClickedFeature?;
2771
+ private lastClickedSourceWithLayers?;
2772
+ private lastCursorStyle;
2773
+ private readonly config;
2774
+ constructor(map: Map_2, config?: MapEventsConfig);
2775
+ private listenToEvents;
2776
+ enable(enabled: boolean): void;
2777
+ private toPaddedBounds;
2778
+ private isEnabled;
2779
+ private getRenderedFeatures;
2780
+ private clearLongHoverTimeout;
2781
+ private restartLongHoverTimeout;
2782
+ private handleLongHoverTimeout;
2783
+ private onMouseStart;
2784
+ private onMouseOut;
2785
+ private onMouseDown;
2786
+ private onMouseUp;
2787
+ private onMouseMove;
2788
+ private updateHoverCursor;
2789
+ private onMapClick;
2790
+ }
2791
+
2792
+ /**
2793
+ * Type of user event supported by the SDK beyond basic MapLibre support.
2294
2794
  *
2295
2795
  * @remarks
2296
- * **Supported Event Types:**
2297
- * - `click`: User clicks/taps on a feature
2298
- * - `contextmenu`: User right-clicks on a feature (or long-press on mobile)
2299
- * - `hover`: Mouse enters a feature
2300
- * - `long-hover`: Mouse hovers over feature for configured duration (300-800ms)
2301
- *
2302
- * **Event Handler Signature:**
2303
- * ```typescript
2304
- * (feature: T, lngLat: LngLat, features: T[]) => void
2305
- * ```
2306
- *
2307
- * **Parameters:**
2308
- * - `feature`: The primary feature under the cursor
2309
- * - `lngLat`: Geographic coordinates of the event
2310
- * - `features`: All features at this location (when multiple overlap)
2311
- *
2312
- * **Key Features:**
2313
- * - Automatic cursor management (pointer on hover)
2314
- * - Smart event handling for overlapping features
2315
- * - Configurable hover delays
2316
- * - Memory-safe cleanup when removing handlers
2796
+ * The SDK extends MapLibre's basic event handling with additional event types
2797
+ * that are commonly needed for interactive map features.
2317
2798
  *
2318
2799
  * @example
2319
2800
  * ```typescript
2320
- * // POI click handler
2321
- * const pois = map.pois();
2322
- * pois.events.on('click', (feature, lngLat) => {
2323
- * console.log('Clicked POI:', feature.properties.name);
2324
- * console.log('Location:', lngLat);
2325
- * showInfoWindow(feature.properties);
2326
- * });
2801
+ * const eventType: EventType = 'click';
2802
+ * const hoverEvent: EventType = 'long-hover';
2803
+ * ```
2327
2804
  *
2328
- * // Route waypoint hover
2329
- * const routing = map.routing();
2330
- * routing.events.waypoints.on('hover', (waypoint) => {
2331
- * showTooltip(`Waypoint ${waypoint.properties.index}`);
2332
- * });
2805
+ * @group User Interaction Events
2806
+ */
2807
+ export declare type EventType = ClickEventType | HoverEventType;
2808
+
2809
+ /**
2810
+ * Extra properties to display color and title for a geometry on the map.
2333
2811
  *
2334
- * // Long-hover for detailed info
2335
- * pois.events.on('long-hover', (feature) => {
2336
- * loadAndShowDetailedInfo(feature.properties.id);
2337
- * });
2812
+ * Provides customization options for rendering polygon geometries, including
2813
+ * visual styling and labeling.
2338
2814
  *
2339
- * // Context menu (right-click)
2340
- * routing.events.mainLines.on('contextmenu', (route, lngLat) => {
2341
- * showContextMenu(lngLat, [
2342
- * { label: 'Add waypoint here', action: () => addWaypoint(lngLat) },
2343
- * { label: 'View route details', action: () => showDetails(route) }
2344
- * ]);
2345
- * });
2815
+ * @remarks
2816
+ * **Use Cases:**
2817
+ * - Search result boundaries (e.g., city limits, postal codes)
2818
+ * - Reachable range polygons
2819
+ * - Delivery zones
2820
+ * - Custom area highlights
2346
2821
  *
2347
- * // Remove all click handlers
2348
- * pois.events.off('click');
2349
- * ```
2822
+ * These properties override default styling and allow per-feature customization.
2350
2823
  *
2351
2824
  * @example
2352
2825
  * ```typescript
2353
- * // Complete interaction example
2354
- * const places = map.places();
2355
- *
2356
- * // Show name on hover
2357
- * places.events.on('hover', (place) => {
2358
- * tooltip.show(place.properties.name);
2359
- * });
2360
- *
2361
- * // Show details on click
2362
- * places.events.on('click', (place, lngLat) => {
2363
- * sidebar.show({
2364
- * title: place.properties.name,
2365
- * address: place.properties.address.freeformAddress,
2366
- * coordinates: lngLat
2367
- * });
2368
- * });
2826
+ * const geometryProps: ExtraGeometryDisplayProps = {
2827
+ * title: 'Amsterdam City Center',
2828
+ * color: '#FF5733',
2829
+ * eventState: 'click'
2830
+ * };
2369
2831
  *
2370
- * // Cleanup on component unmount
2371
- * onUnmount(() => {
2372
- * places.events.off('hover');
2373
- * places.events.off('click');
2374
- * });
2832
+ * // With custom properties
2833
+ * const customProps: ExtraGeometryDisplayProps = {
2834
+ * title: 'Delivery Zone A',
2835
+ * color: '#00FF00',
2836
+ * zoneId: 'zone-a',
2837
+ * capacity: 100
2838
+ * };
2375
2839
  * ```
2376
2840
  *
2377
- * @group User Interaction Events
2841
+ * @group Geometries
2378
2842
  */
2379
- export declare class EventsModule<T = MapGeoJSONFeature> {
2380
- private readonly eventProxy;
2381
- private readonly sourceWithLayers;
2382
- private readonly config;
2383
- /**
2384
- * Optional function that transforms a raw {@link MapGeoJSONFeature} into the
2385
- * feature type `T` exposed by the module. When provided, every feature passed (fired)
2386
- * to event handlers is first run through this function, so callers receive the
2387
- * module's own feature shape instead of the underlying MapLibre feature.
2388
- *
2389
- * When omitted, `T` defaults to `MapGeoJSONFeature` and features are forwarded
2390
- * as-is.
2391
- */
2392
- private readonly mapping?;
2393
- constructor(eventProxy: EventsProxy, sourceWithLayers: SourceWithLayers, config: EventHandlerConfig | undefined,
2394
- /**
2395
- * Optional function that transforms a raw {@link MapGeoJSONFeature} into the
2396
- * feature type `T` exposed by the module. When provided, every feature passed (fired)
2397
- * to event handlers is first run through this function, so callers receive the
2398
- * module's own feature shape instead of the underlying MapLibre feature.
2399
- *
2400
- * When omitted, `T` defaults to `MapGeoJSONFeature` and features are forwarded
2401
- * as-is.
2402
- */
2403
- mapping?: ((feature: MapGeoJSONFeature) => T) | undefined);
2843
+ export declare type ExtraGeometryDisplayProps = {
2404
2844
  /**
2405
- * Register an event handler for user interactions with map features.
2406
- *
2407
- * Attaches a callback function that will be invoked when users interact with
2408
- * features in this module (e.g., clicking on a POI, hovering over a route).
2409
- *
2410
- * @param type The type of event to listen for (click, contextmenu, hover, long-hover)
2411
- * @param handler Callback function invoked when the event occurs
2845
+ * Display title for the geometry.
2412
2846
  *
2413
2847
  * @remarks
2414
- * **Handler Parameters:**
2415
- * - `feature`: The primary feature that triggered the event
2416
- * - `lngLat`: Geographic coordinates [longitude, latitude] of the event
2417
- * - `features`: Array of all features at the event location (for overlapping features)
2418
- *
2419
- * **Behavior:**
2420
- * - Only one handler per event type (calling `on()` again replaces the previous handler)
2421
- * - Handlers are preserved across map style changes
2422
- * - Cursor automatically changes to pointer on hover
2423
- * - Events respect module visibility (hidden features don't trigger events)
2424
- *
2425
- * **Performance:**
2426
- * - Hover events use spatial indexing for fast lookup
2427
- * - Long-hover has configurable delay to prevent accidental triggers
2428
- * - Event handlers should be lightweight to maintain smooth interaction
2429
- *
2430
- * @example
2431
- * ```typescript
2432
- * // Basic click handler
2433
- * module.events.on('click', (feature, lngLat, features) => {
2434
- * console.log('Clicked feature:', feature.properties);
2435
- * console.log('Location:', lngLat);
2436
- * console.log('All features here:', features.length);
2437
- * });
2438
- *
2439
- * // Hover with tooltip
2440
- * module.events.on('hover', (feature) => {
2441
- * const name = feature.properties.name || 'Unnamed';
2442
- * tooltip.show(name);
2443
- * });
2444
- *
2445
- * // Long-hover for detailed preview
2446
- * module.events.on('long-hover', (feature) => {
2447
- * // Only triggered after hovering for 300-800ms
2448
- * loadPreview(feature.properties.id);
2449
- * });
2848
+ * Optional text label displayed at the center of the polygon.
2849
+ * If not provided, no label will be shown.
2450
2850
  *
2451
- * // Right-click context menu
2452
- * module.events.on('contextmenu', (feature, lngLat) => {
2453
- * event.preventDefault(); // Prevent browser context menu
2454
- * showCustomMenu(lngLat, feature);
2455
- * });
2456
- * ```
2851
+ * **Common Uses:**
2852
+ * - Area names (e.g., "Downtown", "Zone A")
2853
+ * - Statistics (e.g., "30 min reachable")
2854
+ * - Custom labels
2457
2855
  *
2458
2856
  * @example
2459
2857
  * ```typescript
2460
- * // Route-specific handlers
2461
- * const routing = map.routing();
2462
- *
2463
- * // Handle route line clicks
2464
- * routing.events.mainLines.on('click', (route) => {
2465
- * highlightRoute(route.properties.routeID);
2466
- * showRouteSummary(route.properties.summary);
2467
- * });
2468
- *
2469
- * // Handle waypoint interactions
2470
- * routing.events.waypoints.on('hover', (waypoint) => {
2471
- * const index = waypoint.properties.index;
2472
- * showTooltip(`Stop ${index + 1}`);
2473
- * });
2858
+ * title: 'Amsterdam City Center'
2859
+ * title: 'Zone A'
2860
+ * title: '30 min driving range'
2861
+ * title: undefined // No label
2474
2862
  * ```
2475
2863
  */
2476
- on(type: EventType, handler: UserEventHandler<T>): void;
2864
+ title?: string;
2477
2865
  /**
2478
- * Remove all event handlers for a specific event type.
2479
- *
2480
- * Unregisters the callback function for the specified event type, stopping
2481
- * further event notifications. This is important for cleanup to prevent
2482
- * memory leaks and unwanted behavior.
2483
- *
2484
- * @param type The type of event to stop listening for
2866
+ * Fill color for the geometry.
2485
2867
  *
2486
2868
  * @remarks
2487
- * **Cleanup Behavior:**
2488
- * - Removes only the specified event type (other types remain active)
2489
- * - Resets cursor behavior for this module
2490
- * - Safe to call multiple times (no error if no handler exists)
2491
- * - Does not affect other modules' event handlers
2492
- *
2493
- * **When to Use:**
2494
- * - Component unmounting/cleanup
2495
- * - Switching between interaction modes
2496
- * - Temporarily disabling interactions
2497
- * - Replacing an existing handler (call `off()` then `on()`)
2498
- *
2499
- * **Best Practices:**
2500
- * - Always clean up event handlers when component unmounts
2501
- * - Remove handlers before removing features from the map
2502
- * - Use framework lifecycle hooks for automatic cleanup
2503
- *
2504
- * @example
2505
- * ```typescript
2506
- * // Remove click handlers
2507
- * module.events.off('click');
2869
+ * Overrides the default fill color from the module configuration.
2870
+ * Accepts any valid CSS color value.
2508
2871
  *
2509
- * // Remove all handlers
2510
- * module.events.off('click');
2511
- * module.events.off('hover');
2512
- * module.events.off('long-hover');
2513
- * module.events.off('contextmenu');
2514
- * ```
2872
+ * **Color Formats:**
2873
+ * - Hex: '#FF5733'
2874
+ * - RGB: 'rgb(255, 87, 51)'
2875
+ * - RGBA: 'rgba(255, 87, 51, 0.5)'
2876
+ * - Named: 'red', 'blue', 'green'
2515
2877
  *
2516
2878
  * @example
2517
2879
  * ```typescript
2518
- * // React component cleanup
2519
- * useEffect(() => {
2520
- * const pois = map.pois();
2521
- *
2522
- * pois.events.on('click', handlePoiClick);
2523
- * pois.events.on('hover', handlePoiHover);
2524
- *
2525
- * return () => {
2526
- * // Cleanup on unmount
2527
- * pois.events.off('click');
2528
- * pois.events.off('hover');
2529
- * };
2530
- * }, [map]);
2531
- * ```
2532
- *
2533
- * @example
2534
- * ```typescript
2535
- * // Replace handler
2536
- * module.events.off('click'); // Remove old handler
2537
- * module.events.on('click', newHandler); // Add new handler
2538
- *
2539
- * // Disable interactions temporarily
2540
- * const savedHandler = currentHandler;
2541
- * module.events.off('click'); // Disable
2542
- * // ... later ...
2543
- * module.events.on('click', savedHandler); // Re-enable
2544
- * ```
2545
- */
2546
- off(type: EventType): void;
2547
- }
2548
-
2549
- /**
2550
- * This is the place where we handle the user events on the map (mousemove/hover and click mostly).
2551
- * To have full control on hovers and clicks when multiple overlapping layers are present, that logic must be centralized here.
2552
- * @ignore
2553
- */
2554
- export declare class EventsProxy extends AbstractEventProxy {
2555
- private readonly map;
2556
- private readonly mapCanvas;
2557
- private enabled;
2558
- private hoveringLngLat?;
2559
- private hoveringPoint?;
2560
- private hoveringFeature?;
2561
- private hoveringFeatures?;
2562
- private hoveringSourceWithLayers?;
2563
- private longHoverTimeoutHandlerID?;
2564
- private firstDelayedHoverSinceMapMove;
2565
- private lastClickedFeature?;
2566
- private lastClickedSourceWithLayers?;
2567
- private lastCursorStyle;
2568
- private readonly config;
2569
- constructor(map: Map_2, config?: MapEventsConfig);
2570
- private listenToEvents;
2571
- enable(enabled: boolean): void;
2572
- private toPaddedBounds;
2573
- private isEnabled;
2574
- private getRenderedFeatures;
2575
- private clearLongHoverTimeout;
2576
- private restartLongHoverTimeout;
2577
- private handleLongHoverTimeout;
2578
- private onMouseStart;
2579
- private onMouseOut;
2580
- private onMouseDown;
2581
- private onMouseUp;
2582
- private onMouseMove;
2583
- private updateHoverCursor;
2584
- private onMapClick;
2585
- }
2586
-
2587
- /**
2588
- * Type of user event supported by the SDK beyond basic MapLibre support.
2589
- *
2590
- * @remarks
2591
- * The SDK extends MapLibre's basic event handling with additional event types
2592
- * that are commonly needed for interactive map features.
2593
- *
2594
- * @example
2595
- * ```typescript
2596
- * const eventType: EventType = 'click';
2597
- * const hoverEvent: EventType = 'long-hover';
2598
- * ```
2599
- *
2600
- * @group User Interaction Events
2601
- */
2602
- export declare type EventType = ClickEventType | HoverEventType;
2603
-
2604
- /**
2605
- * Extra properties to display color and title for a geometry on the map.
2606
- *
2607
- * Provides customization options for rendering polygon geometries, including
2608
- * visual styling and labeling.
2609
- *
2610
- * @remarks
2611
- * **Use Cases:**
2612
- * - Search result boundaries (e.g., city limits, postal codes)
2613
- * - Reachable range polygons
2614
- * - Delivery zones
2615
- * - Custom area highlights
2616
- *
2617
- * These properties override default styling and allow per-feature customization.
2618
- *
2619
- * @example
2620
- * ```typescript
2621
- * const geometryProps: ExtraGeometryDisplayProps = {
2622
- * title: 'Amsterdam City Center',
2623
- * color: '#FF5733',
2624
- * eventState: 'click'
2625
- * };
2626
- *
2627
- * // With custom properties
2628
- * const customProps: ExtraGeometryDisplayProps = {
2629
- * title: 'Delivery Zone A',
2630
- * color: '#00FF00',
2631
- * zoneId: 'zone-a',
2632
- * capacity: 100
2633
- * };
2634
- * ```
2635
- *
2636
- * @group Geometries
2637
- */
2638
- export declare type ExtraGeometryDisplayProps = {
2639
- /**
2640
- * Display title for the geometry.
2641
- *
2642
- * @remarks
2643
- * Optional text label displayed at the center of the polygon.
2644
- * If not provided, no label will be shown.
2645
- *
2646
- * **Common Uses:**
2647
- * - Area names (e.g., "Downtown", "Zone A")
2648
- * - Statistics (e.g., "30 min reachable")
2649
- * - Custom labels
2650
- *
2651
- * @example
2652
- * ```typescript
2653
- * title: 'Amsterdam City Center'
2654
- * title: 'Zone A'
2655
- * title: '30 min driving range'
2656
- * title: undefined // No label
2657
- * ```
2658
- */
2659
- title?: string;
2660
- /**
2661
- * Fill color for the geometry.
2662
- *
2663
- * @remarks
2664
- * Overrides the default fill color from the module configuration.
2665
- * Accepts any valid CSS color value.
2666
- *
2667
- * **Color Formats:**
2668
- * - Hex: '#FF5733'
2669
- * - RGB: 'rgb(255, 87, 51)'
2670
- * - RGBA: 'rgba(255, 87, 51, 0.5)'
2671
- * - Named: 'red', 'blue', 'green'
2672
- *
2673
- * @example
2674
- * ```typescript
2675
- * color: '#FF5733'
2676
- * color: 'rgb(0, 128, 255)'
2677
- * color: 'rgba(255, 0, 0, 0.5)'
2678
- * color: 'red'
2880
+ * color: '#FF5733'
2881
+ * color: 'rgb(0, 128, 255)'
2882
+ * color: 'rgba(255, 0, 0, 0.5)'
2883
+ * color: 'red'
2679
2884
  * ```
2680
2885
  */
2681
2886
  color?: string;
@@ -2781,7 +2986,7 @@ export declare type FlowConfig = MapModuleCommonConfig & {
2781
2986
  export declare class GeoJSONSourceWithLayers<T extends FeatureCollection = FeatureCollection> extends AddedSourceWithLayers<GeoJSONSourceSpecification, GeoJSONSource> {
2782
2987
  shownFeatures: T;
2783
2988
  constructor(map: Map_2, sourceId: string, layerSpecs: ToBeAddedLayerSpecWithoutSource[], addLayersToMap?: boolean);
2784
- show(featureCollection: T): void;
2989
+ show(featureCollection: T, { automaticVisibility }?: ShowOptions): void;
2785
2990
  clear(): void;
2786
2991
  private findFeature;
2787
2992
  putEventState(options: PutEventStateOptions): void;
@@ -2907,6 +3112,7 @@ export declare class GeometriesModule extends AbstractMapModule<GeometrySourcesW
2907
3112
  private titleSourceID;
2908
3113
  private titleLayerID;
2909
3114
  private lastRawInput;
3115
+ private readonly shownFeaturesHandlers;
2910
3116
  /**
2911
3117
  * Make sure the map is ready before create an instance of the module and any other interaction with the map
2912
3118
  * @param tomtomMap The TomTomMap instance.
@@ -3143,7 +3349,7 @@ export declare class GeometriesModule extends AbstractMapModule<GeometrySourcesW
3143
3349
  /**
3144
3350
  * Gets the events interface for handling user interactions with geometries.
3145
3351
  *
3146
- * @returns An EventsModule instance for registering event handlers.
3352
+ * @returns A `UserEvents` instance for registering event handlers.
3147
3353
  *
3148
3354
  * @remarks
3149
3355
  * **Supported Events:**
@@ -3185,7 +3391,7 @@ export declare class GeometriesModule extends AbstractMapModule<GeometrySourcesW
3185
3391
  * });
3186
3392
  * ```
3187
3393
  */
3188
- get events(): EventsModule<MapGeoJSONFeature>;
3394
+ get events(): CombinedEvents<MapGeoJSONFeature, GeometriesModuleConfig, PolygonFeatures>;
3189
3395
  }
3190
3396
 
3191
3397
  /**
@@ -3355,7 +3561,7 @@ export declare type GeometriesModuleConfig = MapModuleCommonConfig & {
3355
3561
  *
3356
3562
  * @group Geometries
3357
3563
  */
3358
- export declare type GeometryBeforeLayerConfig = 'top' | MapStyleLayerID;
3564
+ export declare type GeometryBeforeLayerConfig = BeforeLayerConfig;
3359
3565
 
3360
3566
  /**
3361
3567
  * Color configuration for geometry fill styling.
@@ -3908,25 +4114,25 @@ export declare class HillshadeModule extends AbstractMapModule<HillshadeSourcesW
3908
4114
  */
3909
4115
  isVisible(): boolean;
3910
4116
  /**
3911
- * Gets the events interface for handling user interactions with hillshade.
3912
- *
3913
- * @returns An EventsModule instance for registering event handlers.
3914
- *
3915
- * @remarks
3916
- * **Supported Events:**
3917
- * - `click`: User clicks on the hillshade layer
3918
- * - `contextmenu`: User right-clicks
3919
- * - `hover`: Mouse enters hillshade area
3920
- * - `long-hover`: Extended hover
4117
+ * Gets the unified events interface for this module, covering both user interactions
4118
+ * and module lifecycle events.
3921
4119
  *
3922
- * @example
4120
+ * **User interaction events** (`click`, `contextmenu`, `hover`, `long-hover`):
3923
4121
  * ```typescript
3924
4122
  * hillshade.events.on('click', (feature, lngLat) => {
3925
4123
  * console.log('Clicked terrain at:', lngLat);
3926
4124
  * });
3927
4125
  * ```
4126
+ *
4127
+ * **Module lifecycle events** (`config-change`):
4128
+ * ```typescript
4129
+ * const unsub = hillshade.events.on('config-change', (config) => {
4130
+ * console.log('Hillshade config changed:', config);
4131
+ * });
4132
+ * unsub();
4133
+ * ```
3928
4134
  */
3929
- get events(): EventsModule<MapGeoJSONFeature>;
4135
+ get events(): CombinedEvents<MapGeoJSONFeature, HillshadeModuleConfig, never>;
3930
4136
  }
3931
4137
 
3932
4138
  /**
@@ -4581,6 +4787,107 @@ export declare const MINOR_DELAY_LABEL_COLOR = "#f58240";
4581
4787
  */
4582
4788
  export declare const MODERATE_DELAY_COLOR = "#FB2D09";
4583
4789
 
4790
+ /**
4791
+ * Lifecycle event module for map modules.
4792
+ *
4793
+ * Provides a unified API for subscribing to module-level events that are not tied
4794
+ * to user interaction with map features. Two event types are supported:
4795
+ *
4796
+ * - `config-change`: emitted whenever the module's configuration is updated
4797
+ * (via `applyConfig`, `resetConfig`, or any module-specific setter that mutates config).
4798
+ * - `shown-features`: emitted by modules that have a `show` method, immediately after
4799
+ * features are displayed on the map.
4800
+ *
4801
+ * Each `on()` call returns an unsubscribe function so individual handlers can be
4802
+ * removed without clearing the entire listener list.
4803
+ *
4804
+ * @typeParam TConfig - The module's configuration type.
4805
+ * @typeParam TShownFeatures - The type of data passed to `show()`. Use `never` for
4806
+ * modules that have no `show` method.
4807
+ *
4808
+ * @example
4809
+ * ```typescript
4810
+ * const unsubscribeConfig = trafficFlow.events.on('config-change', (config) => {
4811
+ * console.log('New config:', config);
4812
+ * });
4813
+ *
4814
+ * const unsubscribeShown = places.events.on('shown-features', (features) => {
4815
+ * console.log('Shown:', features);
4816
+ * });
4817
+ *
4818
+ * // Later:
4819
+ * unsubscribeConfig();
4820
+ * unsubscribeShown();
4821
+ * ```
4822
+ *
4823
+ * @group Events
4824
+ */
4825
+ export declare class ModuleEvents<TConfig, TShownFeatures = never> {
4826
+ private readonly configChangeHandlers;
4827
+ private readonly shownFeaturesHandlers;
4828
+ constructor(configChangeHandlers: ((config: TConfig | undefined) => void)[], shownFeaturesHandlers: ((features: TShownFeatures) => void)[]);
4829
+ /**
4830
+ * Subscribe to config-change events.
4831
+ *
4832
+ * The handler is called with the module's full current configuration immediately after
4833
+ * any mutation — whether through `applyConfig`, a module-specific setter, or `resetConfig`.
4834
+ *
4835
+ * @param type - `'config-change'`
4836
+ * @param handler - Receives the module's config (or `undefined` when config is cleared).
4837
+ * @returns An unsubscribe function. Call it to remove **only this handler** without
4838
+ * affecting other registered handlers for the same event type.
4839
+ *
4840
+ * @example
4841
+ * ```typescript
4842
+ * const unsub = trafficFlow.events.on('config-change', (config) => {
4843
+ * toggle.checked = config?.visible ?? false;
4844
+ * });
4845
+ *
4846
+ * // Later:
4847
+ * unsub();
4848
+ * ```
4849
+ */
4850
+ on(type: 'config-change', handler: (config: TConfig | undefined) => void): () => void;
4851
+ /**
4852
+ * Subscribe to shown-features events.
4853
+ *
4854
+ * The handler is called immediately after a module's `show()` method (or equivalent)
4855
+ * has updated the map with new data. Only available on modules that have a `show` method.
4856
+ *
4857
+ * @param type - `'shown-features'`
4858
+ * @param handler - Receives the data that was passed to `show()`.
4859
+ * @returns An unsubscribe function. Call it to remove **only this handler** without
4860
+ * affecting other registered handlers for the same event type.
4861
+ *
4862
+ * @example
4863
+ * ```typescript
4864
+ * const unsub = places.events.on('shown-features', (features) => {
4865
+ * fitMapToResults(features);
4866
+ * });
4867
+ *
4868
+ * // Later:
4869
+ * unsub();
4870
+ * ```
4871
+ */
4872
+ on(type: 'shown-features', handler: (features: TShownFeatures) => void): () => void;
4873
+ /**
4874
+ * Remove **all** handlers for the given event type at once.
4875
+ *
4876
+ * Prefer the unsubscribe function returned by {@link on} when you need to remove a
4877
+ * single handler. Use `off` for bulk teardown — e.g. when unmounting a component that
4878
+ * registered multiple handlers.
4879
+ *
4880
+ * @param type - The event type whose handlers should all be cleared.
4881
+ *
4882
+ * @example
4883
+ * ```typescript
4884
+ * // Clear all config-change listeners in one call
4885
+ * trafficFlow.events.off('config-change');
4886
+ * ```
4887
+ */
4888
+ off(type: 'config-change' | 'shown-features'): void;
4889
+ }
4890
+
4584
4891
  /**
4585
4892
  * @ignore
4586
4893
  */
@@ -4942,6 +5249,7 @@ export declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLaye
4942
5249
  */
4943
5250
  private instanceIndex;
4944
5251
  private defaultPlaceIconID;
5252
+ private readonly shownFeaturesHandlers;
4945
5253
  /**
4946
5254
  * Make sure the map is ready before create an instance of the module and any other interaction with the map
4947
5255
  * @param tomtomMap The TomTomMap instance.
@@ -5181,11 +5489,7 @@ export declare class PlacesModule extends AbstractMapModule<PlacesSourcesAndLaye
5181
5489
  * ```
5182
5490
  */
5183
5491
  cleanEventStates(options?: CleanEventStatesOptions): void;
5184
- /**
5185
- * Create the events on/off for this module
5186
- * @returns An instance of EventsModule
5187
- */
5188
- get events(): EventsModule<Place_2<DisplayPlaceProps>>;
5492
+ get events(): CombinedEvents<Place_2<DisplayPlaceProps>, PlacesModuleConfig, Place_2 | Place_2[] | Places>;
5189
5493
  }
5190
5494
 
5191
5495
  /**
@@ -5859,7 +6163,7 @@ export declare class POIsModule extends AbstractMapModule<PoIsSourcesAndLayers,
5859
6163
  /**
5860
6164
  * Gets the events interface for handling user interactions with POIs.
5861
6165
  *
5862
- * @returns An EventsModule instance for registering event handlers.
6166
+ * @returns A `UserEvents` instance for registering event handlers.
5863
6167
  *
5864
6168
  * @remarks
5865
6169
  * **Supported Events:**
@@ -5889,7 +6193,7 @@ export declare class POIsModule extends AbstractMapModule<PoIsSourcesAndLayers,
5889
6193
  * });
5890
6194
  * ```
5891
6195
  */
5892
- get events(): EventsModule<POIsModuleFeature>;
6196
+ get events(): CombinedEvents<POIsModuleFeature, POIsModuleConfig, never>;
5893
6197
  }
5894
6198
 
5895
6199
  /**
@@ -6208,19 +6512,10 @@ export declare const reachableRangeGeometryConfig: (palette?: ColorPaletteOption
6208
6512
  export declare type ReachableRangeLabelFn = (feature: PolygonFeature, index: number) => string;
6209
6513
 
6210
6514
  /**
6211
- * Renders a day × hour congestion heatmap chart on a `<canvas>`.
6212
- *
6213
- * Treats `entries` as a flat sequential array (index 0 = day 0 hour 0,
6214
- * index 1 = day 0 hour 1, etc.). Uses `startDate` to compute day labels.
6215
- *
6216
- * @param canvas - Target canvas element.
6217
- * @param entries - Sequential hourly entries (168 = 7 days × 24 hours).
6218
- * @param startDate - ISO date string (YYYY-MM-DD) for the first day.
6219
- * @param colorScheme - Color scheme preset (default: `'congestion'`).
6220
- *
6221
- * @group Traffic Area Analytics
6515
+ * Resolves the effective color stops for a given color configuration.
6516
+ * @ignore
6222
6517
  */
6223
- export declare function renderAreaAnalyticsChart(canvas: HTMLCanvasElement, entries: AreaAnalyticsTimedEntry[], startDate: string, colorScheme?: AreaAnalyticsColorScheme): void;
6518
+ export declare const resolveColorStops: (colorConfig: AreaAnalyticsColorTheme | AreaAnalyticsColorStopsConfig) => AreaAnalyticsColorStop[];
6224
6519
 
6225
6520
  /**
6226
6521
  * Available road hierarchy category identifiers.
@@ -6834,6 +7129,7 @@ export declare class RoutingModule extends AbstractMapModule<RoutingSourcesWithL
6834
7129
  * @private
6835
7130
  */
6836
7131
  private instanceIndex;
7132
+ private readonly shownFeaturesHandlers;
6837
7133
  /**
6838
7134
  * Make sure the map is ready before create an instance of the module and any other interaction with the map
6839
7135
  * @param tomtomMap The TomTomMap instance.
@@ -7052,20 +7348,41 @@ export declare class RoutingModule extends AbstractMapModule<RoutingSourcesWithL
7052
7348
  summaryBubbles: DisplayRouteSummaries;
7053
7349
  };
7054
7350
  /**
7055
- * Create the events on/off for this module
7056
- * @returns An instance of EventsModule
7351
+ * Unified events interface for the routing module, split into two namespaces:
7352
+ *
7353
+ * **`events.user`** — user interaction events, keyed by source:
7354
+ * ```typescript
7355
+ * routing.events.user.mainLines.on('click', (route) => { ... });
7356
+ * routing.events.user.waypoints.on('hover', (waypoint) => { ... });
7357
+ * ```
7358
+ *
7359
+ * **`events.module`** — module lifecycle events:
7360
+ * ```typescript
7361
+ * const unsub = routing.events.module.on('config-change', (config) => { ... });
7362
+ * const unsub = routing.events.module.on('shown-features', (features) => {
7363
+ * if ('routes' in features) { ... }
7364
+ * });
7365
+ * unsub();
7366
+ * ```
7057
7367
  */
7058
7368
  get events(): {
7059
- mainLines: EventsModule<Route<DisplayRouteProps>>;
7060
- waypoints: EventsModule<Waypoint<WaypointDisplayProps>>;
7061
- chargingStops: EventsModule<RouteSection>;
7062
- summaryBubbles: EventsModule<DisplayRouteSummary>;
7063
- incidents: EventsModule<RouteSection<DisplayTrafficSectionProps>>;
7064
- vehicleRestricted: EventsModule<RouteSection>;
7065
- ferries: EventsModule<RouteSection>;
7066
- tollRoads: EventsModule<RouteSection>;
7067
- tunnels: EventsModule<RouteSection>;
7068
- instructionLines: EventsModule<DisplayInstruction>;
7369
+ user: {
7370
+ mainLines: UserEvents<Route<DisplayRouteProps>>;
7371
+ waypoints: UserEvents<Waypoint<WaypointDisplayProps>>;
7372
+ chargingStops: UserEvents<RouteSection>;
7373
+ summaryBubbles: UserEvents<DisplayRouteSummary>;
7374
+ incidents: UserEvents<RouteSection<DisplayTrafficSectionProps>>;
7375
+ vehicleRestricted: UserEvents<RouteSection>;
7376
+ ferries: UserEvents<RouteSection>;
7377
+ tollRoads: UserEvents<RouteSection>;
7378
+ tunnels: UserEvents<RouteSection>;
7379
+ instructionLines: UserEvents<DisplayInstruction>;
7380
+ };
7381
+ module: ModuleEvents<RoutingModuleConfig, {
7382
+ routes: Route | Routes_2;
7383
+ } | {
7384
+ waypoints: PlanningWaypoint[] | Waypoints_2;
7385
+ }>;
7069
7386
  };
7070
7387
  /**
7071
7388
  * Returns the map style layer under which route lines are rendered.
@@ -7205,6 +7522,22 @@ export declare const serviceRoadSubCategories: readonly ["parking", "driveway",
7205
7522
  */
7206
7523
  export declare type ServiceRoadSubCategory = (typeof serviceRoadSubCategories)[number];
7207
7524
 
7525
+ /**
7526
+ * Options for the {@link GeoJSONSourceWithLayers.show} method.
7527
+ * @ignore
7528
+ */
7529
+ export declare type ShowOptions = {
7530
+ /**
7531
+ * When `true` (default), layer visibility is automatically set based on whether
7532
+ * the feature collection is non-empty. Pass `false` from state-update calls
7533
+ * (e.g. `putEventState`, `cleanEventState`) to avoid unintentionally hiding or
7534
+ * showing layers when only feature state changes.
7535
+ *
7536
+ * @defaultValue true
7537
+ */
7538
+ automaticVisibility?: boolean;
7539
+ };
7540
+
7208
7541
  /**
7209
7542
  * Optional parameters when showing routes on the map.
7210
7543
  *
@@ -7742,36 +8075,6 @@ export declare type SymbolLayerSpecWithoutSource = Omit<SymbolLayerSpecification
7742
8075
  */
7743
8076
  export declare const themedGeometryConfig: (palette?: ColorPaletteOptions, beforeLayerConfig?: GeometryBeforeLayerConfig) => GeometriesModuleConfig;
7744
8077
 
7745
- /**
7746
- * Converts area-analytics tile entries into a hexagonal polygon grid
7747
- * using Turf's `hexGrid` and spatial-join aggregation.
7748
- *
7749
- * Tiles that fall within the same hexagon cell are averaged. Empty hexagons
7750
- * (containing no tiles) are excluded from the result.
7751
- *
7752
- * @param tiles - Tile entries from the area analytics response.
7753
- * @param cellSideKm - Hex cell side length in kilometres (default 0.5).
7754
- * @returns A Polygon FeatureCollection with averaged metric properties.
7755
- *
7756
- * @group Traffic Area Analytics
7757
- */
7758
- export declare function tilesToHexFeatures(tiles: ReadonlyArray<AreaAnalyticsTileEntry>, cellSideKm?: number): FeatureCollection<Polygon, AreaAnalyticsDisplayProperties>;
7759
-
7760
- /**
7761
- * Converts an array of area-analytics tile entries into a GeoJSON
7762
- * `FeatureCollection<Point>` suitable for the heatmap visualization layer.
7763
- *
7764
- * Each tile centre becomes a Point feature whose properties contain every
7765
- * metric value returned by the API.
7766
- *
7767
- * @param tiles - Tile entries from `TrafficAreaAnalytics.features[0].properties.tiledData.tiles`.
7768
- * @returns A Point FeatureCollection ready to pass to
7769
- * {@link TrafficAreaAnalyticsModule.show} as the `points` field.
7770
- *
7771
- * @group Traffic Area Analytics
7772
- */
7773
- export declare function tilesToPointFeatures(tiles: ReadonlyArray<AreaAnalyticsTileEntry>): FeatureCollection<Point, AreaAnalyticsDisplayProperties>;
7774
-
7775
8078
  /**
7776
8079
  * @ignore
7777
8080
  */
@@ -8477,8 +8780,35 @@ export declare const TRAFFIC_INCIDENTS_SOURCE_ID = "vectorTilesIncidents";
8477
8780
  * Configuration for the Traffic Area Analytics visualization module.
8478
8781
  *
8479
8782
  * @remarks
8480
- * Controls which visualization mode is active, which metric drives
8481
- * the color/height, and overall layer visibility.
8783
+ * The active metric is set via `activeMetric` (defaults to `'congestionLevel'`).
8784
+ * Per-metric style settings (color, height, filters) are nested under `metricConfig` keyed by
8785
+ * `AreaAnalyticsMetricKey`, making it easy to pre-configure multiple metrics independently and switch
8786
+ * between them at runtime via `setMetric()`.
8787
+ *
8788
+ * @example
8789
+ * ```typescript
8790
+ * const config: TrafficAreaAnalyticsConfig = {
8791
+ * displayMode: 'hexgrid-3d',
8792
+ * activeMetric: 'congestionLevel',
8793
+ * metricConfig: {
8794
+ * congestionLevel: {
8795
+ * color: 'heat',
8796
+ * height: { maxHeightMeters: 80, scaleMode: 'predefinedRange' },
8797
+ * filters: { min: 10 },
8798
+ * },
8799
+ * speed: {
8800
+ * color: {
8801
+ * valueType: 'raw',
8802
+ * stops: [
8803
+ * { value: 0, color: '#e03030' },
8804
+ * { value: 60, color: '#f5a623' },
8805
+ * { value: 120, color: '#2dc653' },
8806
+ * ],
8807
+ * },
8808
+ * },
8809
+ * },
8810
+ * };
8811
+ * ```
8482
8812
  *
8483
8813
  * @group Traffic Area Analytics
8484
8814
  */
@@ -8492,37 +8822,54 @@ export declare type TrafficAreaAnalyticsConfig = MapModuleCommonConfig & {
8492
8822
  /**
8493
8823
  * Visualization mode.
8494
8824
  *
8495
- * @defaultValue 'hexgrid'
8825
+ * @defaultValue 'hexgrid-3d'
8496
8826
  */
8497
- mode?: AreaAnalyticsMode;
8827
+ displayMode?: AreaAnalyticsDisplayMode;
8498
8828
  /**
8499
- * The traffic metric that drives color and height.
8829
+ * The metric that drives color and extrusion height.
8500
8830
  *
8501
8831
  * @defaultValue 'congestionLevel'
8502
8832
  */
8503
- metric?: AreaAnalyticsMetricKey;
8833
+ activeMetric?: AreaAnalyticsMetricKey;
8504
8834
  /**
8505
- * Preset color scheme for the visualization layers.
8835
+ * Per-metric visualization configuration (color, height, filters).
8506
8836
  *
8507
- * @defaultValue 'congestion'
8837
+ * Metrics not listed here fall back to defaults (congestion color theme, metric-dependent height scale).
8508
8838
  */
8509
- colorScheme?: AreaAnalyticsColorScheme;
8839
+ metricConfig?: Partial<Record<AreaAnalyticsMetricKey, AreaAnalyticsMetricConfig>>;
8840
+ /**
8841
+ * Per-layer-type positioning — controls where each analytics layer type sits in the map layer stack.
8842
+ * Omitted layer types fall back to their default positions (`'lowestLabel'` for flat/heatmap, `'lowestPlaceLabel'` for extrusions).
8843
+ */
8844
+ beforeLayerConfig?: AreaAnalyticsBeforeLayerConfig;
8845
+ /**
8846
+ * Display options for the region polygon boundary drawn alongside the analytics data.
8847
+ */
8848
+ regionPolygon?: AreaAnalyticsRegionPolygonConfig;
8510
8849
  };
8511
8850
 
8512
8851
  /**
8513
8852
  * Traffic Area Analytics visualization module.
8514
8853
  *
8515
- * Renders area-analytics data on the map in one of two modes:
8516
- * - **hexgrid** — 3D extruded hexagonal polygons coloured and raised by the active metric
8854
+ * Renders area-analytics data on the map in one of five modes:
8855
+ * - **hexgrid-3d** — 3D extruded hexagonal cells coloured and raised by the active metric (default)
8856
+ * - **hexgrid-2d** — Flat hexagonal cells coloured by the active metric
8857
+ * - **square-3d** — 3D extruded square cells coloured and raised by the active metric
8858
+ * - **square-2d** — Flat square cells coloured by the active metric
8517
8859
  * - **heatmap** — a MapLibre density-heatmap layer built from tile-centre points
8518
8860
  *
8861
+ * The actual region boundary is always rendered alongside the analytics cells.
8862
+ *
8519
8863
  * @remarks
8520
8864
  * **Quick start:**
8521
8865
  * ```typescript
8522
8866
  * import { TrafficAreaAnalyticsModule } from '@tomtom-org/maps-sdk/map';
8523
8867
  * import { trafficAreaAnalytics } from '@tomtom-org/maps-sdk/services';
8524
8868
  *
8525
- * const module = await TrafficAreaAnalyticsModule.get(map);
8869
+ * const module = await TrafficAreaAnalyticsModule.get(map, {
8870
+ * displayMode: 'hexgrid-3d',
8871
+ * metric: { active: 'congestionLevel' },
8872
+ * });
8526
8873
  * const analytics = await trafficAreaAnalytics({ ... });
8527
8874
  * await module.show(analytics);
8528
8875
  * ```
@@ -8531,34 +8878,51 @@ export declare type TrafficAreaAnalyticsConfig = MapModuleCommonConfig & {
8531
8878
  */
8532
8879
  export declare class TrafficAreaAnalyticsModule extends AbstractMapModule<AreaAnalyticsSourcesWithLayers, TrafficAreaAnalyticsConfig> {
8533
8880
  private static lastInstanceIndex;
8534
- /** Named layer IDs for explicit access in paint updates. */
8535
- private heatmapLayerId;
8536
- private hexFillLayerId;
8537
- private hexExtrusionLayerId;
8538
- /** Cached for style-change restoration. */
8881
+ private heatmapLayerSpec;
8882
+ private hexFillLayerSpec;
8883
+ private hexExtrusionLayerSpec;
8884
+ private hexOutlineLayerSpec;
8885
+ private hexExtrusionHighlightLayerSpec;
8886
+ private squareFillLayerSpec;
8887
+ private squareExtrusionLayerSpec;
8888
+ private squareOutlineLayerSpec;
8889
+ private squareExtrusionHighlightLayerSpec;
8890
+ private regionFillLayerSpec;
8891
+ private regionLineLayerSpec;
8539
8892
  private lastAnalytics;
8893
+ private readonly shownFeaturesHandlers;
8540
8894
  /**
8541
- * Creates a new Traffic Area Analytics module.
8895
+ * Creates and initialises a new Traffic Area Analytics module.
8896
+ *
8897
+ * All configuration properties are optional. When `config` is omitted (or only
8898
+ * partially supplied), built-in defaults are applied for every missing field.
8899
+ * After `get()` resolves, {@link TrafficAreaAnalyticsModule.getConfig} always returns a
8900
+ * fully-populated configuration — there is no need to reference any default
8901
+ * values yourself.
8542
8902
  *
8543
8903
  * @param tomtomMap - The TomTomMap instance.
8544
- * @param config - Optional initial configuration.
8904
+ * @param config - Optional initial configuration. Omit to use all defaults.
8545
8905
  * @returns A promise that resolves with the initialised module.
8546
8906
  *
8547
8907
  * @example
8548
8908
  * ```typescript
8549
- * const module = await TrafficAreaAnalyticsModule.get(map, {
8550
- * mode: 'hexgrid',
8551
- * metric: 'congestionLevel',
8909
+ * // No config needed — defaults are applied automatically.
8910
+ * const module = await TrafficAreaAnalyticsModule.get(map);
8911
+ * await module.show(analytics);
8912
+ *
8913
+ * // Or override specific properties while keeping everything else at default:
8914
+ * const module = await TrafficAreaAnalyticsModule.get(map, {
8915
+ * displayMode: 'heatmap',
8916
+ * metricConfig: {
8917
+ * congestionLevel: { color: 'heat' },
8918
+ * },
8552
8919
  * });
8553
8920
  * ```
8554
8921
  */
8555
8922
  static get(tomtomMap: TomTomMap, config?: TrafficAreaAnalyticsConfig): Promise<TrafficAreaAnalyticsModule>;
8556
8923
  private constructor();
8557
- private get mode();
8558
- private get metric();
8559
- private get colorScheme();
8560
8924
  /** @ignore */
8561
- protected _initSourcesWithLayers(_config?: TrafficAreaAnalyticsConfig, restore?: boolean): AreaAnalyticsSourcesWithLayers;
8925
+ protected _initSourcesWithLayers(config?: TrafficAreaAnalyticsConfig, restore?: boolean): AreaAnalyticsSourcesWithLayers;
8562
8926
  /** @ignore */
8563
8927
  protected _applyConfig(config: TrafficAreaAnalyticsConfig | undefined): TrafficAreaAnalyticsConfig | undefined;
8564
8928
  /** @ignore */
@@ -8567,8 +8931,9 @@ export declare class TrafficAreaAnalyticsModule extends AbstractMapModule<AreaAn
8567
8931
  * Displays area analytics data on the map.
8568
8932
  *
8569
8933
  * Accepts the raw response from `trafficAreaAnalytics()`. Tile data is
8570
- * transformed internally to point features (heatmap) and hexagonal
8571
- * polygons (hexgrid) — no manual data preparation is needed.
8934
+ * transformed internally to point features (heatmap), hexagonal polygons
8935
+ * (hexgrid modes), and square polygons (square modes).
8936
+ * The region boundary geometry is also displayed.
8572
8937
  *
8573
8938
  * @param analytics - The raw `TrafficAreaAnalytics` service response.
8574
8939
  *
@@ -8586,49 +8951,149 @@ export declare class TrafficAreaAnalyticsModule extends AbstractMapModule<AreaAn
8586
8951
  /**
8587
8952
  * Switches the visualisation mode.
8588
8953
  *
8589
- * @param mode - `'heatmap'` or `'hexgrid'`.
8954
+ * @param mode - One of `'heatmap'`, `'hexgrid-3d'`, `'hexgrid-2d'`, `'square-3d'`, `'square-2d'`.
8590
8955
  */
8591
- setMode(mode: AreaAnalyticsMode): void;
8956
+ setMode(mode: AreaAnalyticsDisplayMode): void;
8592
8957
  /**
8593
8958
  * Changes the active metric that drives colour and height.
8594
8959
  *
8595
- * @param metric - One of `'congestionLevel'`, `'speed'`, or `'travelTime'`.
8960
+ * Updates `activeMetric` in the config to the given metric key.
8961
+ *
8962
+ * @param metric - One of `'congestionLevel'`, `'speed'`, `'travelTime'`, `'freeFlowSpeed'`, or `'networkLength'`.
8596
8963
  */
8597
- setMetric(metric: AreaAnalyticsMetricKey): void;
8964
+ setMetric(metric: AreaAnalyticsMetricKey_2): void;
8598
8965
  /**
8599
- * Changes the color scheme preset.
8966
+ * Sets the color for one or more metrics.
8967
+ *
8968
+ * Pass a preset theme name or a custom color-stops configuration.
8969
+ * Pass `undefined` to clear the color override for the targeted metrics.
8970
+ *
8971
+ * @param color - A preset theme, an `AreaAnalyticsColorStopsConfig`, or `undefined` to clear.
8972
+ * @param metrics - Optional list of metrics to target.
8973
+ * When omitted, the color is applied to **all** metrics.
8974
+ *
8975
+ * @example
8976
+ * ```typescript
8977
+ * // Apply a theme to all metrics
8978
+ * module.setColor('heat');
8979
+ *
8980
+ * // Apply a theme to specific metrics only
8981
+ * module.setColor('heat', ['speed', 'freeFlowSpeed']);
8982
+ *
8983
+ * // Apply custom stops to a single metric
8984
+ * module.setColor(
8985
+ * { valueType: 'raw', stops: [{ value: 0, color: '#2dc653' }, { value: 100, color: '#e03030' }] },
8986
+ * ['congestionLevel'],
8987
+ * );
8988
+ *
8989
+ * // Clear color override for all metrics
8990
+ * module.setColor(undefined);
8600
8991
  *
8601
- * @param scheme - One of `'congestion'`, `'thermal'`, or `'monochrome'`.
8992
+ * // Clear color override for a specific metric
8993
+ * module.setColor(undefined, ['speed']);
8994
+ * ```
8602
8995
  */
8603
- setColorScheme(scheme: AreaAnalyticsColorScheme): void;
8996
+ setColor(color: AreaAnalyticsColorTheme | AreaAnalyticsColorStopsConfig | undefined, metrics?: AreaAnalyticsMetricKey_2[]): void;
8997
+ /**
8998
+ * Configures extrusion height behaviour for one or more metrics.
8999
+ *
9000
+ * @param heightConfig - Height configuration.
9001
+ * @param metrics - Optional list of metrics to target.
9002
+ * When omitted, the height config is applied to **all** metrics.
9003
+ *
9004
+ * @example
9005
+ * ```typescript
9006
+ * // Apply to all metrics
9007
+ * module.setHeight({ maxHeightMeters: 100, minHeightMeters: 5 });
9008
+ *
9009
+ * // Apply only to specific metrics
9010
+ * module.setHeight({ scaleMode: 'currentRange', maxHeightMeters: 500 }, ['speed', 'freeFlowSpeed']);
9011
+ * ```
9012
+ */
9013
+ setHeight(heightConfig: AreaAnalyticsHeightConfig, metrics?: AreaAnalyticsMetricKey_2[]): void;
9014
+ /**
9015
+ * Filters visible tiles by value range for one or more metrics.
9016
+ *
9017
+ * @param filter - Filter config. Pass `undefined` to clear.
9018
+ * @param metrics - Optional list of metrics to target.
9019
+ * When omitted, the filter is applied to **all** metrics.
9020
+ *
9021
+ * @example
9022
+ * ```typescript
9023
+ * // Filter all metrics
9024
+ * module.filter({ min: 20, max: 80 });
9025
+ *
9026
+ * // Filter only a specific metric
9027
+ * module.filter({ min: 50 }, ['congestionLevel']);
9028
+ *
9029
+ * // Clear filter for all metrics
9030
+ * module.filter(undefined);
9031
+ * ```
9032
+ */
9033
+ filter(filter?: AreaAnalyticsMetricFilter, metrics?: AreaAnalyticsMetricKey_2[]): void;
9034
+ /**
9035
+ * Clears any active tile filter for one or more metrics.
9036
+ *
9037
+ * @param metrics - Optional list of metrics to clear. When omitted, clears filters for **all** metrics.
9038
+ */
9039
+ clearFilter(metrics?: AreaAnalyticsMetricKey_2[]): void;
8604
9040
  /**
8605
9041
  * Shows or hides all area analytics layers.
8606
9042
  */
8607
9043
  setVisible(visible: boolean): void;
8608
9044
  /**
8609
- * Whether any area analytics layer is currently visible.
9045
+ * Whether any area analytics (data) layer is currently visible.
8610
9046
  */
8611
9047
  isVisible(): boolean;
8612
9048
  /**
8613
- * Returns the currently displayed data for both visualisation modes.
9049
+ * Returns the currently displayed data for all visualisation modes.
8614
9050
  */
8615
9051
  getShown(): {
8616
9052
  heatmap: FeatureCollection<Point, AreaAnalyticsDisplayProperties>;
8617
9053
  hexgrid: FeatureCollection<Polygon, AreaAnalyticsDisplayProperties>;
9054
+ square: FeatureCollection<Polygon, AreaAnalyticsDisplayProperties>;
8618
9055
  };
8619
9056
  /**
8620
- * Event interface for the hexgrid layer (hover / click on hexagonal cells).
9057
+ * Repositions analytics layers independently by layer type.
9058
+ *
9059
+ * Only the properties present in `layerConfig` are repositioned; omitted layer types are left in place.
9060
+ *
9061
+ * @param layerConfig - Per-layer-type positioning config. Each value is `'top'` or a `MapStyleLayerID`.
9062
+ */
9063
+ moveBeforeLayer(layerConfig: AreaAnalyticsBeforeLayerConfig): void;
9064
+ /**
9065
+ * Event interface for the hexgrid and square layers.
9066
+ *
9067
+ * Supports feature-interaction events (`hover`, `click`, `contextmenu`, `long-hover`) as well
9068
+ * as module lifecycle events (`config-change`, `shown-features`) — all through the same
9069
+ * `events.on(type, handler)` surface.
8621
9070
  *
8622
9071
  * @example
8623
9072
  * ```typescript
8624
9073
  * module.events.on('hover', (feature, lngLat) => {
8625
9074
  * console.log(feature.properties.congestionLevel);
8626
9075
  * });
9076
+ *
9077
+ * const unsub = module.events.on('config-change', (config) => {
9078
+ * console.log('Config updated:', config);
9079
+ * });
9080
+ *
9081
+ * module.events.on('shown-features', (data) => {
9082
+ * console.log('Analytics data shown:', data);
9083
+ * });
8627
9084
  * ```
8628
9085
  */
8629
- get events(): EventsModule<AreaAnalyticsHexFeature>;
9086
+ get events(): CombinedEvents<AreaAnalyticsTileFeature, TrafficAreaAnalyticsConfig, TrafficAreaAnalytics>;
9087
+ private get mode();
9088
+ private get activeMetric();
8630
9089
  private applyModeVisibility;
8631
- private applyMetricToLayers;
9090
+ private hideAllDataLayers;
9091
+ private addHighlightLayersToMap;
9092
+ private setHighlightLayerVisible;
9093
+ private applyLayerConfig;
9094
+ private applyRegionConfig;
9095
+ private applyFiltersToLayers;
9096
+ private buildRegionFC;
8632
9097
  }
8633
9098
 
8634
9099
  /**
@@ -8985,11 +9450,7 @@ export declare class TrafficFlowModule extends AbstractMapModule<TrafficFlowSour
8985
9450
  getShown(): {
8986
9451
  trafficFlow: TrafficFlowModuleFeature[];
8987
9452
  };
8988
- /**
8989
- * Create the events on/off for this module
8990
- * @returns An instance of EventsModule
8991
- */
8992
- get events(): EventsModule<TrafficFlowModuleFeature>;
9453
+ get events(): CombinedEvents<TrafficFlowModuleFeature, FlowConfig, never>;
8993
9454
  }
8994
9455
 
8995
9456
  /**
@@ -9481,11 +9942,7 @@ export declare class TrafficIncidentsModule extends AbstractMapModule<TrafficInc
9481
9942
  getShown(): {
9482
9943
  trafficIncidents: TrafficIncidentsModuleFeature[];
9483
9944
  };
9484
- /**
9485
- * Create the events on/off for this module
9486
- * @returns An instance of EventsModule
9487
- */
9488
- get events(): EventsModule<TrafficIncidentsModuleFeature>;
9945
+ get events(): CombinedEvents<TrafficIncidentsModuleFeature, IncidentsConfig, never>;
9489
9946
  }
9490
9947
 
9491
9948
  /**
@@ -9593,12 +10050,282 @@ export declare const UNKNOWN_DELAY_COLOR = "#000000";
9593
10050
  * });
9594
10051
  * ```
9595
10052
  *
9596
- * @see {@link EventsModule.on} - For registering event handlers
10053
+ * @see {@link UserEvents.on} - For registering event handlers
9597
10054
  *
9598
10055
  * @group User Interaction Events
9599
10056
  */
9600
10057
  export declare type UserEventHandler<T> = (topFeature: T, lngLat: LngLat, allEventFeatures: MapGeoJSONFeature[], sourceWithLayers: SourceWithLayers) => void;
9601
10058
 
10059
+ /**
10060
+ * Event handling interface for map features.
10061
+ *
10062
+ * Provides a simple API for attaching and removing event handlers for user interactions
10063
+ * with map features such as clicks, hovers, and context menus. Each map module (POIs, Routing,
10064
+ * Places, etc.) exposes an `events` property that returns a `UserEvents` instance.
10065
+ *
10066
+ * @typeParam T - The feature type returned in event handlers (extends MapGeoJSONFeature)
10067
+ *
10068
+ * @remarks
10069
+ * **Supported Event Types:**
10070
+ * - `click`: User clicks/taps on a feature
10071
+ * - `contextmenu`: User right-clicks on a feature (or long-press on mobile)
10072
+ * - `hover`: Mouse enters a feature
10073
+ * - `long-hover`: Mouse hovers over feature for configured duration (300-800ms)
10074
+ *
10075
+ * **Event Handler Signature:**
10076
+ * ```typescript
10077
+ * (feature: T, lngLat: LngLat, features: T[]) => void
10078
+ * ```
10079
+ *
10080
+ * **Parameters:**
10081
+ * - `feature`: The primary feature under the cursor
10082
+ * - `lngLat`: Geographic coordinates of the event
10083
+ * - `features`: All features at this location (when multiple overlap)
10084
+ *
10085
+ * **Key Features:**
10086
+ * - Automatic cursor management (pointer on hover)
10087
+ * - Smart event handling for overlapping features
10088
+ * - Configurable hover delays
10089
+ * - Memory-safe cleanup when removing handlers
10090
+ *
10091
+ * @example
10092
+ * ```typescript
10093
+ * // POI click handler
10094
+ * const pois = map.pois();
10095
+ * pois.events.on('click', (feature, lngLat) => {
10096
+ * console.log('Clicked POI:', feature.properties.name);
10097
+ * console.log('Location:', lngLat);
10098
+ * showInfoWindow(feature.properties);
10099
+ * });
10100
+ *
10101
+ * // Route waypoint hover
10102
+ * const routing = map.routing();
10103
+ * routing.events.waypoints.on('hover', (waypoint) => {
10104
+ * showTooltip(`Waypoint ${waypoint.properties.index}`);
10105
+ * });
10106
+ *
10107
+ * // Long-hover for detailed info
10108
+ * pois.events.on('long-hover', (feature) => {
10109
+ * loadAndShowDetailedInfo(feature.properties.id);
10110
+ * });
10111
+ *
10112
+ * // Context menu (right-click)
10113
+ * routing.events.mainLines.on('contextmenu', (route, lngLat) => {
10114
+ * showContextMenu(lngLat, [
10115
+ * { label: 'Add waypoint here', action: () => addWaypoint(lngLat) },
10116
+ * { label: 'View route details', action: () => showDetails(route) }
10117
+ * ]);
10118
+ * });
10119
+ *
10120
+ * // Remove all click handlers
10121
+ * pois.events.off('click');
10122
+ * ```
10123
+ *
10124
+ * @example
10125
+ * ```typescript
10126
+ * // Complete interaction example
10127
+ * const places = map.places();
10128
+ *
10129
+ * // Show name on hover
10130
+ * places.events.on('hover', (place) => {
10131
+ * tooltip.show(place.properties.name);
10132
+ * });
10133
+ *
10134
+ * // Show details on click
10135
+ * places.events.on('click', (place, lngLat) => {
10136
+ * sidebar.show({
10137
+ * title: place.properties.name,
10138
+ * address: place.properties.address.freeformAddress,
10139
+ * coordinates: lngLat
10140
+ * });
10141
+ * });
10142
+ *
10143
+ * // Cleanup on component unmount
10144
+ * onUnmount(() => {
10145
+ * places.events.off('hover');
10146
+ * places.events.off('click');
10147
+ * });
10148
+ * ```
10149
+ *
10150
+ * @group Events
10151
+ */
10152
+ export declare class UserEvents<T = MapGeoJSONFeature> {
10153
+ private readonly eventProxy;
10154
+ private readonly config;
10155
+ /**
10156
+ * Optional function that transforms a raw {@link MapGeoJSONFeature} into the
10157
+ * feature type `T` exposed by the module. When provided, every feature passed (fired)
10158
+ * to event handlers is first run through this function, so callers receive the
10159
+ * module's own feature shape instead of the underlying MapLibre feature.
10160
+ *
10161
+ * When omitted, `T` defaults to `MapGeoJSONFeature` and features are forwarded
10162
+ * as-is.
10163
+ */
10164
+ private readonly mapping?;
10165
+ private readonly sources;
10166
+ constructor(eventProxy: EventsProxy,
10167
+ /**
10168
+ * The source(s) whose features this module handles events for.
10169
+ * Pass an array to register handlers across multiple sources representing similar data in different display modes (e.g. hexgrid + square
10170
+ * in {@link TrafficAreaAnalyticsModule}). A single value is also accepted for
10171
+ * backwards compatibility.
10172
+ */
10173
+ sourcesWithLayers: SourceWithLayers | SourceWithLayers[], config: EventHandlerConfig | undefined,
10174
+ /**
10175
+ * Optional function that transforms a raw {@link MapGeoJSONFeature} into the
10176
+ * feature type `T` exposed by the module. When provided, every feature passed (fired)
10177
+ * to event handlers is first run through this function, so callers receive the
10178
+ * module's own feature shape instead of the underlying MapLibre feature.
10179
+ *
10180
+ * When omitted, `T` defaults to `MapGeoJSONFeature` and features are forwarded
10181
+ * as-is.
10182
+ */
10183
+ mapping?: ((feature: MapGeoJSONFeature) => T) | undefined);
10184
+ /**
10185
+ * Register an event handler for user interactions with map features.
10186
+ *
10187
+ * Attaches a callback function that will be invoked when users interact with
10188
+ * features in this module (e.g., clicking on a POI, hovering over a route).
10189
+ *
10190
+ * @param type The type of event to listen for (click, contextmenu, hover, long-hover)
10191
+ * @param handler Callback function invoked when the event occurs
10192
+ *
10193
+ * @remarks
10194
+ * **Handler Parameters:**
10195
+ * - `feature`: The primary feature that triggered the event
10196
+ * - `lngLat`: Geographic coordinates [longitude, latitude] of the event
10197
+ * - `features`: Array of all features at the event location (for overlapping features)
10198
+ *
10199
+ * **Behavior:**
10200
+ * - Only one handler per event type (calling `on()` again replaces the previous handler)
10201
+ * - Handlers are preserved across map style changes
10202
+ * - Cursor automatically changes to pointer on hover
10203
+ * - Events respect module visibility (hidden features don't trigger events)
10204
+ *
10205
+ * **Performance:**
10206
+ * - Hover events use spatial indexing for fast lookup
10207
+ * - Long-hover has configurable delay to prevent accidental triggers
10208
+ * - Event handlers should be lightweight to maintain smooth interaction
10209
+ *
10210
+ * @example
10211
+ * ```typescript
10212
+ * // Basic click handler
10213
+ * module.events.on('click', (feature, lngLat, features) => {
10214
+ * console.log('Clicked feature:', feature.properties);
10215
+ * console.log('Location:', lngLat);
10216
+ * console.log('All features here:', features.length);
10217
+ * });
10218
+ *
10219
+ * // Hover with tooltip
10220
+ * module.events.on('hover', (feature) => {
10221
+ * const name = feature.properties.name || 'Unnamed';
10222
+ * tooltip.show(name);
10223
+ * });
10224
+ *
10225
+ * // Long-hover for detailed preview
10226
+ * module.events.on('long-hover', (feature) => {
10227
+ * // Only triggered after hovering for 300-800ms
10228
+ * loadPreview(feature.properties.id);
10229
+ * });
10230
+ *
10231
+ * // Right-click context menu
10232
+ * module.events.on('contextmenu', (feature, lngLat) => {
10233
+ * event.preventDefault(); // Prevent browser context menu
10234
+ * showCustomMenu(lngLat, feature);
10235
+ * });
10236
+ * ```
10237
+ *
10238
+ * @example
10239
+ * ```typescript
10240
+ * // Route-specific handlers
10241
+ * const routing = map.routing();
10242
+ *
10243
+ * // Handle route line clicks
10244
+ * routing.events.mainLines.on('click', (route) => {
10245
+ * highlightRoute(route.properties.routeID);
10246
+ * showRouteSummary(route.properties.summary);
10247
+ * });
10248
+ *
10249
+ * // Handle waypoint interactions
10250
+ * routing.events.waypoints.on('hover', (waypoint) => {
10251
+ * const index = waypoint.properties.index;
10252
+ * showTooltip(`Stop ${index + 1}`);
10253
+ * });
10254
+ * ```
10255
+ */
10256
+ on(type: EventType, handler: UserEventHandler<T>): () => void;
10257
+ /**
10258
+ * Remove all event handlers for a specific event type.
10259
+ *
10260
+ * Unregisters the callback function for the specified event type, stopping
10261
+ * further event notifications. This is important for cleanup to prevent
10262
+ * memory leaks and unwanted behavior.
10263
+ *
10264
+ * @param type The type of event to stop listening for
10265
+ *
10266
+ * @remarks
10267
+ * **Cleanup Behavior:**
10268
+ * - Removes only the specified event type (other types remain active)
10269
+ * - Resets cursor behavior for this module
10270
+ * - Safe to call multiple times (no error if no handler exists)
10271
+ * - Does not affect other modules' event handlers
10272
+ *
10273
+ * **When to Use:**
10274
+ * - Component unmounting/cleanup
10275
+ * - Switching between interaction modes
10276
+ * - Temporarily disabling interactions
10277
+ * - Replacing an existing handler (call `off()` then `on()`)
10278
+ *
10279
+ * **Best Practices:**
10280
+ * - Always clean up event handlers when component unmounts
10281
+ * - Remove handlers before removing features from the map
10282
+ * - Use framework lifecycle hooks for automatic cleanup
10283
+ *
10284
+ * @example
10285
+ * ```typescript
10286
+ * // Remove click handlers
10287
+ * module.events.off('click');
10288
+ *
10289
+ * // Remove all handlers
10290
+ * module.events.off('click');
10291
+ * module.events.off('hover');
10292
+ * module.events.off('long-hover');
10293
+ * module.events.off('contextmenu');
10294
+ * ```
10295
+ *
10296
+ * @example
10297
+ * ```typescript
10298
+ * // React component cleanup
10299
+ * useEffect(() => {
10300
+ * const pois = map.pois();
10301
+ *
10302
+ * pois.events.on('click', handlePoiClick);
10303
+ * pois.events.on('hover', handlePoiHover);
10304
+ *
10305
+ * return () => {
10306
+ * // Cleanup on unmount
10307
+ * pois.events.off('click');
10308
+ * pois.events.off('hover');
10309
+ * };
10310
+ * }, [map]);
10311
+ * ```
10312
+ *
10313
+ * @example
10314
+ * ```typescript
10315
+ * // Replace handler
10316
+ * module.events.off('click'); // Remove old handler
10317
+ * module.events.on('click', newHandler); // Add new handler
10318
+ *
10319
+ * // Disable interactions temporarily
10320
+ * const savedHandler = currentHandler;
10321
+ * module.events.off('click'); // Disable
10322
+ * // ... later ...
10323
+ * module.events.on('click', savedHandler); // Re-enable
10324
+ * ```
10325
+ */
10326
+ off(type: EventType): void;
10327
+ }
10328
+
9602
10329
  /**
9603
10330
  * Generic filter configuration for showing or hiding items by value.
9604
10331
  *