@maptiler/sdk 3.2.2 → 3.4.0-rc1

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 (100) hide show
  1. package/.husky/pre-commit +2 -1
  2. package/README.md +155 -1
  3. package/e2e/global.d.ts +12 -0
  4. package/e2e/public/animated-route.geojson +82 -0
  5. package/e2e/public/animatedRouteLayer.html +24 -0
  6. package/e2e/public/mapLoad.html +24 -0
  7. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-0-chromium-darwin.png +0 -0
  8. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-1-chromium-darwin.png +0 -0
  9. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-10-chromium-darwin.png +0 -0
  10. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-11-chromium-darwin.png +0 -0
  11. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-12-chromium-darwin.png +0 -0
  12. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-13-chromium-darwin.png +0 -0
  13. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-14-chromium-darwin.png +0 -0
  14. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-15-chromium-darwin.png +0 -0
  15. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-16-chromium-darwin.png +0 -0
  16. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-17-chromium-darwin.png +0 -0
  17. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-18-chromium-darwin.png +0 -0
  18. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-19-chromium-darwin.png +0 -0
  19. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-2-chromium-darwin.png +0 -0
  20. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-3-chromium-darwin.png +0 -0
  21. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-4-chromium-darwin.png +0 -0
  22. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-5-chromium-darwin.png +0 -0
  23. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-6-chromium-darwin.png +0 -0
  24. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-7-chromium-darwin.png +0 -0
  25. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-8-chromium-darwin.png +0 -0
  26. package/e2e/snapshots/tests/AnimatedRouteLayer.test.ts-snapshots/animated-route-9-chromium-darwin.png +0 -0
  27. package/e2e/snapshots/tests/map-load.test.ts-snapshots/mapLoad-chromium-darwin.png +0 -0
  28. package/e2e/tests/AnimatedRouteLayer.test.ts +45 -0
  29. package/e2e/tests/consts.ts +0 -0
  30. package/e2e/tests/expected-results/animatedRouteLayer-1.json +202 -0
  31. package/e2e/tests/helpers/fetchGeojson.ts +21 -0
  32. package/e2e/tests/helpers/getMapInstanceForFixture.ts +86 -0
  33. package/e2e/tests/map-load.test.ts +14 -0
  34. package/e2e/tests/mocks/maptiler-style.json +27 -0
  35. package/e2e/tests/mocks/tile.png +0 -0
  36. package/e2e/tsconfig.json +10 -0
  37. package/eslint.config.mjs +3 -73
  38. package/package.json +11 -4
  39. package/playwright.config.ts +82 -0
  40. package/tsconfig.json +4 -1
  41. package/typedoc.json +3 -2
  42. package/vite.config-e2e.ts +13 -0
  43. package/vite.config-es.ts +2 -2
  44. package/dist/maptiler-sdk.d.ts +0 -2
  45. package/dist/maptiler-sdk.mjs +0 -10797
  46. package/dist/maptiler-sdk.mjs.map +0 -1
  47. package/dist/src/ColorRamp.d.ts +0 -359
  48. package/dist/src/MLAdapters/AttributionControl.d.ts +0 -5
  49. package/dist/src/MLAdapters/BoxZoomHandler.d.ts +0 -7
  50. package/dist/src/MLAdapters/CanvasSource.d.ts +0 -5
  51. package/dist/src/MLAdapters/CooperativeGesturesHandler.d.ts +0 -5
  52. package/dist/src/MLAdapters/FullscreenControl.d.ts +0 -5
  53. package/dist/src/MLAdapters/GeoJSONSource.d.ts +0 -5
  54. package/dist/src/MLAdapters/GeolocateControl.d.ts +0 -5
  55. package/dist/src/MLAdapters/ImageSource.d.ts +0 -5
  56. package/dist/src/MLAdapters/KeyboardHandler.d.ts +0 -5
  57. package/dist/src/MLAdapters/LogoControl.d.ts +0 -5
  58. package/dist/src/MLAdapters/MapMouseEvent.d.ts +0 -5
  59. package/dist/src/MLAdapters/MapTouchEvent.d.ts +0 -5
  60. package/dist/src/MLAdapters/MapWheelEvent.d.ts +0 -5
  61. package/dist/src/MLAdapters/Marker.d.ts +0 -5
  62. package/dist/src/MLAdapters/NavigationControl.d.ts +0 -5
  63. package/dist/src/MLAdapters/Popup.d.ts +0 -5
  64. package/dist/src/MLAdapters/RasterDEMTileSource.d.ts +0 -5
  65. package/dist/src/MLAdapters/RasterTileSource.d.ts +0 -5
  66. package/dist/src/MLAdapters/ScaleControl.d.ts +0 -5
  67. package/dist/src/MLAdapters/ScrollZoomHandler.d.ts +0 -5
  68. package/dist/src/MLAdapters/Style.d.ts +0 -5
  69. package/dist/src/MLAdapters/TerrainControl.d.ts +0 -5
  70. package/dist/src/MLAdapters/TwoFingersTouchPitchHandler.d.ts +0 -5
  71. package/dist/src/MLAdapters/VectorTileSource.d.ts +0 -5
  72. package/dist/src/MLAdapters/VideoSource.d.ts +0 -5
  73. package/dist/src/Map.d.ts +0 -403
  74. package/dist/src/Point.d.ts +0 -177
  75. package/dist/src/Telemetry.d.ts +0 -21
  76. package/dist/src/caching.d.ts +0 -4
  77. package/dist/src/config.d.ts +0 -85
  78. package/dist/src/constants/defaults.d.ts +0 -15
  79. package/dist/src/controls/MaptilerGeolocateControl.d.ts +0 -21
  80. package/dist/src/controls/MaptilerLogoControl.d.ts +0 -19
  81. package/dist/src/controls/MaptilerNavigationControl.d.ts +0 -17
  82. package/dist/src/controls/MaptilerProjectionControl.d.ts +0 -14
  83. package/dist/src/controls/MaptilerTerrainControl.d.ts +0 -16
  84. package/dist/src/controls/Minimap.d.ts +0 -57
  85. package/dist/src/controls/index.d.ts +0 -6
  86. package/dist/src/converters/index.d.ts +0 -1
  87. package/dist/src/converters/xml.d.ts +0 -54
  88. package/dist/src/helpers/index.d.ts +0 -3
  89. package/dist/src/helpers/screenshot.d.ts +0 -18
  90. package/dist/src/helpers/stylehelper.d.ts +0 -28
  91. package/dist/src/helpers/vectorlayerhelpers.d.ts +0 -508
  92. package/dist/src/index.d.ts +0 -87
  93. package/dist/src/language.d.ts +0 -107
  94. package/dist/src/mapstyle.d.ts +0 -17
  95. package/dist/src/tools.d.ts +0 -84
  96. package/dist/src/types.d.ts +0 -1
  97. package/dist/src/utils/dom.d.ts +0 -2
  98. package/dist/src/utils/index.d.ts +0 -1
  99. package/dist/vite.config-test.d.ts +0 -2
  100. package/dist/vitest-setup-tests.d.ts +0 -1
