@tomtom-org/maps-sdk-plugin-flyover 0.0.0-stage → 0.0.2

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.
@@ -0,0 +1,288 @@
1
+ The following third-party components are bundled into this package. Their licenses
2
+ are reproduced below.
3
+
4
+ Name: @turf/helpers
5
+ Version: 7.4.0
6
+ License: MIT
7
+ Bundled: true
8
+ Description: Provides helper functions to create GeoJSON features, like points, lines, or areas on a map.
9
+ Repository: git://github.com/Turfjs/turf.git
10
+ Homepage: https://github.com/Turfjs/turf
11
+ Author: Turf Authors
12
+ Contributors:
13
+ Tom MacWright <@tmcw>
14
+ Stefano Borghi <@stebogit>
15
+ Denis Carriere <@DenisCarriere>
16
+ William Nordmann <@wnordmann>
17
+ License Text:
18
+ ===
19
+
20
+ The MIT License (MIT)
21
+
22
+ Copyright (c) 2017 TurfJS
23
+
24
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
25
+ this software and associated documentation files (the "Software"), to deal in
26
+ the Software without restriction, including without limitation the rights to
27
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
28
+ the Software, and to permit persons to whom the Software is furnished to do so,
29
+ subject to the following conditions:
30
+
31
+ The above copyright notice and this permission notice shall be included in all
32
+ copies or substantial portions of the Software.
33
+
34
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
35
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
36
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
37
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
38
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
39
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
40
+
41
+
42
+
43
+ ---
44
+
45
+ Name: @turf/invariant
46
+ Version: 7.4.0
47
+ License: MIT
48
+ Bundled: true
49
+ Description: Lightweight utility for input validation and data extraction in Turf.js. Ensures GeoJSON inputs are in the correct format and extracts specific components like coordinates or geometries.
50
+ Repository: git://github.com/Turfjs/turf.git
51
+ Homepage: https://github.com/Turfjs/turf
52
+ Author: Turf Authors
53
+ Contributors:
54
+ Tom MacWright <@tmcw>
55
+ Denis Carriere <@DenisCarriere>
56
+ License Text:
57
+ ===
58
+
59
+ The MIT License (MIT)
60
+
61
+ Copyright (c) 2017 TurfJS
62
+
63
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
64
+ this software and associated documentation files (the "Software"), to deal in
65
+ the Software without restriction, including without limitation the rights to
66
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
67
+ the Software, and to permit persons to whom the Software is furnished to do so,
68
+ subject to the following conditions:
69
+
70
+ The above copyright notice and this permission notice shall be included in all
71
+ copies or substantial portions of the Software.
72
+
73
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
74
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
75
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
76
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
77
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
78
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
79
+
80
+
81
+
82
+ ---
83
+
84
+ Name: @turf/bearing
85
+ Version: 7.4.0
86
+ License: MIT
87
+ Bundled: true
88
+ Description: Takes two points and finds the geographic bearing between them.
89
+ Repository: git://github.com/Turfjs/turf.git
90
+ Homepage: https://github.com/Turfjs/turf
91
+ Author: Turf Authors
92
+ License Text:
93
+ ===
94
+
95
+ The MIT License (MIT)
96
+
97
+ Copyright (c) 2017 TurfJS
98
+
99
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
100
+ this software and associated documentation files (the "Software"), to deal in
101
+ the Software without restriction, including without limitation the rights to
102
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
103
+ the Software, and to permit persons to whom the Software is furnished to do so,
104
+ subject to the following conditions:
105
+
106
+ The above copyright notice and this permission notice shall be included in all
107
+ copies or substantial portions of the Software.
108
+
109
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
110
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
111
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
112
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
113
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
114
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
115
+
116
+
117
+
118
+ ---
119
+
120
+ Name: @turf/destination
121
+ Version: 7.4.0
122
+ License: MIT
123
+ Bundled: true
124
+ Description: turf destination module
125
+ Repository: git://github.com/Turfjs/turf.git
126
+ Homepage: https://github.com/Turfjs/turf
127
+ Author: Turf Authors
128
+ Contributors:
129
+ Pavel Rozvora <@prozvora>
130
+ License Text:
131
+ ===
132
+
133
+ The MIT License (MIT)
134
+
135
+ Copyright (c) 2017 TurfJS
136
+
137
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
138
+ this software and associated documentation files (the "Software"), to deal in
139
+ the Software without restriction, including without limitation the rights to
140
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
141
+ the Software, and to permit persons to whom the Software is furnished to do so,
142
+ subject to the following conditions:
143
+
144
+ The above copyright notice and this permission notice shall be included in all
145
+ copies or substantial portions of the Software.
146
+
147
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
148
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
149
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
150
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
151
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
152
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
153
+
154
+
155
+
156
+ --------------------------------------------------------------------------------
157
+
158
+ The following third-party components are declared as peer dependencies. Their code is
159
+ NOT bundled into this package: your package manager installs them alongside it and
160
+ your application bundles them. The licenses below apply to those copies, and each of
161
+ these components may in turn install its own dependencies under their own licenses.
162
+
163
+ Name: maplibre-gl
164
+ Version: 6.11.2
165
+ License: BSD-3-Clause
166
+ Bundled: false (peer dependency)
167
+ Description: BSD licensed community fork of mapbox-gl, a WebGL interactive maps library
168
+ Repository: https://github.com/maplibre/maplibre-gl-js
169
+ Homepage: https://maplibre.org/
170
+ License Text:
171
+ ===
172
+
173
+ Copyright (c) 2023, MapLibre contributors
174
+
175
+ All rights reserved.
176
+
177
+ Redistribution and use in source and binary forms, with or without modification,
178
+ are permitted provided that the following conditions are met:
179
+
180
+ * Redistributions of source code must retain the above copyright notice,
181
+ this list of conditions and the following disclaimer.
182
+ * Redistributions in binary form must reproduce the above copyright notice,
183
+ this list of conditions and the following disclaimer in the documentation
184
+ and/or other materials provided with the distribution.
185
+ * Neither the name of MapLibre GL JS nor the names of its contributors
186
+ may be used to endorse or promote products derived from this software
187
+ without specific prior written permission.
188
+
189
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
190
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
191
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
192
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
193
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
194
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
195
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
196
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
197
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
198
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
199
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
200
+
201
+
202
+ -------------------------------------------------------------------------------
203
+
204
+ Contains code from mapbox-gl-js v1.13 and earlier
205
+
206
+ Version v1.13 of mapbox-gl-js and earlier are licensed under a BSD-3-Clause license
207
+
208
+ Copyright (c) 2020, Mapbox
209
+ Redistribution and use in source and binary forms, with or without modification,
210
+ are permitted provided that the following conditions are met:
211
+
212
+ * Redistributions of source code must retain the above copyright notice,
213
+ this list of conditions and the following disclaimer.
214
+ * Redistributions in binary form must reproduce the above copyright notice,
215
+ this list of conditions and the following disclaimer in the documentation
216
+ and/or other materials provided with the distribution.
217
+ * Neither the name of Mapbox GL JS nor the names of its contributors
218
+ may be used to endorse or promote products derived from this software
219
+ without specific prior written permission.
220
+
221
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
222
+ "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
223
+ LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
224
+ A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
225
+ CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
226
+ EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
227
+ PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
228
+ PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
229
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
230
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
231
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
232
+
233
+
234
+ -------------------------------------------------------------------------------
235
+
236
+ Contains code from glfx.js
237
+
238
+ Copyright (C) 2011 by Evan Wallace
239
+
240
+ Permission is hereby granted, free of charge, to any person obtaining a copy
241
+ of this software and associated documentation files (the "Software"), to deal
242
+ in the Software without restriction, including without limitation the rights
243
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
244
+ copies of the Software, and to permit persons to whom the Software is
245
+ furnished to do so, subject to the following conditions:
246
+
247
+ The above copyright notice and this permission notice shall be included in
248
+ all copies or substantial portions of the Software.
249
+
250
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
251
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
252
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
253
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
254
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
255
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
256
+ THE SOFTWARE.
257
+
258
+ --------------------------------------------------------------------------------
259
+
260
+ Contains a portion of d3-color https://github.com/d3/d3-color
261
+
262
+ Copyright 2010-2016 Mike Bostock
263
+ All rights reserved.
264
+
265
+ Redistribution and use in source and binary forms, with or without modification,
266
+ are permitted provided that the following conditions are met:
267
+
268
+ * Redistributions of source code must retain the above copyright notice, this
269
+ list of conditions and the following disclaimer.
270
+
271
+ * Redistributions in binary form must reproduce the above copyright notice,
272
+ this list of conditions and the following disclaimer in the documentation
273
+ and/or other materials provided with the distribution.
274
+
275
+ * Neither the name of the author nor the names of contributors may be used to
276
+ endorse or promote products derived from this software without specific prior
277
+ written permission.
278
+
279
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
280
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
281
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
282
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
283
+ ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
284
+ (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
285
+ LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
286
+ ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
287
+ (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
288
+ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
@@ -0,0 +1,264 @@
1
+ import { CustomImage, SVGIconStyleOptions, TomTomMap } from "@tomtom-org/maps-sdk/map";
2
+ import { Route } from "@tomtom-org/maps-sdk/core";
3
+ //#region src/framing.d.ts
4
+ /**
5
+ * Where the position being followed sits in the view, as fractions of the viewport: `{ x: 0.5, y:
6
+ * 0.5 }` is the middle of the screen, `y: 0.67` two thirds of the way down.
7
+ *
8
+ * @group Flyover
9
+ */
10
+ type FlyoverAnchor = {
11
+ x: number;
12
+ y: number;
13
+ };
14
+ /**
15
+ * Where a camera at this pitch puts the position it follows, absent an anchor of your own.
16
+ *
17
+ * A level map is a plan, so the position belongs in the middle. Tilt the camera and the picture
18
+ * becomes mostly what lies *ahead*, so the position slides down with the pitch, reaching the lower
19
+ * third at 60° — and a top-down pass stays centred without switching modes.
20
+ *
21
+ * @group Flyover
22
+ */
23
+ export declare const anchorForPitch: (pitchDegrees: number) => FlyoverAnchor;
24
+ //#endregion
25
+ //#region src/marker.d.ts
26
+ /**
27
+ * The image that rides the route, drawn pointing up: the flight turns it to face the road.
28
+ *
29
+ * - `arrow` — the plugin's own arrow, recoloured with the SDK's SVG icon options. Its fill defaults
30
+ * to the SDK's default route outline colour, not a theme's accent, and its outline to white.
31
+ * - `custom` — yours: a URL, raw SVG markup, a data URI or a loaded `<img>`, as for any SDK custom
32
+ * image. A URL on another origin needs CORS, since the image becomes a WebGL texture.
33
+ *
34
+ * @group Flyover
35
+ */
36
+ type FlyoverMarkerImage = ({
37
+ type: 'arrow';
38
+ } & SVGIconStyleOptions) | {
39
+ type: 'custom';
40
+ image: NonNullable<CustomImage['image']>;
41
+ };
42
+ /**
43
+ * The marker that rides the route at the followed position, lying on the map and facing the road.
44
+ *
45
+ * @group Flyover
46
+ */
47
+ type FlyoverMarkerConfig = {
48
+ /** @default true */
49
+ visible?: boolean;
50
+ /** @default `{ type: 'arrow' }` */
51
+ image?: FlyoverMarkerImage;
52
+ /** Width and height on screen, in pixels, before the pitch foreshortens it. @default 44 */
53
+ size?: number;
54
+ };
55
+ //#endregion
56
+ //#region src/RouteFlyover.d.ts
57
+ /**
58
+ * What the camera points at, which is what decides how early it turns into a bend.
59
+ *
60
+ * - `distance` — a fixed distance down the road. Predictable, and blind to what the road does.
61
+ * - `points` — a number of the route's own vertices. The line is denser through bends, so the aim
62
+ * shortens exactly where the road is turning.
63
+ * - `instruction` — the next guidance instruction, so the camera looks at the junction it is
64
+ * heading for. Needs a route asked for with `guidance`; without instructions it aims by distance.
65
+ *
66
+ * @group Flyover
67
+ */
68
+ type FlyoverAim = {
69
+ mode: 'distance';
70
+ metersAhead: number;
71
+ } | {
72
+ mode: 'points';
73
+ pointsAhead: number;
74
+ } | {
75
+ mode: 'instruction';
76
+ fallbackMetersAhead: number;
77
+ };
78
+ /**
79
+ * How high the camera rides. Whatever the mode, it pulls back further where terrain would otherwise
80
+ * come between the camera and the road.
81
+ *
82
+ * - `fixed` — one MapLibre zoom, whatever the road does.
83
+ * - `instructions` — framed on the junctions ahead: the zoom that fits the next N instructions (one
84
+ * at least) in the view, so a run of hairpins pulls back and a straight closes in.
85
+ * - `speed` — tied to the ground speed, the way a driver's eyes lift with it.
86
+ *
87
+ * @group Flyover
88
+ */
89
+ type FlyoverZoom = {
90
+ mode: 'fixed';
91
+ zoom: number;
92
+ } | {
93
+ mode: 'instructions';
94
+ instructionsAhead: number;
95
+ } | {
96
+ mode: 'speed';
97
+ };
98
+ /**
99
+ * How the camera flies.
100
+ *
101
+ * @group Flyover
102
+ */
103
+ type FlyoverCamera = {
104
+ /** Ground speed of the camera, in kilometres per hour. @default 200 */
105
+ speedKMH: number;
106
+ /** Camera tilt, in degrees; the map's `maxPitch` is the ceiling. @default 70 */
107
+ pitch: number;
108
+ /** What the camera aims at down the route. @default `{ mode: 'instruction', fallbackMetersAhead: 250 }` */
109
+ aim: FlyoverAim;
110
+ /** What sets the camera's height. @default `{ mode: 'instructions', instructionsAhead: 2 }` */
111
+ zoom: FlyoverZoom;
112
+ /**
113
+ * Where the followed position sits on screen. Omitted, it follows the pitch — see
114
+ * {@link anchorForPitch}.
115
+ */
116
+ anchor?: FlyoverAnchor;
117
+ };
118
+ /**
119
+ * How far along the route the flight has got, reported as it advances.
120
+ *
121
+ * @group Flyover
122
+ */
123
+ type FlyoverProgress = {
124
+ traveledDistanceInMeters: number;
125
+ traveledTimeInSeconds: number;
126
+ };
127
+ /**
128
+ * @group Flyover
129
+ */
130
+ type RouteFlyoverOptions = {
131
+ /** The route to fly. Replace it later with {@link RouteFlyover.setRoute}. */
132
+ route: Route;
133
+ /** Overrides for the camera; anything left out takes the default on {@link FlyoverCamera}. */
134
+ camera?: Partial<FlyoverCamera>;
135
+ /** The marker riding the route at the followed position; an arrow by default. */
136
+ marker?: FlyoverMarkerConfig;
137
+ /** Called with the flight's progress, once per survey rather than once per frame. */
138
+ onProgress?: (progress: FlyoverProgress) => void;
139
+ };
140
+ /**
141
+ * A camera that flies a route on a loop: it advances a distance along the line every frame, reads
142
+ * the coordinate the route has at that distance, and points itself at where it will be next.
143
+ *
144
+ * @remarks
145
+ * The route is the only geometry it needs — no path of camera keyframes to author, and no
146
+ * animation to re-time when the route changes. What it adds on top of following the line:
147
+ *
148
+ * - **it aims ahead** rather than at its own position, by distance, by route vertices or at the
149
+ * next guidance instruction, so the view turns into a bend before the camera reaches it;
150
+ * - **it frames** what is coming: the zoom that fits the next junctions, or one tied to the speed;
151
+ * - **it clears the ground**, pulling back where terrain would come between the camera and the road;
152
+ * - **it parks the position where you want it on screen** — see {@link FlyoverAnchor} — and marks
153
+ * it with an arrow, or an image of your own, facing the road;
154
+ * - **it moves like a camera**: every value it changes eases on a critically damped spring, so a new
155
+ * heading, zoom or setting bends the motion rather than kicking it, and a start ramps the speed.
156
+ *
157
+ * While it runs, the flight owns the altitude of the point the camera looks at — the ground under
158
+ * the followed position — so it takes MapLibre off clamping the centre to the ground, and gives
159
+ * that back when it stops.
160
+ *
161
+ * @example
162
+ * ```typescript
163
+ * import { RouteFlyover } from '@tomtom-org/maps-sdk-plugin-flyover';
164
+ *
165
+ * const [route] = (await calculateRoute({ locations, guidance: { type: 'coded' } })).features;
166
+ * const flyover = new RouteFlyover(map, { route, camera: { speedKMH: 300, pitch: 76 } });
167
+ * flyover.start();
168
+ * ```
169
+ *
170
+ * @group Flyover
171
+ */
172
+ export declare class RouteFlyover {
173
+ private readonly map;
174
+ private route;
175
+ private camera;
176
+ private readonly onProgress;
177
+ private readonly marker;
178
+ private animationFrame;
179
+ private lastFrameTime;
180
+ private traveledDistanceInMeters;
181
+ private speedKMH;
182
+ private motion;
183
+ private readonly target;
184
+ private framedZoom;
185
+ private secondsSinceSurvey;
186
+ private viewport;
187
+ private flying;
188
+ private pageCenterClampedToGround;
189
+ private pagePadding;
190
+ constructor(map: TomTomMap, options: RouteFlyoverOptions);
191
+ /** Whether the flight is advancing. */
192
+ get running(): boolean;
193
+ /** Starts, or resumes, the flight, ramping up to its speed. */
194
+ start(): void;
195
+ /**
196
+ * Stops the flight where it is; {@link start} resumes from there. The centre clamp goes back to
197
+ * what the map had before {@link start}.
198
+ */
199
+ stop(): void;
200
+ /** Puts a new route under the flight, from its departure point. */
201
+ setRoute(route: Route): void;
202
+ /** Applies camera settings — speed, pitch, aim, framing, anchor — paused or under way. */
203
+ setCamera(camera: Partial<FlyoverCamera>): void;
204
+ /** The camera the flight is using, including the defaults it was not given. */
205
+ getCamera(): FlyoverCamera;
206
+ /** Replaces the marker riding the route, or hides it with `visible: false`. */
207
+ setMarker(marker: FlyoverMarkerConfig): void;
208
+ /** Moves the flight to a point along the route, as a share of its length within 0..1. */
209
+ seek(fraction: number): void;
210
+ /**
211
+ * Stops the flight and gives the map back: the marker leaves, and the padding returns to what
212
+ * the map had before the flight first placed the camera.
213
+ */
214
+ remove(): void;
215
+ private readonly readViewport;
216
+ private routeLengthInMeters;
217
+ private readonly step;
218
+ private coordinateAt;
219
+ private positionAt;
220
+ private wrapped;
221
+ private roadHeading;
222
+ private instructions;
223
+ /**
224
+ * The instruction the flight is heading for — the first one still ahead of it, and the first of
225
+ * all once the loop has passed the last. `undefined` when the route carries no guidance.
226
+ */
227
+ private instructionAhead;
228
+ private pointIndexHere;
229
+ /** Where the camera looks: the point the current {@link FlyoverAim} picks out. */
230
+ private aimPosition;
231
+ /** The zoom the current {@link FlyoverZoom} asks for at this point of the route. */
232
+ private modeZoom;
233
+ /**
234
+ * The closest zoom at which nothing between the camera and the road stands higher than the line
235
+ * of sight.
236
+ *
237
+ * The camera trails the road along the bearing, so its ground track is sampled from under the
238
+ * camera towards the followed position. A sample a share `t` of the way along needs the camera
239
+ * `(ground − road) / (1 − t)` higher than the road, on top of a clearance that narrows the same
240
+ * way — which puts the camera itself `CLEARANCE_METERS` over the ground beneath it.
241
+ */
242
+ private clearanceZoom;
243
+ private groundAt;
244
+ /**
245
+ * Where the camera is going: the heading the road asks for, the zoom the framing and the
246
+ * terrain allow, and the ground the followed position is on.
247
+ *
248
+ * Everything in here costs a walk of the route or a question to the terrain, and none of it is
249
+ * worth asking every frame — see {@link SURVEY_INTERVAL_SECONDS}.
250
+ */
251
+ private survey;
252
+ private targetAnchor;
253
+ private ease;
254
+ private settle;
255
+ private placeMarkerOutright;
256
+ /**
257
+ * One frame: where the flight has got to, and a step of the camera towards what the last survey
258
+ * decided. Without `elapsedSeconds` — a seek, a new route, a changed setting — the camera is
259
+ * surveyed and placed at its targets outright.
260
+ */
261
+ private placeCamera;
262
+ }
263
+ //#endregion
264
+ export type { FlyoverAim, FlyoverAnchor, FlyoverCamera, FlyoverMarkerConfig, FlyoverMarkerImage, FlyoverProgress, FlyoverZoom, RouteFlyoverOptions };
@@ -0,0 +1,2 @@
1
+ import{calculateProgressAtRoutePoint as e,generateId as t,getCoordinateAtRouteProgress as r}from"@tomtom-org/maps-sdk/core";import{ROUTE_LINE_OUTLINE_COLOR as i}from"@tomtom-org/maps-sdk/map";import{MercatorCoordinate as a}from"maplibre-gl";var n=6371008.8,o={centimeters:637100880,centimetres:637100880,cm:637100880,degrees:360/(2*Math.PI),deg:360/(2*Math.PI),feet:20902260.511392,ft:20902260.511392,inches:39.37*n,in:39.37*n,kilometers:6371.0088,kilometres:6371.0088,km:6371.0088,meters:n,metres:n,m:n,miles:3958.761333810546,mi:3958.761333810546,millimeters:6371008800,millimetres:6371008800,mm:6371008800,nauticalmiles:n/1852,nmi:n/1852,radians:1,rad:1,yards:6967335.223679999,yd:6967335.223679999};function s(e,t,r={}){if(!e)throw new Error("coordinates is required");if(!Array.isArray(e))throw new Error("coordinates must be an Array");if(e.length<2)throw new Error("coordinates must be at least 2 numbers long");if(!c(e[0])||!c(e[1]))throw new Error("coordinates must contain numbers");return function(e,t,r={}){const i={type:"Feature"};return(0===r.id||r.id)&&(i.id=r.id),r.bbox&&(i.bbox=r.bbox),i.properties=t||{},i.geometry=e,i}({type:"Point",coordinates:e},t,r)}function h(e){return e%(2*Math.PI)*180/Math.PI}function m(e){return e%360*Math.PI/180}function c(e){return!isNaN(e)&&null!==e&&!Array.isArray(e)}function d(e){if(!e)throw new Error("coord is required");if(!Array.isArray(e)){if("Feature"===e.type&&null!==e.geometry&&"Point"===e.geometry.type)return[...e.geometry.coordinates];if("Point"===e.type)return[...e.coordinates]}if(Array.isArray(e)&&e.length>=2&&!Array.isArray(e[0])&&!Array.isArray(e[1]))return[...e];throw new Error("coord must be GeoJSON Point or an Array of numbers")}function u(e,t,r={}){if(!0===r.final)return function(e,t){let r=u(t,e);return r=(r+180)%360,r>180?r-360:r}(e,t);const i=d(e),a=d(t),n=m(i[0]),o=m(a[0]),s=m(i[1]),c=m(a[1]),g=Math.sin(o-n)*Math.cos(c),l=Math.cos(s)*Math.sin(c)-Math.sin(s)*Math.cos(c)*Math.cos(o-n);return h(Math.atan2(g,l))}function g(e,t,r,i={}){const a=d(e),n=m(a[0]),c=m(a[1]),u=m(r),g=function(e,t="kilometers"){const r=o[t];if(!r)throw new Error(t+" units is invalid");return e/r}(t,i.units),l=Math.asin(Math.sin(c)*Math.cos(g)+Math.cos(c)*Math.sin(g)*Math.cos(u)),p=h(n+Math.atan2(Math.sin(u)*Math.sin(g)*Math.cos(c),Math.cos(g)-Math.sin(c)*Math.sin(l))),v=h(l);return void 0!==a[2]?s([p,v,a[2]],i.properties):s([p,v],i.properties)}var l=(e,t)=>function(e){let t=e%360;return t<0&&(t+=360),t}(u(e,t)),p=(e,t)=>(t-e+540)%360-180,v=(e,t,r)=>Math.min(Math.max(e,t),r),M=e=>({value:e,velocity:0}),f=1e-6,y=(e,t,r,i,a=Number.POSITIVE_INFINITY)=>{const n=4/i,o=2*a/n,s=v(e.value-t,-o,o);if(Math.abs(s)<f&&Math.abs(e.velocity)<f)return M(t);const h=(e.velocity+n*s)*r,m=Math.exp(-n*r);return{value:e.value-s+(s+h)*m,velocity:(e.velocity-n*h)*m}},A=(e,t,r,i,a)=>{const n=y(e,e.value+p(e.value,t),r,i,a);return{value:(n.value+360)%360,velocity:n.velocity}},w=e=>v(e,.05,.95),T=e=>({x:.5,y:.5+v(e,0,60)/60*.16666666666666663}),E=(e,t)=>{const r=w(e.x)-.5,i=w(e.y)-.5,a=(e,t)=>Math.max(2*e*t,0);return{left:a(r,t.width),right:a(-r,t.width),top:a(i,t.height),bottom:a(-i,t.height)}},b=40075016.686/512,x=(e,t)=>Math.log2(b*Math.cos(m(t))/e),_=({viewportHeight:e,fieldOfViewDegrees:t})=>.5*e/Math.tan(m(t)/2),I=(e,t)=>_(t)*((e,t)=>b*Math.cos(m(t))/2**e)(e,t.latitudeDegrees),R=(e,t)=>{const r=document.createElementNS("http://www.w3.org/2000/svg",e);for(const[i,a]of Object.entries(t))r.setAttribute(i,a);return r},L=e=>`data:image/svg+xml;charset=utf-8,${encodeURIComponent(e)}`,P=(e,t)=>{const r="arrow"===e.type?L((({fillColor:e=i,outlineColor:t="white",outlineOpacity:r=1},a)=>{const n=R("svg",{viewBox:"0 0 24 24",width:String(a),height:String(a)});return n.append(R("path",{d:"M12 3l8 18-8-4-8 4z",fill:e,stroke:t,"stroke-opacity":String(r),"stroke-width":"3","stroke-linejoin":"round","paint-order":"stroke"})),(new XMLSerializer).serializeToString(n)})(e,t)):e.image;if("string"!=typeof r)return r;const a=new Image;return a.crossOrigin="anonymous",a.src=r.includes("<svg")?L(r):r,a},k=(e,t,r)=>{const i=e.createShader(t);if(!i)throw new Error("The fly-over marker could not create a shader");return e.shaderSource(i,r),e.compileShader(i),i},D=class{map;id=`tomtom-flyover-marker-${t()}`;type="custom";renderingMode="2d";config={};placed;raster;gl;drawing;removed=!1;stopRestoring;constructor(e,t){this.map=e,this.stopRestoring=e.addStyleChangeHandler({onStyleChanged:()=>this.install()}),this.installWhenReady(),this.apply(t)}apply(e){this.config=e;const t=e.size??44;var r;(async(e,t)=>{const r=P(e,t);await r.decode();const i=document.createElement("canvas");i.width=t,i.height=t;const a=t/Math.max(r.naturalWidth,r.naturalHeight,1),[n,o]=[r.naturalWidth*a,r.naturalHeight*a];return i.getContext("2d")?.drawImage(r,(t-n)/2,(t-o)/2,n,o),i})(e.image??{type:"arrow"},(r=t,Math.min(2**Math.ceil(Math.log2(Math.max(r*devicePixelRatio,1))),512))).then(t=>{this.config===e&&(this.raster=t,this.releaseTexture(),this.map.mapLibreMap.triggerRepaint())}).catch(e=>console.warn("The fly-over marker image could not be loaded",e)),this.map.mapLibreMap.triggerRepaint()}place(e,t){this.placed={position:e,heading:t},this.map.mapLibreMap.triggerRepaint()}remove(){this.removed=!0,this.stopRestoring(),this.map.mapLibreMap.getLayer(this.id)&&this.map.mapLibreMap.removeLayer(this.id)}onAdd(e,t){this.gl=t,this.drawing=(e=>{const t=e.createProgram(),r=e.createBuffer();if(!t||!r)throw new Error("The fly-over marker could not create its program");return e.attachShader(t,k(e,e.VERTEX_SHADER,"\nuniform mat4 u_matrix;\nuniform vec2 u_right;\nuniform vec2 u_forward;\nattribute vec2 a_corner;\nvarying vec2 v_uv;\nvoid main() {\n v_uv = vec2(a_corner.x, -a_corner.y) * 0.5 + 0.5;\n gl_Position = u_matrix * vec4(u_right * a_corner.x + u_forward * a_corner.y, 0.0, 1.0);\n}")),e.attachShader(t,k(e,e.FRAGMENT_SHADER,"\nprecision mediump float;\nuniform sampler2D u_image;\nvarying vec2 v_uv;\nvoid main() {\n gl_FragColor = texture2D(u_image, v_uv);\n}")),e.linkProgram(t),e.bindBuffer(e.ARRAY_BUFFER,r),e.bufferData(e.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,1,1]),e.STATIC_DRAW),{program:t,corners:r,texture:void 0,uniforms:{matrix:e.getUniformLocation(t,"u_matrix"),right:e.getUniformLocation(t,"u_right"),forward:e.getUniformLocation(t,"u_forward"),image:e.getUniformLocation(t,"u_image")},corner:e.getAttribLocation(t,"a_corner")}})(t)}onRemove(e,t){this.releaseTexture(),this.drawing&&(t.deleteProgram(this.drawing.program),t.deleteBuffer(this.drawing.corners)),this.drawing=void 0,this.gl=void 0}render(e,t){const{drawing:r,placed:i,raster:n}=this;if(!r||!i||!n||!1===this.config.visible)return;r.texture??=((e,t)=>{const r=e.createTexture()??void 0;return e.bindTexture(e.TEXTURE_2D,r??null),e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!0),e.texImage2D(e.TEXTURE_2D,0,e.RGBA,e.RGBA,e.UNSIGNED_BYTE,t),e.pixelStorei(e.UNPACK_PREMULTIPLY_ALPHA_WEBGL,!1),e.generateMipmap(e.TEXTURE_2D),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR_MIPMAP_LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),r})(e,n);const o=this.map.mapLibreMap,[s,h]=i.position,c=o.queryTerrainElevation([s,h])??0,d=a.fromLngLat([s,h],c),u=(this.config.size??44)/2*(1/(512*2**o.getZoom()));const g=m(i.heading),[l,p]=[Math.sin(g)*u,Math.cos(g)*u];e.useProgram(r.program),e.uniformMatrix4fv(r.uniforms.matrix,!1,((e,{x:t,y:r,z:i})=>{const a=Float32Array.from(e);for(let n=0;n<4;n++)a[12+n]=e[n]*t+e[4+n]*r+e[8+n]*i+e[12+n];return a})(t.defaultProjectionData.mainMatrix,d)),e.uniform2f(r.uniforms.right,p,l),e.uniform2f(r.uniforms.forward,l,-p),e.activeTexture(e.TEXTURE0),e.bindTexture(e.TEXTURE_2D,r.texture??null),e.uniform1i(r.uniforms.image,0),e.bindBuffer(e.ARRAY_BUFFER,r.corners),e.enableVertexAttribArray(r.corner),e.vertexAttribPointer(r.corner,2,e.FLOAT,!1,0,0),e.disable(e.DEPTH_TEST),e.enable(e.BLEND),e.blendFunc(e.ONE,e.ONE_MINUS_SRC_ALPHA),e.drawArrays(e.TRIANGLE_STRIP,0,4)}releaseTexture(){this.drawing?.texture&&this.gl?.deleteTexture(this.drawing.texture),this.drawing&&(this.drawing.texture=void 0)}installWhenReady(){this.map.mapReady?this.install():this.map.mapLibreMap.once("styledata",()=>this.installWhenReady())}install(){this.removed||this.map.mapLibreMap.getLayer(this.id)||this.map.mapLibreMap.addLayer(this)}},H={speedKMH:200,pitch:70,aim:{mode:"instruction",fallbackMetersAhead:250},zoom:{mode:"instructions",instructionsAhead:2}},S=2,C=2,F=3,U=1.5,z=1.5,N=.6,X=.5,O=15,G=e=>v(e,11,15),B=class{map;route;camera;onProgress;marker;animationFrame;lastFrameTime=0;traveledDistanceInMeters=0;speedKMH=M(0);motion;target;framedZoom;secondsSinceSurvey=0;viewport={width:1,height:1};flying=!1;pageCenterClampedToGround=!0;pagePadding;constructor(e,t){this.map=e,this.route=t.route,this.camera={...H,...t.camera},this.onProgress=t.onProgress??(()=>{});const r=e.mapLibreMap,i=this.targetAnchor();this.motion={bearing:M(r.getBearing()),zoom:M(r.getZoom()),pitch:M(r.getPitch()),anchorX:M(i.x),anchorY:M(i.y),elevation:M(r.getCenterElevation()),markerHeading:M(0)},this.target={bearing:this.motion.bearing.value,zoom:this.motion.zoom.value,elevation:this.motion.elevation.value,markerHeading:0},this.framedZoom=this.target.zoom,this.readViewport(),r.on("resize",this.readViewport),this.marker=new D(e,t.marker??{}),this.placeMarkerOutright()}get running(){return void 0!==this.animationFrame}start(){if(this.running)return;const e=this.map.mapLibreMap;this.pageCenterClampedToGround=e.getCenterClampedToGround(),e.setCenterClampedToGround(!1),this.speedKMH=M(0),this.lastFrameTime=performance.now(),this.animationFrame=requestAnimationFrame(this.step)}stop(){void 0!==this.animationFrame&&(cancelAnimationFrame(this.animationFrame),this.animationFrame=void 0,this.map.mapLibreMap.setCenterClampedToGround(this.pageCenterClampedToGround))}setRoute(e){this.route=e,this.traveledDistanceInMeters=0,this.flying=!1,this.running?this.placeCamera():this.placeMarkerOutright()}setCamera(e){this.camera={...this.camera,...e},this.flying&&!this.running&&this.placeCamera()}getCamera(){return{...this.camera}}setMarker(e){this.marker.apply(e)}seek(e){this.traveledDistanceInMeters=this.routeLengthInMeters()*v(e,0,1),this.placeCamera()}remove(){this.stop(),this.marker.remove();const e=this.map.mapLibreMap;e.off("resize",this.readViewport),this.pagePadding&&e.setPadding(this.pagePadding)}readViewport=()=>{const e=this.map.mapLibreMap.getCanvas();this.viewport={width:Math.max(e.clientWidth,1),height:Math.max(e.clientHeight,1)}};routeLengthInMeters(){return this.route.properties.summary.lengthInMeters}step=e=>{const t=v((e-this.lastFrameTime)/1e3,0,.25);this.lastFrameTime=e;const r=this.speedKMH.value;this.speedKMH=y(this.speedKMH,this.camera.speedKMH,t,S);const i=(r+this.speedKMH.value)/2/3.6;this.traveledDistanceInMeters=this.wrapped(this.traveledDistanceInMeters+i*t),this.placeCamera(t),this.animationFrame=requestAnimationFrame(this.step)};coordinateAt(e){return r(this.route,{traveledDistanceInMeters:e})}positionAt(e){return this.coordinateAt(this.wrapped(this.traveledDistanceInMeters+e))?.position}wrapped(e){const t=this.routeLengthInMeters();return t>0?(e%t+t)%t:0}roadHeading(){const[e,t]=[-15,O].map(e=>this.coordinateAt(this.traveledDistanceInMeters+e)?.position);return e&&t?l(e,t):void 0}instructions(){return this.route.properties.guidance?.instructions??[]}instructionAhead(e=0){const t=this.instructions();if(!t.length)return;const r=t.findIndex(e=>e.routeOffsetInMeters>this.traveledDistanceInMeters);return t[Math.min((-1===r?0:r)+e,t.length-1)]}pointIndexHere(){let t=0,r=this.route.geometry.coordinates.length-1;for(;t<r;){const i=Math.floor((t+r)/2),a=e(this.route,i);void 0!==a&&a.distanceInMeters<this.traveledDistanceInMeters?t=i+1:r=i}return t}aimPosition(){const e=this.camera.aim;switch(e.mode){case"distance":return this.positionAt(e.metersAhead);case"points":{const t=this.route.geometry.coordinates;return t[(this.pointIndexHere()+e.pointsAhead)%t.length]}case"instruction":{const t=this.instructionAhead(),r=t&&this.wrapped(t.routeOffsetInMeters-this.traveledDistanceInMeters);return void 0===r?this.positionAt(e.fallbackMetersAhead):this.positionAt(r)}}}modeZoom(e){const t=this.camera.zoom;if("fixed"===t.mode)return t.zoom;if("speed"===t.mode){const e=Math.log2(Math.max(this.camera.speedKMH,1)/90);return G(14-1*e)}const r=this.instructionAhead(Math.max(t.instructionsAhead,1)-1);if(!r)return G(14);const i=this.wrapped(r.routeOffsetInMeters-this.traveledDistanceInMeters)*Math.cos(m(Math.min(this.camera.pitch,85)));return G(((e,t,r)=>x(Math.max(e,1)/Math.max(t,1),r))(i,.6*this.viewport.height,e))}clearanceZoom(e,t,r){const i=m(Math.min(this.camera.pitch,85)),a=I(this.motion.zoom.value,r)*Math.sin(i)/1e3,n=this.motion.bearing.value+180;let o=200;for(let s=0;s<4;s++){const r=s/4,i=g(e,a*(1-r),n).geometry.coordinates,h=this.groundAt(i);void 0!==h&&(o=Math.max(o,200+(h-t)/(1-r)))}return((e,t)=>x(Math.max(e,1)/_(t),t.latitudeDegrees))(o/Math.cos(i),r)}groundAt([e,t]){return this.map.mapLibreMap.queryTerrainElevation([e,t])??void 0}survey(e){const t={latitudeDegrees:e[1],viewportHeight:this.viewport.height,fieldOfViewDegrees:this.map.mapLibreMap.getVerticalFieldOfView()},r=this.aimPosition();r&&(this.target.bearing=((e,t,r)=>Math.abs(p(e,t))>r?t:e)(this.target.bearing,l(e,r),2.5)),this.target.markerHeading=this.roadHeading()??this.target.markerHeading;const i=this.modeZoom(t.latitudeDegrees),a="instructions"===this.camera.zoom.mode?.2:0;Math.abs(i-this.framedZoom)>a&&(this.framedZoom=i);const n=this.groundAt(e);void 0===n?(this.map.mapLibreMap.getTerrain()||(this.target.elevation=0),this.target.zoom=this.framedZoom):(this.target.elevation=n,this.target.zoom=Math.min(this.framedZoom,this.clearanceZoom(e,n,t)))}targetAnchor(){return this.camera.anchor??T(this.camera.pitch)}ease(e){const{motion:t,target:r}=this,i=this.targetAnchor(),a=(t,r,i)=>y(t,r,e,i);this.motion={bearing:A(t.bearing,r.bearing,e,C,22),markerHeading:A(t.markerHeading,r.markerHeading,e,X),zoom:a(t.zoom,r.zoom,F),elevation:a(t.elevation,r.elevation,N),pitch:a(t.pitch,this.camera.pitch,U),anchorX:a(t.anchorX,i.x,z),anchorY:a(t.anchorY,i.y,z)}}settle(){const e=this.targetAnchor();this.motion={bearing:M(this.target.bearing),markerHeading:M(this.target.markerHeading),zoom:M(this.target.zoom),elevation:M(this.target.elevation),pitch:M(this.camera.pitch),anchorX:M(e.x),anchorY:M(e.y)}}placeMarkerOutright(){const e=this.positionAt(0);this.target.markerHeading=this.roadHeading()??this.target.markerHeading,this.motion.markerHeading=M(this.target.markerHeading),e&&this.marker.place(e,this.target.markerHeading)}placeCamera(e){const t=this.coordinateAt(this.traveledDistanceInMeters);if(!t)return;const r=void 0!==e&&this.flying;this.secondsSinceSurvey+=e??0;const i=!r||this.secondsSinceSurvey>=.2;i&&(this.secondsSinceSurvey=0,this.survey(t.position)),r?this.ease(e):this.settle(),this.flying=!0;const[a,n]=t.position,{bearing:o,zoom:s,pitch:h,elevation:m,anchorX:c,anchorY:d,markerHeading:u}=this.motion,g=this.map.mapLibreMap;this.pagePadding??=g.getPadding(),g.jumpTo({center:[a,n],elevation:m.value,bearing:o.value,pitch:h.value,zoom:s.value,padding:E({x:c.value,y:d.value},this.viewport)}),this.marker.place(t.position,u.value),i&&this.onProgress({traveledDistanceInMeters:t.distanceInMeters,traveledTimeInSeconds:t.travelTimeInSeconds})}};export{B as RouteFlyover,T as anchorForPitch};
2
+ //# sourceMappingURL=index.es.js.map