isard 1.1.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 (254) hide show
  1. package/CHANGELOG.md +121 -0
  2. package/README.md +44 -39
  3. package/dist/basemap/basemaps.d.ts +1 -1
  4. package/dist/basemap/basemaps.js +2 -2
  5. package/dist/basemap/basemaps.js.map +1 -1
  6. package/dist/basemap/grid.d.ts +5 -5
  7. package/dist/basemap/grid.js +59 -65
  8. package/dist/basemap/grid.js.map +1 -1
  9. package/dist/basemap/mvt.d.ts +1 -1
  10. package/dist/basemap/mvt.js +6 -6
  11. package/dist/basemap/mvt.js.map +1 -1
  12. package/dist/basemap/pmtiles.d.ts +10 -10
  13. package/dist/basemap/pmtiles.js +39 -31
  14. package/dist/basemap/pmtiles.js.map +1 -1
  15. package/dist/basemap/pmtileslayer.d.ts +33 -0
  16. package/dist/basemap/pmtileslayer.js +97 -0
  17. package/dist/basemap/pmtileslayer.js.map +1 -0
  18. package/dist/basemap/resample.d.ts +2 -2
  19. package/dist/basemap/resample.js +16 -14
  20. package/dist/basemap/resample.js.map +1 -1
  21. package/dist/basemap/terrain.d.ts +3 -3
  22. package/dist/basemap/terrain.js +6 -6
  23. package/dist/basemap/terrain.js.map +1 -1
  24. package/dist/basemap/trees.d.ts +26 -0
  25. package/dist/basemap/trees.js +141 -0
  26. package/dist/basemap/trees.js.map +1 -0
  27. package/dist/basemap/vectorstyle.d.ts +22 -10
  28. package/dist/basemap/vectorstyle.js +163 -110
  29. package/dist/basemap/vectorstyle.js.map +1 -1
  30. package/dist/basemap/vectortiles.d.ts +70 -47
  31. package/dist/basemap/vectortiles.js +480 -358
  32. package/dist/basemap/vectortiles.js.map +1 -1
  33. package/dist/basemap/wmts.d.ts +3 -3
  34. package/dist/basemap/wmts.js +16 -11
  35. package/dist/basemap/wmts.js.map +1 -1
  36. package/dist/basemap/workerpool.d.ts +17 -0
  37. package/dist/basemap/workerpool.js +194 -0
  38. package/dist/basemap/workerpool.js.map +1 -0
  39. package/dist/basemap.worker.js +2 -2
  40. package/dist/basemap.worker.js.map +21 -13
  41. package/dist/bind/layers.d.ts +13 -4
  42. package/dist/bind/layers.js +64 -40
  43. package/dist/bind/layers.js.map +1 -1
  44. package/dist/data/crs.d.ts +10 -10
  45. package/dist/data/crs.js +38 -34
  46. package/dist/data/crs.js.map +1 -1
  47. package/dist/data/gpx.d.ts +1 -1
  48. package/dist/data/gpx.js +20 -20
  49. package/dist/data/gpx.js.map +1 -1
  50. package/dist/data/kml.d.ts +1 -1
  51. package/dist/data/kml.js +42 -39
  52. package/dist/data/kml.js.map +1 -1
  53. package/dist/data/topojson.d.ts +1 -1
  54. package/dist/data/topojson.js +15 -10
  55. package/dist/data/topojson.js.map +1 -1
  56. package/dist/data/xml.d.ts +5 -5
  57. package/dist/data/xml.js +19 -18
  58. package/dist/data/xml.js.map +1 -1
  59. package/dist/decoder.worker.js +4 -4
  60. package/dist/decoder.worker.js.map +6 -6
  61. package/dist/engine/decoders.d.ts +2 -2
  62. package/dist/engine/decoders.js +28 -25
  63. package/dist/engine/decoders.js.map +1 -1
  64. package/dist/engine/loader.js +13 -14
  65. package/dist/engine/loader.js.map +1 -1
  66. package/dist/engine/requests.d.ts +1 -1
  67. package/dist/engine/requests.js +19 -16
  68. package/dist/engine/requests.js.map +1 -1
  69. package/dist/engine-loader.d.ts +13 -9
  70. package/dist/engine-loader.js +38 -28
  71. package/dist/engine-loader.js.map +1 -1
  72. package/dist/geoplateforme.d.ts +26 -10
  73. package/dist/geoplateforme.js +45 -20
  74. package/dist/geoplateforme.js.map +1 -1
  75. package/dist/index.d.ts +12 -4
  76. package/dist/index.js +9 -2
  77. package/dist/index.js.map +1 -1
  78. package/dist/isard_bg.wasm +0 -0
  79. package/dist/isard_core_bg.wasm +0 -0
  80. package/dist/isard_points_bg.wasm +0 -0
  81. package/dist/isard_tess_bg.wasm +0 -0
  82. package/dist/layers/extrusions.d.ts +1 -1
  83. package/dist/layers/extrusions.js +10 -5
  84. package/dist/layers/extrusions.js.map +1 -1
  85. package/dist/layers/features.d.ts +10 -10
  86. package/dist/layers/features.js +41 -42
  87. package/dist/layers/features.js.map +1 -1
  88. package/dist/layers/glyphs.d.ts +3 -3
  89. package/dist/layers/glyphs.js +34 -40
  90. package/dist/layers/glyphs.js.map +1 -1
  91. package/dist/layers/icons.d.ts +8 -8
  92. package/dist/layers/icons.js +76 -68
  93. package/dist/layers/icons.js.map +1 -1
  94. package/dist/layers/layers.d.ts +1 -1
  95. package/dist/layers/layers.js +42 -29
  96. package/dist/layers/layers.js.map +1 -1
  97. package/dist/layers/panoramas.d.ts +2 -2
  98. package/dist/layers/panoramas.js +52 -41
  99. package/dist/layers/panoramas.js.map +1 -1
  100. package/dist/layers/pointclouds.d.ts +3 -3
  101. package/dist/layers/pointclouds.js +25 -33
  102. package/dist/layers/pointclouds.js.map +1 -1
  103. package/dist/layers/symbols.d.ts +1 -1
  104. package/dist/layers/symbols.js +68 -71
  105. package/dist/layers/symbols.js.map +1 -1
  106. package/dist/layers/vectors.d.ts +60 -0
  107. package/dist/layers/vectors.js +130 -0
  108. package/dist/layers/vectors.js.map +1 -0
  109. package/dist/map/basemap-layers.d.ts +26 -0
  110. package/dist/map/basemap-layers.js +61 -0
  111. package/dist/map/basemap-layers.js.map +1 -0
  112. package/dist/map/canvas.d.ts +17 -0
  113. package/dist/map/canvas.js +56 -0
  114. package/dist/map/canvas.js.map +1 -0
  115. package/dist/map/checks.d.ts +11 -0
  116. package/dist/map/checks.js +39 -0
  117. package/dist/map/checks.js.map +1 -0
  118. package/dist/map/credits.d.ts +17 -0
  119. package/dist/map/credits.js +34 -0
  120. package/dist/map/credits.js.map +1 -0
  121. package/dist/map/engine-settings.d.ts +15 -0
  122. package/dist/map/engine-settings.js +45 -0
  123. package/dist/map/engine-settings.js.map +1 -0
  124. package/dist/map/engines.d.ts +41 -0
  125. package/dist/map/engines.js +77 -0
  126. package/dist/map/engines.js.map +1 -0
  127. package/dist/map/events.d.ts +14 -0
  128. package/dist/map/events.js +46 -0
  129. package/dist/map/events.js.map +1 -0
  130. package/dist/map/frame-loop.d.ts +64 -0
  131. package/dist/map/frame-loop.js +145 -0
  132. package/dist/map/frame-loop.js.map +1 -0
  133. package/dist/map/hover-pick.d.ts +30 -0
  134. package/dist/map/hover-pick.js +56 -0
  135. package/dist/map/hover-pick.js.map +1 -0
  136. package/dist/map/layer-spec.d.ts +42 -0
  137. package/dist/map/layer-spec.js +34 -0
  138. package/dist/map/layer-spec.js.map +1 -0
  139. package/dist/map/layer-stack.d.ts +36 -0
  140. package/dist/map/layer-stack.js +101 -0
  141. package/dist/map/layer-stack.js.map +1 -0
  142. package/dist/map/overlay-host.d.ts +36 -0
  143. package/dist/map/overlay-host.js +101 -0
  144. package/dist/map/overlay-host.js.map +1 -0
  145. package/dist/map/panorama-host.d.ts +5 -0
  146. package/dist/map/panorama-host.js +32 -0
  147. package/dist/map/panorama-host.js.map +1 -0
  148. package/dist/map/raster-source.d.ts +11 -0
  149. package/dist/map/raster-source.js +26 -0
  150. package/dist/map/raster-source.js.map +1 -0
  151. package/dist/map/symbol-atlases.d.ts +26 -0
  152. package/dist/map/symbol-atlases.js +59 -0
  153. package/dist/map/symbol-atlases.js.map +1 -0
  154. package/dist/map/viewshed.d.ts +5 -0
  155. package/dist/map/viewshed.js +28 -0
  156. package/dist/map/viewshed.js.map +1 -0
  157. package/dist/map/workers.d.ts +46 -0
  158. package/dist/map/workers.js +73 -0
  159. package/dist/map/workers.js.map +1 -0
  160. package/dist/map.d.ts +54 -126
  161. package/dist/map.js +227 -698
  162. package/dist/map.js.map +1 -1
  163. package/dist/react/Control.d.ts +11 -0
  164. package/dist/react/Control.js +18 -0
  165. package/dist/react/Control.js.map +1 -0
  166. package/dist/react/CustomLayer.d.ts +11 -0
  167. package/dist/react/CustomLayer.js +30 -0
  168. package/dist/react/CustomLayer.js.map +1 -0
  169. package/dist/react/IsardMap.d.ts +43 -0
  170. package/dist/react/IsardMap.js +147 -0
  171. package/dist/react/IsardMap.js.map +1 -0
  172. package/dist/react/Layer.d.ts +42 -0
  173. package/dist/react/Layer.js +74 -0
  174. package/dist/react/Layer.js.map +1 -0
  175. package/dist/react/Marker.d.ts +24 -0
  176. package/dist/react/Marker.js +53 -0
  177. package/dist/react/Marker.js.map +1 -0
  178. package/dist/react/Panel.d.ts +11 -0
  179. package/dist/react/Panel.js +37 -0
  180. package/dist/react/Panel.js.map +1 -0
  181. package/dist/react/Popup.d.ts +18 -0
  182. package/dist/react/Popup.js +60 -0
  183. package/dist/react/Popup.js.map +1 -0
  184. package/dist/react/Swipe.d.ts +16 -0
  185. package/dist/react/Swipe.js +52 -0
  186. package/dist/react/Swipe.js.map +1 -0
  187. package/dist/react/VectorGeometry.d.ts +35 -0
  188. package/dist/react/VectorGeometry.js +82 -0
  189. package/dist/react/VectorGeometry.js.map +1 -0
  190. package/dist/react/Viewshed.d.ts +5 -0
  191. package/dist/react/Viewshed.js +28 -0
  192. package/dist/react/Viewshed.js.map +1 -0
  193. package/dist/react/context.d.ts +33 -0
  194. package/dist/react/context.js +20 -0
  195. package/dist/react/context.js.map +1 -0
  196. package/dist/react/index.d.ts +16 -108
  197. package/dist/react/index.js +11 -397
  198. package/dist/react/index.js.map +1 -1
  199. package/dist/settings.d.ts +5 -9
  200. package/dist/settings.js +17 -15
  201. package/dist/settings.js.map +1 -1
  202. package/dist/types.d.ts +27 -4
  203. package/dist/types.js.map +1 -1
  204. package/dist/ui/controls.js +6 -4
  205. package/dist/ui/controls.js.map +1 -1
  206. package/dist/ui/interaction.d.ts +2 -2
  207. package/dist/ui/interaction.js +8 -7
  208. package/dist/ui/interaction.js.map +1 -1
  209. package/dist/ui/minimap.d.ts +25 -0
  210. package/dist/ui/minimap.js +90 -0
  211. package/dist/ui/minimap.js.map +1 -0
  212. package/dist/ui/overlay.js +18 -20
  213. package/dist/ui/overlay.js.map +1 -1
  214. package/dist/ui/scale.d.ts +19 -0
  215. package/dist/ui/scale.js +44 -0
  216. package/dist/ui/scale.js.map +1 -0
  217. package/dist/ui/search.d.ts +25 -0
  218. package/dist/ui/search.js +119 -0
  219. package/dist/ui/search.js.map +1 -0
  220. package/dist/ui/style.d.ts +1 -1
  221. package/dist/ui/style.js +19 -2
  222. package/dist/ui/style.js.map +1 -1
  223. package/dist/util/animation.d.ts +3 -3
  224. package/dist/util/animation.js +6 -6
  225. package/dist/util/animation.js.map +1 -1
  226. package/dist/util/color.d.ts +1 -1
  227. package/dist/util/color.js +14 -16
  228. package/dist/util/color.js.map +1 -1
  229. package/dist/util/geo.d.ts +6 -6
  230. package/dist/util/geo.js +12 -12
  231. package/dist/util/geo.js.map +1 -1
  232. package/dist/util/guards.d.ts +7 -0
  233. package/dist/util/guards.js +8 -0
  234. package/dist/util/guards.js.map +1 -0
  235. package/dist/util/lru.js.map +1 -1
  236. package/dist/util/sun.d.ts +11 -0
  237. package/dist/util/sun.js +26 -0
  238. package/dist/util/sun.js.map +1 -0
  239. package/dist/wasm/isard.d.ts +250 -7
  240. package/dist/wasm/isard.js +375 -8
  241. package/dist/wasm/isard_core.d.ts +226 -7
  242. package/dist/wasm/isard_core.js +351 -8
  243. package/dist/wasm/isard_tess.d.ts +109 -0
  244. package/dist/wasm/isard_tess.js +398 -0
  245. package/dist/workers/basemap/geometry.d.ts +72 -0
  246. package/dist/workers/basemap/labels.d.ts +8 -0
  247. package/dist/workers/basemap/raster.d.ts +10 -0
  248. package/dist/workers/basemap/tiles.d.ts +65 -0
  249. package/dist/workers/basemap/trees.d.ts +19 -0
  250. package/dist/workers/basemap.worker.d.ts +126 -22
  251. package/dist/workers/basemap.worker.js +76 -544
  252. package/dist/workers/basemap.worker.js.map +1 -1
  253. package/package.json +5 -4
  254. package/vite.js +10 -2
