@feltmaps/js-sdk 1.11.0 → 1.11.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.
Files changed (2) hide show
  1. package/llms-full.txt +1942 -0
  2. package/package.json +7 -4
package/llms-full.txt ADDED
@@ -0,0 +1,1942 @@
1
+ # Felt SDK API Reference
2
+
3
+ Generated from the SDK's TypeScript definitions. Sections follow the SDK's module structure; every type and every `FeltController` member appears exactly once. `felt` is the `FeltController` returned by `Felt.embed(...)` or `Felt.connect(...)`.
4
+
5
+ Methods on `felt`, by section:
6
+
7
+ - Layers: getLayer, getLayers, setLayerVisibility, setLayerStyle, setLayerLegendVisibility, createLayersFromGeoJson, updateLayer, deleteLayer, duplicateLayer, getLayerGroup, getLayerGroups, setLayerGroupVisibility, setLayerGroupLegendVisibility, getLegendItem, getLegendItems, setLegendItemVisibility, getLayerFilters, setLayerFilters, getLayerBoundaries, setLayerBoundary, getRenderedFeatures, getFeature, getFeatures, getGeoJsonFeature, getCategoryData, getHistogramData, getAggregates, getPrecomputedAggregates, getRasterAggregates, getRasterHistogramData, getRasterCategoryData, getRasterProfile, getLayerSchema; events: onLayerChange, onLayerGroupChange, onLegendItemChange, onLayerFiltersChange, onLayerBoundariesChange
8
+ - Elements: getElement, getElementGeometry, getElements, getElementGroup, getElementGroups, setElementGroupVisibility, createElement, updateElement, deleteElement; events: onElementCreate, onElementCreateEnd, onElementChange, onElementDelete, onElementGroupChange
9
+ - Selection: getSelection, selectFeature, clearSelection; events: onSelectionChange
10
+ - Interactions: events: onPointerClick, onPointerMove
11
+ - Basemaps: getCurrentBasemap, getBasemaps, chooseBasemap, addCustomBasemap, removeBasemap; events: onBasemapChange
12
+ - Tools: setTool, getTool, setToolSettings, getToolSettings; events: onToolChange, onToolSettingsChange
13
+ - UI: createActionTrigger, updateActionTrigger, deleteActionTrigger, createFeatureAction, updateFeatureAction, deleteFeatureAction, createPanelId, createOrUpdatePanel, deletePanel, createPanelElements, updatePanelElements, deletePanelElements, updateUiControls, setOnMapInteractionsUi, showLayerDataTable, hideLayerDataTable
14
+ - Viewport: getViewport, setViewport, getViewportConstraints, setViewportConstraints, fitViewportToBounds; events: onViewportMove, onViewportMoveEnd, onMapIdle
15
+ - Map Details: getMapDetails
16
+
17
+ ## Entry Point
18
+
19
+ ```typescript
20
+ type FeltEmbedOptions = {
21
+ uiControls?: UiControlsOptions;
22
+ initialViewport?: ViewportCenterZoom;
23
+ // A short-lived (15 minutes) authentication token to use for showing embeds that are configured to be private.
24
+ token?: string;
25
+ };
26
+
27
+ // The Felt SDK is a library for embedding Felt maps into your website.
28
+ const Felt: {
29
+ embed: (container: HTMLElement, mapId: string, options?: FeltEmbedOptions) => Promise<FeltController>;
30
+ connect: (feltWindow: Pick<Window, "postMessage">) => Promise<FeltController>;
31
+ };
32
+ ```
33
+
34
+ ### Properties
35
+
36
+ ```typescript
37
+ // The iframe element containing the Felt map, if it is an embedded map.
38
+ felt.iframe: HTMLIFrameElement | null;
39
+ ```
40
+
41
+ ## Core Types
42
+
43
+ ```typescript
44
+ // A tuple representing a longitude and latitude coordinate.
45
+ type LngLatTuple = [longitude: number, latitude: number];
46
+
47
+ // The zoom level of the map.
48
+ type FeltZoom = number;
49
+
50
+ // The edges of the map in the form of a bounding box.
51
+ type FeltBoundary = [number, number, number, number];
52
+
53
+ // Specifies the direction to sort data in
54
+ type SortDirection = "asc" | "desc";
55
+
56
+ // Represents a point in world coordinates.
57
+ type LatLng = { latitude: number; longitude: number };
58
+
59
+ // A GeoJSON feature object, compliant with: https://datatracker.ietf.org/doc/html/rfc7946#section-3.2
60
+ type GeoJsonFeature = {
61
+ type: "Feature";
62
+ geometry: GeoJsonGeometry;
63
+ properties: GeoJsonProperties;
64
+ // The bounding box of the feature in [west, south, east, north] order.
65
+ bbox?: FeltBoundary;
66
+ // A value that uniquely identifies this feature in a https://tools.ietf.org/html/rfc7946#section-3.2.
67
+ id?: string | number;
68
+ };
69
+
70
+ type PointGeometry = { type: "Point"; coordinates: LngLatTuple };
71
+
72
+ // A GeoJSON multi-point geometry.
73
+ // You shouldn't expect this to come from Felt - it is here for completeness of the GeoJSON spec.
74
+ type MultiPointGeometry = { type: "MultiPoint"; coordinates: LngLatTuple[] };
75
+
76
+ type PolygonGeometry = { type: "Polygon"; coordinates: LngLatTuple[][] };
77
+
78
+ // A GeoJSON multi-polygon geometry.
79
+ type MultiPolygonGeometry = { type: "MultiPolygon"; coordinates: LngLatTuple[][][] };
80
+
81
+ // A GeoJSON line string geometry.
82
+ type LineStringGeometry = { type: "LineString"; coordinates: LngLatTuple[] };
83
+
84
+ // A GeoJSON multi-line string geometry.
85
+ type MultiLineStringGeometry = { type: "MultiLineString"; coordinates: LngLatTuple[][] };
86
+
87
+ // The parameters for the methods that change the visibility of entities.
88
+ type SetVisibilityRequest = {
89
+ // The ids of the entities you want to change the visibility of.
90
+ show?: string[];
91
+ hide?: string[];
92
+ };
93
+
94
+ // Configuration for sorting data by a specific attribute
95
+ type SortConfig = { direction: "asc" | "desc"; attribute: string };
96
+
97
+ // A GeoJSON properties object.
98
+ type GeoJsonProperties = Record<string, unknown>;
99
+
100
+ // A GeoJSON geometry of any type
101
+ type GeoJsonGeometry = PointGeometry | PolygonGeometry | LineStringGeometry | MultiLineStringGeometry | MultiPolygonGeometry | MultiPointGeometry;
102
+ ```
103
+
104
+ ## Layers
105
+
106
+ ```typescript
107
+ // This describes the processing status of a layer.
108
+ type LayerProcessingStatus = "processing" | "completed" | "failed" | "incomplete";
109
+
110
+ // Describes how the layer is displayed in the legend.
111
+ type LegendDisplay = "default" | "nameOnly";
112
+
113
+ // A LayerFeature is a single geographical item in a layer.
114
+ type LayerFeature = {
115
+ id: string | number; // The identifier of the feature, unique within the layer.
116
+ // If the id is deterministic, it means that the id can be used to reference the feature in the layer
117
+ // and therefore in all the SDK feature-related methods.
118
+ // When the id is not deterministic, the feature cannot be referenced on SDK methods like
119
+ // FeltController.getFeature or SelectionController.selectFeature.
120
+ // For layers created and processed on Felt servers, the feature IDs are deterministic because Felt
121
+ // ensures every feature is correctly identified in vector tiles. This cannot be guaranteed for layers
122
+ // created using a GeoJSON source on the SDK (see LayersController.createLayersFromGeoJson) where the
123
+ // ID will only be deterministic if GeoJSON features have an `id` property.
124
+ isDeterministicId: boolean;
125
+ layerId: string;
126
+ // Because LayerFeatures can be read from tiled features, it's possible that this `geometryType` won't
127
+ // match the `geometry.type` of the GeoJsonFeature returned by FeltController.getGeoJsonFeature.
128
+ // For example, this may return `LineString` but the full feature is a `MultiLineString`, or, similarly
129
+ // `Polygon` here may be a `MultiPolygon` in the full feature.
130
+ // As a result, you should treat this property as being indicative only.
131
+ geometryType: "Polygon" | "MultiPolygon" | "LineString" | "MultiLineString" | "Point" | "MultiPoint" | string & {};
132
+ // Because LayerFeatures can be read from tiled features and considering that feature geometry can go
133
+ // through multiple tiles, it's possible that this is not the complete bounding box of the feature.
134
+ bbox: FeltBoundary | undefined;
135
+ properties: GeoJsonProperties;
136
+ };
137
+
138
+ // A raster pixel value for a specific layer.
139
+ type RasterValue = {
140
+ value: number;
141
+ layerId: string;
142
+ categoryName: string | null;
143
+ color: { r: number; g: number; b: number; a: number } | null;
144
+ };
145
+
146
+ // The common properties for all layers.
147
+ type LayerCommon = {
148
+ id: string;
149
+ groupId: string | null;
150
+ name: string; // The name of the layer can be displayed in the Legend.
151
+ caption: string | null;
152
+ description: string | null; // The layer description forms part of the layer's metadata.
153
+ visible: boolean;
154
+ shownInLegend: boolean;
155
+ legendDisplay: LegendDisplay;
156
+ style: object;
157
+ status: LayerProcessingStatus;
158
+ // The bounding box of the layer in [west, south, east, north] order
159
+ bounds: FeltBoundary | null;
160
+ };
161
+
162
+ // A raster layer is a layer that contains raster data that can be rendered on the map
163
+ type RasterLayer = LayerCommon & { geometryType: "Raster"; source: RasterLayerSource };
164
+
165
+ // The source of a raster layer's data.
166
+ type RasterLayerSource = {
167
+ imageTileTemplateUrl: string;
168
+ // A URL template for fetching encoded tiles for the raster, or `null` for TileService layers.
169
+ encodedTileTemplateUrl: string | null;
170
+ bands: RasterBand[];
171
+ };
172
+
173
+ // The RasterBand interface describes one band of a raster: how to identify it when asking for statistics.
174
+ type RasterBand = {
175
+ id: string;
176
+ displayName: string; // The name of the band, such as "Red" or "Elevation".
177
+ base: number; // Encoding base value as a floating point number
178
+ interval: number; // Encoding interval as a floating point number
179
+ bandIndex: number;
180
+ };
181
+
182
+ // A vector layer is a layer that contains vector data that can be rendered on the map
183
+ type VectorLayer = LayerCommon & {
184
+ geometryType: "Polygon" | "Point" | "Line";
185
+ source: GeoJsonUrlVectorSource | FeltTiledVectorSource | Omit<GeoJsonDataVectorSource, "data">;
186
+ };
187
+
188
+ // A GeoJSON URL source is a layer that is populated from a GeoJSON file at a remote URL.
189
+ type GeoJsonUrlVectorSource = {
190
+ type: "geoJsonUrl";
191
+ // The remote URL of the GeoJSON file used to populate the layer.
192
+ url: string;
193
+ // The interval in milliseconds between automatic refreshes of the GeoJSON.
194
+ refreshInterval?: number | null;
195
+ };
196
+
197
+ // A GeoJSON data source is a layer that is populated from GeoJSON data, such as from a local file.
198
+ type GeoJsonDataVectorSource = { type: "geoJsonData"; data: object };
199
+
200
+ // A GeoJSON file source is a layer that is populated from a GeoJSON file on your local machine.
201
+ type GeoJsonFileVectorSource = { type: "geoJsonFile"; file: File };
202
+
203
+ // The value you need to pass to LayersController.updateLayer
204
+ type UpdateLayerParams = {
205
+ id: string;
206
+ shownInLegend?: boolean;
207
+ legendDisplay?: LegendDisplay;
208
+ name?: string;
209
+ caption?: string;
210
+ description?: string;
211
+ bounds?: FeltBoundary;
212
+ style?: object;
213
+ source?: GeoJsonUrlVectorSource | GeoJsonDataVectorSource | GeoJsonFileVectorSource;
214
+ };
215
+
216
+ // A data-only layer doesn't have any geometry, but can be used to join with other layers
217
+ type DataOnlyLayer = LayerCommon & { geometryType: null; bounds: null };
218
+
219
+ type LayerGroup = {
220
+ id: string;
221
+ name: string;
222
+ caption: string | null;
223
+ // You can use these ids to get the full layer objects via the `getLayers` method.
224
+ layerIds: string[];
225
+ visible: boolean;
226
+ shownInLegend: boolean;
227
+ // The bounding box of the layer group in [west, south, east, north] order.
228
+ bounds: FeltBoundary | null;
229
+ };
230
+
231
+ // The constraints to apply when getting layers.
232
+ type GetLayersConstraint = { ids?: string[] };
233
+
234
+ // The constraints to apply when getting layer groups.
235
+ type GetLayerGroupsConstraint = { ids?: string[] };
236
+
237
+ // The parameters for the `onLayerChange` listener.
238
+ type LayerChangeCallbackParams = {
239
+ layer: Layer | null; // The new data for the layer or null if the layer was removed.
240
+ };
241
+
242
+ // The parameters for the `onLayerGroupChange` listener.
243
+ type LayerGroupChangeCallbackParams = { layerGroup: LayerGroup | null };
244
+
245
+ // A legend item, which often represents a sub-class of features in a layer in the case of categorical or...
246
+ type LegendItem = LegendItemIdentifier & {
247
+ title: string | string[];
248
+ titleDependsOnZoom: boolean; // Whether the title depends on the zoom level or not.
249
+ visible: boolean;
250
+ };
251
+
252
+ // The identifier for a legend item.
253
+ type LegendItemIdentifier = { id: string; layerId: string };
254
+
255
+ // Constraints for legend items.
256
+ type LegendItemsConstraint = { ids?: LegendItemIdentifier[]; layerIds?: string[] };
257
+
258
+ // The parameters for the `onLegendItemChange` listener.
259
+ type LegendItemChangeCallbackParams = {
260
+ // The new data for the legend item or null if the legend item was removed.
261
+ legendItem: LegendItem | null;
262
+ };
263
+
264
+ // Constraints for the `getRenderedFeatures` method.
265
+ type GetRenderedFeaturesConstraint = {
266
+ areaQuery?: { coordinates: LatLng } | { boundary: FeltBoundary };
267
+ layerIds?: string[];
268
+ };
269
+
270
+ // The schema that describes the structure of the features in a layer.
271
+ // This can be useful to build generic UIs that need to know the structure of the data in a layer, such
272
+ // as a dropdown to choose an attribute.
273
+ type LayerSchema = {
274
+ featureCount: number;
275
+ // Array of attribute schemas describing the properties available on features in this layer.
276
+ attributes: LayerSchemaAttribute[];
277
+ };
278
+
279
+ // The common schema for all attributes.
280
+ type LayerSchemaCommonAttribute = {
281
+ id: string;
282
+ displayName: string;
283
+ // The specific data type of this attribute, providing more detail than the basic type.
284
+ detailedType: string;
285
+ // The number of distinct values present for this attribute across all features.
286
+ distinctCount: number;
287
+ };
288
+
289
+ // The schema for a numeric attribute on a layer.
290
+ type LayerSchemaNumericAttribute = LayerSchemaCommonAttribute & {
291
+ type: "numeric";
292
+ // A small sample of values for this attribute and their frequency.
293
+ sampleValues: { value: number; count: number }[];
294
+ // The minimum value present for this attribute across all features.
295
+ min: number;
296
+ // The maximum value present for this attribute across all features.
297
+ max: number;
298
+ };
299
+
300
+ // The schema for a text attribute on a layer.
301
+ type LayerSchemaTextAttribute = LayerSchemaCommonAttribute & {
302
+ type: "text";
303
+ // A small sample of string values for this attribute and their frequency.
304
+ sampleValues: { value: string; count: number }[];
305
+ };
306
+
307
+ // The schema for a boolean attribute on a layer.
308
+ type LayerSchemaBooleanAttribute = LayerSchemaCommonAttribute & {
309
+ type: "boolean";
310
+ // A representative sample of boolean values for this attribute and their frequency.
311
+ sampleValues: { value: boolean; count: number }[];
312
+ };
313
+
314
+ // The schema for a date attribute on a layer.
315
+ type LayerSchemaDateAttribute = LayerSchemaCommonAttribute & {
316
+ type: "date";
317
+ // The earliest date present for this attribute in truncated ISO8601 format (YYYY-MM-DD).
318
+ min: string;
319
+ // The latest date present for this attribute in truncated ISO8601 format (YYYY-MM-DD).
320
+ max: string;
321
+ // A representative sample of date values for this attribute and their frequency.
322
+ sampleValues: { value: string; count: number }[];
323
+ };
324
+
325
+ // The schema for a datetime attribute on a layer.
326
+ type LayerSchemaDateTimeAttribute = LayerSchemaCommonAttribute & {
327
+ type: "datetime";
328
+ // The earliest datetime present for this attribute in ISO8601 format.
329
+ min: string;
330
+ // The latest datetime present for this attribute in ISO8601 format.
331
+ max: string;
332
+ // A representative sample of datetime values for this attribute and their frequency.
333
+ sampleValues: { value: string; count: number }[];
334
+ };
335
+
336
+ // The parameters for the LayersController.createLayersFromGeoJson method.
337
+ type CreateLayersFromGeoJsonParams = {
338
+ name: string;
339
+ source: GeoJsonUrlVectorSource | GeoJsonDataVectorSource | GeoJsonFileVectorSource;
340
+ bounds?: FeltBoundary;
341
+ caption?: string;
342
+ description?: string;
343
+ geometryStyles?: { Point?: object; Line?: object; Polygon?: object };
344
+ };
345
+
346
+ // A tiled vector source is a layer that is populated from data the has been uploaded to Felt.
347
+ type FeltTiledVectorSource = { type: "felt"; tileTemplateUrl: string };
348
+
349
+ type Layer = RasterLayer | VectorLayer | DataOnlyLayer;
350
+
351
+ // A single attribute from the layer schema.
352
+ // Each feature in a layer has a set of attributes, and these types describe the structure of a single
353
+ // attribute, including things like id, display name, type, and sample values.
354
+ type LayerSchemaAttribute = LayerSchemaNumericAttribute | LayerSchemaTextAttribute | LayerSchemaBooleanAttribute | LayerSchemaDateAttribute | LayerSchemaDateTimeAttribute;
355
+ ```
356
+
357
+ ### Filters
358
+
359
+ ```typescript
360
+ type FilterLogicGate = "and" | "or";
361
+
362
+ type FilterExpression = [string | null, "in" | "ni", (string | number | boolean | null)[] | null] | [string | null, "lt" | "gt" | "le" | "ge" | "eq" | "ne" | "cn" | "nc" | "is" | "isnt", string | number | boolean | null];
363
+
364
+ // A `FilterTernary` is a tree structure for combining expressions with logical operators.
365
+ type FilterTernary = [Filters, FilterLogicGate, Filters];
366
+
367
+ // The filters that are currently set on a layer.
368
+ type LayerFilters = {
369
+ style: Filters;
370
+ // Filters that are set in the layer's components, which are interactive elements in the legend.
371
+ components: Filters;
372
+ // Filters that are set ephemerally by viewers in their own session.
373
+ ephemeral: Filters;
374
+ combined: Filters;
375
+ };
376
+
377
+ // All the different sources for boundaries for a layer, including their combined result.
378
+ type LayerBoundaries = {
379
+ spatialFilters: MultiPolygonGeometry | null;
380
+ // Boundaries that are set ephemerally by viewers in their own session.
381
+ ephemeral: GeometryFilter | null;
382
+ combined: MultiPolygonGeometry | null;
383
+ };
384
+
385
+ // Filters can be used to change which features in a layer are rendered.
386
+ // The possible operators are:
387
+ // - `lt`: Less than
388
+ // - `gt`: Greater than
389
+ // - `le`: Less than or equal to
390
+ // - `ge`: Greater than or equal to
391
+ // - `eq`: Equal to
392
+ // - `ne`: Not equal to
393
+ // - `cn`: Contains
394
+ // - `nc`: Does not contain
395
+ // - `is`: Is
396
+ // - `isnt`: Is not
397
+ // - `in`: In
398
+ // - `ni`: Not in
399
+ // The allowed boolean operators are:
400
+ // - `and`: Logical AND
401
+ // - `or`: Logical OR
402
+ type Filters = FilterTernary | FilterExpression | boolean | null;
403
+
404
+ // The common type for filtering data by a spatial boundary.
405
+ type GeometryFilter = FeltBoundary | PolygonGeometry | MultiPolygonGeometry | LngLatTuple[];
406
+ ```
407
+
408
+ ### Raster
409
+
410
+ ```typescript
411
+ // A statistic that can be calculated for a raster band.
412
+ type RasterAggregationMethod = AggregationMethod | "stddev" | "majority" | "area";
413
+
414
+ // The parameters for calculating statistics for a raster band.
415
+ type GetRasterAggregatesParams<T extends RasterAggregationMethod> = {
416
+ layerId: string;
417
+ // The ID of the band to calculate statistics for, read from the `bands` on a raster layer's source.
418
+ bandId: string;
419
+ aggregation: {
420
+ methods: T[]; // The statistics to calculate for the band.
421
+ // Percentile ranks between 0 and 100 to calculate, such as `[10, 50, 90]`.
422
+ percentiles?: number[];
423
+ };
424
+ boundary?: GeometryFilter; // The spatial boundary for the pixels to include.
425
+ // Filters on band values for the pixels to include, such as `["band:1", "gt", 100]`.
426
+ filters?: Filters;
427
+ };
428
+
429
+ // One percentile from the response to the LayersController.getRasterAggregates method.
430
+ type RasterPercentile = { rank: number; value: number | null };
431
+
432
+ // The response from the LayersController.getRasterAggregates method.
433
+ type GetRasterAggregatesResult<T extends RasterAggregationMethod> = {
434
+ stats: Record<T, number | null>; // The value calculated for each requested statistic.
435
+ percentiles?: RasterPercentile[]; // The requested percentiles, in the order they were requested.
436
+ };
437
+
438
+ // The parameters for requesting a histogram of a raster band's values.
439
+ type GetRasterHistogramParams = {
440
+ layerId: string;
441
+ // The ID of the band to bin, read from the `bands` on a raster layer's source.
442
+ bandId: string;
443
+ // How to divide the band's values into bins, either as a number of equal intervals or as the bin edges...
444
+ steps: number[] | { type: "equal-intervals"; count: number };
445
+ boundary?: GeometryFilter; // The spatial boundary for the pixels to include.
446
+ filters?: Filters; // Filters on band values for the pixels to include.
447
+ };
448
+
449
+ // One bin from the response to the LayersController.getRasterHistogramData method.
450
+ type RasterHistogramBin = { min: number; max: number; value: number };
451
+
452
+ // The response from the LayersController.getRasterHistogramData method.
453
+ type GetRasterHistogramResult = { bins: RasterHistogramBin[] };
454
+
455
+ // The parameters for counting the distinct values of a raster band.
456
+ type GetRasterCategoriesParams = {
457
+ layerId: string;
458
+ // The ID of the band to count values for, read from the `bands` on a raster layer's source.
459
+ bandId: string;
460
+ boundary?: GeometryFilter; // The spatial boundary for the pixels to include.
461
+ filters?: Filters; // Filters on band values for the pixels to include.
462
+ limit?: number;
463
+ };
464
+
465
+ // One category from the response to the LayersController.getRasterCategoryData method.
466
+ type RasterCategory = {
467
+ key: number;
468
+ value: number;
469
+ areaM2?: number; // The ground area of this category's pixels, in square metres.
470
+ };
471
+
472
+ // The response from the LayersController.getRasterCategoryData method.
473
+ type GetRasterCategoriesResult = {
474
+ categories: RasterCategory[]; // The categories, most frequent first.
475
+ total: number; // How many distinct values the band holds within the scope.
476
+ };
477
+
478
+ // The parameters for sampling a raster band along a line.
479
+ type GetRasterProfileParams = {
480
+ layerId: string;
481
+ // The ID of the band to sample, read from the `bands` on a raster layer's source.
482
+ bandId: string;
483
+ boundary: LineStringGeometry | MultiLineStringGeometry; // The line to sample the band along.
484
+ };
485
+
486
+ // One sample from the response to the LayersController.getRasterProfile method.
487
+ type RasterProfileSample = {
488
+ // How far along the line this sample was taken, in ground metres from the line's start.
489
+ distanceM: number;
490
+ // The band's value at this sample, or `null` where the raster holds no data or the line runs outside the raster.
491
+ value: number | null;
492
+ };
493
+
494
+ // The response from the LayersController.getRasterProfile method.
495
+ type GetRasterProfileResult = {
496
+ samples: RasterProfileSample[]; // The samples, ordered from the line's start.
497
+ };
498
+ ```
499
+
500
+ ### Stats
501
+
502
+ ```typescript
503
+ // The method to use for the aggregation.
504
+ type AggregationMethod = "min" | "max" | "avg" | "sum" | "median";
505
+
506
+ // The method to use for the precomputed aggregation.
507
+ type PrecomputedAggregationMethod = "min" | "max" | "avg" | "sum" | "count";
508
+
509
+ // The type of grid to use for precomputed aggregate values.
510
+ type GridType = "h3";
511
+
512
+ // Defines how to aggregate a value across features in a layer.
513
+ type AggregationConfig = { attribute: string; method: AggregationMethod };
514
+
515
+ // Defines how to aggregate a value across features in a layer with multiple aggregations returned at once.
516
+ type MultiAggregationConfig<T extends AggregationMethod | "count"> = {
517
+ // The operations to use on the values from the features in the layer
518
+ methods: T[];
519
+ // The attribute ID to use for the aggregation when aggregations other than "count" are used.
520
+ attribute?: string;
521
+ };
522
+
523
+ // Configuration for filtering and aggregating values across features.
524
+ type ValueConfiguration = {
525
+ boundary?: GeometryFilter; // The spatial boundary for what to count or aggregate.
526
+ // Attribute filters to determine what gets counted or aggregated.
527
+ filters?: Filters;
528
+ // Specifies how to aggregate values within each category or bin.
529
+ aggregation?: AggregationConfig;
530
+ };
531
+
532
+ // The parameters for getting categories from a layer, passed to the LayersController.getCategoryData method.
533
+ type GetLayerCategoriesParams = {
534
+ layerId: string;
535
+ attribute: string;
536
+ limit?: number;
537
+ // Attribute filters for the features to include when calculating the categories.
538
+ filters?: Filters;
539
+ // The spatial boundary for the features to include when calculating the categories.
540
+ boundary?: GeometryFilter;
541
+ // Configuration for filtering and aggregating values while preserving the full set of categories in the results.
542
+ values?: ValueConfiguration;
543
+ };
544
+
545
+ // A single category from the response from the LayersController.getCategoryData method.
546
+ type GetLayerCategoriesGroup = {
547
+ key: string | number | boolean; // The category for which the value was calculated.
548
+ // The value calculated for the category, whether a count, sum, average, etc.
549
+ value: number | null;
550
+ };
551
+
552
+ // The params used to request a histogram of values from a layer.
553
+ type GetLayerHistogramParams = {
554
+ layerId: string;
555
+ attribute: string;
556
+ steps: number[] | { type: "equal-intervals"; count: number } | {
557
+ type: "time-interval";
558
+ interval: "hour" | "day" | "week" | "month" | "year";
559
+ };
560
+ // Configuration for filtering and aggregating values while preserving the full set of bin ranges in the results.
561
+ values?: ValueConfiguration;
562
+ // Attribute filters for the features to include when calculating the histogram bins.
563
+ filters?: Filters;
564
+ // The spatial boundary for the features to include when calculating the histogram bins.
565
+ boundary?: GeometryFilter;
566
+ };
567
+
568
+ // One bin from the response from the LayersController.getHistogramData method.
569
+ type GetLayerHistogramBin = { min: number; max: number; value: number };
570
+
571
+ // The parameters for calculating a single aggregate value for a layer.
572
+ type GetLayerCalculationParams<T extends AggregationMethod | "count"> = {
573
+ layerId: string;
574
+ // Specifies how to aggregate values within each category or bin.
575
+ aggregation: MultiAggregationConfig<T>;
576
+ // Attribute filters for the features to include when calculating the aggregate value.
577
+ filters?: Filters;
578
+ // The spatial boundary for the features to include when calculating the aggregate value.
579
+ boundary?: GeometryFilter;
580
+ };
581
+
582
+ // The grid configuration for a count-based precomputed aggregate value.
583
+ type CountGridConfig = {
584
+ resolution: number;
585
+ type: "h3";
586
+ // The method to use for the precomputed calculation, which in this case is always "count".
587
+ method: "count";
588
+ };
589
+
590
+ // The grid configuration for an aggregated precomputed aggregate value.
591
+ type AggregatedGridConfig = {
592
+ resolution: number;
593
+ attribute: string;
594
+ type: "h3";
595
+ method: "min" | "max" | "avg" | "sum";
596
+ };
597
+
598
+ // The parameters for calculating a single aggregate value for a layer.
599
+ type GetLayerPrecomputedCalculationParams = {
600
+ layerId: string;
601
+ gridConfig: GridConfig;
602
+ // Attribute filters for the features to include when calculating the aggregate value.
603
+ filters?: Filters;
604
+ // The spatial boundary for the features to include when calculating the aggregate value.
605
+ boundary?: GeometryFilter;
606
+ };
607
+
608
+ // Describes the type of grid to use for precomputed aggregate values.
609
+ type GridConfig = CountGridConfig | AggregatedGridConfig;
610
+ ```
611
+
612
+ ### Methods
613
+
614
+ ```typescript
615
+ // Get a single layer from the map by its id.
616
+ felt.getLayer(id: string): Promise<Layer | null>;
617
+
618
+ // Gets layers from the map, according to the constraints supplied.
619
+ // The layers in the map, ordered by the order specified in Felt. This is not necessarily the order
620
+ // that they are drawn in, as Felt draws points above lines and lines above polygons, for instance.
621
+ felt.getLayers(constraint?: GetLayersConstraint): Promise<(Layer | null)[]>;
622
+
623
+ // Hide or show layers with the given ids.
624
+ felt.setLayerVisibility(visibility: SetVisibilityRequest): Promise<void>;
625
+
626
+ // Set the style for a layer using FSL, the Felt Style Language.
627
+ felt.setLayerStyle(params: { id: string; style: object }): Promise<void>;
628
+
629
+ // Hide or show layers with the given ids from the legend.
630
+ felt.setLayerLegendVisibility(params: SetVisibilityRequest): Promise<void>;
631
+
632
+ // Adds layers to the map from file or URL sources.
633
+ // This allows you to add temporary layers to the map that don't depend on any processing by Felt. This
634
+ // is useful for viewing data from external sources or remote files.
635
+ felt.createLayersFromGeoJson(params: CreateLayersFromGeoJsonParams): Promise<{
636
+ // The layer group that was created containing the created layers.
637
+ layerGroup: LayerGroup;
638
+ layers: Layer[]; // The layers that were created from the source.
639
+ } | null>;
640
+
641
+ // Update a layer by passing a subset of the layer's properties.
642
+ felt.updateLayer(params: UpdateLayerParams): Promise<Layer>;
643
+
644
+ // Delete a layer from the map by its id.
645
+ // This only works for layers created via the SDK `createLayersFromGeoJson` method, not layers added
646
+ // via the Felt UI.
647
+ felt.deleteLayer(id: string): Promise<void>;
648
+
649
+ // Duplicate a layer from the map by its id.
650
+ // This will create an ephemeral copy of the layer, just for the duration of the session. The
651
+ // duplicated layer will not be persisted to the map.
652
+ felt.duplicateLayer(id: string): Promise<Layer>;
653
+
654
+ // Get a layer group from the map by its id.
655
+ felt.getLayerGroup(id: string): Promise<LayerGroup | null>;
656
+
657
+ // Gets layer groups from the map, according to the constraints supplied.
658
+ felt.getLayerGroups(constraint?: GetLayerGroupsConstraint): Promise<(LayerGroup | null)[]>;
659
+
660
+ // Hide or show layer groups with the given ids.
661
+ felt.setLayerGroupVisibility(visibility: SetVisibilityRequest): Promise<void>;
662
+
663
+ // Hide or show layer groups with the given ids from the legend.
664
+ felt.setLayerGroupLegendVisibility(params: SetVisibilityRequest): Promise<void>;
665
+
666
+ // Allows you to get the state of a single legend item.
667
+ felt.getLegendItem(id: LegendItemIdentifier): Promise<LegendItem | null>;
668
+
669
+ // Allows you to obtain the state of several legend items.
670
+ felt.getLegendItems(constraint?: LegendItemsConstraint): Promise<(LegendItem | null)[]>;
671
+
672
+ // Hide or show legend items with the given identifiers.
673
+ felt.setLegendItemVisibility(visibility: { show?: LegendItemIdentifier[]; hide?: LegendItemIdentifier[] }): Promise<void>;
674
+
675
+ // Get the filters for a layer.
676
+ // The return type gives you the filters split up into the various sources that make up the overall
677
+ // filters for a layer.
678
+ felt.getLayerFilters(layerId: string): Promise<LayerFilters | null>;
679
+
680
+ // Sets the **ephemeral** filters for a layer.
681
+ felt.setLayerFilters(params: {
682
+ layerId: string;
683
+ filters: Filters;
684
+ // A note to display on the layer legend when this filter is applied.
685
+ note?: string;
686
+ }): Promise<void>;
687
+
688
+ // Get the spatial boundaries that are filtering a layer.
689
+ // The return type gives you the boundaries split up into the various sources that make up the overall
690
+ // boundary for a layer.
691
+ // The combined boundary is the intersection of the other sources of boundaries.
692
+ felt.getLayerBoundaries(layerId: string): Promise<LayerBoundaries | null>;
693
+
694
+ // Set the `ephemeral` boundary for one or more layers.
695
+ felt.setLayerBoundary(params: { layerIds: string[]; boundary: GeometryFilter | null }): Promise<void>;
696
+
697
+ // Get the features that are currently **rendered** on the map in the viewport.
698
+ felt.getRenderedFeatures(params?: GetRenderedFeaturesConstraint): Promise<LayerFeature[]>;
699
+
700
+ // Get a feature from the map by its ID and layer ID.
701
+ felt.getFeature(params: { id: string | number; layerId: string }): Promise<LayerFeature | null>;
702
+
703
+ // Get a list of layer features.
704
+ // This list is paginated in sets of 20 features for each page. In order to paginate between pages, the
705
+ // response includes `previousPage` and `nextPage` that are tokens that should be sent in the
706
+ // `pagination` params for requesting sibling pages.
707
+ // Text search is case-insensitive and looks for matches across all feature properties.
708
+ felt.getFeatures(params: {
709
+ layerId: string;
710
+ filters?: Filters;
711
+ sorting?: SortConfig;
712
+ boundary?: GeometryFilter;
713
+ search?: string;
714
+ pagination?: string | null;
715
+ pageSize?: number; // The number of features to return per page.
716
+ select?: string[]; // The attributes to select from the features.
717
+ }): Promise<{
718
+ features: LayerFeature[]; // The list of features returned from the query.
719
+ count: number; // The total number of features that match the query.
720
+ previousPage: string | null; // The pagination token to get the previous page of features.
721
+ nextPage: string | null; // The pagination token to get the next page of features.
722
+ }>;
723
+
724
+ // Get a feature in GeoJSON format from the map by its ID and layer ID.
725
+ felt.getGeoJsonFeature(params: { id: string | number; layerId: string }): Promise<GeoJsonFeature | null>;
726
+
727
+ // Gets values from a layer grouped by a given attribute.
728
+ // Groups features in your layer by unique values in the specified attribute and calculates a value for
729
+ // each group. By default, this value is the count of features in each group.
730
+ // You can apply filters in two ways:
731
+ // 1. At the top level (using `boundary` and `filters`), which affects both what categories are
732
+ // included and how values are calculated
733
+ // 2. In the `values` configuration, which only affects the values but keeps all categories
734
+ // This two-level filtering is particularly useful when you want to compare subsets of data while
735
+ // maintaining consistent categories. For example, you might want to show the distribution of all
736
+ // building types in a city, but only count buildings built after 2000 in each category.
737
+ felt.getCategoryData(params: GetLayerCategoriesParams): Promise<GetLayerCategoriesGroup[]>;
738
+
739
+ // Gets a histogram of values from a layer for a given attribute.
740
+ // Creates bins (ranges) for numeric data and counts how many features fall into each bin, or returns
741
+ // aggregated values for each bin.
742
+ // You can control how the bins are created using the `steps` parameter, choosing from several methods
743
+ // like equal intervals, quantiles, or natural breaks (Jenks), or passing in the step values directly
744
+ // if you know how you want to bin the data.
745
+ // Like getCategoryData, you can apply filters in two ways:
746
+ // 1. At the top level (using `boundary` and `filters`), which affects both how the bins are calculated
747
+ // and what features are counted in each bin
748
+ // 2. In the `values` configuration, which only affects what gets counted but keeps the bin ranges the
749
+ // same
750
+ // This is particularly useful when you want to compare distributions while keeping consistent bin
751
+ // ranges. For example, you might want to compare the distribution of building heights in different
752
+ // years while using the same height ranges.
753
+ felt.getHistogramData(params: GetLayerHistogramParams): Promise<GetLayerHistogramBin[]>;
754
+
755
+ // Calculates a single aggregate value for a layer based on the provided configuration.
756
+ // Performs statistical calculations on your data, like counting features or computing averages, sums,
757
+ // etc. You can focus your calculation on specific areas or subsets of your data using boundaries and
758
+ // filters.
759
+ // When you request an aggregation other than count, you must specify an attribute to aggregate on.
760
+ felt.getAggregates<T extends AggregationMethod | "count">(params: GetLayerCalculationParams<T>): Promise<Record<T, number | null>>;
761
+
762
+ // Calculates aggregates for spatial cells of a layer.
763
+ // Performs statistical calculations on spatial cells of a layer, returning min, max, avg, sum, and
764
+ // count. You can focus your calculation on specific areas or subsets of your data using boundaries and
765
+ // filters. When using the count method, an attribute is not required.
766
+ felt.getPrecomputedAggregates(params: GetLayerPrecomputedCalculationParams): Promise<{
767
+ avg: number | null;
768
+ max: number | null;
769
+ min: number | null;
770
+ sum: number | null;
771
+ count: number | null;
772
+ }>;
773
+
774
+ // Calculates statistics for a raster band.
775
+ // Summarizes the pixel values of one band of a raster layer. Omit the boundary to summarize the whole
776
+ // raster, or pass a bounding box or polygon to summarize part of it. Filters restrict the summary to
777
+ // pixels whose band values match a condition.
778
+ felt.getRasterAggregates<T extends RasterAggregationMethod>(params: GetRasterAggregatesParams<T>): Promise<GetRasterAggregatesResult<T>>;
779
+
780
+ // Calculates a histogram of a raster band's values.
781
+ // Divides a band's values into bins and counts the pixels falling into each one. You can pass a number
782
+ // of equal intervals, or the bin edges themselves when you already know how you want the values
783
+ // divided.
784
+ felt.getRasterHistogramData(params: GetRasterHistogramParams): Promise<GetRasterHistogramResult>;
785
+
786
+ // Counts the pixels holding each distinct value of a raster band.
787
+ // This suits a band whose values are class codes, such as a land cover raster. Each category reports
788
+ // how many pixels hold the value and how much ground they cover. A band whose values are not whole
789
+ // numbers cannot be counted this way, and throws.
790
+ felt.getRasterCategoryData(params: GetRasterCategoriesParams): Promise<GetRasterCategoriesResult>;
791
+
792
+ // Samples a raster band's values along a line.
793
+ // Returns the values themselves rather than a summary of them, each paired with how far along the line
794
+ // it was taken. This is what an elevation profile along a route is drawn from.
795
+ felt.getRasterProfile(params: GetRasterProfileParams): Promise<GetRasterProfileResult>;
796
+
797
+ // Get the schema for a layer.
798
+ // The schema describes the structure of the data in a layer, including the attributes that are
799
+ // available on the features in the layer.
800
+ // This can be useful to build generic UIs that need to know the structure of the data in a layer, such
801
+ // as a dropdown to choose an attribute.
802
+ felt.getLayerSchema(layerId: string): Promise<LayerSchema>;
803
+ ```
804
+
805
+ ### Events
806
+
807
+ ```typescript
808
+ // Adds a listener for when a layer changes.
809
+ felt.onLayerChange(args: {
810
+ options: {
811
+ id: string; // The id of the layer to listen for changes to.
812
+ };
813
+ handler: (change: LayerChangeCallbackParams) => void;
814
+ }): VoidFunction;
815
+
816
+ // Adds a listener for when a layer group changes.
817
+ felt.onLayerGroupChange(args: {
818
+ options: { id: string };
819
+ handler: (change: LayerGroupChangeCallbackParams) => void;
820
+ }): VoidFunction;
821
+
822
+ // Adds a listener for when a legend item changes.
823
+ felt.onLegendItemChange(args: {
824
+ options: LegendItemIdentifier;
825
+ handler: (change: LegendItemChangeCallbackParams) => void;
826
+ }): VoidFunction;
827
+
828
+ // Adds a listener for when a layer's filters change.
829
+ // This event fires whenever any type of filter changes on the layer, including ephemeral filters set
830
+ // via the SDK, style-based filters, or filters set through the Felt UI via Components.
831
+ felt.onLayerFiltersChange(params: { options: { layerId: string }; handler: (change: LayerFilters) => void }): VoidFunction;
832
+
833
+ // Adds a listener for when a layer's spatial boundaries change.
834
+ // This event fires whenever any type of spatial boundary changes on the layer, including ephemeral
835
+ // boundaries set via the SDK or boundaries set through the Felt UI via Spatial filter components.
836
+ felt.onLayerBoundariesChange(params: {
837
+ options: {
838
+ layerId: string; // The id of the layer to listen for boundary changes on.
839
+ };
840
+ handler: (boundaries: LayerBoundaries | null) => void; // A function that is called when the boundaries change.
841
+ }): VoidFunction;
842
+ ```
843
+
844
+ ## Elements
845
+
846
+ ```typescript
847
+ // Shared by every ElementCreate variant. Documentation shorthand, not an exported type.
848
+ type ElementCreateCommon = {
849
+ groupId?: string | null;
850
+ // Text describing the element, which is shown in an element's popup when it is selected.
851
+ description?: string | null;
852
+ // A set of key-value pairs that can be used to store arbitrary data about the element.
853
+ attributes?: Record<string, unknown>;
854
+ interaction?: "default" | "locked"; // default: "default"
855
+ };
856
+
857
+ type PlaceElementCreate = ElementCreateCommon & {
858
+ type: "Place";
859
+ coordinates: LngLatTuple;
860
+ color?: string; // The color of the element in some CSS-like format. (default: "#C93535")
861
+ name?: string | null;
862
+ imageUrl?: string | null; // The URL of an image that has been added to the element.
863
+ symbol?: string;
864
+ frame?: PlaceFrame; // The frame that is rendered around the Place's symbol.
865
+ hideLabel?: boolean; // Whether the element's label is hidden on the map. (default: false)
866
+ };
867
+
868
+ type PlaceElementRead = {
869
+ id: string;
870
+ interaction?: "default" | "locked"; // default: "default"
871
+ } & Required<Omit<PlaceElementCreate, "interaction">>;
872
+
873
+ type PlaceElementUpdate = { id: string; coordinates?: LngLatTuple } & Omit<PlaceElementCreate, "coordinates">;
874
+
875
+ type PathElementCreate = ElementCreateCommon & {
876
+ type: "Path";
877
+ coordinates: LngLatTuple[][];
878
+ color?: string; // The color of the element in some CSS-like format. (default: "#C93535")
879
+ name?: string | null;
880
+ imageUrl?: string | null; // The URL of an image that has been added to the element.
881
+ strokeOpacity?: number; // default: 1
882
+ strokeWidth?: number; // default: 2
883
+ strokeStyle?: "solid" | "dashed" | "dotted"; // default: "solid"
884
+ // Whether a distance marker is shown at the midpoint of the path.
885
+ distanceMarker?: boolean; // default: false
886
+ // Whether this represents a route, and if so, what mode of transport is used.
887
+ routingMode?: "driving" | "cycling" | "walking" | "flying" | null; // default: null
888
+ endCaps?: boolean; // Whether or not to show Start and End caps on the path. (default: false)
889
+ };
890
+
891
+ type PathElementRead = {
892
+ id: string;
893
+ interaction?: "default" | "locked"; // default: "default"
894
+ } & Required<Omit<PathElementCreate, "interaction" | "coordinates">>;
895
+
896
+ type PathElementUpdate = { id: string; coordinates?: LngLatTuple[][] } & Omit<PathElementCreate, "coordinates">;
897
+
898
+ type PolygonElementCreate = ElementCreateCommon & {
899
+ type: "Polygon";
900
+ coordinates: LngLatTuple[][];
901
+ color?: string; // The color of the element in some CSS-like format. (default: "#C93535")
902
+ name?: string | null;
903
+ imageUrl?: string | null; // The URL of an image that has been added to the element.
904
+ strokeOpacity?: number; // default: 1
905
+ strokeWidth?: number; // default: 2
906
+ strokeStyle?: "solid" | "dashed" | "dotted"; // default: "solid"
907
+ fillOpacity?: number; // default: 0.25
908
+ areaMarker?: boolean; // default: false
909
+ };
910
+
911
+ type PolygonElementRead = {
912
+ id: string;
913
+ interaction?: "default" | "locked"; // default: "default"
914
+ } & Required<Omit<PolygonElementCreate, "interaction" | "coordinates">>;
915
+
916
+ type PolygonElementUpdate = { id: string; coordinates?: LngLatTuple[][] } & Omit<PolygonElementCreate, "coordinates">;
917
+
918
+ type CircleElementCreate = ElementCreateCommon & {
919
+ type: "Circle";
920
+ radius: number;
921
+ center: LngLatTuple;
922
+ color?: string; // The color of the element in some CSS-like format. (default: "#C93535")
923
+ name?: string | null;
924
+ imageUrl?: string | null; // The URL of an image that has been added to the element.
925
+ strokeOpacity?: number; // default: 1
926
+ strokeWidth?: number; // default: 2
927
+ strokeStyle?: "solid" | "dashed" | "dotted"; // default: "solid"
928
+ // Whether to show a marker on the circle that indicates the radius
929
+ radiusMarker?: boolean; // default: false
930
+ // The angle at which the control point for setting the radius is displayed, in degrees.
931
+ radiusDisplayAngle?: number; // default: 90
932
+ radiusDisplayUnit?: "meter" | "kilometer" | "foot" | "mile" | null; // default: null
933
+ fillOpacity?: number; // default: 0.25
934
+ };
935
+
936
+ type CircleElementRead = {
937
+ id: string;
938
+ interaction?: "default" | "locked"; // default: "default"
939
+ } & Required<Omit<CircleElementCreate, "interaction">>;
940
+
941
+ type CircleElementUpdate = { id: string; type: "Circle" } & Partial<Omit<CircleElementCreate, "type">>;
942
+
943
+ type MarkerElementCreate = ElementCreateCommon & {
944
+ type: "Marker";
945
+ coordinates: LngLatTuple[][];
946
+ color?: string; // The color of the element in some CSS-like format. (default: "#C93535")
947
+ name?: string | null;
948
+ opacity?: number; // default: 1
949
+ // The size of the marker, used in conjunction with the `zoom` to determine the actual size of the marker.
950
+ size?: number; // default: 10
951
+ zoom?: number; // The zoom level at which the marker was created.
952
+ };
953
+
954
+ type MarkerElementRead = {
955
+ id: string;
956
+ interaction?: "default" | "locked"; // default: "default"
957
+ } & Required<Omit<MarkerElementCreate, "interaction" | "coordinates">>;
958
+
959
+ type MarkerElementUpdate = { id: string; coordinates?: LngLatTuple[][] } & Omit<MarkerElementCreate, "coordinates">;
960
+
961
+ type HighlighterElementCreate = ElementCreateCommon & {
962
+ type: "Highlighter";
963
+ coordinates: LngLatTuple[][][]; // A multipolygon describing the area that is highlighted.
964
+ color?: string; // The color of the element in some CSS-like format. (default: "#C93535")
965
+ name?: string | null;
966
+ renderHoles?: boolean; // Whether to render the holes of the highlighted area. (default: false)
967
+ opacity?: number; // default: 0.5
968
+ };
969
+
970
+ type HighlighterElementRead = {
971
+ id: string;
972
+ interaction?: "default" | "locked"; // default: "default"
973
+ } & Required<Omit<HighlighterElementCreate, "interaction" | "coordinates">>;
974
+
975
+ type HighlighterElementUpdate = {
976
+ id: string;
977
+ coordinates?: LngLatTuple[][][]; // A multipolygon describing the area that is highlighted.
978
+ } & Omit<HighlighterElementCreate, "coordinates">;
979
+
980
+ type TextElementCreate = ElementCreateCommon & {
981
+ type: "Text";
982
+ text: string;
983
+ color?: string; // The color of the element in some CSS-like format. (default: "#C93535")
984
+ rotation?: number; // default: 0
985
+ scale?: number; // The relative scale of the element from the default size. (default: 1)
986
+ zoom?: number; // The zoom level at which the element was created.
987
+ align?: "center" | "left" | "right"; // default: "center"
988
+ style?: "light" | "italic" | "regular" | "caps"; // default: "regular"
989
+ position?: LngLatTuple;
990
+ };
991
+
992
+ type TextElementRead = {
993
+ id: string;
994
+ // The text shown in the element, which is identical to the `text` property.
995
+ // This is added for consistency with other elements that have a `name` property.
996
+ name: string;
997
+ interaction?: "default" | "locked"; // default: "default"
998
+ } & Required<Omit<TextElementCreate, "interaction">>;
999
+
1000
+ type TextElementUpdate = { id: string; text?: string } & Omit<TextElementCreate, "text">;
1001
+
1002
+ type NoteElementCreate = ElementCreateCommon & {
1003
+ type: "Note";
1004
+ text: string;
1005
+ color?: string; // The color of the element in some CSS-like format. (default: "#C93535")
1006
+ rotation?: number; // default: 0
1007
+ scale?: number; // The relative scale of the element from the default size. (default: 1)
1008
+ zoom?: number; // The zoom level at which the element was created.
1009
+ // The alignment of the text, either `left`, `center` or `right`.
1010
+ align?: "center" | "left" | "right"; // default: "center"
1011
+ style?: "light" | "italic" | "regular" | "caps"; // default: "regular"
1012
+ widthScale?: number;
1013
+ position?: LngLatTuple;
1014
+ };
1015
+
1016
+ type NoteElementRead = {
1017
+ id: string;
1018
+ // The text shown in the element, which is identical to the `text` property.
1019
+ // This is added for consistency with other elements that have a `name` property.
1020
+ name: string;
1021
+ interaction?: "default" | "locked"; // default: "default"
1022
+ } & Required<Omit<NoteElementCreate, "interaction">>;
1023
+
1024
+ type NoteElementUpdate = { id: string; text?: string } & Omit<NoteElementCreate, "text">;
1025
+
1026
+ type ImageElementCreate = ElementCreateCommon & {
1027
+ type: "Image";
1028
+ coordinates: LngLatTuple[][];
1029
+ imageUrl: string;
1030
+ name?: string | null;
1031
+ opacity?: number; // default: 1
1032
+ };
1033
+
1034
+ type ImageElementRead = {
1035
+ id: string;
1036
+ interaction?: "default" | "locked"; // default: "default"
1037
+ } & Required<Omit<ImageElementCreate, "interaction" | "coordinates">>;
1038
+
1039
+ type ImageElementUpdate = { id: string; type: "Image" } & Partial<Omit<ImageElementCreate, "type">>;
1040
+
1041
+ type LinkElementRead = {
1042
+ id: string;
1043
+ groupId: string | null;
1044
+ color: string; // The color of the element in some CSS-like format. (default: "#C93535")
1045
+ name: string | null;
1046
+ // Text describing the element, which is shown in an element's popup when it is selected.
1047
+ description: string | null;
1048
+ // A set of key-value pairs that can be used to store arbitrary data about the element.
1049
+ attributes: Record<string, unknown>;
1050
+ type: "Link";
1051
+ url: string;
1052
+ interaction?: "default" | "locked"; // default: "default"
1053
+ };
1054
+
1055
+ type ElementGroup = {
1056
+ id: string;
1057
+ name: string;
1058
+ caption: string | null;
1059
+ // You can use these ids to get the full element objects via the `getElements` method.
1060
+ elementIds: string[];
1061
+ visible: boolean;
1062
+ shownInLegend: boolean;
1063
+ };
1064
+
1065
+ // The constraints to apply when getting elements.
1066
+ type GetElementsConstraint = { ids?: string[] };
1067
+
1068
+ // The constraints to apply when getting element groups.
1069
+ type GetElementGroupsConstraint = { ids?: string[] };
1070
+
1071
+ // The parameters for the `onElementChange` and the `onElementCreate` listeners.
1072
+ type ElementChangeCallbackParams = {
1073
+ // The new data for the element or null if the element was removed.
1074
+ element: Element | null;
1075
+ // Whether or not this element is still being created by a drawing tool.
1076
+ isBeingCreated: boolean;
1077
+ };
1078
+
1079
+ // The parameters for the `onElementGroupChange` listener.
1080
+ type ElementGroupChangeCallbackParams = { elementGroup: ElementGroup | null };
1081
+
1082
+ type ElementCreate = PlaceElementCreate | PathElementCreate | PolygonElementCreate | CircleElementCreate | MarkerElementCreate | HighlighterElementCreate | ImageElementCreate | TextElementCreate | NoteElementCreate;
1083
+
1084
+ type ElementUpdate = PlaceElementUpdate | PathElementUpdate | PolygonElementUpdate | CircleElementUpdate | MarkerElementUpdate | HighlighterElementUpdate | TextElementUpdate | NoteElementUpdate | ImageElementUpdate;
1085
+
1086
+ type Element = PlaceElementRead | PathElementRead | PolygonElementRead | CircleElementRead | MarkerElementRead | HighlighterElementRead | TextElementRead | NoteElementRead | ImageElementRead | LinkElementRead;
1087
+ ```
1088
+
1089
+ ### Methods
1090
+
1091
+ ```typescript
1092
+ // Get a single element from the map by its id.
1093
+ felt.getElement(id: string): Promise<Element | null>;
1094
+
1095
+ // Get the geometry of an element in GeoJSON geometry format.
1096
+ felt.getElementGeometry(id: string): Promise<GeoJsonGeometry | null>;
1097
+
1098
+ // Gets elements from the map, according to the constraints supplied.
1099
+ // The elements in the map, ordered by the order specified in Felt. This is not necessarily the order
1100
+ // that they are drawn in, as Felt draws points above lines and lines above polygons, for instance.
1101
+ felt.getElements(constraint?: GetElementsConstraint): Promise<(Element | null)[]>;
1102
+
1103
+ // Get an element group from the map by its id.
1104
+ felt.getElementGroup(id: string): Promise<ElementGroup | null>;
1105
+
1106
+ // Gets element groups from the map, according to the filters supplied.
1107
+ felt.getElementGroups(constraint?: GetElementGroupsConstraint): Promise<(ElementGroup | null)[]>;
1108
+
1109
+ // Hide or show element groups with the given ids.
1110
+ felt.setElementGroupVisibility(visibility: SetVisibilityRequest): Promise<void>;
1111
+
1112
+ // Create a new element on the map.
1113
+ felt.createElement(element: ElementCreate): Promise<Element>;
1114
+
1115
+ // Update an element on the map.
1116
+ felt.updateElement(element: ElementUpdate): Promise<Element>;
1117
+
1118
+ // Delete an element from the map.
1119
+ felt.deleteElement(id: string): Promise<void>;
1120
+ ```
1121
+
1122
+ ### Events
1123
+
1124
+ ```typescript
1125
+ // Adds a listener for when an element is created.
1126
+ felt.onElementCreate(args: { handler: (change: ElementChangeCallbackParams) => void }): VoidFunction;
1127
+
1128
+ // Listens for when a new element is finished being created by a drawing tool.
1129
+ felt.onElementCreateEnd(args: {
1130
+ handler: (params: { element: Element }) => void; // The handler to call whenever this event fires.
1131
+ }): VoidFunction;
1132
+
1133
+ // Adds a listener for when an element changes.
1134
+ felt.onElementChange(args: {
1135
+ options: { id: string };
1136
+ handler: (change: ElementChangeCallbackParams) => void;
1137
+ }): VoidFunction;
1138
+
1139
+ // Adds a listener for when an element is deleted.
1140
+ felt.onElementDelete(args: { options: { id: string }; handler: () => void }): VoidFunction;
1141
+
1142
+ // Adds a listener for when an element group changes.
1143
+ felt.onElementGroupChange(args: {
1144
+ options: { id: string };
1145
+ handler: (change: ElementGroupChangeCallbackParams) => void;
1146
+ }): VoidFunction;
1147
+ ```
1148
+
1149
+ ## Selection
1150
+
1151
+ ```typescript
1152
+ // References an element on the map.
1153
+ type ElementNode = { type: "element"; entity: Element };
1154
+
1155
+ // References an element group.
1156
+ type ElementGroupNode = { type: "elementGroup"; entity: ElementGroup };
1157
+
1158
+ // References a layer on the map.
1159
+ type LayerNode = { type: "layer"; entity: Layer };
1160
+
1161
+ // References a layer group on the map.
1162
+ type LayerGroupNode = { type: "layerGroup"; entity: LayerGroup };
1163
+
1164
+ // References a feature on the map.
1165
+ type FeatureNode = { type: "feature"; entity: LayerFeature };
1166
+
1167
+ // The options for selecting a feature in a layer.
1168
+ type FeatureSelection = {
1169
+ id: string | number;
1170
+ layerId: string;
1171
+ // Whether to show the feature's popup, if it is configured in the layer's style.
1172
+ showPopup?: boolean; // default: true
1173
+ // Whether to center the view on the feature after selecting it.
1174
+ fitViewport?: boolean | { maxZoom: number }; // default: true
1175
+ };
1176
+
1177
+ // A reference to any kind of entity in the map.
1178
+ // EntityNodes are used when you have some collection of entities and you need to
1179
+ type EntityNode = ElementNode | ElementGroupNode | LayerNode | LayerGroupNode | FeatureNode;
1180
+ ```
1181
+
1182
+ ### Methods
1183
+
1184
+ ```typescript
1185
+ // Gets the current selection as a list of entity identifiers.
1186
+ felt.getSelection(): Promise<EntityNode[]>;
1187
+
1188
+ // Selects a feature on a layer.
1189
+ felt.selectFeature(params: FeatureSelection): Promise<void>;
1190
+
1191
+ // Clears the current selection (elements, features or both).
1192
+ felt.clearSelection(params?: {
1193
+ features?: boolean; // Whether to clear the features from the selection.
1194
+ elements?: boolean; // Whether to clear the elements from the selection.
1195
+ }): Promise<void>;
1196
+ ```
1197
+
1198
+ ### Events
1199
+
1200
+ ```typescript
1201
+ // Adds a listener for when the selection changes.
1202
+ felt.onSelectionChange(params: { handler: (change: { selection: EntityNode[] }) => void }): VoidFunction;
1203
+ ```
1204
+
1205
+ ## Interactions
1206
+
1207
+ ```typescript
1208
+ // The event object passed to the interaction listeners.
1209
+ type MapInteractionEvent = {
1210
+ coordinate: LatLng; // The cursor position in world coordinates.
1211
+ // The pixel coordinates of the mouse cursor, relative to the map and measured from the top left corner.
1212
+ point: { x: number; y: number };
1213
+ features: LayerFeature[]; // The vector features that are under the cursor.
1214
+ rasterValues: RasterValue[]; // The raster pixel values that are under the cursor.
1215
+ };
1216
+ ```
1217
+
1218
+ ### Events
1219
+
1220
+ ```typescript
1221
+ // Allows you to be notified when the user clicks on the map.
1222
+ felt.onPointerClick(params: { handler: (event: MapInteractionEvent) => void }): VoidFunction;
1223
+
1224
+ // Allows you to be notified when the user moves the mouse over the map.
1225
+ felt.onPointerMove(params: { handler: (event: MapInteractionEvent) => void }): VoidFunction;
1226
+ ```
1227
+
1228
+ ## Basemaps
1229
+
1230
+ ```typescript
1231
+ // Shared by every Basemap variant. Documentation shorthand, not an exported type.
1232
+ type BasemapCommon = {
1233
+ // Do not rely on the stability of this ID for Felt basemaps, as they are subject to change.
1234
+ id: string;
1235
+ name: string;
1236
+ uiColorScheme: "light" | "dark";
1237
+ attribution?: string;
1238
+ };
1239
+
1240
+ type FeltBasemap = BasemapCommon & {
1241
+ type: "felt";
1242
+ theme: "color_light" | "monochrome_dark" | "monochrome_light" | "satellite";
1243
+ };
1244
+
1245
+ type ColorBasemap = BasemapCommon & { type: "color"; color: string };
1246
+
1247
+ type CustomTileBasemap = BasemapCommon & { type: "xyz_tile"; tileUrl: string };
1248
+
1249
+ type ColorBasemapInput = Omit<ColorBasemap, "id">;
1250
+
1251
+ type CustomTileBasemapInput = Omit<CustomTileBasemap, "id">;
1252
+
1253
+ type Basemap = FeltBasemap | ColorBasemap | CustomTileBasemap;
1254
+ ```
1255
+
1256
+ ### Methods
1257
+
1258
+ ```typescript
1259
+ // Gets the currently active basemap.
1260
+ felt.getCurrentBasemap(): Promise<Basemap>;
1261
+
1262
+ // Gets all basemaps available on the map.
1263
+ felt.getBasemaps(): Promise<Basemap[]>;
1264
+
1265
+ // Chooses the basemap to use for the map.
1266
+ felt.chooseBasemap(id: string): void;
1267
+
1268
+ // Adds a custom basemap to the map.
1269
+ felt.addCustomBasemap(args: {
1270
+ basemap: ColorBasemapInput | CustomTileBasemapInput;
1271
+ select?: boolean; // Whether to select the basemap after adding it.
1272
+ }): Promise<Basemap>;
1273
+
1274
+ // Removes a basemap from the list of available basemaps.
1275
+ felt.removeBasemap(id: string): Promise<void>;
1276
+ ```
1277
+
1278
+ ### Events
1279
+
1280
+ ```typescript
1281
+ // Adds a listener for when the basemap changes.
1282
+ felt.onBasemapChange(args: { handler: (basemap: Basemap) => void }): VoidFunction;
1283
+ ```
1284
+
1285
+ ## Tools
1286
+
1287
+ ```typescript
1288
+ type ToolType = "circle" | "highlighter" | "line" | "link" | "marker" | "note" | "pin" | "polygon" | "route" | "text";
1289
+
1290
+ type PlaceFrame = "frame-circle" | "frame-square" | null;
1291
+
1292
+ type PinToolSettings = {
1293
+ color: string; // The color of the element in some CSS-like format. (default: "#C93535")
1294
+ frame: PlaceFrame; // The frame that is rendered around the Place's symbol.
1295
+ showInspector: boolean; // default: false
1296
+ symbol: PlaceSymbol;
1297
+ afterCreation: "select" | "enter name" | "add another"; // What to do after creating the Place element. (default: "enter name")
1298
+ };
1299
+
1300
+ type LineToolSettings = {
1301
+ color: string; // The color of the element in some CSS-like format. (default: "#C93535")
1302
+ // A value between 0 and 1 that describes the opacity of the element's stroke.
1303
+ strokeOpacity: number; // default: 1
1304
+ strokeWidth: number; // default: 2
1305
+ strokeStyle: "solid" | "dashed" | "dotted"; // default: "solid"
1306
+ // Whether a distance marker is shown at the midpoint of the path.
1307
+ distanceMarker: boolean; // default: false
1308
+ showInspector: boolean; // default: false
1309
+ };
1310
+
1311
+ type RouteToolSettings = {
1312
+ color: string; // The color of the element in some CSS-like format. (default: "#C93535")
1313
+ // A value between 0 and 1 that describes the opacity of the element's stroke.
1314
+ strokeOpacity: number; // default: 1
1315
+ strokeWidth: number; // default: 2
1316
+ strokeStyle: "solid" | "dashed" | "dotted"; // default: "solid"
1317
+ // Whether a distance marker is shown at the midpoint of the path.
1318
+ distanceMarker: boolean; // default: false
1319
+ // Whether this represents a route, and if so, what mode of transport is used.
1320
+ routingMode: "driving" | "cycling" | "walking" | "flying" | null; // default: null
1321
+ endCaps: boolean; // Whether or not to show Start and End caps on the path. (default: false)
1322
+ showInspector: boolean; // default: false
1323
+ };
1324
+
1325
+ type PolygonToolSettings = {
1326
+ color: string; // The color of the element in some CSS-like format. (default: "#C93535")
1327
+ // A value between 0 and 1 that describes the opacity of the element's stroke.
1328
+ strokeOpacity: number; // default: 1
1329
+ strokeWidth: number; // default: 2
1330
+ strokeStyle: "solid" | "dashed" | "dotted"; // default: "solid"
1331
+ fillOpacity: number; // default: 0.25
1332
+ areaMarker: boolean; // default: false
1333
+ showInspector: boolean; // default: false
1334
+ };
1335
+
1336
+ type CircleToolSettings = {
1337
+ color: string; // The color of the element in some CSS-like format. (default: "#C93535")
1338
+ // A value between 0 and 1 that describes the opacity of the element's stroke.
1339
+ strokeOpacity: number; // default: 1
1340
+ strokeWidth: number; // default: 2
1341
+ strokeStyle: "solid" | "dashed" | "dotted"; // default: "solid"
1342
+ // Whether to show a marker on the circle that indicates the radius
1343
+ radiusMarker: boolean; // default: false
1344
+ fillOpacity: number; // default: 0.25
1345
+ showInspector: boolean; // default: false
1346
+ };
1347
+
1348
+ type MarkerToolSettings = {
1349
+ color: string; // The color of the element in some CSS-like format. (default: "#C93535")
1350
+ opacity: number; // default: 1
1351
+ // The size of the marker, used in conjunction with the `zoom` to determine the actual size of the marker.
1352
+ size: number; // default: 10
1353
+ showInspector: boolean; // default: false
1354
+ };
1355
+
1356
+ type HighlighterToolSettings = {
1357
+ color: string; // The color of the element in some CSS-like format. (default: "#C93535")
1358
+ renderHoles: boolean; // Whether to render the holes of the highlighted area. (default: false)
1359
+ opacity: number; // default: 0.5
1360
+ showInspector: boolean; // default: false
1361
+ size: number;
1362
+ };
1363
+
1364
+ type TextToolSettings = {
1365
+ color: string; // The color of the element in some CSS-like format. (default: "#C93535")
1366
+ align: "center" | "left" | "right"; // default: "center"
1367
+ style: "light" | "italic" | "regular" | "caps"; // default: "regular"
1368
+ showInspector: boolean; // default: false
1369
+ };
1370
+
1371
+ type NoteToolSettings = {
1372
+ color: string; // The color of the element in some CSS-like format. (default: "#C93535")
1373
+ // The alignment of the text, either `left`, `center` or `right`.
1374
+ align: "center" | "left" | "right"; // default: "center"
1375
+ style: "light" | "italic" | "regular" | "caps"; // default: "regular"
1376
+ showInspector: boolean; // default: false
1377
+ };
1378
+
1379
+ type ConfigurableToolType = Exclude<ToolType, "link">;
1380
+
1381
+ type ToolSettingsMap = {
1382
+ pin: PinToolSettings;
1383
+ line: LineToolSettings;
1384
+ route: RouteToolSettings;
1385
+ polygon: PolygonToolSettings;
1386
+ circle: CircleToolSettings;
1387
+ marker: MarkerToolSettings;
1388
+ highlighter: HighlighterToolSettings;
1389
+ text: TextToolSettings;
1390
+ note: NoteToolSettings;
1391
+ };
1392
+
1393
+ // The parameters for changing the settings of each tool.
1394
+ type InputToolSettings = { tool: "pin" } & Partial<PinToolSettings> | { tool: "line" } & Partial<LineToolSettings> | { tool: "route" } & Partial<RouteToolSettings> | { tool: "polygon" } & Partial<PolygonToolSettings> | { tool: "circle" } & Partial<CircleToolSettings> | { tool: "marker" } & Partial<MarkerToolSettings> | { tool: "highlighter" } & Partial<HighlighterToolSettings> | { tool: "text" } & Partial<TextToolSettings> | { tool: "note" } & Partial<NoteToolSettings>;
1395
+
1396
+ // The result of listening for changes to the settings of each tool.
1397
+ type ToolSettingsChangeEvent = { tool: "pin" } & PinToolSettings | { tool: "line" } & LineToolSettings | { tool: "route" } & RouteToolSettings | { tool: "polygon" } & PolygonToolSettings | { tool: "circle" } & CircleToolSettings | { tool: "marker" } & MarkerToolSettings | { tool: "highlighter" } & HighlighterToolSettings | { tool: "text" } & TextToolSettings | { tool: "note" } & NoteToolSettings;
1398
+
1399
+ type PlaceSymbol = "dot" | "square" | "diamond" | "triangle" | "x" | "plus" | "circle-line" | "circle-slash" | "star" | "heart" | "hexagon" | "octagon" | "pedestrian" | "bicycle" | "wheelchair" | "airport" | "car" | "bus" | "train" | "truck" | "ferry" | "sailboat" | "electric-service" | "gas-service" | "blood-clinic" | "badge" | "traffic-light" | "traffic-cone" | "road-sign-caution" | "person" | "restroom" | "house" | "work" | "letter" | "hotel" | "factory" | "hospital" | "religious-facility" | "school" | "government" | "university" | "bank" | "landmark" | "museum" | "clothing" | "shopping" | "store" | "bar" | "pub" | "cafe" | "food" | "park" | "amusement-park" | "camping-tent" | "cabin" | "picnic" | "water-refill" | "trailhead" | "guidepost" | "viewpoint" | "camera" | "us-football" | "football" | "tennis" | "binoculars" | "swimming" | "zap" | "battery-full" | "battery-half" | "battery-low" | "boom" | "radar" | "wind-turbine" | "solar-panel" | "antenna" | "telephone-pole" | "oil-well" | "oil-barrel" | "railroad-track" | "bridge" | "lighthouse" | "lock-closed" | "lock-open" | "wifi" | "trash" | "recycle" | "tree" | "flower" | "leaf" | "fire" | "mountain" | "snowy-mountain" | "volcano" | "island" | "wave" | "hot-springs" | "water" | "lake" | "ocean" | "animal" | "bird" | "duck" | "dog" | "fish" | "beach" | "wetland" | "sun" | "moon" | "cloud" | "partial-sun" | "rain" | "lightning" | "snowflake" | "wind" | "snow" | "fog" | "sleet" | "hurricane" | "warning" | "parking" | "info" | "circle-exclamation" | "circle-triangle" | "circle-x" | "circle-plus" | `:${string}:` & {};
1400
+ ```
1401
+
1402
+ ### Methods
1403
+
1404
+ ```typescript
1405
+ // Sets the tool to use for drawing elements on the map.
1406
+ felt.setTool(tool: ToolType | null): void;
1407
+
1408
+ // Gets the current tool, if any is in use.
1409
+ felt.getTool(): Promise<ToolType | null>;
1410
+
1411
+ // Sets the settings for the current tool.
1412
+ felt.setToolSettings(settings: InputToolSettings): void;
1413
+
1414
+ // Gets the settings for the chosen tool.
1415
+ felt.getToolSettings<T extends ConfigurableToolType>(tool: T): Promise<ToolSettingsMap[T]>;
1416
+ ```
1417
+
1418
+ ### Events
1419
+
1420
+ ```typescript
1421
+ // Listens for changes to the current tool.
1422
+ felt.onToolChange(args: {
1423
+ // This callback is called with the current tool whenever the tool changes.
1424
+ handler: (tool: ToolType | null) => void;
1425
+ }): VoidFunction;
1426
+
1427
+ // Listens for changes to the settings on all tools.
1428
+ felt.onToolSettingsChange(args: { handler: (settings: ToolSettingsChangeEvent) => void }): VoidFunction;
1429
+ ```
1430
+
1431
+ ## UI
1432
+
1433
+ ```typescript
1434
+ type CreateActionTriggerParams = { actionTrigger: UIActionTriggerCreate; placement?: PlacementForUIElement };
1435
+
1436
+ type UpdateActionTriggerParams = {
1437
+ id: string;
1438
+ label?: string;
1439
+ disabled?: boolean;
1440
+ type?: undefined;
1441
+ onTrigger?: (args: { id: string }) => void;
1442
+ onCreate?: (args: { id: string }) => void; // A function to call when the element is created.
1443
+ onDestroy?: (args: { id: string }) => void; // A function to call when the element is destroyed.
1444
+ };
1445
+
1446
+ type CreateFeatureActionParams = { action: UIFeatureActionCreate; placement?: PlacementForUIElement };
1447
+
1448
+ type UpdateFeatureActionParams = {
1449
+ id: string;
1450
+ label?: string;
1451
+ layerIds?: string[];
1452
+ geometryTypes?: ("Polygon" | "Point" | "Line" | "Raster")[]; // The geometry type of the features to add the action to.
1453
+ type?: undefined;
1454
+ onTrigger?: (args: { feature: LayerFeature }) => void;
1455
+ onCreate?: (args: { id: string }) => void; // A function to call when the element is created.
1456
+ onDestroy?: (args: { id: string }) => void; // A function to call when the element is destroyed.
1457
+ };
1458
+
1459
+ // The parameters for creating or updating a panel by using UiController.createOrUpdatePanel.
1460
+ type CreateOrUpdatePanelParams = {
1461
+ panel: UIPanelCreateOrUpdate;
1462
+ placement?: PlacementForUIElement;
1463
+ initialPlacement?: PlacementForUIElement; // The placement of the panel on the right sidebar stack. (default: { at: "end" })
1464
+ };
1465
+
1466
+ type CreatePanelElementsParams = {
1467
+ panelId: string;
1468
+ elements: {
1469
+ element: UIPanelElementCreate;
1470
+ container?: "footer" | "body" | { id: string }; // default: "body"
1471
+ // The placement of the element in the target container (based on the `container` property).
1472
+ placement?: PlacementForUIElement; // default: { at: "end" }
1473
+ }[];
1474
+ };
1475
+
1476
+ type UpdatePanelElementsParams = { panelId: string; elements: { element: UIPanelElementUpdate }[] };
1477
+
1478
+ type DeletePanelElementsParams = { panelId: string; elements: string[] };
1479
+
1480
+ type UiControlsOptions = {
1481
+ showLegend?: boolean; // Whether or not the legend is shown. (default: true)
1482
+ // When co-operative gestures are enabled, the pan and zoom gestures are adjusted to work better when the map is...
1483
+ // On mobile devices, enabling co-operative gestures will allow the user to pan past the embedded map
1484
+ // with a single finger drag. To pan the map, they must use two fingers.
1485
+ // On desktop devices, enabling co-operative gestures allows the user to scroll past the embedded map
1486
+ // using their scroll wheel or trackpad. To zoom the map, they must hold the Ctrl (Windows) or Command
1487
+ // key (Mac) while scrolling.
1488
+ cooperativeGestures?: boolean; // default: true
1489
+ // Whether or not the full screen button is shown in an embedded map.
1490
+ // When clicked, this will open the map in a new tab or window.
1491
+ fullScreenButton?: boolean; // default: true
1492
+ // Whether or not the geolocation button is shown in an embedded map.
1493
+ // The geolocation feature will plot your position on the map. If you click the button again, it will
1494
+ // start tracking your position.
1495
+ geolocation?: boolean; // default: false
1496
+ // Whether or not the zoom controls are shown in an embedded map.
1497
+ // This does not affect whether or not the map can be zoomed, just the display of the zoom controls in
1498
+ // the bottom right corner of the map.
1499
+ zoomControls?: boolean; // default: true
1500
+ scaleBar?: boolean; // Whether or not the scale bar is shown in an embedded map. (default: true)
1501
+ // Whether or not the map can be rotated.
1502
+ // This affects all rotation interactions — dragging with the right mouse button or Ctrl held,
1503
+ // two-finger touch rotation, and keyboard shortcuts — as well as the compass control, which is hidden
1504
+ // when rotation is disabled.
1505
+ rotation?: boolean; // default: true
1506
+ // Whether or not the right-click context menu is available on the map.
1507
+ // When disabled, right-clicking the map opens neither Felt's context menu nor the browser's own.
1508
+ contextMenu?: boolean; // default: true
1509
+ };
1510
+
1511
+ // The options for which parts of the Felt UI can be shown when interacting with features and elements on the...
1512
+ type OnMapInteractionsOptions = {
1513
+ // Set this to `false` to prevent the panel that shows information about a selected feature from being shown.
1514
+ featureSelectPanel?: boolean;
1515
+ // Set this to `false` to prevent the panel that shows information about a hovered feature from being shown.
1516
+ featureHoverPanel?: boolean;
1517
+ // Set this to `false` to prevent the panel that shows information about a selected element from being shown.
1518
+ elementSelectPanel?: boolean;
1519
+ // Set this to `false` to prevent clicking on a map link element from opening that link in a new tab or window.
1520
+ linkClickOpen?: boolean;
1521
+ // Set this to `false` to prevent clicking on an image element from opening the image in a lightbox.
1522
+ imageLightboxOpen?: boolean;
1523
+ };
1524
+
1525
+ // Represents an action trigger.
1526
+ type UIActionTriggerCreate = {
1527
+ label: string;
1528
+ onTrigger: (args: { id: string }) => void; // The function to call when the action trigger is triggered.
1529
+ id?: string;
1530
+ disabled?: boolean; // Whether the action trigger is disabled or not.
1531
+ type?: undefined;
1532
+ onCreate?: (args: { id: string }) => void; // A function to call when the element is created.
1533
+ onDestroy?: (args: { id: string }) => void; // A function to call when the element is destroyed.
1534
+ };
1535
+
1536
+ // Shared by every UIPanelElementCreate variant. Documentation shorthand, not an exported type.
1537
+ type UIPanelElementCreateCommon = {
1538
+ onCreate?: (args: { id: string }) => void; // A function to call when the element is created.
1539
+ onDestroy?: (args: { id: string }) => void;
1540
+ // If not provided, the element will be assigned a random ID, but it is recommended to provide it to
1541
+ // perform further updates on the element.
1542
+ // If provided, it must be unique within the UI.
1543
+ id?: string;
1544
+ };
1545
+
1546
+ // The parameters for creating a button element.
1547
+ // `id` is optional but recommended if you want to be able to perform updates.
1548
+ type UIButtonElementCreate = UIPanelElementCreateCommon & {
1549
+ type: "Button";
1550
+ label: string;
1551
+ onClick: (args: { id: string }) => void; // The action to perform when the button is clicked.
1552
+ variant?: "filled" | "transparent" | "outlined"; // default: "filled"
1553
+ tint?: "default" | "primary" | "accent" | "danger"; // default: "default"
1554
+ disabled?: boolean; // default: false
1555
+ };
1556
+
1557
+ // Represents a button element in a panel.
1558
+ type UIButtonElement = { id: string } & Omit<UIButtonElementCreate, "id">;
1559
+
1560
+ // The parameters for updating a button element.
1561
+ // `id` and `type` are required to identify the element to update.
1562
+ type UIButtonElementUpdate = { type: "Button"; id: string } & Partial<Omit<UIButtonElementCreate, "type" | "id">>;
1563
+
1564
+ // The parameters for creating a button row element.
1565
+ type UIButtonRowElementCreate = UIPanelElementCreateCommon & {
1566
+ type: "ButtonRow";
1567
+ items: UIButtonElementCreate[];
1568
+ align?: "start" | "end"; // default: "start"
1569
+ // Label text to display above the element and used for screen readers.
1570
+ label?: string;
1571
+ };
1572
+
1573
+ // Represents a row of buttons.
1574
+ type UIButtonRowElement = { items: UIButtonElement[]; id: string } & Omit<UIButtonRowElementCreate, "items" | "id">;
1575
+
1576
+ // The parameters for updating a button row element.
1577
+ type UIButtonRowElementUpdate = { id: string; items?: UIButtonElementCreate[] } & Omit<UIButtonRowElementCreate, "id" | "items">;
1578
+
1579
+ // The parameters for creating a checkbox group element.
1580
+ type UICheckboxGroupElementCreate = UIPanelElementCreateCommon & {
1581
+ type: "CheckboxGroup";
1582
+ value: string[]; // default: []
1583
+ options: UIControlElementOption[];
1584
+ // The function to call when the value of the checkbox group changes.
1585
+ onChange: (args: { value: string[]; id: string }) => void;
1586
+ // Label text to display above the element and used for screen readers.
1587
+ label?: string;
1588
+ };
1589
+
1590
+ // The parameters for creating a checkbox group element.
1591
+ type UICheckboxGroupElement = { id: string } & Omit<UICheckboxGroupElementCreate, "id">;
1592
+
1593
+ // The parameters for updating a checkbox group element.
1594
+ type UICheckboxGroupElementUpdate = { type: "CheckboxGroup"; id: string } & Partial<Omit<UICheckboxGroupElementCreate, "type" | "id">>;
1595
+
1596
+ // The parameters for creating a divider element.
1597
+ // `id` is optional but recommended if you want to be able to delete the element.
1598
+ type UIDividerElementCreate = UIPanelElementCreateCommon & { type: "Divider" };
1599
+
1600
+ // Represents a divider element in a panel.
1601
+ type UIDividerElement = { id: string } & Omit<UIDividerElementCreate, "id">;
1602
+
1603
+ // The parameters for updating a divider element.
1604
+ // `id` and `type` are required to identify the element to update.
1605
+ type UIDividerElementUpdate = { id: string } & Omit<UIDividerElementCreate, "id">;
1606
+
1607
+ // Represents a feature action for creation.
1608
+ type UIFeatureActionCreate = {
1609
+ label: string;
1610
+ onTrigger: (args: { feature: LayerFeature }) => void;
1611
+ layerIds?: string[];
1612
+ geometryTypes?: ("Polygon" | "Point" | "Line" | "Raster")[]; // The geometry type of the features to add the action to.
1613
+ type?: undefined;
1614
+ onCreate?: (args: { id: string }) => void; // A function to call when the element is created.
1615
+ onDestroy?: (args: { id: string }) => void; // A function to call when the element is destroyed.
1616
+ };
1617
+
1618
+ // Represents a feature action after creation (with generated id).
1619
+ type UIFeatureAction = UIFeatureActionCreate & { id: string };
1620
+
1621
+ // The parameters for creating a flexible space element.
1622
+ // `id` is optional but recommended if you want to be able to perform updates.
1623
+ type UIFlexibleSpaceElementCreate = UIPanelElementCreateCommon & { type: "FlexibleSpace" };
1624
+
1625
+ // Represents a flexible space element in a container.
1626
+ type UIFlexibleSpaceElement = { id: string } & Omit<UIFlexibleSpaceElementCreate, "id">;
1627
+
1628
+ // The parameters for updating a flexible space element.
1629
+ // `id` and `type` are required to identify the element to update.
1630
+ type UIFlexibleSpaceElementUpdate = { id: string } & Omit<UIFlexibleSpaceElementCreate, "id">;
1631
+
1632
+ // The parameters for creating a grid container element.
1633
+ type UIGridContainerElementCreate = UIPanelElementCreateCommon & {
1634
+ type: "Grid";
1635
+ items: (UIButtonElementCreate | UITextElementCreate | UIDividerElementCreate | UITextInputElementCreate | UISelectElementCreate | UIFlexibleSpaceElementCreate | UIButtonRowElementCreate | UICheckboxGroupElementCreate | UIRadioGroupElementCreate | UIToggleGroupElementCreate | UIIframeElementCreate)[];
1636
+ grid?: string;
1637
+ verticalAlignment?: "center" | "top" | "bottom"; // default: "top"
1638
+ horizontalDistribution?: "center" | "start" | "end" | "space-between" | "space-around" | "space-evenly"; // default: "start"
1639
+ };
1640
+
1641
+ // Represents a container with a grid layout in a panel.
1642
+ type UIGridContainerElement = {
1643
+ items: (UIButtonElement | UITextElement | UIDividerElement | UITextInputElement | UISelectElement | UIFlexibleSpaceElement | UIButtonRowElement | UICheckboxGroupElement | UIRadioGroupElement | UIToggleGroupElement | UIIframeElement)[];
1644
+ id: string;
1645
+ } & Omit<UIGridContainerElementCreate, "items" | "id">;
1646
+
1647
+ // The parameters for updating a grid container element.
1648
+ // `id` and `type` are required to identify the element to update.
1649
+ type UIGridContainerElementUpdate = {
1650
+ id: string;
1651
+ items?: (UIButtonElementCreate | UITextElementCreate | UIDividerElementCreate | UITextInputElementCreate | UISelectElementCreate | UIFlexibleSpaceElementCreate | UIButtonRowElementCreate | UICheckboxGroupElementCreate | UIRadioGroupElementCreate | UIToggleGroupElementCreate | UIIframeElementCreate)[];
1652
+ } & Omit<UIGridContainerElementCreate, "id" | "items">;
1653
+
1654
+ // The parameters for creating an iframe element.
1655
+ // `id` is optional but recommended if you want to be able to perform updates.
1656
+ type UIIframeElementCreate = UIPanelElementCreateCommon & { type: "Iframe"; url: string; height?: string | number };
1657
+
1658
+ // Represents an iframe element in a panel.
1659
+ type UIIframeElement = { id: string } & Omit<UIIframeElementCreate, "id">;
1660
+
1661
+ // The parameters for updating an iframe element.
1662
+ // `id` and `type` are required to identify the element to update.
1663
+ type UIIframeElementUpdate = { id: string; url?: string } & Omit<UIIframeElementCreate, "id" | "url">;
1664
+
1665
+ // A UI panel that can be added to the map using UiController.createOrUpdatePanel.
1666
+ type UIPanel = {
1667
+ type: "Panel";
1668
+ // The ID of the panel obtained from UiController.createPanelId.
1669
+ // Custom IDs are not supported.
1670
+ id: string;
1671
+ title?: string; // The title to display in the panel header.
1672
+ body?: UIPanelElement[];
1673
+ footer?: UIPanelElement[];
1674
+ onClickClose?: (args: { id: string }) => void; // A function to call when panel's close button is clicked.
1675
+ onCreate?: (args: { id: string }) => void; // A function to call when the element is created.
1676
+ onDestroy?: (args: { id: string }) => void; // A function to call when the element is destroyed.
1677
+ };
1678
+
1679
+ // The parameters for creating a panel by using UiController.createOrUpdatePanel.
1680
+ type UIPanelCreateOrUpdate = {
1681
+ // The ID of the panel obtained from UiController.createPanelId.
1682
+ // Custom IDs are not supported.
1683
+ id: string;
1684
+ title?: string; // The title to display in the panel header.
1685
+ onClickClose?: (args: { id: string }) => void; // A function to call when panel's close button is clicked.
1686
+ type?: "Panel";
1687
+ body?: UIPanelElementCreate[];
1688
+ footer?: UIPanelElementCreate[];
1689
+ onCreate?: (args: { id: string }) => void; // A function to call when the element is created.
1690
+ onDestroy?: (args: { id: string }) => void; // A function to call when the element is destroyed.
1691
+ };
1692
+
1693
+ // The parameters for creating a radio group element.
1694
+ type UIRadioGroupElementCreate = UIPanelElementCreateCommon & {
1695
+ type: "RadioGroup";
1696
+ options: UIControlElementOption[];
1697
+ // The function to call when the value of the radio group changes.
1698
+ onChange: (args: { value: string | undefined; id: string }) => void;
1699
+ value?: string;
1700
+ // Label text to display above the element and used for screen readers.
1701
+ label?: string;
1702
+ };
1703
+
1704
+ // The parameters for creating a radio group element.
1705
+ type UIRadioGroupElement = { id: string } & Omit<UIRadioGroupElementCreate, "id">;
1706
+
1707
+ // The parameters for updating a radio group element.
1708
+ type UIRadioGroupElementUpdate = { type: "RadioGroup"; id: string } & Partial<Omit<UIRadioGroupElementCreate, "type" | "id">>;
1709
+
1710
+ // The parameters for creating a select element.
1711
+ // `id` is optional but recommended if you want to be able to perform updates.
1712
+ type UISelectElementCreate = UIPanelElementCreateCommon & {
1713
+ type: "Select";
1714
+ options: UIControlElementOption[];
1715
+ onChange: (args: { value: string; id: string }) => void; // The function to call when the value of the select changes.
1716
+ value?: string;
1717
+ placeholder?: string; // The placeholder text to display in the select.
1718
+ // Whether the select should allow searching through the options.
1719
+ search?: boolean; // default: false
1720
+ // Label text to display above the element and used for screen readers.
1721
+ label?: string;
1722
+ };
1723
+
1724
+ // Represents a select element in a panel.
1725
+ // `options` property is required. `label` property is displayed above the select and used for screen
1726
+ // readers. `value` property is optional, for empty value use `undefined`. `placeholder` property is
1727
+ // displayed in the select when no value is selected. `search` property is used to enable searching
1728
+ // through the options. `onChange` property is used to handle the value change event.
1729
+ type UISelectElement = { id: string } & Omit<UISelectElementCreate, "id">;
1730
+
1731
+ // The parameters for updating a select element.
1732
+ // `id` and `type` are required to identify the element to update.
1733
+ type UISelectElementUpdate = { type: "Select"; id: string } & Partial<Omit<UISelectElementCreate, "type" | "id">>;
1734
+
1735
+ // The parameters for creating a text element.
1736
+ // `id` is optional but recommended if you want to be able to perform updates.
1737
+ type UITextElementCreate = UIPanelElementCreateCommon & { type: "Text"; content: string };
1738
+
1739
+ // Represents a text element in a panel.
1740
+ type UITextElement = { id: string } & Omit<UITextElementCreate, "id">;
1741
+
1742
+ // The parameters for updating a text element.
1743
+ // `id` and `type` are required to identify the element to update.
1744
+ type UITextElementUpdate = {
1745
+ type: "Text";
1746
+ id: string;
1747
+ content?: string;
1748
+ onCreate?: (args: { id: string }) => void; // A function to call when the element is created.
1749
+ onDestroy?: (args: { id: string }) => void;
1750
+ };
1751
+
1752
+ // The parameters for creating a text input element.
1753
+ // `id` is optional but recommended if you want to be able to perform updates.
1754
+ type UITextInputElementCreate = UIPanelElementCreateCommon & {
1755
+ type: "TextInput";
1756
+ value: string;
1757
+ placeholder?: string;
1758
+ onChange?: (args: { value: string; id: string }) => void; // The function to call when the value of the input changes.
1759
+ onBlur?: (args: { value: string; id: string }) => void; // The function to call when the input is blurred.
1760
+ onFocus?: (args: { value: string; id: string }) => void; // The function to call when the input is focused.
1761
+ // Label text to display above the element and used for screen readers.
1762
+ label?: string;
1763
+ };
1764
+
1765
+ // Represents a text input element in a panel.
1766
+ // `value` property is required, for empty value use `""`. `label` property is displayed above the
1767
+ // input and used for screen readers.
1768
+ type UITextInputElement = { id: string } & Omit<UITextInputElementCreate, "id">;
1769
+
1770
+ // The parameters for updating a text input element.
1771
+ // `id` and `type` are required to identify the element to update.
1772
+ type UITextInputElementUpdate = { id: string; value?: string } & Omit<UITextInputElementCreate, "id" | "value">;
1773
+
1774
+ // The parameters for creating a toggle group element.
1775
+ type UIToggleGroupElementCreate = UIPanelElementCreateCommon & {
1776
+ type: "ToggleGroup";
1777
+ value: string[]; // default: []
1778
+ options: UIControlElementOption[];
1779
+ // The function to call when the value of the toggle group changes.
1780
+ onChange: (args: { value: string[]; id: string }) => void;
1781
+ alignment?: "start" | "end"; // default: "start"
1782
+ // Label text to display above the element and used for screen readers.
1783
+ label?: string;
1784
+ };
1785
+
1786
+ // The parameters for creating a toggle group element.
1787
+ type UIToggleGroupElement = { id: string } & Omit<UIToggleGroupElementCreate, "id">;
1788
+
1789
+ // The parameters for updating a toggle group element.
1790
+ type UIToggleGroupElementUpdate = { type: "ToggleGroup"; id: string } & Partial<Omit<UIToggleGroupElementCreate, "type" | "id">>;
1791
+
1792
+ // An option to display in a control element.
1793
+ type UIControlElementOption = { label: string; value: string; disabled?: boolean };
1794
+
1795
+ // Used in UiController.createOrUpdatePanel to specify the position of a panel in the stack and in...
1796
+ type PlacementForUIElement = { after: string } | { before: string } | { at: "start" | "end" };
1797
+
1798
+ type UIPanelElement = UIButtonElement | UITextElement | UIDividerElement | UITextInputElement | UISelectElement | UIFlexibleSpaceElement | UIButtonRowElement | UICheckboxGroupElement | UIRadioGroupElement | UIToggleGroupElement | UIIframeElement | UIGridContainerElement;
1799
+
1800
+ // This is a union of all the possible elements that can be created inside panel's body or footer.
1801
+ // For the sake of convenience, `id` is optional but recommended if you want to be able to perform
1802
+ // updates.
1803
+ type UIPanelElementCreate = UIButtonElementCreate | UITextElementCreate | UIDividerElementCreate | UITextInputElementCreate | UISelectElementCreate | UIFlexibleSpaceElementCreate | UIButtonRowElementCreate | UICheckboxGroupElementCreate | UIRadioGroupElementCreate | UIToggleGroupElementCreate | UIIframeElementCreate | UIGridContainerElementCreate;
1804
+
1805
+ // This is a union of all the possible elements that can be updated inside panel's body or footer.
1806
+ // `id` and `type` are required to identify the element to update.
1807
+ type UIPanelElementUpdate = UIButtonElementUpdate | UITextElementUpdate | UITextInputElementUpdate | UISelectElementUpdate | UIDividerElementUpdate | UIButtonRowElementUpdate | UICheckboxGroupElementUpdate | UIRadioGroupElementUpdate | UIToggleGroupElementUpdate | UIGridContainerElementUpdate | UIFlexibleSpaceElementUpdate | UIIframeElementUpdate;
1808
+ ```
1809
+
1810
+ ### Methods
1811
+
1812
+ ```typescript
1813
+ // Creates an action trigger.
1814
+ felt.createActionTrigger(args: CreateActionTriggerParams): Promise<UIActionTriggerCreate>;
1815
+
1816
+ // Updates an action trigger.
1817
+ // Properties provided will override the existing properties.
1818
+ felt.updateActionTrigger(args: UpdateActionTriggerParams): Promise<UIActionTriggerCreate>;
1819
+
1820
+ // Deletes an action trigger.
1821
+ felt.deleteActionTrigger(id: string): void;
1822
+
1823
+ // Creates a feature contextual action.
1824
+ felt.createFeatureAction(args: CreateFeatureActionParams): Promise<UIFeatureAction>;
1825
+
1826
+ // Updates a feature contextual action.
1827
+ // Properties provided will override the existing properties.
1828
+ felt.updateFeatureAction(args: UpdateFeatureActionParams): Promise<UIFeatureAction>;
1829
+
1830
+ // Deletes a feature contextual action.
1831
+ felt.deleteFeatureAction(id: string): void;
1832
+
1833
+ // Creates a panel ID.
1834
+ felt.createPanelId(): Promise<string>;
1835
+
1836
+ // Creates or updates a panel.
1837
+ felt.createOrUpdatePanel(args: CreateOrUpdatePanelParams): Promise<UIPanel>;
1838
+
1839
+ // Deletes a panel.
1840
+ felt.deletePanel(id: string): void;
1841
+
1842
+ // Creates elements in a panel.
1843
+ felt.createPanelElements(args: CreatePanelElementsParams): Promise<UIPanel>;
1844
+
1845
+ // Updates an existing element in a panel.
1846
+ felt.updatePanelElements(args: UpdatePanelElementsParams): Promise<UIPanel>;
1847
+
1848
+ // Deletes elements from a panel.
1849
+ felt.deletePanelElements(args: DeletePanelElementsParams): void;
1850
+
1851
+ // Updates the UI controls on the embedded map.
1852
+ felt.updateUiControls(controls: UiControlsOptions): void;
1853
+
1854
+ // Control the on-map UI shown when interacting with features and elements.
1855
+ felt.setOnMapInteractionsUi(options: UiOnMapInteractionsOptions): void;
1856
+
1857
+ // Shows a data table view for the specified layer, optionally sorted by a given attribute.
1858
+ felt.showLayerDataTable(params?: {
1859
+ layerId: string;
1860
+ sorting?: SortConfig; // Optional sorting configuration for the table.
1861
+ }): Promise<void>;
1862
+
1863
+ // Hides the data table.
1864
+ felt.hideLayerDataTable(): Promise<void>;
1865
+ ```
1866
+
1867
+ ## Viewport
1868
+
1869
+ ```typescript
1870
+ // The input type for setting the viewport to a particular center and zoom.
1871
+ type ViewportCenterZoom = { center: LatLng; zoom: number };
1872
+
1873
+ // The current state of the viewport, including the derived bounds.
1874
+ type ViewportState = {
1875
+ center: LatLng;
1876
+ zoom: number;
1877
+ // The bounding box of the viewport in [west, south, east, north] order.
1878
+ bounds: FeltBoundary;
1879
+ };
1880
+
1881
+ // The parameters for the `setViewport` method.
1882
+ type SetViewportCenterZoomParams = { center?: LatLng; zoom?: number };
1883
+
1884
+ // The constraints for the viewport.
1885
+ type ViewportConstraints = {
1886
+ minZoom: number | null;
1887
+ maxZoom: number | null;
1888
+ bounds: FeltBoundary | null;
1889
+ };
1890
+
1891
+ // The parameters for the `fitViewportToBounds` method.
1892
+ type ViewportFitBoundsParams = { bounds: FeltBoundary };
1893
+ ```
1894
+
1895
+ ### Methods
1896
+
1897
+ ```typescript
1898
+ // Gets the current state of the viewport.
1899
+ felt.getViewport(): Promise<ViewportState>;
1900
+
1901
+ // Moves the map to the specified location.
1902
+ felt.setViewport(viewport: SetViewportCenterZoomParams): void;
1903
+
1904
+ // Gets the current state of the viewport constraints.
1905
+ felt.getViewportConstraints(): Promise<ViewportConstraints | null>;
1906
+
1907
+ // Constrains the map viewport so it stays inside certain bounds and/or certain zoom levels.
1908
+ felt.setViewportConstraints(constraints: Partial<ViewportConstraints> | null): void;
1909
+
1910
+ // Fits the map to the specified bounds.
1911
+ felt.fitViewportToBounds(bounds: ViewportFitBoundsParams): void;
1912
+ ```
1913
+
1914
+ ### Events
1915
+
1916
+ ```typescript
1917
+ // Adds a listener for when the viewport changes.
1918
+ felt.onViewportMove(args: {
1919
+ // This callback is called with the current viewport state whenever the viewport changes.
1920
+ handler: (viewport: ViewportState) => void;
1921
+ }): VoidFunction;
1922
+
1923
+ // Adds a listener for when the viewport move ends, which is when the user stops dragging or zooming the map.
1924
+ felt.onViewportMoveEnd(args: { handler: (viewport: ViewportState) => void }): VoidFunction;
1925
+
1926
+ // Adds a listener for when the map is idle, which is defined as: - No transitions are in progress - The user is...
1927
+ felt.onMapIdle(args: { handler: () => void }): VoidFunction;
1928
+ ```
1929
+
1930
+ ## Map Details
1931
+
1932
+ ```typescript
1933
+ // The details of a map.
1934
+ type MapDetails = { id: string; title: string; description: string | null };
1935
+ ```
1936
+
1937
+ ### Methods
1938
+
1939
+ ```typescript
1940
+ // Gets the details of the map.
1941
+ felt.getMapDetails(): Promise<MapDetails>;
1942
+ ```