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
@@ -1 +1 @@
1
- {"version":3,"file":"trees.js","sourceRoot":"","sources":["../../src/basemap/trees.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The trees of a vector map (`VectorTiles.trees`): low-poly trees made here as glTF binaries (no file to download), a\n * broadleaved one and a conifer, their trunk and crown flat-shaded in their colors; the style layers they grow on by\n * default, and the share of conifers in a wood from its data.\n */\n\nimport { bounds, glbOf } from '../util/gltf.ts';\nimport type { Value } from './mvt.ts';\nimport type { StyleLayer } from './vectorstyle.ts';\n\n/** Numbers of a tree in the workers' answer: longitude, latitude, scale, heading, rank, kind (0 broadleaved, 1\n * conifer) */\nexport const TREE_NUMBERS = 6;\n\n/** A point or a vector: x, y, z */\ntype Vec3 = [number, number, number];\n\n/** Sides of the trunk and of the crown near the view; of the crown far away (a pyramid), of the trunk there */\nconst SIDES = 7;\nconst FAR_SIDES = 4;\nconst FAR_TRUNK_SIDES = 3;\n\n/** Colors of the trunk, of the broadleaved crown and of the conifers' (linear RGBA, as glTF's `baseColorFactor`) */\nexport interface TreeColors {\n trunk: [number, number, number, number];\n crown: [number, number, number, number];\n conifer: [number, number, number, number];\n}\n\nconst DEFAULT_COLORS: TreeColors = {\n trunk: [0.2, 0.12, 0.07, 1],\n crown: [0.12, 0.27, 0.08, 1],\n conifer: [0.05, 0.16, 0.08, 1],\n};\n\n/** A solid of revolution around the vertical (glTF +Y up), flat-shaded: rings of (height, radius), a point at the\n * top when its radius is 0; the triangles' positions and normals, one normal per face */\nexport const revolve = (\n rings: [height: number, radius: number][],\n sides = SIDES,\n): { positions: number[]; normals: number[] } => {\n const at = (k: number, [h, r]: [number, number]): Vec3 => {\n const a = (k / sides) * Math.PI * 2;\n\n return [Math.cos(a) * r, h, Math.sin(a) * r];\n };\n const positions: number[] = [];\n const normals: number[] = [];\n const face = (a: Vec3, b: Vec3, c: Vec3) => {\n const u: Vec3 = [b[0] - a[0], b[1] - a[1], b[2] - a[2]];\n const v: Vec3 = [c[0] - a[0], c[1] - a[1], c[2] - a[2]];\n const n: Vec3 = [u[1] * v[2] - u[2] * v[1], u[2] * v[0] - u[0] * v[2], u[0] * v[1] - u[1] * v[0]];\n const length = Math.hypot(...n);\n\n // A degenerate face (two points at the apex) is left out\n if (length === 0) return;\n positions.push(...a, ...b, ...c);\n [0, 1, 2].forEach(() => {\n normals.push(n[0] / length, n[1] / length, n[2] / length);\n });\n };\n\n rings.slice(1).forEach((ring, i) => {\n const below = rings[i] ?? ring;\n\n Array.from({ length: sides }, (_, k) => k).forEach((k) => {\n const [a, b] = [at(k, below), at(k + 1, below)];\n const [c, d] = [at(k, ring), at(k + 1, ring)];\n\n // Counter-clockwise seen from outside\n face(a, c, b);\n face(b, c, d);\n });\n });\n // The bottom closed: seen from below\n const base = rings[0];\n\n if (base && base[1] > 0) {\n Array.from({ length: sides }, (_, k) => k).forEach((k) => {\n face([0, base[0], 0], at(k, base), at(k + 1, base));\n });\n }\n\n return { positions, normals };\n};\n\n/** Parts flat-shaded in their colors as a glTF binary: one mesh of a primitive each, its front +Z\n * (`ModelInstance.heading` turns it), standing on its origin */\nexport const glb = (\n parts: { positions: number[]; normals: number[] }[],\n colors: TreeColors[keyof TreeColors][],\n): Uint8Array<ArrayBuffer> => {\n // The buffer: each part's positions then normals, 4-byte floats\n const floats = parts.flatMap((p) => [...p.positions, ...p.normals]);\n const bin = new Float32Array(floats);\n const views = parts.flatMap((p, i) => {\n const before = parts.slice(0, i).reduce((n, q) => n + (q.positions.length + q.normals.length) * 4, 0);\n\n return [\n { buffer: 0, byteOffset: before, byteLength: p.positions.length * 4, target: 34962 },\n { buffer: 0, byteOffset: before + p.positions.length * 4, byteLength: p.normals.length * 4, target: 34962 },\n ];\n });\n const accessors = parts.flatMap((p, i) => [\n { bufferView: i * 2, componentType: 5126, count: p.positions.length / 3, type: 'VEC3', ...bounds(p.positions) },\n { bufferView: i * 2 + 1, componentType: 5126, count: p.normals.length / 3, type: 'VEC3' },\n ]);\n const gltf = {\n asset: { version: '2.0', generator: 'isard' },\n scene: 0,\n scenes: [{ nodes: [0] }],\n nodes: [{ mesh: 0 }],\n meshes: [\n {\n primitives: parts.map((_, i) => ({ attributes: { POSITION: i * 2, NORMAL: i * 2 + 1 }, material: i })),\n },\n ],\n materials: colors.map((color) => ({\n pbrMetallicRoughness: { baseColorFactor: color, metallicFactor: 0, roughnessFactor: 1 },\n })),\n accessors,\n bufferViews: views,\n buffers: [{ byteLength: bin.byteLength }],\n };\n return glbOf(gltf, new Uint8Array(bin.buffer));\n};\n\n/**\n * A broadleaved tree as a glTF binary, about 10 metres high: a trunk and a rounded crown in `colors`; `far`: the\n * same simplified for far away, a few faces (some 30 triangles instead of 100)\n */\nexport const treeModel = (colors: Partial<TreeColors> = {}, far = false): Uint8Array<ArrayBuffer> => {\n const { trunk, crown } = { ...DEFAULT_COLORS, ...colors };\n\n if (far) {\n const stem = revolve(\n [\n [0, 0.3],\n [3, 0.22],\n ],\n FAR_TRUNK_SIDES,\n );\n const top = revolve(\n [\n [2.4, 0.8],\n [5.6, 2.9],\n [10.2, 0],\n ],\n FAR_SIDES,\n );\n\n return glb([stem, top], [trunk, crown]);\n }\n\n const parts = [\n revolve([\n [0, 0.28],\n [3.2, 0.2],\n ]),\n revolve([\n [2.4, 0.6],\n [3.6, 2.4],\n [5.6, 2.9],\n [7.8, 2.3],\n [9.4, 1.1],\n [10.2, 0],\n ]),\n ];\n\n return glb(parts, [trunk, crown]);\n};\n\n/** A cone of the conifers' crown: from `base` metres up, `radius` wide, to its point at `top` */\nconst cone = (base: number, radius: number, top: number) =>\n revolve([\n [base, radius],\n [top, 0],\n ]);\n\n/**\n * A conifer as a glTF binary, about 11 metres high: a trunk and three cones one over the other in `colors`; `far`: one\n * pyramid on a trunk of three faces for far away (some 17 triangles instead of 63)\n */\nexport const coniferModel = (colors: Partial<TreeColors> = {}, far = false): Uint8Array<ArrayBuffer> => {\n const { trunk, conifer } = { ...DEFAULT_COLORS, ...colors };\n\n if (far) {\n const stem = revolve(\n [\n [0, 0.24],\n [2, 0.18],\n ],\n FAR_TRUNK_SIDES,\n );\n const top = revolve(\n [\n [1.4, 2.3],\n [11, 0],\n ],\n FAR_SIDES,\n );\n\n return glb([stem, top], [trunk, conifer]);\n }\n const tiers = [cone(1.4, 2.4, 5.4), cone(3.6, 1.9, 8), cone(6, 1.3, 11)];\n const crown = {\n positions: tiers.flatMap((t) => t.positions),\n normals: tiers.flatMap((t) => t.normals),\n };\n const stem = revolve([\n [0, 0.24],\n [2, 0.18],\n ]);\n\n return glb([stem, crown], [trunk, conifer]);\n};\n\n/** Whether a style layer is OpenMapTiles' grass (the lawns of parks and gardens among it) */\nconst isGrass = (layer: StyleLayer): boolean => layer['source-layer'] === 'landcover' && /grass/i.test(layer.id);\n\n/**\n * Whether trees grow on a style layer by default: the woods and forests of the style's fills (OpenMapTiles'\n * `landcover` wood, PLAN IGN's forests) and the grass of its parks and gardens; not the wooded relief of PLAN IGN,\n * which repeats its forests, nor OpenMapTiles' `park` layer (protected areas and historic sites: a river's banks\n * among them)\n */\nexport const isWoodland = (layer: StyleLayer): boolean =>\n layer.type === 'fill' &&\n layer['source-layer'] !== 'oro_relief' &&\n (/wood|forest|for[eê]t/i.test(layer.id) || isGrass(layer));\n\n/** Default spacing of the trees of a layer (metres): close in woods and forests, apart on grass */\nexport const treeSpacing = (layer: StyleLayer): number => (isGrass(layer) ? 25 : 9);\n\n/**\n * The share of conifers in a wood from its properties: OpenStreetMap's `leaf_type` (needleleaved, broadleaved,\n * mixed), PLAN IGN's `nature` (« conifères », « feuillus », « mixte »); without them, OpenMapTiles' forests a third\n * conifers and its other woods some, the grass of parks none\n */\nexport const coniferShare = (properties: Record<string, Value>): number => {\n const leaf = properties.leaf_type;\n const nature = typeof properties.nature === 'string' ? properties.nature : '';\n\n if (leaf === 'needleleaved' || /conif/i.test(nature)) return 1;\n if (leaf === 'broadleaved' || /feuillu/i.test(nature)) return 0;\n if (leaf === 'mixed' || /mixte/i.test(nature)) return 0.5;\n if (properties.class === 'wood') return properties.subclass === 'forest' ? 0.35 : 0.15;\n\n return 0;\n};\n"]}
1
+ {"version":3,"file":"trees.js","sourceRoot":"","sources":["../../src/basemap/trees.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The trees of a vector map (`VectorTiles.trees`): low-poly trees made here as glTF binaries (no file to download), a\n * broadleaved one and a conifer, their trunk and crown flat-shaded in their colors; the style layers they grow on by\n * default, and the share of conifers in a wood from its data.\n */\n\nimport { glb, join, revolve } from './meshes.ts';\nimport type { Value } from './mvt.ts';\nimport type { StyleLayer } from './vectorstyle.ts';\n\n/** Sides of the trunk and of the crown near the view; of the crown far away (a pyramid), of the trunk there */\nconst SIDES = 7;\nconst FAR_SIDES = 4;\nconst FAR_TRUNK_SIDES = 3;\n\n/** Colors of the trunk, of the broadleaved crown and of the conifers' (linear RGBA, as glTF's `baseColorFactor`) */\nexport interface TreeColors {\n trunk: [number, number, number, number];\n crown: [number, number, number, number];\n conifer: [number, number, number, number];\n}\n\n/** The models' heights (metres): a tree's height from its data scales them by it */\nexport const TREE_METRES = { broadleaved: 10.2, conifer: 11 } as const;\n\nconst DEFAULT_COLORS: TreeColors = {\n trunk: [0.2, 0.12, 0.07, 1],\n crown: [0.12, 0.27, 0.08, 1],\n conifer: [0.05, 0.16, 0.08, 1],\n};\n\n/**\n * A broadleaved tree as a glTF binary, about 10 metres high: a trunk and a rounded crown in `colors`; `far`: the\n * same simplified for far away, a few faces (some 30 triangles instead of 100)\n */\nexport const treeModel = (colors: Partial<TreeColors> = {}, far = false): Uint8Array<ArrayBuffer> => {\n const { trunk, crown } = { ...DEFAULT_COLORS, ...colors };\n\n if (far) {\n const stem = revolve(\n [\n [0, 0.3],\n [3, 0.22],\n ],\n FAR_TRUNK_SIDES,\n );\n const top = revolve(\n [\n [2.4, 0.8],\n [5.6, 2.9],\n [TREE_METRES.broadleaved, 0],\n ],\n FAR_SIDES,\n );\n\n return glb([stem, top], [trunk, crown]);\n }\n\n const parts = [\n revolve(\n [\n [0, 0.28],\n [3.2, 0.2],\n ],\n SIDES,\n ),\n revolve(\n [\n [2.4, 0.6],\n [3.6, 2.4],\n [5.6, 2.9],\n [7.8, 2.3],\n [9.4, 1.1],\n [TREE_METRES.broadleaved, 0],\n ],\n SIDES,\n ),\n ];\n\n return glb(parts, [trunk, crown]);\n};\n\n/** A cone of the conifers' crown: from `base` metres up, `radius` wide, to its point at `top` */\nconst cone = (base: number, radius: number, top: number) =>\n revolve(\n [\n [base, radius],\n [top, 0],\n ],\n SIDES,\n );\n\n/**\n * A conifer as a glTF binary, about 11 metres high: a trunk and three cones one over the other in `colors`; `far`: one\n * pyramid on a trunk of three faces for far away (some 17 triangles instead of 63)\n */\nexport const coniferModel = (colors: Partial<TreeColors> = {}, far = false): Uint8Array<ArrayBuffer> => {\n const { trunk, conifer } = { ...DEFAULT_COLORS, ...colors };\n\n if (far) {\n const stem = revolve(\n [\n [0, 0.24],\n [2, 0.18],\n ],\n FAR_TRUNK_SIDES,\n );\n const top = revolve(\n [\n [1.4, 2.3],\n [TREE_METRES.conifer, 0],\n ],\n FAR_SIDES,\n );\n\n return glb([stem, top], [trunk, conifer]);\n }\n const tiers = [cone(1.4, 2.4, 5.4), cone(3.6, 1.9, 8), cone(6, 1.3, TREE_METRES.conifer)];\n const crown = join(...tiers);\n const stem = revolve(\n [\n [0, 0.24],\n [2, 0.18],\n ],\n SIDES,\n );\n\n return glb([stem, crown], [trunk, conifer]);\n};\n\n/** Whether a style layer is OpenMapTiles' grass (the lawns of parks and gardens among it) */\nconst isGrass = (layer: StyleLayer): boolean => layer['source-layer'] === 'landcover' && /grass/i.test(layer.id);\n\n/**\n * Whether trees grow on a style layer by default: the woods and forests of the style's fills (OpenMapTiles'\n * `landcover` wood, PLAN IGN's forests) and the grass of its parks and gardens; not the wooded relief of PLAN IGN,\n * which repeats its forests, nor OpenMapTiles' `park` layer (protected areas and historic sites: a river's banks\n * among them)\n */\nexport const isWoodland = (layer: StyleLayer): boolean =>\n layer.type === 'fill' &&\n layer['source-layer'] !== 'oro_relief' &&\n (/wood|forest|for[eê]t/i.test(layer.id) || isGrass(layer));\n\n/** Default spacing of the trees of a layer (metres): close in woods and forests, apart on grass */\nexport const treeSpacing = (layer: StyleLayer): number => (isGrass(layer) ? 25 : 9);\n\n/**\n * The share of conifers in a wood from its properties: OpenStreetMap's `leaf_type` (needleleaved, broadleaved,\n * mixed), PLAN IGN's `nature` (« conifères », « feuillus », « mixte »); without them, OpenMapTiles' forests a third\n * conifers and its other woods some, the grass of parks none\n */\nexport const coniferShare = (properties: Record<string, Value>): number => {\n const leaf = properties.leaf_type;\n const nature = typeof properties.nature === 'string' ? properties.nature : '';\n\n if (leaf === 'needleleaved' || /conif/i.test(nature)) return 1;\n if (leaf === 'broadleaved' || /feuillu/i.test(nature)) return 0;\n if (leaf === 'mixed' || /mixte/i.test(nature)) return 0.5;\n if (properties.class === 'wood') return properties.subclass === 'forest' ? 0.35 : 0.15;\n\n return 0;\n};\n"]}
@@ -41,6 +41,8 @@ export interface VectorTilesContext {
41
41
  /** The style's sprites among the map's icons (under `iconPrefix`), added once: the labels' icons, the fills'
42
42
  * patterns */
43
43
  addSprites(): Promise<void>;
44
- /** Makes a layer's tiles follow the view, its `requests` aborted when it is destroyed */
45
- followView(update: () => Promise<unknown>, requests: TileRequests, moving: () => unknown): void;
44
+ /** Makes a layer's tiles follow the view, its `requests` aborted when it is destroyed or the layer removed */
45
+ followView(layer: Layer, update: () => Promise<unknown>, requests: TileRequests, moving: () => unknown): void;
46
+ /** Calls `stop` when it is destroyed or the layer removed, once */
47
+ stopWith(layer: Layer, stop: () => void): void;
46
48
  }
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/context.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * What the layers of a `VectorTiles` (its extrusions, streets' wind, trees, vectors and labels) use of it: built by\n * the instance for its layers only, its own fields staying private.\n */\n\nimport type { LoadedSprite } from '../../layers/icons.ts';\nimport type { Layer, RasterLayer } from '../../layers/layers.ts';\nimport type { GeoMap } from '../../map.ts';\nimport type { BasemapResponse, BasemapWork } from '../../workers/basemap.worker.ts';\nimport type { Style, StyleLayer } from '../vectorstyle.ts';\nimport type { BasemapWorkers } from '../workerpool.ts';\nimport type { TileRequests } from './requests.ts';\nimport type { LoadedStyle } from './style.ts';\n\n/** A renderer sent to the workers: its key, the source's deepest level, its style layers */\nexport interface Renderer {\n key: string;\n maxzoom: number;\n layers: StyleLayer[];\n}\n\nexport interface VectorTilesContext {\n readonly map: GeoMap;\n /** The style once loaded, with its source resolved */\n readonly ready: Promise<LoadedStyle>;\n /** Its raster and label layers, removed with it: a layer made is added to them */\n readonly layers: Layer[];\n /** Called when it is destroyed: a layer adds what stops it (its listeners, its timers) */\n readonly cleanup: (() => void)[];\n /** Prefix of the names of its sprites' images among the map's icons */\n readonly iconPrefix: string;\n /** Whether it was destroyed */\n destroyed(): boolean;\n /** Its first raster layer: the ground its labels follow */\n ground(): RasterLayer | undefined;\n /** A message to every worker of its pool */\n broadcast(message: Parameters<BasemapWorkers['broadcast']>[0]): void;\n /** A work asked of the worker of the vector tile `vz/vx/vy` */\n request(vz: number, vx: number, vy: number, work: BasemapWork, signal?: AbortSignal): Promise<BasemapResponse>;\n /** Sends a renderer of these layers to every worker (again under `again`, restyled) */\n renderer(select: (layer: StyleLayer) => boolean, extra: StyleLayer[], again?: string): Promise<Renderer>;\n /** The style's sprites, kept once all of them came */\n loadSprites(sprite: Style['sprite']): Promise<LoadedSprite[]>;\n /** The style's sprites among the map's icons (under `iconPrefix`), added once: the labels' icons, the fills'\n * patterns */\n addSprites(): Promise<void>;\n /** Makes a layer's tiles follow the view, its `requests` aborted when it is destroyed */\n followView(update: () => Promise<unknown>, requests: TileRequests, moving: () => unknown): void;\n}\n"]}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/context.ts"],"names":[],"mappings":"AAAA;;;GAGG","sourcesContent":["/**\n * What the layers of a `VectorTiles` (its extrusions, streets' wind, trees, vectors and labels) use of it: built by\n * the instance for its layers only, its own fields staying private.\n */\n\nimport type { LoadedSprite } from '../../layers/icons.ts';\nimport type { Layer, RasterLayer } from '../../layers/layers.ts';\nimport type { GeoMap } from '../../map.ts';\nimport type { BasemapResponse, BasemapWork } from '../../workers/basemap.worker.ts';\nimport type { Style, StyleLayer } from '../vectorstyle.ts';\nimport type { BasemapWorkers } from '../workerpool.ts';\nimport type { TileRequests } from './requests.ts';\nimport type { LoadedStyle } from './style.ts';\n\n/** A renderer sent to the workers: its key, the source's deepest level, its style layers */\nexport interface Renderer {\n key: string;\n maxzoom: number;\n layers: StyleLayer[];\n}\n\nexport interface VectorTilesContext {\n readonly map: GeoMap;\n /** The style once loaded, with its source resolved */\n readonly ready: Promise<LoadedStyle>;\n /** Its raster and label layers, removed with it: a layer made is added to them */\n readonly layers: Layer[];\n /** Called when it is destroyed: a layer adds what stops it (its listeners, its timers) */\n readonly cleanup: (() => void)[];\n /** Prefix of the names of its sprites' images among the map's icons */\n readonly iconPrefix: string;\n /** Whether it was destroyed */\n destroyed(): boolean;\n /** Its first raster layer: the ground its labels follow */\n ground(): RasterLayer | undefined;\n /** A message to every worker of its pool */\n broadcast(message: Parameters<BasemapWorkers['broadcast']>[0]): void;\n /** A work asked of the worker of the vector tile `vz/vx/vy` */\n request(vz: number, vx: number, vy: number, work: BasemapWork, signal?: AbortSignal): Promise<BasemapResponse>;\n /** Sends a renderer of these layers to every worker (again under `again`, restyled) */\n renderer(select: (layer: StyleLayer) => boolean, extra: StyleLayer[], again?: string): Promise<Renderer>;\n /** The style's sprites, kept once all of them came */\n loadSprites(sprite: Style['sprite']): Promise<LoadedSprite[]>;\n /** The style's sprites among the map's icons (under `iconPrefix`), added once: the labels' icons, the fills'\n * patterns */\n addSprites(): Promise<void>;\n /** Makes a layer's tiles follow the view, its `requests` aborted when it is destroyed or the layer removed */\n followView(layer: Layer, update: () => Promise<unknown>, requests: TileRequests, moving: () => unknown): void;\n /** Calls `stop` when it is destroyed or the layer removed, once */\n stopWith(layer: Layer, stop: () => void): void;\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  /** The extrusions of a vector basemap (`VectorTiles.extrusions`): its buildings raised, tile by tile around the view */
2
2
  import type { ExtrusionLayer, ExtrusionOptions } from '../../layers/extrusions.ts';
3
- import type { RoofMode } from '../../workers/basemap/geometry.ts';
3
+ import { type RoofMode } from '../../util/roofs.ts';
4
4
  import type { StyleLayer } from '../vectorstyle.ts';
5
5
  import type { VectorTilesContext } from './context.ts';
6
6
  /** The options of `VectorTiles.extrusions` */
@@ -1,22 +1,13 @@
1
1
  /** The extrusions of a vector basemap (`VectorTiles.extrusions`): its buildings raised, tile by tile around the view */
2
- import { isRecord } from "../../util/guards.js";
2
+ import { roofHeightOf, roofShapeOf } from "../../util/roofs.js";
3
3
  import { TileRequests } from "./requests.js";
4
4
  import { isBuildings, isPolygonLayer } from "./style.js";
5
5
  import { MAX_TILES, nearPriority, STREET_ZOOM, tileKey, tilesAround } from "./tiles.js";
6
- /** The first of a feature's properties `names` it has */
7
- const property = (p, names) => isRecord(p) ? names.map((n) => p[n]).find((v) => v !== undefined) : undefined;
8
- /** The roof style of a `RoofMode`: a feature's `roof:shape` (or `roof_shape`), else flat or generated; its
9
- * `roof:height` */
10
- const roofStyle = (mode) => {
11
- const fallback = mode === 'generated' ? 'generated' : 'flat';
12
- return {
13
- roof: (p) => {
14
- const shape = property(p, ['roof:shape', 'roof_shape']);
15
- return typeof shape === 'string' && shape !== 'generated' ? shape : fallback;
16
- },
17
- roofHeight: (p) => Number(property(p, ['roof:height', 'roof_height']) ?? Number.NaN),
18
- };
19
- };
6
+ /** The roof style of a `RoofMode`, as the vector tiles' buildings read theirs (`roofShapeOf`, `roofHeightOf`) */
7
+ const roofStyle = (mode) => ({
8
+ roof: (p) => roofShapeOf(p, mode) ?? 'flat',
9
+ roofHeight: roofHeightOf,
10
+ });
20
11
  export const extrusions = (context, options = {}) => {
21
12
  const { map } = context;
22
13
  const { layers = isBuildings, minZoom = STREET_ZOOM, maxTiles = MAX_TILES, roofs = 'flat', ...style } = options;
@@ -55,7 +46,7 @@ export const extrusions = (context, options = {}) => {
55
46
  });
56
47
  });
