@tomtom-org/maps-sdk 0.47.9 → 0.48.1

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.
@@ -111,6 +111,18 @@ declare abstract class AbstractEventProxy {
111
111
  * @param sourceId The source id (should be linked to a SourceWithLayers instance).
112
112
  */
113
113
  hasSourceID(sourceId: string): boolean;
114
+ /**
115
+ * Look up the {@link SourceWithLayers} registered for the given source ID, if any.
116
+ *
117
+ * The SDK assumes at most one `SourceWithLayers` per MapLibre source ID — each
118
+ * module creates its own source — so any non-empty handler bucket gives us the
119
+ * right reference. We iterate event-type buckets defensively to skip transient
120
+ * empty arrays left mid-`removeHandler` before the bucket itself is deleted.
121
+ *
122
+ * NOTE: if two modules ever register against the same source ID with overlapping
123
+ * layers, this returns the first one we encounter.
124
+ */
125
+ protected sourceWithLayersFor(sourceId: string | undefined): SourceWithLayers | undefined;
114
126
  /**
115
127
  * Updates the given sourcesWithLayers, if they have any handlers.
116
128
  * * (This is typically called to refresh any registered, stale sourceWithLayers references after a map style has changed).
@@ -3148,6 +3160,18 @@ export declare class EventsProxy extends AbstractEventProxy {
3148
3160
  enable(enabled: boolean): void;
3149
3161
  private toPaddedBounds;
3150
3162
  private isEnabled;
3163
+ /**
3164
+ * Build the consumer-facing `allEventFeatures`: scope to the firing source, dedupe, then
3165
+ * substitute cached typed originals. Scope and dedupe run on the raw features, since
3166
+ * `.source` and the rendered id survive only before substitution; the top hit stays first.
3167
+ *
3168
+ * Scoping leaves only `firingSource`'s hits, so its {@link SourceWithLayers} is resolved once
3169
+ * here rather than per feature. For GeoJSON-backed sources we substitute the cached typed
3170
+ * original (un-stringified properties, real Dates, nested objects); for everything else — vector
3171
+ * tiles, unregistered sources — the MapLibre-rendered feature passes through (`MapGeoJSONFeature
3172
+ * extends Feature`).
3173
+ */
3174
+ private toCallerFeatures;
3151
3175
  private getRenderedFeatures;
3152
3176
  private clearLongHoverTimeout;
3153
3177
  private restartLongHoverTimeout;
@@ -3321,6 +3345,13 @@ export declare type FilterShowMode = 'all_except' | 'only';
3321
3345
  */
3322
3346
  export declare type FilterSyntaxVersion = 'expression' | 'legacy';
3323
3347
 
3348
+ /**
3349
+ * Find the first feature whose {@link renderedRefId} equals `id`, with its index, or
3350
+ * `undefined` (also for a nullish `id`).
3351
+ * @ignore
3352
+ */
3353
+ export declare const findFeatureByRefId: <F extends RenderedRef>(features: readonly F[], id: string | number | undefined) => IndexedFeature<F> | undefined;
3354
+
3324
3355
  /**
3325
3356
  * @group Routing
3326
3357
  */
@@ -3366,6 +3397,11 @@ export declare class GeoJSONSourceWithLayers<T extends FeatureCollection = Featu
3366
3397
  shownFeatures: T;
3367
3398
  constructor(map: Map_2, sourceId: string, layerSpecs: ToBeAddedLayerSpecWithoutSource[], addLayersToMap?: boolean, clusterOptions?: GeoJSONSourceClusterOptions);
3368
3399
  show(featureCollection: T, { automaticVisibility }?: ShowOptions): void;
3400
+ /**
3401
+ * Canonical id-based lookup into `shownFeatures.features` via {@link findFeatureByRefId}
3402
+ * (first match wins on duplicate ids). Returns `undefined` for a nullish or absent id.
3403
+ */
3404
+ findById(id: string | number | undefined): IndexedFeature<T['features'][number]> | undefined;
3369
3405
  clear(): void;
3370
3406
  private findFeature;
3371
3407
  putEventState(options: PutEventStateOptions): void;
@@ -4668,6 +4704,12 @@ export declare const INDEFINITE_DELAY_DASH_COLOR = "rgba(137, 150, 168, 1)";
4668
4704
  */
4669
4705
  export declare const INDEX_TYPE = "indexType";
4670
4706
 
4707
+ /** A feature together with its index in the array it was found in. @ignore */
4708
+ export declare type IndexedFeature<F> = {
4709
+ feature: F;
4710
+ index: number;
4711
+ };
4712
+
4671
4713
  /**
4672
4714
  * Complete TomTom map parameters after merging with global configuration.
4673
4715
  * This type represents the fully resolved configuration used internally by the SDK.
@@ -7103,6 +7145,33 @@ export declare const reachableRangeGeometryConfig: (palette?: ColorPaletteOption
7103
7145
  /** Custom label generator for reachable range features. */
7104
7146
  export declare type ReachableRangeLabelFn = (feature: PolygonFeature, index: number) => string;
7105
7147
 
7148
+ /**
7149
+ * Class-independent feature-id recovery and lookup, shared by the event subsystem and the
7150
+ * source/layer caches. Operate on the minimal {@link RenderedRef} shape, so they accept
7151
+ * MapLibre `MapGeoJSONFeature`s, plain GeoJSON `Feature`s, and cached originals alike.
7152
+ */
7153
+ /** Minimal shape needed to look a feature up by id. @ignore */
7154
+ export declare type RenderedRef = {
7155
+ id?: string | number;
7156
+ properties?: {
7157
+ id?: unknown;
7158
+ } | null;
7159
+ };
7160
+
7161
+ /**
7162
+ * Recover the SDK-assigned id of a feature, preferring `properties.id` over the top-level `id`.
7163
+ *
7164
+ * The SDK always stamps the real id into `properties.id` and uses `promoteId: 'id'`, so MapLibre
7165
+ * mirrors it onto the top-level `id` — the two are normally identical. The exception is **clustered**
7166
+ * GeoJSON sources: clustering disables `promoteId`, and MapLibre's supercluster then assigns its own
7167
+ * **synthetic** numeric top-level `id` (0, 1, 2, …) to rendered features. Preferring the top-level
7168
+ * `id` there would return that synthetic value and miss the cache, whereas `properties.id` is still
7169
+ * the real id. So read `properties.id` first, falling back to the top-level `id` (e.g. vector-tile
7170
+ * features that only carry a top-level id). Returns `undefined` when neither is set.
7171
+ * @ignore
7172
+ */
7173
+ export declare const renderedRefId: (rendered: RenderedRef) => string | number | undefined;
7174
+
7106
7175
  /**
7107
7176
  * Resolves the effective color stops for a given color configuration.
7108
7177
  * @ignore
@@ -10215,7 +10284,7 @@ export declare type TrafficIncidentOverlayConfig = MapModuleCommonConfig & {
10215
10284
  * await overlay.show(result);
10216
10285
  *
10217
10286
  * // Highlight a subset.
10218
- * overlay.setFocus([result.features[0].id as string]);
10287
+ * overlay.setFocus([result.features[0].properties.id as string]);
10219
10288
  * ```
10220
10289
  *
10221
10290
  * @see {@link TrafficIncidentsModule} — the vector-tile alternative. Hidden in the
@@ -10261,18 +10330,17 @@ export declare class TrafficIncidentOverlayModule extends AbstractMapModule<Sour
10261
10330
  */
10262
10331
  moveBeforeLayer(beforeLayerConfig: BeforeLayerConfig): void;
10263
10332
  /**
10264
- * Incidents currently rendered in the viewport.
10333
+ * Returns the currently shown incidents — the exact data that was passed to {@link show}.
10334
+ *
10335
+ * Reads the module's client-side cache (`shownFeatures`), mirroring the other GeoJSON
10336
+ * modules (`PlacesModule`, `TrafficAreaAnalyticsModule`, `GeometriesModule`). It does
10337
+ * **not** hit-test the viewport: the proxy already scopes and de-duplicates the
10338
+ * `allEventFeatures` it dispatches to click handlers, so no caller needs viewport-level
10339
+ * de-duplication here.
10265
10340
  */
10266
10341
  getShown(): {
10267
- incidents: TrafficIncident[];
10342
+ incidents: TrafficIncidentDetails;
10268
10343
  };
10269
- /**
10270
- * Reduce a hit-test result (typically the `features` argument in a click handler) to the
10271
- * distinct incidents drawn at that point. Each incident renders across multiple layers
10272
- * (outline + inner + symbol), so `queryRenderedFeatures` returns several entries per
10273
- * incident — this de-duplicates by feature id.
10274
- */
10275
- distinctIncidents(features: readonly MapGeoJSONFeature[]): TrafficIncident[];
10276
10344
  get events(): CombinedEvents<TrafficIncident, TrafficIncidentOverlayConfig, TrafficIncidentDetails>;
10277
10345
  /**
10278
10346
  * Mark a subset of currently-rendered incidents as "focused" via MapLibre
@@ -10285,7 +10353,6 @@ export declare class TrafficIncidentOverlayModule extends AbstractMapModule<Sour
10285
10353
  */
10286
10354
  setFocus(ids: readonly string[] | null): void;
10287
10355
  private clearFeatureState;
10288
- private findSourceFeature;
10289
10356
  }
