isard 0.2.0 → 0.2.1
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 +76 -14
- package/dist/basemap.worker.d.ts +10 -0
- package/dist/basemap.worker.js +2 -2
- package/dist/basemap.worker.js.map +3 -3
- package/dist/basemaps.d.ts +5 -3
- package/dist/basemaps.js +5 -3
- package/dist/basemaps.js.map +1 -1
- package/dist/decoder.worker.js +3 -3
- package/dist/decoder.worker.js.map +3 -3
- package/dist/equirectangular.d.ts +6 -6
- package/dist/equirectangular.js +54 -24
- package/dist/equirectangular.js.map +1 -1
- package/dist/extrusions.js +11 -2
- package/dist/extrusions.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.js.map +1 -1
- package/dist/interaction.d.ts +3 -0
- package/dist/interaction.js +19 -3
- package/dist/interaction.js.map +1 -1
- package/dist/isard_bg.wasm +0 -0
- package/dist/isard_core_bg.wasm +0 -0
- package/dist/layers.d.ts +4 -1
- package/dist/layers.js +14 -5
- package/dist/layers.js.map +1 -1
- package/dist/map.d.ts +10 -2
- package/dist/map.js +172 -33
- package/dist/map.js.map +1 -1
- package/dist/terrain.js +30 -18
- package/dist/terrain.js.map +1 -1
- package/dist/types.d.ts +11 -3
- package/dist/types.js.map +1 -1
- package/dist/vectortiles.d.ts +3 -0
- package/dist/vectortiles.js +21 -5
- package/dist/vectortiles.js.map +1 -1
- package/dist/wasm/isard.d.ts +6 -5
- package/dist/wasm/isard.js +27 -10
- package/dist/wasm/isard_core.d.ts +6 -5
- package/dist/wasm/isard_core.js +35 -10
- package/package.json +1 -1
package/dist/layers.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"layers.js","sourceRoot":"","sources":["../src/layers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Handles of the layers added to a map. Each one keeps what it needs to be created again: after a WebGL context loss,\n * the map recreates its engine and every layer in order, with the same handle (its id is updated).\n */\nimport { parseColor, rampTexels, stops } from './features.ts';\nimport type { LayerHost, LonLat, NetworkOptions, NetworkStyle, RasterOptions, Tiles3dStyle } from './types.ts';\nimport type { Engine, NetworkStats, Tiles3dStats } from './wasm/isard.js';\n\nexport abstract class Layer {\n #id = -1;\n\n /** @internal */\n protected readonly map: LayerHost;\n\n /** @internal */\n constructor(map: LayerHost) {\n this.map = map;\n }\n\n /** Id of the layer in the engine */\n get id(): number {\n return this.#id;\n }\n\n /** @internal Creates the layer in an engine (again after a context loss) */\n attach(engine: Engine): void {\n this.#id = this.create(engine);\n }\n\n /** @internal */\n protected abstract create(engine: Engine): number;\n\n remove(): void {\n // Not created yet: a 3D Tiles layer waiting for the engine with 3D Tiles\n if (this.#id >= 0) this.map.engine.removeLayer(this.#id);\n this.map.detach(this);\n this.map.requestRender();\n }\n\n /** Moves the layer under `other`, or on top of every layer (above the labels of a vector basemap too) */\n moveBefore(other: Layer | undefined): void {\n this.map.moveLayer(this, other);\n }\n}\n\n/** Raster tiles (basemaps, overlays) */\nexport class RasterLayer extends Layer {\n /** @internal */\n constructor(\n map: LayerHost,\n private readonly options: Required<Omit<RasterOptions, 'size' | 'loader' | 'grid' | 'attribution'>> & {\n size: number | undefined;\n loader: RasterOptions['loader'] | undefined;\n },\n ) {\n super(map);\n }\n\n setStyle(opacity: number, saturation = 1): void {\n this.options.opacity = opacity;\n this.options.saturation = saturation;\n this.map.engine.setRasterStyle(this.id, opacity, saturation);\n this.map.requestRender();\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const { url, minZoom, maxZoom, opacity, saturation, size, loader } = this.options;\n return engine.addRaster(url, minZoom, maxZoom, opacity, saturation, size, loader);\n }\n}\n\n/** Line network colored by a value per node (travel time, water depth…) */\nexport class NetworkLayer extends Layer {\n private values: Float32Array | undefined;\n /** Node and line positions in Mercator, kept for a context loss: f32 offsets from an origin (exact to the centimetre\n * across a region, half the memory of f64) */\n private kept: { origin: [number, number]; nodes: Float32Array; lines: Float32Array | undefined } | undefined;\n\n /** @internal */\n constructor(\n map: LayerHost,\n private geometry: { nodes: Float64Array; edges: Uint32Array; lines: NetworkOptions['lines'] | undefined },\n private costs: Float32Array | undefined,\n private style: NetworkStyle,\n private edgeWidths: Float32Array | undefined,\n ) {\n super(map);\n }\n\n /** One value per node, in node order; negative (or 1e30 and above) = unreached. Costs one texture upload, drawn\n * next frame. */\n setValues(values: Float32Array): void {\n this.values = values;\n this.map.engine.setNetworkValues(this.id, values);\n this.map.requestRender();\n }\n\n /** Costs of the edges, A → B then B → A (see `NetworkOptions.costs`), when the way the network is travelled\n * changes; undefined: values interpolated along the edges. The geometry stays on the graphics card. */\n setCosts(costs: Float32Array | undefined): void {\n this.costs = costs;\n this.map.engine.setNetworkCosts(this.id, costs);\n this.map.requestRender();\n }\n\n setStyle(style: Partial<NetworkStyle>): void {\n const ramp = this.style.ramp;\n this.style = { ...this.style, ...style };\n this.map.engine.setNetworkStyle(this.id, networkStyle(this.style));\n if (this.style.ramp !== ramp)\n this.map.engine.setNetworkRamp(this.id, this.style.ramp && rampTexels(this.style.ramp).rgba);\n this.map.requestRender();\n }\n\n /** Width factor of each edge (undefined: 1 for all) */\n setEdgeWidths(widths: Float32Array | undefined): void {\n this.edgeWidths = widths;\n this.map.engine.setNetworkScales(this.id, widths);\n this.map.requestRender();\n }\n\n /** Pieces in all and drawn in the last frame */\n stats(): NetworkStats | undefined {\n return this.map.engine.networkStats(this.id);\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const { nodes, edges, lines } = this.geometry;\n let mercator: { nodes: Float64Array; lines: Float64Array | undefined };\n if (this.kept) {\n const { origin, nodes: n, lines: l } = this.kept;\n mercator = { nodes: unpack(n, origin), lines: l && unpack(l, origin) };\n } else {\n // Mercator here: Math.tan and Math.log run natively, several times faster than in WebAssembly\n mercator = { nodes: toMercator(nodes), lines: lines && toMercator(lines.points) };\n const origin: [number, number] = [mercator.nodes[0] ?? 0, mercator.nodes[1] ?? 0];\n this.kept = {\n origin,\n nodes: pack(mercator.nodes, origin),\n lines: mercator.lines && pack(mercator.lines, origin),\n };\n // The degrees are not needed again: millions of points for a region\n this.geometry = { nodes: EMPTY, edges, lines: lines && { start: lines.start, points: EMPTY } };\n }\n const id = engine.addNetwork(\n mercator.nodes,\n edges,\n lines?.start,\n mercator.lines,\n this.costs,\n networkStyle(this.style),\n );\n if (this.style.ramp) engine.setNetworkRamp(id, rampTexels(this.style.ramp).rgba);\n if (this.edgeWidths) engine.setNetworkScales(id, this.edgeWidths);\n if (this.values) engine.setNetworkValues(id, this.values);\n return id;\n }\n}\n\n/** The 25 numbers of a network style for the engine */\nfunction networkStyle(style: NetworkStyle): Float32Array {\n const { width, halo, max, contour, opacity, haloOpacity, unreachedColor, fade } = style;\n return Float32Array.from([\n ...stops(width),\n ...stops(halo),\n max,\n contour,\n opacity,\n haloOpacity,\n ...parseColor(unreachedColor),\n fade,\n ]);\n}\n\nconst EMPTY = new Float64Array(0);\n\n/** Interleaved points as f32 offsets from an origin, and back */\nfunction pack(points: Float64Array, [ox, oy]: [number, number]): Float32Array {\n const out = new Float32Array(points.length);\n for (let i = 0; i < points.length; i += 2) {\n out[i] = (points[i] ?? 0) - ox;\n out[i + 1] = (points[i + 1] ?? 0) - oy;\n }\n return out;\n}\n\nfunction unpack(points: Float32Array, [ox, oy]: [number, number]): Float64Array {\n const out = new Float64Array(points.length);\n for (let i = 0; i < points.length; i += 2) {\n out[i] = (points[i] ?? 0) + ox;\n out[i + 1] = (points[i + 1] ?? 0) + oy;\n }\n return out;\n}\n\nconst MAX_LAT = 85.051128779806589;\n\n/** Longitudes and latitudes (degrees, interleaved) to Mercator [0, 1], y towards the south */\nfunction toMercator(lonLat: Float64Array): Float64Array {\n const out = new Float64Array(lonLat.length);\n for (let i = 0; i < lonLat.length; i += 2) {\n const lat = (Math.max(-MAX_LAT, Math.min(MAX_LAT, lonLat[i + 1] ?? 0)) * Math.PI) / 180;\n out[i] = ((lonLat[i] ?? 0) + 180) / 360;\n out[i + 1] = 0.5 - Math.log(Math.tan(Math.PI / 4 + lat / 2)) / (2 * Math.PI);\n }\n return out;\n}\n\n/** Textured meshes in 3D Tiles */\nexport class Tiles3dLayer extends Layer {\n /** @internal */\n constructor(\n map: LayerHost,\n private readonly url: string,\n private style: Tiles3dStyle,\n ) {\n super(map);\n }\n\n setStyle(style: Partial<Tiles3dStyle>): void {\n this.style = { ...this.style, ...style };\n // Kept for its creation while the engine with 3D Tiles loads\n if (this.id < 0) return;\n this.map.engine.setTiles3dStyle(this.id, this.style.maxScreenSpaceError, this.style.opacity);\n this.map.requestRender();\n }\n\n /** Loading counters; undefined once the layer is removed, and while the engine with 3D Tiles loads (see\n * `GeoMapOptions.tiles3d`) */\n stats(): Tiles3dStats | undefined {\n return this.id < 0 ? undefined : this.map.engine.tiles3dStats(this.id);\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const id = engine.addTiles3d(this.url, this.style.maxScreenSpaceError);\n engine.setTiles3dStyle(id, this.style.maxScreenSpaceError, this.style.opacity);\n return id;\n }\n}\n\n/** A texture of a ground layer (see `GroundLayer`) */\nexport interface GroundTexture {\n /** `r8`, `r8ui`, `r16ui`, `r16i`, `r32ui`, `r32f`, `rg16ui`, `rg32f`, `rgba8`, `rgba8ui`, `rgba16ui`, `rgba32f`:\n * integer formats are read with `usampler2D` / `isampler2D` and `texelFetch` */\n format: string;\n width: number;\n height: number;\n /** Layers of a 2D array (`sampler2DArray`, `usampler2DArray`…); 0 or undefined: a 2D texture */\n depth?: number;\n /** Linear filtering (non-integer formats); default nearest */\n linear?: boolean;\n /** Texels row after row (layer after layer), any typed array; undefined: left empty */\n data?: ArrayBufferView;\n}\n\nexport interface GroundOptions {\n /**\n * GLSL ES 3.0 defining `vec4 ground(vec2 offset)`: the color of the ground (premultiplied alpha, 0 for nothing) at\n * `offset`, the Mercator offset of the pixel from `anchor` (times `ISARD_EARTH`: metres of EPSG:3857), exact to\n * the millimetre at any zoom. The code declares its own uniforms and samplers; also there: `u_zoom`,\n * `u_pixel_ratio`\n */\n code: string;\n /** Where the offsets are taken from */\n anchor: LonLat;\n /** Box it shows in, `[west, south, east, north]` (default the world): only the ground there is drawn again */\n bounds?: [west: number, south: number, east: number, north: number];\n textures?: Record<string, GroundTexture>;\n uniforms?: Record<string, number | readonly number[]>;\n}\n\nconst bytesOf = (data: ArrayBufferView) => new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n\n/** The application's fragment shader run over the ground, draped on the relief (water depth, heat maps…) */\nexport class GroundLayer extends Layer {\n private readonly textures = new Map<string, GroundTexture>();\n private readonly uniforms = new Map<string, number[]>();\n private visible = true;\n\n /** @internal */\n constructor(\n map: LayerHost,\n private readonly options: GroundOptions,\n ) {\n super(map);\n for (const [name, texture] of Object.entries(options.textures ?? {})) this.textures.set(name, texture);\n for (const [name, value] of Object.entries(options.uniforms ?? {})) this.uniforms.set(name, [value].flat());\n }\n\n /** Creates or replaces a texture of the code's sampler `name` */\n setTexture(name: string, texture: GroundTexture): void {\n this.textures.set(name, texture);\n this.sendTexture(this.map.engine, this.id, name, texture);\n this.map.requestRender();\n }\n\n /**\n * Replaces a region of a texture: `data` holds `width` × `height` texels for (`x`, `y`) of `layer` (2D arrays).\n * Keep the texture's own `data` up to date too if it must survive a WebGL context loss.\n */\n updateTexture(\n name: string,\n data: ArrayBufferView,\n region: { x?: number; y?: number; layer?: number; width: number; height: number },\n ): void {\n const { x = 0, y = 0, layer = 0, width, height } = region;\n this.map.engine.updateGroundTexture(this.id, name, x, y, layer, width, height, bytesOf(data));\n this.map.requestRender();\n }\n\n /** A uniform of the code: a number, or numbers for vectors, arrays and matrices (column major) */\n setUniform(name: string, value: number | readonly number[]): void {\n const values = [value].flat();\n this.uniforms.set(name, values);\n this.map.engine.setGroundUniform(this.id, name, Float64Array.from(values));\n this.map.requestRender();\n }\n\n setBounds(bounds: [west: number, south: number, east: number, north: number]): void {\n this.options.bounds = bounds;\n this.map.engine.setGroundBounds(this.id, ...mercatorBox(bounds));\n this.map.requestRender();\n }\n\n setVisible(visible: boolean): void {\n this.visible = visible;\n this.map.engine.setGroundVisible(this.id, visible);\n this.map.requestRender();\n }\n\n private sendTexture(engine: Engine, id: number, name: string, t: GroundTexture): void {\n const data = t.data && bytesOf(t.data);\n engine.setGroundTexture(id, name, t.format, t.width, t.height, t.depth ?? 0, t.linear ?? false, data);\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const [ax, ay] = mercatorPoint(this.options.anchor);\n const id = engine.addGround(\n this.options.code,\n ax,\n ay,\n ...mercatorBox(this.options.bounds ?? [-180, -85.06, 180, 85.06]),\n );\n for (const [name, texture] of this.textures) this.sendTexture(engine, id, name, texture);\n for (const [name, values] of this.uniforms) engine.setGroundUniform(id, name, Float64Array.from(values));\n engine.setGroundVisible(id, this.visible);\n return id;\n }\n}\n\nfunction mercatorPoint([lon, lat]: LonLat): [number, number] {\n const out = toMercator(Float64Array.of(lon, lat));\n return [out[0] ?? 0, out[1] ?? 0];\n}\n\n/** A lon/lat box to Mercator min x, min y, max x, max y (y towards the south) */\nfunction mercatorBox([west, south, east, north]: [number, number, number, number]): [number, number, number, number] {\n const [x0, y1] = mercatorPoint([west, south]);\n const [x1, y0] = mercatorPoint([east, north]);\n return [x0, y0, x1, y1];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"layers.js","sourceRoot":"","sources":["../src/layers.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Handles of the layers added to a map. Each one keeps what it needs to be created again: after a WebGL context loss,\n * the map recreates its engine and every layer in order, with the same handle (its id is updated).\n */\nimport { parseColor, rampTexels, stops } from './features.ts';\nimport type {\n LayerHost,\n LonLat,\n NetworkOptions,\n NetworkStyle,\n RasterOptions,\n RasterStyle,\n Tiles3dStyle,\n} from './types.ts';\nimport type { Engine, NetworkStats, Tiles3dStats } from './wasm/isard.js';\n\nexport abstract class Layer {\n #id = -1;\n\n /** @internal */\n protected readonly map: LayerHost;\n\n /** @internal */\n constructor(map: LayerHost) {\n this.map = map;\n }\n\n /** Id of the layer in the engine */\n get id(): number {\n return this.#id;\n }\n\n /** @internal Creates the layer in an engine (again after a context loss); its id is -1 if that fails */\n attach(engine: Engine): void {\n this.#id = -1;\n this.#id = this.create(engine);\n }\n\n /** @internal Forgets its id in an engine that is gone (before the layers are created in a new one) */\n forgetEngine(): void {\n this.#id = -1;\n }\n\n /** @internal Sends what refers to other layers, once every layer of a new engine has its id */\n relink(_engine: Engine): void {}\n\n /** @internal */\n protected abstract create(engine: Engine): number;\n\n remove(): void {\n // Not created yet: a 3D Tiles layer waiting for the engine with 3D Tiles\n if (this.#id >= 0) this.map.engine.removeLayer(this.#id);\n this.#id = -1;\n this.map.detach(this);\n this.map.requestRender();\n }\n\n /** Moves the layer under `other`, or on top of every layer (above the labels of a vector basemap too) */\n moveBefore(other: Layer | undefined): void {\n this.map.moveLayer(this, other);\n }\n}\n\n/** Raster tiles (basemaps, overlays) */\nexport class RasterLayer extends Layer {\n /** @internal */\n constructor(\n map: LayerHost,\n private readonly options: Required<Omit<RasterOptions, 'size' | 'loader' | 'grid' | 'attribution'>> & {\n size: number | undefined;\n loader: RasterOptions['loader'] | undefined;\n },\n ) {\n super(map);\n }\n\n /** Changes the opacity or saturation, the other kept */\n setStyle(style: Partial<RasterStyle>): void;\n /** @deprecated Positional form (saturation back to 1 when not given): `setStyle({ opacity, saturation })` */\n setStyle(opacity: number, saturation?: number): void;\n setStyle(style: Partial<RasterStyle> | number, saturation = 1): void {\n const changed = typeof style === 'number' ? { opacity: style, saturation } : style;\n this.options.opacity = changed.opacity ?? this.options.opacity;\n this.options.saturation = changed.saturation ?? this.options.saturation;\n this.map.engine.setRasterStyle(this.id, this.options.opacity, this.options.saturation);\n this.map.requestRender();\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const { url, minZoom, maxZoom, opacity, saturation, size, loader } = this.options;\n return engine.addRaster(url, minZoom, maxZoom, opacity, saturation, size, loader);\n }\n}\n\n/** Line network colored by a value per node (travel time, water depth…) */\nexport class NetworkLayer extends Layer {\n private values: Float32Array | undefined;\n /** Node and line positions in Mercator, kept for a context loss: f32 offsets from an origin (exact to the centimetre\n * across a region, half the memory of f64) */\n private kept: { origin: [number, number]; nodes: Float32Array; lines: Float32Array | undefined } | undefined;\n\n /** @internal */\n constructor(\n map: LayerHost,\n private geometry: { nodes: Float64Array; edges: Uint32Array; lines: NetworkOptions['lines'] | undefined },\n private costs: Float32Array | undefined,\n private style: NetworkStyle,\n private edgeWidths: Float32Array | undefined,\n ) {\n super(map);\n }\n\n /** One value per node, in node order; negative (or 1e30 and above) = unreached. Costs one texture upload, drawn\n * next frame. */\n setValues(values: Float32Array): void {\n this.values = values;\n this.map.engine.setNetworkValues(this.id, values);\n this.map.requestRender();\n }\n\n /** Costs of the edges, A → B then B → A (see `NetworkOptions.costs`), when the way the network is travelled\n * changes; undefined: values interpolated along the edges. The geometry stays on the graphics card. */\n setCosts(costs: Float32Array | undefined): void {\n this.costs = costs;\n this.map.engine.setNetworkCosts(this.id, costs);\n this.map.requestRender();\n }\n\n setStyle(style: Partial<NetworkStyle>): void {\n const ramp = this.style.ramp;\n this.style = { ...this.style, ...style };\n this.map.engine.setNetworkStyle(this.id, networkStyle(this.style));\n if (this.style.ramp !== ramp)\n this.map.engine.setNetworkRamp(this.id, this.style.ramp && rampTexels(this.style.ramp).rgba);\n this.map.requestRender();\n }\n\n /** Width factor of each edge (undefined: 1 for all) */\n setEdgeWidths(widths: Float32Array | undefined): void {\n this.edgeWidths = widths;\n this.map.engine.setNetworkScales(this.id, widths);\n this.map.requestRender();\n }\n\n /** Pieces in all and drawn in the last frame */\n stats(): NetworkStats | undefined {\n return this.map.engine.networkStats(this.id);\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const { nodes, edges, lines } = this.geometry;\n let mercator: { nodes: Float64Array; lines: Float64Array | undefined };\n if (this.kept) {\n const { origin, nodes: n, lines: l } = this.kept;\n mercator = { nodes: unpack(n, origin), lines: l && unpack(l, origin) };\n } else {\n // Mercator here: Math.tan and Math.log run natively, several times faster than in WebAssembly\n mercator = { nodes: toMercator(nodes), lines: lines && toMercator(lines.points) };\n const origin: [number, number] = [mercator.nodes[0] ?? 0, mercator.nodes[1] ?? 0];\n this.kept = {\n origin,\n nodes: pack(mercator.nodes, origin),\n lines: mercator.lines && pack(mercator.lines, origin),\n };\n // The degrees are not needed again: millions of points for a region\n this.geometry = { nodes: EMPTY, edges, lines: lines && { start: lines.start, points: EMPTY } };\n }\n const id = engine.addNetwork(\n mercator.nodes,\n edges,\n lines?.start,\n mercator.lines,\n this.costs,\n networkStyle(this.style),\n );\n if (this.style.ramp) engine.setNetworkRamp(id, rampTexels(this.style.ramp).rgba);\n if (this.edgeWidths) engine.setNetworkScales(id, this.edgeWidths);\n if (this.values) engine.setNetworkValues(id, this.values);\n return id;\n }\n}\n\n/** The 25 numbers of a network style for the engine */\nfunction networkStyle(style: NetworkStyle): Float32Array {\n const { width, halo, max, contour, opacity, haloOpacity, unreachedColor, fade } = style;\n return Float32Array.from([\n ...stops(width),\n ...stops(halo),\n max,\n contour,\n opacity,\n haloOpacity,\n ...parseColor(unreachedColor),\n fade,\n ]);\n}\n\nconst EMPTY = new Float64Array(0);\n\n/** Interleaved points as f32 offsets from an origin, and back */\nfunction pack(points: Float64Array, [ox, oy]: [number, number]): Float32Array {\n const out = new Float32Array(points.length);\n for (let i = 0; i < points.length; i += 2) {\n out[i] = (points[i] ?? 0) - ox;\n out[i + 1] = (points[i + 1] ?? 0) - oy;\n }\n return out;\n}\n\nfunction unpack(points: Float32Array, [ox, oy]: [number, number]): Float64Array {\n const out = new Float64Array(points.length);\n for (let i = 0; i < points.length; i += 2) {\n out[i] = (points[i] ?? 0) + ox;\n out[i + 1] = (points[i + 1] ?? 0) + oy;\n }\n return out;\n}\n\nconst MAX_LAT = 85.051128779806589;\n\n/** Longitudes and latitudes (degrees, interleaved) to Mercator [0, 1], y towards the south */\nfunction toMercator(lonLat: Float64Array): Float64Array {\n const out = new Float64Array(lonLat.length);\n for (let i = 0; i < lonLat.length; i += 2) {\n const lat = (Math.max(-MAX_LAT, Math.min(MAX_LAT, lonLat[i + 1] ?? 0)) * Math.PI) / 180;\n out[i] = ((lonLat[i] ?? 0) + 180) / 360;\n out[i + 1] = 0.5 - Math.log(Math.tan(Math.PI / 4 + lat / 2)) / (2 * Math.PI);\n }\n return out;\n}\n\n/** Textured meshes in 3D Tiles */\nexport class Tiles3dLayer extends Layer {\n /** @internal */\n constructor(\n map: LayerHost,\n private readonly url: string,\n private style: Tiles3dStyle,\n ) {\n super(map);\n }\n\n setStyle(style: Partial<Tiles3dStyle>): void {\n this.style = { ...this.style, ...style };\n // Kept for its creation while the engine with 3D Tiles loads\n if (this.id < 0) return;\n this.map.engine.setTiles3dStyle(this.id, this.style.maxScreenSpaceError, this.style.opacity);\n this.map.requestRender();\n }\n\n /** Loading counters; undefined once the layer is removed, and while the engine with 3D Tiles loads (see\n * `GeoMapOptions.tiles3d`) */\n stats(): Tiles3dStats | undefined {\n return this.id < 0 ? undefined : this.map.engine.tiles3dStats(this.id);\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const id = engine.addTiles3d(this.url, this.style.maxScreenSpaceError);\n engine.setTiles3dStyle(id, this.style.maxScreenSpaceError, this.style.opacity);\n return id;\n }\n}\n\n/** A texture of a ground layer (see `GroundLayer`) */\nexport interface GroundTexture {\n /** `r8`, `r8ui`, `r16ui`, `r16i`, `r32ui`, `r32f`, `rg16ui`, `rg32f`, `rgba8`, `rgba8ui`, `rgba16ui`, `rgba32f`:\n * integer formats are read with `usampler2D` / `isampler2D` and `texelFetch` */\n format: string;\n width: number;\n height: number;\n /** Layers of a 2D array (`sampler2DArray`, `usampler2DArray`…); 0 or undefined: a 2D texture */\n depth?: number;\n /** Linear filtering (non-integer formats); default nearest */\n linear?: boolean;\n /** Texels row after row (layer after layer), any typed array; undefined: left empty */\n data?: ArrayBufferView;\n}\n\nexport interface GroundOptions {\n /**\n * GLSL ES 3.0 defining `vec4 ground(vec2 offset)`: the color of the ground (premultiplied alpha, 0 for nothing) at\n * `offset`, the Mercator offset of the pixel from `anchor` (times `ISARD_EARTH`: metres of EPSG:3857), exact to\n * the millimetre at any zoom. The code declares its own uniforms and samplers; also there: `u_zoom`,\n * `u_pixel_ratio`\n */\n code: string;\n /** Where the offsets are taken from */\n anchor: LonLat;\n /** Box it shows in, `[west, south, east, north]` (default the world): only the ground there is drawn again */\n bounds?: [west: number, south: number, east: number, north: number];\n textures?: Record<string, GroundTexture>;\n uniforms?: Record<string, number | readonly number[]>;\n}\n\nconst bytesOf = (data: ArrayBufferView) => new Uint8Array(data.buffer, data.byteOffset, data.byteLength);\n\n/** The application's fragment shader run over the ground, draped on the relief (water depth, heat maps…) */\nexport class GroundLayer extends Layer {\n private readonly textures = new Map<string, GroundTexture>();\n private readonly uniforms = new Map<string, number[]>();\n private visible = true;\n\n /** @internal */\n constructor(\n map: LayerHost,\n private readonly options: GroundOptions,\n ) {\n super(map);\n for (const [name, texture] of Object.entries(options.textures ?? {})) this.textures.set(name, texture);\n for (const [name, value] of Object.entries(options.uniforms ?? {})) this.uniforms.set(name, [value].flat());\n }\n\n /** Creates or replaces a texture of the code's sampler `name` */\n setTexture(name: string, texture: GroundTexture): void {\n this.textures.set(name, texture);\n this.sendTexture(this.map.engine, this.id, name, texture);\n this.map.requestRender();\n }\n\n /**\n * Replaces a region of a texture: `data` holds `width` × `height` texels for (`x`, `y`) of `layer` (2D arrays).\n * Keep the texture's own `data` up to date too if it must survive a WebGL context loss.\n */\n updateTexture(\n name: string,\n data: ArrayBufferView,\n region: { x?: number; y?: number; layer?: number; width: number; height: number },\n ): void {\n const { x = 0, y = 0, layer = 0, width, height } = region;\n this.map.engine.updateGroundTexture(this.id, name, x, y, layer, width, height, bytesOf(data));\n this.map.requestRender();\n }\n\n /** A uniform of the code: a number, or numbers for vectors, arrays and matrices (column major) */\n setUniform(name: string, value: number | readonly number[]): void {\n const values = [value].flat();\n this.uniforms.set(name, values);\n this.map.engine.setGroundUniform(this.id, name, Float64Array.from(values));\n this.map.requestRender();\n }\n\n setBounds(bounds: [west: number, south: number, east: number, north: number]): void {\n this.options.bounds = bounds;\n this.map.engine.setGroundBounds(this.id, ...mercatorBox(bounds));\n this.map.requestRender();\n }\n\n setVisible(visible: boolean): void {\n this.visible = visible;\n this.map.engine.setGroundVisible(this.id, visible);\n this.map.requestRender();\n }\n\n private sendTexture(engine: Engine, id: number, name: string, t: GroundTexture): void {\n const data = t.data && bytesOf(t.data);\n engine.setGroundTexture(id, name, t.format, t.width, t.height, t.depth ?? 0, t.linear ?? false, data);\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const [ax, ay] = mercatorPoint(this.options.anchor);\n const id = engine.addGround(\n this.options.code,\n ax,\n ay,\n ...mercatorBox(this.options.bounds ?? [-180, -85.06, 180, 85.06]),\n );\n for (const [name, texture] of this.textures) this.sendTexture(engine, id, name, texture);\n for (const [name, values] of this.uniforms) engine.setGroundUniform(id, name, Float64Array.from(values));\n engine.setGroundVisible(id, this.visible);\n return id;\n }\n}\n\nfunction mercatorPoint([lon, lat]: LonLat): [number, number] {\n const out = toMercator(Float64Array.of(lon, lat));\n return [out[0] ?? 0, out[1] ?? 0];\n}\n\n/** A lon/lat box to Mercator min x, min y, max x, max y (y towards the south) */\nfunction mercatorBox([west, south, east, north]: [number, number, number, number]): [number, number, number, number] {\n const [x0, y1] = mercatorPoint([west, south]);\n const [x1, y0] = mercatorPoint([east, north]);\n return [x0, y0, x1, y1];\n}\n"]}
|
package/dist/map.d.ts
CHANGED
|
@@ -58,6 +58,8 @@ export declare class GeoMap {
|
|
|
58
58
|
private hoverPoint;
|
|
59
59
|
/** Frame polling the engine for the answer of the hover picking, 0 if none */
|
|
60
60
|
private hoverPoll;
|
|
61
|
+
/** Polls of the hover picking under way: given up after `MAX_POLLS` (an answer that never comes) */
|
|
62
|
+
private hoverPolls;
|
|
61
63
|
/** What 'hoverfeature' looks for: within `radius` CSS pixels, in `layers` only if given */
|
|
62
64
|
hoverPicking: {
|
|
63
65
|
radius?: number;
|
|
@@ -76,6 +78,8 @@ export declare class GeoMap {
|
|
|
76
78
|
private basemapPool;
|
|
77
79
|
/** Stops watching the device pixel ratio */
|
|
78
80
|
private unwatchRatio;
|
|
81
|
+
/** Stops listening to the canvas's context loss and restoration */
|
|
82
|
+
private readonly unwatchContext;
|
|
79
83
|
/** Loads the engine (once per page) and creates a map filling `container` */
|
|
80
84
|
static create(container: HTMLElement, options?: GeoMapOptions): Promise<GeoMap>;
|
|
81
85
|
private constructor();
|
|
@@ -88,6 +92,9 @@ export declare class GeoMap {
|
|
|
88
92
|
/** A 3D Tiles layer on the core engine: loads the engine with 3D Tiles, then rebuilds the map on it (camera,
|
|
89
93
|
* settings and layers kept, as after a context loss); the layer is created then */
|
|
90
94
|
private upgrade;
|
|
95
|
+
/** Downloads and compiles the engine with 3D Tiles once the map is idle (`tiles3d: 'preload'`), without running
|
|
96
|
+
* it: the first 3D Tiles layer then only instantiates it */
|
|
97
|
+
private preloadTiles3d;
|
|
91
98
|
/** After a context loss: a new engine with the same camera, settings and layers (same handles, same order) */
|
|
92
99
|
private restore;
|
|
93
100
|
/** Takes a layer out of the drawing order (to put it back elsewhere, or for good) */
|
|
@@ -132,8 +139,9 @@ export declare class GeoMap {
|
|
|
132
139
|
/** Tile counters of the raster layers, for diagnostics */
|
|
133
140
|
stats(): RasterLayerStats[];
|
|
134
141
|
/**
|
|
135
|
-
*
|
|
136
|
-
*
|
|
142
|
+
* The feature under a screen point (CSS pixels), undefined if none: its layer id and index. Reads one pixel of an
|
|
143
|
+
* offscreen picking pass, whatever the number of features, but waits for the GPU to finish the frame (a stall): for
|
|
144
|
+
* clicks and one-off queries. On hover, listen to 'hoverfeature' instead, which picks without waiting.
|
|
137
145
|
*/
|
|
138
146
|
pick(point: Point, radius?: number, layers?: readonly Layer[]): PickHit | undefined;
|
|
139
147
|
/**
|
package/dist/map.js
CHANGED
|
@@ -44,6 +44,28 @@ function report(error) {
|
|
|
44
44
|
* every map; `full` with them, loaded for the first 3D Tiles layer, its module shared with the decoding workers. The
|
|
45
45
|
* core engine has the same API but the 3D Tiles methods: its class is typed as the full one. */
|
|
46
46
|
const engines = {};
|
|
47
|
+
/** The modules compiled (downloaded and compiled off the main thread, not instantiated): `tiles3d: 'preload'`
|
|
48
|
+
* compiles the full engine ahead, its first 3D Tiles layer then only instantiates it */
|
|
49
|
+
const modules = {};
|
|
50
|
+
/** @internal Forgets the engines loaded (tests) */
|
|
51
|
+
export function forgetEngines() {
|
|
52
|
+
for (const kind of ['core', 'full']) {
|
|
53
|
+
delete engines[kind];
|
|
54
|
+
delete modules[kind];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
function compileEngine(kind, url) {
|
|
58
|
+
const compiled = modules[kind];
|
|
59
|
+
if (compiled)
|
|
60
|
+
return compiled;
|
|
61
|
+
const compiling = compile(url).catch((error) => {
|
|
62
|
+
// A later call tries again (a network error, a wrong URL fixed)
|
|
63
|
+
delete modules[kind];
|
|
64
|
+
throw error;
|
|
65
|
+
});
|
|
66
|
+
modules[kind] = compiling;
|
|
67
|
+
return compiling;
|
|
68
|
+
}
|
|
47
69
|
function loadEngine(kind, url) {
|
|
48
70
|
const loaded = engines[kind];
|
|
49
71
|
if (loaded)
|
|
@@ -51,13 +73,12 @@ function loadEngine(kind, url) {
|
|
|
51
73
|
const loading = (async () => {
|
|
52
74
|
// The bindings by dynamic import: an application bundles the ones it loads only
|
|
53
75
|
const [module, bindings] = await Promise.all([
|
|
54
|
-
|
|
76
|
+
compileEngine(kind, url),
|
|
55
77
|
kind === 'core' ? import('./wasm/isard_core.js') : import('./wasm/isard.js'),
|
|
56
78
|
]);
|
|
57
79
|
await bindings.default({ module_or_path: module });
|
|
58
80
|
return { module, Engine: bindings.Engine };
|
|
59
81
|
})().catch((error) => {
|
|
60
|
-
// A later call tries again (a network error, a wrong URL fixed)
|
|
61
82
|
delete engines[kind];
|
|
62
83
|
throw error;
|
|
63
84
|
});
|
|
@@ -164,12 +185,19 @@ function terrainSettings(terrain, body, radius) {
|
|
|
164
185
|
if (url === undefined)
|
|
165
186
|
throw new Error('isard: the relief of this body needs a url');
|
|
166
187
|
const encoding = options.encoding ?? 'float32';
|
|
188
|
+
// PNG encodings are fetched tile by tile: a {bbox} or an image service would be fetched as it is
|
|
189
|
+
if (encoding !== 'float32' &&
|
|
190
|
+
(IMAGE_SERVER.test(url) || !/\{z\}/.test(url) || !/\{x\}/.test(url) || !/\{y\}/.test(url))) {
|
|
191
|
+
throw new Error(`isard: the '${encoding}' terrain encoding takes a tile URL with {z}, {x} and {y} (${url})`);
|
|
192
|
+
}
|
|
167
193
|
return {
|
|
168
194
|
url: IMAGE_SERVER.test(url) ? imageServerTerrain(url, earth, radius) : url,
|
|
169
195
|
exaggeration,
|
|
170
196
|
maxZoom: options.maxZoom ?? (options.url === undefined && preset ? preset.maxZoom : 15),
|
|
171
197
|
geoid: options.geoid ?? false,
|
|
172
198
|
...(encoding === 'float32' ? {} : { loader: terrainLoader(url, encoding) }),
|
|
199
|
+
// NASA's credits for its models
|
|
200
|
+
...(options.url === undefined && preset ? { attribution: preset.attribution } : {}),
|
|
173
201
|
};
|
|
174
202
|
}
|
|
175
203
|
/** Sky settings for the engine: colors (RGB 0-1) and blends, MapLibre's defaults */
|
|
@@ -217,6 +245,16 @@ function rgb(color) {
|
|
|
217
245
|
return [r, g, b];
|
|
218
246
|
}
|
|
219
247
|
const CORNERS = ['top-left', 'top-right', 'bottom-left', 'bottom-right'];
|
|
248
|
+
/** Frames the hover picking waits for its answer at most (usually one) */
|
|
249
|
+
const MAX_POLLS = 30;
|
|
250
|
+
/** The name of a basemap, checked: an unknown one throws */
|
|
251
|
+
function checkBasemap(basemap) {
|
|
252
|
+
const name = basemapName(basemap);
|
|
253
|
+
if (name !== 'none' && !(name in VECTOR_BASEMAPS) && !(name in BASEMAPS)) {
|
|
254
|
+
throw new Error(`isard: unknown basemap '${basemap}'`);
|
|
255
|
+
}
|
|
256
|
+
return name;
|
|
257
|
+
}
|
|
220
258
|
/** A map (see `GeoMap.create`); layers take it as their host */
|
|
221
259
|
export class GeoMap {
|
|
222
260
|
canvas;
|
|
@@ -279,6 +317,8 @@ export class GeoMap {
|
|
|
279
317
|
hoverPoint;
|
|
280
318
|
/** Frame polling the engine for the answer of the hover picking, 0 if none */
|
|
281
319
|
hoverPoll = 0;
|
|
320
|
+
/** Polls of the hover picking under way: given up after `MAX_POLLS` (an answer that never comes) */
|
|
321
|
+
hoverPolls = 0;
|
|
282
322
|
/** What 'hoverfeature' looks for: within `radius` CSS pixels, in `layers` only if given */
|
|
283
323
|
hoverPicking = {};
|
|
284
324
|
frameRequest = 0;
|
|
@@ -294,14 +334,22 @@ export class GeoMap {
|
|
|
294
334
|
basemapPool;
|
|
295
335
|
/** Stops watching the device pixel ratio */
|
|
296
336
|
unwatchRatio;
|
|
337
|
+
/** Stops listening to the canvas's context loss and restoration */
|
|
338
|
+
unwatchContext;
|
|
297
339
|
/** Loads the engine (once per page) and creates a map filling `container` */
|
|
298
340
|
static async create(container, options = {}) {
|
|
299
341
|
// With 3D Tiles from the start when asked, or when only that engine's URL is given (as before the core engine)
|
|
300
342
|
const full = options.tiles3d === true || (options.wasmUrl !== undefined && options.coreWasmUrl === undefined);
|
|
343
|
+
// Before anything is created
|
|
344
|
+
if (options.basemap !== undefined)
|
|
345
|
+
checkBasemap(options.basemap);
|
|
301
346
|
const bindings = full
|
|
302
347
|
? await loadEngine('full', options.wasmUrl ?? new URL('./isard_bg.wasm', import.meta.url))
|
|
303
348
|
: await loadEngine('core', options.coreWasmUrl ?? new URL('./isard_core_bg.wasm', import.meta.url));
|
|
304
|
-
|
|
349
|
+
const map = new GeoMap(container, options, bindings.Engine, full ? bindings.module : undefined);
|
|
350
|
+
if (options.tiles3d === 'preload' && !full)
|
|
351
|
+
map.preloadTiles3d();
|
|
352
|
+
return map;
|
|
305
353
|
}
|
|
306
354
|
constructor(container, options, engineClass, tiles3dModule) {
|
|
307
355
|
this.engineClass = engineClass;
|
|
@@ -348,13 +396,19 @@ export class GeoMap {
|
|
|
348
396
|
};
|
|
349
397
|
this.#engine = this.createEngine();
|
|
350
398
|
// The browser may take the GPU away (driver reset, background tab on mobile): the map waits, then rebuilds
|
|
351
|
-
|
|
399
|
+
const lost = (event) => {
|
|
352
400
|
event.preventDefault();
|
|
353
401
|
this.lost = true;
|
|
354
402
|
cancelAnimationFrame(this.frameRequest);
|
|
355
403
|
this.frameRequest = 0;
|
|
356
|
-
}
|
|
357
|
-
|
|
404
|
+
};
|
|
405
|
+
const restored = () => this.restore();
|
|
406
|
+
this.canvas.addEventListener('webglcontextlost', lost);
|
|
407
|
+
this.canvas.addEventListener('webglcontextrestored', restored);
|
|
408
|
+
this.unwatchContext = () => {
|
|
409
|
+
this.canvas.removeEventListener('webglcontextlost', lost);
|
|
410
|
+
this.canvas.removeEventListener('webglcontextrestored', restored);
|
|
411
|
+
};
|
|
358
412
|
const start = this.earth
|
|
359
413
|
? { center: [2.4246, 48.8457], zoom: 13, pitch: 0, bearing: 0 }
|
|
360
414
|
: { center: [0, 0], zoom: 2, pitch: 0, bearing: 0 };
|
|
@@ -422,7 +476,10 @@ export class GeoMap {
|
|
|
422
476
|
* settings and layers kept, as after a context loss); the layer is created then */
|
|
423
477
|
upgrade() {
|
|
424
478
|
const url = this.tiles3dOptions.wasmUrl ?? new URL('./isard_bg.wasm', import.meta.url);
|
|
425
|
-
this.upgrading ??= loadEngine('full', url)
|
|
479
|
+
this.upgrading ??= loadEngine('full', url)
|
|
480
|
+
// The map is rebuilt in a task of its own, not in the one that instantiated the engine: two shorter tasks
|
|
481
|
+
.then((bindings) => new Promise((resolve) => setTimeout(() => resolve(bindings), 0)))
|
|
482
|
+
.then(({ module, Engine }) => {
|
|
426
483
|
this.upgrading = undefined;
|
|
427
484
|
if (this.gone)
|
|
428
485
|
return;
|
|
@@ -434,12 +491,39 @@ export class GeoMap {
|
|
|
434
491
|
}, (error) => {
|
|
435
492
|
// The 3D Tiles layers stay empty; the next one added tries again
|
|
436
493
|
this.upgrading = undefined;
|
|
494
|
+
if (this.gone)
|
|
495
|
+
return;
|
|
437
496
|
report(error);
|
|
438
497
|
this.requestRender();
|
|
439
498
|
});
|
|
440
499
|
}
|
|
500
|
+
/** Downloads and compiles the engine with 3D Tiles once the map is idle (`tiles3d: 'preload'`), without running
|
|
501
|
+
* it: the first 3D Tiles layer then only instantiates it */
|
|
502
|
+
preloadTiles3d() {
|
|
503
|
+
const url = this.tiles3dOptions.wasmUrl ?? new URL('./isard_bg.wasm', import.meta.url);
|
|
504
|
+
const start = () => {
|
|
505
|
+
if (!this.gone && !this.tiles3dModule)
|
|
506
|
+
compileEngine('full', url).catch(() => undefined);
|
|
507
|
+
};
|
|
508
|
+
const later = () => {
|
|
509
|
+
if (typeof requestIdleCallback === 'function')
|
|
510
|
+
requestIdleCallback(start, { timeout: 2000 });
|
|
511
|
+
else
|
|
512
|
+
setTimeout(start, 0);
|
|
513
|
+
};
|
|
514
|
+
if (this.settled)
|
|
515
|
+
later();
|
|
516
|
+
else {
|
|
517
|
+
const off = this.on('idle', () => {
|
|
518
|
+
off();
|
|
519
|
+
later();
|
|
520
|
+
});
|
|
521
|
+
}
|
|
522
|
+
}
|
|
441
523
|
/** After a context loss: a new engine with the same camera, settings and layers (same handles, same order) */
|
|
442
524
|
restore() {
|
|
525
|
+
if (this.gone)
|
|
526
|
+
return;
|
|
443
527
|
this.cancelHoverPick();
|
|
444
528
|
const camera = this.getCamera();
|
|
445
529
|
this.#engine.free();
|
|
@@ -447,16 +531,46 @@ export class GeoMap {
|
|
|
447
531
|
this.lost = false;
|
|
448
532
|
this.setCamera(camera);
|
|
449
533
|
this.#glyphs?.attach(this.#engine);
|
|
534
|
+
const engine = this.#engine;
|
|
535
|
+
// No layer refers to an id of the old engine while the others are created
|
|
450
536
|
for (const layer of this.layers)
|
|
451
|
-
layer.
|
|
537
|
+
layer.forgetEngine();
|
|
538
|
+
for (const layer of this.layers) {
|
|
539
|
+
// Still waiting for the engine with 3D Tiles (loading, or failed): created with it
|
|
540
|
+
if (layer instanceof Tiles3dLayer && !this.tiles3dModule)
|
|
541
|
+
continue;
|
|
542
|
+
// A layer that fails is reported and left out; the others are created
|
|
543
|
+
try {
|
|
544
|
+
layer.attach(engine);
|
|
545
|
+
}
|
|
546
|
+
catch (error) {
|
|
547
|
+
report(error);
|
|
548
|
+
}
|
|
549
|
+
}
|
|
550
|
+
// Links between layers, once every layer has its new id (buildings colored by a network above them)
|
|
551
|
+
for (const layer of this.layers) {
|
|
552
|
+
if (layer.id < 0)
|
|
553
|
+
continue;
|
|
554
|
+
try {
|
|
555
|
+
layer.relink(engine);
|
|
556
|
+
}
|
|
557
|
+
catch (error) {
|
|
558
|
+
report(error);
|
|
559
|
+
}
|
|
560
|
+
}
|
|
452
561
|
this.resize();
|
|
453
562
|
}
|
|
454
563
|
/** @internal Forgets a removed layer */
|
|
455
564
|
detach(layer) {
|
|
456
565
|
this.unlist(layer);
|
|
566
|
+
this.onTop.delete(layer);
|
|
457
567
|
if (this.rasterCredits.delete(layer))
|
|
458
568
|
this.attributionChanged();
|
|
459
569
|
}
|
|
570
|
+
/** @internal The layer is on the map */
|
|
571
|
+
hasLayer(layer) {
|
|
572
|
+
return !this.gone && this.layers.includes(layer);
|
|
573
|
+
}
|
|
460
574
|
/** Takes a layer out of the drawing order (to put it back elsewhere, or for good) */
|
|
461
575
|
unlist(layer) {
|
|
462
576
|
const index = this.layers.indexOf(layer);
|
|
@@ -688,8 +802,9 @@ export class GeoMap {
|
|
|
688
802
|
return this.engine.stats();
|
|
689
803
|
}
|
|
690
804
|
/**
|
|
691
|
-
*
|
|
692
|
-
*
|
|
805
|
+
* The feature under a screen point (CSS pixels), undefined if none: its layer id and index. Reads one pixel of an
|
|
806
|
+
* offscreen picking pass, whatever the number of features, but waits for the GPU to finish the frame (a stall): for
|
|
807
|
+
* clicks and one-off queries. On hover, listen to 'hoverfeature' instead, which picks without waiting.
|
|
693
808
|
*/
|
|
694
809
|
pick(point, radius = 0, layers) {
|
|
695
810
|
const only = layers && Uint32Array.from(layers.map((l) => l.id));
|
|
@@ -718,10 +833,15 @@ export class GeoMap {
|
|
|
718
833
|
requestHoverPick(point) {
|
|
719
834
|
const { radius = 0, layers } = this.hoverPicking;
|
|
720
835
|
const only = layers && Uint32Array.from(layers.map((l) => l.id));
|
|
721
|
-
//
|
|
722
|
-
if (!this.engine.requestPick(point[0], point[1], radius, only)
|
|
836
|
+
// The engine cannot pick (no request in flight): the poll under way would wait for nothing
|
|
837
|
+
if (!this.engine.requestPick(point[0], point[1], radius, only)) {
|
|
838
|
+
this.cancelHoverPick();
|
|
723
839
|
return;
|
|
724
|
-
|
|
840
|
+
}
|
|
841
|
+
// A new request replaces the one in flight (in the engine too): one poll loop at most
|
|
842
|
+
this.hoverPolls = 0;
|
|
843
|
+
if (!this.hoverPoll)
|
|
844
|
+
this.hoverPoll = requestAnimationFrame(this.pollHoverPick);
|
|
725
845
|
}
|
|
726
846
|
pollHoverPick = () => {
|
|
727
847
|
this.hoverPoll = 0;
|
|
@@ -729,8 +849,10 @@ export class GeoMap {
|
|
|
729
849
|
return;
|
|
730
850
|
const result = this.engine.pollPick();
|
|
731
851
|
if (!result) {
|
|
732
|
-
// The GPU is not done yet (usually a frame): asked again next frame, without drawing
|
|
733
|
-
this.
|
|
852
|
+
// The GPU is not done yet (usually a frame): asked again next frame, without drawing; given up at last
|
|
853
|
+
this.hoverPolls += 1;
|
|
854
|
+
if (this.hoverPolls < MAX_POLLS)
|
|
855
|
+
this.hoverPoll = requestAnimationFrame(this.pollHoverPick);
|
|
734
856
|
return;
|
|
735
857
|
}
|
|
736
858
|
this.emit('hoverfeature', {
|
|
@@ -795,15 +917,14 @@ export class GeoMap {
|
|
|
795
917
|
/** Replaces the basemap and the IGN hillshade, under the other layers (hillshade by default: 0, none). The former
|
|
796
918
|
* names of the Géoplateforme basemaps (`LegacyBasemap`) are taken under their new ones */
|
|
797
919
|
setBasemap(basemap, hillshade = 0) {
|
|
798
|
-
const name =
|
|
799
|
-
this.basemap
|
|
800
|
-
|
|
801
|
-
if (this.
|
|
802
|
-
this.
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
806
|
-
}
|
|
920
|
+
const name = checkBasemap(basemap);
|
|
921
|
+
if (this.basemap && this.hasLayer(this.basemap))
|
|
922
|
+
this.basemap.remove();
|
|
923
|
+
if (this.hillshade && this.hasLayer(this.hillshade))
|
|
924
|
+
this.hillshade.remove();
|
|
925
|
+
// Its raster and labels go with it
|
|
926
|
+
this.vector?.tiles.destroy();
|
|
927
|
+
this.vector = undefined;
|
|
807
928
|
const vector = VECTOR_BASEMAPS[name];
|
|
808
929
|
if (vector) {
|
|
809
930
|
const tiles = new VectorTiles(this, {
|
|
@@ -834,8 +955,9 @@ export class GeoMap {
|
|
|
834
955
|
let layer;
|
|
835
956
|
if (grid === 'equirectangular' && !options.loader) {
|
|
836
957
|
// The source's level n has the pixel size of Mercator level n + 1 at the equator
|
|
837
|
-
const loader = equirectangularLoader(url, maxZoom, size ?? 256);
|
|
838
|
-
|
|
958
|
+
const loader = equirectangularLoader(url, maxZoom, size ?? 256, minZoom);
|
|
959
|
+
const levels = { minZoom: minZoom + 1, maxZoom: maxZoom + 1 };
|
|
960
|
+
layer = new RasterLayer(this, { url, ...levels, opacity, saturation, size, loader });
|
|
839
961
|
}
|
|
840
962
|
else {
|
|
841
963
|
layer = new RasterLayer(this, { url, minZoom, maxZoom, opacity, saturation, size, loader: options.loader });
|
|
@@ -904,6 +1026,10 @@ export class GeoMap {
|
|
|
904
1026
|
this.vectorSets.add(tiles);
|
|
905
1027
|
return tiles;
|
|
906
1028
|
}
|
|
1029
|
+
/** @internal Forgets a destroyed `VectorTiles` */
|
|
1030
|
+
dropVectorTiles(tiles) {
|
|
1031
|
+
this.vectorSets.delete(tiles);
|
|
1032
|
+
}
|
|
907
1033
|
/**
|
|
908
1034
|
* @internal The workers for a `VectorTiles`: the map's shared pool, or a pool of its own (`own`, to stop with it)
|
|
909
1035
|
* when it asks for another count or URL
|
|
@@ -947,13 +1073,18 @@ export class GeoMap {
|
|
|
947
1073
|
this.animation = step;
|
|
948
1074
|
this.requestRender();
|
|
949
1075
|
}
|
|
950
|
-
/** @internal
|
|
1076
|
+
/** @internal The pointer moved over the map (undefined: it left). Without 'hover' and 'hoverfeature' listeners,
|
|
1077
|
+
* nothing is drawn: a still map stays idle under a moving mouse */
|
|
951
1078
|
hover(point) {
|
|
952
|
-
|
|
953
|
-
|
|
954
|
-
this.requestRender();
|
|
955
|
-
else
|
|
1079
|
+
if (!point) {
|
|
1080
|
+
this.hoverPoint = undefined;
|
|
956
1081
|
this.cancelHoverPick();
|
|
1082
|
+
return;
|
|
1083
|
+
}
|
|
1084
|
+
if (this.listeners.hover.size === 0 && this.listeners.hoverfeature.size === 0)
|
|
1085
|
+
return;
|
|
1086
|
+
this.hoverPoint = point;
|
|
1087
|
+
this.requestRender();
|
|
957
1088
|
}
|
|
958
1089
|
frame(now) {
|
|
959
1090
|
this.frameRequest = 0;
|
|
@@ -991,7 +1122,9 @@ export class GeoMap {
|
|
|
991
1122
|
const point = this.hoverPoint;
|
|
992
1123
|
hovered = point;
|
|
993
1124
|
this.hoverPoint = undefined;
|
|
994
|
-
|
|
1125
|
+
// The position under the pointer for its listeners only (a 'hoverfeature' alone does not need it)
|
|
1126
|
+
if (this.listeners.hover.size > 0)
|
|
1127
|
+
this.emit('hover', { point, lonLat: this.unproject(point) });
|
|
995
1128
|
}
|
|
996
1129
|
const t0 = performance.now();
|
|
997
1130
|
// The engine asks for the next frame while it draws (uploads past the frame budget, fades): not ignored
|
|
@@ -1048,12 +1181,16 @@ export class GeoMap {
|
|
|
1048
1181
|
this.frame(performance.now());
|
|
1049
1182
|
}
|
|
1050
1183
|
destroy() {
|
|
1184
|
+
if (this.gone)
|
|
1185
|
+
return;
|
|
1051
1186
|
this.gone = true;
|
|
1187
|
+
// A context restored later rebuilds nothing
|
|
1188
|
+
this.unwatchContext();
|
|
1052
1189
|
const camera = this.getCamera();
|
|
1053
1190
|
cancelAnimationFrame(this.frameRequest);
|
|
1054
1191
|
this.cancelHoverPick();
|
|
1055
1192
|
this.vector?.tiles.destroy();
|
|
1056
|
-
for (const tiles of this.vectorSets)
|
|
1193
|
+
for (const tiles of [...this.vectorSets])
|
|
1057
1194
|
tiles.destroy();
|
|
1058
1195
|
this.vectorSets.clear();
|
|
1059
1196
|
this.basemapPool?.terminate();
|
|
@@ -1067,6 +1204,8 @@ export class GeoMap {
|
|
|
1067
1204
|
// Work still under way (labels being shaped, tiles arriving, timers) may call the engine after this: it finds one
|
|
1068
1205
|
// that does nothing, and nothing is drawn again
|
|
1069
1206
|
this.#engine = destroyed(camera);
|
|
1207
|
+
// Glyph ranges still arriving upload to it, not to the freed engine
|
|
1208
|
+
this.#glyphs?.attach(this.#engine);
|
|
1070
1209
|
this.lost = true;
|
|
1071
1210
|
for (const control of [...this.controls.keys()])
|
|
1072
1211
|
this.removeControl(control);
|