isard 1.8.0 → 1.10.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 (235) hide show
  1. package/CHANGELOG.md +82 -1
  2. package/README.md +9 -4
  3. package/dist/basemap/grid.js +2 -5
  4. package/dist/basemap/grid.js.map +1 -1
  5. package/dist/basemap/models/furniture.d.ts +12 -0
  6. package/dist/basemap/{furniture.js → models/furniture.js} +6 -8
  7. package/dist/basemap/models/furniture.js.map +1 -0
  8. package/dist/basemap/{meshes.js → models/meshes.js} +1 -1
  9. package/dist/basemap/models/meshes.js.map +1 -0
  10. package/dist/basemap/models/trees.d.ts +21 -0
  11. package/dist/basemap/{trees.js → models/trees.js} +4 -36
  12. package/dist/basemap/models/trees.js.map +1 -0
  13. package/dist/basemap/placed.d.ts +2 -0
  14. package/dist/basemap/placed.js +2 -0
  15. package/dist/basemap/placed.js.map +1 -1
  16. package/dist/basemap/pmtiles.js +4 -3
  17. package/dist/basemap/pmtiles.js.map +1 -1
  18. package/dist/basemap/pmtileslayer.d.ts +4 -4
  19. package/dist/basemap/pmtileslayer.js +2 -1
  20. package/dist/basemap/pmtileslayer.js.map +1 -1
  21. package/dist/basemap/resample.js +3 -2
  22. package/dist/basemap/resample.js.map +1 -1
  23. package/dist/basemap/terrain.d.ts +5 -0
  24. package/dist/basemap/terrain.js +6 -4
  25. package/dist/basemap/terrain.js.map +1 -1
  26. package/dist/basemap/vectortiles/context.d.ts +3 -2
  27. package/dist/basemap/vectortiles/context.js.map +1 -1
  28. package/dist/basemap/vectortiles/extrusions.js.map +1 -1
  29. package/dist/basemap/vectortiles/furniture.d.ts +3 -3
  30. package/dist/basemap/vectortiles/furniture.js +2 -1
  31. package/dist/basemap/vectortiles/furniture.js.map +1 -1
  32. package/dist/basemap/vectortiles/labels.js +2 -1
  33. package/dist/basemap/vectortiles/labels.js.map +1 -1
  34. package/dist/basemap/vectortiles/lamps.d.ts +3 -3
  35. package/dist/basemap/vectortiles/lamps.js +1 -1
  36. package/dist/basemap/vectortiles/lamps.js.map +1 -1
  37. package/dist/basemap/vectortiles/placed.d.ts +3 -2
  38. package/dist/basemap/vectortiles/placed.js +5 -10
  39. package/dist/basemap/vectortiles/placed.js.map +1 -1
  40. package/dist/basemap/vectortiles/requests.d.ts +8 -1
  41. package/dist/basemap/vectortiles/requests.js +32 -4
  42. package/dist/basemap/vectortiles/requests.js.map +1 -1
  43. package/dist/basemap/vectortiles/street-wind.js +2 -2
  44. package/dist/basemap/vectortiles/street-wind.js.map +1 -1
  45. package/dist/basemap/vectortiles/style.js +7 -8
  46. package/dist/basemap/vectortiles/style.js.map +1 -1
  47. package/dist/basemap/vectortiles/tiles.d.ts +1 -3
  48. package/dist/basemap/vectortiles/tiles.js +1 -1
  49. package/dist/basemap/vectortiles/tiles.js.map +1 -1
  50. package/dist/basemap/vectortiles/trees.d.ts +4 -4
  51. package/dist/basemap/vectortiles/trees.js +2 -1
  52. package/dist/basemap/vectortiles/trees.js.map +1 -1
  53. package/dist/basemap/vectortiles/vectors.d.ts +9 -3
  54. package/dist/basemap/vectortiles/vectors.js +26 -2
  55. package/dist/basemap/vectortiles/vectors.js.map +1 -1
  56. package/dist/basemap/vectortiles.d.ts +8 -6
  57. package/dist/basemap/vectortiles.js +7 -4
  58. package/dist/basemap/vectortiles.js.map +1 -1
  59. package/dist/basemap/wmts.js +3 -4
  60. package/dist/basemap/wmts.js.map +1 -1
  61. package/dist/basemap/{trees.d.ts → woods.d.ts} +2 -19
  62. package/dist/basemap/woods.js +38 -0
  63. package/dist/basemap/woods.js.map +1 -0
  64. package/dist/basemap/workerpool.d.ts +1 -1
  65. package/dist/basemap/workerpool.js +3 -3
  66. package/dist/basemap/workerpool.js.map +1 -1
  67. package/dist/basemap.worker.js +2 -2
  68. package/dist/basemap.worker.js.map +23 -22
  69. package/dist/bind/layers.js +3 -0
  70. package/dist/bind/layers.js.map +1 -1
  71. package/dist/data/collada.js +4 -4
  72. package/dist/data/collada.js.map +1 -1
  73. package/dist/data/ifc.js +6 -11
  74. package/dist/data/ifc.js.map +1 -1
  75. package/dist/data/tileset.d.ts +21 -0
  76. package/dist/data/tileset.js +101 -0
  77. package/dist/data/tileset.js.map +1 -0
  78. package/dist/decoder.worker.js +5 -5
  79. package/dist/decoder.worker.js.map +7 -6
  80. package/dist/decoding/decoders.js.map +1 -0
  81. package/dist/{engine → decoding}/loader.js +2 -2
  82. package/dist/decoding/loader.js.map +1 -0
  83. package/dist/{engine → decoding}/protocol.d.ts +1 -1
  84. package/dist/decoding/protocol.js.map +1 -0
  85. package/dist/engine-loader.d.ts +3 -3
  86. package/dist/engine-loader.js +12 -5
  87. package/dist/engine-loader.js.map +1 -1
  88. package/dist/geoplateforme.d.ts +2 -1
  89. package/dist/geoplateforme.js +6 -8
  90. package/dist/geoplateforme.js.map +1 -1
  91. package/dist/index.d.ts +15 -7
  92. package/dist/index.js +9 -3
  93. package/dist/index.js.map +1 -1
  94. package/dist/isard_bg.wasm +0 -0
  95. package/dist/isard_core_bg.wasm +0 -0
  96. package/dist/isard_tess_bg.wasm +0 -0
  97. package/dist/layers/custom.d.ts +56 -0
  98. package/dist/layers/custom.js +93 -0
  99. package/dist/layers/custom.js.map +1 -0
  100. package/dist/layers/extrusions.d.ts +4 -2
  101. package/dist/layers/extrusions.js +2 -1
  102. package/dist/layers/extrusions.js.map +1 -1
  103. package/dist/layers/features.d.ts +3 -14
  104. package/dist/layers/features.js +4 -25
  105. package/dist/layers/features.js.map +1 -1
  106. package/dist/layers/flow.d.ts +3 -3
  107. package/dist/layers/flow.js +3 -4
  108. package/dist/layers/flow.js.map +1 -1
  109. package/dist/layers/glyphs.js +5 -3
  110. package/dist/layers/glyphs.js.map +1 -1
  111. package/dist/layers/ground.d.ts +57 -0
  112. package/dist/layers/ground.js +78 -0
  113. package/dist/layers/ground.js.map +1 -0
  114. package/dist/layers/icons.js +8 -6
  115. package/dist/layers/icons.js.map +1 -1
  116. package/dist/layers/layers.d.ts +2 -199
  117. package/dist/layers/layers.js +2 -469
  118. package/dist/layers/layers.js.map +1 -1
  119. package/dist/layers/models.d.ts +48 -0
  120. package/dist/layers/models.js +111 -0
  121. package/dist/layers/models.js.map +1 -0
  122. package/dist/layers/network.d.ts +26 -0
  123. package/dist/layers/network.js +127 -0
  124. package/dist/layers/network.js.map +1 -0
  125. package/dist/layers/panoramas.d.ts +2 -11
  126. package/dist/layers/panoramas.js +19 -9
  127. package/dist/layers/panoramas.js.map +1 -1
  128. package/dist/layers/photos.d.ts +4 -7
  129. package/dist/layers/photos.js +3 -4
  130. package/dist/layers/photos.js.map +1 -1
  131. package/dist/layers/pointclouds.d.ts +3 -2
  132. package/dist/layers/pointclouds.js +3 -3
  133. package/dist/layers/pointclouds.js.map +1 -1
  134. package/dist/layers/raster.d.ts +9 -0
  135. package/dist/layers/raster.js +24 -0
  136. package/dist/layers/raster.js.map +1 -0
  137. package/dist/layers/symbols.d.ts +2 -2
  138. package/dist/layers/symbols.js +2 -1
  139. package/dist/layers/symbols.js.map +1 -1
  140. package/dist/layers/tiles3d.d.ts +20 -0
  141. package/dist/layers/tiles3d.js +69 -0
  142. package/dist/layers/tiles3d.js.map +1 -0
  143. package/dist/layers/trees.d.ts +5 -7
  144. package/dist/layers/trees.js +2 -1
  145. package/dist/layers/trees.js.map +1 -1
  146. package/dist/layers/vectors.d.ts +3 -0
  147. package/dist/layers/vectors.js +4 -0
  148. package/dist/layers/vectors.js.map +1 -1
  149. package/dist/map/basemap-layers.js +1 -1
  150. package/dist/map/basemap-layers.js.map +1 -1
  151. package/dist/map/engine-settings.d.ts +1 -1
  152. package/dist/map/engine-settings.js +1 -1
  153. package/dist/map/engine-settings.js.map +1 -1
  154. package/dist/map/engines.js.map +1 -1
  155. package/dist/map/layer-spec.d.ts +7 -13
  156. package/dist/map/layer-spec.js.map +1 -1
  157. package/dist/map/workers.js +3 -4
  158. package/dist/map/workers.js.map +1 -1
  159. package/dist/map.d.ts +25 -58
  160. package/dist/map.js +61 -53
  161. package/dist/map.js.map +1 -1
  162. package/dist/panoramax.js +6 -8
  163. package/dist/panoramax.js.map +1 -1
  164. package/dist/react/CustomLayer.d.ts +1 -1
  165. package/dist/react/CustomLayer.js.map +1 -1
  166. package/dist/react/Layer.d.ts +5 -1
  167. package/dist/react/Layer.js.map +1 -1
  168. package/dist/react/VectorGeometry.d.ts +4 -0
  169. package/dist/react/VectorGeometry.js +6 -3
  170. package/dist/react/VectorGeometry.js.map +1 -1
  171. package/dist/react/VectorTiles.d.ts +2 -2
  172. package/dist/react/VectorTiles.js +1 -1
  173. package/dist/react/VectorTiles.js.map +1 -1
  174. package/dist/types.d.ts +16 -4
  175. package/dist/types.js.map +1 -1
  176. package/dist/ui/controls.js +2 -1
  177. package/dist/ui/controls.js.map +1 -1
  178. package/dist/ui/interaction.d.ts +4 -0
  179. package/dist/ui/interaction.js +59 -7
  180. package/dist/ui/interaction.js.map +1 -1
  181. package/dist/ui/minimap.js +1 -1
  182. package/dist/ui/minimap.js.map +1 -1
  183. package/dist/ui/overlay.js +3 -3
  184. package/dist/ui/overlay.js.map +1 -1
  185. package/dist/ui/search.js +1 -1
  186. package/dist/ui/search.js.map +1 -1
  187. package/dist/util/animation.js +3 -2
  188. package/dist/util/animation.js.map +1 -1
  189. package/dist/util/color.d.ts +10 -0
  190. package/dist/util/color.js +29 -9
  191. package/dist/util/color.js.map +1 -1
  192. package/dist/util/fetch.d.ts +5 -0
  193. package/dist/util/fetch.js +11 -0
  194. package/dist/util/fetch.js.map +1 -0
  195. package/dist/util/geo.d.ts +5 -0
  196. package/dist/util/geo.js +8 -2
  197. package/dist/util/geo.js.map +1 -1
  198. package/dist/util/math.d.ts +3 -0
  199. package/dist/util/math.js +4 -0
  200. package/dist/util/math.js.map +1 -0
  201. package/dist/util/requests.js.map +1 -0
  202. package/dist/util/roofs.d.ts +0 -2
  203. package/dist/util/roofs.js +0 -3
  204. package/dist/util/roofs.js.map +1 -1
  205. package/dist/wasm/isard.d.ts +18 -1
  206. package/dist/wasm/isard.js +28 -2
  207. package/dist/wasm/isard_core.d.ts +13 -1
  208. package/dist/wasm/isard_core.js +20 -2
  209. package/dist/workers/basemap/geometry.d.ts +9 -19
  210. package/dist/workers/{basemap.worker.d.ts → basemap/protocol.d.ts} +32 -23
  211. package/dist/workers/basemap/street.d.ts +4 -2
  212. package/dist/workers/basemap/tiles.d.ts +1 -3
  213. package/dist/workers/basemap/trees.d.ts +2 -2
  214. package/package.json +1 -1
  215. package/dist/basemap/furniture.d.ts +0 -26
  216. package/dist/basemap/furniture.js.map +0 -1
  217. package/dist/basemap/meshes.js.map +0 -1
  218. package/dist/basemap/trees.js.map +0 -1
  219. package/dist/engine/decoders.js.map +0 -1
  220. package/dist/engine/loader.js.map +0 -1
  221. package/dist/engine/protocol.js.map +0 -1
  222. package/dist/engine/requests.js.map +0 -1
  223. package/dist/workers/basemap/furniture.d.ts +0 -13
  224. package/dist/workers/basemap/labels.d.ts +0 -24
  225. package/dist/workers/basemap/lamps.d.ts +0 -10
  226. package/dist/workers/basemap/raster.d.ts +0 -10
  227. package/dist/workers/basemap.worker.js +0 -221
  228. package/dist/workers/basemap.worker.js.map +0 -1
  229. /package/dist/basemap/{meshes.d.ts → models/meshes.d.ts} +0 -0
  230. /package/dist/{engine → decoding}/decoders.d.ts +0 -0
  231. /package/dist/{engine → decoding}/decoders.js +0 -0
  232. /package/dist/{engine → decoding}/loader.d.ts +0 -0
  233. /package/dist/{engine → decoding}/protocol.js +0 -0
  234. /package/dist/{engine → util}/requests.d.ts +0 -0
  235. /package/dist/{engine → util}/requests.js +0 -0
