teda-weather 0.1.0
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/README.md +15 -0
- package/dist/chunk-Q5XX75AN.js +534 -0
- package/dist/chunk-ROJRWJ7L.js +534 -0
- package/dist/chunk-Y3HFQZGE.js +2434 -0
- package/dist/decode-strategy-CPjhurHK.d.ts +396 -0
- package/dist/index.d.ts +29 -0
- package/dist/index.js +89 -0
- package/dist/mapbox-client-8dEJk9Xd.d.ts +93 -0
- package/dist/mapbox.d.ts +6 -0
- package/dist/mapbox.js +40 -0
- package/dist/maplibre-client-C5P9RIuy.d.ts +93 -0
- package/dist/maplibre.d.ts +6 -0
- package/dist/maplibre.js +40 -0
- package/fixtures/compat/README.md +7 -0
- package/fixtures/compat/scenarios/bounded-colormap.json +49 -0
- package/fixtures/compat/scenarios/feather.json +58 -0
- package/fixtures/compat/scenarios/particle-image.json +63 -0
- package/fixtures/compat/scenarios/particle-json.json +94 -0
- package/fixtures/compat/scenarios/point-query.json +61 -0
- package/fixtures/compat/scenarios/tiled-colormap.json +46 -0
- package/package.json +43 -0
package/README.md
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
# teda-weather
|
|
2
|
+
|
|
3
|
+
Standalone TypeScript library scaffold for the teda-weather runtime adapters.
|
|
4
|
+
|
|
5
|
+
Compatibility baseline fixtures live under `fixtures/compat/` and capture acceptance-ready public contract payloads.
|
|
6
|
+
|
|
7
|
+
## Migration from `visual-sdk`
|
|
8
|
+
|
|
9
|
+
Use `teda-weather` as the standalone replacement for the old `visual-sdk` runtime entry surface.
|
|
10
|
+
|
|
11
|
+
- `Client` is now a shared, non-instantiable base class only. Do not call `new Client()`.
|
|
12
|
+
- Real integrations must use the engine-specific entrypoints:
|
|
13
|
+
- `import { MapboxClient } from "teda-weather/mapbox"`
|
|
14
|
+
- `import { MapLibreClient } from "teda-weather/maplibre"`
|
|
15
|
+
- Unsupported legacy adapters and facade-style compatibility shims are not included in the first phase.
|
|
@@ -0,0 +1,534 @@
|
|
|
1
|
+
import {
|
|
2
|
+
Client,
|
|
3
|
+
ColormapLayer,
|
|
4
|
+
ColormapTileLayer,
|
|
5
|
+
FeatherLayer,
|
|
6
|
+
ParticleAnimationLayer,
|
|
7
|
+
createCanvasOverlay,
|
|
8
|
+
mountCanvasOverlay,
|
|
9
|
+
syncCanvasLikeData,
|
|
10
|
+
syncCanvasOverlaySize,
|
|
11
|
+
unmountCanvasOverlay
|
|
12
|
+
} from "./chunk-Y3HFQZGE.js";
|
|
13
|
+
|
|
14
|
+
// src/adapters/maplibre/maplibre-client.ts
|
|
15
|
+
var mountIdSequence = 0;
|
|
16
|
+
var MapLibreClient = class extends Client {
|
|
17
|
+
constructor() {
|
|
18
|
+
super(...arguments);
|
|
19
|
+
this.defaultOptionsEnabled = false;
|
|
20
|
+
this.cleanupHandles = [];
|
|
21
|
+
this.destroyed = false;
|
|
22
|
+
}
|
|
23
|
+
useDefault(value) {
|
|
24
|
+
this.assertNotDestroyed();
|
|
25
|
+
if (typeof value === "boolean") {
|
|
26
|
+
this.defaultOptionsEnabled = value;
|
|
27
|
+
}
|
|
28
|
+
if (typeof value === "undefined" || this.defaultOptionsEnabled) {
|
|
29
|
+
this.ensureDefaultLayers();
|
|
30
|
+
}
|
|
31
|
+
return this.defaultOptionsEnabled;
|
|
32
|
+
}
|
|
33
|
+
setColorMapTileOption(option) {
|
|
34
|
+
this.assertNotDestroyed();
|
|
35
|
+
this.ensureDefaultLayers();
|
|
36
|
+
this.colorMapTileLayer?.setOption(option);
|
|
37
|
+
}
|
|
38
|
+
clearColorMapTile() {
|
|
39
|
+
this.assertNotDestroyed();
|
|
40
|
+
this.ensureDefaultLayers();
|
|
41
|
+
const layer = this.colorMapTileLayer;
|
|
42
|
+
const canvas = layer?.overlay.canvas;
|
|
43
|
+
if (!canvas) {
|
|
44
|
+
return;
|
|
45
|
+
}
|
|
46
|
+
layer?.source?.clear?.();
|
|
47
|
+
canvas.data = new Uint8ClampedArray(canvas.width * canvas.height * 4);
|
|
48
|
+
syncCanvasLikeData(canvas);
|
|
49
|
+
delete layer?.source;
|
|
50
|
+
}
|
|
51
|
+
getColorMapTileCanvas() {
|
|
52
|
+
this.assertNotDestroyed();
|
|
53
|
+
this.ensureDefaultLayers();
|
|
54
|
+
return this.colorMapTileLayer?.overlay.canvas;
|
|
55
|
+
}
|
|
56
|
+
setColorMapOption(option) {
|
|
57
|
+
this.assertNotDestroyed();
|
|
58
|
+
this.ensureDefaultLayers();
|
|
59
|
+
this.colorMapLayer?.setOption(option);
|
|
60
|
+
}
|
|
61
|
+
getColorMapCanvas() {
|
|
62
|
+
this.assertNotDestroyed();
|
|
63
|
+
this.ensureDefaultLayers();
|
|
64
|
+
return this.colorMapLayer?.overlay.canvas;
|
|
65
|
+
}
|
|
66
|
+
decodeColorMapTile(pixel, extent, worldZoom) {
|
|
67
|
+
this.assertNotDestroyed();
|
|
68
|
+
this.ensureDefaultLayers();
|
|
69
|
+
if (!this.colorMapTileLayer?.source) {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
return this.colorMapTileLayer?.decodeFromCanvasPixel(
|
|
73
|
+
pixel,
|
|
74
|
+
extent,
|
|
75
|
+
worldZoom
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
decodeColorMapTileValue(pixel, extent, worldZoom) {
|
|
79
|
+
return this.decodeColorMapTile(pixel, extent, worldZoom);
|
|
80
|
+
}
|
|
81
|
+
decodeColorMapTileValueByLngLat(lngLat, worldZoom) {
|
|
82
|
+
this.assertNotDestroyed();
|
|
83
|
+
this.ensureDefaultLayers();
|
|
84
|
+
if (!this.colorMapTileLayer?.source) {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
return this.colorMapTileLayer?.source?.decodeTextByLngLat(
|
|
88
|
+
lngLat,
|
|
89
|
+
worldZoom
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
initColorMapTileLayer(map, mapDiv, layerConfig) {
|
|
93
|
+
this.assertNotDestroyed();
|
|
94
|
+
if (this.tileMount) {
|
|
95
|
+
this.ensureMountedResources(this.tileMount, layerConfig);
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
const mountedLayer = this.mountTileLayer(map, mapDiv, layerConfig);
|
|
99
|
+
this.colorMapTileLayer = mountedLayer.layer;
|
|
100
|
+
this.tileMount = mountedLayer;
|
|
101
|
+
}
|
|
102
|
+
initColorMapLayer(map, mapDiv, layerConfig) {
|
|
103
|
+
this.assertNotDestroyed();
|
|
104
|
+
if (this.colorMount) {
|
|
105
|
+
this.ensureMountedResources(this.colorMount, layerConfig);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const mountedLayer = this.mountColorLayer(map, mapDiv, layerConfig);
|
|
109
|
+
this.colorMapLayer = mountedLayer.layer;
|
|
110
|
+
this.colorMount = mountedLayer;
|
|
111
|
+
}
|
|
112
|
+
initParticleLayer(map, mapDiv, layerConfig) {
|
|
113
|
+
this.assertNotDestroyed();
|
|
114
|
+
if (this.particleMount) {
|
|
115
|
+
this.ensureMountedResources(this.particleMount, layerConfig);
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const mountedLayer = this.mountParticleLayer(map, mapDiv, layerConfig);
|
|
119
|
+
this.particleLayer = mountedLayer.layer;
|
|
120
|
+
this.particleMount = mountedLayer;
|
|
121
|
+
}
|
|
122
|
+
initFeatherLayer(map, mapDiv, layerConfig) {
|
|
123
|
+
this.assertNotDestroyed();
|
|
124
|
+
if (this.featherMount) {
|
|
125
|
+
this.ensureMountedResources(this.featherMount, layerConfig);
|
|
126
|
+
return;
|
|
127
|
+
}
|
|
128
|
+
const mountedLayer = this.mountFeatherLayer(map, mapDiv, layerConfig);
|
|
129
|
+
this.featherLayer = mountedLayer.layer;
|
|
130
|
+
this.featherMount = mountedLayer;
|
|
131
|
+
}
|
|
132
|
+
renderColorMapTileFunction(map = this.tileMount?.map, mapDiv = this.tileMount?.container, weatherOptionOrOnerror, layerConfig) {
|
|
133
|
+
this.assertNotDestroyed();
|
|
134
|
+
const mountedLayer = this.resolveTileMount(map, mapDiv, layerConfig);
|
|
135
|
+
if (!mountedLayer) {
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
this.colorMapTileLayer = mountedLayer.layer;
|
|
139
|
+
const weatherOption = normalizeWeatherOption(
|
|
140
|
+
weatherOptionOrOnerror
|
|
141
|
+
);
|
|
142
|
+
if (weatherOption) {
|
|
143
|
+
mountedLayer.layer.setOption(weatherOption);
|
|
144
|
+
}
|
|
145
|
+
syncCanvasOverlaySize(mountedLayer.overlay, mountedLayer.overlay.container);
|
|
146
|
+
let renderedCanvas = mountedLayer.overlay.canvas;
|
|
147
|
+
if (mountedLayer.layer.source) {
|
|
148
|
+
renderedCanvas = this.renderTileCanvas(mountedLayer);
|
|
149
|
+
copyCanvasLike(renderedCanvas, mountedLayer.overlay);
|
|
150
|
+
}
|
|
151
|
+
this.syncMountedSource(mountedLayer);
|
|
152
|
+
return mountedLayer.overlay.canvas;
|
|
153
|
+
}
|
|
154
|
+
renderColorMapFunction(map = this.colorMount?.map, mapDiv = this.colorMount?.container, weatherOptionOrOnerror, layerConfig) {
|
|
155
|
+
this.assertNotDestroyed();
|
|
156
|
+
const mountedLayer = this.resolveColorMount(map, mapDiv, layerConfig);
|
|
157
|
+
if (!mountedLayer) {
|
|
158
|
+
return;
|
|
159
|
+
}
|
|
160
|
+
this.colorMapLayer = mountedLayer.layer;
|
|
161
|
+
const weatherOption = normalizeWeatherOption(
|
|
162
|
+
weatherOptionOrOnerror
|
|
163
|
+
);
|
|
164
|
+
if (weatherOption) {
|
|
165
|
+
mountedLayer.layer.setOption(weatherOption);
|
|
166
|
+
}
|
|
167
|
+
syncCanvasOverlaySize(mountedLayer.overlay, mountedLayer.overlay.container);
|
|
168
|
+
let renderedCanvas = mountedLayer.overlay.canvas;
|
|
169
|
+
if (mountedLayer.layer.source) {
|
|
170
|
+
renderedCanvas = this.renderColorCanvas(mountedLayer);
|
|
171
|
+
copyCanvasLike(renderedCanvas, mountedLayer.overlay);
|
|
172
|
+
}
|
|
173
|
+
this.syncMountedSource(mountedLayer);
|
|
174
|
+
return mountedLayer.overlay.canvas;
|
|
175
|
+
}
|
|
176
|
+
renderParticleFunction(map = this.particleMount?.map, mapDiv = this.particleMount?.container, weatherOptionOrOnerror, layerConfig) {
|
|
177
|
+
this.assertNotDestroyed();
|
|
178
|
+
const mountedLayer = this.resolveParticleMount(map, mapDiv, layerConfig);
|
|
179
|
+
if (!mountedLayer) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
this.particleLayer = mountedLayer.layer;
|
|
183
|
+
const weatherOption = normalizeWeatherOption(
|
|
184
|
+
weatherOptionOrOnerror
|
|
185
|
+
);
|
|
186
|
+
if (weatherOption) {
|
|
187
|
+
mountedLayer.layer.setOption(weatherOption);
|
|
188
|
+
}
|
|
189
|
+
syncCanvasOverlaySize(mountedLayer.overlay, mountedLayer.overlay.container);
|
|
190
|
+
this.setParticleView(mountedLayer);
|
|
191
|
+
mountedLayer.layer.start();
|
|
192
|
+
this.syncMountedSource(mountedLayer);
|
|
193
|
+
return mountedLayer.overlay.canvas;
|
|
194
|
+
}
|
|
195
|
+
renderFeatherFunction(map = this.featherMount?.map, mapDiv = this.featherMount?.container, weatherOptionOrOnerror, layerConfig) {
|
|
196
|
+
this.assertNotDestroyed();
|
|
197
|
+
const mountedLayer = this.resolveFeatherMount(map, mapDiv, layerConfig);
|
|
198
|
+
if (!mountedLayer) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
this.featherLayer = mountedLayer.layer;
|
|
202
|
+
const weatherOption = normalizeWeatherOption(
|
|
203
|
+
weatherOptionOrOnerror
|
|
204
|
+
);
|
|
205
|
+
if (weatherOption) {
|
|
206
|
+
mountedLayer.layer.setOption(weatherOption);
|
|
207
|
+
}
|
|
208
|
+
syncCanvasOverlaySize(mountedLayer.overlay, mountedLayer.overlay.container);
|
|
209
|
+
this.renderFeatherCanvas(mountedLayer);
|
|
210
|
+
this.syncMountedSource(mountedLayer);
|
|
211
|
+
return mountedLayer.overlay.canvas;
|
|
212
|
+
}
|
|
213
|
+
startParticle(config) {
|
|
214
|
+
this.assertNotDestroyed();
|
|
215
|
+
this.ensureDefaultLayers();
|
|
216
|
+
const mountedLayer = this.particleMount;
|
|
217
|
+
if (mountedLayer) {
|
|
218
|
+
syncCanvasOverlaySize(mountedLayer.overlay, mountedLayer.overlay.container);
|
|
219
|
+
this.setParticleView(mountedLayer);
|
|
220
|
+
const canvas = mountedLayer.layer.start(config);
|
|
221
|
+
this.syncMountedSource(mountedLayer);
|
|
222
|
+
return canvas;
|
|
223
|
+
}
|
|
224
|
+
return this.particleLayer?.start(config);
|
|
225
|
+
}
|
|
226
|
+
clearParticle() {
|
|
227
|
+
this.assertNotDestroyed();
|
|
228
|
+
this.ensureDefaultLayers();
|
|
229
|
+
this.particleLayer?.stop();
|
|
230
|
+
const canvas = this.particleLayer?.overlay.canvas;
|
|
231
|
+
if (!canvas) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
canvas.data = new Uint8ClampedArray(canvas.width * canvas.height * 4);
|
|
235
|
+
syncCanvasLikeData(canvas);
|
|
236
|
+
}
|
|
237
|
+
destroy() {
|
|
238
|
+
if (this.destroyed) {
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
this.destroyed = true;
|
|
242
|
+
this.colorMapTileLayer?.source?.clear?.();
|
|
243
|
+
this.colorMapLayer?.source?.clear?.();
|
|
244
|
+
this.featherLayer?.destroy?.();
|
|
245
|
+
this.particleLayer?.destroy?.();
|
|
246
|
+
for (const cleanupHandle of this.cleanupHandles.splice(0)) {
|
|
247
|
+
cleanupHandle();
|
|
248
|
+
}
|
|
249
|
+
this.colorMapTileLayer = void 0;
|
|
250
|
+
this.colorMapLayer = void 0;
|
|
251
|
+
this.featherLayer = void 0;
|
|
252
|
+
this.particleLayer = void 0;
|
|
253
|
+
this.tileMount = void 0;
|
|
254
|
+
this.colorMount = void 0;
|
|
255
|
+
this.featherMount = void 0;
|
|
256
|
+
this.particleMount = void 0;
|
|
257
|
+
}
|
|
258
|
+
assertNotDestroyed() {
|
|
259
|
+
if (this.destroyed) {
|
|
260
|
+
throw new Error("MapLibreClient has been destroyed");
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
resolveTileMount(map, mapDiv, layerConfig) {
|
|
264
|
+
if (this.tileMount || !map || !mapDiv) {
|
|
265
|
+
return this.tileMount;
|
|
266
|
+
}
|
|
267
|
+
const mountedLayer = this.mountTileLayer(map, mapDiv, layerConfig);
|
|
268
|
+
this.tileMount = mountedLayer;
|
|
269
|
+
this.colorMapTileLayer = mountedLayer.layer;
|
|
270
|
+
return mountedLayer;
|
|
271
|
+
}
|
|
272
|
+
resolveColorMount(map, mapDiv, layerConfig) {
|
|
273
|
+
if (this.colorMount || !map || !mapDiv) {
|
|
274
|
+
return this.colorMount;
|
|
275
|
+
}
|
|
276
|
+
const mountedLayer = this.mountColorLayer(map, mapDiv, layerConfig);
|
|
277
|
+
this.colorMount = mountedLayer;
|
|
278
|
+
this.colorMapLayer = mountedLayer.layer;
|
|
279
|
+
return mountedLayer;
|
|
280
|
+
}
|
|
281
|
+
resolveParticleMount(map, mapDiv, layerConfig) {
|
|
282
|
+
if (this.particleMount || !map || !mapDiv) {
|
|
283
|
+
return this.particleMount;
|
|
284
|
+
}
|
|
285
|
+
const mountedLayer = this.mountParticleLayer(map, mapDiv, layerConfig);
|
|
286
|
+
this.particleMount = mountedLayer;
|
|
287
|
+
this.particleLayer = mountedLayer.layer;
|
|
288
|
+
return mountedLayer;
|
|
289
|
+
}
|
|
290
|
+
resolveFeatherMount(map, mapDiv, layerConfig) {
|
|
291
|
+
if (this.featherMount || !map || !mapDiv) {
|
|
292
|
+
return this.featherMount;
|
|
293
|
+
}
|
|
294
|
+
const mountedLayer = this.mountFeatherLayer(map, mapDiv, layerConfig);
|
|
295
|
+
this.featherMount = mountedLayer;
|
|
296
|
+
this.featherLayer = mountedLayer.layer;
|
|
297
|
+
return mountedLayer;
|
|
298
|
+
}
|
|
299
|
+
mountTileLayer(map, container, layerConfig) {
|
|
300
|
+
return this.mountLayer({
|
|
301
|
+
map,
|
|
302
|
+
container,
|
|
303
|
+
layer: new ColormapTileLayer({
|
|
304
|
+
sourceDependencies: { retainQueryBuffer: true }
|
|
305
|
+
}),
|
|
306
|
+
sourceIdBase: "teda-weather-color-map-tile-source",
|
|
307
|
+
defaultLayerIdBase: "teda-weather-color-map-tile-layer",
|
|
308
|
+
layerConfig,
|
|
309
|
+
render: () => this.renderColorMapTileFunction()
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
mountColorLayer(map, container, layerConfig) {
|
|
313
|
+
return this.mountLayer({
|
|
314
|
+
map,
|
|
315
|
+
container,
|
|
316
|
+
layer: new ColormapLayer(),
|
|
317
|
+
sourceIdBase: "teda-weather-color-map-source",
|
|
318
|
+
defaultLayerIdBase: "teda-weather-color-map-layer",
|
|
319
|
+
layerConfig,
|
|
320
|
+
render: () => this.renderColorMapFunction()
|
|
321
|
+
});
|
|
322
|
+
}
|
|
323
|
+
mountParticleLayer(map, container, layerConfig) {
|
|
324
|
+
return this.mountLayer({
|
|
325
|
+
map,
|
|
326
|
+
container,
|
|
327
|
+
layer: new ParticleAnimationLayer(),
|
|
328
|
+
sourceIdBase: "teda-weather-particle-source",
|
|
329
|
+
defaultLayerIdBase: "teda-weather-particle-layer",
|
|
330
|
+
layerConfig,
|
|
331
|
+
render: () => this.startParticle()
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
mountFeatherLayer(map, container, layerConfig) {
|
|
335
|
+
return this.mountLayer({
|
|
336
|
+
map,
|
|
337
|
+
container,
|
|
338
|
+
layer: new FeatherLayer(),
|
|
339
|
+
sourceIdBase: "teda-weather-feather-source",
|
|
340
|
+
defaultLayerIdBase: "teda-weather-feather-layer",
|
|
341
|
+
layerConfig,
|
|
342
|
+
render: () => this.renderFeatherFunction()
|
|
343
|
+
});
|
|
344
|
+
}
|
|
345
|
+
mountLayer(options) {
|
|
346
|
+
const overlay = createCanvasOverlay(options.container);
|
|
347
|
+
const mountedLayer = Object.assign(options.layer, { overlay });
|
|
348
|
+
attachOverlayCanvas(mountedLayer, overlay.canvas);
|
|
349
|
+
const mountId = ++mountIdSequence;
|
|
350
|
+
const sourceId = `${options.sourceIdBase}-${mountId}`;
|
|
351
|
+
const layerId = options.layerConfig?.layerId ?? options.layerConfig?.id ?? `${options.defaultLayerIdBase}-${mountId}`;
|
|
352
|
+
const syncAndRender = () => {
|
|
353
|
+
syncCanvasOverlaySize(overlay, options.container);
|
|
354
|
+
options.render();
|
|
355
|
+
};
|
|
356
|
+
mountCanvasOverlay(overlay, options.container);
|
|
357
|
+
this.ensureSource(options.map, sourceId, overlay);
|
|
358
|
+
this.ensureLayer(options.map, sourceId, layerId, options.layerConfig);
|
|
359
|
+
options.map.on("move", syncAndRender);
|
|
360
|
+
options.map.on("resize", syncAndRender);
|
|
361
|
+
this.cleanupHandles.push(
|
|
362
|
+
() => options.map.off("move", syncAndRender),
|
|
363
|
+
() => options.map.off("resize", syncAndRender),
|
|
364
|
+
() => options.map.removeLayer?.(layerId),
|
|
365
|
+
() => options.map.removeSource?.(sourceId),
|
|
366
|
+
() => unmountCanvasOverlay(overlay)
|
|
367
|
+
);
|
|
368
|
+
return {
|
|
369
|
+
map: options.map,
|
|
370
|
+
overlay,
|
|
371
|
+
container: options.container,
|
|
372
|
+
layer: mountedLayer,
|
|
373
|
+
sourceId,
|
|
374
|
+
layerId
|
|
375
|
+
};
|
|
376
|
+
}
|
|
377
|
+
ensureDefaultLayers() {
|
|
378
|
+
if (!this.colorMapTileLayer) {
|
|
379
|
+
this.colorMapTileLayer = Object.assign(
|
|
380
|
+
new ColormapTileLayer({
|
|
381
|
+
sourceDependencies: { retainQueryBuffer: true }
|
|
382
|
+
}),
|
|
383
|
+
{
|
|
384
|
+
overlay: createCanvasOverlay({ offsetWidth: 1, offsetHeight: 1 })
|
|
385
|
+
}
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
if (!this.colorMapLayer) {
|
|
389
|
+
this.colorMapLayer = Object.assign(new ColormapLayer(), {
|
|
390
|
+
overlay: createCanvasOverlay({ offsetWidth: 1, offsetHeight: 1 })
|
|
391
|
+
});
|
|
392
|
+
}
|
|
393
|
+
if (!this.featherLayer) {
|
|
394
|
+
const overlay = createCanvasOverlay({ offsetWidth: 1, offsetHeight: 1 });
|
|
395
|
+
this.featherLayer = Object.assign(new FeatherLayer(), { overlay });
|
|
396
|
+
attachOverlayCanvas(this.featherLayer, overlay.canvas);
|
|
397
|
+
}
|
|
398
|
+
if (!this.particleLayer) {
|
|
399
|
+
const overlay = createCanvasOverlay({ offsetWidth: 1, offsetHeight: 1 });
|
|
400
|
+
this.particleLayer = Object.assign(new ParticleAnimationLayer(), {
|
|
401
|
+
overlay
|
|
402
|
+
});
|
|
403
|
+
attachOverlayCanvas(this.particleLayer, overlay.canvas);
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
renderTileCanvas(mountedLayer) {
|
|
407
|
+
const viewState = getMapViewState(mountedLayer.map, mountedLayer.container);
|
|
408
|
+
return mountedLayer.layer.renderExtent(
|
|
409
|
+
viewState.extent,
|
|
410
|
+
viewState.zoom,
|
|
411
|
+
viewState.viewSize,
|
|
412
|
+
viewState.pixelRatio
|
|
413
|
+
);
|
|
414
|
+
}
|
|
415
|
+
renderColorCanvas(mountedLayer) {
|
|
416
|
+
const viewState = getMapViewState(mountedLayer.map, mountedLayer.container);
|
|
417
|
+
return mountedLayer.layer.renderExtent(
|
|
418
|
+
viewState.extent,
|
|
419
|
+
viewState.zoom,
|
|
420
|
+
viewState.viewSize,
|
|
421
|
+
viewState.pixelRatio
|
|
422
|
+
);
|
|
423
|
+
}
|
|
424
|
+
renderFeatherCanvas(mountedLayer) {
|
|
425
|
+
const viewState = getMapViewState(mountedLayer.map, mountedLayer.container);
|
|
426
|
+
return mountedLayer.layer.renderExtent(
|
|
427
|
+
viewState.extent,
|
|
428
|
+
viewState.zoom,
|
|
429
|
+
viewState.viewSize,
|
|
430
|
+
viewState.pixelRatio
|
|
431
|
+
);
|
|
432
|
+
}
|
|
433
|
+
setParticleView(mountedLayer) {
|
|
434
|
+
if (!mountedLayer) {
|
|
435
|
+
return;
|
|
436
|
+
}
|
|
437
|
+
const viewState = getMapViewState(mountedLayer.map, mountedLayer.container);
|
|
438
|
+
mountedLayer.layer.setView(
|
|
439
|
+
viewState.extent,
|
|
440
|
+
viewState.zoom,
|
|
441
|
+
viewState.viewSize
|
|
442
|
+
);
|
|
443
|
+
}
|
|
444
|
+
syncMountedSource(mountedLayer) {
|
|
445
|
+
const coordinates = getCanvasCoordinates(mountedLayer.map);
|
|
446
|
+
const source = this.ensureMountedResources(mountedLayer);
|
|
447
|
+
if (source.setCoordinates) {
|
|
448
|
+
source.setCoordinates(coordinates);
|
|
449
|
+
return;
|
|
450
|
+
}
|
|
451
|
+
source.coordinates = coordinates;
|
|
452
|
+
}
|
|
453
|
+
ensureMountedResources(mountedLayer, layerConfig) {
|
|
454
|
+
this.ensureSource(
|
|
455
|
+
mountedLayer.map,
|
|
456
|
+
mountedLayer.sourceId,
|
|
457
|
+
mountedLayer.overlay
|
|
458
|
+
);
|
|
459
|
+
this.ensureLayer(
|
|
460
|
+
mountedLayer.map,
|
|
461
|
+
mountedLayer.sourceId,
|
|
462
|
+
mountedLayer.layerId,
|
|
463
|
+
layerConfig
|
|
464
|
+
);
|
|
465
|
+
return mountedLayer.map.getSource(mountedLayer.sourceId) ?? {};
|
|
466
|
+
}
|
|
467
|
+
ensureSource(map, sourceId, overlay, coordinates = getCanvasCoordinates(map)) {
|
|
468
|
+
if (map.getSource(sourceId)) {
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
map.addSource(sourceId, {
|
|
472
|
+
type: "canvas",
|
|
473
|
+
canvas: overlay.canvas,
|
|
474
|
+
coordinates,
|
|
475
|
+
animate: true
|
|
476
|
+
});
|
|
477
|
+
}
|
|
478
|
+
ensureLayer(map, sourceId, layerId, layerConfig) {
|
|
479
|
+
if (map.getLayer(layerId)) {
|
|
480
|
+
return;
|
|
481
|
+
}
|
|
482
|
+
map.addLayer(
|
|
483
|
+
{
|
|
484
|
+
id: layerId,
|
|
485
|
+
type: "raster",
|
|
486
|
+
source: sourceId,
|
|
487
|
+
paint: layerConfig?.paint,
|
|
488
|
+
layout: layerConfig?.layout
|
|
489
|
+
},
|
|
490
|
+
layerConfig?.beforeId
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
};
|
|
494
|
+
function getCanvasCoordinates(map) {
|
|
495
|
+
const bounds = map.getBounds();
|
|
496
|
+
return [
|
|
497
|
+
[bounds.getWest(), bounds.getNorth()],
|
|
498
|
+
[bounds.getEast(), bounds.getNorth()],
|
|
499
|
+
[bounds.getEast(), bounds.getSouth()],
|
|
500
|
+
[bounds.getWest(), bounds.getSouth()]
|
|
501
|
+
];
|
|
502
|
+
}
|
|
503
|
+
function getMapViewState(map, container) {
|
|
504
|
+
const bounds = map.getBounds();
|
|
505
|
+
return {
|
|
506
|
+
extent: [
|
|
507
|
+
bounds.getWest(),
|
|
508
|
+
bounds.getSouth(),
|
|
509
|
+
bounds.getEast(),
|
|
510
|
+
bounds.getNorth()
|
|
511
|
+
],
|
|
512
|
+
zoom: map.getZoom() + 1,
|
|
513
|
+
viewSize: [container.offsetWidth ?? 1, container.offsetHeight ?? 1],
|
|
514
|
+
pixelRatio: typeof globalThis.devicePixelRatio === "number" ? globalThis.devicePixelRatio : 1
|
|
515
|
+
};
|
|
516
|
+
}
|
|
517
|
+
function attachOverlayCanvas(layer, canvas) {
|
|
518
|
+
layer.setCanvas?.(canvas);
|
|
519
|
+
}
|
|
520
|
+
function copyCanvasLike(source, overlay) {
|
|
521
|
+
overlay.width = source.width;
|
|
522
|
+
overlay.height = source.height;
|
|
523
|
+
overlay.canvas.width = source.width;
|
|
524
|
+
overlay.canvas.height = source.height;
|
|
525
|
+
overlay.canvas.data = new Uint8ClampedArray(source.data);
|
|
526
|
+
syncCanvasLikeData(overlay.canvas);
|
|
527
|
+
}
|
|
528
|
+
function normalizeWeatherOption(value) {
|
|
529
|
+
return typeof value === "function" ? void 0 : value;
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
export {
|
|
533
|
+
MapLibreClient
|
|
534
|
+
};
|