isard 1.2.0 → 1.3.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.
Files changed (94) hide show
  1. package/CHANGELOG.md +88 -0
  2. package/README.md +44 -39
  3. package/dist/basemap/pmtileslayer.d.ts +33 -0
  4. package/dist/basemap/pmtileslayer.js +97 -0
  5. package/dist/basemap/pmtileslayer.js.map +1 -0
  6. package/dist/basemap/trees.d.ts +26 -0
  7. package/dist/basemap/trees.js +141 -0
  8. package/dist/basemap/trees.js.map +1 -0
  9. package/dist/basemap/vectorstyle.d.ts +10 -0
  10. package/dist/basemap/vectorstyle.js +35 -0
  11. package/dist/basemap/vectorstyle.js.map +1 -1
  12. package/dist/basemap/vectortiles.d.ts +67 -44
  13. package/dist/basemap/vectortiles.js +386 -302
  14. package/dist/basemap/vectortiles.js.map +1 -1
  15. package/dist/basemap/workerpool.d.ts +17 -0
  16. package/dist/basemap/workerpool.js +194 -0
  17. package/dist/basemap/workerpool.js.map +1 -0
  18. package/dist/basemap.worker.js +2 -2
  19. package/dist/basemap.worker.js.map +15 -8
  20. package/dist/decoder.worker.js +4 -4
  21. package/dist/decoder.worker.js.map +3 -3
  22. package/dist/engine-loader.d.ts +5 -1
  23. package/dist/engine-loader.js +11 -1
  24. package/dist/engine-loader.js.map +1 -1
  25. package/dist/geoplateforme.d.ts +16 -0
  26. package/dist/geoplateforme.js +23 -0
  27. package/dist/geoplateforme.js.map +1 -1
  28. package/dist/index.d.ts +11 -4
  29. package/dist/index.js +9 -2
  30. package/dist/index.js.map +1 -1
  31. package/dist/isard_bg.wasm +0 -0
  32. package/dist/isard_core_bg.wasm +0 -0
  33. package/dist/isard_tess_bg.wasm +0 -0
  34. package/dist/layers/layers.js +9 -0
  35. package/dist/layers/layers.js.map +1 -1
  36. package/dist/layers/vectors.d.ts +60 -0
  37. package/dist/layers/vectors.js +130 -0
  38. package/dist/layers/vectors.js.map +1 -0
  39. package/dist/map/frame-loop.d.ts +3 -0
  40. package/dist/map/frame-loop.js +6 -0
  41. package/dist/map/frame-loop.js.map +1 -1
  42. package/dist/map/raster-source.js +1 -1
  43. package/dist/map/raster-source.js.map +1 -1
  44. package/dist/map/workers.d.ts +1 -1
  45. package/dist/map/workers.js +1 -1
  46. package/dist/map/workers.js.map +1 -1
  47. package/dist/map.d.ts +21 -6
  48. package/dist/map.js +65 -11
  49. package/dist/map.js.map +1 -1
  50. package/dist/react/IsardMap.js +1 -0
  51. package/dist/react/IsardMap.js.map +1 -1
  52. package/dist/react/Swipe.d.ts +11 -4
  53. package/dist/react/Swipe.js +26 -15
  54. package/dist/react/Swipe.js.map +1 -1
  55. package/dist/react/VectorGeometry.d.ts +35 -0
  56. package/dist/react/VectorGeometry.js +82 -0
  57. package/dist/react/VectorGeometry.js.map +1 -0
  58. package/dist/react/context.d.ts +2 -1
  59. package/dist/react/context.js.map +1 -1
  60. package/dist/react/index.d.ts +2 -1
  61. package/dist/react/index.js +2 -1
  62. package/dist/react/index.js.map +1 -1
  63. package/dist/types.d.ts +24 -1
  64. package/dist/types.js.map +1 -1
  65. package/dist/ui/minimap.d.ts +25 -0
  66. package/dist/ui/minimap.js +90 -0
  67. package/dist/ui/minimap.js.map +1 -0
  68. package/dist/ui/scale.d.ts +19 -0
  69. package/dist/ui/scale.js +44 -0
  70. package/dist/ui/scale.js.map +1 -0
  71. package/dist/ui/search.d.ts +25 -0
  72. package/dist/ui/search.js +119 -0
  73. package/dist/ui/search.js.map +1 -0
  74. package/dist/ui/style.js +17 -0
  75. package/dist/ui/style.js.map +1 -1
  76. package/dist/util/sun.d.ts +11 -0
  77. package/dist/util/sun.js +26 -0
  78. package/dist/util/sun.js.map +1 -0
  79. package/dist/wasm/isard.d.ts +82 -7
  80. package/dist/wasm/isard.js +229 -8
  81. package/dist/wasm/isard_core.d.ts +82 -7
  82. package/dist/wasm/isard_core.js +229 -8
  83. package/dist/wasm/isard_tess.d.ts +109 -0
  84. package/dist/wasm/isard_tess.js +398 -0
  85. package/dist/workers/basemap/geometry.d.ts +72 -0
  86. package/dist/workers/basemap/labels.d.ts +8 -0
  87. package/dist/workers/basemap/raster.d.ts +10 -0
  88. package/dist/workers/basemap/tiles.d.ts +65 -0
  89. package/dist/workers/basemap/trees.d.ts +19 -0
  90. package/dist/workers/basemap.worker.d.ts +126 -22
  91. package/dist/workers/basemap.worker.js +72 -551
  92. package/dist/workers/basemap.worker.js.map +1 -1
  93. package/package.json +5 -4
  94. package/vite.js +10 -2
