@maptiler/sdk 1.0.8 → 1.0.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/src/Map.ts CHANGED
@@ -5,6 +5,11 @@ import type {
5
5
  MapOptions as MapOptionsML,
6
6
  ControlPosition,
7
7
  StyleOptions,
8
+ MapDataEvent,
9
+ Tile,
10
+ RasterDEMSourceSpecification,
11
+ TerrainSpecification,
12
+ MapTerrainEvent,
8
13
  } from "maplibre-gl";
9
14
  import { v4 as uuidv4 } from "uuid";
10
15
  import { ReferenceMapStyle, MapStyleVariant } from "@maptiler/client";
@@ -23,6 +28,22 @@ import { MaptilerTerrainControl } from "./MaptilerTerrainControl";
23
28
  import { MaptilerNavigationControl } from "./MaptilerNavigationControl";
24
29
  import { geolocation } from "@maptiler/client";
25
30
  import { MaptilerGeolocateControl } from "./MaptilerGeolocateControl";
31
+ import { AttributionControl } from "./AttributionControl";
32
+ import { ScaleControl } from "./ScaleControl";
33
+ import { FullscreenControl } from "./FullscreenControl";
34
+
35
+ function sleepAsync(ms: number) {
36
+ return new Promise((resolve) => setTimeout(resolve, ms));
37
+ }
38
+
39
+ export type LoadWithTerrainEvent = {
40
+ type: "loadWithTerrain";
41
+ target: Map;
42
+ terrain: {
43
+ source: string;
44
+ exaggeration: number;
45
+ };
46
+ };
26
47
 
27
48
  // StyleSwapOptions is not exported by Maplibre, but we can redefine it (used for setStyle)
