isard 0.3.0 → 0.5.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 +68 -0
- package/README.md +11 -3
- package/dist/basemap.worker.d.ts +10 -3
- package/dist/basemap.worker.js +2 -2
- package/dist/basemap.worker.js.map +4 -4
- package/dist/decoder.worker.js +4 -4
- package/dist/decoder.worker.js.map +7 -6
- package/dist/decoders.d.ts +3 -2
- package/dist/decoders.js +28 -5
- package/dist/decoders.js.map +1 -1
- package/dist/engine-loader.d.ts +8 -4
- package/dist/engine-loader.js +10 -3
- package/dist/engine-loader.js.map +1 -1
- package/dist/formats.d.ts +11 -0
- package/dist/formats.js +12 -0
- package/dist/formats.js.map +1 -0
- package/dist/glyphs.d.ts +3 -0
- package/dist/glyphs.js +12 -2
- package/dist/glyphs.js.map +1 -1
- package/dist/icons.d.ts +146 -0
- package/dist/icons.js +333 -0
- package/dist/icons.js.map +1 -0
- package/dist/index.d.ts +8 -5
- package/dist/index.js +2 -1
- 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/layers.d.ts +88 -1
- package/dist/layers.js +165 -4
- package/dist/layers.js.map +1 -1
- package/dist/loader.d.ts +9 -3
- package/dist/loader.js +22 -3
- package/dist/loader.js.map +1 -1
- package/dist/map.d.ts +37 -3
- package/dist/map.js +76 -10
- package/dist/map.js.map +1 -1
- package/dist/pointclouds.d.ts +98 -0
- package/dist/pointclouds.js +232 -0
- package/dist/pointclouds.js.map +1 -0
- package/dist/projections.d.ts +13 -0
- package/dist/projections.js +13 -0
- package/dist/projections.js.map +1 -0
- package/dist/protocol.d.ts +17 -0
- package/dist/protocol.js.map +1 -1
- package/dist/symbols.d.ts +42 -8
- package/dist/symbols.js +160 -35
- package/dist/symbols.js.map +1 -1
- package/dist/types.d.ts +8 -3
- package/dist/types.js.map +1 -1
- package/dist/vectorstyle.d.ts +32 -3
- package/dist/vectorstyle.js.map +1 -1
- package/dist/vectortiles.d.ts +10 -5
- package/dist/vectortiles.js +54 -29
- package/dist/vectortiles.js.map +1 -1
- package/dist/wasm/isard.d.ts +168 -11
- package/dist/wasm/isard.js +234 -9
- package/dist/wasm/isard_core.d.ts +28 -3
- package/dist/wasm/isard_core.js +77 -4
- package/dist/wasm/isard_points.d.ts +43 -0
- package/dist/wasm/isard_points.js +212 -0
- package/package.json +17 -1
package/dist/map.d.ts
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { type Control, type ControlPosition } from './controls.ts';
|
|
2
2
|
import { ExtrusionLayer, type ExtrusionOptions } from './extrusions.ts';
|
|
3
3
|
import { CircleLayer, type CircleOptions, FillLayer, type FillOptions, LineLayer, type LineOptions } from './features.ts';
|
|
4
|
-
import {
|
|
4
|
+
import { type ImageOptions, type Pixels } from './icons.ts';
|
|
5
|
+
import { CustomLayer, type CustomLayerInterface, GroundLayer, type GroundOptions, type Layer, ModelLayer, type ModelOptions, NetworkLayer, RasterLayer, Tiles3dLayer } from './layers.ts';
|
|
6
|
+
import { PointCloudLayer, type PointCloudOptions } from './pointclouds.ts';
|
|
5
7
|
import { SymbolLayer, type SymbolOptions } from './symbols.ts';
|
|
6
8
|
import type { AnimationOptions, AtmosphereOptions, Basemap, FeatureHit, FlyToOptions, GeoMapOptions, LoadingMode, LonLat, MapEvents, NetworkOptions, Point, Projection, RasterOptions, TerrainModel, TerrainOptions, Tiles3dOptions } from './types.ts';
|
|
7
9
|
import { VectorTiles, type VectorTilesOptions } from './vectortiles.ts';
|
|
@@ -72,6 +74,8 @@ export declare class GeoMap {
|
|
|
72
74
|
/** The last frame found everything loaded ('idle' sent) */
|
|
73
75
|
private settled;
|
|
74
76
|
private inFrame;
|
|
77
|
+
/** The camera of the frame being drawn: what `getCamera` gives the custom layers while the engine is busy */
|
|
78
|
+
private frameCamera;
|
|
75
79
|
/** Vector tiles made by `vectorTiles()`, destroyed with the map */
|
|
76
80
|
private readonly vectorSets;
|
|
77
81
|
/** The workers drawing vector tiles, shared by every `VectorTiles` of the map; created on first use */
|
|
@@ -92,8 +96,8 @@ export declare class GeoMap {
|
|
|
92
96
|
private createEngine;
|
|
93
97
|
/** The decoding workers of 3D Tiles, with the engine that has them (they run its module) and unless turned off */
|
|
94
98
|
private startLoader;
|
|
95
|
-
/** A 3D Tiles layer on the core engine: loads the engine with 3D Tiles, then rebuilds the map on it
|
|
96
|
-
* settings and layers kept, as after a context loss); the layer is created then */
|
|
99
|
+
/** A 3D Tiles layer or a model on the core engine: loads the engine with 3D Tiles, then rebuilds the map on it
|
|
100
|
+
* (camera, settings and layers kept, as after a context loss); the layer is created then */
|
|
97
101
|
private upgrade;
|
|
98
102
|
/** Downloads and compiles the engine with 3D Tiles once the map is idle (`tiles3d: 'preload'`), without running
|
|
99
103
|
* it: the first 3D Tiles layer then only instantiates it */
|
|
@@ -193,6 +197,18 @@ export declare class GeoMap {
|
|
|
193
197
|
addExtrusions<P = Record<string, unknown>>(options?: ExtrusionOptions<P>): ExtrusionLayer<P>;
|
|
194
198
|
/** Text labels from GeoJSON (points, the middle of lines, the center of polygons), placed without overlaps */
|
|
195
199
|
addSymbols<P = Record<string, unknown>>(options: SymbolOptions<P>): SymbolLayer<P>;
|
|
200
|
+
/**
|
|
201
|
+
* An image for the symbol layers' icons (`icon: name`), as MapLibre's `addImage`: its pixels (an image, a canvas,
|
|
202
|
+
* `ImageData`, or RGBA bytes with their size), `pixelRatio` 2 for an image drawn at twice its CSS size; `sdf` for a
|
|
203
|
+
* signed distance field drawn in the `iconColor`; `stretchX`, `stretchY` and `content` for an icon stretched around its
|
|
204
|
+
* text. An image of the same name is replaced
|
|
205
|
+
*/
|
|
206
|
+
addImage(name: string, image: Pixels | (CanvasImageSource & {
|
|
207
|
+
width: number;
|
|
208
|
+
height: number;
|
|
209
|
+
}), options?: ImageOptions): void;
|
|
210
|
+
hasImage(name: string): boolean;
|
|
211
|
+
removeImage(name: string): void;
|
|
196
212
|
/**
|
|
197
213
|
* Vector tiles with a MapLibre style (OpenFreeMap's Positron by default): `tiles.raster(…)` draws its fills and lines
|
|
198
214
|
* (or a subset) as a raster layer, `tiles.labels(…)` its labels. `setBasemap('osm-positron')` does both for the
|
|
@@ -212,6 +228,24 @@ export declare class GeoMap {
|
|
|
212
228
|
private place;
|
|
213
229
|
/** Textured meshes in 3D Tiles (photogrammetry, buildings), drawn with depth over the basemap */
|
|
214
230
|
addTiles3d(options: Tiles3dOptions): Tiles3dLayer;
|
|
231
|
+
/**
|
|
232
|
+
* A point cloud (see `PointCloudOptions`): a COPC file read by range requests (IGN's LiDAR HD…), or 3D Tiles
|
|
233
|
+
* points; with depth, on the engine with 3D Tiles; under `before` if given
|
|
234
|
+
*/
|
|
235
|
+
addPointCloud(options: PointCloudOptions & {
|
|
236
|
+
before?: Layer;
|
|
237
|
+
}): PointCloudLayer;
|
|
238
|
+
/** A glTF model drawn at positions (see `ModelOptions`), with depth; on the engine with 3D Tiles, as they are */
|
|
239
|
+
addModels(options: ModelOptions & {
|
|
240
|
+
before?: Layer;
|
|
241
|
+
}): ModelLayer;
|
|
242
|
+
/**
|
|
243
|
+
* The page's own WebGL drawing at its place among the layers, in every frame (see `CustomLayerInterface`): raw
|
|
244
|
+
* WebGL, three.js… with the matrices of the frame (`frame.matrixAt`); under `before` if given
|
|
245
|
+
*/
|
|
246
|
+
addCustomLayer(layer: CustomLayerInterface, options?: {
|
|
247
|
+
before?: Layer;
|
|
248
|
+
}): CustomLayer;
|
|
215
249
|
/** Asks for a frame; several calls before the next frame draw it once */
|
|
216
250
|
requestRender(): void;
|
|
217
251
|
private frame;
|
package/dist/map.js
CHANGED
|
@@ -12,8 +12,10 @@ import { ExtrusionLayer, extrusionStyle } from "./extrusions.js";
|
|
|
12
12
|
import { CircleLayer, circleStyle, FillLayer, fillStyle, LineLayer, lineStyle, } from "./features.js";
|
|
13
13
|
import { Glyphs } from "./glyphs.js";
|
|
14
14
|
import { equirectangularGrid, gridLoader, gridZooms, resolveGrid } from "./grid.js";
|
|
15
|
+
import { Icons, readPixels } from "./icons.js";
|
|
15
16
|
import { Interaction } from "./interaction.js";
|
|
16
|
-
import { GroundLayer, NetworkLayer, RasterLayer, Tiles3dLayer } from "./layers.js";
|
|
17
|
+
import { CustomLayer, GroundLayer, ModelLayer, NetworkLayer, RasterLayer, Tiles3dLayer, } from "./layers.js";
|
|
18
|
+
import { PointCloudLayer } from "./pointclouds.js";
|
|
17
19
|
import { atmosphereSettings, bodySettings, haloSettings, rgb, terrainSettings, } from "./settings.js";
|
|
18
20
|
import { injectStyle } from "./style.js";
|
|
19
21
|
import { SymbolLayer, symbolStyle } from "./symbols.js";
|
|
@@ -56,6 +58,7 @@ function checkBasemap(basemap) {
|
|
|
56
58
|
export class GeoMap {
|
|
57
59
|
canvas;
|
|
58
60
|
#glyphs;
|
|
61
|
+
#icons;
|
|
59
62
|
/** Layers new layers go under */
|
|
60
63
|
onTop = new Set();
|
|
61
64
|
/** The vector basemap, if any: its tiles' workers and its labels */
|
|
@@ -127,6 +130,8 @@ export class GeoMap {
|
|
|
127
130
|
/** The last frame found everything loaded ('idle' sent) */
|
|
128
131
|
settled = false;
|
|
129
132
|
inFrame = false;
|
|
133
|
+
/** The camera of the frame being drawn: what `getCamera` gives the custom layers while the engine is busy */
|
|
134
|
+
frameCamera;
|
|
130
135
|
/** Vector tiles made by `vectorTiles()`, destroyed with the map */
|
|
131
136
|
vectorSets = new Set();
|
|
132
137
|
/** The workers drawing vector tiles, shared by every `VectorTiles` of the map; created on first use */
|
|
@@ -270,8 +275,8 @@ export class GeoMap {
|
|
|
270
275
|
startLoader(engine) {
|
|
271
276
|
return this.tiles3dModule && startTileLoader(this.tiles3dModule, this.tiles3dOptions, engine);
|
|
272
277
|
}
|
|
273
|
-
/** A 3D Tiles layer on the core engine: loads the engine with 3D Tiles, then rebuilds the map on it
|
|
274
|
-
* settings and layers kept, as after a context loss); the layer is created then */
|
|
278
|
+
/** A 3D Tiles layer or a model on the core engine: loads the engine with 3D Tiles, then rebuilds the map on it
|
|
279
|
+
* (camera, settings and layers kept, as after a context loss); the layer is created then */
|
|
275
280
|
upgrade() {
|
|
276
281
|
this.upgrading ??= loadFullEngineLater(engineUrl('full', this.tiles3dOptions)).then(({ module, Engine }) => {
|
|
277
282
|
this.upgrading = undefined;
|
|
@@ -316,13 +321,14 @@ export class GeoMap {
|
|
|
316
321
|
this.lost = false;
|
|
317
322
|
this.setCamera(camera);
|
|
318
323
|
this.#glyphs?.attach(this.#engine);
|
|
324
|
+
this.#icons?.attach(this.#engine);
|
|
319
325
|
const engine = this.#engine;
|
|
320
326
|
// No layer refers to an id of the old engine while the others are created
|
|
321
327
|
for (const layer of this.layers)
|
|
322
328
|
layer.forgetEngine();
|
|
323
329
|
for (const layer of this.layers) {
|
|
324
330
|
// Still waiting for the engine with 3D Tiles (loading, or failed): created with it
|
|
325
|
-
if (layer
|
|
331
|
+
if (layer.needsFullEngine && !this.tiles3dModule)
|
|
326
332
|
continue;
|
|
327
333
|
// A layer that fails is reported and left out; the others are created
|
|
328
334
|
try {
|
|
@@ -363,8 +369,9 @@ export class GeoMap {
|
|
|
363
369
|
this.layers.splice(index, 1);
|
|
364
370
|
}
|
|
365
371
|
add(layer) {
|
|
366
|
-
// On the core engine, a 3D Tiles layer waits for the engine with 3D Tiles: it is created with the
|
|
367
|
-
|
|
372
|
+
// On the core engine, a 3D Tiles layer or a model waits for the engine with 3D Tiles: it is created with the
|
|
373
|
+
// others on it
|
|
374
|
+
if (layer.needsFullEngine && !this.tiles3dModule)
|
|
368
375
|
this.upgrade();
|
|
369
376
|
else
|
|
370
377
|
layer.attach(this.engine);
|
|
@@ -433,7 +440,7 @@ export class GeoMap {
|
|
|
433
440
|
}
|
|
434
441
|
// ── Camera ──
|
|
435
442
|
getCamera() {
|
|
436
|
-
return this.engine.camera();
|
|
443
|
+
return this.frameCamera ?? this.engine.camera();
|
|
437
444
|
}
|
|
438
445
|
setCamera(camera) {
|
|
439
446
|
const c = { ...this.getCamera(), ...camera };
|
|
@@ -758,6 +765,34 @@ export class GeoMap {
|
|
|
758
765
|
}
|
|
759
766
|
return this.#glyphs;
|
|
760
767
|
}
|
|
768
|
+
/** @internal The icons of the symbol layers: the application's images and the vector basemaps' sprites */
|
|
769
|
+
get icons() {
|
|
770
|
+
if (!this.#icons) {
|
|
771
|
+
const gl = this.canvas.getContext('webgl2');
|
|
772
|
+
const max = gl?.getParameter(gl.MAX_TEXTURE_SIZE);
|
|
773
|
+
this.#icons = new Icons(typeof max === 'number' ? max : undefined);
|
|
774
|
+
this.#icons.attach(this.engine);
|
|
775
|
+
}
|
|
776
|
+
return this.#icons;
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* An image for the symbol layers' icons (`icon: name`), as MapLibre's `addImage`: its pixels (an image, a canvas,
|
|
780
|
+
* `ImageData`, or RGBA bytes with their size), `pixelRatio` 2 for an image drawn at twice its CSS size; `sdf` for a
|
|
781
|
+
* signed distance field drawn in the `iconColor`; `stretchX`, `stretchY` and `content` for an icon stretched around its
|
|
782
|
+
* text. An image of the same name is replaced
|
|
783
|
+
*/
|
|
784
|
+
addImage(name, image, options = {}) {
|
|
785
|
+
const pixels = 'data' in image ? image : readPixels(image);
|
|
786
|
+
if (!pixels)
|
|
787
|
+
throw new Error(`isard: the image ${name} has no pixels`);
|
|
788
|
+
this.icons.add(name, pixels, options);
|
|
789
|
+
}
|
|
790
|
+
hasImage(name) {
|
|
791
|
+
return this.#icons?.has(name) ?? false;
|
|
792
|
+
}
|
|
793
|
+
removeImage(name) {
|
|
794
|
+
this.#icons?.remove(name);
|
|
795
|
+
}
|
|
761
796
|
/**
|
|
762
797
|
* Vector tiles with a MapLibre style (OpenFreeMap's Positron by default): `tiles.raster(…)` draws its fills and lines
|
|
763
798
|
* (or a subset) as a raster layer, `tiles.labels(…)` its labels. `setBasemap('osm-positron')` does both for the
|
|
@@ -824,8 +859,27 @@ export class GeoMap {
|
|
|
824
859
|
}
|
|
825
860
|
/** Textured meshes in 3D Tiles (photogrammetry, buildings), drawn with depth over the basemap */
|
|
826
861
|
addTiles3d(options) {
|
|
827
|
-
const { url, maxScreenSpaceError = 16, opacity = 1 } = options;
|
|
828
|
-
return this.add(new Tiles3dLayer(this, url, { maxScreenSpaceError, opacity }));
|
|
862
|
+
const { url, maxScreenSpaceError = 16, opacity = 1, pointSize } = options;
|
|
863
|
+
return this.add(new Tiles3dLayer(this, url, { maxScreenSpaceError, opacity, ...(pointSize !== undefined ? { pointSize } : {}) }));
|
|
864
|
+
}
|
|
865
|
+
/**
|
|
866
|
+
* A point cloud (see `PointCloudOptions`): a COPC file read by range requests (IGN's LiDAR HD…), or 3D Tiles
|
|
867
|
+
* points; with depth, on the engine with 3D Tiles; under `before` if given
|
|
868
|
+
*/
|
|
869
|
+
addPointCloud(options) {
|
|
870
|
+
return this.place(new PointCloudLayer(this, options), options.before);
|
|
871
|
+
}
|
|
872
|
+
/** A glTF model drawn at positions (see `ModelOptions`), with depth; on the engine with 3D Tiles, as they are */
|
|
873
|
+
addModels(options) {
|
|
874
|
+
return this.place(new ModelLayer(this, options), options.before);
|
|
875
|
+
}
|
|
876
|
+
/**
|
|
877
|
+
* The page's own WebGL drawing at its place among the layers, in every frame (see `CustomLayerInterface`): raw
|
|
878
|
+
* WebGL, three.js… with the matrices of the frame (`frame.matrixAt`); under `before` if given
|
|
879
|
+
*/
|
|
880
|
+
addCustomLayer(layer, options = {}) {
|
|
881
|
+
const custom = new CustomLayer(this, layer, this.canvas, this, (lon, lat, altitude) => this.engineClass.customMatrix(lon, lat, altitude), () => this.getCamera());
|
|
882
|
+
return this.place(custom, options.before);
|
|
829
883
|
}
|
|
830
884
|
// ── Frames ──
|
|
831
885
|
/** Asks for a frame; several calls before the next frame draw it once */
|
|
@@ -899,7 +953,15 @@ export class GeoMap {
|
|
|
899
953
|
const t0 = performance.now();
|
|
900
954
|
// The engine asks for the next frame while it draws (uploads past the frame budget, fades): not ignored
|
|
901
955
|
this.inFrame = false;
|
|
902
|
-
|
|
956
|
+
// As the engine has it now (a listener may have moved it), for the custom layers drawn in the frame
|
|
957
|
+
this.frameCamera = this.layers.some((layer) => layer instanceof CustomLayer) ? this.engine.camera() : undefined;
|
|
958
|
+
let loading;
|
|
959
|
+
try {
|
|
960
|
+
loading = this.engine.render();
|
|
961
|
+
}
|
|
962
|
+
finally {
|
|
963
|
+
this.frameCamera = undefined;
|
|
964
|
+
}
|
|
903
965
|
this.inFrame = true;
|
|
904
966
|
// The picking pass sees the frame just drawn; its answer comes on a later frame
|
|
905
967
|
if (hovered && this.listeners.hoverfeature.size > 0)
|
|
@@ -970,12 +1032,16 @@ export class GeoMap {
|
|
|
970
1032
|
this.resizeObserver.disconnect();
|
|
971
1033
|
this.interaction?.destroy();
|
|
972
1034
|
this.loader?.destroy();
|
|
1035
|
+
// Custom layers free their WebGL objects, models their data, while the context is there
|
|
1036
|
+
for (const layer of this.layers)
|
|
1037
|
+
layer.dispose();
|
|
973
1038
|
this.engine.free();
|
|
974
1039
|
// Work still under way (labels being shaped, tiles arriving, timers) may call the engine after this: it finds one
|
|
975
1040
|
// that does nothing, and nothing is drawn again
|
|
976
1041
|
this.#engine = destroyedEngine(camera);
|
|
977
1042
|
// Glyph ranges still arriving upload to it, not to the freed engine
|
|
978
1043
|
this.#glyphs?.attach(this.#engine);
|
|
1044
|
+
this.#icons?.attach(this.#engine);
|
|
979
1045
|
this.lost = true;
|
|
980
1046
|
for (const control of [...this.controls.keys()])
|
|
981
1047
|
this.removeControl(control);
|