package/dist/map.d.ts CHANGED
@@ -5,7 +5,8 @@
5
5
  * the camera animations in animation.ts; the parts of the map with a state of their own (the drawing order of the
6
6
  * layers, the overlays and controls, the frame loop, the hover picking, the workers…) in map/.
7
7
  */
8
- import { type PmtilesOptions, VectorTiles, type VectorTilesOptions } from './basemap/vectortiles.ts';
8
+ import { type PmtilesOptions } from './basemap/pmtileslayer.ts';
9
+ import { VectorTiles, type VectorTilesOptions } from './basemap/vectortiles.ts';
9
10
  import { ExtrusionLayer, type ExtrusionOptions } from './layers/extrusions.ts';
10
11
  import { CircleLayer, type CircleOptions, FillLayer, type FillOptions, LineLayer, type LineOptions } from './layers/features.ts';
11
12
  import type { ImageOptions, Pixels } from './layers/icons.ts';
@@ -15,7 +16,7 @@ import { PointCloudLayer, type PointCloudOptions } from './layers/pointclouds.ts
15
16
  import { SymbolLayer, type SymbolOptions } from './layers/symbols.ts';
16
17
  import { type HoverPicking } from './map/hover-pick.ts';
17
18
  import { type LayerSpec } from './map/layer-spec.ts';
18
- import type { AnimationOptions, AtmosphereOptions, Basemap, FeatureHit, FirstPersonView, FlyToOptions, GeoMapOptions, LoadingMode, LonLat, MapEvents, NetworkOptions, Point, Projection, RasterOptions, SwipeOptions, TerrainModel, TerrainOptions, Tiles3dOptions, ViewshedOptions } from './types.ts';
19
+ import type { AnimationOptions, AtmosphereOptions, Basemap, FeatureHit, FirstPersonView, FlyToOptions, GeoMapOptions, LoadingMode, LonLat, MapEvents, NetworkOptions, Point, Projection, RasterOptions, SunOptions, SwipeOptions, TerrainModel, TerrainOptions, Tiles3dOptions, ViewshedOptions } from './types.ts';
19
20
  import { type Control, type ControlPosition } from './ui/controls.ts';
20
21
  import type { Camera, PickHit, RasterLayerStats } from './wasm/isard.js';
