isard 1.6.0 → 1.7.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 (123) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/dist/basemap/furniture.d.ts +20 -2
  3. package/dist/basemap/furniture.js +72 -3
  4. package/dist/basemap/furniture.js.map +1 -1
  5. package/dist/basemap/meshes.d.ts +21 -0
  6. package/dist/basemap/meshes.js +159 -0
  7. package/dist/basemap/meshes.js.map +1 -0
  8. package/dist/basemap/placed.d.ts +13 -0
  9. package/dist/basemap/placed.js +14 -0
  10. package/dist/basemap/placed.js.map +1 -0
  11. package/dist/basemap/trees.d.ts +4 -14
  12. package/dist/basemap/trees.js +12 -93
  13. package/dist/basemap/trees.js.map +1 -1
  14. package/dist/basemap/vectortiles/context.d.ts +4 -2
  15. package/dist/basemap/vectortiles/context.js.map +1 -1
  16. package/dist/basemap/vectortiles/extrusions.d.ts +1 -1
  17. package/dist/basemap/vectortiles/extrusions.js +7 -16
  18. package/dist/basemap/vectortiles/extrusions.js.map +1 -1
  19. package/dist/basemap/vectortiles/furniture.d.ts +19 -0
  20. package/dist/basemap/vectortiles/furniture.js +29 -0
  21. package/dist/basemap/vectortiles/furniture.js.map +1 -0
  22. package/dist/basemap/vectortiles/labels.js +8 -1
  23. package/dist/basemap/vectortiles/labels.js.map +1 -1
  24. package/dist/basemap/vectortiles/lamps.js +11 -76
  25. package/dist/basemap/vectortiles/lamps.js.map +1 -1
  26. package/dist/basemap/vectortiles/placed.d.ts +38 -0
  27. package/dist/basemap/vectortiles/placed.js +143 -0
  28. package/dist/basemap/vectortiles/placed.js.map +1 -0
  29. package/dist/basemap/vectortiles/street-wind.js +4 -6
  30. package/dist/basemap/vectortiles/street-wind.js.map +1 -1
  31. package/dist/basemap/vectortiles/trees.d.ts +2 -9
  32. package/dist/basemap/vectortiles/trees.js +34 -165
  33. package/dist/basemap/vectortiles/trees.js.map +1 -1
  34. package/dist/basemap/vectortiles/vectors.d.ts +4 -5
  35. package/dist/basemap/vectortiles/vectors.js +17 -16
  36. package/dist/basemap/vectortiles/vectors.js.map +1 -1
  37. package/dist/basemap/vectortiles.d.ts +14 -4
  38. package/dist/basemap/vectortiles.js +40 -12
  39. package/dist/basemap/vectortiles.js.map +1 -1
  40. package/dist/basemap/wmts.js +2 -2
  41. package/dist/basemap/wmts.js.map +1 -1
  42. package/dist/basemap.worker.js +2 -2
  43. package/dist/basemap.worker.js.map +18 -14
  44. package/dist/data/collada.js +3 -17
  45. package/dist/data/collada.js.map +1 -1
  46. package/dist/data/crs.js +1 -1
  47. package/dist/data/crs.js.map +1 -1
  48. package/dist/data/ifc.js +21 -22
  49. package/dist/data/ifc.js.map +1 -1
  50. package/dist/geoplateforme.d.ts +14 -2
  51. package/dist/geoplateforme.js +24 -2
  52. package/dist/geoplateforme.js.map +1 -1
  53. package/dist/index.d.ts +5 -4
  54. package/dist/index.js +3 -3
  55. package/dist/index.js.map +1 -1
  56. package/dist/isard_bg.wasm +0 -0
  57. package/dist/isard_core_bg.wasm +0 -0
  58. package/dist/isard_grid_bg.wasm +0 -0
  59. package/dist/isard_tess_bg.wasm +0 -0
  60. package/dist/layers/extrusions.js +5 -4
  61. package/dist/layers/extrusions.js.map +1 -1
  62. package/dist/layers/features.d.ts +0 -2
  63. package/dist/layers/features.js +5 -6
  64. package/dist/layers/features.js.map +1 -1
  65. package/dist/layers/layers.d.ts +2 -0
  66. package/dist/layers/layers.js +11 -0
  67. package/dist/layers/layers.js.map +1 -1
  68. package/dist/layers/panoramas.d.ts +32 -10
  69. package/dist/layers/panoramas.js +55 -28
  70. package/dist/layers/panoramas.js.map +1 -1
  71. package/dist/layers/photos.js +5 -6
  72. package/dist/layers/photos.js.map +1 -1
  73. package/dist/layers/trees.js +7 -7
  74. package/dist/layers/trees.js.map +1 -1
  75. package/dist/layers/vectors.d.ts +1 -0
  76. package/dist/layers/vectors.js +23 -8
  77. package/dist/layers/vectors.js.map +1 -1
  78. package/dist/map/frame-loop.d.ts +2 -0
  79. package/dist/map/frame-loop.js +3 -3
  80. package/dist/map/frame-loop.js.map +1 -1
  81. package/dist/map.js +17 -0
  82. package/dist/map.js.map +1 -1
  83. package/dist/panoramax.d.ts +6 -0
  84. package/dist/panoramax.js +29 -3
  85. package/dist/panoramax.js.map +1 -1
  86. package/dist/react/VectorGeometry.d.ts +18 -9
  87. package/dist/react/VectorGeometry.js +27 -13
  88. package/dist/react/VectorGeometry.js.map +1 -1
  89. package/dist/react/VectorTiles.d.ts +65 -0
  90. package/dist/react/VectorTiles.js +112 -0
  91. package/dist/react/VectorTiles.js.map +1 -0
  92. package/dist/react/context.d.ts +9 -0
  93. package/dist/react/context.js +32 -0
  94. package/dist/react/context.js.map +1 -1
  95. package/dist/react/index.d.ts +7 -1
  96. package/dist/react/index.js +7 -1
  97. package/dist/react/index.js.map +1 -1
  98. package/dist/types.d.ts +2 -0
  99. package/dist/types.js.map +1 -1
  100. package/dist/util/geo.d.ts +8 -0
  101. package/dist/util/geo.js +8 -0
  102. package/dist/util/geo.js.map +1 -1
  103. package/dist/util/gltf.d.ts +18 -1
  104. package/dist/util/gltf.js +26 -1
  105. package/dist/util/gltf.js.map +1 -1
  106. package/dist/util/roofs.d.ts +8 -0
  107. package/dist/util/roofs.js +16 -2
  108. package/dist/util/roofs.js.map +1 -1
  109. package/dist/util/style-floats.d.ts +33 -0
  110. package/dist/util/style-floats.js +34 -0
  111. package/dist/util/style-floats.js.map +1 -0
  112. package/dist/util/sun.js +1 -1
  113. package/dist/util/sun.js.map +1 -1
  114. package/dist/workers/basemap/furniture.d.ts +13 -0
  115. package/dist/workers/basemap/geometry.d.ts +2 -5
  116. package/dist/workers/basemap/labels.d.ts +5 -2
  117. package/dist/workers/basemap/lamps.d.ts +3 -3
  118. package/dist/workers/basemap/tiles.d.ts +2 -0
  119. package/dist/workers/basemap/trees.d.ts +3 -0
  120. package/dist/workers/basemap.worker.d.ts +17 -1
  121. package/dist/workers/basemap.worker.js +12 -1
  122. package/dist/workers/basemap.worker.js.map +1 -1
  123. package/package.json +1 -1
@@ -2,7 +2,7 @@
2
2
  * The vector layer of a vector basemap (`VectorTiles.vectors`): its fills, lines and buildings cut by the workers
3
3
  * into geometry the engine draws, the tiles following the view, and how its style layers are read for the engine.
4
4
  */
5
- import { FLOATS } from "../../layers/features.js";
5
+ import { FLOATS, STYLE } from "../../util/style-floats.js";
6
6
  import { evaluate, isExpression, vectorKind, zoomOnly } from "../vectorstyle.js";
7
7
  import { TileRequests } from "./requests.js";
8
8
  import { nearPriority, parseTileKey, tileKey, tileTriples } from "./tiles.js";
@@ -12,12 +12,14 @@ import { nearPriority, parseTileKey, tileKey, tileTriples } from "./tiles.js";
12
12
  const OVERZOOM_LEVEL = 18;
13
13
  /** The deepest level of the tiles of `vectors()` over a source whose deepest is `maxzoom` */
14
14
  const deepestLevel = (maxzoom) => Math.max(maxzoom, OVERZOOM_LEVEL);
15
+ /** A layout or paint value at a zoom, whatever the feature (an expression evaluated) */
16
+ const atZoom = (value, zoom) => isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;
15
17
  /**
16
18
  * A `line-dasharray` as the engine takes it: two dashes and gaps in line widths (an odd count repeated, as the
17
19
  * canvas's `setLineDash`; past four, the first four), zeros for a solid line
18
20
  */
