isard 1.16.0 → 2.0.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/CHANGELOG.md +48 -0
- package/README.md +4 -4
- package/dist/basemap/vectortiles/placed.js +7 -4
- package/dist/basemap/vectortiles/placed.js.map +1 -1
- package/dist/basemap/vectortiles/tiles.d.ts +1 -1
- package/dist/basemap/vectortiles/tiles.js.map +1 -1
- package/dist/basemap/workerpool.d.ts +1 -1
- package/dist/basemap/workerpool.js.map +1 -1
- package/dist/decoder.worker.js +4 -5
- package/dist/decoder.worker.js.map +6 -6
- package/dist/decoding/decoders.d.ts +1 -1
- package/dist/decoding/decoders.js.map +1 -1
- package/dist/decoding/loader.d.ts +6 -3
- package/dist/decoding/loader.js +7 -5
- package/dist/decoding/loader.js.map +1 -1
- package/dist/decoding/protocol.d.ts +3 -2
- package/dist/decoding/protocol.js.map +1 -1
- package/dist/engine-loader.d.ts +20 -18
- package/dist/engine-loader.js +45 -42
- package/dist/engine-loader.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.js.map +1 -1
- package/dist/isard_grid_bg.wasm +0 -0
- package/dist/isard_tess_bg.wasm +0 -0
- package/dist/isard_tiles3d_bg.wasm +0 -0
- package/dist/isard_webgl2_bg.wasm +0 -0
- package/dist/isard_webgpu_bg.wasm +0 -0
- package/dist/layers/custom.d.ts +35 -29
- package/dist/layers/custom.js +60 -46
- package/dist/layers/custom.js.map +1 -1
- package/dist/layers/extrusions.js.map +1 -1
- package/dist/layers/features.js.map +1 -1
- package/dist/layers/flow.js.map +1 -1
- package/dist/layers/glyphs.d.ts +1 -1
- package/dist/layers/glyphs.js.map +1 -1
- package/dist/layers/ground.d.ts +20 -13
- package/dist/layers/ground.js +29 -8
- package/dist/layers/ground.js.map +1 -1
- package/dist/layers/icons.d.ts +1 -1
- package/dist/layers/icons.js.map +1 -1
- package/dist/layers/layers.d.ts +1 -2
- package/dist/layers/layers.js +2 -11
- package/dist/layers/layers.js.map +1 -1
- package/dist/layers/models.js +0 -4
- package/dist/layers/models.js.map +1 -1
- package/dist/layers/network.d.ts +1 -1
- package/dist/layers/network.js.map +1 -1
- package/dist/layers/panoramas.d.ts +1 -0
- package/dist/layers/panoramas.js +3 -2
- package/dist/layers/panoramas.js.map +1 -1
- package/dist/layers/pointclouds.d.ts +1 -1
- package/dist/layers/pointclouds.js +0 -4
- package/dist/layers/pointclouds.js.map +1 -1
- package/dist/layers/raster.js.map +1 -1
- package/dist/layers/symbols.js.map +1 -1
- package/dist/layers/tiles3d.d.ts +1 -1
- package/dist/layers/tiles3d.js +0 -4
- package/dist/layers/tiles3d.js.map +1 -1
- package/dist/layers/vectors.d.ts +4 -5
- package/dist/layers/vectors.js +7 -15
- package/dist/layers/vectors.js.map +1 -1
- package/dist/map/engine-settings.d.ts +1 -1
- package/dist/map/engine-settings.js.map +1 -1
- package/dist/map/engines.d.ts +11 -26
- package/dist/map/engines.js +10 -48
- package/dist/map/engines.js.map +1 -1
- package/dist/map/frame-loop.d.ts +1 -3
- package/dist/map/frame-loop.js +3 -3
- package/dist/map/frame-loop.js.map +1 -1
- package/dist/map/hover-pick.d.ts +9 -3
- package/dist/map/hover-pick.js +29 -6
- package/dist/map/hover-pick.js.map +1 -1
- package/dist/map/layer-stack.d.ts +2 -2
- package/dist/map/layer-stack.js +1 -3
- package/dist/map/layer-stack.js.map +1 -1
- package/dist/map/symbol-atlases.d.ts +5 -4
- package/dist/map/symbol-atlases.js +8 -13
- package/dist/map/symbol-atlases.js.map +1 -1
- package/dist/map/viewshed.d.ts +1 -1
- package/dist/map/viewshed.js.map +1 -1
- package/dist/map.d.ts +26 -20
- package/dist/map.js +93 -78
- package/dist/map.js.map +1 -1
- package/dist/react/IsardMap.d.ts +1 -1
- package/dist/react/IsardMap.js.map +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js.map +1 -1
- package/dist/types.d.ts +29 -18
- package/dist/types.js.map +1 -1
- package/dist/ui/interaction.d.ts +1 -1
- package/dist/ui/interaction.js.map +1 -1
- package/dist/util/animation.d.ts +1 -1
- package/dist/util/animation.js.map +1 -1
- package/dist/wasm/isard_tiles3d.d.ts +181 -0
- package/dist/wasm/isard_tiles3d.js +387 -0
- package/dist/wasm/{isard_core.d.ts → isard_webgl2.d.ts} +373 -182
- package/dist/wasm/{isard_core.js → isard_webgl2.js} +2155 -413
- package/dist/wasm/{isard.d.ts → isard_webgpu.d.ts} +176 -353
- package/dist/wasm/{isard.js → isard_webgpu.js} +1361 -1104
- package/package.json +4 -3
- package/vite.js +5 -4
- package/dist/isard_bg.wasm +0 -0
- package/dist/isard_core_bg.wasm +0 -0
package/dist/map.js
CHANGED
|
@@ -9,7 +9,7 @@ import { SEA } from "./basemap/basemaps.js";
|
|
|
9
9
|
import { pmtilesLayer } from "./basemap/pmtileslayer.js";
|
|
10
10
|
import { VectorTiles } from "./basemap/vectortiles.js";
|
|
11
11
|
import { defaultWorkerUrl } from "./basemap/workerpool.js";
|
|
12
|
-
import { destroyedEngine, engineUrl, gridUrl, loadEngine, tessUrl } from "./engine-loader.js";
|
|
12
|
+
import { destroyedEngine, engineUrl, gridUrl, loadEngine, rendererKind, tessUrl, } from "./engine-loader.js";
|
|
13
13
|
import { IGN_PRESETS } from "./geoplateforme.js";
|
|
14
14
|
import { CustomLayer } from "./layers/custom.js";
|
|
15
15
|
import { ExtrusionLayer, extrusionStyle } from "./layers/extrusions.js";
|
|
@@ -34,7 +34,7 @@ import { mapSettings, sendHeaders } from "./map/engine-settings.js";
|
|
|
34
34
|
import { MapEngines } from "./map/engines.js";
|
|
35
35
|
import { MapListeners } from "./map/events.js";
|
|
36
36
|
import { FrameLoop } from "./map/frame-loop.js";
|
|
37
|
-
import { HoverPick } from "./map/hover-pick.js";
|
|
37
|
+
import { HoverPick, pickOnce } from "./map/hover-pick.js";
|
|
38
38
|
import { addSpec } from "./map/layer-spec.js";
|
|
39
39
|
import { LayerStack } from "./map/layer-stack.js";
|
|
40
40
|
import { OverlayHost } from "./map/overlay-host.js";
|
|
@@ -67,9 +67,19 @@ const NETWORK_HALO_OPACITY = 0.11;
|
|
|
67
67
|
/** A layer whose picked features come back with their properties (lines, circles, fills, extrusions, 3D Tiles…) */
|
|
68
68
|
const hasFeatures = (layer) => 'featureAt' in layer && typeof layer.featureAt === 'function';
|
|
69
69
|
/** A map (see `GeoMap.create`); layers take it as their host */
|
|
70
|
+
/** The parts of a frame by their code in the engine's GPU timings (`Engine.gpuTimings`) */
|
|
71
|
+
const GPU_PARTS = ['backdrop', 'ground', 'layer', 'shadows', 'panorama', 'viewshed'];
|
|
72
|
+
/** Turns the GPU timing of an engine on or off: whether it times, false for an engine built without it (only a build to
|
|
73
|
+
* profile has `setGpuTiming`) */
|
|
74
|
+
const engineGpuTiming = (engine, on) => {
|
|
75
|
+
const set = Reflect.get(engine, 'setGpuTiming');
|
|
76
|
+
return typeof set === 'function' && Reflect.apply(set, engine, [on]) === true;
|
|
77
|
+
};
|
|
70
78
|
export class GeoMap {
|
|
71
79
|
canvas;
|
|
72
80
|
#engine;
|
|
81
|
+
/** The frames' parts timed on the GPU (`setGpuTiming`), again on a new engine */
|
|
82
|
+
gpuTiming = false;
|
|
73
83
|
/** The work the map waits on before it is idle (`track`) */
|
|
74
84
|
#working = 0;
|
|
75
85
|
/** The engine class (core, or with 3D Tiles) and the engine with 3D Tiles loaded when needed */
|
|
@@ -124,20 +134,25 @@ export class GeoMap {
|
|
|
124
134
|
static async create(container, given = {}) {
|
|
125
135
|
// A preset under the options given
|
|
126
136
|
const options = given.preset ? { ...IGN_PRESETS[given.preset], ...given } : given;
|
|
127
|
-
// With 3D Tiles from the start when asked, or when only that engine's URL is given (as before the core engine)
|
|
128
|
-
const full = options.tiles3d === true || (options.wasmUrl !== undefined && options.coreWasmUrl === undefined);
|
|
129
137
|
// Before anything is created
|
|
130
138
|
if (options.basemap !== undefined)
|
|
131
139
|
checkBasemap(options.basemap);
|
|
132
|
-
|
|
140
|
+
// The engine on wgpu (#146): WebGPU, else wgpu's WebGL2 fallback
|
|
141
|
+
const kind = await rendererKind(options.renderer);
|
|
133
142
|
const bindings = await loadEngine(kind, engineUrl(kind, options));
|
|
134
|
-
const map = new GeoMap(container, options, bindings.Engine
|
|
135
|
-
|
|
136
|
-
|
|
143
|
+
const map = new GeoMap(container, options, bindings.Engine);
|
|
144
|
+
// Its device asked for: the map started on a placeholder meanwhile, its layers created on the engine once it is
|
|
145
|
+
// there (as after a context loss)
|
|
146
|
+
map.adopt(await map.engines.create(map.canvas, () => map.requestRender(), map.settings));
|
|
147
|
+
// A profiling script's page (`window.__isardProfile` set before isard loads): its maps, to time
|
|
148
|
+
if (Reflect.get(globalThis, '__isardProfile')) {
|
|
149
|
+
const maps = Reflect.get(globalThis, '__isardMaps');
|
|
150
|
+
Reflect.set(globalThis, '__isardMaps', [...(Array.isArray(maps) ? maps : []), map]);
|
|
151
|
+
}
|
|
137
152
|
return map;
|
|
138
153
|
}
|
|
139
|
-
constructor(container, options, engineClass
|
|
140
|
-
this.engines = new MapEngines(engineClass,
|
|
154
|
+
constructor(container, options, engineClass) {
|
|
155
|
+
this.engines = new MapEngines(engineClass, options);
|
|
141
156
|
const workerUrl = options.basemapWorkerUrl ?? defaultWorkerUrl(options.assetsUrl);
|
|
142
157
|
this.tessUrl = tessUrl(options);
|
|
143
158
|
this.gridUrl = gridUrl(options);
|
|
@@ -145,7 +160,8 @@ export class GeoMap {
|
|
|
145
160
|
this.basemaps = new BasemapLayers(this, this.stack, workerUrl, options.basemapTileSize);
|
|
146
161
|
this.container = container;
|
|
147
162
|
this.canvas = createCanvas();
|
|
148
|
-
|
|
163
|
+
// The engine takes the canvas for itself: it says how large a texture its device takes
|
|
164
|
+
this.atlases = new SymbolAtlases(() => this.#engine.maxTextureSize(), options.glyphs, () => this.#engine);
|
|
149
165
|
this.overlays = new OverlayHost(container, this.canvas, this);
|
|
150
166
|
this.earth = (options.body ?? 'earth') === 'earth';
|
|
151
167
|
this.body = options.body;
|
|
@@ -156,7 +172,6 @@ export class GeoMap {
|
|
|
156
172
|
lost: () => this.lost,
|
|
157
173
|
interacting: () => this.interaction?.active === true,
|
|
158
174
|
customLayers: () => this.layers.some((layer) => layer instanceof CustomLayer),
|
|
159
|
-
upgrading: () => this.engines.upgrading !== undefined,
|
|
160
175
|
working: () => this.#working > 0,
|
|
161
176
|
drawn: (hovered) => {
|
|
162
177
|
this.qualityWatch?.frame(performance.now(), this.movingNow);
|
|
@@ -167,7 +182,8 @@ export class GeoMap {
|
|
|
167
182
|
this.overlays.positionAll();
|
|
168
183
|
},
|
|
169
184
|
}, this.listeners);
|
|
170
|
-
|
|
185
|
+
// The engine is made asynchronously (`GeoMap.create` adopts it): a placeholder meanwhile
|
|
186
|
+
this.#engine = destroyedEngine(EARTH_START);
|
|
171
187
|
// Once it has an engine: a map whose creation failed before is not left following them
|
|
172
188
|
this.unwatchHeaders = onHeaderRules((rules) => sendHeaders(this.#engine, rules));
|
|
173
189
|
// The browser may take the GPU away (driver reset, background tab on mobile): the map waits, then rebuilds
|
|
@@ -224,34 +240,6 @@ export class GeoMap {
|
|
|
224
240
|
get onTop() {
|
|
225
241
|
return this.stack.onTop;
|
|
226
242
|
}
|
|
227
|
-
createEngine() {
|
|
228
|
-
return this.engines.create(this.canvas, () => this.requestRender(), this.settings);
|
|
229
|
-
}
|
|
230
|
-
/** A 3D Tiles layer or a model on the core engine: loads the engine with 3D Tiles, then rebuilds the map on it
|
|
231
|
-
* (camera, settings and layers kept, as after a context loss); the layer is created then */
|
|
232
|
-
upgrade() {
|
|
233
|
-
this.engines.upgrade(() => {
|
|
234
|
-
// A lost context: the engine is rebuilt on it once restored
|
|
235
|
-
if (!this.lost)
|
|
236
|
-
this.restore();
|
|
237
|
-
}, (error) => {
|
|
238
|
-
// The 3D Tiles layers stay empty; the next one added tries again
|
|
239
|
-
report(error);
|
|
240
|
-
this.requestRender();
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
/** Downloads and compiles the engine with 3D Tiles once the map is idle (`tiles3d: 'preload'`), without running
|
|
244
|
-
* it: the first 3D Tiles layer then only instantiates it */
|
|
245
|
-
preloadTiles3d() {
|
|
246
|
-
if (this.frames.settled)
|
|
247
|
-
this.engines.preload();
|
|
248
|
-
else {
|
|
249
|
-
const off = this.on('idle', () => {
|
|
250
|
-
off();
|
|
251
|
-
this.engines.preload();
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
}
|
|
255
243
|
/**
|
|
256
244
|
* The context is lost: its engine freed at once, the map's calls going to one that does nothing until `restore`
|
|
257
245
|
* builds the next. The old engine's GPU objects went with the context: deleted now, it is silent (on the context
|
|
@@ -266,19 +254,34 @@ export class GeoMap {
|
|
|
266
254
|
// Glyph ranges and icons arriving meanwhile upload to it, not to the freed engine
|
|
267
255
|
this.atlases.attach(this.#engine);
|
|
268
256
|
}
|
|
269
|
-
/** After a context loss: a new engine with the same camera, settings and layers (same handles, same order)
|
|
257
|
+
/** After a context loss: a new engine with the same camera, settings and layers (same handles, same order); the
|
|
258
|
+
* engine made asynchronously, adopted once there */
|
|
270
259
|
restore() {
|
|
271
260
|
if (this.gone)
|
|
272
261
|
return;
|
|
262
|
+
this.engines
|
|
263
|
+
.create(this.canvas, () => this.requestRender(), this.settings)
|
|
264
|
+
.then((engine) => this.adopt(engine))
|
|
265
|
+
.catch(report);
|
|
266
|
+
}
|
|
267
|
+
/** A new engine in place of the map's (a placeholder, or a lost one): the same camera, settings and layers (same
|
|
268
|
+
* handles, same order) */
|
|
269
|
+
adopt(engine) {
|
|
270
|
+
if (this.gone) {
|
|
271
|
+
engine.free();
|
|
272
|
+
return;
|
|
273
|
+
}
|
|
273
274
|
this.hoverPick.cancel();
|
|
274
275
|
const camera = this.getCamera();
|
|
275
276
|
this.#engine.free();
|
|
276
|
-
this.#engine =
|
|
277
|
+
this.#engine = engine;
|
|
277
278
|
this.lost = false;
|
|
279
|
+
// Still timed (profiling)
|
|
280
|
+
if (this.gpuTiming)
|
|
281
|
+
engineGpuTiming(engine, true);
|
|
278
282
|
this.setCamera(camera);
|
|
279
283
|
this.atlases.attach(this.#engine);
|
|
280
|
-
|
|
281
|
-
this.stack.reattach(this.#engine, (layer) => layer.needsFullEngine && !this.engines.tiles3d);
|
|
284
|
+
this.stack.reattach(this.#engine);
|
|
282
285
|
this.applySwipe();
|
|
283
286
|
// A street-level eye stays one in the new engine
|
|
284
287
|
if (this.#firstPerson)
|
|
@@ -293,6 +296,7 @@ export class GeoMap {
|
|
|
293
296
|
void set.show(set.current.index).catch(report);
|
|
294
297
|
});
|
|
295
298
|
this.resize();
|
|
299
|
+
this.requestRender();
|
|
296
300
|
}
|
|
297
301
|
/** The street-level eye, while there is one (`setFirstPerson`) */
|
|
298
302
|
#firstPerson;
|
|
@@ -354,20 +358,14 @@ export class GeoMap {
|
|
|
354
358
|
return !this.gone && this.stack.has(layer);
|
|
355
359
|
}
|
|
356
360
|
addLayer(layer) {
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
catch (error) {
|
|
366
|
-
// A context lost before the browser says so (its event comes later): nothing could be made on it, the layer is
|
|
367
|
-
// made with the others on the next engine (`restore`). Any other failure is the caller's
|
|
368
|
-
if (!this.contextLost())
|
|
369
|
-
throw error;
|
|
370
|
-
}
|
|
361
|
+
try {
|
|
362
|
+
layer.attach(this.engine);
|
|
363
|
+
}
|
|
364
|
+
catch (error) {
|
|
365
|
+
// A context lost before the browser says so (its event comes later): nothing could be made on it, the layer is
|
|
366
|
+
// made with the others on the next engine (`restore`). Any other failure is the caller's
|
|
367
|
+
if (!this.contextLost())
|
|
368
|
+
throw error;
|
|
371
369
|
}
|
|
372
370
|
// Under the layers kept on top (the basemap's labels)
|
|
373
371
|
this.stack.add(layer);
|
|
@@ -376,6 +374,7 @@ export class GeoMap {
|
|
|
376
374
|
}
|
|
377
375
|
/** Whether the canvas's WebGL context is lost, its event come or not */
|
|
378
376
|
contextLost() {
|
|
377
|
+
// On a WebGPU canvas, no WebGL context: null, nothing taken
|
|
379
378
|
return this.lost || this.canvas.getContext('webgl2')?.isContextLost() === true;
|
|
380
379
|
}
|
|
381
380
|
/** @internal Keeps a layer above the layers added after it (they go under it), as the labels of a basemap */
|
|
@@ -577,22 +576,44 @@ export class GeoMap {
|
|
|
577
576
|
stats() {
|
|
578
577
|
return this.engine.stats();
|
|
579
578
|
}
|
|
579
|
+
/** Times the parts of each frame on the GPU, for profiling (`gpuTimings`): timer queries, read a few frames later.
|
|
580
|
+
* An engine built to profile only (`PROFILE=1 bun run build`); false without one, or if the browser cannot
|
|
581
|
+
* (`EXT_disjoint_timer_query_webgl2`) */
|
|
582
|
+
setGpuTiming(on) {
|
|
583
|
+
this.gpuTiming = engineGpuTiming(this.engine, on);
|
|
584
|
+
return this.gpuTiming;
|
|
585
|
+
}
|
|
586
|
+
/** The GPU time of the last frame measured (`setGpuTiming`), in all and by part: the backdrop, the ground (the raster
|
|
587
|
+
* layers over the relief), each layer, the shadows, the panorama, the viewshed (ms) */
|
|
588
|
+
gpuTimings() {
|
|
589
|
+
// The frame's number, then each part's code, layer id (-1 for none) and milliseconds
|
|
590
|
+
const read = Reflect.get(this.engine, 'gpuTimings');
|
|
591
|
+
const flat = typeof read === 'function' ? Reflect.apply(read, this.engine, []) : undefined;
|
|
592
|
+
if (!(flat instanceof Float64Array) || flat.length === 0)
|
|
593
|
+
return undefined;
|
|
594
|
+
const parts = Array.from({ length: (flat.length - 1) / 3 }, (_, k) => {
|
|
595
|
+
const [code = 0, id = -1, ms = 0] = flat.subarray(1 + k * 3, 4 + k * 3);
|
|
596
|
+
const layer = id >= 0 ? this.layers.find((l) => l.id === id) : undefined;
|
|
597
|
+
return { part: GPU_PARTS[code] ?? 'layer', ms, ...(layer && { layer }) };
|
|
598
|
+
});
|
|
599
|
+
return { frame: flat[0] ?? 0, ms: parts.reduce((sum, p) => sum + p.ms, 0), parts };
|
|
600
|
+
}
|
|
580
601
|
/**
|
|
581
|
-
* The feature under a screen point (CSS pixels), undefined if none: its layer id and index. Reads
|
|
582
|
-
* offscreen picking pass, whatever the number of features,
|
|
583
|
-
*
|
|
602
|
+
* The feature under a screen point (CSS pixels), undefined if none: its layer id and index. Reads the pixels around
|
|
603
|
+
* the point of an offscreen picking pass, whatever the number of features, once the GPU is done (a frame or two
|
|
604
|
+
* later: the GPU is not waited for). On hover, listen to 'hoverfeature' instead.
|
|
584
605
|
*/
|
|
585
|
-
pick(point, { radius = 0, layers } = {}) {
|
|
606
|
+
async pick(point, { radius = 0, layers } = {}) {
|
|
586
607
|
const only = layers && Uint32Array.from(layers.map((l) => l.id));
|
|
587
|
-
return this.engine
|
|
608
|
+
return (await pickOnce(() => this.engine, point, radius, only))?.hit;
|
|
588
609
|
}
|
|
589
610
|
/**
|
|
590
611
|
* The feature under a screen point (CSS pixels), or the nearest one within `radius` pixels: its layer handle, its
|
|
591
612
|
* index there and, for line, circle and fill layers, the feature itself; undefined if none. `layers` restricts the
|
|
592
613
|
* search to some layers (the others hide nothing).
|
|
593
614
|
*/
|
|
594
|
-
pickFeature(point, options = {}) {
|
|
595
|
-
const hit = this.pick(point, options);
|
|
615
|
+
async pickFeature(point, options = {}) {
|
|
616
|
+
const hit = await this.pick(point, options);
|
|
596
617
|
return hit && this.featureHit(hit);
|
|
597
618
|
}
|
|
598
619
|
/** A hit with its layer handle and feature; undefined if the layer is gone */
|
|
@@ -617,13 +638,6 @@ export class GeoMap {
|
|
|
617
638
|
* and calibrations loaded, none shown until `show`, which projects one onto the scene around it
|
|
618
639
|
*/
|
|
619
640
|
async addPanoramas(options) {
|
|
620
|
-
// Drawn by the engine with 3D Tiles: loaded first if needed
|
|
621
|
-
if (!this.engines.tiles3d) {
|
|
622
|
-
this.upgrade();
|
|
623
|
-
await this.engines.upgrading;
|
|
624
|
-
if (!this.engines.tiles3d)
|
|
625
|
-
throw new Error('isard: panoramas need the engine with 3D Tiles, which failed to load');
|
|
626
|
-
}
|
|
627
641
|
const host = panoramaHost(this, (lon, lat) => this.engines.geoidHeight(lon, lat));
|
|
628
642
|
const panoramas = await loadPanoramas(host, options);
|
|
629
643
|
this.panoramaSets.add(panoramas);
|
|
@@ -664,15 +678,16 @@ export class GeoMap {
|
|
|
664
678
|
this.interaction.rotateAroundPointer = enabled;
|
|
665
679
|
}
|
|
666
680
|
/** What is drawn under a screen point (CSS pixels), on the relief or standing on it (a roof, a wall, a mesh): its
|
|
667
|
-
* position and its height above the relief, in metres; undefined where nothing was drawn.
|
|
668
|
-
*
|
|
681
|
+
* position and its height above the relief, in metres; undefined where nothing was drawn. Read from the last copy of
|
|
682
|
+
* the scene's depth (a frame or two old, a pixel every 4 CSS pixels): at once, without waiting for the GPU */
|
|
669
683
|
pickSurface(point) {
|
|
670
684
|
const hit = this.engine.surface(point[0], point[1]);
|
|
671
685
|
return hit && { lonLat: [hit[0], hit[1]], height: hit[2] };
|
|
672
686
|
}
|
|
673
687
|
/** The height above the relief, in metres, of the top of what stands at a position: a roof, a mesh, 0 on the bare
|
|
674
|
-
* ground; undefined where nothing of the last frame is there
|
|
675
|
-
* read back
|
|
688
|
+
* ground; undefined where nothing of the last frame is there, or until measured: the scene is drawn looking down at
|
|
689
|
+
* it after a frame and read back a frame or two later, the answer kept and measured again every 250 ms at most (ask
|
|
690
|
+
* again on the next `render` event) */
|
|
676
691
|
surfaceAt(lonLat) {
|
|
677
692
|
return this.engine.surfaceAt(lonLat[0], lonLat[1]);
|
|
678
693
|
}
|
|
@@ -917,7 +932,7 @@ export class GeoMap {
|
|
|
917
932
|
* WebGL, three.js… with the matrices of the frame (`frame.matrixAt`); under `before` if given
|
|
918
933
|
*/
|
|
919
934
|
addCustomLayer(layer, options = {}) {
|
|
920
|
-
const custom = new CustomLayer(this, layer, this
|
|
935
|
+
const custom = new CustomLayer(this, layer, this, (lon, lat, altitude) => this.engines.customMatrix(lon, lat, altitude), () => this.getCamera());
|
|
921
936
|
return this.place(custom, options.before);
|
|
922
937
|
}
|
|
923
938
|
// ── Frames ──
|