@@ -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 // 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
+ {"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 { clamp } from '../../util/math.ts';\nimport type { BasemapWork } from '../../workers/basemap/protocol.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 = clamp(Math.floor(camera.zoom), 0, 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,10 +1,11 @@
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
- import type { Layer, ModelLayer } from '../../layers/layers.ts';
3
+ import type { ModelLayer } from '../../layers/models.ts';
4
+ import type { Placement } from '../../types.ts';
4
5
  import type { StyleLayer } from '../vectorstyle.ts';
5
6
  import type { VectorTilesContext } from './context.ts';
6
7
  /** The options of `VectorTiles.lamps` */
7
- export interface LampsOptions {
8
+ export interface LampsOptions extends Placement {
8
9
  /** The line layers of the streets lit (default: the roads, as the streets glowing at night) */
9
10
  layers?: (layer: StyleLayer) => boolean;
10
11
  /** Metres between two lamps along a street (default 30, every other one on its other side) */
@@ -18,6 +19,5 @@ export interface LampsOptions {
18
19
  maxInstances?: number;
19
20
  /** The color of their light at night (CSS; default a warm white) */
20
21
  light?: string;
21
- before?: Layer;
22
22
  }
23
23
  export declare const lamps: (context: VectorTilesContext, options?: LampsOptions) => ModelLayer;
@@ -1,6 +1,6 @@
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
- import { LAMP_HEAD, lampModel } from "../furniture.js";
3
+ import { LAMP_HEAD, lampModel } from "../models/furniture.js";
4
4
  import { placed } from "./placed.js";
5
5
  import { isStreet } from "./vectors.js";
6
6
  /** Metres around the ground under the camera where every lamp is drawn at zoom 17 (twice as far a zoom level out);
@@ -1 +1 @@
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"]}
1
+ {"version":3,"file":"lamps.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/lamps.ts"],"names":[],"mappings":"AAAA;WACW;AAIX,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAG9D,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AACrC,OAAO,EAAE,QAAQ,EAAE,MAAM,cAAc,CAAC;AAExC;gCACgC;AAChC,MAAM,iBAAiB,GAAG,GAAG,CAAC;AAmB9B,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 { ModelLayer } from '../../layers/models.ts';\nimport type { Placement } from '../../types.ts';\nimport { LAMP_HEAD, lampModel } from '../models/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 extends Placement {\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}\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"]}
@@ -3,8 +3,9 @@
3
3
  * each kind one instanced model layer: all of them near the ground under the camera, fewer and fewer past it (a
4
4
  * simplified model there when the kind has one), the tiles following the view.
5
5
  */
6
- import type { Layer, ModelLayer, ModelOptions } from '../../layers/layers.ts';
7
- import type { BasemapResponse, BasemapWork, Priority } from '../../workers/basemap.worker.ts';
6
+ import type { Layer } from '../../layers/layers.ts';
7
+ import type { ModelLayer, ModelOptions } from '../../layers/models.ts';
8
+ import type { BasemapResponse, BasemapWork, Priority } from '../../workers/basemap/protocol.ts';
8
9
  import type { StyleLayer } from '../vectorstyle.ts';
9
10
  import type { VectorTilesContext } from './context.ts';
10
11
  /** A model: a glTF binary's URL or bytes */
@@ -3,7 +3,7 @@
3
3
  * each kind one instanced model layer: all of them near the ground under the camera, fewer and fewer past it (a
4
4
  * simplified model there when the kind has one), the tiles following the view.
5
5
  */
6
- import { METRES_PER_DEGREE } from "../../util/geo.js";
6
+ import { METRES_PER_DEGREE, RAD } from "../../util/geo.js";
7
7
  import { PLACED_KIND, PLACED_NUMBERS, PLACED_RANK } from "../placed.js";
8
8
  import { TileRequests } from "./requests.js";
9
9
  import { nearPriority, tileKey, tilesAround } from "./tiles.js";
@@ -16,10 +16,8 @@ const RESEND_SHARE = 0.05;
16
16
  * stands behind the center of a tilted view, `FOV` its field of view) */
17
17
  const groundUnderCamera = (map) => {
18
18
  const { pitch, bearing } = map.getCamera();
19
- const back = ((0.5 * map.getCanvas().clientHeight) / Math.tan(FOV / 2)) *
20
- Math.sin((pitch * Math.PI) / 180) *
21
- (map.metersPerPixel() ?? 0);
22
- return [-back * Math.sin((bearing * Math.PI) / 180), -back * Math.cos((bearing * Math.PI) / 180), back];
19
+ const back = ((0.5 * map.getCanvas().clientHeight) / Math.tan(FOV / 2)) * Math.sin(pitch * RAD) * (map.metersPerPixel() ?? 0);
20
+ return [-back * Math.sin(bearing * RAD), -back * Math.cos(bearing * RAD), back];
23
21
  };
24
22
  /** What follows the camera as it moves: `send` called again once it has gone `RESEND_SHARE` of `radius` metres (or
25
23
  * turned or zoomed as much), not at every frame of a drag */
@@ -28,10 +26,7 @@ const followWhenMoved = (map, radius, send) => {
28
26
  let sent;
29
27
  return () => {
30
28
  const { center, zoom, bearing, pitch } = map.getCamera();
31
- const [x, y] = [
32
- center[0] * METRES_PER_DEGREE * Math.cos((center[1] * Math.PI) / 180),
33
- center[1] * METRES_PER_DEGREE,
34
- ];
29
+ const [x, y] = [center[0] * METRES_PER_DEGREE * Math.cos(center[1] * RAD), center[1] * METRES_PER_DEGREE];
35
30
  if (sent &&
36
31
  Math.hypot(x - sent[0], y - sent[1]) < RESEND_SHARE * radius(zoom) &&
37
32
  Math.abs(zoom - sent[2]) < RESEND_SHARE &&
@@ -62,7 +57,7 @@ export const placed = (context, options) => {
62
57
  * lowered in proportion: no sort) */
63
58
  const send = () => {
64
59
  const { center, zoom } = map.getCamera();
65
- const cos = Math.cos((center[1] * Math.PI) / 180);
60
+ const cos = Math.cos(center[1] * RAD);
66
61
  const [ex, ey, back] = groundUnderCamera(map);
67
62
  const near = radius(zoom) + back;
68
63
  const density = far?.density ?? 1;
@@ -1 +1 @@
1
- {"version":3,"file":"placed.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/placed.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Things placed by the workers in a vector basemap's tiles around the view (trees, street lamps, street furniture),\n * each kind one instanced model layer: all of them near the ground under the camera, fewer and fewer past it (a\n * simplified model there when the kind has one), the tiles following the view.\n */\n\nimport type { Layer, ModelLayer, ModelOptions } from '../../layers/layers.ts';\nimport type { GeoMap } from '../../map.ts';\nimport { METRES_PER_DEGREE } from '../../util/geo.ts';\nimport type { BasemapResponse, BasemapWork, Priority } from '../../workers/basemap.worker.ts';\nimport { PLACED_KIND, PLACED_NUMBERS, PLACED_RANK } from '../placed.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';\n\n/** The engine's vertical field of view (radians, `camera::FOV`): where the camera stands behind the view's center */\nconst FOV = 0.6435011087932844;\n\n/** While the camera moves, the things chosen again once it has gone this share of the near radius (or turned or\n * zoomed as much): going through the tiles' things at every frame of a drag would hold the main thread */\nconst RESEND_SHARE = 0.05;\n\n/** A model: a glTF binary's URL or bytes */\ntype Model = Pick<ModelOptions, 'url' | 'data'>;\n\ninterface PlacedOptions {\n /** A model per kind (`PLACED_KIND`); a kind past them drawn with the first */\n models: [Model, ...Model[]];\n /** Past `near`, the kinds' simplified models (as many), drawn `density` times as densely as the full ones would\n * be, at most `instances` times `maxInstances` */\n far?: { models: Model[]; density: number; instances: number };\n /** The style layers the renderer sends the workers (the tiles' source and its levels) */\n layers: (layer: StyleLayer) => boolean;\n /** The work asked of the worker of a tile (`layers`: the renderer's), and the things in its answer */\n work: (key: string, z: number, x: number, y: number, priority: Priority, layers: StyleLayer[]) => BasemapWork;\n read: (response: BasemapResponse) => Float64Array | undefined;\n /** Metres around the ground under the camera where every one is drawn at a zoom (twice as far a zoom level out) */\n near: [metres: number, zoom: number];\n minZoom: number;\n maxTiles: number;\n /** Things drawn at most, all kinds together (and `far.instances` times as many simplified) */\n maxInstances: number;\n before?: Layer;\n}\n\n/** The ground under the camera: east and north metres from the view's center, and its distance from it (the camera\n * stands behind the center of a tilted view, `FOV` its field of view) */\nconst groundUnderCamera = (map: GeoMap): [east: number, north: number, distance: number] => {\n const { pitch, bearing } = map.getCamera();\n const back =\n ((0.5 * map.getCanvas().clientHeight) / Math.tan(FOV / 2)) *\n Math.sin((pitch * Math.PI) / 180) *\n (map.metersPerPixel() ?? 0);\n\n return [-back * Math.sin((bearing * Math.PI) / 180), -back * Math.cos((bearing * Math.PI) / 180), back];\n};\n\n/** What follows the camera as it moves: `send` called again once it has gone `RESEND_SHARE` of `radius` metres (or\n * turned or zoomed as much), not at every frame of a drag */\nconst followWhenMoved = (map: GeoMap, radius: (zoom: number) => number, send: () => void): (() => void) => {\n /** The view of the last call: center (metres), zoom, bearing, pitch */\n let sent: [number, number, number, number, number] | undefined;\n\n return () => {\n const { center, zoom, bearing, pitch } = map.getCamera();\n const [x, y] = [\n center[0] * METRES_PER_DEGREE * Math.cos((center[1] * Math.PI) / 180),\n center[1] * METRES_PER_DEGREE,\n ];\n\n if (\n sent &&\n Math.hypot(x - sent[0], y - sent[1]) < RESEND_SHARE * radius(zoom) &&\n Math.abs(zoom - sent[2]) < RESEND_SHARE &&\n Math.abs(bearing - sent[3]) < 45 * RESEND_SHARE &&\n Math.abs(pitch - sent[4]) < 45 * RESEND_SHARE\n )\n return;\n sent = [x, y, zoom, bearing, pitch];\n send();\n };\n};\n\n/** The layers of the things placed: one per kind, then one per kind's simplified model; the first holds the others\n * (`Layer.companions`) */\nexport const placed = (context: VectorTilesContext, options: PlacedOptions): [ModelLayer, ...ModelLayer[]] => {\n const { map } = context;\n const { models, far, minZoom, maxTiles, maxInstances } = options;\n const add = (model: Model) =>\n map.addModels({ ...model, instances: [], ...(options.before ? { before: options.before } : {}) });\n const [model, ...more] = models;\n const layers: [ModelLayer, ...ModelLayer[]] = [add(model), ...more.map(add), ...(far?.models ?? []).map(add)];\n const renderer = context.renderer(options.layers, []);\n const radius = (zoom: number) => options.near[0] * 2 ** (options.near[1] - zoom);\n\n renderer.catch(() => undefined);\n layers[0].companions.push(...layers.slice(1));\n context.layers.push(...layers);\n\n const requests = new TileRequests();\n const found = new Map<string, Float64Array>();\n /** The things drawn: all of them near the ground under the camera; past it those of a rank under `density` (near /\n * distance)², simplified; at most `maxInstances` near, `far.instances` times as many past (beyond, the rank kept\n * 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 = radius(zoom) + back;\n const density = far?.density ?? 1;\n /** Each thing that may be drawn: in full (near, or every one without simplified models) or simplified, with its\n * score (the lowest kept first) */\n const visit = (each: (t: Float64Array, at: number, full: boolean, score: number) => void) => {\n found.forEach((t) => {\n for (let at = 0; at < t.length; at += PLACED_NUMBERS) {\n const dx = ((t[at] ?? 0) - center[0]) * METRES_PER_DEGREE * cos - ex;\n const dy = ((t[at + 1] ?? 0) - center[1]) * METRES_PER_DEGREE - ey;\n const distance = (dx * dx + dy * dy) / (near * near);\n const rank = t[at + PLACED_RANK] ?? 0;\n\n if (distance <= 1) each(t, at, true, rank);\n else if (rank * (distance / density) < 1) each(t, at, !far, rank * (distance / density));\n }\n });\n };\n let [fullCount, farCount] = [0, 0];\n\n visit((_, __, full) => {\n if (full) fullCount += 1;\n else farCount += 1;\n });\n\n const limits = [\n Math.min(1, maxInstances / Math.max(fullCount, 1)),\n Math.min(1, (maxInstances * (far?.instances ?? 1)) / Math.max(farCount, 1)),\n ];\n // The engine's numbers: longitude, latitude, altitude, heading, pitch, roll, scale\n const out: number[][] = layers.map(() => []);\n\n visit((t, at, full, score) => {\n if (score >= (limits[full ? 0 : 1] ?? 1)) return;\n\n const kind = t[at + PLACED_KIND] ?? 0;\n const k = (full ? 0 : models.length) + (kind < models.length ? kind : 0);\n\n out[k]?.push(t[at] ?? 0, t[at + 1] ?? 0, 0, t[at + 3] ?? 0, 0, 0, t[at + 2] ?? 1);\n });\n layers.forEach((layer, k) => {\n layer.setInstanceNumbers(Float64Array.from(out[k] ?? []));\n });\n };\n const update = async () => {\n if (context.destroyed()) return;\n\n const { key, maxzoom: z, layers: list } = await renderer;\n const camera = map.getCamera();\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 // Dense around the new center\n send();\n wanted.forEach(([x, y], index) => {\n const k = tileKey(z, x, y);\n\n if (requests.has(k)) return;\n requests.ask(\n k,\n (signal) => context.request(z, x, y, options.work(key, z, x, y, nearPriority(index), list), signal),\n (r) => {\n const things = options.read(r);\n\n if (!things) return;\n found.set(k, things);\n send();\n },\n );\n });\n };\n\n // While the camera moves, the things drawn follow it (dense near it), chosen again once it has gone far enough\n context.followView(layers[0], update, requests, followWhenMoved(map, radius, send));\n\n return layers;\n};\n"]}
1
+ {"version":3,"file":"placed.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/placed.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Things placed by the workers in a vector basemap's tiles around the view (trees, street lamps, street furniture),\n * each kind one instanced model layer: all of them near the ground under the camera, fewer and fewer past it (a\n * simplified model there when the kind has one), the tiles following the view.\n */\n\nimport type { Layer } from '../../layers/layers.ts';\nimport type { ModelLayer, ModelOptions } from '../../layers/models.ts';\nimport type { GeoMap } from '../../map.ts';\nimport { METRES_PER_DEGREE, RAD } from '../../util/geo.ts';\nimport type { BasemapResponse, BasemapWork, Priority } from '../../workers/basemap/protocol.ts';\nimport { PLACED_KIND, PLACED_NUMBERS, PLACED_RANK } from '../placed.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';\n\n/** The engine's vertical field of view (radians, `camera::FOV`): where the camera stands behind the view's center */\nconst FOV = 0.6435011087932844;\n\n/** While the camera moves, the things chosen again once it has gone this share of the near radius (or turned or\n * zoomed as much): going through the tiles' things at every frame of a drag would hold the main thread */\nconst RESEND_SHARE = 0.05;\n\n/** A model: a glTF binary's URL or bytes */\ntype Model = Pick<ModelOptions, 'url' | 'data'>;\n\ninterface PlacedOptions {\n /** A model per kind (`PLACED_KIND`); a kind past them drawn with the first */\n models: [Model, ...Model[]];\n /** Past `near`, the kinds' simplified models (as many), drawn `density` times as densely as the full ones would\n * be, at most `instances` times `maxInstances` */\n far?: { models: Model[]; density: number; instances: number };\n /** The style layers the renderer sends the workers (the tiles' source and its levels) */\n layers: (layer: StyleLayer) => boolean;\n /** The work asked of the worker of a tile (`layers`: the renderer's), and the things in its answer */\n work: (key: string, z: number, x: number, y: number, priority: Priority, layers: StyleLayer[]) => BasemapWork;\n read: (response: BasemapResponse) => Float64Array | undefined;\n /** Metres around the ground under the camera where every one is drawn at a zoom (twice as far a zoom level out) */\n near: [metres: number, zoom: number];\n minZoom: number;\n maxTiles: number;\n /** Things drawn at most, all kinds together (and `far.instances` times as many simplified) */\n maxInstances: number;\n before?: Layer;\n}\n\n/** The ground under the camera: east and north metres from the view's center, and its distance from it (the camera\n * stands behind the center of a tilted view, `FOV` its field of view) */\nconst groundUnderCamera = (map: GeoMap): [east: number, north: number, distance: number] => {\n const { pitch, bearing } = map.getCamera();\n const back =\n ((0.5 * map.getCanvas().clientHeight) / Math.tan(FOV / 2)) * Math.sin(pitch * RAD) * (map.metersPerPixel() ?? 0);\n\n return [-back * Math.sin(bearing * RAD), -back * Math.cos(bearing * RAD), back];\n};\n\n/** What follows the camera as it moves: `send` called again once it has gone `RESEND_SHARE` of `radius` metres (or\n * turned or zoomed as much), not at every frame of a drag */\nconst followWhenMoved = (map: GeoMap, radius: (zoom: number) => number, send: () => void): (() => void) => {\n /** The view of the last call: center (metres), zoom, bearing, pitch */\n let sent: [number, number, number, number, number] | undefined;\n\n return () => {\n const { center, zoom, bearing, pitch } = map.getCamera();\n const [x, y] = [center[0] * METRES_PER_DEGREE * Math.cos(center[1] * RAD), center[1] * METRES_PER_DEGREE];\n\n if (\n sent &&\n Math.hypot(x - sent[0], y - sent[1]) < RESEND_SHARE * radius(zoom) &&\n Math.abs(zoom - sent[2]) < RESEND_SHARE &&\n Math.abs(bearing - sent[3]) < 45 * RESEND_SHARE &&\n Math.abs(pitch - sent[4]) < 45 * RESEND_SHARE\n )\n return;\n sent = [x, y, zoom, bearing, pitch];\n send();\n };\n};\n\n/** The layers of the things placed: one per kind, then one per kind's simplified model; the first holds the others\n * (`Layer.companions`) */\nexport const placed = (context: VectorTilesContext, options: PlacedOptions): [ModelLayer, ...ModelLayer[]] => {\n const { map } = context;\n const { models, far, minZoom, maxTiles, maxInstances } = options;\n const add = (model: Model) =>\n map.addModels({ ...model, instances: [], ...(options.before ? { before: options.before } : {}) });\n const [model, ...more] = models;\n const layers: [ModelLayer, ...ModelLayer[]] = [add(model), ...more.map(add), ...(far?.models ?? []).map(add)];\n const renderer = context.renderer(options.layers, []);\n const radius = (zoom: number) => options.near[0] * 2 ** (options.near[1] - zoom);\n\n renderer.catch(() => undefined);\n layers[0].companions.push(...layers.slice(1));\n context.layers.push(...layers);\n\n const requests = new TileRequests();\n const found = new Map<string, Float64Array>();\n /** The things drawn: all of them near the ground under the camera; past it those of a rank under `density` (near /\n * distance)², simplified; at most `maxInstances` near, `far.instances` times as many past (beyond, the rank kept\n * lowered in proportion: no sort) */\n const send = () => {\n const { center, zoom } = map.getCamera();\n const cos = Math.cos(center[1] * RAD);\n const [ex, ey, back] = groundUnderCamera(map);\n const near = radius(zoom) + back;\n const density = far?.density ?? 1;\n /** Each thing that may be drawn: in full (near, or every one without simplified models) or simplified, with its\n * score (the lowest kept first) */\n const visit = (each: (t: Float64Array, at: number, full: boolean, score: number) => void) => {\n found.forEach((t) => {\n for (let at = 0; at < t.length; at += PLACED_NUMBERS) {\n const dx = ((t[at] ?? 0) - center[0]) * METRES_PER_DEGREE * cos - ex;\n const dy = ((t[at + 1] ?? 0) - center[1]) * METRES_PER_DEGREE - ey;\n const distance = (dx * dx + dy * dy) / (near * near);\n const rank = t[at + PLACED_RANK] ?? 0;\n\n if (distance <= 1) each(t, at, true, rank);\n else if (rank * (distance / density) < 1) each(t, at, !far, rank * (distance / density));\n }\n });\n };\n let [fullCount, farCount] = [0, 0];\n\n visit((_, __, full) => {\n if (full) fullCount += 1;\n else farCount += 1;\n });\n\n const limits = [\n Math.min(1, maxInstances / Math.max(fullCount, 1)),\n Math.min(1, (maxInstances * (far?.instances ?? 1)) / Math.max(farCount, 1)),\n ];\n // The engine's numbers: longitude, latitude, altitude, heading, pitch, roll, scale\n const out: number[][] = layers.map(() => []);\n\n visit((t, at, full, score) => {\n if (score >= (limits[full ? 0 : 1] ?? 1)) return;\n\n const kind = t[at + PLACED_KIND] ?? 0;\n const k = (full ? 0 : models.length) + (kind < models.length ? kind : 0);\n\n out[k]?.push(t[at] ?? 0, t[at + 1] ?? 0, 0, t[at + 3] ?? 0, 0, 0, t[at + 2] ?? 1);\n });\n layers.forEach((layer, k) => {\n layer.setInstanceNumbers(Float64Array.from(out[k] ?? []));\n });\n };\n const update = async () => {\n if (context.destroyed()) return;\n\n const { key, maxzoom: z, layers: list } = await renderer;\n const camera = map.getCamera();\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 // Dense around the new center\n send();\n wanted.forEach(([x, y], index) => {\n const k = tileKey(z, x, y);\n\n if (requests.has(k)) return;\n requests.ask(\n k,\n (signal) => context.request(z, x, y, options.work(key, z, x, y, nearPriority(index), list), signal),\n (r) => {\n const things = options.read(r);\n\n if (!things) return;\n found.set(k, things);\n send();\n },\n );\n });\n };\n\n // While the camera moves, the things drawn follow it (dense near it), chosen again once it has gone far enough\n context.followView(layers[0], update, requests, followWhenMoved(map, radius, send));\n\n return layers;\n};\n"]}
@@ -6,6 +6,11 @@ export declare class TileRequests {
6
6
  private readonly held;
7
7
  /** The requests not answered yet, by key */
8
8
  private readonly pending;
9
+ /** What asks again for the tiles that failed (the layer's update), and when it is due */
10
+ private readonly retry;
11
+ /** Asks again for the tiles that failed with `update` (the layer's), after a pause: a still map brings no update of
12
+ * its own, a tile failed would wait for the next move */
13
+ retryWith(update: () => void): void;
9
14
  /** Whether the tile is held or asked for */
10
15
  has(key: string): boolean;
11
16
  /** The keys of the tiles held or asked for (a copy: the tiles can be dropped while it is gone through) */
@@ -22,7 +27,9 @@ export declare class TileRequests {
22
27
  answered(keys: Iterable<string>): Promise<void>;
23
28
  /** Aborts the tile's request and forgets it */
24
29
  drop(key: string): void;
25
- /** Aborts every request and forgets every tile */
30
+ /** Aborts every request and forgets every tile, a retry due with them */
26
31
  abortAll(): void;
32
+ /** A tile failed: the update asked for after the pause, once for every tile failed meanwhile */
33
+ private failed;
27
34
  private open;
28
35
  }
@@ -2,10 +2,21 @@
2
2
  * The requests of a layer whose tiles follow the view (`VectorTiles`' extrusions, streets' wind, trees, vectors): the
3
3
  * tiles held or asked for, by key, each with the controller that aborts its request.
4
4
  */
5
+ /** Pause before the tiles that failed are asked for again when no move brings an update (ms), doubled at each failure
6
+ * in a row up to `RETRY_MAX_MS` */
7
+ const RETRY_FIRST_MS = 1000;
8
+ const RETRY_MAX_MS = 30_000;
5
9
  export class TileRequests {
6
10
  held = new Map();
7
11
  /** The requests not answered yet, by key */
8
12
  pending = new Map();
13
+ /** What asks again for the tiles that failed (the layer's update), and when it is due */
14
+ retry = { timer: undefined, wait: RETRY_FIRST_MS };
15
+ /** Asks again for the tiles that failed with `update` (the layer's), after a pause: a still map brings no update of
16
+ * its own, a tile failed would wait for the next move */
17
+ retryWith(update) {
18
+ this.retry.update = update;
19
+ }
9
20
  /** Whether the tile is held or asked for */
10
21
  has(key) {
11
22
  return this.held.has(key);
@@ -25,10 +36,12 @@ export class TileRequests {
25
36
  */
26
37
  ask(key, request, use) {
27
38
  const controller = this.open(key);
28
- // A later request under the same key is not forgotten by this one's failure
39
+ // A later request under the same key is not forgotten by this one's failure (nor one dropped: it is not wanted)
29
40
  const forget = () => {
30
- if (this.held.get(key) === controller)
31
- this.held.delete(key);
41
+ if (this.held.get(key) !== controller)
42
+ return;
43
+ this.held.delete(key);
44
+ this.failed();
32
45
  };
33
46
  const answered = request(controller.signal)
34
47
  .then(async (answer) => {
@@ -36,6 +49,7 @@ export class TileRequests {
36
49
  return;
37
50
  try {
38
51
  await use(answer);
52
+ this.retry.wait = RETRY_FIRST_MS;
39
53
  }
40
54
  catch (error) {
41
55
  console.warn('isard: a vector tile not drawn', error);
@@ -58,12 +72,26 @@ export class TileRequests {
58
72
  this.held.get(key)?.abort();
59
73
  this.held.delete(key);
60
74
  }
61
- /** Aborts every request and forgets every tile */
75
+ /** Aborts every request and forgets every tile, a retry due with them */
62
76
  abortAll() {
63
77
  this.held.forEach((controller) => {
64
78
  controller.abort();
65
79
  });
66
80
  this.held.clear();
81
+ clearTimeout(this.retry.timer);
82
+ this.retry.timer = undefined;
83
+ this.retry.wait = RETRY_FIRST_MS;
84
+ }
85
+ /** A tile failed: the update asked for after the pause, once for every tile failed meanwhile */
86
+ failed() {
87
+ const { update, timer, wait } = this.retry;
88
+ if (!update || timer !== undefined)
89
+ return;
90
+ this.retry.timer = setTimeout(() => {
91
+ this.retry.timer = undefined;
92
+ update();
93
+ }, wait);
94
+ this.retry.wait = Math.min(wait * 2, RETRY_MAX_MS);
67
95
  }
68
96
  open(key) {
69
97
  const controller = new AbortController();
@@ -1 +1 @@
1
- {"version":3,"file":"requests.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/requests.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The requests of a layer whose tiles follow the view (`VectorTiles`' extrusions, streets' wind, trees, vectors): the\n * tiles held or asked for, by key, each with the controller that aborts its request.\n */\n\nexport class TileRequests {\n private readonly held = new Map<string, AbortController>();\n /** The requests not answered yet, by key */\n private readonly pending = new Map<string, Promise<void>>();\n\n /** Whether the tile is held or asked for */\n has(key: string): boolean {\n return this.held.has(key);\n }\n\n /** The keys of the tiles held or asked for (a copy: the tiles can be dropped while it is gone through) */\n keys(): string[] {\n return [...this.held.keys()];\n }\n\n /** Holds a new request under `key` (the one it held before is forgotten, not aborted); returns its signal */\n start(key: string): AbortSignal {\n return this.open(key).signal;\n }\n\n /**\n * Asks for a tile (`request`) and does with its answer what `use` does, unless the request was aborted meanwhile. On\n * a failure of either, the tile is forgotten (the next update asks for it again); an error of `use` (the engine\n * refusing the tile) is reported, never left unhandled\n */\n ask<T>(key: string, request: (signal: AbortSignal) => Promise<T>, use: (answer: T) => unknown): Promise<void> {\n const controller = this.open(key);\n // A later request under the same key is not forgotten by this one's failure\n const forget = () => {\n if (this.held.get(key) === controller) this.held.delete(key);\n };\n\n const answered = request(controller.signal)\n .then(async (answer) => {\n if (controller.signal.aborted) return;\n\n try {\n await use(answer);\n } catch (error) {\n console.warn('isard: a vector tile not drawn', error);\n forget();\n }\n }, forget)\n .finally(() => {\n if (this.pending.get(key) === answered) this.pending.delete(key);\n });\n\n this.pending.set(key, answered);\n\n return answered;\n }\n\n /** Resolves once the tiles of `keys` asked for, by this update or an earlier one, are answered (or dropped) */\n answered(keys: Iterable<string>): Promise<void> {\n return Promise.all([...keys].map((k) => this.pending.get(k))).then(() => undefined);\n }\n\n /** Aborts the tile's request and forgets it */\n drop(key: string): void {\n this.held.get(key)?.abort();\n this.held.delete(key);\n }\n\n /** Aborts every request and forgets every tile */\n abortAll(): void {\n this.held.forEach((controller) => {\n controller.abort();\n });\n this.held.clear();\n }\n\n private open(key: string): AbortController {\n const controller = new AbortController();\n\n this.held.set(key, controller);\n\n return controller;\n }\n}\n"]}
1
+ {"version":3,"file":"requests.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/requests.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * The requests of a layer whose tiles follow the view (`VectorTiles`' extrusions, streets' wind, trees, vectors): the\n * tiles held or asked for, by key, each with the controller that aborts its request.\n */\n\n/** Pause before the tiles that failed are asked for again when no move brings an update (ms), doubled at each failure\n * in a row up to `RETRY_MAX_MS` */\nconst RETRY_FIRST_MS = 1000;\nconst RETRY_MAX_MS = 30_000;\n\nexport class TileRequests {\n private readonly held = new Map<string, AbortController>();\n /** The requests not answered yet, by key */\n private readonly pending = new Map<string, Promise<void>>();\n /** What asks again for the tiles that failed (the layer's update), and when it is due */\n private readonly retry: {\n update?: () => void;\n timer: ReturnType<typeof setTimeout> | undefined;\n wait: number;\n } = { timer: undefined, wait: RETRY_FIRST_MS };\n\n /** Asks again for the tiles that failed with `update` (the layer's), after a pause: a still map brings no update of\n * its own, a tile failed would wait for the next move */\n retryWith(update: () => void): void {\n this.retry.update = update;\n }\n\n /** Whether the tile is held or asked for */\n has(key: string): boolean {\n return this.held.has(key);\n }\n\n /** The keys of the tiles held or asked for (a copy: the tiles can be dropped while it is gone through) */\n keys(): string[] {\n return [...this.held.keys()];\n }\n\n /** Holds a new request under `key` (the one it held before is forgotten, not aborted); returns its signal */\n start(key: string): AbortSignal {\n return this.open(key).signal;\n }\n\n /**\n * Asks for a tile (`request`) and does with its answer what `use` does, unless the request was aborted meanwhile. On\n * a failure of either, the tile is forgotten (the next update asks for it again); an error of `use` (the engine\n * refusing the tile) is reported, never left unhandled\n */\n ask<T>(key: string, request: (signal: AbortSignal) => Promise<T>, use: (answer: T) => unknown): Promise<void> {\n const controller = this.open(key);\n // A later request under the same key is not forgotten by this one's failure (nor one dropped: it is not wanted)\n const forget = () => {\n if (this.held.get(key) !== controller) return;\n this.held.delete(key);\n this.failed();\n };\n\n const answered = request(controller.signal)\n .then(async (answer) => {\n if (controller.signal.aborted) return;\n\n try {\n await use(answer);\n this.retry.wait = RETRY_FIRST_MS;\n } catch (error) {\n console.warn('isard: a vector tile not drawn', error);\n forget();\n }\n }, forget)\n .finally(() => {\n if (this.pending.get(key) === answered) this.pending.delete(key);\n });\n\n this.pending.set(key, answered);\n\n return answered;\n }\n\n /** Resolves once the tiles of `keys` asked for, by this update or an earlier one, are answered (or dropped) */\n answered(keys: Iterable<string>): Promise<void> {\n return Promise.all([...keys].map((k) => this.pending.get(k))).then(() => undefined);\n }\n\n /** Aborts the tile's request and forgets it */\n drop(key: string): void {\n this.held.get(key)?.abort();\n this.held.delete(key);\n }\n\n /** Aborts every request and forgets every tile, a retry due with them */\n abortAll(): void {\n this.held.forEach((controller) => {\n controller.abort();\n });\n this.held.clear();\n clearTimeout(this.retry.timer);\n this.retry.timer = undefined;\n this.retry.wait = RETRY_FIRST_MS;\n }\n\n /** A tile failed: the update asked for after the pause, once for every tile failed meanwhile */\n private failed(): void {\n const { update, timer, wait } = this.retry;\n\n if (!update || timer !== undefined) return;\n this.retry.timer = setTimeout(() => {\n this.retry.timer = undefined;\n update();\n }, wait);\n this.retry.wait = Math.min(wait * 2, RETRY_MAX_MS);\n }\n\n private open(key: string): AbortController {\n const controller = new AbortController();\n\n this.held.set(key, controller);\n\n return controller;\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  /** The wind through the streets of a vector basemap (`VectorTiles.streetWind`): a flow round its buildings */
2
- import { EARTH_METRES, latitude, longitude, mercatorX, mercatorY } from "../../util/geo.js";
2
+ import { EARTH_METRES, latitude, longitude, mercatorX, mercatorY, RAD } from "../../util/geo.js";
3
3
  import { TileRequests } from "./requests.js";
4
4
  import { isBuildings, isPolygonLayer } from "./style.js";
5
5
  import { STREET_ZOOM } from "./tiles.js";
@@ -44,7 +44,7 @@ export const streetWind = (context, options = {}) => {
44
44
  const camera = map.getCamera();
45
45
  const [x, y] = [mercatorX(camera.center[0]), mercatorY(camera.center[1])];
46
46
  // Half the square in Mercator, at its latitude
47
- const half = size / 2 / (EARTH_METRES * Math.cos((camera.center[1] * Math.PI) / 180));
47
+ const half = size / 2 / (EARTH_METRES * Math.cos(camera.center[1] * RAD));
48
48
  const square = state.square;
49
49
  // Off street level: no square (its particles gone, asked for again back at street level)
50
50
  if (camera.zoom < minZoom) {
@@ -1 +1 @@
1
- {"version":3,"file":"street-wind.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/street-wind.ts"],"names":[],"mappings":"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","sourcesContent":["/** The wind through the streets of a vector basemap (`VectorTiles.streetWind`): a flow round its buildings */\n\nimport type { StreetFlows } from '../../grid-module.ts';\nimport type { FlowField, FlowLayer, FlowOptions } from '../../layers/flow.ts';\nimport { EARTH_METRES, latitude, longitude, mercatorX, mercatorY } from '../../util/geo.ts';\nimport type { BasemapWork } 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 { STREET_ZOOM } from './tiles.ts';\n\n/** Pause before the first square that failed is asked for again (ms) */\nconst RETRY_FIRST_MS = 1000;\n\n/** Longest pause before a square that failed again and again is asked for again (ms) */\nconst RETRY_MAX_MS = 30_000;\n\n/** The options of `VectorTiles.streetWind` */\nexport type StreetWindOptions = Omit<FlowOptions, 'field' | 'fields' | 'time'> & {\n wind?: [u: number, v: number];\n size?: number;\n cell?: number;\n iterations?: number;\n layers?: (layer: StyleLayer) => boolean;\n minZoom?: number;\n};\n\n/** The layer of `VectorTiles.streetWind` */\nexport type StreetWindLayer = FlowLayer & { setWind(wind: [u: number, v: number]): void; computed: Promise<void> };\n\nexport const streetWind = (context: VectorTilesContext, options: StreetWindOptions = {}): StreetWindLayer => {\n const { map } = context;\n const { size = 1200, cell = 4, iterations = 300, layers = isBuildings, minZoom = STREET_ZOOM, ...flow } = options;\n const renderer = context.renderer(isPolygonLayer(layers), []);\n /** No square: a field of no value at the view's center, where no particle is born nor moves (the map idles) */\n const empty = (): FlowField => {\n const [lon, lat] = map.getCamera().center;\n\n return {\n width: 2,\n height: 2,\n u: [NaN, NaN, NaN, NaN],\n v: [NaN, NaN, NaN, NaN],\n bounds: [lon, lat, lon + 1e-4, lat + 1e-4],\n };\n };\n const layer = map.addFlow({ height: 3, ...flow, field: empty() });\n const state: {\n wind: [number, number];\n /** The square solved (Mercator: west, north, east, south), its grid, the flows of its basis */\n square?: [number, number, number, number] | undefined;\n grid?: { width: number; height: number; bounds: [number, number, number, number] };\n flows?: StreetFlows | undefined;\n /** Bumped by each square asked for: only the last one's answer is taken */\n asked: number;\n /** After a failure, the square asked for again in `wait` ms (doubled each time) */\n retry?: number;\n wait: number;\n } = { wind: options.wind ?? [3, 2], asked: 0, wait: RETRY_FIRST_MS };\n /** The flow of the wind far away: `u` times the flow towards the east plus `v` times the one towards the north,\n * mixed by the engine (the two flows sent once a square, a new wind two numbers) */\n const send = () => {\n const { flows, grid, wind } = state;\n\n if (!flows || !grid) return;\n layer.setBasis({ ...grid, u: flows.eastU, v: flows.eastV }, { ...grid, u: flows.northU, v: flows.northV }, wind);\n };\n /** The square asked for, its only request (under `square`) */\n const requests = new TileRequests();\n const first: { resolve?: () => void } = {};\n const computed = new Promise<void>((resolve) => {\n first.resolve = resolve;\n });\n const update = async () => {\n if (context.destroyed()) return;\n\n const camera = map.getCamera();\n const [x, y] = [mercatorX(camera.center[0]), mercatorY(camera.center[1])];\n // Half the square in Mercator, at its latitude\n const half = size / 2 / (EARTH_METRES * Math.cos((camera.center[1] * Math.PI) / 180));\n const square = state.square;\n\n // Off street level: no square (its particles gone, asked for again back at street level)\n if (camera.zoom < minZoom) {\n if (state.square) {\n state.asked++;\n state.square = undefined;\n state.flows = undefined;\n requests.abortAll();\n layer.setField(empty());\n }\n\n return;\n }\n // Still in the square's middle: nothing to compute\n if (\n square &&\n Math.abs(x - (square[0] + square[2]) / 2) < half / 3 &&\n Math.abs(y - (square[1] + square[3]) / 2) < half / 3\n ) {\n return;\n }\n\n const { key, maxzoom } = await renderer;\n const bounds: [number, number, number, number] = [x - half, y - half, x + half, y + half];\n const n = 2 ** maxzoom;\n const tiles: number[] = [];\n\n for (let ty = Math.floor(bounds[1] * n); ty <= Math.floor(bounds[3] * n); ty++) {\n for (let tx = Math.floor(bounds[0] * n); tx <= Math.floor(bounds[2] * n); tx++) tiles.push(tx, ty);\n }\n\n const sides = Math.max(8, Math.round(size / cell));\n const work: BasemapWork = {\n type: 'street',\n key,\n module: map.gridUrl,\n z: maxzoom,\n tiles,\n bounds,\n width: sides,\n height: sides,\n iterations,\n };\n const asked = ++state.asked;\n\n requests.abortAll();\n\n const signal = requests.start('square');\n\n state.square = bounds;\n\n const answer = await context\n .request(maxzoom, Math.floor(x * n), Math.floor(y * n), work, signal)\n .catch((error: unknown) => ({ error }));\n\n if (asked !== state.asked || signal.aborted) return;\n // Failed (a tile or the grid module not fetched, a worker of an older build): the square asked for again later,\n // a while after each failure\n if (!('street' in answer)) {\n console.warn(\"isard: the streets' wind not computed, tried again\", 'error' in answer ? answer.error : answer);\n state.square = undefined;\n clearTimeout(state.retry);\n state.retry = window.setTimeout(() => {\n update().catch(() => undefined);\n }, state.wait);\n state.wait = Math.min(state.wait * 2, RETRY_MAX_MS);\n\n return;\n }\n state.wait = RETRY_FIRST_MS;\n state.flows = answer.street;\n state.grid = {\n width: sides,\n height: sides,\n bounds: [longitude(bounds[0]), latitude(bounds[3]), longitude(bounds[2]), latitude(bounds[1])],\n };\n send();\n first.resolve?.();\n };\n\n renderer.catch(() => undefined);\n context.layers.push(layer);\n context.followView(layer, update, requests, () => undefined);\n context.stopWith(layer, () => {\n clearTimeout(state.retry);\n });\n\n return Object.assign(layer, {\n computed,\n setWind: (wind: [u: number, v: number]) => {\n state.wind = wind;\n layer.setWeights(wind);\n },\n });\n};\n"]}
1
+ {"version":3,"file":"street-wind.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/street-wind.ts"],"names":[],"mappings":"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","sourcesContent":["/** The wind through the streets of a vector basemap (`VectorTiles.streetWind`): a flow round its buildings */\n\nimport type { StreetFlows } from '../../grid-module.ts';\nimport type { FlowField, FlowLayer, FlowOptions } from '../../layers/flow.ts';\nimport { EARTH_METRES, latitude, longitude, mercatorX, mercatorY, RAD } from '../../util/geo.ts';\nimport type { BasemapWork } from '../../workers/basemap/protocol.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 { STREET_ZOOM } from './tiles.ts';\n\n/** Pause before the first square that failed is asked for again (ms) */\nconst RETRY_FIRST_MS = 1000;\n\n/** Longest pause before a square that failed again and again is asked for again (ms) */\nconst RETRY_MAX_MS = 30_000;\n\n/** The options of `VectorTiles.streetWind` */\nexport type StreetWindOptions = Omit<FlowOptions, 'field' | 'fields' | 'time'> & {\n wind?: [u: number, v: number];\n size?: number;\n cell?: number;\n iterations?: number;\n layers?: (layer: StyleLayer) => boolean;\n minZoom?: number;\n};\n\n/** The layer of `VectorTiles.streetWind` */\nexport type StreetWindLayer = FlowLayer & { setWind(wind: [u: number, v: number]): void; computed: Promise<void> };\n\nexport const streetWind = (context: VectorTilesContext, options: StreetWindOptions = {}): StreetWindLayer => {\n const { map } = context;\n const { size = 1200, cell = 4, iterations = 300, layers = isBuildings, minZoom = STREET_ZOOM, ...flow } = options;\n const renderer = context.renderer(isPolygonLayer(layers), []);\n /** No square: a field of no value at the view's center, where no particle is born nor moves (the map idles) */\n const empty = (): FlowField => {\n const [lon, lat] = map.getCamera().center;\n\n return {\n width: 2,\n height: 2,\n u: [NaN, NaN, NaN, NaN],\n v: [NaN, NaN, NaN, NaN],\n bounds: [lon, lat, lon + 1e-4, lat + 1e-4],\n };\n };\n const layer = map.addFlow({ height: 3, ...flow, field: empty() });\n const state: {\n wind: [number, number];\n /** The square solved (Mercator: west, north, east, south), its grid, the flows of its basis */\n square?: [number, number, number, number] | undefined;\n grid?: { width: number; height: number; bounds: [number, number, number, number] };\n flows?: StreetFlows | undefined;\n /** Bumped by each square asked for: only the last one's answer is taken */\n asked: number;\n /** After a failure, the square asked for again in `wait` ms (doubled each time) */\n retry?: number;\n wait: number;\n } = { wind: options.wind ?? [3, 2], asked: 0, wait: RETRY_FIRST_MS };\n /** The flow of the wind far away: `u` times the flow towards the east plus `v` times the one towards the north,\n * mixed by the engine (the two flows sent once a square, a new wind two numbers) */\n const send = () => {\n const { flows, grid, wind } = state;\n\n if (!flows || !grid) return;\n layer.setBasis({ ...grid, u: flows.eastU, v: flows.eastV }, { ...grid, u: flows.northU, v: flows.northV }, wind);\n };\n /** The square asked for, its only request (under `square`) */\n const requests = new TileRequests();\n const first: { resolve?: () => void } = {};\n const computed = new Promise<void>((resolve) => {\n first.resolve = resolve;\n });\n const update = async () => {\n if (context.destroyed()) return;\n\n const camera = map.getCamera();\n const [x, y] = [mercatorX(camera.center[0]), mercatorY(camera.center[1])];\n // Half the square in Mercator, at its latitude\n const half = size / 2 / (EARTH_METRES * Math.cos(camera.center[1] * RAD));\n const square = state.square;\n\n // Off street level: no square (its particles gone, asked for again back at street level)\n if (camera.zoom < minZoom) {\n if (state.square) {\n state.asked++;\n state.square = undefined;\n state.flows = undefined;\n requests.abortAll();\n layer.setField(empty());\n }\n\n return;\n }\n // Still in the square's middle: nothing to compute\n if (\n square &&\n Math.abs(x - (square[0] + square[2]) / 2) < half / 3 &&\n Math.abs(y - (square[1] + square[3]) / 2) < half / 3\n ) {\n return;\n }\n\n const { key, maxzoom } = await renderer;\n const bounds: [number, number, number, number] = [x - half, y - half, x + half, y + half];\n const n = 2 ** maxzoom;\n const tiles: number[] = [];\n\n for (let ty = Math.floor(bounds[1] * n); ty <= Math.floor(bounds[3] * n); ty++) {\n for (let tx = Math.floor(bounds[0] * n); tx <= Math.floor(bounds[2] * n); tx++) tiles.push(tx, ty);\n }\n\n const sides = Math.max(8, Math.round(size / cell));\n const work: BasemapWork = {\n type: 'street',\n key,\n module: map.gridUrl,\n z: maxzoom,\n tiles,\n bounds,\n width: sides,\n height: sides,\n iterations,\n };\n const asked = ++state.asked;\n\n requests.abortAll();\n\n const signal = requests.start('square');\n\n state.square = bounds;\n\n const answer = await context\n .request(maxzoom, Math.floor(x * n), Math.floor(y * n), work, signal)\n .catch((error: unknown) => ({ error }));\n\n if (asked !== state.asked || signal.aborted) return;\n // Failed (a tile or the grid module not fetched, a worker of an older build): the square asked for again later,\n // a while after each failure\n if (!('street' in answer)) {\n console.warn(\"isard: the streets' wind not computed, tried again\", 'error' in answer ? answer.error : answer);\n state.square = undefined;\n clearTimeout(state.retry);\n state.retry = window.setTimeout(() => {\n update().catch(() => undefined);\n }, state.wait);\n state.wait = Math.min(state.wait * 2, RETRY_MAX_MS);\n\n return;\n }\n state.wait = RETRY_FIRST_MS;\n state.flows = answer.street;\n state.grid = {\n width: sides,\n height: sides,\n bounds: [longitude(bounds[0]), latitude(bounds[3]), longitude(bounds[2]), latitude(bounds[1])],\n };\n send();\n first.resolve?.();\n };\n\n renderer.catch(() => undefined);\n context.layers.push(layer);\n context.followView(layer, update, requests, () => undefined);\n context.stopWith(layer, () => {\n clearTimeout(state.retry);\n });\n\n return Object.assign(layer, {\n computed,\n setWind: (wind: [u: number, v: number]) => {\n state.wind = wind;\n layer.setWeights(wind);\n },\n });\n};\n"]}
@@ -3,9 +3,10 @@
3
3
  * source resolved (a TileJSON, a PMTiles archive) and its raster sources, the fonts of its labels, the style layers
4
4
  * of buildings.
5
5
  */
6
- import { withHeaders } from "../../engine/requests.js";
7
6
  import { IGN_ATTRIBUTION } from "../../geoplateforme.js";
7
+ import { fetchOk } from "../../util/fetch.js";
8
8
  import { isRecord } from "../../util/guards.js";
9
+ import { withHeaders } from "../../util/requests.js";
9
10
  import { OPENFREEMAP_ATTRIBUTION } from "../basemaps.js";
10
11
  import { pmtiles, pmtilesUrl } from "../pmtiles.js";
11
12
  import { isStyle, labelFont } from "../vectorstyle.js";
@@ -49,16 +50,14 @@ const DEFAULT_RASTER_MAXZOOM = 22;
49
50
  const DEFAULT_RASTER_TILE_SIZE = 512;
50
51
  /** Fetches a JSON document (a style, a TileJSON) */
51
52
  const json = async (url) => {
52
- const response = await fetch(url, withHeaders(url));
53
- if (!response.ok)
54
- throw new Error(`${url}: ${response.status}`);
53
+ const response = await fetchOk(url, withHeaders(url));
55
54
  return response.json();
56
55
  };
57
56
  /** A style fetched: a MapLibre style, or an error */
58
57
  const fetchStyle = async (url) => {
59
58
  const style = await json(url);
60
59
  if (!isStyle(style))
61
- throw new Error(`${url}: not a MapLibre style`);
60
+ throw new Error(`isard: ${url}: not a MapLibre style`);
62
61
  return style;
63
62
  };
64
63
  const isTileJson = (value) => isRecord(value) &&
@@ -69,7 +68,7 @@ const isTileJson = (value) => isRecord(value) &&
69
68
  const fetchTileJson = async (url) => {
70
69
  const tilejson = await json(url);
71
70
  if (!isTileJson(tilejson))
72
- throw new Error(`${url}: not a TileJSON`);
71
+ throw new Error(`isard: ${url}: not a TileJSON`);
73
72
  return tilejson;
74
73
  };
75
74
  /**
@@ -92,14 +91,14 @@ export const loadStyle = async (input) => {
92
91
  const style = typeof input === 'string' ? await fetchStyle(input) : input;
93
92
  const [name, source] = Object.entries(style.sources).find(([, s]) => s.type === 'vector') ?? [];
94
93
  if (!name || !source)
95
- throw new Error('the style has no vector source');
94
+ throw new Error('isard: the style has no vector source');
96
95
  const resolved = await resolveSource(source);
97
96
  const tilejson = !resolved.tiles && source.url ? await fetchTileJson(source.url) : undefined;
98
97
  const tiles = tilejson === undefined ? resolved.tiles : tilejson.tiles;
99
98
  const maxzoom = resolved.maxzoom ?? tilejson?.maxzoom;
100
99
  const template = tiles?.[0];
101
100
  if (!template)
102
- throw new Error(`source ${name} has no tiles`);
101
+ throw new Error(`isard: the source ${name} has no tiles`);
103
102
  // Its raster sources of tiles, drawn into the same images (the shaded relief of a style at low zoom)
104
103
  const rasters = {};
105
104
  for (const [key, s] of Object.entries(style.sources)) {