19
21
  export const dashes = (value, zoom) => {
20
- const v = isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;
22
+ const v = atZoom(value, zoom);
21
23
  const list = Array.isArray(v) ? v.map(Number).filter((d) => Number.isFinite(d) && d >= 0) : [];
22
24
  const even = list.length % 2 === 1 ? [...list, ...list] : list;
23
25
  const [a = 0, b = 0, c = 0, d = 0] = even.length >= 2 && even.some((x) => x > 0) ? even : [];
@@ -29,30 +31,29 @@ export const isStreet = (layer) => /road|highway|street|motorway|trunk|primary|s
29
31
  !/casing|outline|rail|path|track|ferry|tunnel|pier|area|pattern|label/i.test(layer.id);
30
32
  /** A `line-cap` as the engine draws it, at the camera's zoom (MapLibre's default: butt) */
31
33
  const lineCap = (value, zoom) => {
32
- const v = isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;
34
+ const v = atZoom(value, zoom);
33
35
  return v === 'round' || v === 'square' ? v : 'butt';
34
36
  };
35
37
  /** A `line-join` as the engine draws it, at the camera's zoom (MapLibre's default: miter) */
36
38
  const lineJoin = (value, zoom) => {
37
- const v = isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;
39
+ const v = atZoom(value, zoom);
38
40
  return v === 'round' || v === 'bevel' ? v : 'miter';
39
41
  };
40
42
  /** A `line-miter-limit` at the camera's zoom (MapLibre's default: 2) */
41
43
  const miterLimit = (value, zoom) => {
42
- const v = Number(isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : (value ?? 2));
44
+ const v = Number(atZoom(value, zoom) ?? 2);
43
45
  return Number.isFinite(v) ? v : 2;
44
46
  };
45
- /** A tile's styles with their patterns placed: each feature's pattern, as its index past one into `names` (float 28
46
- * for a fill, 29 for a line or a building: floats the engine does not keep), replaced by its image's place in the icon
47
- * atlas (texels) and pixel ratio, at 12 and 16 for a fill, 4 and 27 for a line or a building; none if the atlas has no
48
- * such image; the atlas uploaded */
47
+ /** A tile's styles with their patterns placed: each feature's pattern, as its index past one into `names`
48
+ * (`STYLE.fillPattern`, `STYLE.linePattern`), replaced by its image's place in the icon atlas (texels) and pixel
49
+ * ratio; none if the atlas has no such image; the atlas uploaded */
49
50
  export const placePatterns = (styles, names, icons, prefix) => {
50
51
  if (!names?.length)
51
52
  return styles;
52
53
  // Thousands of features a tile: a loop
53
54
  for (let f = 0; f + FLOATS <= styles.length; f += FLOATS) {
54
- const fill = styles[f + 28] ?? 0;
55
- const line = styles[f + 29] ?? 0;
55
+ const fill = styles[f + STYLE.fillPattern] ?? 0;
56
+ const line = styles[f + STYLE.linePattern] ?? 0;
56
57
  const index = fill > 0 ? fill : line;
57
58
  if (index <= 0)
58
59
  continue;
@@ -60,10 +61,10 @@ export const placePatterns = (styles, names, icons, prefix) => {
60
61
  const place = icon ? [icon.x, icon.y, icon.width, icon.height] : [0, 0, 0, 0];
61
62
  const ratio = icon?.pixelRatio ?? 0;
62
63
  if (fill > 0)
63
- styles.set([...place, ratio], f + 12);
64
+ styles.set([...place, ratio], f + STYLE.size + 4);
64
65
  else {
65
- styles.set(place, f + 4);
66
- styles[f + 27] = ratio;
66
+ styles.set(place, f + STYLE.second);
67
+ styles[f + STYLE.patternRatio] = ratio;
67
68
  }
68
69
  }
69
70
  icons.flush();
@@ -73,7 +74,7 @@ export const placePatterns = (styles, names, icons, prefix) => {
73
74
  const PATTERNS = ['fill-pattern', 'background-pattern', 'line-pattern', 'fill-extrusion-pattern'];
74
75
  /** A `fill-translate` or `line-translate` at the camera's zoom (CSS pixels; none if it is not two numbers) */
75
76
  export const translation = (value, zoom) => {
76
- const v = isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;
77
+ const v = atZoom(value, zoom);
77
78
  const [x, y] = Array.isArray(v) ? v.map(Number) : [];
78
79
  return Number.isFinite(x) && Number.isFinite(y) ? [x ?? 0, y ?? 0] : [0, 0];
79
80
  };
@@ -225,7 +226,7 @@ export const vectors = (context, options = {}) => {
225
226
  vector.styled.catch(() => undefined);
226
227
  // While the camera moves, the tiles follow it (as the labels do: a long drag or flight does not leave the view of
227
228
  // its start drawn)
228
- context.followView(update, requests, update);
229
+ context.followView(vector, update, requests, update);
229
230
  return vector;
230
231
  };
231
232
  //# sourceMappingURL=vectors.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"vectors.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/vectors.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The vector layer of a vector basemap (`VectorTiles.vectors`): its fills, lines and buildings cut by the workers\n * into geometry the engine draws, the tiles following the view, and how its style layers are read for the engine.\n */\n\nimport { FLOATS } from '../../layers/features.ts';\nimport type { Icons } from '../../layers/icons.ts';\nimport type { Layer } from '../../layers/layers.ts';\nimport type { VectorLayer, VectorSublayer } from '../../layers/vectors.ts';\nimport type { RoofMode } from '../../workers/basemap/geometry.ts';\nimport type { BasemapWork, Priority } from '../../workers/basemap.worker.ts';\nimport { evaluate, isExpression, type Json, type StyleLayer, vectorKind, zoomOnly } from '../vectorstyle.ts';\nimport type { Renderer, VectorTilesContext } from './context.ts';\nimport { TileRequests } from './requests.ts';\nimport { nearPriority, parseTileKey, type TileTriple, tileKey, tileTriples } from './tiles.ts';\n\n/** The deepest level `vectors()` cuts its tiles at: past the source's deepest level, its tiles cut again into deeper\n * ones (overzoom, as MapLibre does) down to level 18, their styles those of their level, smaller tiles\n * drawn in a closer view; past it, the tiles of that level stretched */\nconst OVERZOOM_LEVEL = 18;\n\n/** The deepest level of the tiles of `vectors()` over a source whose deepest is `maxzoom` */\nconst deepestLevel = (maxzoom: number): number => Math.max(maxzoom, OVERZOOM_LEVEL);\n\n/**\n * A `line-dasharray` as the engine takes it: two dashes and gaps in line widths (an odd count repeated, as the\n * canvas's `setLineDash`; past four, the first four), zeros for a solid line\n */\nexport const dashes = (value: Json | undefined, zoom: number): [number, number, number, number] => {\n const v = isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;\n const list = Array.isArray(v) ? v.map(Number).filter((d) => Number.isFinite(d) && d >= 0) : [];\n const even = list.length % 2 === 1 ? [...list, ...list] : list;\n const [a = 0, b = 0, c = 0, d = 0] = even.length >= 2 && even.some((x) => x > 0) ? even : [];\n\n return [a, b, c, d];\n};\n\n/** Whether a style layer draws streets, which glow at night: its id names a road (OpenMapTiles' styles, PLAN IGN's),\n * not its casing, a railway, a path or a tunnel */\nexport const isStreet = (layer: StyleLayer): boolean =>\n /road|highway|street|motorway|trunk|primary|secondary|tertiary|minor|routier/i.test(layer.id) &&\n !/casing|outline|rail|path|track|ferry|tunnel|pier|area|pattern|label/i.test(layer.id);\n\n/** A `line-cap` as the engine draws it, at the camera's zoom (MapLibre's default: butt) */\nconst lineCap = (value: Json | undefined, zoom: number): 'butt' | 'round' | 'square' => {\n const v = isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;\n\n return v === 'round' || v === 'square' ? v : 'butt';\n};\n\n/** A `line-join` as the engine draws it, at the camera's zoom (MapLibre's default: miter) */\nconst lineJoin = (value: Json | undefined, zoom: number): 'miter' | 'bevel' | 'round' => {\n const v = isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;\n\n return v === 'round' || v === 'bevel' ? v : 'miter';\n};\n\n/** A `line-miter-limit` at the camera's zoom (MapLibre's default: 2) */\nconst miterLimit = (value: Json | undefined, zoom: number): number => {\n const v = Number(isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : (value ?? 2));\n\n return Number.isFinite(v) ? v : 2;\n};\n\n/** A tile's styles with their patterns placed: each feature's pattern, as its index past one into `names` (float 28\n * for a fill, 29 for a line or a building: floats the engine does not keep), replaced by its image's place in the icon\n * atlas (texels) and pixel ratio, at 12 and 16 for a fill, 4 and 27 for a line or a building; none if the atlas has no\n * such image; the atlas uploaded */\nexport const placePatterns = (\n styles: Float32Array,\n names: readonly string[] | undefined,\n icons: Icons,\n prefix: string,\n): Float32Array => {\n if (!names?.length) return styles;\n // Thousands of features a tile: a loop\n for (let f = 0; f + FLOATS <= styles.length; f += FLOATS) {\n const fill = styles[f + 28] ?? 0;\n const line = styles[f + 29] ?? 0;\n const index = fill > 0 ? fill : line;\n\n if (index <= 0) continue;\n\n const icon = icons.get(prefix + (names[index - 1] ?? ''));\n const place = icon ? [icon.x, icon.y, icon.width, icon.height] : [0, 0, 0, 0];\n const ratio = icon?.pixelRatio ?? 0;\n\n if (fill > 0) styles.set([...place, ratio], f + 12);\n else {\n styles.set(place, f + 4);\n styles[f + 27] = ratio;\n }\n }\n icons.flush();\n\n return styles;\n};\n\n/** The paint properties of the patterns `vectors()` draws, whose images come from the style's sprite */\nconst PATTERNS = ['fill-pattern', 'background-pattern', 'line-pattern', 'fill-extrusion-pattern'];\n\n/** A `fill-translate` or `line-translate` at the camera's zoom (CSS pixels; none if it is not two numbers) */\nexport const translation = (value: Json | undefined, zoom: number): [number, number] => {\n const v = isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;\n const [x, y] = Array.isArray(v) ? v.map(Number) : [];\n\n return Number.isFinite(x) && Number.isFinite(y) ? [x ?? 0, y ?? 0] : [0, 0];\n};\n\n/** The options of `VectorTiles.vectors` */\nexport interface VectorsOptions {\n layers?: (layer: StyleLayer) => boolean;\n streets?: (layer: StyleLayer) => boolean;\n before?: Layer;\n /** The buildings' roofs: from their data (`roof:shape`, `roof:height`; flat without, the default), generated from\n * their outline where they have none (hipped, gabled or mansard by size and shape), or all flat */\n roofs?: RoofMode;\n /** The buildings' walls show their windows: glass by day, some lit at night (default false: only the lit ones) */\n facades?: boolean;\n}\n\nexport const vectors = (context: VectorTilesContext, options: VectorsOptions = {}): VectorLayer => {\n const { map } = context;\n const { layers = () => true, streets = isStreet, before, roofs = 'data', facades = false } = options;\n const vector = map.addVectorLayer(before);\n\n vector.setFacades(facades);\n const state: {\n renderer: Promise<Renderer>;\n /** The style layers as the application changed them (`setPaintProperty`…): a copy, its style left as it is */\n own?: StyleLayer[];\n /** Bumped by each update: only the last one drops the tiles out of its view */\n update: number;\n /** Bumped by each restyle: a tile cut under an older style is restyled once it is there */\n style: number;\n } = { renderer: context.renderer((l) => vectorKind(l) !== undefined && layers(l), []), update: 0, style: 0 };\n\n state.renderer.catch(() => undefined);\n\n /** The style's sprites among the map's icons, if a layer drawn has a pattern: waited for before the first tiles */\n const sprites = context.ready\n .then(({ style }) =>\n style.layers.some((l) => layers(l) && PATTERNS.some((k) => l.paint?.[k] !== undefined))\n ? context.addSprites()\n : undefined,\n )\n .catch(() => undefined);\n const placed = (styles: Float32Array, names: readonly string[] | undefined) =>\n placePatterns(styles, names, map.icons, context.iconPrefix);\n context.layers.push(vector);\n\n const sublayers = (list: StyleLayer[]): VectorSublayer[] => {\n const zoom = map.getCamera().zoom;\n\n return list.map((l) => ({\n id: l.id,\n sourceLayer: l['source-layer'],\n kind: vectorKind(l) ?? 'fill',\n minZoom: l.minzoom ?? 0,\n maxZoom: l.maxzoom ?? 24,\n visible: l.layout?.visibility !== 'none',\n opacity: zoomOnly(l.paint?.[`${l.type}-opacity`], 1) ?? 1,\n cap: lineCap(l.layout?.['line-cap'], zoom),\n join: lineJoin(l.layout?.['line-join'], zoom),\n miterLimit: miterLimit(l.layout?.['line-miter-limit'], zoom),\n translate: translation(l.paint?.[`${l.type}-translate`], zoom),\n translateAnchor: l.paint?.[`${l.type}-translate-anchor`] === 'viewport' ? 'viewport' : 'map',\n patterned: l.paint?.['fill-pattern'] !== undefined || l.paint?.['background-pattern'] !== undefined,\n lit: l.type === 'line' && streets(l),\n dash: l.type === 'line' ? dashes(l.paint?.['line-dasharray'], zoom) : [0, 0, 0, 0],\n }));\n };\n\n /** The tiles held or asked for, by `z/x/y` */\n const requests = new TileRequests();\n /** A tile's geometry, or its styles alone, asked of the worker of its tile of the source's level (which keeps the\n * decoded tile its deeper tiles are cut from) */\n const ask = (\n { key, maxzoom }: { key: string; maxzoom: number },\n [z, x, y]: TileTriple,\n styles: boolean,\n priority: Priority,\n signal?: AbortSignal,\n ) => {\n const d = Math.max(0, z - maxzoom);\n const work: BasemapWork = { type: 'vectors', key, z, x, y, deepest: deepestLevel(maxzoom), roofs, priority };\n\n // The geometry made ready for the GPU in the workers, with the prisms the relief needs\n return context.request(\n z - d,\n Math.floor(x / 2 ** d),\n Math.floor(y / 2 ** d),\n styles ? { ...work, styles } : { ...work, prism: map.hasRelief },\n signal,\n );\n };\n\n // The workers tessellate the tiles (the main thread only uploads them), once they know the module\n context.broadcast({ type: 'tess', url: map.tessUrl });\n /** Asks the workers again for the styles of a tile held, under the current style; the tile's geometry stays as it\n * is */\n const restyleTile = async (renderer: { key: string; maxzoom: number }, k: string) => {\n const r = await ask(renderer, parseTileKey(k), true, 'auto').catch(() => undefined);\n\n if (r && 'styles' in r) vector.setTileStyles(k, placed(r.styles, r.patterns));\n };\n const update = async () => {\n if (context.destroyed()) return;\n\n const generation = ++state.update;\n // The style the tiles are cut under: that of the renderer awaited, a restyle meanwhile (a paint property set as the\n // style loads) asking their styles again once they are there\n const style = state.style;\n const { key, maxzoom, layers: list } = await state.renderer;\n\n await sprites;\n\n vector.setSublayers(sublayers(state.own ?? list));\n\n const wanted = tileTriples(map.engine.vectorTilesInView(0, deepestLevel(maxzoom)));\n const keys = new Set(wanted.map((t) => tileKey(...t)));\n const loads = wanted.flatMap((t, index) => {\n const k = tileKey(...t);\n\n if (requests.has(k)) return [];\n\n return [\n requests.ask(\n k,\n (signal) => ask({ key, maxzoom }, t, false, nearPriority(index, 'high', 'auto'), signal),\n async (r) => {\n if (!('vectors' in r)) return;\n await vector.setTile(k, { ...r.vectors, styles: placed(r.vectors.styles, r.vectors.patterns) });\n // Cut under a style changed since: its styles asked for again\n if (style !== state.style) await restyleTile(await state.renderer, k);\n },\n ),\n ];\n });\n // Out of view: those still asked for go at once, those drawn once their replacements are there (no hole). The\n // drawn ones are those the engine shows, held or not (a recut forgets what it held, not what is drawn)\n const drop = (drawn: boolean) => {\n const shown = new Set(vector.tileKeys);\n const known = new Set([...requests.keys(), ...(drawn ? shown : [])]);\n\n known.forEach((k) => {\n if (keys.has(k) || shown.has(k) !== drawn) return;\n requests.drop(k);\n vector.removeTile(k);\n });\n };\n\n drop(false);\n // Every tile of the view, those an earlier update asked for too: a tile out of view stays drawn until all of them\n // are there\n await Promise.all([...loads, requests.answered(keys)]);\n // A later update (the view moved again meanwhile) drops for its own view: these keys are no longer the view\n if (!context.destroyed() && generation === state.update) drop(true);\n };\n const refresh = () => {\n update().catch(() => undefined);\n };\n /** The style layers changed: the workers' copy, then the styles of the tiles held */\n const restyle = async (list: StyleLayer[]) => {\n state.own = list;\n state.style++;\n state.renderer = state.renderer.then(({ key }) => context.renderer(() => false, list, key));\n\n const renderer = await state.renderer;\n\n vector.setSublayers(sublayers(list));\n await Promise.all(vector.tileKeys.map((k) => restyleTile(renderer, k)));\n };\n\n vector.restyle = (id, group, name, value) => {\n state.renderer\n .then(({ layers: list }) => {\n const next = (state.own ?? list).map((l) =>\n l.id === id ? { ...l, [group]: { ...l[group], [name]: value } } : l,\n );\n\n // Visibility and dashes are the engine's: the tiles stay as they are\n if ((group === 'layout' && name === 'visibility') || name === 'line-dasharray') {\n state.own = next;\n vector.setSublayers(sublayers(next));\n\n return undefined;\n }\n // An outline added or taken away: a feature more or less in each tile, cut again\n if (name === 'fill-outline-color' || name === 'fill-antialias') {\n state.own = next;\n state.style++;\n state.renderer = state.renderer.then(({ key }) => context.renderer(() => false, next, key));\n vector.setSublayers(sublayers(next));\n vector.recut?.();\n\n return undefined;\n }\n\n return restyle(next);\n })\n .catch(() => undefined);\n };\n vector.recut = () => {\n requests.abortAll();\n refresh();\n };\n vector.styled = state.renderer.then(({ layers: list }) => {\n if (!context.destroyed()) vector.setSublayers(sublayers(state.own ?? list));\n });\n // Reported by the style's `ready`\n vector.styled.catch(() => undefined);\n\n // While the camera moves, the tiles follow it (as the labels do: a long drag or flight does not leave the view of\n // its start drawn)\n context.followView(update, requests, update);\n\n return vector;\n};\n"]}
1
+ {"version":3,"file":"vectors.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/vectors.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The vector layer of a vector basemap (`VectorTiles.vectors`): its fills, lines and buildings cut by the workers\n * into geometry the engine draws, the tiles following the view, and how its style layers are read for the engine.\n */\n\nimport type { Icons } from '../../layers/icons.ts';\nimport type { Layer } from '../../layers/layers.ts';\nimport type { VectorLayer, VectorSublayer } from '../../layers/vectors.ts';\nimport type { RoofMode } from '../../util/roofs.ts';\nimport { FLOATS, STYLE } from '../../util/style-floats.ts';\nimport type { BasemapWork, Priority } from '../../workers/basemap.worker.ts';\nimport { evaluate, isExpression, type Json, type StyleLayer, vectorKind, zoomOnly } from '../vectorstyle.ts';\nimport type { Renderer, VectorTilesContext } from './context.ts';\nimport { TileRequests } from './requests.ts';\nimport { nearPriority, parseTileKey, type TileTriple, tileKey, tileTriples } from './tiles.ts';\n\n/** The deepest level `vectors()` cuts its tiles at: past the source's deepest level, its tiles cut again into deeper\n * ones (overzoom, as MapLibre does) down to level 18, their styles those of their level, smaller tiles\n * drawn in a closer view; past it, the tiles of that level stretched */\nconst OVERZOOM_LEVEL = 18;\n\n/** The deepest level of the tiles of `vectors()` over a source whose deepest is `maxzoom` */\nconst deepestLevel = (maxzoom: number): number => Math.max(maxzoom, OVERZOOM_LEVEL);\n\n/** A layout or paint value at a zoom, whatever the feature (an expression evaluated) */\nconst atZoom = (value: Json | undefined, zoom: number): unknown =>\n isExpression(value) ? evaluate(value, { zoom, properties: {}, type: 'Unknown' }) : value;\n\n/**\n * A `line-dasharray` as the engine takes it: two dashes and gaps in line widths (an odd count repeated, as the\n * canvas's `setLineDash`; past four, the first four), zeros for a solid line\n */\nexport const dashes = (value: Json | undefined, zoom: number): [number, number, number, number] => {\n const v = atZoom(value, zoom);\n const list = Array.isArray(v) ? v.map(Number).filter((d) => Number.isFinite(d) && d >= 0) : [];\n const even = list.length % 2 === 1 ? [...list, ...list] : list;\n const [a = 0, b = 0, c = 0, d = 0] = even.length >= 2 && even.some((x) => x > 0) ? even : [];\n\n return [a, b, c, d];\n};\n\n/** Whether a style layer draws streets, which glow at night: its id names a road (OpenMapTiles' styles, PLAN IGN's),\n * not its casing, a railway, a path or a tunnel */\nexport const isStreet = (layer: StyleLayer): boolean =>\n /road|highway|street|motorway|trunk|primary|secondary|tertiary|minor|routier/i.test(layer.id) &&\n !/casing|outline|rail|path|track|ferry|tunnel|pier|area|pattern|label/i.test(layer.id);\n\n/** A `line-cap` as the engine draws it, at the camera's zoom (MapLibre's default: butt) */\nconst lineCap = (value: Json | undefined, zoom: number): 'butt' | 'round' | 'square' => {\n const v = atZoom(value, zoom);\n\n return v === 'round' || v === 'square' ? v : 'butt';\n};\n\n/** A `line-join` as the engine draws it, at the camera's zoom (MapLibre's default: miter) */\nconst lineJoin = (value: Json | undefined, zoom: number): 'miter' | 'bevel' | 'round' => {\n const v = atZoom(value, zoom);\n\n return v === 'round' || v === 'bevel' ? v : 'miter';\n};\n\n/** A `line-miter-limit` at the camera's zoom (MapLibre's default: 2) */\nconst miterLimit = (value: Json | undefined, zoom: number): number => {\n const v = Number(atZoom(value, zoom) ?? 2);\n\n return Number.isFinite(v) ? v : 2;\n};\n\n/** A tile's styles with their patterns placed: each feature's pattern, as its index past one into `names`\n * (`STYLE.fillPattern`, `STYLE.linePattern`), replaced by its image's place in the icon atlas (texels) and pixel\n * ratio; none if the atlas has no such image; the atlas uploaded */\nexport const placePatterns = (\n styles: Float32Array,\n names: readonly string[] | undefined,\n icons: Icons,\n prefix: string,\n): Float32Array => {\n if (!names?.length) return styles;\n // Thousands of features a tile: a loop\n for (let f = 0; f + FLOATS <= styles.length; f += FLOATS) {\n const fill = styles[f + STYLE.fillPattern] ?? 0;\n const line = styles[f + STYLE.linePattern] ?? 0;\n const index = fill > 0 ? fill : line;\n\n if (index <= 0) continue;\n\n const icon = icons.get(prefix + (names[index - 1] ?? ''));\n const place = icon ? [icon.x, icon.y, icon.width, icon.height] : [0, 0, 0, 0];\n const ratio = icon?.pixelRatio ?? 0;\n\n if (fill > 0) styles.set([...place, ratio], f + STYLE.size + 4);\n else {\n styles.set(place, f + STYLE.second);\n styles[f + STYLE.patternRatio] = ratio;\n }\n }\n icons.flush();\n\n return styles;\n};\n\n/** The paint properties of the patterns `vectors()` draws, whose images come from the style's sprite */\nconst PATTERNS = ['fill-pattern', 'background-pattern', 'line-pattern', 'fill-extrusion-pattern'];\n\n/** A `fill-translate` or `line-translate` at the camera's zoom (CSS pixels; none if it is not two numbers) */\nexport const translation = (value: Json | undefined, zoom: number): [number, number] => {\n const v = atZoom(value, zoom);\n const [x, y] = Array.isArray(v) ? v.map(Number) : [];\n\n return Number.isFinite(x) && Number.isFinite(y) ? [x ?? 0, y ?? 0] : [0, 0];\n};\n\n/** The options of `VectorTiles.vectors` */\nexport interface VectorsOptions {\n layers?: (layer: StyleLayer) => boolean;\n streets?: (layer: StyleLayer) => boolean;\n before?: Layer;\n /** The buildings' roofs: from their data (`roof:shape`, `roof:height`; flat without, the default), generated from\n * their outline where they have none (hipped, gabled or mansard by size and shape), or all flat */\n roofs?: RoofMode;\n /** The buildings' walls show their windows: glass by day, some lit at night (default false: only the lit ones) */\n facades?: boolean;\n}\n\nexport const vectors = (context: VectorTilesContext, options: VectorsOptions = {}): VectorLayer => {\n const { map } = context;\n const { layers = () => true, streets = isStreet, before, roofs = 'data', facades = false } = options;\n const vector = map.addVectorLayer(before);\n\n vector.setFacades(facades);\n const state: {\n renderer: Promise<Renderer>;\n /** The style layers as the application changed them (`setPaintProperty`…): a copy, its style left as it is */\n own?: StyleLayer[];\n /** Bumped by each update: only the last one drops the tiles out of its view */\n update: number;\n /** Bumped by each restyle: a tile cut under an older style is restyled once it is there */\n style: number;\n } = { renderer: context.renderer((l) => vectorKind(l) !== undefined && layers(l), []), update: 0, style: 0 };\n\n state.renderer.catch(() => undefined);\n\n /** The style's sprites among the map's icons, if a layer drawn has a pattern: waited for before the first tiles */\n const sprites = context.ready\n .then(({ style }) =>\n style.layers.some((l) => layers(l) && PATTERNS.some((k) => l.paint?.[k] !== undefined))\n ? context.addSprites()\n : undefined,\n )\n .catch(() => undefined);\n const placed = (styles: Float32Array, names: readonly string[] | undefined) =>\n placePatterns(styles, names, map.icons, context.iconPrefix);\n context.layers.push(vector);\n\n const sublayers = (list: StyleLayer[]): VectorSublayer[] => {\n const zoom = map.getCamera().zoom;\n\n return list.map((l) => ({\n id: l.id,\n sourceLayer: l['source-layer'],\n kind: vectorKind(l) ?? 'fill',\n minZoom: l.minzoom ?? 0,\n maxZoom: l.maxzoom ?? 24,\n visible: l.layout?.visibility !== 'none',\n opacity: zoomOnly(l.paint?.[`${l.type}-opacity`], 1) ?? 1,\n cap: lineCap(l.layout?.['line-cap'], zoom),\n join: lineJoin(l.layout?.['line-join'], zoom),\n miterLimit: miterLimit(l.layout?.['line-miter-limit'], zoom),\n translate: translation(l.paint?.[`${l.type}-translate`], zoom),\n translateAnchor: l.paint?.[`${l.type}-translate-anchor`] === 'viewport' ? 'viewport' : 'map',\n patterned: l.paint?.['fill-pattern'] !== undefined || l.paint?.['background-pattern'] !== undefined,\n lit: l.type === 'line' && streets(l),\n dash: l.type === 'line' ? dashes(l.paint?.['line-dasharray'], zoom) : [0, 0, 0, 0],\n }));\n };\n\n /** The tiles held or asked for, by `z/x/y` */\n const requests = new TileRequests();\n /** A tile's geometry, or its styles alone, asked of the worker of its tile of the source's level (which keeps the\n * decoded tile its deeper tiles are cut from) */\n const ask = (\n { key, maxzoom }: { key: string; maxzoom: number },\n [z, x, y]: TileTriple,\n styles: boolean,\n priority: Priority,\n signal?: AbortSignal,\n ) => {\n const d = Math.max(0, z - maxzoom);\n const work: BasemapWork = { type: 'vectors', key, z, x, y, deepest: deepestLevel(maxzoom), roofs, priority };\n\n // The geometry made ready for the GPU in the workers, with the prisms the relief needs\n return context.request(\n z - d,\n Math.floor(x / 2 ** d),\n Math.floor(y / 2 ** d),\n styles ? { ...work, styles } : { ...work, prism: map.hasRelief },\n signal,\n );\n };\n\n // The workers tessellate the tiles (the main thread only uploads them), once they know the module\n context.broadcast({ type: 'tess', url: map.tessUrl });\n /** Asks the workers again for the styles of a tile held, under the current style; the tile's geometry stays as it\n * is */\n const restyleTile = async (renderer: { key: string; maxzoom: number }, k: string) => {\n const r = await ask(renderer, parseTileKey(k), true, 'auto').catch(() => undefined);\n\n if (r && 'styles' in r) vector.setTileStyles(k, placed(r.styles, r.patterns));\n };\n const update = async () => {\n if (context.destroyed()) return;\n\n const generation = ++state.update;\n // The style the tiles are cut under: that of the renderer awaited, a restyle meanwhile (a paint property set as the\n // style loads) asking their styles again once they are there\n const style = state.style;\n const { key, maxzoom, layers: list } = await state.renderer;\n\n await sprites;\n\n vector.setSublayers(sublayers(state.own ?? list));\n\n const wanted = tileTriples(map.engine.vectorTilesInView(0, deepestLevel(maxzoom)));\n const keys = new Set(wanted.map((t) => tileKey(...t)));\n const loads = wanted.flatMap((t, index) => {\n const k = tileKey(...t);\n\n if (requests.has(k)) return [];\n\n return [\n requests.ask(\n k,\n (signal) => ask({ key, maxzoom }, t, false, nearPriority(index, 'high', 'auto'), signal),\n async (r) => {\n if (!('vectors' in r)) return;\n await vector.setTile(k, { ...r.vectors, styles: placed(r.vectors.styles, r.vectors.patterns) });\n // Cut under a style changed since: its styles asked for again\n if (style !== state.style) await restyleTile(await state.renderer, k);\n },\n ),\n ];\n });\n // Out of view: those still asked for go at once, those drawn once their replacements are there (no hole). The\n // drawn ones are those the engine shows, held or not (a recut forgets what it held, not what is drawn)\n const drop = (drawn: boolean) => {\n const shown = new Set(vector.tileKeys);\n const known = new Set([...requests.keys(), ...(drawn ? shown : [])]);\n\n known.forEach((k) => {\n if (keys.has(k) || shown.has(k) !== drawn) return;\n requests.drop(k);\n vector.removeTile(k);\n });\n };\n\n drop(false);\n // Every tile of the view, those an earlier update asked for too: a tile out of view stays drawn until all of them\n // are there\n await Promise.all([...loads, requests.answered(keys)]);\n // A later update (the view moved again meanwhile) drops for its own view: these keys are no longer the view\n if (!context.destroyed() && generation === state.update) drop(true);\n };\n const refresh = () => {\n update().catch(() => undefined);\n };\n /** The style layers changed: the workers' copy, then the styles of the tiles held */\n const restyle = async (list: StyleLayer[]) => {\n state.own = list;\n state.style++;\n state.renderer = state.renderer.then(({ key }) => context.renderer(() => false, list, key));\n\n const renderer = await state.renderer;\n\n vector.setSublayers(sublayers(list));\n await Promise.all(vector.tileKeys.map((k) => restyleTile(renderer, k)));\n };\n\n vector.restyle = (id, group, name, value) => {\n state.renderer\n .then(({ layers: list }) => {\n const next = (state.own ?? list).map((l) =>\n l.id === id ? { ...l, [group]: { ...l[group], [name]: value } } : l,\n );\n\n // Visibility and dashes are the engine's: the tiles stay as they are\n if ((group === 'layout' && name === 'visibility') || name === 'line-dasharray') {\n state.own = next;\n vector.setSublayers(sublayers(next));\n\n return undefined;\n }\n // An outline added or taken away: a feature more or less in each tile, cut again\n if (name === 'fill-outline-color' || name === 'fill-antialias') {\n state.own = next;\n state.style++;\n state.renderer = state.renderer.then(({ key }) => context.renderer(() => false, next, key));\n vector.setSublayers(sublayers(next));\n vector.recut?.();\n\n return undefined;\n }\n\n return restyle(next);\n })\n .catch(() => undefined);\n };\n vector.recut = () => {\n requests.abortAll();\n refresh();\n };\n vector.styled = state.renderer.then(({ layers: list }) => {\n if (!context.destroyed()) vector.setSublayers(sublayers(state.own ?? list));\n });\n // Reported by the style's `ready`\n vector.styled.catch(() => undefined);\n\n // While the camera moves, the tiles follow it (as the labels do: a long drag or flight does not leave the view of\n // its start drawn)\n context.followView(vector, update, requests, update);\n\n return vector;\n};\n"]}
@@ -18,6 +18,7 @@ import type { VectorLayer } from '../layers/vectors.ts';
18
18
  import type { GeoMap } from '../map.ts';
19
19
  import type { LabelCandidate, Style, StyleLayer } from './vectorstyle.ts';
20
20
  import { type VectorExtrusionOptions } from './vectortiles/extrusions.ts';
21
+ import { type FurnitureOptions } from './vectortiles/furniture.ts';
21
22
  import { type LabelsOptions, size, tileLabels } from './vectortiles/labels.ts';
22
23
  import { type LampsOptions } from './vectortiles/lamps.ts';
23
24
  import { type StreetWindLayer, type StreetWindOptions } from './vectortiles/street-wind.ts';
@@ -77,9 +78,8 @@ export declare class VectorTiles {
77
78
  /** Prefix of the names of its sprites' images among the map's icons */
78
79
  private get iconPrefix();
79
80
  private request;
80
- /** Sends a renderer of these layers to every worker (again under `again`, restyled), with the style's sprites if it
81
- * `draws` the tiles into images with patterns (the raster path: the others take their images in the page); returns
82
- * its key */
81
+ /** Sends a renderer of these layers to every worker (`again`: under that key, restyled), with the style's sprites if
82
+ * it `draws` the tiles into images with patterns (the raster path: the others take their images in the page) */
83
83
  private renderer;
84
84
  /**
85
85
  * A raster layer drawing the style's fills, lines and circles (or those `layers` keeps, then `extraLayers`, of the
@@ -133,6 +133,14 @@ export declare class VectorTiles {
133
133
  * The models load the engine with 3D Tiles.
134
134
  */
135
135
  lamps(options?: LampsOptions): ModelLayer;
136
+ /**
137
+ * The street furniture as 3D models, from OpenMapTiles' points of interest of the street: bus shelters at the bus
138
+ * stops, waste baskets, post boxes, drinking fountains (Wallace's in Paris), bicycle racks, each facing its street;
139
+ * benches along the pedestrian streets and the paths of the parks and gardens. Placed by the workers, one instanced
140
+ * draw a kind, all of them near the camera and fewer away from it. The layer returned holds the other kinds' (its
141
+ * `companions`); removed with it
142
+ */
143
+ furniture(options?: FurnitureOptions): ModelLayer;
136
144
  /**
137
145
  * A layer drawing the style's fills, lines and buildings (or those `layers` keeps; backgrounds as fills, the
138
146
  * `fill-extrusion` layers raised into buildings by their height and base height) as geometry instead of images: the
@@ -163,9 +171,11 @@ export declare class VectorTiles {
163
171
  labels(options?: LabelsOptions): SymbolLayer<LabelCandidate>;
164
172
  /**
165
173
  * Makes a layer's tiles follow the view: `update` now and where the camera stops (`moveend`), `moving` every
166
- * `VECTOR_MOVE_REFRESH_MS` while it moves; the `requests` aborted when destroyed
174
+ * `VECTOR_MOVE_REFRESH_MS` while it moves; the `requests` aborted when destroyed or the layer removed
167
175
  */
168
176
  private followView;
177
+ /** Calls `stop` when destroyed or once `layer` is removed, whichever comes first */
178
+ private stopWith;
169
179
  /** Stops its workers' work and removes its raster and label layers from the map (those still there) */
170
180
  destroy(): void;
171
181
  }
@@ -13,6 +13,7 @@
13
13
  */
14
14
  import { loadSprites, readPixels, spriteSources } from "../layers/icons.js";
15
15
  import { extrusions } from "./vectortiles/extrusions.js";
16
+ import { furniture } from "./vectortiles/furniture.js";
16
17
  import { labels, size, tileLabels } from "./vectortiles/labels.js";
17
18
  import { lamps } from "./vectortiles/lamps.js";
18
19
  import { streetWind } from "./vectortiles/street-wind.js";
@@ -75,11 +76,14 @@ export class VectorTiles {
75
76
  this.pool.broadcast(message);
76
77
  },
77
78
  request: (vz, vx, vy, work, signal) => this.request(vz, vx, vy, work, signal),
78
- renderer: (select, extra, again) => this.renderer(select, extra, again),
79
+ renderer: (select, extra, again) => this.renderer(select, extra, { again }),
79
80
  loadSprites: (sprite) => this.loadSprites(sprite),
80
81
  addSprites: () => this.addSprites(),
81
- followView: (update, requests, moving) => {
82
- this.followView(update, requests, moving);
82
+ followView: (layer, update, requests, moving) => {
83
+ this.followView(layer, update, requests, moving);
84
+ },
85
+ stopWith: (layer, stop) => {
86
+ this.stopWith(layer, stop);
83
87
  },
84
88
  };
85
89
  }
@@ -124,12 +128,11 @@ export class VectorTiles {
124
128
  request(vz, vx, vy, work, signal) {
125
129
  if (this.destroyed)
126
130
  return Promise.reject(new DOMException('isard: vector tiles destroyed', 'AbortError'));
127
- return this.pool.request(this.pool.worker(vz, vx, vy), work, this, signal);
131
+ return this.map.track(this.pool.request(this.pool.worker(vz, vx, vy), work, this, signal));
128
132
  }
129
- /** Sends a renderer of these layers to every worker (again under `again`, restyled), with the style's sprites if it
130
- * `draws` the tiles into images with patterns (the raster path: the others take their images in the page); returns
131
- * its key */
132
- async renderer(select, extra, again, draws = false) {
133
+ /** Sends a renderer of these layers to every worker (`again`: under that key, restyled), with the style's sprites if
134
+ * it `draws` the tiles into images with patterns (the raster path: the others take their images in the page) */
135
+ async renderer(select, extra, { again, draws = false } = {}) {
133
136
  const { style, tiles, maxzoom, rasters } = await this.ready;
134
137
  const key = again ?? rendererKey(this.namespace, this.keys++);
135
138
  const layers = [...style.layers.filter(select), ...extra];
@@ -150,7 +153,7 @@ export class VectorTiles {
150
153
  raster(options = {}) {
151
154
  const { layers = () => true, extraLayers = [], size: texture = 512, opacity = 1, before } = options;
152
155
  const drawn = (l) => l.type !== 'symbol' && layers(l);
153
- const renderer = this.renderer(drawn, extraLayers, undefined, true);
156
+ const renderer = this.renderer(drawn, extraLayers, { draws: true });
154
157
  // Its failure is reported by `ready` and each tile
155
158
  renderer.catch(() => undefined);
156
159
  const loader = async (z, x, y, signal) => {
@@ -223,6 +226,16 @@ export class VectorTiles {
223
226
  lamps(options = {}) {
224
227
  return lamps(this.context, options);
225
228
  }
229
+ /**
230
+ * The street furniture as 3D models, from OpenMapTiles' points of interest of the street: bus shelters at the bus
231
+ * stops, waste baskets, post boxes, drinking fountains (Wallace's in Paris), bicycle racks, each facing its street;
232
+ * benches along the pedestrian streets and the paths of the parks and gardens. Placed by the workers, one instanced
233
+ * draw a kind, all of them near the camera and fewer away from it. The layer returned holds the other kinds' (its
234
+ * `companions`); removed with it
235
+ */
236
+ furniture(options = {}) {
237
+ return furniture(this.context, options);
238
+ }
226
239
  /**
227
240
  * A layer drawing the style's fills, lines and buildings (or those `layers` keeps; backgrounds as fills, the
228
241
  * `fill-extrusion` layers raised into buildings by their height and base height) as geometry instead of images: the
@@ -257,9 +270,9 @@ export class VectorTiles {
257
270
  }
258
271
  /**
259
272
  * Makes a layer's tiles follow the view: `update` now and where the camera stops (`moveend`), `moving` every
260
- * `VECTOR_MOVE_REFRESH_MS` while it moves; the `requests` aborted when destroyed
273
+ * `VECTOR_MOVE_REFRESH_MS` while it moves; the `requests` aborted when destroyed or the layer removed
261
274
  */
262
- followView(update, requests, moving) {
275
+ followView(layer, update, requests, moving) {
263
276
  const refresh = () => {
264
277
  update().catch(() => undefined);
265
278
  };
@@ -272,12 +285,27 @@ export class VectorTiles {
272
285
  Promise.resolve(moving()).catch(() => undefined);
273
286
  }, VECTOR_MOVE_REFRESH_MS);
274
287
  };
275
- this.cleanup.push(this.map.on('move', follow), this.map.on('moveend', refresh), () => {
288
+ const [offMove, offEnd] = [this.map.on('move', follow), this.map.on('moveend', refresh)];
289
+ this.stopWith(layer, () => {
290
+ offMove();
291
+ offEnd();
276
292
  clearTimeout(pace.timer);
277
293
  requests.abortAll();
278
294
  });
279
295
  refresh();
280
296
  }
297
+ /** Calls `stop` when destroyed or once `layer` is removed, whichever comes first */
298
+ stopWith(layer, stop) {
299
+ const once = { done: false };
300
+ const run = () => {
301
+ if (once.done)
302
+ return;
303
+ once.done = true;
304
+ stop();
305
+ };
306
+ this.cleanup.push(run);
307
+ layer.whenRemoved.push(run);
308
+ }
281
309
  /** Stops its workers' work and removes its raster and label layers from the map (those still there) */
282
310
  destroy() {
283
311
  if (this.destroyed)
@@ -1 +1 @@
1
- {"version":3,"file":"vectortiles.js","sourceRoot":"","sources":["../../src/basemap/vectortiles.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Vector basemaps from a MapLibre style (OpenFreeMap's Positron by default): the fills, lines, circles and raster\n * layers drawn tile by tile in workers into the raster pool, so that they lie on the relief like any basemap and\n * composite with the hillshade in one pass; and the labels of the style's symbol layers in a symbol layer of their own,\n * kept above the application's layers (as MapLibre's `beforeId: firstSymbol` does), listed by the workers, shaped in\n * the page once per vector tile, placed by the engine.\n *\n * Any subset of the style can be drawn on its own raster layer (`raster({ layers })`), at its own place in the stack:\n * rivers from the basemap's data over a flood layer, for instance, restyled with `extraLayers`.\n *\n * The layers other than the raster ones are made in `vectortiles/` (one module each), from what they use of the\n * instance (`VectorTilesContext`); the style's loading is in `vectortiles/style.ts`.\n */\n\nimport type { ExtrusionLayer } from '../layers/extrusions.ts';\nimport { type LoadedSprite, loadSprites, readPixels, spriteSources } from '../layers/icons.ts';\nimport type { Layer, ModelLayer, RasterLayer } from '../layers/layers.ts';\nimport type { SymbolLayer } from '../layers/symbols.ts';\nimport type { VectorLayer } from '../layers/vectors.ts';\nimport type { GeoMap } from '../map.ts';\nimport type { BasemapWork, Sprite } from '../workers/basemap.worker.ts';\nimport type { LabelCandidate, Style, StyleLayer } from './vectorstyle.ts';\nimport type { Renderer, VectorTilesContext } from './vectortiles/context.ts';\nimport { extrusions, type VectorExtrusionOptions } from './vectortiles/extrusions.ts';\nimport { type LabelsOptions, labels, size, tileLabels } from './vectortiles/labels.ts';\nimport { type LampsOptions, lamps } from './vectortiles/lamps.ts';\nimport type { TileRequests } from './vectortiles/requests.ts';\nimport { type StreetWindLayer, type StreetWindOptions, streetWind } from './vectortiles/street-wind.ts';\nimport {\n type LoadedStyle,\n loadStyle,\n OPENFREEMAP_STYLES,\n PLAN_STYLES,\n styleAttribution,\n VECTOR_BASEMAPS,\n} from './vectortiles/style.ts';\nimport { VECTOR_MOVE_REFRESH_MS } from './vectortiles/tiles.ts';\nimport { type TreesOptions, trees } from './vectortiles/trees.ts';\nimport { dashes, type VectorsOptions, vectors } from './vectortiles/vectors.ts';\nimport { type BasemapWorkers, rendererKey, tilePriority } from './workerpool.ts';\n\n// The names the package and its tests import from here, now made in `vectortiles/`\nexport { dashes, OPENFREEMAP_STYLES, PLAN_STYLES, size, styleAttribution, tileLabels, VECTOR_BASEMAPS };\n\nexport interface VectorTilesOptions {\n /** A style URL or object (default OpenFreeMap's Positron) */\n style?: string | Style;\n /** Workers drawing the tiles (default cores - 1, 1 to 4). The vector tiles of a map share its workers (and their\n * decoded tiles); another count gives these tiles workers of their own */\n workers?: number;\n /** Where to load the worker from, when a bundler does not resolve the default URL (default the map's\n * `basemapWorkerUrl`); another URL than the map's gives these tiles workers of their own */\n workerUrl?: string | URL;\n /** Credits of the tiles, shown while its raster layers are on the map (default: OpenFreeMap's for its styles, the\n * IGN's for PLAN.IGN's) */\n attribution?: string;\n}\n\nexport class VectorTiles {\n private readonly pool: BasemapWorkers;\n /** The pool is this instance's own (a worker count or URL other than the map's): stopped with it */\n private readonly ownPool: boolean;\n /** Prefix of its renderer keys in the pool's workers */\n private readonly namespace: string;\n private destroyed = false;\n private keys = 0;\n /** Renderers sent to the workers, dropped on destroy */\n private readonly renderers: string[] = [];\n private readonly cleanup: (() => void)[] = [];\n /** Credits of its raster layers */\n private readonly attribution: string | undefined;\n /** Its raster and label layers, removed with it */\n private readonly layers: Layer[] = [];\n /** Its first raster layer: the ground its labels follow */\n private ground: RasterLayer | undefined;\n /** What its layers made in `vectortiles/` use of it */\n private readonly context: VectorTilesContext;\n /** The style once loaded, with its source resolved */\n readonly ready: Promise<LoadedStyle>;\n\n /**\n * Its workers are the map's (shared by every `VectorTiles` of the map, a vector tile decoded once for all of them),\n * unless `workers` or `workerUrl` asks for others than the map's: then it has workers of its own\n */\n constructor(\n private readonly map: GeoMap,\n options: VectorTilesOptions = {},\n ) {\n const { pool, own } = map.basemapWorkers(options.workers, options.workerUrl);\n\n this.pool = pool;\n this.ownPool = own;\n this.namespace = pool.namespace();\n\n const style = options.style ?? OPENFREEMAP_STYLES.positron;\n\n this.attribution = options.attribution ?? styleAttribution(style);\n this.ready = loadStyle(style);\n // Reported once here; `ready`, the raster tiles and the labels fail with it\n this.ready.catch((error: unknown) => {\n if (!this.destroyed) console.warn('isard: vector tiles', error);\n });\n this.context = {\n map,\n ready: this.ready,\n layers: this.layers,\n cleanup: this.cleanup,\n iconPrefix: this.iconPrefix,\n destroyed: () => this.destroyed,\n ground: () => this.ground,\n broadcast: (message) => {\n this.pool.broadcast(message);\n },\n request: (vz, vx, vy, work, signal) => this.request(vz, vx, vy, work, signal),\n renderer: (select, extra, again) => this.renderer(select, extra, again),\n loadSprites: (sprite) => this.loadSprites(sprite),\n addSprites: () => this.addSprites(),\n followView: (update, requests, moving) => {\n this.followView(update, requests, moving);\n },\n };\n }\n\n /** The style's sprites (their JSON and their images), loaded once, for the fill patterns and the icons */\n private sprites: Promise<LoadedSprite[]> | undefined;\n\n /** The style's sprites, kept once all of them came: one that failed is asked for again by the next layer */\n private loadSprites(sprite: Style['sprite']): Promise<LoadedSprite[]> {\n if (this.sprites) return this.sprites;\n\n const wanted = spriteSources(sprite).length;\n const loading: Promise<LoadedSprite[]> = loadSprites(sprite)\n .catch(() => [])\n .then((loaded) => {\n if (loaded.length < wanted && this.sprites === loading) {\n console.warn(\n `isard: ${wanted - loaded.length} of the style's sprites not loaded, its icons and patterns missing`,\n );\n this.sprites = undefined;\n }\n\n return loaded;\n });\n\n this.sprites = loading;\n\n return loading;\n }\n\n /** The style's sprites added to the map's icons, once */\n private spritesAdded: Promise<void> | undefined;\n\n /** The style's sprites among the map's icons (under `iconPrefix`), added once: the labels' icons, the fills'\n * patterns */\n private addSprites(): Promise<void> {\n this.spritesAdded ??= this.ready.then(async ({ style }) => {\n if (!style.sprite) return;\n (await this.loadSprites(style.sprite)).forEach((sprite) => {\n if (!this.destroyed) this.map.icons.addSprite(this.iconPrefix, sprite.icons, () => readPixels(sprite.image));\n });\n });\n\n return this.spritesAdded;\n }\n\n /** Prefix of the names of its sprites' images among the map's icons */\n private get iconPrefix(): string {\n return `${this.namespace}/`;\n }\n\n private request(vz: number, vx: number, vy: number, work: BasemapWork, signal?: AbortSignal) {\n if (this.destroyed) return Promise.reject(new DOMException('isard: vector tiles destroyed', 'AbortError'));\n\n return this.pool.request(this.pool.worker(vz, vx, vy), work, this, signal);\n }\n\n /** Sends a renderer of these layers to every worker (again under `again`, restyled), with the style's sprites if it\n * `draws` the tiles into images with patterns (the raster path: the others take their images in the page); returns\n * its key */\n private async renderer(\n select: (layer: StyleLayer) => boolean,\n extra: StyleLayer[],\n again?: string,\n draws = false,\n ): Promise<Renderer> {\n const { style, tiles, maxzoom, rasters } = await this.ready;\n const key = again ?? rendererKey(this.namespace, this.keys++);\n const layers = [...style.layers.filter(select), ...extra];\n const patterns = draws && layers.some((l) => l.paint?.['fill-pattern'] !== undefined);\n // The images are downloaded once, copied to each worker\n const sprites: Sprite[] = patterns && style.sprite ? await this.loadSprites(style.sprite) : [];\n\n if (this.destroyed) throw new DOMException('isard: vector tiles destroyed', 'AbortError');\n this.pool.broadcast({ type: 'init', key, tiles, maxzoom, layers, rasters, ...(sprites.length ? { sprites } : {}) });\n if (!again) this.renderers.push(key);\n\n return { key, maxzoom, layers };\n }\n\n /**\n * A raster layer drawing the style's fills, lines and circles (or those `layers` keeps, then `extraLayers`, of the\n * same source); `size`: texture size of its tiles (512 by default: sharp lines)\n */\n raster(\n options: {\n layers?: (layer: StyleLayer) => boolean;\n extraLayers?: StyleLayer[];\n size?: number;\n opacity?: number;\n minZoom?: number;\n maxZoom?: number;\n before?: Parameters<GeoMap['addRaster']>[0]['before'];\n } = {},\n ): RasterLayer {\n const { layers = () => true, extraLayers = [], size: texture = 512, opacity = 1, before } = options;\n const drawn = (l: StyleLayer) => l.type !== 'symbol' && layers(l);\n const renderer = this.renderer(drawn, extraLayers, undefined, true);\n\n // Its failure is reported by `ready` and each tile\n renderer.catch(() => undefined);\n\n const loader = async (z: number, x: number, y: number, signal: AbortSignal) => {\n const { key, maxzoom } = await renderer;\n // The vector tile it is drawn from (see the worker)\n const vz = Math.max(0, Math.min(z - 1, maxzoom));\n const shift = z - vz;\n const priority = tilePriority(z, x, y, this.map.getCamera());\n const response = await this.request(\n vz,\n x >> shift,\n y >> shift,\n { type: 'render', key, z, x, y, size: texture, priority },\n signal,\n );\n\n return 'image' in response ? response.image : null;\n };\n const layer = this.map.addRaster({\n url: '',\n size: texture,\n opacity,\n minZoom: options.minZoom ?? 0,\n maxZoom: options.maxZoom ?? 20,\n loader,\n ...(this.attribution ? { attribution: this.attribution } : {}),\n ...(before ? { before } : {}),\n });\n\n this.layers.push(layer);\n this.ground ??= layer;\n\n return layer;\n }\n\n /**\n * An extrusion layer of the polygons of the style's fill layers that `layers` keeps (by default its buildings: the\n * fill or fill-extrusion layers of PLAN IGN's `bati_surf` or OpenMapTiles' `building`), raised by the style\n * given (`height`, `base`, `color`, `ramp`…; the properties of the tiles' features). Its tiles follow the view: at\n * the source's deepest level, the `maxTiles` nearest to the center, from `minZoom` on (15 by default); the tiles\n * leaving the view are dropped.\n */\n extrusions<P = Record<string, unknown>>(options: VectorExtrusionOptions<P> = {}): ExtrusionLayer<P> {\n return extrusions<P>(this.context, options);\n }\n\n /**\n * The wind through the streets around the view, as particles at street level (`height`, default 3 metres) between\n * the style's buildings (`layers`, default its `building` and `bati_surf` layers): their footprints laid on a grid of\n * `cell` metres (default 4) over a square of `size` metres (default 1200) around the view's center, the flow of the\n * air round them a potential flow (it goes round the blocks and faster through the narrow streets; no wake behind\n * them), computed in a worker by the grid module from street level (`minZoom`, default 15) and again when the view\n * leaves the square's middle. `wind` is the wind far away (east and north, m/s, default a light breeze from the\n * south-west); `setWind` changes it at once (the flow is linear in it: nothing computed again), from a model's hour\n * (`windAt`) for instance; `computed` resolves once the first square's flow is there. The other options are the flow\n * layer's (`addFlow`)\n */\n streetWind(options: StreetWindOptions = {}): StreetWindLayer {\n return streetWind(this.context, options);\n }\n\n /**\n * Trees on the style's woods, forests and grass (or the fill layers `layers` keeps) as 3D models, from street level\n * (`minZoom`, default 15): the workers scatter them over the polygons of the vector tiles around the view, `spacing`\n * metres apart (by style layer: 9 in woods, 25 on grass, by default) on a jittered grid, the same trees whenever a\n * tile comes back; the engine draws them all in one instanced draw, on the relief. A low-poly tree by default (its\n * `colors`), or your own glTF (`url`, `data`, about 10 metres high, standing on its origin). Dense around the\n * view's center, fewer and fewer away from it (as the camera moves too), at most `maxInstances` drawn (default\n * 25000); at most `maxTiles` tiles (default 9) and `maxTrees` trees in each (default 30000). The models load the\n * engine with 3D Tiles.\n */\n trees(options: TreesOptions = {}): ModelLayer {\n return trees(this.context, options);\n }\n\n /**\n * Street lamps along the style's streets (the road line layers, or those `layers` keeps) as 3D models, from street\n * level (`minZoom`, default 16): the workers place them `spacing` metres apart (default 30) along each street, every\n * other one on its other side, as far from its middle as its class says; their heads lit at night (`light`). All of\n * them near the ground under the camera, fewer and fewer away from it, at most `maxInstances` drawn (default 15000).\n * The models load the engine with 3D Tiles.\n */\n lamps(options: LampsOptions = {}): ModelLayer {\n return lamps(this.context, options);\n }\n\n /**\n * A layer drawing the style's fills, lines and buildings (or those `layers` keeps; backgrounds as fills, the\n * `fill-extrusion` layers raised into buildings by their height and base height) as geometry instead of images: the\n * workers cut the vector tiles in view into polygons and lines, which the engine draws on the globe and the relief,\n * in the style's order, each style layer over its zoom range. Sharp at any zoom\n * and pitch, picked by feature (`pick` gives its properties and style layer), restyled without cutting the tiles\n * again (`setPaintProperty`, `setLayoutProperty`). Its tiles follow the view, while it moves too, coarser far away in a\n * tilted view, and those leaving it stay until the ones replacing them are there; past the source's deepest level,\n * cut again from its tiles down to level 18 (overzoom: their styles those of their level; a filter reading the zoom\n * holds at the whole zoom under the camera's, as MapLibre evaluates it). The fills' outlines are drawn one\n * pixel wide, the lines' ends as their `line-cap` says, their joins as their `line-join` says (and `line-miter-limit`),\n * offset by `line-offset`; the colors follow the camera's zoom; the fills', lines' and buildings' patterns from the\n * style's sprite (the fills' over the relief too; on the globe, their average color there), the circle layers' points\n * as circles facing the screen, the lines' blur, the fills' and lines' translations. The buildings' roofs (`roofs`)\n * as their data says (`roof:shape`, `roof:height`; flat without, the default), generated from their outline where\n * they have none (`'generated'`), or all flat. `raster` stays the lighter path for heavy styles and small devices.\n * At night (`setSun`) the line layers `streets` keeps glow (by default those whose id names\n * a road, not its casing, a railway, a path or a tunnel).\n */\n vectors(options: VectorsOptions = {}): VectorLayer {\n return vectors(this.context, options);\n }\n\n /**\n * A symbol layer with the labels of the style's symbol layers (or those `layers` keeps), updated as the view\n * moves: the labels of the vector tiles in view, the higher style layers placed first. With a raster layer of\n * the style (`raster`), the tiles follow the levels the ground is drawn at: a tilted view takes coarser tiles far\n * away, with the few labels of a lower zoom, as near the camera it takes the fine ones. Without, the tiles around\n * the center at the zoom of the view. It stays above the layers added after it unless one is moved over it.\n */\n labels(options: LabelsOptions = {}): SymbolLayer<LabelCandidate> {\n return labels(this.context, options);\n }\n\n /**\n * Makes a layer's tiles follow the view: `update` now and where the camera stops (`moveend`), `moving` every\n * `VECTOR_MOVE_REFRESH_MS` while it moves; the `requests` aborted when destroyed\n */\n private followView(update: () => Promise<unknown>, requests: TileRequests, moving: () => unknown): void {\n const refresh = () => {\n update().catch(() => undefined);\n };\n const pace = { timer: 0 };\n const follow = () => {\n if (pace.timer) return;\n pace.timer = window.setTimeout(() => {\n pace.timer = 0;\n Promise.resolve(moving()).catch(() => undefined);\n }, VECTOR_MOVE_REFRESH_MS);\n };\n\n this.cleanup.push(this.map.on('move', follow), this.map.on('moveend', refresh), () => {\n clearTimeout(pace.timer);\n requests.abortAll();\n });\n refresh();\n }\n\n /** Stops its workers' work and removes its raster and label layers from the map (those still there) */\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.cleanup.forEach((off) => {\n off();\n });\n this.cleanup.length = 0;\n this.layers.forEach((layer) => {\n if (this.map.hasLayer(layer)) layer.remove();\n });\n this.layers.length = 0;\n this.map.dropVectorTiles(this);\n // The page's copy of the sprites (the workers have theirs), and their icons\n this.sprites\n ?.then((sprites) => {\n sprites.forEach((sprite) => {\n sprite.image.close();\n });\n this.map.icons.remove(this.iconPrefix, true);\n })\n .catch(() => undefined);\n if (this.ownPool) {\n this.pool.terminate();\n } else {\n // Shared workers: only its requests stop and its renderers go\n this.pool.cancel(this);\n this.renderers.forEach((key) => {\n this.pool.broadcast({ type: 'drop', key });\n });\n }\n this.renderers.length = 0;\n }\n}\n"]}
1
+ {"version":3,"file":"vectortiles.js","sourceRoot":"","sources":["../../src/basemap/vectortiles.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Vector basemaps from a MapLibre style (OpenFreeMap's Positron by default): the fills, lines, circles and raster\n * layers drawn tile by tile in workers into the raster pool, so that they lie on the relief like any basemap and\n * composite with the hillshade in one pass; and the labels of the style's symbol layers in a symbol layer of their own,\n * kept above the application's layers (as MapLibre's `beforeId: firstSymbol` does), listed by the workers, shaped in\n * the page once per vector tile, placed by the engine.\n *\n * Any subset of the style can be drawn on its own raster layer (`raster({ layers })`), at its own place in the stack:\n * rivers from the basemap's data over a flood layer, for instance, restyled with `extraLayers`.\n *\n * The layers other than the raster ones are made in `vectortiles/` (one module each), from what they use of the\n * instance (`VectorTilesContext`); the style's loading is in `vectortiles/style.ts`.\n */\n\nimport type { ExtrusionLayer } from '../layers/extrusions.ts';\nimport { type LoadedSprite, loadSprites, readPixels, spriteSources } from '../layers/icons.ts';\nimport type { Layer, ModelLayer, RasterLayer } from '../layers/layers.ts';\nimport type { SymbolLayer } from '../layers/symbols.ts';\nimport type { VectorLayer } from '../layers/vectors.ts';\nimport type { GeoMap } from '../map.ts';\nimport type { BasemapWork, Sprite } from '../workers/basemap.worker.ts';\nimport type { LabelCandidate, Style, StyleLayer } from './vectorstyle.ts';\nimport type { Renderer, VectorTilesContext } from './vectortiles/context.ts';\nimport { extrusions, type VectorExtrusionOptions } from './vectortiles/extrusions.ts';\nimport { type FurnitureOptions, furniture } from './vectortiles/furniture.ts';\nimport { type LabelsOptions, labels, size, tileLabels } from './vectortiles/labels.ts';\nimport { type LampsOptions, lamps } from './vectortiles/lamps.ts';\nimport type { TileRequests } from './vectortiles/requests.ts';\nimport { type StreetWindLayer, type StreetWindOptions, streetWind } from './vectortiles/street-wind.ts';\nimport {\n type LoadedStyle,\n loadStyle,\n OPENFREEMAP_STYLES,\n PLAN_STYLES,\n styleAttribution,\n VECTOR_BASEMAPS,\n} from './vectortiles/style.ts';\nimport { VECTOR_MOVE_REFRESH_MS } from './vectortiles/tiles.ts';\nimport { type TreesOptions, trees } from './vectortiles/trees.ts';\nimport { dashes, type VectorsOptions, vectors } from './vectortiles/vectors.ts';\nimport { type BasemapWorkers, rendererKey, tilePriority } from './workerpool.ts';\n\n// The names the package and its tests import from here, now made in `vectortiles/`\nexport { dashes, OPENFREEMAP_STYLES, PLAN_STYLES, size, styleAttribution, tileLabels, VECTOR_BASEMAPS };\n\nexport interface VectorTilesOptions {\n /** A style URL or object (default OpenFreeMap's Positron) */\n style?: string | Style;\n /** Workers drawing the tiles (default cores - 1, 1 to 4). The vector tiles of a map share its workers (and their\n * decoded tiles); another count gives these tiles workers of their own */\n workers?: number;\n /** Where to load the worker from, when a bundler does not resolve the default URL (default the map's\n * `basemapWorkerUrl`); another URL than the map's gives these tiles workers of their own */\n workerUrl?: string | URL;\n /** Credits of the tiles, shown while its raster layers are on the map (default: OpenFreeMap's for its styles, the\n * IGN's for PLAN.IGN's) */\n attribution?: string;\n}\n\nexport class VectorTiles {\n private readonly pool: BasemapWorkers;\n /** The pool is this instance's own (a worker count or URL other than the map's): stopped with it */\n private readonly ownPool: boolean;\n /** Prefix of its renderer keys in the pool's workers */\n private readonly namespace: string;\n private destroyed = false;\n private keys = 0;\n /** Renderers sent to the workers, dropped on destroy */\n private readonly renderers: string[] = [];\n private readonly cleanup: (() => void)[] = [];\n /** Credits of its raster layers */\n private readonly attribution: string | undefined;\n /** Its raster and label layers, removed with it */\n private readonly layers: Layer[] = [];\n /** Its first raster layer: the ground its labels follow */\n private ground: RasterLayer | undefined;\n /** What its layers made in `vectortiles/` use of it */\n private readonly context: VectorTilesContext;\n /** The style once loaded, with its source resolved */\n readonly ready: Promise<LoadedStyle>;\n\n /**\n * Its workers are the map's (shared by every `VectorTiles` of the map, a vector tile decoded once for all of them),\n * unless `workers` or `workerUrl` asks for others than the map's: then it has workers of its own\n */\n constructor(\n private readonly map: GeoMap,\n options: VectorTilesOptions = {},\n ) {\n const { pool, own } = map.basemapWorkers(options.workers, options.workerUrl);\n\n this.pool = pool;\n this.ownPool = own;\n this.namespace = pool.namespace();\n\n const style = options.style ?? OPENFREEMAP_STYLES.positron;\n\n this.attribution = options.attribution ?? styleAttribution(style);\n this.ready = loadStyle(style);\n // Reported once here; `ready`, the raster tiles and the labels fail with it\n this.ready.catch((error: unknown) => {\n if (!this.destroyed) console.warn('isard: vector tiles', error);\n });\n this.context = {\n map,\n ready: this.ready,\n layers: this.layers,\n cleanup: this.cleanup,\n iconPrefix: this.iconPrefix,\n destroyed: () => this.destroyed,\n ground: () => this.ground,\n broadcast: (message) => {\n this.pool.broadcast(message);\n },\n request: (vz, vx, vy, work, signal) => this.request(vz, vx, vy, work, signal),\n renderer: (select, extra, again) => this.renderer(select, extra, { again }),\n loadSprites: (sprite) => this.loadSprites(sprite),\n addSprites: () => this.addSprites(),\n followView: (layer, update, requests, moving) => {\n this.followView(layer, update, requests, moving);\n },\n stopWith: (layer, stop) => {\n this.stopWith(layer, stop);\n },\n };\n }\n\n /** The style's sprites (their JSON and their images), loaded once, for the fill patterns and the icons */\n private sprites: Promise<LoadedSprite[]> | undefined;\n\n /** The style's sprites, kept once all of them came: one that failed is asked for again by the next layer */\n private loadSprites(sprite: Style['sprite']): Promise<LoadedSprite[]> {\n if (this.sprites) return this.sprites;\n\n const wanted = spriteSources(sprite).length;\n const loading: Promise<LoadedSprite[]> = loadSprites(sprite)\n .catch(() => [])\n .then((loaded) => {\n if (loaded.length < wanted && this.sprites === loading) {\n console.warn(\n `isard: ${wanted - loaded.length} of the style's sprites not loaded, its icons and patterns missing`,\n );\n this.sprites = undefined;\n }\n\n return loaded;\n });\n\n this.sprites = loading;\n\n return loading;\n }\n\n /** The style's sprites added to the map's icons, once */\n private spritesAdded: Promise<void> | undefined;\n\n /** The style's sprites among the map's icons (under `iconPrefix`), added once: the labels' icons, the fills'\n * patterns */\n private addSprites(): Promise<void> {\n this.spritesAdded ??= this.ready.then(async ({ style }) => {\n if (!style.sprite) return;\n (await this.loadSprites(style.sprite)).forEach((sprite) => {\n if (!this.destroyed) this.map.icons.addSprite(this.iconPrefix, sprite.icons, () => readPixels(sprite.image));\n });\n });\n\n return this.spritesAdded;\n }\n\n /** Prefix of the names of its sprites' images among the map's icons */\n private get iconPrefix(): string {\n return `${this.namespace}/`;\n }\n\n private request(vz: number, vx: number, vy: number, work: BasemapWork, signal?: AbortSignal) {\n if (this.destroyed) return Promise.reject(new DOMException('isard: vector tiles destroyed', 'AbortError'));\n\n return this.map.track(this.pool.request(this.pool.worker(vz, vx, vy), work, this, signal));\n }\n\n /** Sends a renderer of these layers to every worker (`again`: under that key, restyled), with the style's sprites if\n * it `draws` the tiles into images with patterns (the raster path: the others take their images in the page) */\n private async renderer(\n select: (layer: StyleLayer) => boolean,\n extra: StyleLayer[],\n { again, draws = false }: { again?: string | undefined; draws?: boolean } = {},\n ): Promise<Renderer> {\n const { style, tiles, maxzoom, rasters } = await this.ready;\n const key = again ?? rendererKey(this.namespace, this.keys++);\n const layers = [...style.layers.filter(select), ...extra];\n const patterns = draws && layers.some((l) => l.paint?.['fill-pattern'] !== undefined);\n // The images are downloaded once, copied to each worker\n const sprites: Sprite[] = patterns && style.sprite ? await this.loadSprites(style.sprite) : [];\n\n if (this.destroyed) throw new DOMException('isard: vector tiles destroyed', 'AbortError');\n this.pool.broadcast({ type: 'init', key, tiles, maxzoom, layers, rasters, ...(sprites.length ? { sprites } : {}) });\n if (!again) this.renderers.push(key);\n\n return { key, maxzoom, layers };\n }\n\n /**\n * A raster layer drawing the style's fills, lines and circles (or those `layers` keeps, then `extraLayers`, of the\n * same source); `size`: texture size of its tiles (512 by default: sharp lines)\n */\n raster(\n options: {\n layers?: (layer: StyleLayer) => boolean;\n extraLayers?: StyleLayer[];\n size?: number;\n opacity?: number;\n minZoom?: number;\n maxZoom?: number;\n before?: Parameters<GeoMap['addRaster']>[0]['before'];\n } = {},\n ): RasterLayer {\n const { layers = () => true, extraLayers = [], size: texture = 512, opacity = 1, before } = options;\n const drawn = (l: StyleLayer) => l.type !== 'symbol' && layers(l);\n const renderer = this.renderer(drawn, extraLayers, { draws: true });\n\n // Its failure is reported by `ready` and each tile\n renderer.catch(() => undefined);\n\n const loader = async (z: number, x: number, y: number, signal: AbortSignal) => {\n const { key, maxzoom } = await renderer;\n // The vector tile it is drawn from (see the worker)\n const vz = Math.max(0, Math.min(z - 1, maxzoom));\n const shift = z - vz;\n const priority = tilePriority(z, x, y, this.map.getCamera());\n const response = await this.request(\n vz,\n x >> shift,\n y >> shift,\n { type: 'render', key, z, x, y, size: texture, priority },\n signal,\n );\n\n return 'image' in response ? response.image : null;\n };\n const layer = this.map.addRaster({\n url: '',\n size: texture,\n opacity,\n minZoom: options.minZoom ?? 0,\n maxZoom: options.maxZoom ?? 20,\n loader,\n ...(this.attribution ? { attribution: this.attribution } : {}),\n ...(before ? { before } : {}),\n });\n\n this.layers.push(layer);\n this.ground ??= layer;\n\n return layer;\n }\n\n /**\n * An extrusion layer of the polygons of the style's fill layers that `layers` keeps (by default its buildings: the\n * fill or fill-extrusion layers of PLAN IGN's `bati_surf` or OpenMapTiles' `building`), raised by the style\n * given (`height`, `base`, `color`, `ramp`…; the properties of the tiles' features). Its tiles follow the view: at\n * the source's deepest level, the `maxTiles` nearest to the center, from `minZoom` on (15 by default); the tiles\n * leaving the view are dropped.\n */\n extrusions<P = Record<string, unknown>>(options: VectorExtrusionOptions<P> = {}): ExtrusionLayer<P> {\n return extrusions<P>(this.context, options);\n }\n\n /**\n * The wind through the streets around the view, as particles at street level (`height`, default 3 metres) between\n * the style's buildings (`layers`, default its `building` and `bati_surf` layers): their footprints laid on a grid of\n * `cell` metres (default 4) over a square of `size` metres (default 1200) around the view's center, the flow of the\n * air round them a potential flow (it goes round the blocks and faster through the narrow streets; no wake behind\n * them), computed in a worker by the grid module from street level (`minZoom`, default 15) and again when the view\n * leaves the square's middle. `wind` is the wind far away (east and north, m/s, default a light breeze from the\n * south-west); `setWind` changes it at once (the flow is linear in it: nothing computed again), from a model's hour\n * (`windAt`) for instance; `computed` resolves once the first square's flow is there. The other options are the flow\n * layer's (`addFlow`)\n */\n streetWind(options: StreetWindOptions = {}): StreetWindLayer {\n return streetWind(this.context, options);\n }\n\n /**\n * Trees on the style's woods, forests and grass (or the fill layers `layers` keeps) as 3D models, from street level\n * (`minZoom`, default 15): the workers scatter them over the polygons of the vector tiles around the view, `spacing`\n * metres apart (by style layer: 9 in woods, 25 on grass, by default) on a jittered grid, the same trees whenever a\n * tile comes back; the engine draws them all in one instanced draw, on the relief. A low-poly tree by default (its\n * `colors`), or your own glTF (`url`, `data`, about 10 metres high, standing on its origin). Dense around the\n * view's center, fewer and fewer away from it (as the camera moves too), at most `maxInstances` drawn (default\n * 25000); at most `maxTiles` tiles (default 9) and `maxTrees` trees in each (default 30000). The models load the\n * engine with 3D Tiles.\n */\n trees(options: TreesOptions = {}): ModelLayer {\n return trees(this.context, options);\n }\n\n /**\n * Street lamps along the style's streets (the road line layers, or those `layers` keeps) as 3D models, from street\n * level (`minZoom`, default 16): the workers place them `spacing` metres apart (default 30) along each street, every\n * other one on its other side, as far from its middle as its class says; their heads lit at night (`light`). All of\n * them near the ground under the camera, fewer and fewer away from it, at most `maxInstances` drawn (default 15000).\n * The models load the engine with 3D Tiles.\n */\n lamps(options: LampsOptions = {}): ModelLayer {\n return lamps(this.context, options);\n }\n\n /**\n * The street furniture as 3D models, from OpenMapTiles' points of interest of the street: bus shelters at the bus\n * stops, waste baskets, post boxes, drinking fountains (Wallace's in Paris), bicycle racks, each facing its street;\n * benches along the pedestrian streets and the paths of the parks and gardens. Placed by the workers, one instanced\n * draw a kind, all of them near the camera and fewer away from it. The layer returned holds the other kinds' (its\n * `companions`); removed with it\n */\n furniture(options: FurnitureOptions = {}): ModelLayer {\n return furniture(this.context, options);\n }\n\n /**\n * A layer drawing the style's fills, lines and buildings (or those `layers` keeps; backgrounds as fills, the\n * `fill-extrusion` layers raised into buildings by their height and base height) as geometry instead of images: the\n * workers cut the vector tiles in view into polygons and lines, which the engine draws on the globe and the relief,\n * in the style's order, each style layer over its zoom range. Sharp at any zoom\n * and pitch, picked by feature (`pick` gives its properties and style layer), restyled without cutting the tiles\n * again (`setPaintProperty`, `setLayoutProperty`). Its tiles follow the view, while it moves too, coarser far away in a\n * tilted view, and those leaving it stay until the ones replacing them are there; past the source's deepest level,\n * cut again from its tiles down to level 18 (overzoom: their styles those of their level; a filter reading the zoom\n * holds at the whole zoom under the camera's, as MapLibre evaluates it). The fills' outlines are drawn one\n * pixel wide, the lines' ends as their `line-cap` says, their joins as their `line-join` says (and `line-miter-limit`),\n * offset by `line-offset`; the colors follow the camera's zoom; the fills', lines' and buildings' patterns from the\n * style's sprite (the fills' over the relief too; on the globe, their average color there), the circle layers' points\n * as circles facing the screen, the lines' blur, the fills' and lines' translations. The buildings' roofs (`roofs`)\n * as their data says (`roof:shape`, `roof:height`; flat without, the default), generated from their outline where\n * they have none (`'generated'`), or all flat. `raster` stays the lighter path for heavy styles and small devices.\n * At night (`setSun`) the line layers `streets` keeps glow (by default those whose id names\n * a road, not its casing, a railway, a path or a tunnel).\n */\n vectors(options: VectorsOptions = {}): VectorLayer {\n return vectors(this.context, options);\n }\n\n /**\n * A symbol layer with the labels of the style's symbol layers (or those `layers` keeps), updated as the view\n * moves: the labels of the vector tiles in view, the higher style layers placed first. With a raster layer of\n * the style (`raster`), the tiles follow the levels the ground is drawn at: a tilted view takes coarser tiles far\n * away, with the few labels of a lower zoom, as near the camera it takes the fine ones. Without, the tiles around\n * the center at the zoom of the view. It stays above the layers added after it unless one is moved over it.\n */\n labels(options: LabelsOptions = {}): SymbolLayer<LabelCandidate> {\n return labels(this.context, options);\n }\n\n /**\n * Makes a layer's tiles follow the view: `update` now and where the camera stops (`moveend`), `moving` every\n * `VECTOR_MOVE_REFRESH_MS` while it moves; the `requests` aborted when destroyed or the layer removed\n */\n private followView(\n layer: Layer,\n update: () => Promise<unknown>,\n requests: TileRequests,\n moving: () => unknown,\n ): void {\n const refresh = () => {\n update().catch(() => undefined);\n };\n const pace = { timer: 0 };\n const follow = () => {\n if (pace.timer) return;\n pace.timer = window.setTimeout(() => {\n pace.timer = 0;\n Promise.resolve(moving()).catch(() => undefined);\n }, VECTOR_MOVE_REFRESH_MS);\n };\n const [offMove, offEnd] = [this.map.on('move', follow), this.map.on('moveend', refresh)];\n\n this.stopWith(layer, () => {\n offMove();\n offEnd();\n clearTimeout(pace.timer);\n requests.abortAll();\n });\n refresh();\n }\n\n /** Calls `stop` when destroyed or once `layer` is removed, whichever comes first */\n private stopWith(layer: Layer, stop: () => void): void {\n const once = { done: false };\n const run = () => {\n if (once.done) return;\n once.done = true;\n stop();\n };\n\n this.cleanup.push(run);\n layer.whenRemoved.push(run);\n }\n\n /** Stops its workers' work and removes its raster and label layers from the map (those still there) */\n destroy(): void {\n if (this.destroyed) return;\n this.destroyed = true;\n this.cleanup.forEach((off) => {\n off();\n });\n this.cleanup.length = 0;\n this.layers.forEach((layer) => {\n if (this.map.hasLayer(layer)) layer.remove();\n });\n this.layers.length = 0;\n this.map.dropVectorTiles(this);\n // The page's copy of the sprites (the workers have theirs), and their icons\n this.sprites\n ?.then((sprites) => {\n sprites.forEach((sprite) => {\n sprite.image.close();\n });\n this.map.icons.remove(this.iconPrefix, true);\n })\n .catch(() => undefined);\n if (this.ownPool) {\n this.pool.terminate();\n } else {\n // Shared workers: only its requests stop and its renderers go\n this.pool.cancel(this);\n this.renderers.forEach((key) => {\n this.pool.broadcast({ type: 'drop', key });\n });\n }\n this.renderers.length = 0;\n }\n}\n"]}
@@ -5,8 +5,7 @@
5
5
  import { epsgCode, isGeographic } from "../data/crs.js";
6
6
  import { child, children, childText, parseXml } from "../data/xml.js";
7
7
  import { withHeaders } from "../engine/requests.js";
8
- /** Metres per degree, as WMTS counts the scale of a grid in degrees (OGC 07-057r7, 6.1) */
9
- const METRES_PER_DEGREE = (2 * Math.PI * 6378137) / 360;
8
+ import { METRES_PER_DEGREE } from "../util/geo.js";
10
9
  /** The size of a pixel by which WMTS turns scale denominators into resolutions, metres */
11
10
  const PIXEL = 0.00028;
12
11
  const numbers = (text) => (text ?? '').trim().split(/\s+/).map(Number);
@@ -29,6 +28,7 @@ export const parseWmtsGrid = (xml, layer, matrixSet) => {
29
28
  const geographic = isGeographic(crs);
30
29
  // EPSG's geographic CRSs have their latitude first (CRS:84 and the IGN's WGS84G do not)
31
30
  const latFirst = geographic && epsgCode(crs) === 4326 && /EPSG/i.test(crs);
31
+ // Metres per degree, as WMTS counts the scale of a grid in degrees (OGC 07-057r7, 6.1)
32
32
  const unit = geographic ? METRES_PER_DEGREE : 1;
33
33
  const limits = new Map();
34
34
  children(child(link, 'TileMatrixSetLimits'), 'TileMatrixLimits').forEach((l) => {
@@ -1 +1 @@
1
- {"version":3,"file":"wmts.js","sourceRoot":"","sources":["../../src/basemap/wmts.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The tile grid of a WMTS layer, read from the service's capabilities: its tile matrix set (CRS, levels, origin, tile\n * sizes), the layer's limits in it and its extent, for `addRaster({ url, grid })`.\n */\nimport { epsgCode, isGeographic } from '../data/crs.ts';\nimport { child, children, childText, parseXml } from '../data/xml.ts';\nimport { withHeaders } from '../engine/requests.ts';\nimport type { TileGrid, TileMatrix } from './grid.ts';\n\n/** Metres per degree, as WMTS counts the scale of a grid in degrees (OGC 07-057r7, 6.1) */\nconst METRES_PER_DEGREE = (2 * Math.PI * 6378137) / 360;\n/** The size of a pixel by which WMTS turns scale denominators into resolutions, metres */\nconst PIXEL = 0.00028;\n\nconst numbers = (text: string | undefined) => (text ?? '').trim().split(/\\s+/).map(Number);\n\n/**\n * The tile grid of `layer` in the capabilities document `xml`: its tile matrix set `matrixSet` (default the layer's\n * first), with the layer's tile limits and longitude-latitude extent. Throws if the layer or the set is missing\n */\nexport const parseWmtsGrid = (xml: string, layer: string, matrixSet?: string): TileGrid => {\n const contents = child(parseXml(xml), 'Contents');\n const entry = children(contents, 'Layer').find((l) => childText(l, 'Identifier') === layer);\n\n if (!entry) throw new Error(`isard: no WMTS layer ${layer}`);\n\n const links = children(entry, 'TileMatrixSetLink');\n const link = matrixSet === undefined ? links[0] : links.find((l) => childText(l, 'TileMatrixSet') === matrixSet);\n const name = childText(link, 'TileMatrixSet');\n const set = children(contents, 'TileMatrixSet').find((s) => childText(s, 'Identifier') === name);\n\n if (!name || !set) throw new Error(`isard: no tile matrix set ${matrixSet ?? ''} for the WMTS layer ${layer}`);\n\n const crs = childText(set, 'SupportedCRS') ?? '';\n const geographic = isGeographic(crs);\n // EPSG's geographic CRSs have their latitude first (CRS:84 and the IGN's WGS84G do not)\n const latFirst = geographic && epsgCode(crs) === 4326 && /EPSG/i.test(crs);\n const unit = geographic ? METRES_PER_DEGREE : 1;\n const limits = new Map<string, TileMatrix['limits']>();\n\n children(child(link, 'TileMatrixSetLimits'), 'TileMatrixLimits').forEach((l) => {\n const limit = (k: string) => Number(childText(l, k));\n\n limits.set(childText(l, 'TileMatrix') ?? '', [\n limit('MinTileCol'),\n limit('MinTileRow'),\n limit('MaxTileCol'),\n limit('MaxTileRow'),\n ]);\n });\n\n const matrices = children(set, 'TileMatrix').map((m): TileMatrix => {\n const id = childText(m, 'Identifier') ?? '';\n const [a = 0, b = 0] = numbers(childText(m, 'TopLeftCorner'));\n const limit = limits.get(id);\n\n return {\n id,\n resolution: (Number(childText(m, 'ScaleDenominator')) * PIXEL) / unit,\n origin: latFirst ? [b, a] : [a, b],\n tileWidth: Number(childText(m, 'TileWidth') ?? 256),\n tileHeight: Number(childText(m, 'TileHeight') ?? 256),\n matrixWidth: Number(childText(m, 'MatrixWidth') ?? Infinity),\n matrixHeight: Number(childText(m, 'MatrixHeight') ?? Infinity),\n ...(limit ? { limits: limit } : {}),\n };\n });\n // A layer's limits leave out the matrices it does not have\n const served = limits.size > 0 ? matrices.filter((m) => limits.has(String(m.id))) : matrices;\n const box = child(entry, 'WGS84BoundingBox');\n const [west = Number.NaN, south = Number.NaN] = numbers(childText(box, 'LowerCorner'));\n const [east = Number.NaN, north = Number.NaN] = numbers(childText(box, 'UpperCorner'));\n const bounds: [number, number, number, number] = [west, south, east, north];\n\n return {\n crs,\n matrices: served,\n name,\n ...(bounds.every(Number.isFinite) ? { bounds } : {}),\n };\n};\n\n/**\n * The tile grid of a WMTS layer, from the service's capabilities at `capabilities` (fetched with CORS), for\n * `addRaster`: `await wmtsGrid('https://…/wmts?SERVICE=WMTS&REQUEST=GetCapabilities', 'LAYER', 'MATRIXSET')`. The\n * raster's URL writes the matrix set, {z} for the matrix, {x} and {y} for the column and the row\n */\nexport const wmtsGrid = async (\n capabilities: string | URL,\n layer: string,\n matrixSet?: string,\n options: { signal?: AbortSignal } = {},\n): Promise<TileGrid> => {\n const response = await fetch(\n capabilities,\n withHeaders(capabilities, options.signal ? { signal: options.signal } : {}),\n );\n\n if (!response.ok) throw new Error(`isard: ${response.status} for the WMTS capabilities`);\n\n return parseWmtsGrid(await response.text(), layer, matrixSet);\n};\n"]}
1
+ {"version":3,"file":"wmts.js","sourceRoot":"","sources":["../../src/basemap/wmts.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The tile grid of a WMTS layer, read from the service's capabilities: its tile matrix set (CRS, levels, origin, tile\n * sizes), the layer's limits in it and its extent, for `addRaster({ url, grid })`.\n */\nimport { epsgCode, isGeographic } from '../data/crs.ts';\nimport { child, children, childText, parseXml } from '../data/xml.ts';\nimport { withHeaders } from '../engine/requests.ts';\nimport { METRES_PER_DEGREE } from '../util/geo.ts';\nimport type { TileGrid, TileMatrix } from './grid.ts';\n\n/** The size of a pixel by which WMTS turns scale denominators into resolutions, metres */\nconst PIXEL = 0.00028;\n\nconst numbers = (text: string | undefined) => (text ?? '').trim().split(/\\s+/).map(Number);\n\n/**\n * The tile grid of `layer` in the capabilities document `xml`: its tile matrix set `matrixSet` (default the layer's\n * first), with the layer's tile limits and longitude-latitude extent. Throws if the layer or the set is missing\n */\nexport const parseWmtsGrid = (xml: string, layer: string, matrixSet?: string): TileGrid => {\n const contents = child(parseXml(xml), 'Contents');\n const entry = children(contents, 'Layer').find((l) => childText(l, 'Identifier') === layer);\n\n if (!entry) throw new Error(`isard: no WMTS layer ${layer}`);\n\n const links = children(entry, 'TileMatrixSetLink');\n const link = matrixSet === undefined ? links[0] : links.find((l) => childText(l, 'TileMatrixSet') === matrixSet);\n const name = childText(link, 'TileMatrixSet');\n const set = children(contents, 'TileMatrixSet').find((s) => childText(s, 'Identifier') === name);\n\n if (!name || !set) throw new Error(`isard: no tile matrix set ${matrixSet ?? ''} for the WMTS layer ${layer}`);\n\n const crs = childText(set, 'SupportedCRS') ?? '';\n const geographic = isGeographic(crs);\n // EPSG's geographic CRSs have their latitude first (CRS:84 and the IGN's WGS84G do not)\n const latFirst = geographic && epsgCode(crs) === 4326 && /EPSG/i.test(crs);\n // Metres per degree, as WMTS counts the scale of a grid in degrees (OGC 07-057r7, 6.1)\n const unit = geographic ? METRES_PER_DEGREE : 1;\n const limits = new Map<string, TileMatrix['limits']>();\n\n children(child(link, 'TileMatrixSetLimits'), 'TileMatrixLimits').forEach((l) => {\n const limit = (k: string) => Number(childText(l, k));\n\n limits.set(childText(l, 'TileMatrix') ?? '', [\n limit('MinTileCol'),\n limit('MinTileRow'),\n limit('MaxTileCol'),\n limit('MaxTileRow'),\n ]);\n });\n\n const matrices = children(set, 'TileMatrix').map((m): TileMatrix => {\n const id = childText(m, 'Identifier') ?? '';\n const [a = 0, b = 0] = numbers(childText(m, 'TopLeftCorner'));\n const limit = limits.get(id);\n\n return {\n id,\n resolution: (Number(childText(m, 'ScaleDenominator')) * PIXEL) / unit,\n origin: latFirst ? [b, a] : [a, b],\n tileWidth: Number(childText(m, 'TileWidth') ?? 256),\n tileHeight: Number(childText(m, 'TileHeight') ?? 256),\n matrixWidth: Number(childText(m, 'MatrixWidth') ?? Infinity),\n matrixHeight: Number(childText(m, 'MatrixHeight') ?? Infinity),\n ...(limit ? { limits: limit } : {}),\n };\n });\n // A layer's limits leave out the matrices it does not have\n const served = limits.size > 0 ? matrices.filter((m) => limits.has(String(m.id))) : matrices;\n const box = child(entry, 'WGS84BoundingBox');\n const [west = Number.NaN, south = Number.NaN] = numbers(childText(box, 'LowerCorner'));\n const [east = Number.NaN, north = Number.NaN] = numbers(childText(box, 'UpperCorner'));\n const bounds: [number, number, number, number] = [west, south, east, north];\n\n return {\n crs,\n matrices: served,\n name,\n ...(bounds.every(Number.isFinite) ? { bounds } : {}),\n };\n};\n\n/**\n * The tile grid of a WMTS layer, from the service's capabilities at `capabilities` (fetched with CORS), for\n * `addRaster`: `await wmtsGrid('https://…/wmts?SERVICE=WMTS&REQUEST=GetCapabilities', 'LAYER', 'MATRIXSET')`. The\n * raster's URL writes the matrix set, {z} for the matrix, {x} and {y} for the column and the row\n */\nexport const wmtsGrid = async (\n capabilities: string | URL,\n layer: string,\n matrixSet?: string,\n options: { signal?: AbortSignal } = {},\n): Promise<TileGrid> => {\n const response = await fetch(\n capabilities,\n withHeaders(capabilities, options.signal ? { signal: options.signal } : {}),\n );\n\n if (!response.ok) throw new Error(`isard: ${response.status} for the WMTS capabilities`);\n\n return parseWmtsGrid(await response.text(), layer, matrixSet);\n};\n"]}