28
49
  export type TransformStyleFunction = (
@@ -45,6 +66,13 @@ export const GeolocationType: {
45
66
  COUNTRY: "COUNTRY",
46
67
  } as const;
47
68
 
69
+ type MapTerrainDataEvent = MapDataEvent & {
70
+ isSourceLoaded: boolean;
71
+ tile: Tile;
72
+ sourceId: string;
73
+ source: RasterDEMSourceSpecification;
74
+ };
75
+
48
76
  /**
49
77
  * Options to provide to the `Map` constructor
50
78
  */
@@ -129,25 +157,21 @@ export type MapOptions = Omit<MapOptionsML, "style" | "maplibreLogo"> & {
129
157
  *
130
158
  * Default: `false`
131
159
  */
132
- geolocate?: typeof GeolocationType[keyof typeof GeolocationType] | boolean;
160
+ geolocate?: (typeof GeolocationType)[keyof typeof GeolocationType] | boolean;
133
161
  };
134
162
 
135
163
  /**
136
164
  * The Map class can be instanciated to display a map in a `<div>`
137
165
  */
138
166
  export class Map extends maplibregl.Map {
139
- private languageShouldUpdate = false;
140
- private isStyleInitialized = false;
141
167
  private isTerrainEnabled = false;
142
168
  private terrainExaggeration = 1;
143
169
  private primaryLanguage: LanguageString | null = null;
144
170
  private secondaryLanguage: LanguageString | null = null;
171
+ private terrainGrowing = false;
172
+ private terrainFlattening = false;
145
173
 
146
174
  constructor(options: MapOptions) {
147
- // if (options.language) {
148
- // config.primaryLanguage = options.language;
149
- // }
150
-
151
175
  if (options.apiKey) {
152
176
  config.apiKey = options.apiKey;
153
177
  }
@@ -201,12 +225,15 @@ export class Map extends maplibregl.Map {
201
225
 
202
226
  this.primaryLanguage = options.language ?? config.primaryLanguage;
203
227
  this.secondaryLanguage = config.secondaryLanguage;
228
+ this.terrainExaggeration =
229
+ options.terrainExaggeration ?? this.terrainExaggeration;
204
230
 
205
231
  // Map centering and geolocation
206
232
  this.once("styledata", async () => {
207
233
  // Not using geolocation centering if...
208
234
 
209
- if (options.geolocate === false) {
235
+ // the geolcoate option is not provided or is falsy
236
+ if (!options.geolocate) {
210
237
  return;
211
238
  }
212
239
 
@@ -241,6 +268,11 @@ export class Map extends maplibregl.Map {
241
268
  console.warn(e.message);
242
269
  }
243
270
 
271
+ // A more precise localization
272
+
273
+ // This more advanced localization is commented out because the easeTo animation
274
+ // triggers an error if the terrain grow is enabled (due to being nable to project the center while moving)
275
+
244
276
  // Then, the get a more precise location, we rely on the browser location, but only if it was already granted
245
277
  // before (we don't want to ask wih a popup at launch time)
246
278
  const locationResult = await navigator.permissions.query({
@@ -256,11 +288,21 @@ export class Map extends maplibregl.Map {
256
288
  return;
257
289
  }
258
290
 
259
- this.easeTo({
260
- center: [data.coords.longitude, data.coords.latitude],
261
- zoom: options.zoom || 12,
262
- duration: 2000,
263
- });
291
+ if (this.terrain) {
292
+ this.easeTo({
293
+ center: [data.coords.longitude, data.coords.latitude],
294
+ zoom: options.zoom || 12,
295
+ duration: 2000,
296
+ });
297
+ } else {
298
+ this.once("terrain", () => {
299
+ this.easeTo({
300
+ center: [data.coords.longitude, data.coords.latitude],
301
+ zoom: options.zoom || 12,
302
+ duration: 2000,
303
+ });
304
+ });
305
+ }
264
306
  },
265
307
 
266
308
  // error callback
@@ -335,7 +377,7 @@ export class Map extends maplibregl.Map {
335
377
 
336
378
  // if attribution in option is `false` but the the logo shows up in the tileJson, then the attribution must show anyways
337
379
  if (options.attributionControl === false) {
338
- this.addControl(new maplibregl.AttributionControl(options));
380
+ this.addControl(new AttributionControl(options));
339
381
  }
340
382
  } else if (options.maptilerLogo) {
341
383
  this.addControl(new MaptilerLogoControl(), options.logoPosition);
@@ -353,7 +395,7 @@ export class Map extends maplibregl.Map {
353
395
  : options.scaleControl
354
396
  ) as ControlPosition;
355
397
 
356
- const scaleControl = new maplibregl.ScaleControl({ unit: config.unit });
398
+ const scaleControl = new ScaleControl({ unit: config.unit });
357
399
  this.addControl(scaleControl, position);
358
400
  config.on("unit", (unit) => {
359
401
  scaleControl.setUnit(unit);
@@ -420,10 +462,44 @@ export class Map extends maplibregl.Map {
420
462
  : options.fullscreenControl
421
463
  ) as ControlPosition;
422
464
 
423
- this.addControl(new maplibregl.FullscreenControl({}), position);
465
+ this.addControl(new FullscreenControl({}), position);
466
+ }
467
+ });
468
+
469
+ // Creating a custom event: "loadWithTerrain"
470
+ // that fires only once when both:
471
+ // - the map has full loaded (corresponds to the the "load" event)
472
+ // - the terrain has loaded (corresponds to the "terrain" event with terrain beion non-null)
473
+ // This custom event is necessary to wait for when the map is instanciated with `terrain: true`
474
+ // and some animation (flyTo, easeTo) are running from the begining.
475
+ let loadEventTriggered = false;
476
+ let terrainEventTriggered = false;
477
+ let terrainEventData: LoadWithTerrainEvent = null;
478
+
479
+ this.once("load", (_) => {
480
+ loadEventTriggered = true;
481
+ if (terrainEventTriggered) {
482
+ this.fire("loadWithTerrain", terrainEventData);
424
483
  }
425
484
  });
426
485
 
486
+ const terrainCallback = (evt) => {
487
+ if (!evt.terrain) return;
488
+ terrainEventTriggered = true;
489
+ terrainEventData = {
490
+ type: "loadWithTerrain",
491
+ target: this,
492
+ terrain: evt.terrain,
493
+ };
494
+ this.off("terrain", terrainCallback);
495
+
496
+ if (loadEventTriggered) {
497
+ this.fire("loadWithTerrain", terrainEventData as LoadWithTerrainEvent);
498
+ }
499
+ };
500
+
501
+ this.on("terrain", terrainCallback);
502
+
427
503
  // enable 3D terrain if provided in options
428
504
  if (options.terrain) {
429
505
  this.enableTerrain(
@@ -432,6 +508,43 @@ export class Map extends maplibregl.Map {
432
508
  }
433
509
  }
434
510
 
511
+ /**
512
+ * Awaits for _this_ Map instance to be "loaded" and returns a Promise to the Map.
513
+ * If _this_ Map instance is already loaded, the Promise is resolved directly,
514
+ * otherwise, it is resolved as a result of the "load" event.
515
+ * @returns
516
+ */
517
+ async onLoadAsync() {
518
+ return new Promise<Map>((resolve, reject) => {
519
+ if (this.loaded()) {
520
+ return resolve(this);
521
+ }
522
+
523
+ this.once("load", (_) => {
524
+ resolve(this);
525
+ });
526
+ });
527
+ }
528
+
529
+ /**
530
+ * Awaits for _this_ Map instance to be "loaded" as well as with terrain being non-null for the first time
531
+ * and returns a Promise to the Map.
532
+ * If _this_ Map instance is already loaded with terrain, the Promise is resolved directly,
533
+ * otherwise, it is resolved as a result of the "loadWithTerrain" event.
534
+ * @returns
535
+ */
536
+ async onLoadWithTerrainAsync() {
537
+ return new Promise<Map>((resolve, reject) => {
538
+ if (this.loaded() && this.terrain) {
539
+ return resolve(this);
540
+ }
541
+
542
+ this.once("loadWithTerrain", (_) => {
543
+ resolve(this);
544
+ });
545
+ });
546
+ }
547
+
435
548
  /**
436
549
  * Update the style of the map.
437
550
  * Can be:
@@ -791,6 +904,54 @@ export class Map extends maplibregl.Map {
791
904
  return this.isTerrainEnabled;
792
905
  }
793
906
 
907
+ private growTerrain(exaggeration, durationMs = 1000) {
908
+ // This method assumes the terrain is already built
909
+ if (!this.terrain) {
910
+ return;
911
+ }
912
+
913
+ const startTime = performance.now();
914
+ // This is supposedly 0, but it could be something else (e.g. already in the middle of growing, or user defined other)
915
+ const currentExaggeration = this.terrain.exaggeration;
916
+ const deltaExaggeration = exaggeration - currentExaggeration;
917
+
918
+ // This is again called in a requestAnimationFrame ~loop, until the terrain has grown enough
919
+ // that it has reached the target
920
+ const updateExaggeration = () => {
921
+ if (!this.terrain) {
922
+ return;
923
+ }
924
+
925
+ // If the flattening animation is triggered while the growing animation
926
+ // is running, then the flattening animation is stopped
927
+ if (this.terrainFlattening) {
928
+ return;
929
+ }
930
+
931
+ // normalized value in interval [0, 1] of where we are currently in the animation loop
932
+ const positionInLoop = (performance.now() - startTime) / durationMs;
933
+
934
+ // The animation goes on until we reached 99% of the growing sequence duration
935
+ if (positionInLoop < 0.99) {
936
+ const exaggerationFactor = 1 - Math.pow(1 - positionInLoop, 4);
937
+ const newExaggeration =
938
+ currentExaggeration + exaggerationFactor * deltaExaggeration;
939
+ this.terrain.exaggeration = newExaggeration;
940
+ requestAnimationFrame(updateExaggeration);
941
+ } else {
942
+ this.terrainGrowing = false;
943
+ this.terrainFlattening = false;
944
+ this.terrain.exaggeration = exaggeration;
945
+ }
946
+
947
+ this.triggerRepaint();
948
+ };
949
+
950
+ this.terrainGrowing = true;
951
+ this.terrainFlattening = false;
952
+ requestAnimationFrame(updateExaggeration);
953
+ }
954
+
794
955
  /**
795
956
  * Enables the 3D terrain visualization
796
957
  * @param exaggeration
@@ -802,27 +963,72 @@ export class Map extends maplibregl.Map {
802
963
  return;
803
964
  }
804
965
 
805
- const terrainInfo = this.getTerrain();
966
+ // This function is mapped to a map "data" event. It checks that the terrain
967
+ // tiles are loaded and when so, it starts an animation to make the terrain grow
968
+ const dataEventTerrainGrow = async (evt: MapTerrainDataEvent) => {
969
+ if (!this.terrain) {
970
+ return;
971
+ }
972
+
973
+ if (
974
+ evt.type !== "data" ||
975
+ evt.dataType !== "source" ||
976
+ !("source" in evt)
977
+ ) {
978
+ return;
979
+ }
980
+
981
+ if (evt.sourceId !== "maptiler-terrain") {
982
+ return;
983
+ }
984
+
985
+ const source = evt.source;
806
986
 
987
+ if (source.type !== "raster-dem") {
988
+ return;
989
+ }
990
+
991
+ if (!evt.isSourceLoaded) {
992
+ return;
993
+ }
994
+
995
+ // We shut this event off because we want it to happen only once.
996
+ // Yet, we cannot use the "once" method because only the last event of the series
997
+ // has `isSourceLoaded` true
998
+ this.off("data", dataEventTerrainGrow);
999
+
1000
+ this.growTerrain(exaggeration);
1001
+ };
1002
+
1003
+ // This is put into a function so that it can be called regardless
1004
+ // of the loading state of _this_ the map instance
807
1005
  const addTerrain = () => {
808
1006
  // When style is changed,
809
1007
  this.isTerrainEnabled = true;
810
1008
  this.terrainExaggeration = exaggeration;
811
1009
 
1010
+ // Mapping it to the "data" event so that we can check that the terrain
1011
+ // growing starts only when terrain tiles are loaded (to reduce glitching)
1012
+ this.on("data", dataEventTerrainGrow);
1013
+
812
1014
  this.addSource(defaults.terrainSourceId, {
813
1015
  type: "raster-dem",
814
1016
  url: defaults.terrainSourceURL,
815
1017
  });
1018
+
1019
+ // Setting up the terrain with a 0 exaggeration factor
1020
+ // so it loads ~seamlessly and then can grow from there
816
1021
  this.setTerrain({
817
1022
  source: defaults.terrainSourceId,
818
- exaggeration: exaggeration,
1023
+ exaggeration: 0,
819
1024
  });
820
1025
  };
821
1026
 
822
1027
  // The terrain has already been loaded,
823
1028
  // we just update the exaggeration.
824
- if (terrainInfo) {
825
- this.setTerrain({ ...terrainInfo, exaggeration });
1029
+ if (this.getTerrain()) {
1030
+ this.isTerrainEnabled = true;
1031
+ this.growTerrain(exaggeration);
826
1032
  return;
827
1033
  }
828
1034
 
@@ -842,44 +1048,80 @@ export class Map extends maplibregl.Map {
842
1048
  * Disable the 3D terrain visualization
843
1049
  */
844
1050
  disableTerrain() {
845
- this.isTerrainEnabled = false;
846
- this.setTerrain(null);
847
- if (this.getSource(defaults.terrainSourceId)) {
848
- this.removeSource(defaults.terrainSourceId);
1051
+ // It could be disabled already
1052
+ if (!this.terrain) {
1053
+ return;
849
1054
  }
1055
+
1056
+ this.isTerrainEnabled = false;
1057
+ // this.stopFlattening = false;
1058
+
1059
+ // Duration of the animation in millisec
1060
+ const animationLoopDuration = 1 * 1000;
1061
+ const startTime = performance.now();
1062
+ // This is supposedly 0, but it could be something else (e.g. already in the middle of growing, or user defined other)
1063
+ const currentExaggeration = this.terrain.exaggeration;
1064
+
1065
+ // This is again called in a requestAnimationFrame ~loop, until the terrain has grown enough
1066
+ // that it has reached the target
1067
+ const updateExaggeration = () => {
1068
+ if (!this.terrain) {
1069
+ return;
1070
+ }
1071
+
1072
+ // If the growing animation is triggered while flattening,
1073
+ // then we exist the flatening
1074
+ if (this.terrainGrowing) {
1075
+ return;
1076
+ }
1077
+
1078
+ // normalized value in interval [0, 1] of where we are currently in the animation loop
1079
+ const positionInLoop =
1080
+ (performance.now() - startTime) / animationLoopDuration;
1081
+
1082
+ // The animation goes on until we reached 99% of the growing sequence duration
1083
+ if (positionInLoop < 0.99) {
1084
+ const exaggerationFactor = Math.pow(1 - positionInLoop, 4);
1085
+ const newExaggeration = currentExaggeration * exaggerationFactor;
1086
+ this.terrain.exaggeration = newExaggeration;
1087
+ requestAnimationFrame(updateExaggeration);
1088
+ } else {
1089
+ this.terrain.exaggeration = 0;
1090
+ this.terrainGrowing = false;
1091
+ this.terrainFlattening = false;
1092
+ this.setTerrain(null);
1093
+ if (this.getSource(defaults.terrainSourceId)) {
1094
+ this.removeSource(defaults.terrainSourceId);
1095
+ }
1096
+ }
1097
+
1098
+ this.triggerRepaint();
1099
+ };
1100
+
1101
+ this.terrainGrowing = false;
1102
+ this.terrainFlattening = true;
1103
+ requestAnimationFrame(updateExaggeration);
850
1104
  }
851
1105
 
852
1106
  /**
853
1107
  * Sets the 3D terrain exageration factor.
854
- * Note: this is only a shortcut to `.enableTerrain()`
1108
+ * If the terrain was not enabled prior to the call of this method,
1109
+ * the method `.enableTerrain()` will be called.
1110
+ * If `animate` is `true`, the terrain transformation will be animated in the span of 1 second.
1111
+ * If `animate` is `false`, no animated transition to the newly defined exaggeration.
855
1112
  * @param exaggeration
1113
+ * @param animate
856
1114
  */
857
- setTerrainExaggeration(exaggeration: number) {
858
- this.enableTerrain(exaggeration);
1115
+ setTerrainExaggeration(exaggeration: number, animate = true) {
1116
+ if (!animate && this.terrain) {
1117
+ this.terrainExaggeration = exaggeration;
1118
+ this.terrain.exaggeration = exaggeration;
1119
+ this.triggerRepaint();
1120
+ } else {
1121
+ this.enableTerrain(exaggeration);
1122
+ }
859
1123
  }
860
1124
 
861
- // getLanguages() {
862
- // const layers = this.getStyle().layers;
863
-
864
- // for (let i = 0; i < layers.length; i += 1) {
865
- // const layer = layers[i];
866
- // const layout = layer.layout;
867
-
868
- // if (!layout) {
869
- // continue;
870
- // }
871
-
872
- // if (!layout["text-field"]) {
873
- // continue;
874
- // }
875
-
876
- // const textFieldLayoutProp = this.getLayoutProperty(
877
- // layer.id,
878
- // "text-field"
879
- // );
880
- // }
881
- // }
882
-
883
1125
  /**
884
1126
  * Perform an action when the style is ready. It could be at the moment of calling this method
885
1127
  * or later.
@@ -1,8 +1,8 @@
1
1
  import type { LngLatLike } from "maplibre-gl";
2
2
  import maplibregl from "maplibre-gl";
3
+ import { GeolocateControl } from "./GeolocateControl";
3
4
  import { DOMcreate } from "./tools";
4
5
 
5
- const GeolocateControl = maplibregl.GeolocateControl;
6
6
  const Marker = maplibregl.Marker;
7
7
  const LngLat = maplibregl.LngLat;
8
8
 
@@ -2,6 +2,7 @@ import maplibregl from "maplibre-gl";
2
2
  import type { LogoOptions as LogoOptionsML } from "maplibre-gl";
3
3
  import { defaults } from "./defaults";
4
4
  import { Map } from "./Map";
5
+ import { LogoControl } from "./LogoControl";
5
6
 
6
7
  type LogoOptions = LogoOptionsML & {
7
8
  logoURL?: string;
@@ -12,7 +13,7 @@ type LogoOptions = LogoOptionsML & {
12
13
  * This LogoControl extends the MapLibre LogoControl but instead can use any image URL and
13
14
  * any link URL. By default this is using MapTiler logo and URL.
14
15
  */
15
- export class MaptilerLogoControl extends maplibregl.LogoControl {
16
+ export class MaptilerLogoControl extends LogoControl {
16
17
  private logoURL = "";
17
18
  private linkURL = "";
18
19
 
@@ -1,10 +1,10 @@
1
- import maplibregl from "maplibre-gl";
1
+ import { NavigationControl } from "./NavigationControl";
2
2
 
3
3
  type HTMLButtonElementPlus = HTMLButtonElement & {
4
4
  clickFunction: (e?: any) => unknown;
5
5
  };
6
6
 
7
- export class MaptilerNavigationControl extends maplibregl.NavigationControl {
7
+ export class MaptilerNavigationControl extends NavigationControl {
8
8
  constructor() {
9
9
  super({
10
10
  showCompass: true,
package/src/Marker.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * This is an extension of MapLibre Marker to make it fully type compatible with the SDK
3
+ */
4
+
5
+ import maplibregl from "maplibre-gl";
6
+ import type { Map as MapMLGL } from "maplibre-gl";
7
+ import { Map } from "./Map";
8
+
9
+ export class Marker extends maplibregl.Marker {
10
+ addTo(map: Map | MapMLGL): this {
11
+ return super.addTo(map as MapMLGL);
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * This is an extension of MapLibre NavigationControl to make it fully type compatible with the SDK
3
+ */
4
+
5
+ import maplibregl from "maplibre-gl";
6
+ import type { Map as MapMLGL } from "maplibre-gl";
7
+ import { Map } from "./Map";
8
+
9
+ export class NavigationControl extends maplibregl.NavigationControl {
10
+ onAdd(map: Map | MapMLGL) {
11
+ return super.onAdd(map as MapMLGL);
12
+ }
13
+ }
package/src/Popup.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * This is an extension of MapLibre Popup to make it fully type compatible with the SDK
3
+ */
4
+
5
+ import maplibregl from "maplibre-gl";
6
+ import type { Map as MapMLGL } from "maplibre-gl";
7
+ import { Map } from "./Map";
8
+
9
+ export class Popup extends maplibregl.Popup {
10
+ addTo(map: Map | MapMLGL): this {
11
+ return super.addTo(map as MapMLGL);
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * This is an extension of MapLibre RasterDEMTileSource to make it fully type compatible with the SDK
3
+ */
4
+
5
+ import maplibregl from "maplibre-gl";
6
+ import type { Map as MapMLGL } from "maplibre-gl";
7
+ import { Map } from "./Map";
8
+
9
+ export class RasterDEMTileSource extends maplibregl.RasterDEMTileSource {
10
+ onAdd(map: Map | MapMLGL) {
11
+ super.onAdd(map as MapMLGL);
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * This is an extension of MapLibre RasterTileSource to make it fully type compatible with the SDK
3
+ */
4
+
5
+ import maplibregl from "maplibre-gl";
6
+ import type { Map as MapMLGL } from "maplibre-gl";
7
+ import { Map } from "./Map";
8
+
9
+ export class RasterTileSource extends maplibregl.RasterTileSource {
10
+ onAdd(map: Map | MapMLGL) {
11
+ super.onAdd(map as MapMLGL);
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * This is an extension of MapLibre ScaleControl to make it fully type compatible with the SDK
3
+ */
4
+
5
+ import maplibregl from "maplibre-gl";
6
+ import type { Map as MapMLGL } from "maplibre-gl";
7
+ import { Map } from "./Map";
8
+
9
+ export class ScaleControl extends maplibregl.ScaleControl {
10
+ onAdd(map: Map | MapMLGL) {
11
+ return super.onAdd(map as MapMLGL);
12
+ }
13
+ }
package/src/Style.ts ADDED
@@ -0,0 +1,13 @@
1
+ /**
2
+ * This is an extension of MapLibre Style to make it fully type compatible with the SDK
3
+ */
4
+
5
+ import maplibregl from "maplibre-gl";
6
+ import type { Map as MapMLGL, StyleOptions } from "maplibre-gl";
7
+ import { Map } from "./Map";
8
+
9
+ export class Style extends maplibregl.Style {
10
+ constructor(map: Map, options: StyleOptions = {}) {
11
+ super(map as MapMLGL, options);
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * This is an extension of MapLibre TerrainControl to make it fully type compatible with the SDK
3
+ */
4
+
5
+ import maplibregl from "maplibre-gl";
6
+ import type { Map as MapMLGL } from "maplibre-gl";
7
+ import { Map } from "./Map";
8
+
9
+ export class TerrainControl extends maplibregl.TerrainControl {
10
+ onAdd(map: Map | MapMLGL) {
11
+ return super.onAdd(map as MapMLGL);
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * This is an extension of MapLibre VectorTileSource to make it fully type compatible with the SDK
3
+ */
4
+
5
+ import maplibregl from "maplibre-gl";
6
+ import type { Map as MapMLGL } from "maplibre-gl";
7
+ import { Map } from "./Map";
8
+
9
+ export class VectorTileSource extends maplibregl.VectorTileSource {
10
+ onAdd(map: Map | MapMLGL) {
11
+ super.onAdd(map as MapMLGL);
12
+ }
13
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * This is an extension of MapLibre VideoSource to make it fully type compatible with the SDK
3
+ */
4
+
5
+ import maplibregl from "maplibre-gl";
6
+ import type { Map as MapMLGL } from "maplibre-gl";
7
+ import { Map } from "./Map";
8
+
9
+ export class VideoSource extends maplibregl.VideoSource {
10
+ onAdd(map: Map | MapMLGL) {
11
+ super.onAdd(map as MapMLGL);
12
+ }
13
+ }