57
48
  };
58
- context.followView(update, requests, update);
49
+ context.followView(layer, update, requests, update);
59
50
  return layer;
60
51
  };
61
52
  //# sourceMappingURL=extrusions.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"extrusions.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/extrusions.ts"],"names":[],"mappings":"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","sourcesContent":["/** The extrusions of a vector basemap (`VectorTiles.extrusions`): its buildings raised, tile by tile around the view */\n\nimport type { ExtrusionLayer, ExtrusionOptions } from '../../layers/extrusions.ts';\nimport { isRecord } from '../../util/guards.ts';\nimport type { RoofMode } from '../../workers/basemap/geometry.ts';\nimport type { BasemapWork, TilePolygons } from '../../workers/basemap.worker.ts';\nimport type { StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { TileRequests } from './requests.ts';\nimport { isBuildings, isPolygonLayer } from './style.ts';\nimport { MAX_TILES, nearPriority, STREET_ZOOM, tileKey, tilesAround } from './tiles.ts';\n\n/** The options of `VectorTiles.extrusions` */\nexport type VectorExtrusionOptions<P> = Omit<ExtrusionOptions<P>, 'data'> & {\n layers?: (layer: StyleLayer) => boolean;\n minZoom?: number;\n maxTiles?: number;\n /** The roofs, as `vectors()` makes them: from the tiles' data (`roof:shape`, `roof:height`; flat without),\n * generated where they have none, or flat (the default, unless `roof` is given) */\n roofs?: RoofMode;\n};\n\n/** The first of a feature's properties `names` it has */\nconst property = (p: unknown, names: readonly string[]): unknown =>\n isRecord(p) ? names.map((n) => p[n]).find((v) => v !== undefined) : undefined;\n\n/** The roof style of a `RoofMode`: a feature's `roof:shape` (or `roof_shape`), else flat or generated; its\n * `roof:height` */\nconst roofStyle = <P>(mode: RoofMode): Pick<ExtrusionOptions<P>, 'roof' | 'roofHeight'> => {\n const fallback = mode === 'generated' ? 'generated' : 'flat';\n\n return {\n roof: (p) => {\n const shape = property(p, ['roof:shape', 'roof_shape']);\n\n return typeof shape === 'string' && shape !== 'generated' ? shape : fallback;\n },\n roofHeight: (p) => Number(property(p, ['roof:height', 'roof_height']) ?? Number.NaN),\n };\n};\n\nexport const extrusions = <P = Record<string, unknown>>(\n context: VectorTilesContext,\n options: VectorExtrusionOptions<P> = {},\n): ExtrusionLayer<P> => {\n const { map } = context;\n const { layers = isBuildings, minZoom = STREET_ZOOM, maxTiles = MAX_TILES, roofs = 'flat', ...style } = options;\n const layer = map.addExtrusions<P>(roofs === 'flat' ? style : { ...roofStyle<P>(roofs), ...style });\n const renderer = context.renderer(isPolygonLayer(layers), []);\n\n renderer.catch(() => undefined);\n context.layers.push(layer);\n\n /** The tiles held or asked for, by key */\n const requests = new TileRequests();\n const update = async () => {\n if (context.destroyed()) return;\n\n const { key, maxzoom } = await renderer;\n const camera = map.getCamera();\n const z = maxzoom;\n const wanted = camera.zoom < minZoom ? [] : tilesAround(map, camera, z, maxTiles);\n const keys = new Set(wanted.map(([x, y]) => tileKey(z, x, y)));\n\n // Out of view: dropped, or no longer asked for\n requests.keys().forEach((k) => {\n if (keys.has(k)) return;\n requests.drop(k);\n layer.removeTile(k);\n });\n wanted.forEach(([x, y], index) => {\n const k = tileKey(z, x, y);\n\n if (requests.has(k)) return;\n\n const work: BasemapWork = { type: 'polygons', key, z, x, y, priority: nearPriority(index) };\n\n requests.ask(\n k,\n (signal) => context.request(z, x, y, work, signal),\n (r) => {\n if (!('polygons' in r)) return;\n\n const tile: TilePolygons = r.polygons;\n\n // The features' properties as the style reads them\n layer.setTile(k, { arrays: tile.arrays, properties: tile.properties as P[] });\n },\n );\n });\n };\n context.followView(update, requests, update);\n\n return layer;\n};\n"]}