21
22
  export type { LayerSpec } from './map/layer-spec.ts';
@@ -95,7 +96,8 @@ export declare class GeoMap {
95
96
  /**
96
97
  * Compares two states of a place: `layers` shown on one side of a vertical line only, at `position` CSS pixels
97
98
  * from the left of the map (left of it by default, `side: 'right'` for the other), the layers beneath them on the
98
- * other side. Set again as the line moves (a slider, a drag); undefined stops
99
+ * other side; `other`: layers shown on the other side only (two meshes of a place, each on its side). Set again as
100
+ * the line moves (a slider, a drag); undefined stops
99
101
  */
100
102
  setSwipe(options: SwipeOptions | undefined): void;
101
103
  private applySwipe;
@@ -134,9 +136,10 @@ export declare class GeoMap {
134
136
  readonly elevationAt: (lonLat: LonLat) => number | undefined;
135
137
  readonly metersPerPixel: (point?: Point) => number | undefined;
136
138
  };
137
- /** What is drawn over the scene, together: `viewshed` (`setViewshed`), `swipe` (`setSwipe`) */
139
+ /** What is drawn over the scene, together: `viewshed` (`setViewshed`), `sun` (`setSun`), `swipe` (`setSwipe`) */
138
140
  readonly effects: {
139
141
  readonly viewshed: (options: ViewshedOptions | readonly ViewshedOptions[] | undefined) => void;
142
+ readonly sun: (options: SunOptions | undefined) => void;
140
143
  readonly swipe: (options: SwipeOptions | undefined) => void;
141
144
  };
142
145
  getCamera(): Camera;
@@ -164,6 +167,18 @@ export declare class GeoMap {
164
167
  setSky(enabled: boolean): void;
165
168
  /** The viewshed set, set again in a new engine */
166
169
  private viewshed;
170
+ /** The sun set, set again in a new engine */
171
+ private sun;
172
+ /**
173
+ * The sun casting shadows: the buildings, trees, models, 3D Tiles and the relief shade the ground and one another,
174
+ * the walls turned away from it are in their own shade; the labels stay over them. The sun stands where it is at
175
+ * `date` over the map's center (now by default), or at `azimuth` and `altitude`. As it sets the night falls (`night`
176
+ * to set it by hand): the scene tinted in its blue, the windows of the buildings and the streets of `vectors()` lit,
177
+ * the labels light on dark.
178
+ * The shadows cover the ground around the view's center, fading out away from it, and cost two more depth passes
179
+ * of the solid scene each frame. Undefined removes them
180
+ */
181
+ setSun(options: SunOptions | undefined): void;
167
182
  /** Tints what can be seen from a point and what is hidden from it, within a range, all around or within a cone
168
183
  * (`direction`): the relief, extrusions, 3D Tiles and models hide what lies behind them (only what the map has
169
184
  * loaded for its view). Several observers (16 at most): what any of them sees is seen, what is hidden from all those
@@ -279,8 +294,8 @@ export declare class GeoMap {
279
294
  removeImage(name: string): void;
280
295
  /**
281
296
  * Vector tiles with a MapLibre style (OpenFreeMap's Positron by default): `tiles.raster(…)` draws its fills and lines
282
- * (or a subset) as a raster layer, `tiles.labels(…)` its labels. `setBasemap('osm-positron')` does both for the
283
- * basemap.
297
+ * (or a subset) as a raster layer, `tiles.vectors(…)` as geometry, `tiles.labels(…)` its labels.
298
+ * `setBasemap('osm-positron')` draws the basemap with a raster layer and the labels.
284
299
  */
285
300
  vectorTiles(options?: VectorTilesOptions): VectorTiles;
286
301
  /** Adds a layer, under `before` if given */
package/dist/map.js CHANGED
@@ -6,9 +6,11 @@
6
6
  * layers, the overlays and controls, the frame loop, the hover picking, the workers…) in map/.
7
7
  */
8
8
  import { SEA } from "./basemap/basemaps.js";
9
- import { defaultWorkerUrl, pmtilesLayer, VectorTiles, } from "./basemap/vectortiles.js";
9
+ import { pmtilesLayer } from "./basemap/pmtileslayer.js";
10
+ import { VectorTiles } from "./basemap/vectortiles.js";
11
+ import { defaultWorkerUrl } from "./basemap/workerpool.js";
10
12
  import { onHeaderRules } from "./engine/requests.js";
11
- import { destroyedEngine, engineUrl, loadEngine } from "./engine-loader.js";
13
+ import { destroyedEngine, engineUrl, loadEngine, tessUrl } from "./engine-loader.js";
12
14
  import { IGN_PRESETS } from "./geoplateforme.js";
13
15
  import { ExtrusionLayer, extrusionStyle } from "./layers/extrusions.js";
14
16
  import { CircleLayer, circleStyle, FillLayer, fillStyle, LineLayer, lineStyle, } from "./layers/features.js";
@@ -16,6 +18,7 @@ import { CustomLayer, GroundLayer, ModelLayer, NetworkLayer, RasterLayer, Tiles3
16
18
  import { loadPanoramas } from "./layers/panoramas.js";
17
19
  import { PointCloudLayer } from "./layers/pointclouds.js";
18
20
  import { SymbolLayer, symbolStyle } from "./layers/symbols.js";
21
+ import { VectorLayer } from "./layers/vectors.js";
19
22
  import { BasemapLayers } from "./map/basemap-layers.js";
20
23
  import { createCanvas, labelCanvas, watchContext, watchPixelRatio } from "./map/canvas.js";
21
24
  import { checkBasemap, report, validateNetwork } from "./map/checks.js";
@@ -37,6 +40,7 @@ import { atmosphereSettings, rgb, terrainSettings } from "./settings.js";
37
40
  import { AttributionControl } from "./ui/controls.js";
38
41
  import { Interaction } from "./ui/interaction.js";
39
42
  import { easeTo, flyTo } from "./util/animation.js";
43
+ import { sunPosition } from "./util/sun.js";
40
44
  /** A layer whose picked features come back with their properties (lines, circles, fills, extrusions, 3D Tiles…) */
41
45
  const hasFeatures = (layer) => 'featureAt' in layer && typeof layer.featureAt === 'function';
42
46
  /** A map (see `GeoMap.create`); layers take it as their host */
@@ -57,6 +61,8 @@ export class GeoMap {
57
61
  /** The canvas in the container, the markers and popups over it, the controls in its corners */
58
62
  overlays;
59
63
  settings;
64
+ /** @internal Where the basemap workers load the tessellation module from (`isard_tess_bg.wasm`) */
65
+ tessUrl;
60
66
  /** The WebGL context is lost: nothing is drawn until it is restored */
61
67
  lost = false;
62
68
  gone = false;
@@ -106,6 +112,7 @@ export class GeoMap {
106
112
  constructor(container, options, engineClass, tiles3dModule) {
107
113
  this.engines = new MapEngines(engineClass, tiles3dModule, options, () => this.gone);
108
114
  const workerUrl = options.basemapWorkerUrl ?? defaultWorkerUrl(options.assetsUrl);
115
+ this.tessUrl = tessUrl(options);
109
116
  this.workers = new MapWorkers(workerUrl, options.workers, () => this.gone, this);
110
117
  this.basemaps = new BasemapLayers(this, this.stack, workerUrl, options.basemapTileSize);
111
118
  this.container = container;
@@ -143,6 +150,8 @@ export class GeoMap {
143
150
  : { center: [0, 0], zoom: 2, pitch: 0, bearing: 0 };
144
151
  this.setCamera({ ...start, ...options });
145
152
  this.setBasemap(options.basemap ?? (this.earth ? 'osm-positron' : 'none'), options.hillshade ?? 0);
153
+ if (options.sun)
154
+ this.setSun(options.sun);
146
155
  this.resizeObserver = new ResizeObserver(() => this.resize());
147
156
  this.resizeObserver.observe(container);
148
157
  this.unwatchRatio = watchPixelRatio(() => this.resize());
@@ -220,9 +229,11 @@ export class GeoMap {
220
229
  // A street-level eye stays one in the new engine
221
230
  if (this.#firstPerson)
222
231
  this.setFirstPerson(this.#firstPerson);
223
- // What the old engine drew over the scene: the viewshed, the panoramas shown
232
+ // What the old engine drew over the scene: the viewshed, the sun's shadows, the panoramas shown
224
233
  if (this.viewshed)
225
234
  this.setViewshed(this.viewshed);
235
+ if (this.sun)
236
+ this.setSun(this.sun);
226
237
  this.panoramaSets.forEach((set) => {
227
238
  if (set.current)
228
239
  void set.show(set.current.index).catch(report);
@@ -262,17 +273,22 @@ export class GeoMap {
262
273
  /**
263
274
  * Compares two states of a place: `layers` shown on one side of a vertical line only, at `position` CSS pixels
264
275
  * from the left of the map (left of it by default, `side: 'right'` for the other), the layers beneath them on the
265
- * other side. Set again as the line moves (a slider, a drag); undefined stops
276
+ * other side; `other`: layers shown on the other side only (two meshes of a place, each on its side). Set again as
277
+ * the line moves (a slider, a drag); undefined stops
266
278
  */
267
279
  setSwipe(options) {
268
- this.swipe = options && options.layers.length > 0 ? { ...options, layers: [...options.layers] } : undefined;
280
+ const used = options && (options.layers.length > 0 || (options.other?.length ?? 0) > 0);
281
+ this.swipe = used ? { ...options, layers: [...options.layers], other: [...(options.other ?? [])] } : undefined;
269
282
  this.applySwipe();
270
283
  this.requestRender();
271
284
  }
272
285
  applySwipe() {
273
286
  const s = this.swipe;
274
- const ids = Uint32Array.from((s?.layers ?? []).filter((l) => l.id >= 0), (l) => l.id);
275
- this.engine.setSwipe(s && ids.length > 0 ? s.position : Number.NaN, s?.side === 'right', ids);
287
+ const idsOf = (layers) => Uint32Array.from((layers ?? []).filter((l) => l.id >= 0), (l) => l.id);
288
+ const ids = idsOf(s?.layers);
289
+ const others = idsOf(s?.other);
290
+ const shown = ids.length > 0 || others.length > 0;
291
+ this.engine.setSwipe(s && shown ? s.position : Number.NaN, s?.side === 'right', ids, others);
276
292
  }
277
293
  /** @internal Forgets a removed layer */
278
294
  detach(layer) {
@@ -344,9 +360,10 @@ export class GeoMap {
344
360
  elevationAt: (lonLat) => this.elevationAt(lonLat),
345
361
  metersPerPixel: (point) => this.metersPerPixel(point),
346
362
  };
347
- /** What is drawn over the scene, together: `viewshed` (`setViewshed`), `swipe` (`setSwipe`) */
363
+ /** What is drawn over the scene, together: `viewshed` (`setViewshed`), `sun` (`setSun`), `swipe` (`setSwipe`) */
348
364
  effects = {
349
365
  viewshed: (options) => this.setViewshed(options),
366
+ sun: (options) => this.setSun(options),
350
367
  swipe: (options) => this.setSwipe(options),
351
368
  };
352
369
  getCamera() {
@@ -423,6 +440,35 @@ export class GeoMap {
423
440
  }
424
441
  /** The viewshed set, set again in a new engine */
425
442
  viewshed;
443
+ /** The sun set, set again in a new engine */
444
+ sun;
445
+ /**
446
+ * The sun casting shadows: the buildings, trees, models, 3D Tiles and the relief shade the ground and one another,
447
+ * the walls turned away from it are in their own shade; the labels stay over them. The sun stands where it is at
448
+ * `date` over the map's center (now by default), or at `azimuth` and `altitude`. As it sets the night falls (`night`
449
+ * to set it by hand): the scene tinted in its blue, the windows of the buildings and the streets of `vectors()` lit,
450
+ * the labels light on dark.
451
+ * The shadows cover the ground around the view's center, fading out away from it, and cost two more depth passes
452
+ * of the solid scene each frame. Undefined removes them
453
+ */
454
+ setSun(options) {
455
+ this.sun = options;
456
+ if (!options) {
457
+ this.engine.setSun(Number.NaN, Number.NaN, 0, 0);
458
+ this.requestRender();
459
+ return;
460
+ }
461
+ const { azimuth, altitude } = options.azimuth !== undefined && options.altitude !== undefined
462
+ ? { azimuth: options.azimuth, altitude: options.altitude }
463
+ : sunPosition(options.date ?? new Date(), this.getCamera().center);
464
+ // The twilight: from 6° above the horizon to 6° under it, smoothly
465
+ const dusk = Math.min(1, Math.max(0, (6 - altitude) / 12));
466
+ const night = Math.min(1, Math.max(0, options.night ?? dusk * dusk * (3 - 2 * dusk)));
467
+ // The shadows fade with the sun's light
468
+ const opacity = Math.min(1, Math.max(0, options.opacity ?? 0.35)) * (1 - night);
469
+ this.engine.setSun(azimuth, altitude, opacity, night);
470
+ this.requestRender();
471
+ }
426
472
  /** Tints what can be seen from a point and what is hidden from it, within a range, all around or within a cone
427
473
  * (`direction`): the relief, extrusions, 3D Tiles and models hide what lies behind them (only what the map has
428
474
  * loaded for its view). Several observers (16 at most): what any of them sees is seen, what is hidden from all those
@@ -442,6 +488,10 @@ export class GeoMap {
442
488
  this.credits.changed();
443
489
  this.requestRender();
444
490
  }
491
+ /** @internal Whether a relief is under the basemap: the fills of vector tiles drawn as geometry need their prisms */
492
+ get hasRelief() {
493
+ return this.settings.terrain !== undefined;
494
+ }
445
495
  /** @internal The credits of the raster layers (the basemap first) and of the relief in use, each once */
446
496
  attributions() {
447
497
  return this.credits.of(this.layers, this.settings.terrain?.attribution);
@@ -641,7 +691,7 @@ export class GeoMap {
641
691
  off();
642
692
  resolve();
643
693
  });
644
- this.requestRender();
694
+ this.frames.requestIdle();
645
695
  });
646
696
  }
647
697
  /** Lines from GeoJSON (line strings, and polygon outlines), styled per feature */
@@ -693,8 +743,8 @@ export class GeoMap {
693
743
  }
694
744
  /**
695
745
  * Vector tiles with a MapLibre style (OpenFreeMap's Positron by default): `tiles.raster(…)` draws its fills and lines
696
- * (or a subset) as a raster layer, `tiles.labels(…)` its labels. `setBasemap('osm-positron')` does both for the
697
- * basemap.
746
+ * (or a subset) as a raster layer, `tiles.vectors(…)` as geometry, `tiles.labels(…)` its labels.
747
+ * `setBasemap('osm-positron')` draws the basemap with a raster layer and the labels.
698
748
  */
699
749
  vectorTiles(options = {}) {
700
750
  const tiles = new VectorTiles(this, {
@@ -705,6 +755,10 @@ export class GeoMap {
705
755
  this.vectorSets.add(tiles);
706
756
  return tiles;
707
757
  }
758
+ /** @internal The geometry of a `VectorTiles` (`vectors`), under `before` if given */
759
+ addVectorLayer(before) {
760
+ return this.place(new VectorLayer(this), before);
761
+ }
708
762
  /** @internal Forgets a destroyed `VectorTiles` */
709
763
  dropVectorTiles(tiles) {
710
764
  this.vectorSets.delete(tiles);