10290
10357
 
10291
10358
  /**
@@ -10818,7 +10885,7 @@ export declare const UNKNOWN_DELAY_DASH_COLOR = "rgba(190, 39, 27, 1)";
10818
10885
  *
10819
10886
  * @param topFeature - The primary target feature for the event, positioned on top of any overlapping features
10820
10887
  * @param lngLat - The geographic coordinates where the event occurred
10821
- * @param allEventFeatures - All features matching the event coordinates across all map modules, as raw MapLibre GeoJSON features. The first feature corresponds to `topFeature`
10888
+ * @param allEventFeatures - The features at the event coordinates, scoped to the module whose handler fired and de-duplicated (a feature drawn across multiple layers or tiles appears once). Entries from GeoJSON-backed modules (places, routes, geometries) are the original typed `Feature` you passed to `show()`, with un-stringified properties (nested objects, Dates, arrays); entries from vector-tile modules (POIs, traffic) are the underlying `MapGeoJSONFeature` (which extends `Feature`). The first entry is the same feature as `topFeature` — though for modules with a mapping callback, `topFeature` is the mapped shape while this entry stays raw. To inspect **every** feature at the point across all modules — including the base map, with `.source`/`.layer` intact — query MapLibre directly (note `lngLat` is geographic, so project it to a pixel first): `const p = map.mapLibreMap.project(lngLat); const all = map.mapLibreMap.queryRenderedFeatures([[p.x - 5, p.y + 5], [p.x + 5, p.y - 5]]);`
10822
10889
  * @param sourceWithLayers - The source and layer configuration to which the `topFeature` belongs
10823
10890
  *
10824
10891
  * @example
@@ -10853,7 +10920,7 @@ export declare const UNKNOWN_DELAY_DASH_COLOR = "rgba(190, 39, 27, 1)";
10853
10920
  *
10854
10921
  * @group User Interaction Events
10855
10922
  */