package/.husky/pre-commit CHANGED
@@ -1,2 +1,3 @@
1
1
  npx lint-staged;
2
- npm run test;
2
+ npm run test;
3
+ npm run docs;
package/README.md CHANGED
@@ -32,7 +32,12 @@ npm install --save @maptiler/sdk
32
32
  ⚠️ Please keep in mind that if you use any additional [MapTiler modules](https://docs.maptiler.com/sdk-js/modules/), you must update them to a version that supports MapTiler SDK JS v3.
33
33
 
34
34
  # API documentation
35
- In addition to the details and examples provided in this readme, check out the [complete API documentation](https://docs.maptiler.com/sdk-js/api/)
35
+ For further documentation and examples, check out [docs.maptiler.com](https://docs.maptiler.com/sdk-js/api/).
36
+
37
+ Full api typedoc documentation can also be generated via the commands:
38
+
39
+ `npm run docs:md` to generate markdown in `docs`
40
+ `npm run docs:html` to generate html docs in `docs-html`
36
41
 
37
42
  # Quick start
38
43
 
@@ -1109,6 +1114,155 @@ Turning off *zoom compensation* allows for more accurate adjustments to the visu
1109
1114
  All the other options are documented on [our reference page](https://docs.maptiler.com/sdk-js/api/helpers/#heatmap) and more examples are available [here](https://docs.maptiler.com/sdk-js/examples/?q=heatmap+helper).
1110
1115
 
1111
1116
  # Other helpers
1117
+
1118
+ ## Camera routes and animations
1119
+
1120
+ The SDK comes with several classes to help with animations, particularly route animations.
1121
+
1122
+ See `demos/07-animated-routes.html` for examples.
1123
+
1124
+ ### 🧩 `MaptilerAnimation`
1125
+
1126
+ MaptilerAnimation is a utility class for smoothly animating between keyframes using custom easing and playback control. It supports event-based hooks for frame updates and completion, and works well within rendering loops or UI transitions.
1127
+
1128
+ #### 🚀 Usage
1129
+
1130
+ ```ts
1131
+ // linearly animated between values
1132
+ const animation = new MaptilerAnimation({
1133
+ keyframes: [
1134
+ // `props` are interpolated across the duration
1135
+ { delta: 0, props: { lon: -7.445, } },
1136
+ // `userData` can hold any type of custom data to pass with the keyframe
1137
+ { delta: 0.5, userData: { mydata: "whoa!" } },
1138
+ { delta: 1, props: { lon: -7.455 } }
1139
+ ],
1140
+ duration: 1000, // 1 second
1141
+ iterations: Infinity // loop forever
1142
+ });
1143
+
1144
+ const marker = new Marker().setLngLat(
1145
+ new LngLat(
1146
+ -7.449346225791231,
1147
+ 39.399728941536836,
1148
+ )
1149
+ ).addTo(map);
1150
+
1151
+ // TimeUpdate is fired every frame
1152
+ animation.addEventListener(AnimationEventTypes.TimeUpdate, (e) => {
1153
+ marker.setLngLat(
1154
+ new LngLat(
1155
+ e.props.lon,
1156
+ 39.399728941536836,
1157
+ )
1158
+ )
1159
+ })
1160
+ // fired when the keyframe changes
1161
+ animation.addEventListener(AnimationEventTypes.Keyframe, ({ userData }) => {
1162
+ console.log(userData.mydata) // "whoa!"
1163
+ });
1164
+
1165
+ animation.play();
1166
+ ```
1167
+ ![](images/animate-linear-trimmed.gif)
1168
+
1169
+ ```ts
1170
+ // eased between values
1171
+ const animation = new MaptilerAnimation({
1172
+ keyframes: [
1173
+ // `props` are interpolated across the duration
1174
+ { delta: 0, easing: EasingFunctionName.ElasticInOut, props: { lon: -7.445, } },
1175
+ { delta: 1, props: { lon: -7.455 } }
1176
+ ],
1177
+ duration: 1000, // 1 second
1178
+ iterations: Infinity // loop forever
1179
+ });
1180
+ ```
1181
+ ![](images/animate-elastic-trimmed.gif)
1182
+
1183
+ ### 🗺️ `AnimatedRouteLayer`
1184
+
1185
+ `AnimatedRouteLayer` is custom layer that animates a path or route on the map based on keyframes or GeoJSON data. It supports animated line styling and camera following, making it ideal for visualizing routes, playback tracks, or timeline-based geographic events.
1186
+
1187
+ Note: At present, to avoid problems arising from the camera being manipulated by two animatioons at any one time, there can only ever be one instance of `AnimatedRouteLayer` on the map at any time. This API may change in the future, but at present you must remove each instance of `AnimatedRouteLayer` from the map before adding another.
1188
+
1189
+ #### ✨ Features
1190
+ - Animate a path using keyframes or GeoJSON data
1191
+ - Optional animated stroke styles to indicate progress
1192
+ - Camera movement smoothing, following along the route
1193
+ - Configurable duration, easing, delay, and iterations via geojson properties
1194
+ - Event-based lifecycle hooks for adaptibility.
1195
+ - Optional manual frame advancement (e.g., for scrubbing or syncing with map events, scroll etc etc)
1196
+
1197
+ #### 🚀 Basic Usage
1198
+ ```ts
1199
+ const myGeoJSONSource = {
1200
+ "type": "FeatureCollection",
1201
+ "features": [
1202
+ {
1203
+ "type": "Feature",
1204
+ "geometry": {
1205
+ "type": "LineString",
1206
+ "coordinates": [
1207
+ [-74.0060, 40.7128],
1208
+ [-73.9352, 40.7306],
1209
+ [-73.9851, 40.7580]
1210
+ ]
1211
+ },
1212
+ "properties": {
1213
+ "@duration": 5000, // animation params are prepended with '@'
1214
+ "@iterations": 3,
1215
+ "@delay": 1000,
1216
+ "@autoplay": true,
1217
+ "bearing": [
1218
+ 40,
1219
+ 30,
1220
+ 10,
1221
+ 10,
1222
+ 20,
1223
+ 40,
1224
+ ]
1225
+ }
1226
+ }
1227
+ ]
1228
+ }
1229
+
1230
+ const animatedRoute = new AnimatedRouteLayer({
1231
+ source: {
1232
+ // assumes that the source is already added to the map with the given layer ID
1233
+ id: "my-geojson-source", // the name of the source
1234
+ layerID: "route-layer", // the name of the layer
1235
+ featureSetIndex: 0, // the index of the featureset within the geojson
1236
+ },
1237
+ // OR
1238
+ keyframes: [], // an array of keyframes
1239
+
1240
+ duration: 5000,
1241
+ pathStrokeAnimation: {
1242
+ // will only be appliued to LineString GeoJSON types
1243
+ activeColor: [0, 128, 0, 1], // color of the line that has already been traversed
1244
+ inactiveColor: [128, 128, 128, 0.5],
1245
+ },
1246
+ cameraAnimation: {
1247
+ follow: true, // should the camera follow the route?
1248
+ pathSmoothing: {
1249
+ resolution: 20, // the resolution of the smoothness
1250
+ epsilon: 10, // how much the path is simplified before smoothing
1251
+ },
1252
+ },
1253
+ autoplay: true,
1254
+ });
1255
+
1256
+ // Add to map
1257
+ map.addLayer(animatedRoute);
1258
+
1259
+ // Playback controls
1260
+ animatedRoute.play();
1261
+ animatedRoute.pause();
1262
+ ```
1263
+
1264
+ For a full example of how to use this, look at [the example](./demos/07-animated-routes.html)
1265
+
1112
1266
  ## Convert GPX and KML to GeoJSON
1113
1267
  In the [Polyline helper section](#polyline-layer-helper) above, we have seen that one can feed the helper directly with a path to a GPX or KML file, that is then converted under the hood client-side into a GeoJSON `FeatureCollection` object. This conversion feature is also exposed and can be used as such:
1114
1268
 
@@ -0,0 +1,12 @@
1
+ import { Map } from "@maptiler/sdk";
2
+
3
+ declare global {
4
+ interface Window {
5
+ __map: Map;
6
+ __pageLoadTimeout: number;
7
+ notifyScreenshotStateReady: (data: TTestTransferData) => Promise<void>;
8
+ __pageObjects: Record<string, unknown>;
9
+ }
10
+
11
+ type TTestTransferData = string | number | boolean | string[] | number[] | boolean[] | null | Record<string, unknown> | [number, number];
12
+ }
@@ -0,0 +1,82 @@
1
+ {
2
+ "type": "FeatureCollection",
3
+ "features": [
4
+ {
5
+ "type": "Feature",
6
+ "properties": {
7
+ "pitch": [
8
+ 30,
9
+ 40,
10
+ 50,
11
+ 60,
12
+ 50,
13
+ 40,
14
+ 30
15
+ ],
16
+ "bearing": [
17
+ 0,
18
+ 180,
19
+ 360
20
+ ],
21
+ "zoom": [
22
+ 13.5,
23
+ 14,
24
+ 14.5,
25
+ 15,
26
+ 14.5,
27
+ 14,
28
+ 13.5
29
+ ]
30
+ },
31
+ "geometry": {
32
+ "coordinates": [
33
+ [
34
+ -5.513465218122661,
35
+ 55.44452556522981
36
+ ],
37
+ [
38
+ -5.498757996681263,
39
+ 55.45488849896259
40
+ ],
41
+ [
42
+ -5.4776627901701715,
43
+ 55.459774141237716
44
+ ],
45
+ [
46
+ -5.450773829757111,
47
+ 55.45446729456921
48
+ ],
49
+ [
50
+ -5.434581030391769,
51
+ 55.44241894502119
52
+ ],
53
+ [
54
+ -5.434433020938883,
55
+ 55.42337006037573
56
+ ],
57
+ [
58
+ -5.447655667245527,
59
+ 55.40895140980018
60
+ ],
61
+ [
62
+ -5.474692405196635,
63
+ 55.40169789075969
64
+ ],
65
+ [
66
+ -5.504997423959253,
67
+ 55.410637475280794
68
+ ],
69
+ [
70
+ -5.520595992154796,
71
+ 55.42809094495976
72
+ ],
73
+ [
74
+ -5.513910891499705,
75
+ 55.44393572290733
76
+ ]
77
+ ],
78
+ "type": "LineString"
79
+ }
80
+ }
81
+ ]
82
+ }
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>MapTiler E2E Animated Route Layer</title>
7
+ <style>
8
+ #map {
9
+ width: 100vw;
10
+ height: 100vh;
11
+ border: 1px solid red;
12
+ }
13
+
14
+ body {
15
+ margin: 0;
16
+ padding: 0;
17
+ }
18
+ </style>
19
+ </head>
20
+ <body>
21
+ <div id="map"></div>
22
+ <script type="module" src="/src/animatedRouteLayer.ts"></script>
23
+ </body>
24
+ </html>
@@ -0,0 +1,24 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="UTF-8">
5
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
+ <title>MapTiler E2E Map Load</title>
7
+ <style>
8
+ #map {
9
+ width: 100vw;
10
+ height: 100vh;
11
+ border: 1px solid red;
12
+ }
13
+
14
+ body {
15
+ margin: 0;
16
+ padding: 0;
17
+ }
18
+ </style>
19
+ </head>
20
+ <body>
21
+ <div id="map"></div>
22
+ <script type="module" src="/src/mapLoad.ts"></script>
23
+ </body>
24
+ </html>
@@ -0,0 +1,45 @@
1
+ import { expect, test } from "@playwright/test";
2
+ import getMapInstanceForFixture from "./helpers/getMapInstanceForFixture";
3
+ import { AnimatedRouteLayer } from "index";
4
+ import { Map } from "@maptiler/sdk";
5
+ import expected from "./expected-results/animatedRouteLayer-1.json" assert { type: "json" };
6
+
7
+ test("Follows the correct path taking screenshots at each interval", async ({ page }) => {
8
+ await getMapInstanceForFixture({
9
+ fixture: "animatedRouteLayer",
10
+ page,
11
+ timeout: 10000,
12
+ });
13
+
14
+ expect(await page.title()).toBe("MapTiler E2E Animated Route Layer");
15
+
16
+ await page.exposeFunction("notifyScreenshotStateReady", async (data: Record<string, TTestTransferData>) => {
17
+ await expect(page).toHaveScreenshot(`animated-route-${data.frame}.png`);
18
+ expect(data).toEqual(expected[data.frame as number]);
19
+ });
20
+
21
+ await page.clock.install();
22
+
23
+ await page.evaluate(async () => {
24
+ const NUM_SCREENSHOTS = 20;
25
+ const NUM_FRAMES_BETWEEN_SCREENSHOTS = 20;
26
+
27
+ const { animatedRouteLayer } = window.__pageObjects as { animatedRouteLayer: AnimatedRouteLayer };
28
+ const map = window.__map as Map;
29
+
30
+ for (let i = 0; i < NUM_SCREENSHOTS; i++) {
31
+ for (let j = 0; j < NUM_FRAMES_BETWEEN_SCREENSHOTS; j++) {
32
+ animatedRouteLayer.updateManual();
33
+ }
34
+ await window.notifyScreenshotStateReady({
35
+ frame: i,
36
+ center: map.getCenter().toArray(),
37
+ zoom: map.getZoom(),
38
+ pitch: map.getPitch(),
39
+ bearing: map.getBearing(),
40
+ });
41
+ }
42
+ });
43
+
44
+ await page.clock.runFor(10000);
45
+ });
File without changes
@@ -0,0 +1,202 @@
1
+ [
2
+ {
3
+ "frame": 0,
4
+ "center": [
5
+ -5.466042011463379,
6
+ 55.4577906319048
7
+ ],
8
+ "zoom": 13.598461538461539,
9
+ "pitch": 31.96923076923077,
10
+ "bearing": 11.519999999999984
11
+ },
12
+ {
13
+ "frame": 1,
14
+ "center": [
15
+ -5.460399670970225,
16
+ 55.4563116595035
17
+ ],
18
+ "zoom": 13.696923076923076,
19
+ "pitch": 33.93846153846154,
20
+ "bearing": 23.039999999999967
21
+ },
22
+ {
23
+ "frame": 2,
24
+ "center": [
25
+ -5.454680854842297,
26
+ 55.454199187343335
27
+ ],
28
+ "zoom": 13.795384615384616,
29
+ "pitch": 35.90769230769231,
30
+ "bearing": 34.55999999999994
31
+ },
32
+ {
33
+ "frame": 3,
34
+ "center": [
35
+ -5.449154714432449,
36
+ 55.45161563359928
37
+ ],
38
+ "zoom": 13.893846153846155,
39
+ "pitch": 37.87692307692308,
40
+ "bearing": 46.08000000000004
41
+ },
42
+ {
43
+ "frame": 4,
44
+ "center": [
45
+ -5.4440854476088205,
46
+ 55.448695922972746
47
+ ],
48
+ "zoom": 13.992307692307692,
49
+ "pitch": 39.84615384615384,
50
+ "bearing": 57.5999999999999
51
+ },
52
+ {
53
+ "frame": 5,
54
+ "center": [
55
+ -5.439747931704942,
56
+ 55.4455842681447
57
+ ],
58
+ "zoom": 14.09076923076923,
59
+ "pitch": 41.8153846153846,
60
+ "bearing": 69.11999999999988
61
+ },
62
+ {
63
+ "frame": 6,
64
+ "center": [
65
+ -5.436381601488342,
66
+ 55.44242356593315
67
+ ],
68
+ "zoom": 14.189230769230766,
69
+ "pitch": 43.78461538461536,
70
+ "bearing": 80.63999999999987
71
+ },
72
+ {
73
+ "frame": 7,
74
+ "center": [
75
+ -5.434285966180362,
76
+ 55.43932695213108
77
+ ],
78
+ "zoom": 14.287692307692307,
79
+ "pitch": 45.753846153846105,
80
+ "bearing": 92.15999999999974
81
+ },
82
+ {
83
+ "frame": 8,
84
+ "center": [
85
+ -5.433268915702869,
86
+ 55.43589535070747
87
+ ],
88
+ "zoom": 14.386153846153844,
89
+ "pitch": 47.723076923076874,
90
+ "bearing": 103.67999999999961
91
+ },
92
+ {
93
+ "frame": 9,
94
+ "center": [
95
+ -5.433177455811488,
96
+ 55.43198983159487
97
+ ],
98
+ "zoom": 14.484615384615381,
99
+ "pitch": 49.69230769230762,
100
+ "bearing": 115.19999999999958
101
+ },
102
+ {
103
+ "frame": 10,
104
+ "center": [
105
+ -5.433880699537133,
106
+ 55.42784291729489
107
+ ],
108
+ "zoom": 14.577142857142853,
109
+ "pitch": 51.54285714285707,
110
+ "bearing": 126.71999999999957
111
+ },
112
+ {
113
+ "frame": 11,
114
+ "center": [
115
+ -5.435326079044055,
116
+ 55.423654806187365
117
+ ],
118
+ "zoom": 14.668571428571424,
119
+ "pitch": 53.37142857142849,
120
+ "bearing": 138.23999999999944
121
+ },
122
+ {
123
+ "frame": 12,
124
+ "center": [
125
+ -5.437416792145254,
126
+ 55.419638086917715
127
+ ],
128
+ "zoom": 14.759999999999996,
129
+ "pitch": 55.1999999999999,
130
+ "bearing": 149.75999999999942
131
+ },
132
+ {
133
+ "frame": 13,
134
+ "center": [
135
+ -5.440072094355931,
136
+ 55.41599788270592
137
+ ],
138
+ "zoom": 14.851428571428567,
139
+ "pitch": 57.028571428571325,
140
+ "bearing": 161.2799999999993
141
+ },
142
+ {
143
+ "frame": 14,
144
+ "center": [
145
+ -5.4432174520051015,
146
+ 55.412956866373364
147
+ ],
148
+ "zoom": 14.942857142857138,
149
+ "pitch": 58.85714285714275,
150
+ "bearing": 172.79999999999927
151
+ },
152
+ {
153
+ "frame": 15,
154
+ "center": [
155
+ -5.446829788111814,
156
+ 55.41064796034502
157
+ ],
158
+ "zoom": 14.963076923076928,
159
+ "pitch": 59.26153846153856,
160
+ "bearing": -175.5692307692314
161
+ },
162
+ {
163
+ "frame": 16,
164
+ "center": [
165
+ -5.451519315760324,
166
+ 55.40879433251729
167
+ ],
168
+ "zoom": 14.864615384615387,
169
+ "pitch": 57.292307692307745,
170
+ "bearing": -163.75384615384647
171
+ },
172
+ {
173
+ "frame": 17,
174
+ "center": [
175
+ -5.457134643435197,
176
+ 55.407280629375585
177
+ ],
178
+ "zoom": 14.766153846153847,
179
+ "pitch": 55.32307692307692,
180
+ "bearing": -151.9384615384615
181
+ },
182
+ {
183
+ "frame": 18,
184
+ "center": [
185
+ -5.463405013806986,
186
+ 55.40615466316898
187
+ ],
188
+ "zoom": 14.667692307692304,
189
+ "pitch": 53.3538461538461,
190
+ "bearing": -140.1230769230766
191
+ },
192
+ {
193
+ "frame": 19,
194
+ "center": [
195
+ -5.469987343492665,
196
+ 55.405428197723374
197
+ ],
198
+ "zoom": 14.569230769230764,
199
+ "pitch": 51.38461538461526,
200
+ "bearing": -128.30769230769158
201
+ }
202
+ ]
@@ -0,0 +1,21 @@
1
+ import { KeyframeableGeoJSONFeature } from "utils";
2
+
3
+ type GeoJSON = {
4
+ type: "FeatureCollection";
5
+ features: KeyframeableGeoJSONFeature[];
6
+ };
7
+
8
+ export default async function fetchGeoJSON(assetUrl: string): Promise<GeoJSON> {
9
+ try {
10
+ const response = await fetch(assetUrl);
11
+
12
+ if (!response.ok) {
13
+ throw new Error(`Failed to fetch GeoJSON: ${response.statusText}`);
14
+ }
15
+
16
+ const geojson = await response.json();
17
+ return geojson as GeoJSON;
18
+ } catch (e) {
19
+ throw e;
20
+ }
21
+ }