isard 1.0.0 → 1.2.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 +51 -0
- package/dist/{basemaps.d.ts → basemap/basemaps.d.ts} +3 -3
- package/dist/{basemaps.js → basemap/basemaps.js} +3 -3
- package/dist/basemap/basemaps.js.map +1 -0
- package/dist/{grid.d.ts → basemap/grid.d.ts} +6 -6
- package/dist/{grid.js → basemap/grid.js} +61 -67
- package/dist/basemap/grid.js.map +1 -0
- package/dist/{mvt.d.ts → basemap/mvt.d.ts} +1 -1
- package/dist/{mvt.js → basemap/mvt.js} +6 -6
- package/dist/basemap/mvt.js.map +1 -0
- package/dist/{pmtiles.d.ts → basemap/pmtiles.d.ts} +16 -10
- package/dist/{pmtiles.js → basemap/pmtiles.js} +41 -33
- package/dist/basemap/pmtiles.js.map +1 -0
- package/dist/{resample.d.ts → basemap/resample.d.ts} +11 -2
- package/dist/{resample.js → basemap/resample.js} +18 -16
- package/dist/basemap/resample.js.map +1 -0
- package/dist/{terrain.d.ts → basemap/terrain.d.ts} +3 -3
- package/dist/{terrain.js → basemap/terrain.js} +7 -7
- package/dist/basemap/terrain.js.map +1 -0
- package/dist/{vectorstyle.d.ts → basemap/vectorstyle.d.ts} +12 -10
- package/dist/{vectorstyle.js → basemap/vectorstyle.js} +129 -111
- package/dist/basemap/vectorstyle.js.map +1 -0
- package/dist/{vectortiles.d.ts → basemap/vectortiles.d.ts} +18 -18
- package/dist/{vectortiles.js → basemap/vectortiles.js} +157 -109
- package/dist/basemap/vectortiles.js.map +1 -0
- package/dist/{wmts.d.ts → basemap/wmts.d.ts} +3 -3
- package/dist/{wmts.js → basemap/wmts.js} +19 -14
- package/dist/basemap/wmts.js.map +1 -0
- package/dist/basemap.worker.js +2 -2
- package/dist/basemap.worker.js.map +14 -13
- package/dist/bind/layers.d.ts +46 -0
- package/dist/bind/layers.js +154 -0
- package/dist/bind/layers.js.map +1 -0
- package/dist/{crs.d.ts → data/crs.d.ts} +11 -11
- package/dist/{crs.js → data/crs.js} +38 -34
- package/dist/data/crs.js.map +1 -0
- package/dist/{gpx.d.ts → data/gpx.d.ts} +2 -2
- package/dist/{gpx.js → data/gpx.js} +20 -20
- package/dist/data/gpx.js.map +1 -0
- package/dist/{kml.d.ts → data/kml.d.ts} +2 -2
- package/dist/{kml.js → data/kml.js} +42 -39
- package/dist/data/kml.js.map +1 -0
- package/dist/{topojson.d.ts → data/topojson.d.ts} +2 -2
- package/dist/{topojson.js → data/topojson.js} +15 -10
- package/dist/data/topojson.js.map +1 -0
- package/dist/{xml.d.ts → data/xml.d.ts} +5 -5
- package/dist/{xml.js → data/xml.js} +19 -18
- package/dist/data/xml.js.map +1 -0
- package/dist/decoder.worker.js +4 -4
- package/dist/decoder.worker.js.map +7 -7
- package/dist/{decoders.d.ts → engine/decoders.d.ts} +3 -3
- package/dist/{decoders.js → engine/decoders.js} +28 -25
- package/dist/engine/decoders.js.map +1 -0
- package/dist/{loader.d.ts → engine/loader.d.ts} +1 -1
- package/dist/{loader.js → engine/loader.js} +17 -14
- package/dist/engine/loader.js.map +1 -0
- package/dist/{protocol.d.ts → engine/protocol.d.ts} +1 -1
- package/dist/engine/protocol.js +3 -0
- package/dist/engine/protocol.js.map +1 -0
- package/dist/{requests.d.ts → engine/requests.d.ts} +1 -1
- package/dist/{requests.js → engine/requests.js} +19 -16
- package/dist/engine/requests.js.map +1 -0
- package/dist/engine-loader.d.ts +13 -9
- package/dist/engine-loader.js +30 -30
- package/dist/engine-loader.js.map +1 -1
- package/dist/formats.d.ts +3 -3
- package/dist/formats.js +3 -3
- package/dist/formats.js.map +1 -1
- package/dist/geoplateforme.d.ts +13 -13
- package/dist/geoplateforme.js +23 -21
- package/dist/geoplateforme.js.map +1 -1
- package/dist/index.d.ts +30 -29
- package/dist/index.js +18 -18
- package/dist/index.js.map +1 -1
- package/dist/isard_bg.wasm +0 -0
- package/dist/isard_core_bg.wasm +0 -0
- package/dist/isard_points_bg.wasm +0 -0
- package/dist/{extrusions.d.ts → layers/extrusions.d.ts} +1 -1
- package/dist/{extrusions.js → layers/extrusions.js} +10 -5
- package/dist/layers/extrusions.js.map +1 -0
- package/dist/{features.d.ts → layers/features.d.ts} +10 -10
- package/dist/{features.js → layers/features.js} +44 -45
- package/dist/layers/features.js.map +1 -0
- package/dist/{glyphs.d.ts → layers/glyphs.d.ts} +6 -6
- package/dist/{glyphs.js → layers/glyphs.js} +45 -41
- package/dist/layers/glyphs.js.map +1 -0
- package/dist/{icons.d.ts → layers/icons.d.ts} +10 -10
- package/dist/{icons.js → layers/icons.js} +84 -69
- package/dist/layers/icons.js.map +1 -0
- package/dist/{layers.d.ts → layers/layers.d.ts} +9 -4
- package/dist/{layers.js → layers/layers.js} +35 -31
- package/dist/layers/layers.js.map +1 -0
- package/dist/{panoramas.d.ts → layers/panoramas.d.ts} +3 -3
- package/dist/{panoramas.js → layers/panoramas.js} +54 -43
- package/dist/layers/panoramas.js.map +1 -0
- package/dist/{pointclouds.d.ts → layers/pointclouds.d.ts} +5 -5
- package/dist/{pointclouds.js → layers/pointclouds.js} +26 -34
- package/dist/layers/pointclouds.js.map +1 -0
- package/dist/{symbols.d.ts → layers/symbols.d.ts} +3 -3
- package/dist/{symbols.js → layers/symbols.js} +69 -72
- package/dist/layers/symbols.js.map +1 -0
- package/dist/map/basemap-layers.d.ts +26 -0
- package/dist/map/basemap-layers.js +61 -0
- package/dist/map/basemap-layers.js.map +1 -0
- package/dist/map/canvas.d.ts +17 -0
- package/dist/map/canvas.js +56 -0
- package/dist/map/canvas.js.map +1 -0
- package/dist/map/checks.d.ts +11 -0
- package/dist/map/checks.js +39 -0
- package/dist/map/checks.js.map +1 -0
- package/dist/map/credits.d.ts +17 -0
- package/dist/map/credits.js +34 -0
- package/dist/map/credits.js.map +1 -0
- package/dist/map/engine-settings.d.ts +15 -0
- package/dist/map/engine-settings.js +45 -0
- package/dist/map/engine-settings.js.map +1 -0
- package/dist/map/engines.d.ts +41 -0
- package/dist/map/engines.js +77 -0
- package/dist/map/engines.js.map +1 -0
- package/dist/map/events.d.ts +14 -0
- package/dist/map/events.js +46 -0
- package/dist/map/events.js.map +1 -0
- package/dist/map/frame-loop.d.ts +61 -0
- package/dist/map/frame-loop.js +139 -0
- package/dist/map/frame-loop.js.map +1 -0
- package/dist/map/hover-pick.d.ts +30 -0
- package/dist/map/hover-pick.js +56 -0
- package/dist/map/hover-pick.js.map +1 -0
- package/dist/map/layer-spec.d.ts +42 -0
- package/dist/map/layer-spec.js +34 -0
- package/dist/map/layer-spec.js.map +1 -0
- package/dist/map/layer-stack.d.ts +36 -0
- package/dist/map/layer-stack.js +101 -0
- package/dist/map/layer-stack.js.map +1 -0
- package/dist/map/overlay-host.d.ts +36 -0
- package/dist/map/overlay-host.js +101 -0
- package/dist/map/overlay-host.js.map +1 -0
- package/dist/map/panorama-host.d.ts +5 -0
- package/dist/map/panorama-host.js +32 -0
- package/dist/map/panorama-host.js.map +1 -0
- package/dist/map/raster-source.d.ts +11 -0
- package/dist/map/raster-source.js +26 -0
- package/dist/map/raster-source.js.map +1 -0
- package/dist/map/symbol-atlases.d.ts +26 -0
- package/dist/map/symbol-atlases.js +59 -0
- package/dist/map/symbol-atlases.js.map +1 -0
- package/dist/map/viewshed.d.ts +5 -0
- package/dist/map/viewshed.js +28 -0
- package/dist/map/viewshed.js.map +1 -0
- package/dist/map/workers.d.ts +46 -0
- package/dist/map/workers.js +73 -0
- package/dist/map/workers.js.map +1 -0
- package/dist/map.d.ts +46 -127
- package/dist/map.js +183 -698
- package/dist/map.js.map +1 -1
- package/dist/projections.d.ts +3 -3
- package/dist/projections.js +2 -2
- package/dist/projections.js.map +1 -1
- package/dist/react/Control.d.ts +11 -0
- package/dist/react/Control.js +18 -0
- package/dist/react/Control.js.map +1 -0
- package/dist/react/CustomLayer.d.ts +11 -0
- package/dist/react/CustomLayer.js +30 -0
- package/dist/react/CustomLayer.js.map +1 -0
- package/dist/react/IsardMap.d.ts +43 -0
- package/dist/react/IsardMap.js +146 -0
- package/dist/react/IsardMap.js.map +1 -0
- package/dist/react/Layer.d.ts +42 -0
- package/dist/react/Layer.js +74 -0
- package/dist/react/Layer.js.map +1 -0
- package/dist/react/Marker.d.ts +24 -0
- package/dist/react/Marker.js +53 -0
- package/dist/react/Marker.js.map +1 -0
- package/dist/react/Panel.d.ts +11 -0
- package/dist/react/Panel.js +37 -0
- package/dist/react/Panel.js.map +1 -0
- package/dist/react/Popup.d.ts +18 -0
- package/dist/react/Popup.js +60 -0
- package/dist/react/Popup.js.map +1 -0
- package/dist/react/Swipe.d.ts +9 -0
- package/dist/react/Swipe.js +41 -0
- package/dist/react/Swipe.js.map +1 -0
- package/dist/react/Viewshed.d.ts +5 -0
- package/dist/react/Viewshed.js +28 -0
- package/dist/react/Viewshed.js.map +1 -0
- package/dist/react/context.d.ts +32 -0
- package/dist/react/context.js +20 -0
- package/dist/react/context.js.map +1 -0
- package/dist/react/index.d.ts +26 -0
- package/dist/react/index.js +22 -0
- package/dist/react/index.js.map +1 -0
- package/dist/settings.d.ts +6 -10
- package/dist/settings.js +19 -17
- package/dist/settings.js.map +1 -1
- package/dist/types.d.ts +8 -8
- package/dist/types.js +1 -0
- package/dist/types.js.map +1 -1
- package/dist/{controls.d.ts → ui/controls.d.ts} +1 -1
- package/dist/{controls.js → ui/controls.js} +6 -4
- package/dist/ui/controls.js.map +1 -0
- package/dist/{interaction.d.ts → ui/interaction.d.ts} +9 -5
- package/dist/{interaction.js → ui/interaction.js} +9 -8
- package/dist/ui/interaction.js.map +1 -0
- package/dist/{overlay.d.ts → ui/overlay.d.ts} +2 -2
- package/dist/{overlay.js → ui/overlay.js} +18 -20
- package/dist/ui/overlay.js.map +1 -0
- package/dist/{style.d.ts → ui/style.d.ts} +1 -1
- package/dist/{style.js → ui/style.js} +2 -2
- package/dist/ui/style.js.map +1 -0
- package/dist/{animation.d.ts → util/animation.d.ts} +9 -5
- package/dist/{animation.js → util/animation.js} +6 -6
- package/dist/util/animation.js.map +1 -0
- package/dist/{color.d.ts → util/color.d.ts} +1 -1
- package/dist/{color.js → util/color.js} +14 -16
- package/dist/util/color.js.map +1 -0
- package/dist/{geo.d.ts → util/geo.d.ts} +6 -6
- package/dist/{geo.js → util/geo.js} +12 -12
- package/dist/util/geo.js.map +1 -0
- package/dist/util/guards.d.ts +7 -0
- package/dist/util/guards.js +8 -0
- package/dist/util/guards.js.map +1 -0
- package/dist/util/lru.js.map +1 -0
- package/dist/wasm/isard.d.ts +168 -0
- package/dist/wasm/isard.js +146 -0
- package/dist/wasm/isard_core.d.ts +144 -0
- package/dist/wasm/isard_core.js +122 -0
- package/dist/{basemap.worker.d.ts → workers/basemap.worker.d.ts} +17 -7
- package/dist/workers/basemap.worker.js +658 -0
- package/dist/workers/basemap.worker.js.map +1 -0
- package/package.json +24 -1
- package/vite.js +1 -1
- package/dist/animation.js.map +0 -1
- package/dist/basemaps.js.map +0 -1
- package/dist/color.js.map +0 -1
- package/dist/controls.js.map +0 -1
- package/dist/crs.js.map +0 -1
- package/dist/decoders.js.map +0 -1
- package/dist/extrusions.js.map +0 -1
- package/dist/features.js.map +0 -1
- package/dist/geo.js.map +0 -1
- package/dist/glyphs.js.map +0 -1
- package/dist/gpx.js.map +0 -1
- package/dist/grid.js.map +0 -1
- package/dist/icons.js.map +0 -1
- package/dist/interaction.js.map +0 -1
- package/dist/kml.js.map +0 -1
- package/dist/layers.js.map +0 -1
- package/dist/loader.js.map +0 -1
- package/dist/lru.js.map +0 -1
- package/dist/mvt.js.map +0 -1
- package/dist/overlay.js.map +0 -1
- package/dist/panoramas.js.map +0 -1
- package/dist/pmtiles.js.map +0 -1
- package/dist/pointclouds.js.map +0 -1
- package/dist/protocol.js +0 -2
- package/dist/protocol.js.map +0 -1
- package/dist/requests.js.map +0 -1
- package/dist/resample.js.map +0 -1
- package/dist/style.js.map +0 -1
- package/dist/symbols.js.map +0 -1
- package/dist/terrain.js.map +0 -1
- package/dist/topojson.js.map +0 -1
- package/dist/vectorstyle.js.map +0 -1
- package/dist/vectortiles.js.map +0 -1
- package/dist/wmts.js.map +0 -1
- package/dist/xml.js.map +0 -1
- /package/dist/{lru.d.ts → util/lru.d.ts} +0 -0
- /package/dist/{lru.js → util/lru.js} +0 -0
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/** The layers of a map's basemap: a raster or vector basemap (its labels kept on top) and the IGN hillshade, under the
|
|
2
|
+
* other layers. */
|
|
3
|
+
import { BASEMAPS, HILLSHADE } from "../basemap/basemaps.js";
|
|
4
|
+
import { VECTOR_BASEMAPS, VectorTiles } from "../basemap/vectortiles.js";
|
|
5
|
+
const isVector = (name) => Object.hasOwn(VECTOR_BASEMAPS, name);
|
|
6
|
+
const isRaster = (name) => Object.hasOwn(BASEMAPS, name);
|
|
7
|
+
/** The basemap and the hillshade of a map, replaced together */
|
|
8
|
+
export class BasemapLayers {
|
|
9
|
+
map;
|
|
10
|
+
stack;
|
|
11
|
+
/** URL of the vector basemaps' workers */
|
|
12
|
+
workerUrl;
|
|
13
|
+
/** Texture size of the vector basemap's tiles */
|
|
14
|
+
tileSize;
|
|
15
|
+
basemap;
|
|
16
|
+
hillshade;
|
|
17
|
+
/** The vector basemap, if any: its tiles' workers and its labels */
|
|
18
|
+
vector;
|
|
19
|
+
/** `stack`: the map's drawing order */
|
|
20
|
+
constructor(map, stack, workerUrl, tileSize) {
|
|
21
|
+
this.map = map;
|
|
22
|
+
this.stack = stack;
|
|
23
|
+
this.workerUrl = workerUrl;
|
|
24
|
+
this.tileSize = tileSize;
|
|
25
|
+
}
|
|
26
|
+
/** Removes the basemap and the hillshade, then adds the basemap `name` (none for 'none') */
|
|
27
|
+
replace(name) {
|
|
28
|
+
const { map } = this;
|
|
29
|
+
if (this.basemap && map.hasLayer(this.basemap))
|
|
30
|
+
this.basemap.remove();
|
|
31
|
+
if (this.hillshade && map.hasLayer(this.hillshade))
|
|
32
|
+
this.hillshade.remove();
|
|
33
|
+
// Its raster and labels go with it
|
|
34
|
+
this.destroy();
|
|
35
|
+
this.vector = undefined;
|
|
36
|
+
if (isVector(name)) {
|
|
37
|
+
const tiles = new VectorTiles(map, {
|
|
38
|
+
style: VECTOR_BASEMAPS[name],
|
|
39
|
+
...(this.workerUrl ? { workerUrl: this.workerUrl } : {}),
|
|
40
|
+
});
|
|
41
|
+
this.basemap = tiles.raster(this.tileSize ? { size: this.tileSize } : {});
|
|
42
|
+
this.vector = { tiles, labels: tiles.labels() };
|
|
43
|
+
}
|
|
44
|
+
else {
|
|
45
|
+
this.basemap = isRaster(name) ? map.addRaster(BASEMAPS[name]) : undefined;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
/** Adds the hillshade at `opacity` (0: none), then puts it and the basemap under all the other layers */
|
|
49
|
+
addHillshade(opacity) {
|
|
50
|
+
this.hillshade = opacity > 0 ? this.map.addRaster({ ...HILLSHADE, opacity }) : undefined;
|
|
51
|
+
if (this.hillshade)
|
|
52
|
+
this.stack.toBottom(this.hillshade);
|
|
53
|
+
if (this.basemap)
|
|
54
|
+
this.stack.toBottom(this.basemap);
|
|
55
|
+
}
|
|
56
|
+
/** Stops the vector basemap's tiles (their layers removed) */
|
|
57
|
+
destroy() {
|
|
58
|
+
this.vector?.tiles.destroy();
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=basemap-layers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"basemap-layers.js","sourceRoot":"","sources":["../../src/map/basemap-layers.ts"],"names":[],"mappings":"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","sourcesContent":["/** The layers of a map's basemap: a raster or vector basemap (its labels kept on top) and the IGN hillshade, under the\n * other layers. */\n\nimport { BASEMAPS, HILLSHADE } from '../basemap/basemaps.ts';\nimport type { LabelCandidate } from '../basemap/vectorstyle.ts';\nimport { VECTOR_BASEMAPS, VectorTiles } from '../basemap/vectortiles.ts';\nimport type { RasterLayer } from '../layers/layers.ts';\nimport type { SymbolLayer } from '../layers/symbols.ts';\nimport type { GeoMap } from '../map.ts';\nimport type { BasemapName } from '../types.ts';\nimport type { LayerStack } from './layer-stack.ts';\n\nconst isVector = (name: BasemapName): name is keyof typeof VECTOR_BASEMAPS => Object.hasOwn(VECTOR_BASEMAPS, name);\nconst isRaster = (name: BasemapName): name is keyof typeof BASEMAPS => Object.hasOwn(BASEMAPS, name);\n\n/** The basemap and the hillshade of a map, replaced together */\nexport class BasemapLayers {\n private readonly map: GeoMap;\n private readonly stack: LayerStack;\n /** URL of the vector basemaps' workers */\n private readonly workerUrl: string | URL;\n /** Texture size of the vector basemap's tiles */\n private readonly tileSize: number | undefined;\n private basemap: RasterLayer | undefined;\n private hillshade: RasterLayer | undefined;\n /** The vector basemap, if any: its tiles' workers and its labels */\n private vector: { tiles: VectorTiles; labels: SymbolLayer<LabelCandidate> } | undefined;\n\n /** `stack`: the map's drawing order */\n constructor(map: GeoMap, stack: LayerStack, workerUrl: string | URL, tileSize: number | undefined) {\n this.map = map;\n this.stack = stack;\n this.workerUrl = workerUrl;\n this.tileSize = tileSize;\n }\n\n /** Removes the basemap and the hillshade, then adds the basemap `name` (none for 'none') */\n replace(name: BasemapName): void {\n const { map } = this;\n\n if (this.basemap && map.hasLayer(this.basemap)) this.basemap.remove();\n if (this.hillshade && map.hasLayer(this.hillshade)) this.hillshade.remove();\n // Its raster and labels go with it\n this.destroy();\n this.vector = undefined;\n\n if (isVector(name)) {\n const tiles = new VectorTiles(map, {\n style: VECTOR_BASEMAPS[name],\n ...(this.workerUrl ? { workerUrl: this.workerUrl } : {}),\n });\n\n this.basemap = tiles.raster(this.tileSize ? { size: this.tileSize } : {});\n this.vector = { tiles, labels: tiles.labels() };\n } else {\n this.basemap = isRaster(name) ? map.addRaster(BASEMAPS[name]) : undefined;\n }\n }\n\n /** Adds the hillshade at `opacity` (0: none), then puts it and the basemap under all the other layers */\n addHillshade(opacity: number): void {\n this.hillshade = opacity > 0 ? this.map.addRaster({ ...HILLSHADE, opacity }) : undefined;\n if (this.hillshade) this.stack.toBottom(this.hillshade);\n if (this.basemap) this.stack.toBottom(this.basemap);\n }\n\n /** Stops the vector basemap's tiles (their layers removed) */\n destroy(): void {\n this.vector?.tiles.destroy();\n }\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The map's canvas: created, named for screen readers, its WebGL context's loss and restoration followed, the device
|
|
3
|
+
* pixel ratio watched (a canvas's pixels follow it).
|
|
4
|
+
*/
|
|
5
|
+
/** A canvas filling its container, the pointer's gestures left to the map */
|
|
6
|
+
export declare const createCanvas: () => HTMLCanvasElement;
|
|
7
|
+
/** Reached with Tab when the keys move the map (`keyboard`); named for screen readers either way */
|
|
8
|
+
export declare const labelCanvas: (canvas: HTMLCanvasElement, keyboard: boolean, label: string) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Follows the loss and restoration of the canvas's WebGL context (the browser may take the GPU away: driver reset,
|
|
11
|
+
* background tab on mobile): `lost` once it is gone, the context kept to be restored, `restored` once it is back.
|
|
12
|
+
* Returns what stops following them
|
|
13
|
+
*/
|
|
14
|
+
export declare const watchContext: (canvas: HTMLCanvasElement, lost: () => void, restored: () => void) => (() => void);
|
|
15
|
+
/** Calls `changed` when the device pixel ratio changes (browser zoom, a window moved to another screen); returns what
|
|
16
|
+
* stops watching it */
|
|
17
|
+
export declare const watchPixelRatio: (changed: () => void) => (() => void);
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The map's canvas: created, named for screen readers, its WebGL context's loss and restoration followed, the device
|
|
3
|
+
* pixel ratio watched (a canvas's pixels follow it).
|
|
4
|
+
*/
|
|
5
|
+
/** A canvas filling its container, the pointer's gestures left to the map */
|
|
6
|
+
export const createCanvas = () => {
|
|
7
|
+
const canvas = document.createElement('canvas');
|
|
8
|
+
Object.assign(canvas.style, { display: 'block', width: '100%', height: '100%', touchAction: 'none' });
|
|
9
|
+
return canvas;
|
|
10
|
+
};
|
|
11
|
+
/** Reached with Tab when the keys move the map (`keyboard`); named for screen readers either way */
|
|
12
|
+
export const labelCanvas = (canvas, keyboard, label) => {
|
|
13
|
+
canvas.classList.add('isard-canvas');
|
|
14
|
+
canvas.setAttribute('role', keyboard ? 'application' : 'region');
|
|
15
|
+
canvas.setAttribute('aria-roledescription', 'map');
|
|
16
|
+
canvas.setAttribute('aria-label', label);
|
|
17
|
+
if (keyboard)
|
|
18
|
+
canvas.tabIndex = 0;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Follows the loss and restoration of the canvas's WebGL context (the browser may take the GPU away: driver reset,
|
|
22
|
+
* background tab on mobile): `lost` once it is gone, the context kept to be restored, `restored` once it is back.
|
|
23
|
+
* Returns what stops following them
|
|
24
|
+
*/
|
|
25
|
+
export const watchContext = (canvas, lost, restored) => {
|
|
26
|
+
const onLost = (event) => {
|
|
27
|
+
event.preventDefault();
|
|
28
|
+
lost();
|
|
29
|
+
};
|
|
30
|
+
canvas.addEventListener('webglcontextlost', onLost);
|
|
31
|
+
canvas.addEventListener('webglcontextrestored', restored);
|
|
32
|
+
return () => {
|
|
33
|
+
canvas.removeEventListener('webglcontextlost', onLost);
|
|
34
|
+
canvas.removeEventListener('webglcontextrestored', restored);
|
|
35
|
+
};
|
|
36
|
+
};
|
|
37
|
+
/** Calls `changed` when the device pixel ratio changes (browser zoom, a window moved to another screen); returns what
|
|
38
|
+
* stops watching it */
|
|
39
|
+
export const watchPixelRatio = (changed) => {
|
|
40
|
+
if (typeof matchMedia !== 'function')
|
|
41
|
+
return () => undefined;
|
|
42
|
+
let stop = () => undefined;
|
|
43
|
+
const watch = () => {
|
|
44
|
+
const query = matchMedia(`(resolution: ${window.devicePixelRatio || 1}dppx)`);
|
|
45
|
+
const listener = () => {
|
|
46
|
+
// A query for the new ratio
|
|
47
|
+
watch();
|
|
48
|
+
changed();
|
|
49
|
+
};
|
|
50
|
+
query.addEventListener('change', listener, { once: true });
|
|
51
|
+
stop = () => query.removeEventListener('change', listener);
|
|
52
|
+
};
|
|
53
|
+
watch();
|
|
54
|
+
return () => stop();
|
|
55
|
+
};
|
|
56
|
+
//# sourceMappingURL=canvas.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"canvas.js","sourceRoot":"","sources":["../../src/map/canvas.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,6EAA6E;AAC7E,MAAM,CAAC,MAAM,YAAY,GAAG,GAAsB,EAAE;IAClD,MAAM,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC;IAEhD,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,EAAE,EAAE,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,EAAE,CAAC,CAAC;IAEtG,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAEF,oGAAoG;AACpG,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,MAAyB,EAAE,QAAiB,EAAE,KAAa,EAAQ,EAAE;IAC/F,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,cAAc,CAAC,CAAC;IACrC,MAAM,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;IACjE,MAAM,CAAC,YAAY,CAAC,sBAAsB,EAAE,KAAK,CAAC,CAAC;IACnD,MAAM,CAAC,YAAY,CAAC,YAAY,EAAE,KAAK,CAAC,CAAC;IACzC,IAAI,QAAQ;QAAE,MAAM,CAAC,QAAQ,GAAG,CAAC,CAAC;AACpC,CAAC,CAAC;AAEF;;;;GAIG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,MAAyB,EAAE,IAAgB,EAAE,QAAoB,EAAgB,EAAE;IAC9G,MAAM,MAAM,GAAG,CAAC,KAAY,EAAE,EAAE;QAC9B,KAAK,CAAC,cAAc,EAAE,CAAC;QACvB,IAAI,EAAE,CAAC;IACT,CAAC,CAAC;IAEF,MAAM,CAAC,gBAAgB,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;IACpD,MAAM,CAAC,gBAAgB,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC;IAE1D,OAAO,GAAG,EAAE;QACV,MAAM,CAAC,mBAAmB,CAAC,kBAAkB,EAAE,MAAM,CAAC,CAAC;QACvD,MAAM,CAAC,mBAAmB,CAAC,sBAAsB,EAAE,QAAQ,CAAC,CAAC;IAC/D,CAAC,CAAC;AACJ,CAAC,CAAC;AAEF;uBACuB;AACvB,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,OAAmB,EAAgB,EAAE;IACnE,IAAI,OAAO,UAAU,KAAK,UAAU;QAAE,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC;IAE7D,IAAI,IAAI,GAAG,GAAS,EAAE,CAAC,SAAS,CAAC;IACjC,MAAM,KAAK,GAAG,GAAG,EAAE;QACjB,MAAM,KAAK,GAAG,UAAU,CAAC,gBAAgB,MAAM,CAAC,gBAAgB,IAAI,CAAC,OAAO,CAAC,CAAC;QAC9E,MAAM,QAAQ,GAAG,GAAG,EAAE;YACpB,4BAA4B;YAC5B,KAAK,EAAE,CAAC;YACR,OAAO,EAAE,CAAC;QACZ,CAAC,CAAC;QAEF,KAAK,CAAC,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;QAC3D,IAAI,GAAG,GAAG,EAAE,CAAC,KAAK,CAAC,mBAAmB,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAC7D,CAAC,CAAC;IAEF,KAAK,EAAE,CAAC;IAER,OAAO,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC,CAAC","sourcesContent":["/**\n * The map's canvas: created, named for screen readers, its WebGL context's loss and restoration followed, the device\n * pixel ratio watched (a canvas's pixels follow it).\n */\n\n/** A canvas filling its container, the pointer's gestures left to the map */\nexport const createCanvas = (): HTMLCanvasElement => {\n const canvas = document.createElement('canvas');\n\n Object.assign(canvas.style, { display: 'block', width: '100%', height: '100%', touchAction: 'none' });\n\n return canvas;\n};\n\n/** Reached with Tab when the keys move the map (`keyboard`); named for screen readers either way */\nexport const labelCanvas = (canvas: HTMLCanvasElement, keyboard: boolean, label: string): void => {\n canvas.classList.add('isard-canvas');\n canvas.setAttribute('role', keyboard ? 'application' : 'region');\n canvas.setAttribute('aria-roledescription', 'map');\n canvas.setAttribute('aria-label', label);\n if (keyboard) canvas.tabIndex = 0;\n};\n\n/**\n * Follows the loss and restoration of the canvas's WebGL context (the browser may take the GPU away: driver reset,\n * background tab on mobile): `lost` once it is gone, the context kept to be restored, `restored` once it is back.\n * Returns what stops following them\n */\nexport const watchContext = (canvas: HTMLCanvasElement, lost: () => void, restored: () => void): (() => void) => {\n const onLost = (event: Event) => {\n event.preventDefault();\n lost();\n };\n\n canvas.addEventListener('webglcontextlost', onLost);\n canvas.addEventListener('webglcontextrestored', restored);\n\n return () => {\n canvas.removeEventListener('webglcontextlost', onLost);\n canvas.removeEventListener('webglcontextrestored', restored);\n };\n};\n\n/** Calls `changed` when the device pixel ratio changes (browser zoom, a window moved to another screen); returns what\n * stops watching it */\nexport const watchPixelRatio = (changed: () => void): (() => void) => {\n if (typeof matchMedia !== 'function') return () => undefined;\n\n let stop = (): void => undefined;\n const watch = () => {\n const query = matchMedia(`(resolution: ${window.devicePixelRatio || 1}dppx)`);\n const listener = () => {\n // A query for the new ratio\n watch();\n changed();\n };\n\n query.addEventListener('change', listener, { once: true });\n stop = () => query.removeEventListener('change', listener);\n };\n\n watch();\n\n return () => stop();\n};\n"]}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the map checks of what the application gives it before the engine sees it (a basemap's name, a network's
|
|
3
|
+
* arrays), and how it reports an error it does not throw.
|
|
4
|
+
*/
|
|
5
|
+
import type { Basemap, BasemapName } from '../types.ts';
|
|
6
|
+
/** Reports an error without throwing it here: the console shows it, as an uncaught one */
|
|
7
|
+
export declare const report: (error: unknown) => void;
|
|
8
|
+
/** Checks a network's arrays before the engine reads them: node index pairs, indices of existing nodes */
|
|
9
|
+
export declare const validateNetwork: (nodes: Float64Array, edges: Uint32Array) => void;
|
|
10
|
+
/** The name of a basemap, checked: an unknown one throws */
|
|
11
|
+
export declare const checkBasemap: (basemap: Basemap) => BasemapName;
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What the map checks of what the application gives it before the engine sees it (a basemap's name, a network's
|
|
3
|
+
* arrays), and how it reports an error it does not throw.
|
|
4
|
+
*/
|
|
5
|
+
import { BASEMAPS, RENAMED_BASEMAPS } from "../basemap/basemaps.js";
|
|
6
|
+
import { VECTOR_BASEMAPS } from "../basemap/vectortiles.js";
|
|
7
|
+
/** Reports an error without throwing it here: the console shows it, as an uncaught one */
|
|
8
|
+
export const report = (error) => {
|
|
9
|
+
if (typeof reportError === 'function')
|
|
10
|
+
reportError(error);
|
|
11
|
+
else
|
|
12
|
+
queueMicrotask(() => {
|
|
13
|
+
throw error;
|
|
14
|
+
});
|
|
15
|
+
};
|
|
16
|
+
/** Checks a network's arrays before the engine reads them: node index pairs, indices of existing nodes */
|
|
17
|
+
export const validateNetwork = (nodes, edges) => {
|
|
18
|
+
if (nodes.length % 2 !== 0)
|
|
19
|
+
throw new Error(`isard: network nodes must be lon, lat pairs (length ${nodes.length})`);
|
|
20
|
+
if (edges.length % 2 !== 0)
|
|
21
|
+
throw new Error(`isard: network edges must be node index pairs (length ${edges.length})`);
|
|
22
|
+
const count = nodes.length / 2;
|
|
23
|
+
for (let i = 0; i < edges.length; i += 1) {
|
|
24
|
+
const node = edges[i];
|
|
25
|
+
if (node >= count)
|
|
26
|
+
throw new Error(`isard: network edge ${i >> 1} refers to node ${node}, of ${count} nodes`);
|
|
27
|
+
}
|
|
28
|
+
};
|
|
29
|
+
/** The name of a basemap, checked: an unknown one throws */
|
|
30
|
+
export const checkBasemap = (basemap) => {
|
|
31
|
+
const renamed = RENAMED_BASEMAPS[basemap];
|
|
32
|
+
if (renamed)
|
|
33
|
+
throw new Error(`isard: the basemap '${basemap}' is now named '${renamed}'`);
|
|
34
|
+
if (basemap !== 'none' && !(basemap in VECTOR_BASEMAPS) && !(basemap in BASEMAPS)) {
|
|
35
|
+
throw new Error(`isard: unknown basemap '${basemap}'`);
|
|
36
|
+
}
|
|
37
|
+
return basemap;
|
|
38
|
+
};
|
|
39
|
+
//# sourceMappingURL=checks.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"checks.js","sourceRoot":"","sources":["../../src/map/checks.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,QAAQ,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,MAAM,2BAA2B,CAAC;AAG5D,0FAA0F;AAC1F,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,KAAc,EAAQ,EAAE;IAC7C,IAAI,OAAO,WAAW,KAAK,UAAU;QAAE,WAAW,CAAC,KAAK,CAAC,CAAC;;QAExD,cAAc,CAAC,GAAG,EAAE;YAClB,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;AACP,CAAC,CAAC;AAEF,0GAA0G;AAC1G,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,KAAmB,EAAE,KAAkB,EAAQ,EAAE;IAC/E,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,uDAAuD,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IACpH,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,KAAK,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,yDAAyD,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAEtH,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC;IAE/B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;QACzC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAW,CAAC;QAEhC,IAAI,IAAI,IAAI,KAAK;YAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,IAAI,CAAC,mBAAmB,IAAI,QAAQ,KAAK,QAAQ,CAAC,CAAC;IAChH,CAAC;AACH,CAAC,CAAC;AAEF,4DAA4D;AAC5D,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,OAAgB,EAAe,EAAE;IAC5D,MAAM,OAAO,GAAG,gBAAgB,CAAC,OAAO,CAAC,CAAC;IAE1C,IAAI,OAAO;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,OAAO,mBAAmB,OAAO,GAAG,CAAC,CAAC;IAC1F,IAAI,OAAO,KAAK,MAAM,IAAI,CAAC,CAAC,OAAO,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC,OAAO,IAAI,QAAQ,CAAC,EAAE,CAAC;QAClF,MAAM,IAAI,KAAK,CAAC,2BAA2B,OAAO,GAAG,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC","sourcesContent":["/**\n * What the map checks of what the application gives it before the engine sees it (a basemap's name, a network's\n * arrays), and how it reports an error it does not throw.\n */\n\nimport { BASEMAPS, RENAMED_BASEMAPS } from '../basemap/basemaps.ts';\nimport { VECTOR_BASEMAPS } from '../basemap/vectortiles.ts';\nimport type { Basemap, BasemapName } from '../types.ts';\n\n/** Reports an error without throwing it here: the console shows it, as an uncaught one */\nexport const report = (error: unknown): void => {\n if (typeof reportError === 'function') reportError(error);\n else\n queueMicrotask(() => {\n throw error;\n });\n};\n\n/** Checks a network's arrays before the engine reads them: node index pairs, indices of existing nodes */\nexport const validateNetwork = (nodes: Float64Array, edges: Uint32Array): void => {\n if (nodes.length % 2 !== 0) throw new Error(`isard: network nodes must be lon, lat pairs (length ${nodes.length})`);\n if (edges.length % 2 !== 0) throw new Error(`isard: network edges must be node index pairs (length ${edges.length})`);\n\n const count = nodes.length / 2;\n\n for (let i = 0; i < edges.length; i += 1) {\n const node = edges[i] as number;\n\n if (node >= count) throw new Error(`isard: network edge ${i >> 1} refers to node ${node}, of ${count} nodes`);\n }\n};\n\n/** The name of a basemap, checked: an unknown one throws */\nexport const checkBasemap = (basemap: Basemap): BasemapName => {\n const renamed = RENAMED_BASEMAPS[basemap];\n\n if (renamed) throw new Error(`isard: the basemap '${basemap}' is now named '${renamed}'`);\n if (basemap !== 'none' && !(basemap in VECTOR_BASEMAPS) && !(basemap in BASEMAPS)) {\n throw new Error(`isard: unknown basemap '${basemap}'`);\n }\n\n return basemap;\n};\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/** The credits of a map's raster layers, and who is told when they change (the attribution controls). */
|
|
2
|
+
/** The credits of the raster layers that have some (basemaps, hillshade, the Géoplateforme's rasters…) */
|
|
3
|
+
export declare class Credits {
|
|
4
|
+
private readonly byLayer;
|
|
5
|
+
/** Called when the credits of the layers or relief change */
|
|
6
|
+
private readonly listeners;
|
|
7
|
+
/** A layer's credit */
|
|
8
|
+
set(layer: object, credit: string): void;
|
|
9
|
+
/** Forgets a removed layer's credit, if it had one */
|
|
10
|
+
forget(layer: object): void;
|
|
11
|
+
/** The credits of `layers` (in their order) and of the relief, each once */
|
|
12
|
+
of(layers: readonly object[], relief: string | undefined): string[];
|
|
13
|
+
/** Calls `listener` when the credits change; returns what stops it */
|
|
14
|
+
onChange(listener: () => void): () => void;
|
|
15
|
+
/** Tells the listeners the credits changed */
|
|
16
|
+
changed(): void;
|
|
17
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/** The credits of a map's raster layers, and who is told when they change (the attribution controls). */
|
|
2
|
+
/** The credits of the raster layers that have some (basemaps, hillshade, the Géoplateforme's rasters…) */
|
|
3
|
+
export class Credits {
|
|
4
|
+
byLayer = new Map();
|
|
5
|
+
/** Called when the credits of the layers or relief change */
|
|
6
|
+
listeners = new Set();
|
|
7
|
+
/** A layer's credit */
|
|
8
|
+
set(layer, credit) {
|
|
9
|
+
this.byLayer.set(layer, credit);
|
|
10
|
+
this.changed();
|
|
11
|
+
}
|
|
12
|
+
/** Forgets a removed layer's credit, if it had one */
|
|
13
|
+
forget(layer) {
|
|
14
|
+
if (this.byLayer.delete(layer))
|
|
15
|
+
this.changed();
|
|
16
|
+
}
|
|
17
|
+
/** The credits of `layers` (in their order) and of the relief, each once */
|
|
18
|
+
of(layers, relief) {
|
|
19
|
+
const credits = [...layers.map((layer) => this.byLayer.get(layer)), relief];
|
|
20
|
+
return [...new Set(credits.filter((c) => c !== undefined))];
|
|
21
|
+
}
|
|
22
|
+
/** Calls `listener` when the credits change; returns what stops it */
|
|
23
|
+
onChange(listener) {
|
|
24
|
+
this.listeners.add(listener);
|
|
25
|
+
return () => this.listeners.delete(listener);
|
|
26
|
+
}
|
|
27
|
+
/** Tells the listeners the credits changed */
|
|
28
|
+
changed() {
|
|
29
|
+
this.listeners.forEach((listener) => {
|
|
30
|
+
listener();
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
//# sourceMappingURL=credits.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"credits.js","sourceRoot":"","sources":["../../src/map/credits.ts"],"names":[],"mappings":"AAAA,yGAAyG;AAEzG,0GAA0G;AAC1G,MAAM,OAAO,OAAO;IACD,OAAO,GAAG,IAAI,GAAG,EAAkB,CAAC;IACrD,6DAA6D;IAC5C,SAAS,GAAG,IAAI,GAAG,EAAc,CAAC;IAEnD,uBAAuB;IACvB,GAAG,CAAC,KAAa,EAAE,MAAc;QAC/B,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,EAAE,MAAM,CAAC,CAAC;QAChC,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;IAED,sDAAsD;IACtD,MAAM,CAAC,KAAa;QAClB,IAAI,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,IAAI,CAAC,OAAO,EAAE,CAAC;IACjD,CAAC;IAED,4EAA4E;IAC5E,EAAE,CAAC,MAAyB,EAAE,MAA0B;QACtD,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC;QAE5E,OAAO,CAAC,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC;IAC3E,CAAC;IAED,sEAAsE;IACtE,QAAQ,CAAC,QAAoB;QAC3B,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAE7B,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC/C,CAAC;IAED,8CAA8C;IAC9C,OAAO;QACL,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YAClC,QAAQ,EAAE,CAAC;QACb,CAAC,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["/** The credits of a map's raster layers, and who is told when they change (the attribution controls). */\n\n/** The credits of the raster layers that have some (basemaps, hillshade, the Géoplateforme's rasters…) */\nexport class Credits {\n private readonly byLayer = new Map<object, string>();\n /** Called when the credits of the layers or relief change */\n private readonly listeners = new Set<() => void>();\n\n /** A layer's credit */\n set(layer: object, credit: string): void {\n this.byLayer.set(layer, credit);\n this.changed();\n }\n\n /** Forgets a removed layer's credit, if it had one */\n forget(layer: object): void {\n if (this.byLayer.delete(layer)) this.changed();\n }\n\n /** The credits of `layers` (in their order) and of the relief, each once */\n of(layers: readonly object[], relief: string | undefined): string[] {\n const credits = [...layers.map((layer) => this.byLayer.get(layer)), relief];\n\n return [...new Set(credits.filter((c): c is string => c !== undefined))];\n }\n\n /** Calls `listener` when the credits change; returns what stops it */\n onChange(listener: () => void): () => void {\n this.listeners.add(listener);\n\n return () => this.listeners.delete(listener);\n }\n\n /** Tells the listeners the credits changed */\n changed(): void {\n this.listeners.forEach((listener) => {\n listener();\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The settings of the map's engine: made from the options, given to each new engine (at creation, and again after a
|
|
3
|
+
* context loss or once the engine with 3D Tiles is loaded), with the page's request headers.
|
|
4
|
+
*/
|
|
5
|
+
import type { PngEncoding } from '../basemap/terrain.ts';
|
|
6
|
+
import { type HeaderRules } from '../engine/requests.ts';
|
|
7
|
+
import { type Settings, type TerrainLoader } from '../settings.ts';
|
|
8
|
+
import type { GeoMapOptions } from '../types.ts';
|
|
9
|
+
import type { Engine } from '../wasm/isard.js';
|
|
10
|
+
/** The settings of a map from its options; `earth`: the map is of the Earth */
|
|
11
|
+
export declare const mapSettings: (options: GeoMapOptions, earth: boolean, terrainLoader: (url: string, encoding: PngEncoding, floor?: number) => TerrainLoader) => Settings;
|
|
12
|
+
/** Gives a new engine the settings and the page's request headers */
|
|
13
|
+
export declare const applySettings: (engine: Engine, settings: Settings) => void;
|
|
14
|
+
/** The page's request headers to an engine (its own requests: raster tiles, tilesets, point clouds) */
|
|
15
|
+
export declare const sendHeaders: (engine: Engine, rules: HeaderRules) => void;
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The settings of the map's engine: made from the options, given to each new engine (at creation, and again after a
|
|
3
|
+
* context loss or once the engine with 3D Tiles is loaded), with the page's request headers.
|
|
4
|
+
*/
|
|
5
|
+
import { SEA } from "../basemap/basemaps.js";
|
|
6
|
+
import { headerRules } from "../engine/requests.js";
|
|
7
|
+
import { atmosphereSettings, bodySettings, haloSettings, rgb, terrainSettings, } from "../settings.js";
|
|
8
|
+
/** The settings of a map from its options; `earth`: the map is of the Earth */
|
|
9
|
+
export const mapSettings = (options, earth, terrainLoader) => {
|
|
10
|
+
const body = bodySettings(options.body);
|
|
11
|
+
return {
|
|
12
|
+
body,
|
|
13
|
+
zoomRange: [options.minZoom ?? 0, options.maxZoom ?? 22],
|
|
14
|
+
maxPitch: options.maxPitch ?? 70,
|
|
15
|
+
globe: (options.projection ?? 'globe') === 'globe',
|
|
16
|
+
sky: options.sky ?? true,
|
|
17
|
+
atmosphere: atmosphereSettings(options.atmosphere),
|
|
18
|
+
terrain: terrainSettings(options.terrain, options.body, body.radius, terrainLoader),
|
|
19
|
+
loading: options.loading ?? 'immediate',
|
|
20
|
+
background: rgb(options.background ?? (earth ? '#f2f2f0' : '#000000')),
|
|
21
|
+
globeColor: earth ? SEA['osm-positron'] : rgb(body.color),
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
/** Gives a new engine the settings and the page's request headers */
|
|
25
|
+
export const applySettings = (engine, settings) => {
|
|
26
|
+
// The body first: the layers' shaders may take its size
|
|
27
|
+
const { radius, flattening, atmosphere: air, relief } = settings.body;
|
|
28
|
+
engine.setBody(radius, flattening, haloSettings(air), ...relief);
|
|
29
|
+
sendHeaders(engine, headerRules());
|
|
30
|
+
const { zoomRange, maxPitch, globe, sky, atmosphere, terrain, loading, background, globeColor } = settings;
|
|
31
|
+
engine.setZoomRange(...zoomRange);
|
|
32
|
+
engine.setMaxPitch(maxPitch);
|
|
33
|
+
engine.setGlobe(globe);
|
|
34
|
+
engine.setSky(sky);
|
|
35
|
+
engine.setAtmosphere(atmosphere);
|
|
36
|
+
engine.setTerrain(terrain?.url, terrain?.exaggeration ?? 1, terrain?.maxZoom, terrain?.geoid, terrain?.loader);
|
|
37
|
+
engine.setImmediateLoading(loading === 'immediate');
|
|
38
|
+
engine.setBackground(...background);
|
|
39
|
+
engine.setGlobeColor(...globeColor);
|
|
40
|
+
};
|
|
41
|
+
/** The page's request headers to an engine (its own requests: raster tiles, tilesets, point clouds) */
|
|
42
|
+
export const sendHeaders = (engine, rules) => {
|
|
43
|
+
engine.setRequestHeaders(rules.map(([prefix]) => prefix), Uint32Array.from(rules, ([, headers]) => Object.keys(headers).length), rules.flatMap(([, headers]) => Object.entries(headers).flat()));
|
|
44
|
+
};
|
|
45
|
+
//# sourceMappingURL=engine-settings.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine-settings.js","sourceRoot":"","sources":["../../src/map/engine-settings.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The settings of the map's engine: made from the options, given to each new engine (at creation, and again after a\n * context loss or once the engine with 3D Tiles is loaded), with the page's request headers.\n */\n\nimport { SEA } from '../basemap/basemaps.ts';\nimport type { PngEncoding } from '../basemap/terrain.ts';\nimport { type HeaderRules, headerRules } from '../engine/requests.ts';\nimport {\n atmosphereSettings,\n bodySettings,\n haloSettings,\n rgb,\n type Settings,\n type TerrainLoader,\n terrainSettings,\n} from '../settings.ts';\nimport type { GeoMapOptions } from '../types.ts';\nimport type { Engine } from '../wasm/isard.js';\n\n/** The settings of a map from its options; `earth`: the map is of the Earth */\nexport const mapSettings = (\n options: GeoMapOptions,\n earth: boolean,\n terrainLoader: (url: string, encoding: PngEncoding, floor?: number) => TerrainLoader,\n): Settings => {\n const body = bodySettings(options.body);\n\n return {\n body,\n zoomRange: [options.minZoom ?? 0, options.maxZoom ?? 22],\n maxPitch: options.maxPitch ?? 70,\n globe: (options.projection ?? 'globe') === 'globe',\n sky: options.sky ?? true,\n atmosphere: atmosphereSettings(options.atmosphere),\n terrain: terrainSettings(options.terrain, options.body, body.radius, terrainLoader),\n loading: options.loading ?? 'immediate',\n background: rgb(options.background ?? (earth ? '#f2f2f0' : '#000000')),\n globeColor: earth ? SEA['osm-positron'] : rgb(body.color),\n };\n};\n\n/** Gives a new engine the settings and the page's request headers */\nexport const applySettings = (engine: Engine, settings: Settings): void => {\n // The body first: the layers' shaders may take its size\n const { radius, flattening, atmosphere: air, relief } = settings.body;\n\n engine.setBody(radius, flattening, haloSettings(air), ...relief);\n sendHeaders(engine, headerRules());\n\n const { zoomRange, maxPitch, globe, sky, atmosphere, terrain, loading, background, globeColor } = settings;\n\n engine.setZoomRange(...zoomRange);\n engine.setMaxPitch(maxPitch);\n engine.setGlobe(globe);\n engine.setSky(sky);\n engine.setAtmosphere(atmosphere);\n engine.setTerrain(terrain?.url, terrain?.exaggeration ?? 1, terrain?.maxZoom, terrain?.geoid, terrain?.loader);\n engine.setImmediateLoading(loading === 'immediate');\n engine.setBackground(...background);\n engine.setGlobeColor(...globeColor);\n};\n\n/** The page's request headers to an engine (its own requests: raster tiles, tilesets, point clouds) */\nexport const sendHeaders = (engine: Engine, rules: HeaderRules): void => {\n engine.setRequestHeaders(\n rules.map(([prefix]) => prefix),\n Uint32Array.from(rules, ([, headers]) => Object.keys(headers).length),\n rules.flatMap(([, headers]) => Object.entries(headers).flat()),\n );\n};\n"]}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which engine a map runs: the core one, or the one with 3D Tiles, from the start or loaded once a layer needs it
|
|
3
|
+
* (the map is rebuilt on it then); and the workers decoding its 3D Tiles, started with the first engine that has them.
|
|
4
|
+
*/
|
|
5
|
+
import { type EngineClass } from '../engine-loader.ts';
|
|
6
|
+
import type { Settings } from '../settings.ts';
|
|
7
|
+
import type { GeoMapOptions } from '../types.ts';
|
|
8
|
+
import type { Engine } from '../wasm/isard.js';
|
|
9
|
+
/** What loading the engine with 3D Tiles and its workers needs */
|
|
10
|
+
export type Tiles3dEngineOptions = Pick<GeoMapOptions, 'wasmUrl' | 'workers' | 'workerUrl' | 'decoders' | 'pointsWasmUrl' | 'assetsUrl'>;
|
|
11
|
+
/** The engine class of a map, and the engine with 3D Tiles loaded when needed */
|
|
12
|
+
export declare class MapEngines {
|
|
13
|
+
#private;
|
|
14
|
+
/** The class of the engine: without 3D Tiles until a 3D Tiles layer is added, unless asked for from the start */
|
|
15
|
+
private engineClass;
|
|
16
|
+
/** The module of the engine with 3D Tiles once it runs the map (the decoding workers run it too) */
|
|
17
|
+
private module;
|
|
18
|
+
private loader;
|
|
19
|
+
private readonly options;
|
|
20
|
+
/** The map is destroyed: a loaded engine is not used */
|
|
21
|
+
private readonly gone;
|
|
22
|
+
/** `module`: the module of the engine with 3D Tiles if `engineClass` is that engine */
|
|
23
|
+
constructor(engineClass: EngineClass, module: WebAssembly.Module | undefined, options: Tiles3dEngineOptions, gone: () => boolean);
|
|
24
|
+
/** The engine with 3D Tiles runs the map */
|
|
25
|
+
get tiles3d(): boolean;
|
|
26
|
+
/** The engine with 3D Tiles is loading, for the 3D Tiles layers added on the core engine */
|
|
27
|
+
get upgrading(): Promise<void> | undefined;
|
|
28
|
+
/** A new engine drawing on `canvas`, with the settings and the decoding workers of 3D Tiles if it has them */
|
|
29
|
+
create(canvas: HTMLCanvasElement, redraw: () => void, settings: Settings): Engine;
|
|
30
|
+
/** Height of the geoid above the ellipsoid at a position, in metres */
|
|
31
|
+
geoidHeight(lon: number, lat: number): number;
|
|
32
|
+
/** The matrix of a custom layer's model at a position */
|
|
33
|
+
customMatrix(lon: number, lat: number, altitude: number): Float32Array | undefined;
|
|
34
|
+
/** Loads the engine with 3D Tiles, once at a time: `loaded` once it is the map's class, `failed` with the error;
|
|
35
|
+
* neither if the map is gone by then */
|
|
36
|
+
upgrade(loaded: () => void, failed: (error: unknown) => void): void;
|
|
37
|
+
/** Downloads and compiles the engine with 3D Tiles without running it, unless the map is gone or has it by then */
|
|
38
|
+
preload(): void;
|
|
39
|
+
/** Stops the decoding workers */
|
|
40
|
+
destroy(): void;
|
|
41
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Which engine a map runs: the core one, or the one with 3D Tiles, from the start or loaded once a layer needs it
|
|
3
|
+
* (the map is rebuilt on it then); and the workers decoding its 3D Tiles, started with the first engine that has them.
|
|
4
|
+
*/
|
|
5
|
+
import { engineUrl, loadFullEngineLater, preloadFullEngine, startTileLoader, } from "../engine-loader.js";
|
|
6
|
+
import { applySettings } from "./engine-settings.js";
|
|
7
|
+
/** The engine class of a map, and the engine with 3D Tiles loaded when needed */
|
|
8
|
+
export class MapEngines {
|
|
9
|
+
/** The class of the engine: without 3D Tiles until a 3D Tiles layer is added, unless asked for from the start */
|
|
10
|
+
engineClass;
|
|
11
|
+
/** The module of the engine with 3D Tiles once it runs the map (the decoding workers run it too) */
|
|
12
|
+
module;
|
|
13
|
+
#upgrading;
|
|
14
|
+
loader;
|
|
15
|
+
options;
|
|
16
|
+
/** The map is destroyed: a loaded engine is not used */
|
|
17
|
+
gone;
|
|
18
|
+
/** `module`: the module of the engine with 3D Tiles if `engineClass` is that engine */
|
|
19
|
+
constructor(engineClass, module, options, gone) {
|
|
20
|
+
this.engineClass = engineClass;
|
|
21
|
+
this.module = module;
|
|
22
|
+
this.options = { ...options };
|
|
23
|
+
this.gone = gone;
|
|
24
|
+
}
|
|
25
|
+
/** The engine with 3D Tiles runs the map */
|
|
26
|
+
get tiles3d() {
|
|
27
|
+
return this.module !== undefined;
|
|
28
|
+
}
|
|
29
|
+
/** The engine with 3D Tiles is loading, for the 3D Tiles layers added on the core engine */
|
|
30
|
+
get upgrading() {
|
|
31
|
+
return this.#upgrading;
|
|
32
|
+
}
|
|
33
|
+
/** A new engine drawing on `canvas`, with the settings and the decoding workers of 3D Tiles if it has them */
|
|
34
|
+
create(canvas, redraw, settings) {
|
|
35
|
+
const engine = new this.engineClass(canvas, redraw);
|
|
36
|
+
applySettings(engine, settings);
|
|
37
|
+
// The decoding workers of 3D Tiles, with the engine that has them (they run its module) and unless turned off
|
|
38
|
+
this.loader ??= this.module && startTileLoader(this.module, this.options, engine);
|
|
39
|
+
if (this.loader)
|
|
40
|
+
engine.setTileLoader(this.loader);
|
|
41
|
+
return engine;
|
|
42
|
+
}
|
|
43
|
+
/** Height of the geoid above the ellipsoid at a position, in metres */
|
|
44
|
+
geoidHeight(lon, lat) {
|
|
45
|
+
return this.engineClass.geoidHeight(lon, lat);
|
|
46
|
+
}
|
|
47
|
+
/** The matrix of a custom layer's model at a position */
|
|
48
|
+
customMatrix(lon, lat, altitude) {
|
|
49
|
+
return this.engineClass.customMatrix(lon, lat, altitude);
|
|
50
|
+
}
|
|
51
|
+
/** Loads the engine with 3D Tiles, once at a time: `loaded` once it is the map's class, `failed` with the error;
|
|
52
|
+
* neither if the map is gone by then */
|
|
53
|
+
upgrade(loaded, failed) {
|
|
54
|
+
this.#upgrading ??= loadFullEngineLater(engineUrl('full', this.options)).then(({ module, Engine }) => {
|
|
55
|
+
this.#upgrading = undefined;
|
|
56
|
+
if (this.gone())
|
|
57
|
+
return;
|
|
58
|
+
this.engineClass = Engine;
|
|
59
|
+
this.module = module;
|
|
60
|
+
loaded();
|
|
61
|
+
}, (error) => {
|
|
62
|
+
this.#upgrading = undefined;
|
|
63
|
+
if (this.gone())
|
|
64
|
+
return;
|
|
65
|
+
failed(error);
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
/** Downloads and compiles the engine with 3D Tiles without running it, unless the map is gone or has it by then */
|
|
69
|
+
preload() {
|
|
70
|
+
preloadFullEngine(engineUrl('full', this.options), () => !this.gone() && !this.module);
|
|
71
|
+
}
|
|
72
|
+
/** Stops the decoding workers */
|
|
73
|
+
destroy() {
|
|
74
|
+
this.loader?.destroy();
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=engines.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engines.js","sourceRoot":"","sources":["../../src/map/engines.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Which engine a map runs: the core one, or the one with 3D Tiles, from the start or loaded once a layer needs it\n * (the map is rebuilt on it then); and the workers decoding its 3D Tiles, started with the first engine that has them.\n */\n\nimport type { TileLoader } from '../engine/loader.ts';\nimport {\n type EngineClass,\n engineUrl,\n loadFullEngineLater,\n preloadFullEngine,\n startTileLoader,\n} from '../engine-loader.ts';\nimport type { Settings } from '../settings.ts';\nimport type { GeoMapOptions } from '../types.ts';\nimport type { Engine } from '../wasm/isard.js';\nimport { applySettings } from './engine-settings.ts';\n\n/** What loading the engine with 3D Tiles and its workers needs */\nexport type Tiles3dEngineOptions = Pick<\n GeoMapOptions,\n 'wasmUrl' | 'workers' | 'workerUrl' | 'decoders' | 'pointsWasmUrl' | 'assetsUrl'\n>;\n\n/** The engine class of a map, and the engine with 3D Tiles loaded when needed */\nexport class MapEngines {\n /** The class of the engine: without 3D Tiles until a 3D Tiles layer is added, unless asked for from the start */\n private engineClass: EngineClass;\n /** The module of the engine with 3D Tiles once it runs the map (the decoding workers run it too) */\n private module: WebAssembly.Module | undefined;\n #upgrading: Promise<void> | undefined;\n private loader: TileLoader | undefined;\n private readonly options: Tiles3dEngineOptions;\n /** The map is destroyed: a loaded engine is not used */\n private readonly gone: () => boolean;\n\n /** `module`: the module of the engine with 3D Tiles if `engineClass` is that engine */\n constructor(\n engineClass: EngineClass,\n module: WebAssembly.Module | undefined,\n options: Tiles3dEngineOptions,\n gone: () => boolean,\n ) {\n this.engineClass = engineClass;\n this.module = module;\n this.options = { ...options };\n this.gone = gone;\n }\n\n /** The engine with 3D Tiles runs the map */\n get tiles3d(): boolean {\n return this.module !== undefined;\n }\n\n /** The engine with 3D Tiles is loading, for the 3D Tiles layers added on the core engine */\n get upgrading(): Promise<void> | undefined {\n return this.#upgrading;\n }\n\n /** A new engine drawing on `canvas`, with the settings and the decoding workers of 3D Tiles if it has them */\n create(canvas: HTMLCanvasElement, redraw: () => void, settings: Settings): Engine {\n const engine = new this.engineClass(canvas, redraw);\n\n applySettings(engine, settings);\n // The decoding workers of 3D Tiles, with the engine that has them (they run its module) and unless turned off\n this.loader ??= this.module && startTileLoader(this.module, this.options, engine);\n if (this.loader) engine.setTileLoader(this.loader);\n\n return engine;\n }\n\n /** Height of the geoid above the ellipsoid at a position, in metres */\n geoidHeight(lon: number, lat: number): number {\n return this.engineClass.geoidHeight(lon, lat);\n }\n\n /** The matrix of a custom layer's model at a position */\n customMatrix(lon: number, lat: number, altitude: number): Float32Array | undefined {\n return this.engineClass.customMatrix(lon, lat, altitude);\n }\n\n /** Loads the engine with 3D Tiles, once at a time: `loaded` once it is the map's class, `failed` with the error;\n * neither if the map is gone by then */\n upgrade(loaded: () => void, failed: (error: unknown) => void): void {\n this.#upgrading ??= loadFullEngineLater(engineUrl('full', this.options)).then(\n ({ module, Engine }) => {\n this.#upgrading = undefined;\n if (this.gone()) return;\n this.engineClass = Engine;\n this.module = module;\n loaded();\n },\n (error: unknown) => {\n this.#upgrading = undefined;\n if (this.gone()) return;\n failed(error);\n },\n );\n }\n\n /** Downloads and compiles the engine with 3D Tiles without running it, unless the map is gone or has it by then */\n preload(): void {\n preloadFullEngine(engineUrl('full', this.options), () => !this.gone() && !this.module);\n }\n\n /** Stops the decoding workers */\n destroy(): void {\n this.loader?.destroy();\n }\n}\n"]}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/** The listeners of the map's events: added, called, cleared with the map. */
|
|
2
|
+
import type { MapEvents } from '../types.ts';
|
|
3
|
+
/** The listeners of the map's events, by type */
|
|
4
|
+
export declare class MapListeners {
|
|
5
|
+
private readonly listeners;
|
|
6
|
+
/** Listens to an event; returns the function that stops listening */
|
|
7
|
+
on<K extends keyof MapEvents>(type: K, listener: (event: MapEvents[K]) => void): () => void;
|
|
8
|
+
/** Calls the listeners; one that throws is reported and does not stop the others nor the frame */
|
|
9
|
+
emit<K extends keyof MapEvents>(type: K, event: MapEvents[K]): void;
|
|
10
|
+
/** Something listens to `type` */
|
|
11
|
+
has(type: keyof MapEvents): boolean;
|
|
12
|
+
/** Forgets every listener */
|
|
13
|
+
clear(): void;
|
|
14
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/** The listeners of the map's events: added, called, cleared with the map. */
|
|
2
|
+
import { report } from "./checks.js";
|
|
3
|
+
/** The listeners of the map's events, by type */
|
|
4
|
+
export class MapListeners {
|
|
5
|
+
listeners = {
|
|
6
|
+
movestart: new Set(),
|
|
7
|
+
move: new Set(),
|
|
8
|
+
moveend: new Set(),
|
|
9
|
+
resize: new Set(),
|
|
10
|
+
hover: new Set(),
|
|
11
|
+
hoverfeature: new Set(),
|
|
12
|
+
click: new Set(),
|
|
13
|
+
render: new Set(),
|
|
14
|
+
idle: new Set(),
|
|
15
|
+
leave: new Set(),
|
|
16
|
+
};
|
|
17
|
+
/** Listens to an event; returns the function that stops listening */
|
|
18
|
+
on(type, listener) {
|
|
19
|
+
const listeners = this.listeners[type];
|
|
20
|
+
listeners.add(listener);
|
|
21
|
+
return () => listeners.delete(listener);
|
|
22
|
+
}
|
|
23
|
+
/** Calls the listeners; one that throws is reported and does not stop the others nor the frame */
|
|
24
|
+
emit(type, event) {
|
|
25
|
+
const listeners = this.listeners[type];
|
|
26
|
+
listeners.forEach((listener) => {
|
|
27
|
+
try {
|
|
28
|
+
listener(event);
|
|
29
|
+
}
|
|
30
|
+
catch (error) {
|
|
31
|
+
report(error);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
/** Something listens to `type` */
|
|
36
|
+
has(type) {
|
|
37
|
+
return this.listeners[type].size > 0;
|
|
38
|
+
}
|
|
39
|
+
/** Forgets every listener */
|
|
40
|
+
clear() {
|
|
41
|
+
Object.values(this.listeners).forEach((listeners) => {
|
|
42
|
+
listeners.clear();
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
//# sourceMappingURL=events.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/map/events.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAG9E,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAIrC,iDAAiD;AACjD,MAAM,OAAO,YAAY;IACN,SAAS,GAAc;QACtC,SAAS,EAAE,IAAI,GAAG,EAAE;QACpB,IAAI,EAAE,IAAI,GAAG,EAAE;QACf,OAAO,EAAE,IAAI,GAAG,EAAE;QAClB,MAAM,EAAE,IAAI,GAAG,EAAE;QACjB,KAAK,EAAE,IAAI,GAAG,EAAE;QAChB,YAAY,EAAE,IAAI,GAAG,EAAE;QACvB,KAAK,EAAE,IAAI,GAAG,EAAE;QAChB,MAAM,EAAE,IAAI,GAAG,EAAE;QACjB,IAAI,EAAE,IAAI,GAAG,EAAE;QACf,KAAK,EAAE,IAAI,GAAG,EAAE;KACjB,CAAC;IAEF,qEAAqE;IACrE,EAAE,CAA4B,IAAO,EAAE,QAAuC;QAC5E,MAAM,SAAS,GAAuC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAE3E,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC;QAExB,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC;IAC1C,CAAC;IAED,kGAAkG;IAClG,IAAI,CAA4B,IAAO,EAAE,KAAmB;QAC1D,MAAM,SAAS,GAAuC,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAE3E,SAAS,CAAC,OAAO,CAAC,CAAC,QAAQ,EAAE,EAAE;YAC7B,IAAI,CAAC;gBACH,QAAQ,CAAC,KAAK,CAAC,CAAC;YAClB,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,MAAM,CAAC,KAAK,CAAC,CAAC;YAChB,CAAC;QACH,CAAC,CAAC,CAAC;IACL,CAAC;IAED,kCAAkC;IAClC,GAAG,CAAC,IAAqB;QACvB,OAAO,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC,IAAI,GAAG,CAAC,CAAC;IACvC,CAAC;IAED,6BAA6B;IAC7B,KAAK;QACH,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,CAAC,SAAS,EAAE,EAAE;YAClD,SAAS,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC,CAAC,CAAC;IACL,CAAC;CACF","sourcesContent":["/** The listeners of the map's events: added, called, cleared with the map. */\n\nimport type { MapEvents } from '../types.ts';\nimport { report } from './checks.ts';\n\ntype Listeners = { [K in keyof MapEvents]: Set<(event: MapEvents[K]) => void> };\n\n/** The listeners of the map's events, by type */\nexport class MapListeners {\n private readonly listeners: Listeners = {\n movestart: new Set(),\n move: new Set(),\n moveend: new Set(),\n resize: new Set(),\n hover: new Set(),\n hoverfeature: new Set(),\n click: new Set(),\n render: new Set(),\n idle: new Set(),\n leave: new Set(),\n };\n\n /** Listens to an event; returns the function that stops listening */\n on<K extends keyof MapEvents>(type: K, listener: (event: MapEvents[K]) => void): () => void {\n const listeners: Set<(event: MapEvents[K]) => void> = this.listeners[type];\n\n listeners.add(listener);\n\n return () => listeners.delete(listener);\n }\n\n /** Calls the listeners; one that throws is reported and does not stop the others nor the frame */\n emit<K extends keyof MapEvents>(type: K, event: MapEvents[K]): void {\n const listeners: Set<(event: MapEvents[K]) => void> = this.listeners[type];\n\n listeners.forEach((listener) => {\n try {\n listener(event);\n } catch (error) {\n report(error);\n }\n });\n }\n\n /** Something listens to `type` */\n has(type: keyof MapEvents): boolean {\n return this.listeners[type].size > 0;\n }\n\n /** Forgets every listener */\n clear(): void {\n Object.values(this.listeners).forEach((listeners) => {\n listeners.clear();\n });\n }\n}\n"]}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The frame loop of a map: frames drawn on demand only (an idle map costs nothing), the running animation stepped in
|
|
3
|
+
* each, and the events of a frame sent with it: the camera's moves, the pointer's position (coalesced to one per
|
|
4
|
+
* frame, so the values computed for it are drawn in the same frame), 'render', and 'idle' once everything is loaded.
|
|
5
|
+
*/
|
|
6
|
+
import type { Point } from '../types.ts';
|
|
7
|
+
import type { Step } from '../util/animation.ts';
|
|
8
|
+
import type { Camera, Engine } from '../wasm/isard.js';
|
|
9
|
+
import type { MapListeners } from './events.ts';
|
|
10
|
+
/** What the frame loop needs of its map */
|
|
11
|
+
export interface FrameHost {
|
|
12
|
+
/** The map's engine of the moment */
|
|
13
|
+
engine(): Engine;
|
|
14
|
+
/** The map's camera */
|
|
15
|
+
camera(): Camera;
|
|
16
|
+
/** The WebGL context is lost: nothing is drawn */
|
|
17
|
+
lost(): boolean;
|
|
18
|
+
/** The pointer or the keys are moving the camera: no 'moveend' yet */
|
|
19
|
+
interacting(): boolean;
|
|
20
|
+
/** Custom layers are drawn: they read the camera of the frame */
|
|
21
|
+
customLayers(): boolean;
|
|
22
|
+
/** The engine with 3D Tiles is loading: not idle */
|
|
23
|
+
upgrading(): boolean;
|
|
24
|
+
/** The frame is drawn: what follows it (the overlays placed, the hover picking asked for at `hovered`) */
|
|
25
|
+
drawn(hovered: Point | undefined): void;
|
|
26
|
+
}
|
|
27
|
+
/** The frames of a map, asked for and drawn */
|
|
28
|
+
export declare class FrameLoop {
|
|
29
|
+
#private;
|
|
30
|
+
private readonly host;
|
|
31
|
+
private readonly listeners;
|
|
32
|
+
/** Frame asked for, 0 if none */
|
|
33
|
+
private requested;
|
|
34
|
+
private inFrame;
|
|
35
|
+
private animation;
|
|
36
|
+
/** The pointer's position for the next frame */
|
|
37
|
+
private hoverPoint;
|
|
38
|
+
private lastCamera;
|
|
39
|
+
/** The camera moved since the last 'moveend' */
|
|
40
|
+
private moving;
|
|
41
|
+
/** `listeners`: the map's, told of the frame's events */
|
|
42
|
+
constructor(host: FrameHost, listeners: MapListeners);
|
|
43
|
+
/** The last frame found everything loaded ('idle' sent) */
|
|
44
|
+
get settled(): boolean;
|
|
45
|
+
/** The camera of the frame being drawn: what `getCamera` gives the custom layers while the engine is busy */
|
|
46
|
+
get camera(): Camera | undefined;
|
|
47
|
+
/** Asks for a frame; several calls before the next frame draw it once */
|
|
48
|
+
request(): void;
|
|
49
|
+
/** Runs `step` every frame until it returns false; replaces the running animation */
|
|
50
|
+
animate(step: Step | undefined): void;
|
|
51
|
+
/** The pointer's position for the next frame (undefined: none) */
|
|
52
|
+
hover(point: Point | undefined): void;
|
|
53
|
+
/** Draws a frame now, in place of the one asked for (a resized canvas is cleared: waiting one frame would flash) */
|
|
54
|
+
drawNow(): void;
|
|
55
|
+
/** Cancels the frame asked for (the context is lost); a new one can be asked for */
|
|
56
|
+
cancel(): void;
|
|
57
|
+
/** Cancels the frame asked for, for good (the map is destroyed): it stays marked as asked for */
|
|
58
|
+
stop(): void;
|
|
59
|
+
private frame;
|
|
60
|
+
private draw;
|
|
61
|
+
}
|