10856
- export declare type UserEventHandler<T> = (topFeature: T, lngLat: LngLat, allEventFeatures: MapGeoJSONFeature[], sourceWithLayers: SourceWithLayers) => void;
10923
+ export declare type UserEventHandler<T> = (topFeature: T, lngLat: LngLat, allEventFeatures: T[], sourceWithLayers: SourceWithLayers) => void;
10857
10924
 
10858
10925
  /**
10859
10926
  * Event handling interface for map features.
@@ -10989,14 +11056,20 @@ export declare class UserEvents<T = MapGeoJSONFeature> {
10989
11056
  * @param type The type of event to listen for (click, contextmenu, hover, long-hover)
10990
11057
  * @param handler Callback function invoked when the event occurs
10991
11058
  *
11059
+ * @returns An unsubscribe function that removes the handler registered by this call.
11060
+ *
10992
11061
  * @remarks
10993
11062
  * **Handler Parameters:**
10994
11063
  * - `feature`: The primary feature that triggered the event
10995
11064
  * - `lngLat`: Geographic coordinates [longitude, latitude] of the event
10996
- * - `features`: Array of all features at the event location (for overlapping features)
11065
+ * - `features`: The features from this module at the event location, de-duplicated (for
11066
+ * overlapping features within the module). To inspect features across all modules, query
11067
+ * `map.mapLibreMap.queryRenderedFeatures(...)` directly — see {@link UserEventHandler}.
10997
11068
  *
10998
11069
  * **Behavior:**
10999
- * - Only one handler per event type (calling `on()` again replaces the previous handler)
11070
+ * - Multiple handlers per event type are supported — each `on()` adds a handler (it does
11071
+ * **not** replace existing ones) and all of them fire. To remove one, call the unsubscribe
11072
+ * this returns; to clear them all, use `off(type)`.
11000
11073
  * - Handlers are preserved across map style changes
11001
11074
  * - Cursor automatically changes to pointer on hover
11002
11075
  * - Events respect module visibility (hidden features don't trigger events)
@@ -11064,7 +11137,9 @@ export declare class UserEvents<T = MapGeoJSONFeature> {
11064
11137
  *
11065
11138
  * @remarks
11066
11139
  * **Cleanup Behavior:**
11067
- * - Removes only the specified event type (other types remain active)
11140
+ * - Removes **all** handlers for the specified event type — to remove a single handler, call
11141
+ * the unsubscribe function returned by {@link on}
11142
+ * - Other event types remain active
11068
11143
  * - Resets cursor behavior for this module
11069
11144
  * - Safe to call multiple times (no error if no handler exists)
11070
11145
  * - Does not affect other modules' event handlers