@@ -0,0 +1,130 @@
1
+ /**
2
+ * The fills and lines of a MapLibre style drawn as geometry, tile by tile (`VectorTiles.vectors`), instead of into the
3
+ * images of a raster layer: sharp at any zoom and pitch, on the relief, picked by feature, restyled without cutting the
4
+ * tiles again. The workers cut each vector tile into polygons and lines and style its features; the engine draws the
5
+ * style's layers in their order, each over its zoom range.
6
+ */
7
+ import { FLOATS, stops } from "./features.js";
8
+ import { Layer } from "./layers.js";
9
+ export class VectorLayer extends Layer {
10
+ tiles = new Map();
11
+ sublayers = [];
12
+ nextKey = 0;
13
+ /** The whole layer shown (`setVisible`), over each style layer's visibility */
14
+ shown = true;
15
+ /** @internal Resolved once the style is loaded and its layers drawn known (set by its `VectorTiles`) */
16
+ styled = Promise.resolve();
17
+ /** @internal Changes a property of a style layer drawn (set by its `VectorTiles`) */
18
+ restyle;
19
+ /** @internal Asks the workers for the tiles in view again (set by its `VectorTiles`): an engine made anew has none */
20
+ recut;
21
+ /** @internal */
22
+ constructor(map) {
23
+ super(map);
24
+ }
25
+ /** Resolves once the style is loaded, its layers drawn known (`layers`), and the map has drawn the layer; rejected
26
+ * if the style fails */
27
+ get ready() {
28
+ return this.styled.then(() => super.ready);
29
+ }
30
+ /** The style layers drawn, in order */
31
+ get layers() {
32
+ return this.sublayers;
33
+ }
34
+ /** Keys of the tiles held (`z/x/y`) */
35
+ get tileKeys() {
36
+ return [...this.tiles.keys()];
37
+ }
38
+ /** @internal Sets the style layers drawn, in order (the tiles' sublayers) */
39
+ setSublayers(sublayers) {
40
+ this.sublayers = sublayers;
41
+ this.sendSublayers(this.map.engine, this.id);
42
+ this.map.requestRender();
43
+ }
44
+ /** @internal Adds or replaces a tile, cut by the workers (and made ready for the GPU there, with its mesh) */
45
+ setTile(tile, vectors) {
46
+ const key = this.tiles.get(tile)?.key ?? this.nextKey++;
47
+ const { properties, sublayer } = vectors;
48
+ this.tiles.set(tile, { key, vectors: { properties, sublayer } });
49
+ this.sendTile(this.map.engine, this.id, key, vectors);
50
+ this.map.requestRender();
51
+ }
52
+ /** @internal New styles of a tile's features, as the workers evaluated them (the same features) */
53
+ setTileStyles(tile, styles) {
54
+ const t = this.tiles.get(tile);
55
+ if (!t || styles.length !== t.vectors.properties.length * FLOATS)
56
+ return;
57
+ this.map.engine.setFeatureStyle(this.id, styles, t.key);
58
+ this.map.requestRender();
59
+ }
60
+ /** @internal */
61
+ removeTile(tile) {
62
+ const t = this.tiles.get(tile);
63
+ if (!t)
64
+ return;
65
+ this.tiles.delete(tile);
66
+ this.map.engine.removeVectorTile(this.id, t.key);
67
+ this.map.requestRender();
68
+ }
69
+ /** The feature of a picked index (no geometry: the tiles hold it cut), its properties and style layer. Tiles are
70
+ * numbered one after the other, in the order they were first added */
71
+ featureAt(index) {
72
+ const tiles = [...this.tiles.values()].sort((a, b) => a.key - b.key);
73
+ // The tile holding the index, and the index among its features (one pass, the features of the tiles before
74
+ // taken off)
75
+ const { tile, rest } = tiles.reduce((found, t) => {
76
+ if (found.tile)
77
+ return found;
78
+ const count = t.vectors.properties.length;
79
+ return found.rest < count ? { tile: t, rest: found.rest } : { rest: found.rest - count };
80
+ }, { rest: index });
81
+ if (!tile)
82
+ return undefined;
83
+ const properties = tile.vectors.properties[rest];
84
+ const sublayer = this.sublayers[tile.vectors.sublayer[rest] ?? -1];
85
+ if (properties === undefined || !sublayer)
86
+ return undefined;
87
+ return { type: 'Feature', properties, geometry: null, layer: sublayer.id, sourceLayer: sublayer.sourceLayer };
88
+ }
89
+ /** Changes a paint property of a style layer drawn, as MapLibre's `setPaintProperty`: the tiles are restyled, not cut
90
+ * again */
91
+ setPaintProperty(layer, name, value) {
92
+ this.restyle?.(layer, 'paint', name, value);
93
+ }
94
+ /** Changes a layout property of a style layer drawn (`visibility`: shown or hidden at once), as MapLibre's
95
+ * `setLayoutProperty` */
96
+ setLayoutProperty(layer, name, value) {
97
+ this.restyle?.(layer, 'layout', name, value);
98
+ }
99
+ setVisible(visible) {
100
+ this.shown = visible;
101
+ this.sendSublayers(this.map.engine, this.id);
102
+ this.map.requestRender();
103
+ }
104
+ sendSublayers(engine, id) {
105
+ const s = this.sublayers;
106
+ engine.setVectorSublayers(id, Uint8Array.from(s, (l) => ({ fill: 0, line: 1, extrusion: 2 })[l.kind]), Float64Array.from(s.flatMap((l) => [l.minZoom, l.maxZoom])), Uint8Array.from(s, (l) => (l.visible && this.shown ? 1 : 0)), Float32Array.from(s.flatMap((l) => l.dash)), Float32Array.from(s.flatMap((l) => stops(l.opacity))), Uint8Array.from(s, (l) => ({ butt: 0, round: 1, square: 2 })[l.cap]), Uint8Array.from(s, (l) => (l.lit ? 1 : 0)));
107
+ }
108
+ /** A tile to the engine: its mesh uploaded as it is, or without one its geometry, which the engine makes ready */
109
+ sendTile(engine, id, key, vectors) {
110
+ const { fills, lines, styles, properties, mesh } = vectors;
111
+ if (mesh) {
112
+ engine.setVectorTileMesh(id, key, fills.points, fills.ringStart, fills.polygonStart, fills.feature, fills.fillStart, mesh.vertices, mesh.indices, mesh.fillRanges, mesh.prism, mesh.pieces, mesh.lineTable, mesh.lineRanges, mesh.blocks, mesh.blockIndices, mesh.blockRanges, mesh.bounds, properties.length);
113
+ engine.setFeatureStyle(id, styles, key);
114
+ return;
115
+ }
116
+ engine.setVectorTile(id, key, fills.points, fills.ringStart, fills.polygonStart, fills.feature, fills.fillStart, lines.points, lines.start, lines.feature, lines.lineStart, properties.length, vectors.tile ?? new Float64Array());
117
+ engine.setFeatureStyle(id, styles, key);
118
+ }
119
+ /** @internal */
120
+ create(engine) {
121
+ const id = engine.addVectorTiles();
122
+ this.sendSublayers(engine, id);
123
+ // An engine made anew (after a context loss, or the one with 3D Tiles): its tiles cut again by the workers, once
124
+ // the layer has its id there. Keeping their geometry here would double the memory they take
125
+ this.tiles.clear();
126
+ queueMicrotask(() => this.recut?.());
127
+ return id;
128
+ }
129
+ }
130
+ //# sourceMappingURL=vectors.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vectors.js","sourceRoot":"","sources":["../../src/layers/vectors.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The fills and lines of a MapLibre style drawn as geometry, tile by tile (`VectorTiles.vectors`), instead of into the\n * images of a raster layer: sharp at any zoom and pitch, on the relief, picked by feature, restyled without cutting the\n * tiles again. The workers cut each vector tile into polygons and lines and style its features; the engine draws the\n * style's layers in their order, each over its zoom range.\n */\n\nimport type { LayerHost } from '../types.ts';\nimport type { Engine } from '../wasm/isard.js';\nimport type { TileVectors } from '../workers/basemap.worker.ts';\nimport { type Feature, FLOATS, type Size, stops } from './features.ts';\nimport { Layer } from './layers.ts';\n\n/** A style layer as the engine draws it: its kind, zoom range, visibility and dashes (dash, gap, dash, gap, in line\n * widths; zeros: solid) */\nexport interface VectorSublayer {\n /** The style layer's id */\n id: string;\n /** Its source layer, if any (not for a background) */\n sourceLayer: string | undefined;\n kind: 'fill' | 'line' | 'extrusion';\n minZoom: number;\n maxZoom: number;\n visible: boolean;\n /** Its opacity when it depends on the zoom only, evaluated at the camera's zoom (else 1: the features' colors hold\n * it) */\n opacity: Size;\n dash: [number, number, number, number];\n /** The caps of its lines' ends (`line-cap`; the joins between their pieces are round) */\n cap: 'butt' | 'round' | 'square';\n /** Its lines glow at night (the streets: its id names a road, not its casing; `setSun`) */\n lit: boolean;\n}\n\n/** The properties of a picked feature, with the style layer that drew it */\nexport type VectorFeature = Feature<Record<string, unknown>> & { layer: string; sourceLayer: string | undefined };\n\ninterface Tile {\n /** Its number in the engine: tiles are numbered for picking in this order */\n key: number;\n /** What picking needs (its geometry and styles are the engine's only: an engine made anew asks the tiles again) */\n vectors: Pick<TileVectors, 'properties' | 'sublayer'>;\n}\n\nexport class VectorLayer extends Layer {\n private readonly tiles = new Map<string, Tile>();\n private sublayers: VectorSublayer[] = [];\n private nextKey = 0;\n /** The whole layer shown (`setVisible`), over each style layer's visibility */\n private shown = true;\n /** @internal Resolved once the style is loaded and its layers drawn known (set by its `VectorTiles`) */\n styled: Promise<void> = Promise.resolve();\n /** @internal Changes a property of a style layer drawn (set by its `VectorTiles`) */\n restyle: ((layer: string, group: 'paint' | 'layout', name: string, value: unknown) => void) | undefined;\n /** @internal Asks the workers for the tiles in view again (set by its `VectorTiles`): an engine made anew has none */\n recut: (() => void) | undefined;\n\n /** @internal */\n constructor(map: LayerHost) {\n super(map);\n }\n\n /** Resolves once the style is loaded, its layers drawn known (`layers`), and the map has drawn the layer; rejected\n * if the style fails */\n override get ready(): Promise<void> {\n return this.styled.then(() => super.ready);\n }\n\n /** The style layers drawn, in order */\n get layers(): readonly VectorSublayer[] {\n return this.sublayers;\n }\n\n /** Keys of the tiles held (`z/x/y`) */\n get tileKeys(): string[] {\n return [...this.tiles.keys()];\n }\n\n /** @internal Sets the style layers drawn, in order (the tiles' sublayers) */\n setSublayers(sublayers: VectorSublayer[]): void {\n this.sublayers = sublayers;\n this.sendSublayers(this.map.engine, this.id);\n this.map.requestRender();\n }\n\n /** @internal Adds or replaces a tile, cut by the workers (and made ready for the GPU there, with its mesh) */\n setTile(tile: string, vectors: TileVectors): void {\n const key = this.tiles.get(tile)?.key ?? this.nextKey++;\n const { properties, sublayer } = vectors;\n\n this.tiles.set(tile, { key, vectors: { properties, sublayer } });\n this.sendTile(this.map.engine, this.id, key, vectors);\n this.map.requestRender();\n }\n\n /** @internal New styles of a tile's features, as the workers evaluated them (the same features) */\n setTileStyles(tile: string, styles: Float32Array): void {\n const t = this.tiles.get(tile);\n\n if (!t || styles.length !== t.vectors.properties.length * FLOATS) return;\n this.map.engine.setFeatureStyle(this.id, styles, t.key);\n this.map.requestRender();\n }\n\n /** @internal */\n removeTile(tile: string): void {\n const t = this.tiles.get(tile);\n\n if (!t) return;\n this.tiles.delete(tile);\n this.map.engine.removeVectorTile(this.id, t.key);\n this.map.requestRender();\n }\n\n /** The feature of a picked index (no geometry: the tiles hold it cut), its properties and style layer. Tiles are\n * numbered one after the other, in the order they were first added */\n featureAt(index: number): VectorFeature | undefined {\n const tiles = [...this.tiles.values()].sort((a, b) => a.key - b.key);\n // The tile holding the index, and the index among its features (one pass, the features of the tiles before\n // taken off)\n const { tile, rest } = tiles.reduce<{ tile?: Tile; rest: number }>(\n (found, t) => {\n if (found.tile) return found;\n\n const count = t.vectors.properties.length;\n\n return found.rest < count ? { tile: t, rest: found.rest } : { rest: found.rest - count };\n },\n { rest: index },\n );\n\n if (!tile) return undefined;\n\n const properties = tile.vectors.properties[rest];\n const sublayer = this.sublayers[tile.vectors.sublayer[rest] ?? -1];\n\n if (properties === undefined || !sublayer) return undefined;\n\n return { type: 'Feature', properties, geometry: null, layer: sublayer.id, sourceLayer: sublayer.sourceLayer };\n }\n\n /** Changes a paint property of a style layer drawn, as MapLibre's `setPaintProperty`: the tiles are restyled, not cut\n * again */\n setPaintProperty(layer: string, name: string, value: unknown): void {\n this.restyle?.(layer, 'paint', name, value);\n }\n\n /** Changes a layout property of a style layer drawn (`visibility`: shown or hidden at once), as MapLibre's\n * `setLayoutProperty` */\n setLayoutProperty(layer: string, name: string, value: unknown): void {\n this.restyle?.(layer, 'layout', name, value);\n }\n\n setVisible(visible: boolean): void {\n this.shown = visible;\n this.sendSublayers(this.map.engine, this.id);\n this.map.requestRender();\n }\n\n private sendSublayers(engine: Engine, id: number): void {\n const s = this.sublayers;\n\n engine.setVectorSublayers(\n id,\n Uint8Array.from(s, (l) => ({ fill: 0, line: 1, extrusion: 2 })[l.kind]),\n Float64Array.from(s.flatMap((l) => [l.minZoom, l.maxZoom])),\n Uint8Array.from(s, (l) => (l.visible && this.shown ? 1 : 0)),\n Float32Array.from(s.flatMap((l) => l.dash)),\n Float32Array.from(s.flatMap((l) => stops(l.opacity))),\n Uint8Array.from(s, (l) => ({ butt: 0, round: 1, square: 2 })[l.cap]),\n Uint8Array.from(s, (l) => (l.lit ? 1 : 0)),\n );\n }\n\n /** A tile to the engine: its mesh uploaded as it is, or without one its geometry, which the engine makes ready */\n private sendTile(engine: Engine, id: number, key: number, vectors: TileVectors): void {\n const { fills, lines, styles, properties, mesh } = vectors;\n\n if (mesh) {\n engine.setVectorTileMesh(\n id,\n key,\n fills.points,\n fills.ringStart,\n fills.polygonStart,\n fills.feature,\n fills.fillStart,\n mesh.vertices,\n mesh.indices,\n mesh.fillRanges,\n mesh.prism,\n mesh.pieces,\n mesh.lineTable,\n mesh.lineRanges,\n mesh.blocks,\n mesh.blockIndices,\n mesh.blockRanges,\n mesh.bounds,\n properties.length,\n );\n engine.setFeatureStyle(id, styles, key);\n\n return;\n }\n engine.setVectorTile(\n id,\n key,\n fills.points,\n fills.ringStart,\n fills.polygonStart,\n fills.feature,\n fills.fillStart,\n lines.points,\n lines.start,\n lines.feature,\n lines.lineStart,\n properties.length,\n vectors.tile ?? new Float64Array(),\n );\n engine.setFeatureStyle(id, styles, key);\n }\n\n /** @internal */\n protected create(engine: Engine): number {\n const id = engine.addVectorTiles();\n\n this.sendSublayers(engine, id);\n // An engine made anew (after a context loss, or the one with 3D Tiles): its tiles cut again by the workers, once\n // the layer has its id there. Keeping their geometry here would double the memory they take\n this.tiles.clear();\n queueMicrotask(() => this.recut?.());\n\n return id;\n }\n}\n"]}
@@ -0,0 +1,26 @@
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 type { GeoMap } from '../map.ts';
4
+ import type { BasemapName } from '../types.ts';
5
+ import type { LayerStack } from './layer-stack.ts';
6
+ /** The basemap and the hillshade of a map, replaced together */
7
+ export declare class BasemapLayers {
8
+ private readonly map;
9
+ private readonly stack;
10
+ /** URL of the vector basemaps' workers */
11
+ private readonly workerUrl;
12
+ /** Texture size of the vector basemap's tiles */
13
+ private readonly tileSize;
14
+ private basemap;
15
+ private hillshade;
16
+ /** The vector basemap, if any: its tiles' workers and its labels */
17
+ private vector;
18
+ /** `stack`: the map's drawing order */
19
+ constructor(map: GeoMap, stack: LayerStack, workerUrl: string | URL, tileSize: number | undefined);
20
+ /** Removes the basemap and the hillshade, then adds the basemap `name` (none for 'none') */
21
+ replace(name: BasemapName): void;
22
+ /** Adds the hillshade at `opacity` (0: none), then puts it and the basemap under all the other layers */
23
+ addHillshade(opacity: number): void;
24
+ /** Stops the vector basemap's tiles (their layers removed) */
25
+ destroy(): void;
26
+ }
@@ -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
+ }