@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.
- package/LICENSE.txt +87 -0
- package/README.md +45 -2
- package/THIRD_PARTY.txt +296 -0
- package/dist/THIRD_PARTY.txt +288 -0
- package/dist/index.d.ts +264 -0
- package/dist/index.es.js +2 -0
- package/dist/index.es.js.map +1 -0
- package/dist/third-party.json +70 -0
- package/package.json +46 -3
|
@@ -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.
|
package/dist/index.d.ts
ADDED
|
@@ -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 };
|
package/dist/index.es.js
ADDED
|
@@ -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
|