1
+ {"version":3,"file":"extrusions.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/extrusions.ts"],"names":[],"mappings":"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","sourcesContent":["/** The extrusions of a vector basemap (`VectorTiles.extrusions`): its buildings raised, tile by tile around the view */\n\nimport type { ExtrusionLayer, ExtrusionOptions } from '../../layers/extrusions.ts';\nimport { type RoofMode, roofHeightOf, roofShapeOf } from '../../util/roofs.ts';\nimport type { BasemapWork, TilePolygons } from '../../workers/basemap.worker.ts';\nimport type { StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { TileRequests } from './requests.ts';\nimport { isBuildings, isPolygonLayer } from './style.ts';\nimport { MAX_TILES, nearPriority, STREET_ZOOM, tileKey, tilesAround } from './tiles.ts';\n\n/** The options of `VectorTiles.extrusions` */\nexport type VectorExtrusionOptions<P> = Omit<ExtrusionOptions<P>, 'data'> & {\n layers?: (layer: StyleLayer) => boolean;\n minZoom?: number;\n maxTiles?: number;\n /** The roofs, as `vectors()` makes them: from the tiles' data (`roof:shape`, `roof:height`; flat without),\n * generated where they have none, or flat (the default, unless `roof` is given) */\n roofs?: RoofMode;\n};\n\n/** The roof style of a `RoofMode`, as the vector tiles' buildings read theirs (`roofShapeOf`, `roofHeightOf`) */\nconst roofStyle = <P>(mode: RoofMode): Pick<ExtrusionOptions<P>, 'roof' | 'roofHeight'> => ({\n roof: (p) => roofShapeOf(p, mode) ?? 'flat',\n roofHeight: roofHeightOf,\n});\n\nexport const extrusions = <P = Record<string, unknown>>(\n context: VectorTilesContext,\n options: VectorExtrusionOptions<P> = {},\n): ExtrusionLayer<P> => {\n const { map } = context;\n const { layers = isBuildings, minZoom = STREET_ZOOM, maxTiles = MAX_TILES, roofs = 'flat', ...style } = options;\n const layer = map.addExtrusions<P>(roofs === 'flat' ? style : { ...roofStyle<P>(roofs), ...style });\n const renderer = context.renderer(isPolygonLayer(layers), []);\n\n renderer.catch(() => undefined);\n context.layers.push(layer);\n\n /** The tiles held or asked for, by key */\n const requests = new TileRequests();\n const update = async () => {\n if (context.destroyed()) return;\n\n const { key, maxzoom } = await renderer;\n const camera = map.getCamera();\n const z = maxzoom;\n const wanted = camera.zoom < minZoom ? [] : tilesAround(map, camera, z, maxTiles);\n const keys = new Set(wanted.map(([x, y]) => tileKey(z, x, y)));\n\n // Out of view: dropped, or no longer asked for\n requests.keys().forEach((k) => {\n if (keys.has(k)) return;\n requests.drop(k);\n layer.removeTile(k);\n });\n wanted.forEach(([x, y], index) => {\n const k = tileKey(z, x, y);\n\n if (requests.has(k)) return;\n\n const work: BasemapWork = { type: 'polygons', key, z, x, y, priority: nearPriority(index) };\n\n requests.ask(\n k,\n (signal) => context.request(z, x, y, work, signal),\n (r) => {\n if (!('polygons' in r)) return;\n\n const tile: TilePolygons = r.polygons;\n\n // The features' properties as the style reads them\n layer.setTile(k, { arrays: tile.arrays, properties: tile.properties as P[] });\n },\n );\n });\n };\n context.followView(layer, update, requests, update);\n\n return layer;\n};\n"]}
@@ -0,0 +1,19 @@
1
+ /** The street furniture of a vector basemap (`VectorTiles.furniture`): 3D models placed by the workers from its
2
+ * points of interest of the street (bus shelters, waste baskets, post boxes, drinking fountains, bicycle racks), each
3
+ * facing its street, and benches along the pedestrian streets and the parks' paths */
4
+ import type { Layer, ModelLayer } from '../../layers/layers.ts';
5
+ import type { VectorTilesContext } from './context.ts';
6
+ /** The options of `VectorTiles.furniture` */
7
+ export interface FurnitureOptions {
8
+ /** From this zoom on (default 16.5) */
9
+ minZoom?: number;
10
+ maxTiles?: number;
11
+ /** Pieces in a tile at most (default 20000) */
12
+ maxObjects?: number;
13
+ /** Pieces drawn at most (default 12000) */
14
+ maxInstances?: number;
15
+ before?: Layer;
16
+ }
17
+ /** The layers of the street furniture, a kind each (`FURNITURE`'s order: shelters, bins, post boxes, fountains, racks,
18
+ * benches): the first holds the others (`Layer.companions`) */
19
+ export declare const furniture: (context: VectorTilesContext, options?: FurnitureOptions) => ModelLayer;
@@ -0,0 +1,29 @@
1
+ /** The street furniture of a vector basemap (`VectorTiles.furniture`): 3D models placed by the workers from its
2
+ * points of interest of the street (bus shelters, waste baskets, post boxes, drinking fountains, bicycle racks), each
3
+ * facing its street, and benches along the pedestrian streets and the parks' paths */
4
+ import { FURNITURE, FURNITURE_MODELS } from "../furniture.js";
5
+ import { placed } from "./placed.js";
6
+ /** Metres around the ground under the camera where every piece is drawn at zoom 17 (twice as far a zoom level out);
7
+ * past them, fewer and fewer */
8
+ const FURNITURE_NEAR_METRES = 160;
9
+ /** The layers of the street furniture, a kind each (`FURNITURE`'s order: shelters, bins, post boxes, fountains, racks,
10
+ * benches): the first holds the others (`Layer.companions`) */
11
+ export const furniture = (context, options = {}) => {
12
+ const { minZoom = 16.5, maxTiles = 9, maxObjects = 20000, maxInstances = 12000 } = options;
13
+ const model = (kind) => ({ data: FURNITURE_MODELS[kind]() });
14
+ const [layer] = placed(context, {
15
+ // A model per kind, in the workers' order
16
+ models: [model(FURNITURE[0]), ...FURNITURE.slice(1).map(model)],
17
+ // The source of the style's buildings and streets: OpenMapTiles' layers read from its tiles
18
+ layers: (l) => l.type === 'line' || l.type === 'fill',
19
+ work: (key, z, x, y, priority) => ({ type: 'furniture', key, z, x, y, maxObjects, priority }),
20
+ read: (r) => ('furniture' in r ? r.furniture : undefined),
21
+ near: [FURNITURE_NEAR_METRES, 17],
22
+ minZoom,
23
+ maxTiles,
24
+ maxInstances,
25
+ ...(options.before && { before: options.before }),
26
+ });
27
+ return layer;
28
+ };
29
+ //# sourceMappingURL=furniture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"furniture.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/furniture.ts"],"names":[],"mappings":"AAAA;;sFAEsF;AAGtF,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,iBAAiB,CAAC;AAE9D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;gCACgC;AAChC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAclC;+DAC+D;AAC/D,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,OAA2B,EAAE,UAA4B,EAAE,EAAc,EAAE;IACnG,MAAM,EAAE,OAAO,GAAG,IAAI,EAAE,QAAQ,GAAG,CAAC,EAAE,UAAU,GAAG,KAAK,EAAE,YAAY,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IAC3F,MAAM,KAAK,GAAG,CAAC,IAAgC,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC;IACzF,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE;QAC9B,0CAA0C;QAC1C,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;QAC/D,4FAA4F;QAC5F,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,CAAC,IAAI,KAAK,MAAM;QACrD,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,UAAU,EAAE,QAAQ,EAAE,CAAC;QAC7F,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,WAAW,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC;QACzD,IAAI,EAAE,CAAC,qBAAqB,EAAE,EAAE,CAAC;QACjC,OAAO;QACP,QAAQ;QACR,YAAY;QACZ,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;KAClD,CAAC,CAAC;IAEH,OAAO,KAAK,CAAC;AACf,CAAC,CAAC","sourcesContent":["/** The street furniture of a vector basemap (`VectorTiles.furniture`): 3D models placed by the workers from its\n * points of interest of the street (bus shelters, waste baskets, post boxes, drinking fountains, bicycle racks), each\n * facing its street, and benches along the pedestrian streets and the parks' paths */\n\nimport type { Layer, ModelLayer } from '../../layers/layers.ts';\nimport { FURNITURE, FURNITURE_MODELS } from '../furniture.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { placed } from './placed.ts';\n\n/** Metres around the ground under the camera where every piece is drawn at zoom 17 (twice as far a zoom level out);\n * past them, fewer and fewer */\nconst FURNITURE_NEAR_METRES = 160;\n\n/** The options of `VectorTiles.furniture` */\nexport interface FurnitureOptions {\n /** From this zoom on (default 16.5) */\n minZoom?: number;\n maxTiles?: number;\n /** Pieces in a tile at most (default 20000) */\n maxObjects?: number;\n /** Pieces drawn at most (default 12000) */\n maxInstances?: number;\n before?: Layer;\n}\n\n/** The layers of the street furniture, a kind each (`FURNITURE`'s order: shelters, bins, post boxes, fountains, racks,\n * benches): the first holds the others (`Layer.companions`) */\nexport const furniture = (context: VectorTilesContext, options: FurnitureOptions = {}): ModelLayer => {\n const { minZoom = 16.5, maxTiles = 9, maxObjects = 20000, maxInstances = 12000 } = options;\n const model = (kind: (typeof FURNITURE)[number]) => ({ data: FURNITURE_MODELS[kind]() });\n const [layer] = placed(context, {\n // A model per kind, in the workers' order\n models: [model(FURNITURE[0]), ...FURNITURE.slice(1).map(model)],\n // The source of the style's buildings and streets: OpenMapTiles' layers read from its tiles\n layers: (l) => l.type === 'line' || l.type === 'fill',\n work: (key, z, x, y, priority) => ({ type: 'furniture', key, z, x, y, maxObjects, priority }),\n read: (r) => ('furniture' in r ? r.furniture : undefined),\n near: [FURNITURE_NEAR_METRES, 17],\n minZoom,\n maxTiles,\n maxInstances,\n ...(options.before && { before: options.before }),\n });\n\n return layer;\n};\n"]}
@@ -154,6 +154,9 @@ export const labels = (context, options = {}) => {
154
154
  if (raised !== occluded) {
155
155
  occluded = raised;
156
156
  symbol.setStyle({ occluded, height: occluded ? (p) => p.height ?? 0 : 0 });
157
+ // The labels asked again, with their heights or without
158
+ tiles.clear();
159
+ shown = '';
157
160
  }
158
161
  const run = ++generation;
159
162
  const camera = map.getCamera();
@@ -201,6 +204,7 @@ export const labels = (context, options = {}) => {
201
204
  y,
202
205
  priority: nearPriority(index),
203
206
  ...(deeper === undefined ? {} : { zoom: Number(deeper) }),
207
+ ...(occluded ? { roofs: true } : {}),
204
208
  };
205
209
  const p = context.request(tz, x, y, work).then((r) => tileLabels('labels' in r ? r.labels : []), () => {
206
210
  // A network error is not kept: the tile is asked for again on the next update
@@ -240,7 +244,10 @@ export const labels = (context, options = {}) => {
240
244
  refresh();
241
245
  }, LABELS_MOVE_REFRESH_MS);
242
246
  };
243
- context.cleanup.push(map.on('move', schedule), map.on('moveend', refresh), () => {
247
+ const [offMove, offEnd] = [map.on('move', schedule), map.on('moveend', refresh)];
248
+ context.stopWith(symbol, () => {
249
+ offMove();
250
+ offEnd();
244
251
  clearTimeout(timer);
245
252
  clearTimeout(retry);
246
253
  });
@@ -1 +1 @@
1
- {"version":3,"file":"labels.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/labels.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The labels of a vector basemap (`VectorTiles.labels`): the label candidates the workers list for each vector tile in\n * view, shaped in the page once per tile, placed by the engine in a symbol layer of their own.\n */\n\nimport { ExtrusionLayer } from '../../layers/extrusions.ts';\nimport type { Feature, Size } from '../../layers/features.ts';\nimport type { Layer } from '../../layers/layers.ts';\nimport type { SymbolLayer } from '../../layers/symbols.ts';\nimport { VectorLayer } from '../../layers/vectors.ts';\nimport type { Anchor } from '../../ui/overlay.ts';\nimport { isRecord } from '../../util/guards.ts';\nimport { Lru } from '../../util/lru.ts';\nimport type { BasemapWork } from '../../workers/basemap.worker.ts';\nimport type { Json, LabelCandidate, StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { styleFonts } from './style.ts';\nimport { MAX_TILES, nearPriority, parseTileKey, tileKey, tilesAround, tileTriples } from './tiles.ts';\n\n/** Pause before the labels of tiles that failed are asked for again, when no move brings an update (ms) */\nconst RETRY_LABELS_MS = 3000;\n\n/** Milliseconds between two updates of the labels while the camera moves */\nconst LABELS_MOVE_REFRESH_MS = 250;\n\n/** Vector tiles' labels kept, shaped, the least recently used dropped past it */\nconst CACHED_TILES = 256;\n\n/** Text or icon size of a style (a number, legacy stops, or the stops of a zoom expression made by the worker) as a\n * size for the symbol layer */\nexport const size = (value: Json, fallback = 16): Size => {\n const stop = (s: Json): [number, number] => {\n const [z, v] = Array.isArray(s) ? s : [];\n\n return [Number(z), Number(v)];\n };\n\n if (typeof value === 'number') return value;\n if (Array.isArray(value) && value.length > 0 && value.every(Array.isArray)) return value.map(stop);\n if (isRecord(value) && Array.isArray(value.stops)) return value.stops.map(stop);\n\n return fallback;\n};\n\n/** The anchors of the symbol layer */\nconst ANCHORS: ReadonlySet<string> = new Set<Anchor>([\n 'center',\n 'top',\n 'bottom',\n 'left',\n 'right',\n 'top-left',\n 'top-right',\n 'bottom-left',\n 'bottom-right',\n]);\n\nconst isAnchor = (value: string | undefined): value is Anchor => value !== undefined && ANCHORS.has(value);\n\n/** A style's anchor (`text-anchor`, `icon-anchor`) for the symbol layer: `center` if it is none */\nconst anchor = (value: string | undefined): Anchor => (isAnchor(value) ? value : 'center');\n\n/** The labels of a vector tile: features by style layer (its index in the style), the higher layers first */\ntype TileLabels = [layer: number, features: Feature<LabelCandidate>[]][];\n\n/** Where a candidate is labelled: the line around a text that follows it, a short line along a line's direction (its\n * middle the anchor), or its point */\nconst geometryOf = (p: LabelCandidate): Feature<LabelCandidate>['geometry'] => {\n const { path, along } = p;\n\n if (path) {\n return {\n type: 'LineString',\n coordinates: Array.from({ length: path.length / 2 }, (_, i) => [path[i * 2] ?? 0, path[i * 2 + 1] ?? 0]),\n };\n }\n if (along) {\n return {\n type: 'LineString',\n coordinates: [\n [p.lon - along[0] / 2, p.lat - along[1] / 2],\n [p.lon + along[0] / 2, p.lat + along[1] / 2],\n ],\n };\n }\n\n return { type: 'Point', coordinates: [p.lon, p.lat] };\n};\n\n/** A tile's label candidates as features, by style layer */\nexport const tileLabels = (candidates: readonly LabelCandidate[]): TileLabels => {\n const byLayer = new Map<number, Feature<LabelCandidate>[]>();\n\n candidates.forEach((p) => {\n const feature: Feature<LabelCandidate> = {\n type: 'Feature',\n properties: p,\n geometry: geometryOf(p),\n };\n const list = byLayer.get(p.layer);\n\n if (list) list.push(feature);\n else byLayer.set(p.layer, [feature]);\n });\n\n return [...byLayer].sort((a, b) => b[0] - a[0]);\n};\n\n/** The key of a vector tile's labels: `z/x/y`, then `@zoom` when they are those of a deeper zoom than the tile's */\nconst labelsKey = (z: number, x: number, y: number, zoom: number): string =>\n `${tileKey(z, x, y)}${zoom > z ? `@${zoom}` : ''}`;\n\n/** Whether a layer of the basemap raises its buildings: its extrusions, or a style layer `fill-extrusion` of its\n * vectors shown */\nconst raisesBuildings = (layer: Layer): boolean =>\n layer instanceof ExtrusionLayer ||\n (layer instanceof VectorLayer && layer.layers.some((l) => l.kind === 'extrusion' && l.visible));\n\n/** The options of `VectorTiles.labels` */\nexport interface LabelsOptions {\n layers?: (layer: StyleLayer) => boolean;\n maxTiles?: number;\n /** Hidden by the solids before them (the buildings, the trees, the models) and lifted onto the roofs (default: when\n * these tiles raise buildings; `true` for buildings raised by others, a `<VectorGeometry>` of the same style) */\n occluded?: boolean;\n}\n\nexport const labels = (context: VectorTilesContext, options: LabelsOptions = {}): SymbolLayer<LabelCandidate> => {\n const { map } = context;\n const { layers = () => true, maxTiles = MAX_TILES } = options;\n const symbol = map.addSymbols<LabelCandidate>({\n data: [],\n text: (p) => p.text,\n font: (p) => p.font,\n size: (p) => size(p.size),\n color: (p) => p.color,\n haloColor: (p) => p.haloColor,\n haloWidth: (p) => p.haloWidth,\n anchor: (p) => anchor(p.anchor),\n offset: (p) => p.offset,\n maxWidth: (p) => p.maxWidth,\n lineHeight: (p) => p.lineHeight,\n overlap: (p) => p.overlap,\n placement: (p) => (p.textAlong ? 'line' : 'point'),\n textOptional: (p) => p.textOptional === true,\n icon: (p) => (p.icon ? context.iconPrefix + p.icon.image : ''),\n iconSize: (p) => size(p.icon?.size ?? 1, 1),\n iconAnchor: (p) => anchor(p.icon?.anchor),\n iconOffset: (p) => p.icon?.offset ?? [0, 0],\n iconRotate: (p) => p.icon?.rotate ?? 0,\n iconRotationAlignment: (p) => p.icon?.alignment ?? 'viewport',\n iconOverlap: (p) => p.icon?.overlap ?? false,\n iconOptional: (p) => p.icon?.optional ?? false,\n iconTextFit: (p) => p.icon?.fit ?? 'none',\n iconTextFitPadding: (p) => p.icon?.padding ?? [0, 0, 0, 0],\n iconColor: (p) => p.icon?.color ?? '#000',\n iconOpacity: (p) => p.icon?.opacity ?? 1,\n });\n\n map.keepOnTop(symbol);\n context.layers.push(symbol);\n\n const renderer = context.ready.then(async ({ style }) => {\n // The style's fonts from its own glyphs\n if (style.glyphs) map.glyphs.register(style.glyphs, styleFonts(style));\n\n // Its icons from its sprites, before the first labels\n const icons = style.layers.some((l) => l.type === 'symbol' && l.layout?.['icon-image'] !== undefined);\n\n if (icons) await context.addSprites();\n\n // With the buildings: a label in one stands on its roof\n return context.renderer((l) => (l.type === 'symbol' && layers(l)) || l.type === 'fill-extrusion', []);\n });\n\n renderer.catch(() => undefined);\n\n /** The labels of the tiles, as features by style layer, the higher layers first: each list is given to the symbol\n * layer as a group, shaped once while the tile is kept */\n const tiles = new Lru<string, Promise<TileLabels>>(CACHED_TILES);\n let generation = 0;\n /** The tiles whose labels are shown */\n let shown = '';\n /** The update asked again after tiles failed */\n let retry = 0;\n /** The labels hidden by the buildings the basemap raises, those in one standing on its roof */\n let occluded = false;\n const update = async () => {\n if (context.destroyed()) return;\n\n const { key, maxzoom } = await renderer;\n const others = context.layers.filter((l) => l !== symbol);\n\n // Its vectors' style layers known first\n await Promise.all(others.map((l) => (l instanceof VectorLayer ? l.styled : undefined)));\n\n const raised = options.occluded ?? others.some(raisesBuildings);\n\n if (raised !== occluded) {\n occluded = raised;\n symbol.setStyle({ occluded, height: occluded ? (p) => p.height ?? 0 : 0 });\n }\n\n const run = ++generation;\n const camera = map.getCamera();\n const zoom = Math.max(0, Math.min(Math.floor(camera.zoom), 24));\n const ground = context.ground();\n const groundTiles = ground && map.hasLayer(ground) ? tileTriples(map.engine.wantedTiles(ground.id)) : [];\n const keys: string[] = [];\n\n if (groundTiles.length > 0) {\n // The ground's tiles, the nearest first: a tile so many levels coarser than the finest in view has its\n // labels of a zoom as many under the view's, past the source's deepest level those of that level at the zoom\n const top = groundTiles.reduce((t, [z]) => Math.max(t, z), 0);\n\n groundTiles.forEach(([z, x, y]) => {\n if (keys.length >= maxTiles) return;\n\n const at = Math.max(0, zoom - (top - z));\n const tz = Math.min(at, maxzoom, z);\n const shift = 2 ** (z - tz);\n const key = labelsKey(tz, Math.floor(x / shift), Math.floor(y / shift), at);\n\n if (!keys.includes(key)) keys.push(key);\n });\n } else {\n const z = Math.min(zoom, maxzoom);\n const wanted = tilesAround(map, camera, z, maxTiles);\n\n // Past the source's deepest level, its tiles' labels at the zoom of the view (the layers of the deeper zooms)\n keys.push(...wanted.map(([x, y]) => labelsKey(z, x, y, zoom)));\n }\n\n // The same tiles as the labels shown: nothing to do\n const set = keys.join(' ');\n\n if (set === shown) return;\n\n const lists = await Promise.all(\n keys.map((k, index) => {\n const cached = tiles.get(k);\n\n if (cached) return cached;\n\n const [tile = '', deeper] = k.split('@');\n const [tz, x, y] = parseTileKey(tile);\n // The nearest tiles first: the others wait for the raster tiles\n const work: BasemapWork = {\n type: 'labels',\n key,\n z: tz,\n x,\n y,\n priority: nearPriority(index),\n ...(deeper === undefined ? {} : { zoom: Number(deeper) }),\n };\n const p = context.request(tz, x, y, work).then(\n (r) => tileLabels('labels' in r ? r.labels : []),\n () => {\n // A network error is not kept: the tile is asked for again on the next update\n tiles.delete(k);\n\n return [];\n },\n );\n\n // A bounded cache of tiles' labels, the least recently used dropped\n tiles.set(k, p);\n\n return p;\n }),\n );\n\n if (run !== generation || context.destroyed()) return;\n // A tile that failed is missing: the next update asks for it again, after a pause if no move brings one\n shown = keys.every((k) => tiles.has(k)) ? set : '';\n if (shown === '' && !retry) {\n retry = window.setTimeout(() => {\n retry = 0;\n refresh();\n }, RETRY_LABELS_MS);\n }\n\n // The labels of the higher style layers first: they win the collisions; for each style layer, the tiles nearest\n // to the center first\n const layerIds = [...new Set(lists.flatMap((list) => list.map(([layer]) => layer)))].sort((a, b) => b - a);\n const groups = layerIds.flatMap((layer) =>\n lists.map((list) => list.find(([l]) => l === layer)?.[1]).filter((group) => group !== undefined),\n );\n\n symbol.setGroups(groups);\n };\n // The style failed to load: reported by `ready`\n const refresh = () => {\n update().catch(() => undefined);\n };\n let timer = 0;\n const schedule = () => {\n if (timer) return;\n timer = window.setTimeout(() => {\n timer = 0;\n refresh();\n }, LABELS_MOVE_REFRESH_MS);\n };\n\n context.cleanup.push(map.on('move', schedule), map.on('moveend', refresh), () => {\n clearTimeout(timer);\n clearTimeout(retry);\n });\n refresh();\n\n return symbol;\n};\n"]}
1
+ {"version":3,"file":"labels.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/labels.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAI5D,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AAEtD,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAIxC,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,YAAY,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAEtG,2GAA2G;AAC3G,MAAM,eAAe,GAAG,IAAI,CAAC;AAE7B,4EAA4E;AAC5E,MAAM,sBAAsB,GAAG,GAAG,CAAC;AAEnC,iFAAiF;AACjF,MAAM,YAAY,GAAG,GAAG,CAAC;AAEzB;+BAC+B;AAC/B,MAAM,CAAC,MAAM,IAAI,GAAG,CAAC,KAAW,EAAE,QAAQ,GAAG,EAAE,EAAQ,EAAE;IACvD,MAAM,IAAI,GAAG,CAAC,CAAO,EAAoB,EAAE;QACzC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAEzC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC;IAChC,CAAC,CAAC;IAEF,IAAI,OAAO,KAAK,KAAK,QAAQ;QAAE,OAAO,KAAK,CAAC;IAC5C,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,OAAO,CAAC;QAAE,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IACnG,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC;QAAE,OAAO,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAEhF,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,sCAAsC;AACtC,MAAM,OAAO,GAAwB,IAAI,GAAG,CAAS;IACnD,QAAQ;IACR,KAAK;IACL,QAAQ;IACR,MAAM;IACN,OAAO;IACP,UAAU;IACV,WAAW;IACX,aAAa;IACb,cAAc;CACf,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,CAAC,KAAyB,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,IAAI,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;AAE3G,mGAAmG;AACnG,MAAM,MAAM,GAAG,CAAC,KAAyB,EAAU,EAAE,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAK3F;sCACsC;AACtC,MAAM,UAAU,GAAG,CAAC,CAAiB,EAAuC,EAAE;IAC5E,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;IAE1B,IAAI,IAAI,EAAE,CAAC;QACT,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;SACzG,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,EAAE,CAAC;QACV,OAAO;YACL,IAAI,EAAE,YAAY;YAClB,WAAW,EAAE;gBACX,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;gBAC5C,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;aAC7C;SACF,CAAC;IACJ,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,WAAW,EAAE,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC;AACxD,CAAC,CAAC;AAEF,4DAA4D;AAC5D,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,UAAqC,EAAc,EAAE;IAC9E,MAAM,OAAO,GAAG,IAAI,GAAG,EAAqC,CAAC;IAE7D,UAAU,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE;QACvB,MAAM,OAAO,GAA4B;YACvC,IAAI,EAAE,SAAS;YACf,UAAU,EAAE,CAAC;YACb,QAAQ,EAAE,UAAU,CAAC,CAAC,CAAC;SACxB,CAAC;QACF,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC;QAElC,IAAI,IAAI;YAAE,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;;YACxB,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;IAEH,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClD,CAAC,CAAC;AAEF,oHAAoH;AACpH,MAAM,SAAS,GAAG,CAAC,CAAS,EAAE,CAAS,EAAE,CAAS,EAAE,IAAY,EAAU,EAAE,CAC1E,GAAG,OAAO,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAErD;mBACmB;AACnB,MAAM,eAAe,GAAG,CAAC,KAAY,EAAW,EAAE,CAChD,KAAK,YAAY,cAAc;IAC/B,CAAC,KAAK,YAAY,WAAW,IAAI,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,WAAW,IAAI,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC;AAWlG,MAAM,CAAC,MAAM,MAAM,GAAG,CAAC,OAA2B,EAAE,UAAyB,EAAE,EAA+B,EAAE;IAC9G,MAAM,EAAE,GAAG,EAAE,GAAG,OAAO,CAAC;IACxB,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,CAAC,IAAI,EAAE,QAAQ,GAAG,SAAS,EAAE,GAAG,OAAO,CAAC;IAC9D,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,CAAiB;QAC5C,IAAI,EAAE,EAAE;QACR,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI;QACnB,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI;QACnB,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QACzB,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,KAAK;QACrB,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS;QAC7B,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS;QAC7B,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;QAC/B,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM;QACvB,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ;QAC3B,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU;QAC/B,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO;QACzB,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,OAAO,CAAC;QAClD,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,KAAK,IAAI;QAC5C,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,OAAO,CAAC,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC;QAC9D,QAAQ,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,EAAE,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC;QAC3C,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,CAAC;QACzC,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC,CAAC,EAAE,CAAC,CAAC;QAC3C,UAAU,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,MAAM,IAAI,CAAC;QACtC,qBAAqB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,SAAS,IAAI,UAAU;QAC7D,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,IAAI,KAAK;QAC5C,YAAY,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,QAAQ,IAAI,KAAK;QAC9C,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,IAAI,MAAM;QACzC,kBAAkB,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,IAAI,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC;QAC1D,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,MAAM;QACzC,WAAW,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,OAAO,IAAI,CAAC;KACzC,CAAC,CAAC;IAEH,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACtB,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IAE5B,MAAM,QAAQ,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE;QACtD,wCAAwC;QACxC,IAAI,KAAK,CAAC,MAAM;YAAE,GAAG,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,KAAK,CAAC,CAAC,CAAC;QAEvE,sDAAsD;QACtD,MAAM,KAAK,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC,YAAY,CAAC,KAAK,SAAS,CAAC,CAAC;QAEtG,IAAI,KAAK;YAAE,MAAM,OAAO,CAAC,UAAU,EAAE,CAAC;QAEtC,wDAAwD;QACxD,OAAO,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,KAAK,QAAQ,IAAI,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,KAAK,gBAAgB,EAAE,EAAE,CAAC,CAAC;IACxG,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAEhC;8DAC0D;IAC1D,MAAM,KAAK,GAAG,IAAI,GAAG,CAA8B,YAAY,CAAC,CAAC;IACjE,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,uCAAuC;IACvC,IAAI,KAAK,GAAG,EAAE,CAAC;IACf,gDAAgD;IAChD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,+FAA+F;IAC/F,IAAI,QAAQ,GAAG,KAAK,CAAC;IACrB,MAAM,MAAM,GAAG,KAAK,IAAI,EAAE;QACxB,IAAI,OAAO,CAAC,SAAS,EAAE;YAAE,OAAO;QAEhC,MAAM,EAAE,GAAG,EAAE,OAAO,EAAE,GAAG,MAAM,QAAQ,CAAC;QACxC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC;QAE1D,wCAAwC;QACxC,MAAM,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,YAAY,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC;QAExF,MAAM,MAAM,GAAG,OAAO,CAAC,QAAQ,IAAI,MAAM,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAEhE,IAAI,MAAM,KAAK,QAAQ,EAAE,CAAC;YACxB,QAAQ,GAAG,MAAM,CAAC;YAClB,MAAM,CAAC,QAAQ,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAC3E,wDAAwD;YACxD,KAAK,CAAC,KAAK,EAAE,CAAC;YACd,KAAK,GAAG,EAAE,CAAC;QACb,CAAC;QAED,MAAM,GAAG,GAAG,EAAE,UAAU,CAAC;QACzB,MAAM,MAAM,GAAG,GAAG,CAAC,SAAS,EAAE,CAAC;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QAChE,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QAChC,MAAM,WAAW,GAAG,MAAM,IAAI,GAAG,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACzG,MAAM,IAAI,GAAa,EAAE,CAAC;QAE1B,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC3B,uGAAuG;YACvG,6GAA6G;YAC7G,MAAM,GAAG,GAAG,WAAW,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAE9D,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE;gBAChC,IAAI,IAAI,CAAC,MAAM,IAAI,QAAQ;oBAAE,OAAO;gBAEpC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC,CAAC;gBACzC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC;gBACpC,MAAM,KAAK,GAAG,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC;gBAC5B,MAAM,GAAG,GAAG,SAAS,CAAC,EAAE,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,KAAK,CAAC,EAAE,EAAE,CAAC,CAAC;gBAE5E,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC;oBAAE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAC1C,CAAC,CAAC,CAAC;QACL,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;YAClC,MAAM,MAAM,GAAG,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,CAAC,EAAE,QAAQ,CAAC,CAAC;YAErD,8GAA8G;YAC9G,IAAI,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QACjE,CAAC;QAED,oDAAoD;QACpD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAE3B,IAAI,GAAG,KAAK,KAAK;YAAE,OAAO;QAE1B,MAAM,KAAK,GAAG,MAAM,OAAO,CAAC,GAAG,CAC7B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE;YACpB,MAAM,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;YAE5B,IAAI,MAAM;gBAAE,OAAO,MAAM,CAAC;YAE1B,MAAM,CAAC,IAAI,GAAG,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;YACzC,MAAM,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,GAAG,YAAY,CAAC,IAAI,CAAC,CAAC;YACtC,gEAAgE;YAChE,MAAM,IAAI,GAAgB;gBACxB,IAAI,EAAE,QAAQ;gBACd,GAAG;gBACH,CAAC,EAAE,EAAE;gBACL,CAAC;gBACD,CAAC;gBACD,QAAQ,EAAE,YAAY,CAAC,KAAK,CAAC;gBAC7B,GAAG,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;gBACzD,GAAG,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;aACrC,CAAC;YACF,MAAM,CAAC,GAAG,OAAO,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,IAAI,CAC5C,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAChD,GAAG,EAAE;gBACH,8EAA8E;gBAC9E,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;gBAEhB,OAAO,EAAE,CAAC;YACZ,CAAC,CACF,CAAC;YAEF,oEAAoE;YACpE,KAAK,CAAC,GAAG,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;YAEhB,OAAO,CAAC,CAAC;QACX,CAAC,CAAC,CACH,CAAC;QAEF,IAAI,GAAG,KAAK,UAAU,IAAI,OAAO,CAAC,SAAS,EAAE;YAAE,OAAO;QACtD,wGAAwG;QACxG,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;QACnD,IAAI,KAAK,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC;YAC3B,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;gBAC7B,KAAK,GAAG,CAAC,CAAC;gBACV,OAAO,EAAE,CAAC;YACZ,CAAC,EAAE,eAAe,CAAC,CAAC;QACtB,CAAC;QAED,gHAAgH;QAChH,sBAAsB;QACtB,MAAM,QAAQ,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAC3G,MAAM,MAAM,GAAG,QAAQ,CAAC,OAAO,CAAC,CAAC,KAAK,EAAE,EAAE,CACxC,KAAK,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CACjG,CAAC;QAEF,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IAC3B,CAAC,CAAC;IACF,gDAAgD;IAChD,MAAM,OAAO,GAAG,GAAG,EAAE;QACnB,MAAM,EAAE,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAClC,CAAC,CAAC;IACF,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,MAAM,QAAQ,GAAG,GAAG,EAAE;QACpB,IAAI,KAAK;YAAE,OAAO;QAClB,KAAK,GAAG,MAAM,CAAC,UAAU,CAAC,GAAG,EAAE;YAC7B,KAAK,GAAG,CAAC,CAAC;YACV,OAAO,EAAE,CAAC;QACZ,CAAC,EAAE,sBAAsB,CAAC,CAAC;IAC7B,CAAC,CAAC;IAEF,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,QAAQ,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,CAAC;IAEjF,OAAO,CAAC,QAAQ,CAAC,MAAM,EAAE,GAAG,EAAE;QAC5B,OAAO,EAAE,CAAC;QACV,MAAM,EAAE,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;QACpB,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC,CAAC,CAAC;IACH,OAAO,EAAE,CAAC;IAEV,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC","sourcesContent":["/**\n * The labels of a vector basemap (`VectorTiles.labels`): the label candidates the workers list for each vector tile in\n * view, shaped in the page once per tile, placed by the engine in a symbol layer of their own.\n */\n\nimport { ExtrusionLayer } from '../../layers/extrusions.ts';\nimport type { Feature, Size } from '../../layers/features.ts';\nimport type { Layer } from '../../layers/layers.ts';\nimport type { SymbolLayer } from '../../layers/symbols.ts';\nimport { VectorLayer } from '../../layers/vectors.ts';\nimport type { Anchor } from '../../ui/overlay.ts';\nimport { isRecord } from '../../util/guards.ts';\nimport { Lru } from '../../util/lru.ts';\nimport type { BasemapWork } from '../../workers/basemap.worker.ts';\nimport type { Json, LabelCandidate, StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { styleFonts } from './style.ts';\nimport { MAX_TILES, nearPriority, parseTileKey, tileKey, tilesAround, tileTriples } from './tiles.ts';\n\n/** Pause before the labels of tiles that failed are asked for again, when no move brings an update (ms) */\nconst RETRY_LABELS_MS = 3000;\n\n/** Milliseconds between two updates of the labels while the camera moves */\nconst LABELS_MOVE_REFRESH_MS = 250;\n\n/** Vector tiles' labels kept, shaped, the least recently used dropped past it */\nconst CACHED_TILES = 256;\n\n/** Text or icon size of a style (a number, legacy stops, or the stops of a zoom expression made by the worker) as a\n * size for the symbol layer */\nexport const size = (value: Json, fallback = 16): Size => {\n const stop = (s: Json): [number, number] => {\n const [z, v] = Array.isArray(s) ? s : [];\n\n return [Number(z), Number(v)];\n };\n\n if (typeof value === 'number') return value;\n if (Array.isArray(value) && value.length > 0 && value.every(Array.isArray)) return value.map(stop);\n if (isRecord(value) && Array.isArray(value.stops)) return value.stops.map(stop);\n\n return fallback;\n};\n\n/** The anchors of the symbol layer */\nconst ANCHORS: ReadonlySet<string> = new Set<Anchor>([\n 'center',\n 'top',\n 'bottom',\n 'left',\n 'right',\n 'top-left',\n 'top-right',\n 'bottom-left',\n 'bottom-right',\n]);\n\nconst isAnchor = (value: string | undefined): value is Anchor => value !== undefined && ANCHORS.has(value);\n\n/** A style's anchor (`text-anchor`, `icon-anchor`) for the symbol layer: `center` if it is none */\nconst anchor = (value: string | undefined): Anchor => (isAnchor(value) ? value : 'center');\n\n/** The labels of a vector tile: features by style layer (its index in the style), the higher layers first */\ntype TileLabels = [layer: number, features: Feature<LabelCandidate>[]][];\n\n/** Where a candidate is labelled: the line around a text that follows it, a short line along a line's direction (its\n * middle the anchor), or its point */\nconst geometryOf = (p: LabelCandidate): Feature<LabelCandidate>['geometry'] => {\n const { path, along } = p;\n\n if (path) {\n return {\n type: 'LineString',\n coordinates: Array.from({ length: path.length / 2 }, (_, i) => [path[i * 2] ?? 0, path[i * 2 + 1] ?? 0]),\n };\n }\n if (along) {\n return {\n type: 'LineString',\n coordinates: [\n [p.lon - along[0] / 2, p.lat - along[1] / 2],\n [p.lon + along[0] / 2, p.lat + along[1] / 2],\n ],\n };\n }\n\n return { type: 'Point', coordinates: [p.lon, p.lat] };\n};\n\n/** A tile's label candidates as features, by style layer */\nexport const tileLabels = (candidates: readonly LabelCandidate[]): TileLabels => {\n const byLayer = new Map<number, Feature<LabelCandidate>[]>();\n\n candidates.forEach((p) => {\n const feature: Feature<LabelCandidate> = {\n type: 'Feature',\n properties: p,\n geometry: geometryOf(p),\n };\n const list = byLayer.get(p.layer);\n\n if (list) list.push(feature);\n else byLayer.set(p.layer, [feature]);\n });\n\n return [...byLayer].sort((a, b) => b[0] - a[0]);\n};\n\n/** The key of a vector tile's labels: `z/x/y`, then `@zoom` when they are those of a deeper zoom than the tile's */\nconst labelsKey = (z: number, x: number, y: number, zoom: number): string =>\n `${tileKey(z, x, y)}${zoom > z ? `@${zoom}` : ''}`;\n\n/** Whether a layer of the basemap raises its buildings: its extrusions, or a style layer `fill-extrusion` of its\n * vectors shown */\nconst raisesBuildings = (layer: Layer): boolean =>\n layer instanceof ExtrusionLayer ||\n (layer instanceof VectorLayer && layer.layers.some((l) => l.kind === 'extrusion' && l.visible));\n\n/** The options of `VectorTiles.labels` */\nexport interface LabelsOptions {\n layers?: (layer: StyleLayer) => boolean;\n maxTiles?: number;\n /** Hidden by the solids before them (the buildings, the trees, the models) and lifted onto the roofs (default: when\n * these tiles raise buildings; `true` for buildings raised by others, a `<VectorGeometry>` of the same style) */\n occluded?: boolean;\n}\n\nexport const labels = (context: VectorTilesContext, options: LabelsOptions = {}): SymbolLayer<LabelCandidate> => {\n const { map } = context;\n const { layers = () => true, maxTiles = MAX_TILES } = options;\n const symbol = map.addSymbols<LabelCandidate>({\n data: [],\n text: (p) => p.text,\n font: (p) => p.font,\n size: (p) => size(p.size),\n color: (p) => p.color,\n haloColor: (p) => p.haloColor,\n haloWidth: (p) => p.haloWidth,\n anchor: (p) => anchor(p.anchor),\n offset: (p) => p.offset,\n maxWidth: (p) => p.maxWidth,\n lineHeight: (p) => p.lineHeight,\n overlap: (p) => p.overlap,\n placement: (p) => (p.textAlong ? 'line' : 'point'),\n textOptional: (p) => p.textOptional === true,\n icon: (p) => (p.icon ? context.iconPrefix + p.icon.image : ''),\n iconSize: (p) => size(p.icon?.size ?? 1, 1),\n iconAnchor: (p) => anchor(p.icon?.anchor),\n iconOffset: (p) => p.icon?.offset ?? [0, 0],\n iconRotate: (p) => p.icon?.rotate ?? 0,\n iconRotationAlignment: (p) => p.icon?.alignment ?? 'viewport',\n iconOverlap: (p) => p.icon?.overlap ?? false,\n iconOptional: (p) => p.icon?.optional ?? false,\n iconTextFit: (p) => p.icon?.fit ?? 'none',\n iconTextFitPadding: (p) => p.icon?.padding ?? [0, 0, 0, 0],\n iconColor: (p) => p.icon?.color ?? '#000',\n iconOpacity: (p) => p.icon?.opacity ?? 1,\n });\n\n map.keepOnTop(symbol);\n context.layers.push(symbol);\n\n const renderer = context.ready.then(async ({ style }) => {\n // The style's fonts from its own glyphs\n if (style.glyphs) map.glyphs.register(style.glyphs, styleFonts(style));\n\n // Its icons from its sprites, before the first labels\n const icons = style.layers.some((l) => l.type === 'symbol' && l.layout?.['icon-image'] !== undefined);\n\n if (icons) await context.addSprites();\n\n // With the buildings: a label in one stands on its roof\n return context.renderer((l) => (l.type === 'symbol' && layers(l)) || l.type === 'fill-extrusion', []);\n });\n\n renderer.catch(() => undefined);\n\n /** The labels of the tiles, as features by style layer, the higher layers first: each list is given to the symbol\n * layer as a group, shaped once while the tile is kept */\n const tiles = new Lru<string, Promise<TileLabels>>(CACHED_TILES);\n let generation = 0;\n /** The tiles whose labels are shown */\n let shown = '';\n /** The update asked again after tiles failed */\n let retry = 0;\n /** The labels hidden by the buildings the basemap raises, those in one standing on its roof */\n let occluded = false;\n const update = async () => {\n if (context.destroyed()) return;\n\n const { key, maxzoom } = await renderer;\n const others = context.layers.filter((l) => l !== symbol);\n\n // Its vectors' style layers known first\n await Promise.all(others.map((l) => (l instanceof VectorLayer ? l.styled : undefined)));\n\n const raised = options.occluded ?? others.some(raisesBuildings);\n\n if (raised !== occluded) {\n occluded = raised;\n symbol.setStyle({ occluded, height: occluded ? (p) => p.height ?? 0 : 0 });\n // The labels asked again, with their heights or without\n tiles.clear();\n shown = '';\n }\n\n const run = ++generation;\n const camera = map.getCamera();\n const zoom = Math.max(0, Math.min(Math.floor(camera.zoom), 24));\n const ground = context.ground();\n const groundTiles = ground && map.hasLayer(ground) ? tileTriples(map.engine.wantedTiles(ground.id)) : [];\n const keys: string[] = [];\n\n if (groundTiles.length > 0) {\n // The ground's tiles, the nearest first: a tile so many levels coarser than the finest in view has its\n // labels of a zoom as many under the view's, past the source's deepest level those of that level at the zoom\n const top = groundTiles.reduce((t, [z]) => Math.max(t, z), 0);\n\n groundTiles.forEach(([z, x, y]) => {\n if (keys.length >= maxTiles) return;\n\n const at = Math.max(0, zoom - (top - z));\n const tz = Math.min(at, maxzoom, z);\n const shift = 2 ** (z - tz);\n const key = labelsKey(tz, Math.floor(x / shift), Math.floor(y / shift), at);\n\n if (!keys.includes(key)) keys.push(key);\n });\n } else {\n const z = Math.min(zoom, maxzoom);\n const wanted = tilesAround(map, camera, z, maxTiles);\n\n // Past the source's deepest level, its tiles' labels at the zoom of the view (the layers of the deeper zooms)\n keys.push(...wanted.map(([x, y]) => labelsKey(z, x, y, zoom)));\n }\n\n // The same tiles as the labels shown: nothing to do\n const set = keys.join(' ');\n\n if (set === shown) return;\n\n const lists = await Promise.all(\n keys.map((k, index) => {\n const cached = tiles.get(k);\n\n if (cached) return cached;\n\n const [tile = '', deeper] = k.split('@');\n const [tz, x, y] = parseTileKey(tile);\n // The nearest tiles first: the others wait for the raster tiles\n const work: BasemapWork = {\n type: 'labels',\n key,\n z: tz,\n x,\n y,\n priority: nearPriority(index),\n ...(deeper === undefined ? {} : { zoom: Number(deeper) }),\n ...(occluded ? { roofs: true } : {}),\n };\n const p = context.request(tz, x, y, work).then(\n (r) => tileLabels('labels' in r ? r.labels : []),\n () => {\n // A network error is not kept: the tile is asked for again on the next update\n tiles.delete(k);\n\n return [];\n },\n );\n\n // A bounded cache of tiles' labels, the least recently used dropped\n tiles.set(k, p);\n\n return p;\n }),\n );\n\n if (run !== generation || context.destroyed()) return;\n // A tile that failed is missing: the next update asks for it again, after a pause if no move brings one\n shown = keys.every((k) => tiles.has(k)) ? set : '';\n if (shown === '' && !retry) {\n retry = window.setTimeout(() => {\n retry = 0;\n refresh();\n }, RETRY_LABELS_MS);\n }\n\n // The labels of the higher style layers first: they win the collisions; for each style layer, the tiles nearest\n // to the center first\n const layerIds = [...new Set(lists.flatMap((list) => list.map(([layer]) => layer)))].sort((a, b) => b - a);\n const groups = layerIds.flatMap((layer) =>\n lists.map((list) => list.find(([l]) => l === layer)?.[1]).filter((group) => group !== undefined),\n );\n\n symbol.setGroups(groups);\n };\n // The style failed to load: reported by `ready`\n const refresh = () => {\n update().catch(() => undefined);\n };\n let timer = 0;\n const schedule = () => {\n if (timer) return;\n timer = window.setTimeout(() => {\n timer = 0;\n refresh();\n }, LABELS_MOVE_REFRESH_MS);\n };\n\n const [offMove, offEnd] = [map.on('move', schedule), map.on('moveend', refresh)];\n\n context.stopWith(symbol, () => {\n offMove();\n offEnd();\n clearTimeout(timer);\n clearTimeout(retry);\n });\n refresh();\n\n return symbol;\n};\n"]}
@@ -1,90 +1,25 @@
1
1
  /** The street lamps of a vector basemap (`VectorTiles.lamps`): 3D models placed by the workers along its streets, lit at
2
2
  * night */
3
3
  import { LAMP_HEAD, lampModel } from "../furniture.js";
4
- import { TREE_NUMBERS } from "../trees.js";
5
- import { TileRequests } from "./requests.js";
6
- import { nearPriority, tileKey, tilesAround } from "./tiles.js";
7
- import { followWhenMoved, groundUnderCamera, METRES_PER_DEGREE } from "./trees.js";
4
+ import { placed } from "./placed.js";
8
5
  import { isStreet } from "./vectors.js";
9
6
  /** Metres around the ground under the camera where every lamp is drawn at zoom 17 (twice as far a zoom level out);
10
7
  * past them, fewer and fewer */
11
8
  const LAMPS_NEAR_METRES = 250;
12
9
  export const lamps = (context, options = {}) => {
13
- const { map } = context;
14
10
  const { layers = isStreet, spacing = 30, minZoom = 16, maxTiles = 9, maxLamps = 20000, maxInstances = 15000, light = '#ffd9a0', } = options;
15
- const layer = map.addModels({
16
- data: lampModel(),
17
- instances: [],
18
- ...(options.before ? { before: options.before } : {}),
11
+ const [layer] = placed(context, {
12
+ models: [{ data: lampModel() }],
13
+ layers: (l) => l.type === 'line' && layers(l),
14
+ work: (key, z, x, y, priority) => ({ type: 'lamps', key, z, x, y, spacing, maxLamps, priority }),
15
+ read: (r) => ('lamps' in r ? r.lamps : undefined),
16
+ near: [LAMPS_NEAR_METRES, 17],
17
+ minZoom,
18
+ maxTiles,
19
+ maxInstances,
20
+ ...(options.before && { before: options.before }),
19
21
  });
20
- const renderer = context.renderer((l) => l.type === 'line' && layers(l), []);
21
22
  layer.setGlow(LAMP_HEAD, light);
22
- renderer.catch(() => undefined);
23
- context.layers.push(layer);
24
- const requests = new TileRequests();
25
- const found = new Map();
26
- /** The lamps drawn: all of them near the ground under the camera, past it those of a rank under (near / distance)²,
27
- * at most `maxInstances` (past it, the rank kept lowered in proportion: no sort) */
28
- const send = () => {
29
- const { center, zoom } = map.getCamera();
30
- const cos = Math.cos((center[1] * Math.PI) / 180);
31
- const [ex, ey, back] = groundUnderCamera(map);
32
- const near = LAMPS_NEAR_METRES * 2 ** (17 - zoom) + back;
33
- const each = (keep) => {
34
- found.forEach((t) => {
35
- for (let i = 0; i < t.length / TREE_NUMBERS; i += 1) {
36
- const dx = ((t[i * TREE_NUMBERS] ?? 0) - center[0]) * METRES_PER_DEGREE * cos - ex;
37
- const dy = ((t[i * TREE_NUMBERS + 1] ?? 0) - center[1]) * METRES_PER_DEGREE - ey;
38
- const score = (t[i * TREE_NUMBERS + 4] ?? 0) * Math.max(1, (dx * dx + dy * dy) / (near * near));
39
- if (score < 1)
40
- keep(t, i, score);
41
- }
42
- });
43
- };
44
- let count = 0;
45
- each(() => {
46
- count += 1;
47
- });
48
- const limit = Math.min(1, maxInstances / Math.max(count, 1));
49
- const out = [];
50
- each((t, i, score) => {
51
- const at = i * TREE_NUMBERS;
52
- if (score < limit)
53
- out.push(t[at] ?? 0, t[at + 1] ?? 0, 0, t[at + 3] ?? 0, 0, 0, t[at + 2] ?? 1);
54
- });
55
- layer.setInstanceNumbers(Float64Array.from(out));
56
- };
57
- const update = async () => {
58
- if (context.destroyed())
59
- return;
60
- const { key, maxzoom } = await renderer;
61
- const camera = map.getCamera();
62
- const z = maxzoom;
63
- const wanted = camera.zoom < minZoom ? [] : tilesAround(map, camera, z, maxTiles);
64
- const keys = new Set(wanted.map(([x, y]) => tileKey(z, x, y)));
65
- // Out of view: dropped, or no longer asked for
66
- requests
67
- .keys()
68
- .filter((k) => !keys.has(k))
69
- .forEach((k) => {
70
- requests.drop(k);
71
- found.delete(k);
72
- });
73
- send();
74
- wanted.forEach(([x, y], index) => {
75
- const k = tileKey(z, x, y);
76
- if (requests.has(k))
77
- return;
78
- const work = { type: 'lamps', key, z, x, y, spacing, maxLamps, priority: nearPriority(index) };
79
- requests.ask(k, (signal) => context.request(z, x, y, work, signal), (r) => {
80
- if (!('lamps' in r))
81
- return;
82
- found.set(k, r.lamps);
83
- send();
84
- });
85
- });
86
- };
87
- context.followView(update, requests, followWhenMoved(map, (zoom) => LAMPS_NEAR_METRES * 2 ** (17 - zoom), send));
88
23
  return layer;
89
24
  };
90
25
  //# sourceMappingURL=lamps.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"lamps.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/lamps.ts"],"names":[],"mappings":"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","sourcesContent":["/** The street lamps of a vector basemap (`VectorTiles.lamps`): 3D models placed by the workers along its streets, lit at\n * night */\n\nimport type { Layer, ModelLayer } from '../../layers/layers.ts';\nimport type { BasemapWork } from '../../workers/basemap.worker.ts';\nimport { LAMP_HEAD, lampModel } from '../furniture.ts';\nimport { TREE_NUMBERS } from '../trees.ts';\nimport type { StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { TileRequests } from './requests.ts';\nimport { nearPriority, tileKey, tilesAround } from './tiles.ts';\nimport { followWhenMoved, groundUnderCamera, METRES_PER_DEGREE } from './trees.ts';\nimport { isStreet } from './vectors.ts';\n\n/** Metres around the ground under the camera where every lamp is drawn at zoom 17 (twice as far a zoom level out);\n * past them, fewer and fewer */\nconst LAMPS_NEAR_METRES = 250;\n\n/** The options of `VectorTiles.lamps` */\nexport interface LampsOptions {\n /** The line layers of the streets lit (default: the roads, as the streets glowing at night) */\n layers?: (layer: StyleLayer) => boolean;\n /** Metres between two lamps along a street (default 30, every other one on its other side) */\n spacing?: number;\n /** From this zoom on (default 16) */\n minZoom?: number;\n maxTiles?: number;\n /** Lamps in a tile at most (default 20000) */\n maxLamps?: number;\n /** Lamps drawn at most (default 15000) */\n maxInstances?: number;\n /** The color of their light at night (CSS; default a warm white) */\n light?: string;\n before?: Layer;\n}\n\nexport const lamps = (context: VectorTilesContext, options: LampsOptions = {}): ModelLayer => {\n const { map } = context;\n const {\n layers = isStreet,\n spacing = 30,\n minZoom = 16,\n maxTiles = 9,\n maxLamps = 20000,\n maxInstances = 15000,\n light = '#ffd9a0',\n } = options;\n const layer = map.addModels({\n data: lampModel(),\n instances: [],\n ...(options.before ? { before: options.before } : {}),\n });\n const renderer = context.renderer((l) => l.type === 'line' && layers(l), []);\n\n layer.setGlow(LAMP_HEAD, light);\n renderer.catch(() => undefined);\n context.layers.push(layer);\n\n const requests = new TileRequests();\n const found = new Map<string, Float64Array>();\n /** The lamps drawn: all of them near the ground under the camera, past it those of a rank under (near / distance)²,\n * at most `maxInstances` (past it, the rank kept lowered in proportion: no sort) */\n const send = () => {\n const { center, zoom } = map.getCamera();\n const cos = Math.cos((center[1] * Math.PI) / 180);\n const [ex, ey, back] = groundUnderCamera(map);\n const near = LAMPS_NEAR_METRES * 2 ** (17 - zoom) + back;\n const each = (keep: (t: Float64Array, i: number, score: number) => void) => {\n found.forEach((t) => {\n for (let i = 0; i < t.length / TREE_NUMBERS; i += 1) {\n const dx = ((t[i * TREE_NUMBERS] ?? 0) - center[0]) * METRES_PER_DEGREE * cos - ex;\n const dy = ((t[i * TREE_NUMBERS + 1] ?? 0) - center[1]) * METRES_PER_DEGREE - ey;\n const score = (t[i * TREE_NUMBERS + 4] ?? 0) * Math.max(1, (dx * dx + dy * dy) / (near * near));\n\n if (score < 1) keep(t, i, score);\n }\n });\n };\n let count = 0;\n\n each(() => {\n count += 1;\n });\n\n const limit = Math.min(1, maxInstances / Math.max(count, 1));\n const out: number[] = [];\n\n each((t, i, score) => {\n const at = i * TREE_NUMBERS;\n\n if (score < limit) out.push(t[at] ?? 0, t[at + 1] ?? 0, 0, t[at + 3] ?? 0, 0, 0, t[at + 2] ?? 1);\n });\n layer.setInstanceNumbers(Float64Array.from(out));\n };\n const update = async () => {\n if (context.destroyed()) return;\n\n const { key, maxzoom } = await renderer;\n const camera = map.getCamera();\n const z = maxzoom;\n const wanted = camera.zoom < minZoom ? [] : tilesAround(map, camera, z, maxTiles);\n const keys = new Set(wanted.map(([x, y]) => tileKey(z, x, y)));\n\n // Out of view: dropped, or no longer asked for\n requests\n .keys()\n .filter((k) => !keys.has(k))\n .forEach((k) => {\n requests.drop(k);\n found.delete(k);\n });\n send();\n wanted.forEach(([x, y], index) => {\n const k = tileKey(z, x, y);\n\n if (requests.has(k)) return;\n\n const work: BasemapWork = { type: 'lamps', key, z, x, y, spacing, maxLamps, priority: nearPriority(index) };\n\n requests.ask(\n k,\n (signal) => context.request(z, x, y, work, signal),\n (r) => {\n if (!('lamps' in r)) return;\n found.set(k, r.lamps);\n send();\n },\n );\n });\n };\n\n context.followView(\n update,\n requests,\n followWhenMoved(map, (zoom) => LAMPS_NEAR_METRES * 2 ** (17 - zoom), send),\n );\n\n return layer;\n};\n"]}
1
+ {"version":3,"file":"lamps.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/lamps.ts"],"names":[],"mappings":"AAAA;WACW;AAGX,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAGvD,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC;gCACgC;AAChC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAoB9B,MAAM,CAAC,MAAM,KAAK,GAAG,CAAC,OAA2B,EAAE,UAAwB,EAAE,EAAc,EAAE;IAC3F,MAAM,EACJ,MAAM,GAAG,QAAQ,EACjB,OAAO,GAAG,EAAE,EACZ,OAAO,GAAG,EAAE,EACZ,QAAQ,GAAG,CAAC,EACZ,QAAQ,GAAG,KAAK,EAChB,YAAY,GAAG,KAAK,EACpB,KAAK,GAAG,SAAS,GAClB,GAAG,OAAO,CAAC;IACZ,MAAM,CAAC,KAAK,CAAC,GAAG,MAAM,CAAC,OAAO,EAAE;QAC9B,MAAM,EAAE,CAAC,EAAE,IAAI,EAAE,SAAS,EAAE,EAAE,CAAC;QAC/B,MAAM,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,IAAI,MAAM,CAAC,CAAC,CAAC;QAC7C,IAAI,EAAE,CAAC,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,QAAQ,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;QAChG,IAAI,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QACjD,IAAI,EAAE,CAAC,iBAAiB,EAAE,EAAE,CAAC;QAC7B,OAAO;QACP,QAAQ;QACR,YAAY;QACZ,GAAG,CAAC,OAAO,CAAC,MAAM,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC;KAClD,CAAC,CAAC;IAEH,KAAK,CAAC,OAAO,CAAC,SAAS,EAAE,KAAK,CAAC,CAAC;IAEhC,OAAO,KAAK,CAAC;AACf,CAAC,CAAC","sourcesContent":["/** The street lamps of a vector basemap (`VectorTiles.lamps`): 3D models placed by the workers along its streets, lit at\n * night */\n\nimport type { Layer, ModelLayer } from '../../layers/layers.ts';\nimport { LAMP_HEAD, lampModel } from '../furniture.ts';\nimport type { StyleLayer } from '../vectorstyle.ts';\nimport type { VectorTilesContext } from './context.ts';\nimport { placed } from './placed.ts';\nimport { isStreet } from './vectors.ts';\n\n/** Metres around the ground under the camera where every lamp is drawn at zoom 17 (twice as far a zoom level out);\n * past them, fewer and fewer */\nconst LAMPS_NEAR_METRES = 250;\n\n/** The options of `VectorTiles.lamps` */\nexport interface LampsOptions {\n /** The line layers of the streets lit (default: the roads, as the streets glowing at night) */\n layers?: (layer: StyleLayer) => boolean;\n /** Metres between two lamps along a street (default 30, every other one on its other side) */\n spacing?: number;\n /** From this zoom on (default 16) */\n minZoom?: number;\n maxTiles?: number;\n /** Lamps in a tile at most (default 20000) */\n maxLamps?: number;\n /** Lamps drawn at most (default 15000) */\n maxInstances?: number;\n /** The color of their light at night (CSS; default a warm white) */\n light?: string;\n before?: Layer;\n}\n\nexport const lamps = (context: VectorTilesContext, options: LampsOptions = {}): ModelLayer => {\n const {\n layers = isStreet,\n spacing = 30,\n minZoom = 16,\n maxTiles = 9,\n maxLamps = 20000,\n maxInstances = 15000,\n light = '#ffd9a0',\n } = options;\n const [layer] = placed(context, {\n models: [{ data: lampModel() }],\n layers: (l) => l.type === 'line' && layers(l),\n work: (key, z, x, y, priority) => ({ type: 'lamps', key, z, x, y, spacing, maxLamps, priority }),\n read: (r) => ('lamps' in r ? r.lamps : undefined),\n near: [LAMPS_NEAR_METRES, 17],\n minZoom,\n maxTiles,\n maxInstances,\n ...(options.before && { before: options.before }),\n });\n\n layer.setGlow(LAMP_HEAD, light);\n\n return layer;\n};\n"]}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Things placed by the workers in a vector basemap's tiles around the view (trees, street lamps, street furniture),
3
+ * each kind one instanced model layer: all of them near the ground under the camera, fewer and fewer past it (a
4
+ * simplified model there when the kind has one), the tiles following the view.
5
+ */
6
+ import type { Layer, ModelLayer, ModelOptions } from '../../layers/layers.ts';
7
+ import type { BasemapResponse, BasemapWork, Priority } from '../../workers/basemap.worker.ts';
8
+ import type { StyleLayer } from '../vectorstyle.ts';
9
+ import type { VectorTilesContext } from './context.ts';
10
+ /** A model: a glTF binary's URL or bytes */
11
+ type Model = Pick<ModelOptions, 'url' | 'data'>;
12
+ interface PlacedOptions {
13
+ /** A model per kind (`PLACED_KIND`); a kind past them drawn with the first */
14
+ models: [Model, ...Model[]];
15
+ /** Past `near`, the kinds' simplified models (as many), drawn `density` times as densely as the full ones would
16
+ * be, at most `instances` times `maxInstances` */
17
+ far?: {
18
+ models: Model[];
19
+ density: number;
20
+ instances: number;
21
+ };
22
+ /** The style layers the renderer sends the workers (the tiles' source and its levels) */
23
+ layers: (layer: StyleLayer) => boolean;
24
+ /** The work asked of the worker of a tile (`layers`: the renderer's), and the things in its answer */
25
+ work: (key: string, z: number, x: number, y: number, priority: Priority, layers: StyleLayer[]) => BasemapWork;
26
+ read: (response: BasemapResponse) => Float64Array | undefined;
27
+ /** Metres around the ground under the camera where every one is drawn at a zoom (twice as far a zoom level out) */
28
+ near: [metres: number, zoom: number];
29
+ minZoom: number;
30
+ maxTiles: number;
31
+ /** Things drawn at most, all kinds together (and `far.instances` times as many simplified) */
32
+ maxInstances: number;
33
+ before?: Layer;
34
+ }
35
+ /** The layers of the things placed: one per kind, then one per kind's simplified model; the first holds the others
36
+ * (`Layer.companions`) */
37
+ export declare const placed: (context: VectorTilesContext, options: PlacedOptions) => [ModelLayer, ...ModelLayer[]];
38
+ export {};