isard 1.7.0 → 1.9.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 (229) hide show
  1. package/CHANGELOG.md +53 -0
  2. package/dist/basemap/grid.js +2 -5
  3. package/dist/basemap/grid.js.map +1 -1
  4. package/dist/basemap/models/furniture.d.ts +12 -0
  5. package/dist/basemap/{furniture.js → models/furniture.js} +6 -8
  6. package/dist/basemap/models/furniture.js.map +1 -0
  7. package/dist/basemap/{meshes.js → models/meshes.js} +1 -1
  8. package/dist/basemap/models/meshes.js.map +1 -0
  9. package/dist/basemap/models/trees.d.ts +21 -0
  10. package/dist/basemap/{trees.js → models/trees.js} +4 -36
  11. package/dist/basemap/models/trees.js.map +1 -0
  12. package/dist/basemap/placed.d.ts +2 -0
  13. package/dist/basemap/placed.js +2 -0
  14. package/dist/basemap/placed.js.map +1 -1
  15. package/dist/basemap/pmtiles.js +4 -3
  16. package/dist/basemap/pmtiles.js.map +1 -1
  17. package/dist/basemap/pmtileslayer.d.ts +4 -4
  18. package/dist/basemap/pmtileslayer.js +2 -1
  19. package/dist/basemap/pmtileslayer.js.map +1 -1
  20. package/dist/basemap/resample.js +3 -2
  21. package/dist/basemap/resample.js.map +1 -1
  22. package/dist/basemap/terrain.d.ts +5 -0
  23. package/dist/basemap/terrain.js +6 -4
  24. package/dist/basemap/terrain.js.map +1 -1
  25. package/dist/basemap/vectortiles/context.d.ts +3 -2
  26. package/dist/basemap/vectortiles/context.js.map +1 -1
  27. package/dist/basemap/vectortiles/extrusions.js.map +1 -1
  28. package/dist/basemap/vectortiles/furniture.d.ts +3 -3
  29. package/dist/basemap/vectortiles/furniture.js +2 -1
  30. package/dist/basemap/vectortiles/furniture.js.map +1 -1
  31. package/dist/basemap/vectortiles/labels.js +2 -1
  32. package/dist/basemap/vectortiles/labels.js.map +1 -1
  33. package/dist/basemap/vectortiles/lamps.d.ts +3 -3
  34. package/dist/basemap/vectortiles/lamps.js +1 -1
  35. package/dist/basemap/vectortiles/lamps.js.map +1 -1
  36. package/dist/basemap/vectortiles/placed.d.ts +3 -2
  37. package/dist/basemap/vectortiles/placed.js +5 -10
  38. package/dist/basemap/vectortiles/placed.js.map +1 -1
  39. package/dist/basemap/vectortiles/street-wind.js +2 -2
  40. package/dist/basemap/vectortiles/street-wind.js.map +1 -1
  41. package/dist/basemap/vectortiles/style.js +7 -8
  42. package/dist/basemap/vectortiles/style.js.map +1 -1
  43. package/dist/basemap/vectortiles/tiles.d.ts +1 -3
  44. package/dist/basemap/vectortiles/tiles.js +1 -1
  45. package/dist/basemap/vectortiles/tiles.js.map +1 -1
  46. package/dist/basemap/vectortiles/trees.d.ts +4 -4
  47. package/dist/basemap/vectortiles/trees.js +2 -1
  48. package/dist/basemap/vectortiles/trees.js.map +1 -1
  49. package/dist/basemap/vectortiles/vectors.d.ts +2 -3
  50. package/dist/basemap/vectortiles/vectors.js.map +1 -1
  51. package/dist/basemap/vectortiles.d.ts +6 -5
  52. package/dist/basemap/vectortiles.js +4 -3
  53. package/dist/basemap/vectortiles.js.map +1 -1
  54. package/dist/basemap/wmts.js +3 -4
  55. package/dist/basemap/wmts.js.map +1 -1
  56. package/dist/basemap/{trees.d.ts → woods.d.ts} +2 -19
  57. package/dist/basemap/woods.js +38 -0
  58. package/dist/basemap/woods.js.map +1 -0
  59. package/dist/basemap/workerpool.d.ts +1 -1
  60. package/dist/basemap/workerpool.js +3 -3
  61. package/dist/basemap/workerpool.js.map +1 -1
  62. package/dist/basemap.worker.js +2 -2
  63. package/dist/basemap.worker.js.map +23 -22
  64. package/dist/bind/layers.d.ts +10 -3
  65. package/dist/bind/layers.js +11 -4
  66. package/dist/bind/layers.js.map +1 -1
  67. package/dist/data/collada.js +4 -4
  68. package/dist/data/collada.js.map +1 -1
  69. package/dist/data/ifc.js +6 -11
  70. package/dist/data/ifc.js.map +1 -1
  71. package/dist/decoder.worker.js +5 -5
  72. package/dist/decoder.worker.js.map +7 -6
  73. package/dist/decoding/decoders.js.map +1 -0
  74. package/dist/{engine → decoding}/loader.js +2 -2
  75. package/dist/decoding/loader.js.map +1 -0
  76. package/dist/{engine → decoding}/protocol.d.ts +1 -1
  77. package/dist/decoding/protocol.js.map +1 -0
  78. package/dist/engine-loader.d.ts +1 -1
  79. package/dist/engine-loader.js +3 -2
  80. package/dist/engine-loader.js.map +1 -1
  81. package/dist/geoplateforme.d.ts +4 -3
  82. package/dist/geoplateforme.js +8 -10
  83. package/dist/geoplateforme.js.map +1 -1
  84. package/dist/index.d.ts +16 -8
  85. package/dist/index.js +9 -3
  86. package/dist/index.js.map +1 -1
  87. package/dist/isard_bg.wasm +0 -0
  88. package/dist/isard_core_bg.wasm +0 -0
  89. package/dist/isard_grid_bg.wasm +0 -0
  90. package/dist/isard_tess_bg.wasm +0 -0
  91. package/dist/layers/custom.d.ts +56 -0
  92. package/dist/layers/custom.js +93 -0
  93. package/dist/layers/custom.js.map +1 -0
  94. package/dist/layers/extrusions.d.ts +4 -2
  95. package/dist/layers/extrusions.js +2 -1
  96. package/dist/layers/extrusions.js.map +1 -1
  97. package/dist/layers/features.d.ts +3 -14
  98. package/dist/layers/features.js +4 -25
  99. package/dist/layers/features.js.map +1 -1
  100. package/dist/layers/flow.d.ts +3 -3
  101. package/dist/layers/flow.js +3 -4
  102. package/dist/layers/flow.js.map +1 -1
  103. package/dist/layers/glyphs.js +5 -3
  104. package/dist/layers/glyphs.js.map +1 -1
  105. package/dist/layers/ground.d.ts +57 -0
  106. package/dist/layers/ground.js +78 -0
  107. package/dist/layers/ground.js.map +1 -0
  108. package/dist/layers/icons.js +8 -6
  109. package/dist/layers/icons.js.map +1 -1
  110. package/dist/layers/layers.d.ts +2 -199
  111. package/dist/layers/layers.js +2 -469
  112. package/dist/layers/layers.js.map +1 -1
  113. package/dist/layers/models.d.ts +48 -0
  114. package/dist/layers/models.js +111 -0
  115. package/dist/layers/models.js.map +1 -0
  116. package/dist/layers/network.d.ts +26 -0
  117. package/dist/layers/network.js +127 -0
  118. package/dist/layers/network.js.map +1 -0
  119. package/dist/layers/panoramas.d.ts +2 -11
  120. package/dist/layers/panoramas.js +19 -9
  121. package/dist/layers/panoramas.js.map +1 -1
  122. package/dist/layers/photos.d.ts +4 -7
  123. package/dist/layers/photos.js +3 -4
  124. package/dist/layers/photos.js.map +1 -1
  125. package/dist/layers/pointclouds.d.ts +3 -2
  126. package/dist/layers/pointclouds.js +3 -3
  127. package/dist/layers/pointclouds.js.map +1 -1
  128. package/dist/layers/raster.d.ts +9 -0
  129. package/dist/layers/raster.js +24 -0
  130. package/dist/layers/raster.js.map +1 -0
  131. package/dist/layers/symbols.d.ts +2 -2
  132. package/dist/layers/symbols.js +2 -1
  133. package/dist/layers/symbols.js.map +1 -1
  134. package/dist/layers/tiles3d.d.ts +15 -0
  135. package/dist/layers/tiles3d.js +55 -0
  136. package/dist/layers/tiles3d.js.map +1 -0
  137. package/dist/layers/trees.d.ts +5 -7
  138. package/dist/layers/trees.js +2 -1
  139. package/dist/layers/trees.js.map +1 -1
  140. package/dist/layers/vectors.js.map +1 -1
  141. package/dist/map/basemap-layers.js +1 -1
  142. package/dist/map/basemap-layers.js.map +1 -1
  143. package/dist/map/engine-settings.d.ts +1 -1
  144. package/dist/map/engine-settings.js +1 -1
  145. package/dist/map/engine-settings.js.map +1 -1
  146. package/dist/map/engines.js.map +1 -1
  147. package/dist/map/layer-spec.d.ts +7 -13
  148. package/dist/map/layer-spec.js.map +1 -1
  149. package/dist/map/workers.js +3 -4
  150. package/dist/map/workers.js.map +1 -1
  151. package/dist/map.d.ts +15 -58
  152. package/dist/map.js +39 -52
  153. package/dist/map.js.map +1 -1
  154. package/dist/panoramax.d.ts +15 -2
  155. package/dist/panoramax.js +38 -21
  156. package/dist/panoramax.js.map +1 -1
  157. package/dist/react/CustomLayer.d.ts +1 -1
  158. package/dist/react/CustomLayer.js +5 -4
  159. package/dist/react/CustomLayer.js.map +1 -1
  160. package/dist/react/Layer.d.ts +6 -2
  161. package/dist/react/Layer.js +6 -5
  162. package/dist/react/Layer.js.map +1 -1
  163. package/dist/react/VectorGeometry.js +5 -4
  164. package/dist/react/VectorGeometry.js.map +1 -1
  165. package/dist/react/VectorTiles.d.ts +2 -2
  166. package/dist/react/VectorTiles.js +1 -1
  167. package/dist/react/VectorTiles.js.map +1 -1
  168. package/dist/react/context.d.ts +3 -0
  169. package/dist/react/context.js +8 -1
  170. package/dist/react/context.js.map +1 -1
  171. package/dist/types.d.ts +14 -4
  172. package/dist/types.js.map +1 -1
  173. package/dist/ui/controls.js +2 -1
  174. package/dist/ui/controls.js.map +1 -1
  175. package/dist/ui/interaction.js +6 -5
  176. package/dist/ui/interaction.js.map +1 -1
  177. package/dist/ui/minimap.js +1 -1
  178. package/dist/ui/minimap.js.map +1 -1
  179. package/dist/ui/overlay.js +3 -3
  180. package/dist/ui/overlay.js.map +1 -1
  181. package/dist/ui/search.js +1 -1
  182. package/dist/ui/search.js.map +1 -1
  183. package/dist/util/animation.js +3 -2
  184. package/dist/util/animation.js.map +1 -1
  185. package/dist/util/color.d.ts +10 -0
  186. package/dist/util/color.js +29 -9
  187. package/dist/util/color.js.map +1 -1
  188. package/dist/util/fetch.d.ts +5 -0
  189. package/dist/util/fetch.js +11 -0
  190. package/dist/util/fetch.js.map +1 -0
  191. package/dist/util/geo.d.ts +5 -0
  192. package/dist/util/geo.js +8 -2
  193. package/dist/util/geo.js.map +1 -1
  194. package/dist/util/math.d.ts +3 -0
  195. package/dist/util/math.js +4 -0
  196. package/dist/util/math.js.map +1 -0
  197. package/dist/util/requests.js.map +1 -0
  198. package/dist/util/roofs.d.ts +0 -2
  199. package/dist/util/roofs.js +0 -3
  200. package/dist/util/roofs.js.map +1 -1
  201. package/dist/wasm/isard.js +1 -1
  202. package/dist/wasm/isard_core.js +1 -1
  203. package/dist/workers/basemap/geometry.d.ts +9 -19
  204. package/dist/workers/{basemap.worker.d.ts → basemap/protocol.d.ts} +29 -23
  205. package/dist/workers/basemap/street.d.ts +4 -2
  206. package/dist/workers/basemap/tiles.d.ts +1 -3
  207. package/dist/workers/basemap/trees.d.ts +2 -2
  208. package/package.json +1 -1
  209. package/dist/basemap/furniture.d.ts +0 -26
  210. package/dist/basemap/furniture.js.map +0 -1
  211. package/dist/basemap/meshes.js.map +0 -1
  212. package/dist/basemap/trees.js.map +0 -1
  213. package/dist/engine/decoders.js.map +0 -1
  214. package/dist/engine/loader.js.map +0 -1
  215. package/dist/engine/protocol.js.map +0 -1
  216. package/dist/engine/requests.js.map +0 -1
  217. package/dist/workers/basemap/furniture.d.ts +0 -13
  218. package/dist/workers/basemap/labels.d.ts +0 -24
  219. package/dist/workers/basemap/lamps.d.ts +0 -10
  220. package/dist/workers/basemap/raster.d.ts +0 -10
  221. package/dist/workers/basemap.worker.js +0 -221
  222. package/dist/workers/basemap.worker.js.map +0 -1
  223. /package/dist/basemap/{meshes.d.ts → models/meshes.d.ts} +0 -0
  224. /package/dist/{engine → decoding}/decoders.d.ts +0 -0
  225. /package/dist/{engine → decoding}/decoders.js +0 -0
  226. /package/dist/{engine → decoding}/loader.d.ts +0 -0
  227. /package/dist/{engine → decoding}/protocol.js +0 -0
  228. /package/dist/{engine → util}/requests.d.ts +0 -0
  229. /package/dist/{engine → util}/requests.js +0 -0
@@ -1 +1 @@
1
- {"version":3,"file":"pmtiles.js","sourceRoot":"","sources":["../../src/basemap/pmtiles.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * PMTiles v3 archives: one file of tiles read by HTTP range requests (or from a `Blob`), as Protomaps publishes them.\n * The header and root directory in one request, the leaf directories as needed (kept in a small cache), each tile in\n * its own range; gzip through `DecompressionStream`. The same reader in the page (raster tiles) and in the basemap\n * workers (vector tiles of a style source `pmtiles://…`, as MapLibre's protocol names them).\n */\n\nimport { withHeaders } from '../engine/requests.ts';\nimport { isRecord } from '../util/guards.ts';\nimport { Lru } from '../util/lru.ts';\n\n/** What a PMTiles archive's tiles are */\nexport type PmtilesTileType = 'unknown' | 'mvt' | 'png' | 'jpeg' | 'webp' | 'avif';\n\n/** The header of a PMTiles archive (v3) */\nexport interface PmtilesHeader {\n rootDirectoryOffset: number;\n rootDirectoryLength: number;\n metadataOffset: number;\n metadataLength: number;\n leafDirectoryOffset: number;\n leafDirectoryLength: number;\n tileDataOffset: number;\n tileDataLength: number;\n /** 1 none, 2 gzip, 3 brotli, 4 zstd (only none and gzip are read) */\n internalCompression: number;\n tileCompression: number;\n tileType: PmtilesTileType;\n minZoom: number;\n maxZoom: number;\n /** `[west, south, east, north]`, degrees */\n bounds: [number, number, number, number];\n center: [lon: number, lat: number, zoom: number];\n}\n\n/** An entry of a directory: a run of tiles (`runLength` > 0) or a leaf directory (0) */\nexport interface PmtilesEntry {\n tileId: number;\n offset: number;\n length: number;\n runLength: number;\n}\n\nconst HEADER = 127;\n/** The header and the root directory lie within the first 16 KB of the file */\nconst FIRST = 16384;\nconst TYPES: PmtilesTileType[] = ['unknown', 'mvt', 'png', 'jpeg', 'webp', 'avif'];\n\n/** Tiles before level z: (4^z - 1) / 3 */\nconst levelStart = (z: number) => (4 ** z - 1) / 3;\n\n/** The tile id of z/x/y: the tiles of the lower levels, then the position along the level's Hilbert curve */\nexport const zxyToTileId = (z: number, x: number, y: number): number => {\n if (z > 26) throw new Error(`isard: PMTiles level ${z} past 26`);\n\n const n = 2 ** z;\n\n if (x < 0 || y < 0 || x >= n || y >= n) throw new Error(`isard: PMTiles tile ${z}/${x}/${y} out of its level`);\n\n let [px, py] = [x, y];\n let d = 0;\n\n for (let s = n / 2; s >= 1; s /= 2) {\n const rx = (px & s) > 0 ? 1 : 0;\n const ry = (py & s) > 0 ? 1 : 0;\n\n d += s * s * ((3 * rx) ^ ry);\n if (ry === 0) {\n if (rx === 1) [px, py] = [s - 1 - px, s - 1 - py];\n [px, py] = [py, px];\n }\n }\n\n return levelStart(z) + d;\n};\n\n/** The z/x/y of a tile id (the inverse of `zxyToTileId`) */\nexport const tileIdToZxy = (id: number): [z: number, x: number, y: number] => {\n let z = 0;\n\n while (levelStart(z + 1) <= id) z += 1;\n\n const n = 2 ** z;\n let t = id - levelStart(z);\n let [x, y] = [0, 0];\n\n for (let s = 1; s < n; s *= 2) {\n // Arithmetic, not bitwise: positions pass 32 bits past level 16\n const rx = Math.floor(t / 2) % 2;\n const ry = (t % 2) ^ rx;\n\n if (ry === 0) {\n if (rx === 1) [x, y] = [s - 1 - x, s - 1 - y];\n [x, y] = [y, x];\n }\n x += s * rx;\n y += s * ry;\n t = Math.floor(t / 4);\n }\n\n return [z, x, y];\n};\n\n/** A reader of unsigned varints past 32 bits (tile ids reach 2^52) */\nclass Varints {\n pos = 0;\n constructor(private readonly bytes: Uint8Array) {}\n next(): number {\n let value = 0;\n let scale = 1;\n\n for (;;) {\n const b = this.bytes[this.pos++];\n\n if (b === undefined) throw new Error('isard: PMTiles directory truncated');\n value += (b & 0x7f) * scale;\n if (b < 0x80) return value;\n scale *= 128;\n if (scale > 2 ** 63) throw new Error('isard: PMTiles varint too long');\n }\n }\n}\n\n/** The entries of a directory (decompressed) */\nexport const parseDirectory = (bytes: Uint8Array): PmtilesEntry[] => {\n const v = new Varints(bytes);\n const count = v.next();\n\n if (count > bytes.length) throw new Error('isard: PMTiles directory larger than its bytes');\n\n const entries: PmtilesEntry[] = [];\n let id = 0;\n\n for (let i = 0; i < count; i += 1) {\n id += v.next();\n entries.push({ tileId: id, offset: 0, length: 0, runLength: 1 });\n }\n for (const e of entries) e.runLength = v.next();\n for (const e of entries) e.length = v.next();\n entries.forEach((e, i) => {\n const value = v.next();\n const previous = entries[i - 1];\n\n // 0 after the first: right after the previous entry's bytes\n e.offset = value === 0 && previous ? previous.offset + previous.length : value - 1;\n });\n\n return entries;\n};\n\n/** The entry holding a tile id: its run of tiles, or the leaf directory it falls in; undefined if none */\nexport const findEntry = (entries: readonly PmtilesEntry[], id: number): PmtilesEntry | undefined => {\n let [lo, hi] = [0, entries.length - 1];\n\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n const e = entries[mid];\n\n if (!e) break;\n if (e.tileId === id) return e;\n if (e.tileId < id) lo = mid + 1;\n else hi = mid - 1;\n }\n\n const e = entries[hi];\n\n if (!e) return undefined;\n if (e.runLength === 0 || id - e.tileId < e.runLength) return e;\n\n return undefined;\n};\n\n/** The header of an archive from its first bytes */\nexport const parseHeader = (bytes: Uint8Array): PmtilesHeader => {\n if (bytes.length < HEADER || String.fromCharCode(...bytes.subarray(0, 7)) !== 'PMTiles') {\n throw new Error('isard: not a PMTiles archive');\n }\n if (bytes[7] !== 3) throw new Error(`isard: PMTiles version ${bytes[7]} (only 3 is read)`);\n\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const u64 = (at: number) => Number(view.getBigUint64(at, true));\n const deg = (at: number) => view.getInt32(at, true) / 1e7;\n\n return {\n rootDirectoryOffset: u64(8),\n rootDirectoryLength: u64(16),\n metadataOffset: u64(24),\n metadataLength: u64(32),\n leafDirectoryOffset: u64(40),\n leafDirectoryLength: u64(48),\n tileDataOffset: u64(56),\n tileDataLength: u64(64),\n internalCompression: view.getUint8(97),\n tileCompression: view.getUint8(98),\n tileType: TYPES[view.getUint8(99)] ?? 'unknown',\n minZoom: view.getUint8(100),\n maxZoom: view.getUint8(101),\n bounds: [deg(102), deg(106), deg(110), deg(114)],\n center: [deg(119), deg(123), view.getUint8(118)],\n };\n};\n\n/** Bytes as they are stored, decompressed (1: none, 2: gzip; 0, unknown, is read as none) */\nexport const decompress = async (\n bytes: Uint8Array<ArrayBuffer>,\n compression: number,\n): Promise<Uint8Array<ArrayBuffer>> => {\n if (compression === 0 || compression === 1) return bytes;\n if (compression !== 2) {\n throw new Error(`isard: PMTiles compression ${compression === 3 ? 'brotli' : 'zstd'} is not read (gzip only)`);\n }\n\n const stream = new Blob([bytes]).stream().pipeThrough(new DecompressionStream('gzip'));\n\n return new Uint8Array(await new Response(stream).arrayBuffer());\n};\n\n/** Past this, a whole file sent for a range request (a server ignoring ranges) is an error rather than kept */\nconst WHOLE_FILE_MAX = 64 * 1024 * 1024;\n\n/** A PMTiles archive at a URL (range requests) or in a `Blob` (a dropped file) */\nexport class PMTiles {\n private head: Promise<{ header: PmtilesHeader; root: PmtilesEntry[] }> | undefined;\n /** The leaf directories read, by offset */\n private readonly leaves = new Lru<number, Promise<PmtilesEntry[]>>(64);\n /** The whole file, when the server answered a range request with it (small files, `blob:` URLs) */\n private whole: Promise<Uint8Array<ArrayBuffer>> | undefined;\n\n constructor(readonly source: string | Blob) {}\n\n /** `length` bytes from `offset` */\n private async range(offset: number, length: number, signal?: AbortSignal): Promise<Uint8Array<ArrayBuffer>> {\n if (typeof this.source !== 'string') {\n return new Uint8Array(await this.source.slice(offset, offset + length).arrayBuffer());\n }\n if (this.whole) return (await this.whole).subarray(offset, offset + length);\n\n const response = await fetch(\n this.source,\n withHeaders(this.source, {\n headers: { Range: `bytes=${offset}-${offset + Math.max(length, 1) - 1}` },\n ...(signal ? { signal } : {}),\n }),\n );\n\n if (!response.ok) throw new Error(`${this.source}: HTTP ${response.status}`);\n if (response.status === 206) return new Uint8Array(await response.arrayBuffer());\n\n // The whole file: kept, when small enough, for the next ranges\n const size = Number(response.headers.get('Content-Length'));\n\n if (size > WHOLE_FILE_MAX) {\n await response.body?.cancel();\n throw new Error(`${this.source}: the server ignores range requests (HTTP 206 expected)`);\n }\n\n const whole = response.arrayBuffer().then((b) => new Uint8Array(b));\n\n this.whole = whole;\n whole.catch(() => {\n this.whole = undefined;\n });\n\n return (await whole).subarray(offset, offset + length);\n }\n\n private load() {\n this.head ??= (async () => {\n const first = await this.range(0, FIRST);\n const header = parseHeader(first);\n const { rootDirectoryOffset: o, rootDirectoryLength: n } = header;\n const raw = o + n <= first.length ? first.subarray(o, o + n) : await this.range(o, n);\n const root = parseDirectory(await decompress(raw, header.internalCompression));\n\n return { header, root };\n })();\n // A failure is not kept: asked again next time\n this.head.catch(() => {\n this.head = undefined;\n });\n\n return this.head;\n }\n\n /** The archive's header */\n async header(): Promise<PmtilesHeader> {\n return (await this.load()).header;\n }\n\n /** The archive's JSON metadata (`vector_layers`, `attribution`, `name`…); `{}` if it has none */\n async metadata(): Promise<Record<string, unknown>> {\n const { header } = await this.load();\n\n if (header.metadataLength === 0) return {};\n\n const raw = await this.range(header.metadataOffset, header.metadataLength);\n const text = new TextDecoder().decode(await decompress(raw, header.internalCompression));\n const value: unknown = JSON.parse(text);\n\n return isRecord(value) ? value : {};\n }\n\n private leaf(header: PmtilesHeader, entry: PmtilesEntry): Promise<PmtilesEntry[]> {\n const offset = header.leafDirectoryOffset + entry.offset;\n const cached = this.leaves.get(offset);\n\n if (cached) return cached;\n\n const leaf = this.range(offset, entry.length).then(async (raw) =>\n parseDirectory(await decompress(raw, header.internalCompression)),\n );\n\n leaf.catch(() => this.leaves.delete(offset));\n this.leaves.set(offset, leaf);\n\n return leaf;\n }\n\n /** The bytes of tile z/x/y, decompressed (a vector tile ungzipped); undefined where the archive has none */\n async tile(z: number, x: number, y: number, signal?: AbortSignal): Promise<Uint8Array<ArrayBuffer> | undefined> {\n const { header, root } = await this.load();\n\n if (z < header.minZoom || z > header.maxZoom) return undefined;\n\n const id = zxyToTileId(z, x, y);\n let entries = root;\n\n // The root, then at most three levels of leaves\n for (let depth = 0; depth < 4; depth += 1) {\n const entry = findEntry(entries, id);\n\n if (!entry) return undefined;\n if (entry.runLength > 0) {\n const raw = await this.range(header.tileDataOffset + entry.offset, entry.length, signal);\n\n return decompress(raw, header.tileCompression);\n }\n entries = await this.leaf(header, entry);\n }\n throw new Error('isard: PMTiles directories nested too deep');\n }\n}\n\n/** The archives opened, by URL: one reader (and its directory cache) per archive in a page or worker */\nconst archives = new Lru<string, PMTiles>(16);\n\n/** The reader of an archive URL (without `pmtiles://`), shared */\nexport const pmtiles = (url: string): PMTiles => {\n const cached = archives.get(url);\n\n if (cached) return cached;\n\n const archive = new PMTiles(url);\n\n archives.set(url, archive);\n\n return archive;\n};\n\n/** The URL of the page (or of the worker); undefined out of a browser */\nconst pageUrl = (): string | undefined => {\n const location: unknown = Reflect.get(globalThis, 'location');\n\n return isRecord(location) && typeof location.href === 'string' ? location.href : undefined;\n};\n\n/** The archive URL of a `pmtiles://` URL, absolute (relative to the page), or undefined for another URL */\nexport const pmtilesUrl = (url: string, base?: string): string | undefined => {\n if (!url.startsWith('pmtiles://')) return undefined;\n\n const inner = url.slice('pmtiles://'.length);\n const from = base ?? pageUrl();\n\n try {\n return from ? new URL(inner, from).href : inner;\n } catch {\n return inner;\n }\n};\n\n/** A tile URL `pmtiles://<archive>/{z}/{x}/{y}` (with its numbers in) read from its archive: its bytes, undefined\n * where there is none; undefined too (`false`) for a URL that is not one */\nexport const pmtilesTile = (\n url: string,\n signal?: AbortSignal,\n): Promise<Uint8Array<ArrayBuffer> | undefined> | false => {\n const match = /^pmtiles:\\/\\/(.+)\\/(\\d+)\\/(\\d+)\\/(\\d+)$/.exec(url);\n\n if (!match) return false;\n\n const [, archive = '', z, x, y] = match;\n\n return pmtiles(archive).tile(Number(z), Number(x), Number(y), signal);\n};\n"]}
1
+ {"version":3,"file":"pmtiles.js","sourceRoot":"","sources":["../../src/basemap/pmtiles.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * PMTiles v3 archives: one file of tiles read by HTTP range requests (or from a `Blob`), as Protomaps publishes them.\n * The header and root directory in one request, the leaf directories as needed (kept in a small cache), each tile in\n * its own range; gzip through `DecompressionStream`. The same reader in the page (raster tiles) and in the basemap\n * workers (vector tiles of a style source `pmtiles://…`, as MapLibre's protocol names them).\n */\n\nimport { httpError } from '../util/fetch.ts';\nimport { isRecord } from '../util/guards.ts';\nimport { Lru } from '../util/lru.ts';\nimport { withHeaders } from '../util/requests.ts';\n\n/** What a PMTiles archive's tiles are */\nexport type PmtilesTileType = 'unknown' | 'mvt' | 'png' | 'jpeg' | 'webp' | 'avif';\n\n/** The header of a PMTiles archive (v3) */\nexport interface PmtilesHeader {\n rootDirectoryOffset: number;\n rootDirectoryLength: number;\n metadataOffset: number;\n metadataLength: number;\n leafDirectoryOffset: number;\n leafDirectoryLength: number;\n tileDataOffset: number;\n tileDataLength: number;\n /** 1 none, 2 gzip, 3 brotli, 4 zstd (only none and gzip are read) */\n internalCompression: number;\n tileCompression: number;\n tileType: PmtilesTileType;\n minZoom: number;\n maxZoom: number;\n /** `[west, south, east, north]`, degrees */\n bounds: [number, number, number, number];\n center: [lon: number, lat: number, zoom: number];\n}\n\n/** An entry of a directory: a run of tiles (`runLength` > 0) or a leaf directory (0) */\nexport interface PmtilesEntry {\n tileId: number;\n offset: number;\n length: number;\n runLength: number;\n}\n\nconst HEADER = 127;\n/** The header and the root directory lie within the first 16 KB of the file */\nconst FIRST = 16384;\nconst TYPES: PmtilesTileType[] = ['unknown', 'mvt', 'png', 'jpeg', 'webp', 'avif'];\n\n/** Tiles before level z: (4^z - 1) / 3 */\nconst levelStart = (z: number) => (4 ** z - 1) / 3;\n\n/** The tile id of z/x/y: the tiles of the lower levels, then the position along the level's Hilbert curve */\nexport const zxyToTileId = (z: number, x: number, y: number): number => {\n if (z > 26) throw new Error(`isard: PMTiles level ${z} past 26`);\n\n const n = 2 ** z;\n\n if (x < 0 || y < 0 || x >= n || y >= n) throw new Error(`isard: PMTiles tile ${z}/${x}/${y} out of its level`);\n\n let [px, py] = [x, y];\n let d = 0;\n\n for (let s = n / 2; s >= 1; s /= 2) {\n const rx = (px & s) > 0 ? 1 : 0;\n const ry = (py & s) > 0 ? 1 : 0;\n\n d += s * s * ((3 * rx) ^ ry);\n if (ry === 0) {\n if (rx === 1) [px, py] = [s - 1 - px, s - 1 - py];\n [px, py] = [py, px];\n }\n }\n\n return levelStart(z) + d;\n};\n\n/** The z/x/y of a tile id (the inverse of `zxyToTileId`) */\nexport const tileIdToZxy = (id: number): [z: number, x: number, y: number] => {\n let z = 0;\n\n while (levelStart(z + 1) <= id) z += 1;\n\n const n = 2 ** z;\n let t = id - levelStart(z);\n let [x, y] = [0, 0];\n\n for (let s = 1; s < n; s *= 2) {\n // Arithmetic, not bitwise: positions pass 32 bits past level 16\n const rx = Math.floor(t / 2) % 2;\n const ry = (t % 2) ^ rx;\n\n if (ry === 0) {\n if (rx === 1) [x, y] = [s - 1 - x, s - 1 - y];\n [x, y] = [y, x];\n }\n x += s * rx;\n y += s * ry;\n t = Math.floor(t / 4);\n }\n\n return [z, x, y];\n};\n\n/** A reader of unsigned varints past 32 bits (tile ids reach 2^52) */\nclass Varints {\n pos = 0;\n constructor(private readonly bytes: Uint8Array) {}\n next(): number {\n let value = 0;\n let scale = 1;\n\n for (;;) {\n const b = this.bytes[this.pos++];\n\n if (b === undefined) throw new Error('isard: PMTiles directory truncated');\n value += (b & 0x7f) * scale;\n if (b < 0x80) return value;\n scale *= 128;\n if (scale > 2 ** 63) throw new Error('isard: PMTiles varint too long');\n }\n }\n}\n\n/** The entries of a directory (decompressed) */\nexport const parseDirectory = (bytes: Uint8Array): PmtilesEntry[] => {\n const v = new Varints(bytes);\n const count = v.next();\n\n if (count > bytes.length) throw new Error('isard: PMTiles directory larger than its bytes');\n\n const entries: PmtilesEntry[] = [];\n let id = 0;\n\n for (let i = 0; i < count; i += 1) {\n id += v.next();\n entries.push({ tileId: id, offset: 0, length: 0, runLength: 1 });\n }\n for (const e of entries) e.runLength = v.next();\n for (const e of entries) e.length = v.next();\n entries.forEach((e, i) => {\n const value = v.next();\n const previous = entries[i - 1];\n\n // 0 after the first: right after the previous entry's bytes\n e.offset = value === 0 && previous ? previous.offset + previous.length : value - 1;\n });\n\n return entries;\n};\n\n/** The entry holding a tile id: its run of tiles, or the leaf directory it falls in; undefined if none */\nexport const findEntry = (entries: readonly PmtilesEntry[], id: number): PmtilesEntry | undefined => {\n let [lo, hi] = [0, entries.length - 1];\n\n while (lo <= hi) {\n const mid = (lo + hi) >> 1;\n const e = entries[mid];\n\n if (!e) break;\n if (e.tileId === id) return e;\n if (e.tileId < id) lo = mid + 1;\n else hi = mid - 1;\n }\n\n const e = entries[hi];\n\n if (!e) return undefined;\n if (e.runLength === 0 || id - e.tileId < e.runLength) return e;\n\n return undefined;\n};\n\n/** The header of an archive from its first bytes */\nexport const parseHeader = (bytes: Uint8Array): PmtilesHeader => {\n if (bytes.length < HEADER || String.fromCharCode(...bytes.subarray(0, 7)) !== 'PMTiles') {\n throw new Error('isard: not a PMTiles archive');\n }\n if (bytes[7] !== 3) throw new Error(`isard: PMTiles version ${bytes[7]} (only 3 is read)`);\n\n const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);\n const u64 = (at: number) => Number(view.getBigUint64(at, true));\n const deg = (at: number) => view.getInt32(at, true) / 1e7;\n\n return {\n rootDirectoryOffset: u64(8),\n rootDirectoryLength: u64(16),\n metadataOffset: u64(24),\n metadataLength: u64(32),\n leafDirectoryOffset: u64(40),\n leafDirectoryLength: u64(48),\n tileDataOffset: u64(56),\n tileDataLength: u64(64),\n internalCompression: view.getUint8(97),\n tileCompression: view.getUint8(98),\n tileType: TYPES[view.getUint8(99)] ?? 'unknown',\n minZoom: view.getUint8(100),\n maxZoom: view.getUint8(101),\n bounds: [deg(102), deg(106), deg(110), deg(114)],\n center: [deg(119), deg(123), view.getUint8(118)],\n };\n};\n\n/** Bytes as they are stored, decompressed (1: none, 2: gzip; 0, unknown, is read as none) */\nexport const decompress = async (\n bytes: Uint8Array<ArrayBuffer>,\n compression: number,\n): Promise<Uint8Array<ArrayBuffer>> => {\n if (compression === 0 || compression === 1) return bytes;\n if (compression !== 2) {\n throw new Error(`isard: PMTiles compression ${compression === 3 ? 'brotli' : 'zstd'} is not read (gzip only)`);\n }\n\n const stream = new Blob([bytes]).stream().pipeThrough(new DecompressionStream('gzip'));\n\n return new Uint8Array(await new Response(stream).arrayBuffer());\n};\n\n/** Past this, a whole file sent for a range request (a server ignoring ranges) is an error rather than kept */\nconst WHOLE_FILE_MAX = 64 * 1024 * 1024;\n\n/** A PMTiles archive at a URL (range requests) or in a `Blob` (a dropped file) */\nexport class PMTiles {\n private head: Promise<{ header: PmtilesHeader; root: PmtilesEntry[] }> | undefined;\n /** The leaf directories read, by offset */\n private readonly leaves = new Lru<number, Promise<PmtilesEntry[]>>(64);\n /** The whole file, when the server answered a range request with it (small files, `blob:` URLs) */\n private whole: Promise<Uint8Array<ArrayBuffer>> | undefined;\n\n constructor(readonly source: string | Blob) {}\n\n /** `length` bytes from `offset` */\n private async range(offset: number, length: number, signal?: AbortSignal): Promise<Uint8Array<ArrayBuffer>> {\n if (typeof this.source !== 'string') {\n return new Uint8Array(await this.source.slice(offset, offset + length).arrayBuffer());\n }\n if (this.whole) return (await this.whole).subarray(offset, offset + length);\n\n const response = await fetch(\n this.source,\n withHeaders(this.source, {\n headers: { Range: `bytes=${offset}-${offset + Math.max(length, 1) - 1}` },\n ...(signal ? { signal } : {}),\n }),\n );\n\n if (!response.ok) throw httpError(this.source, response.status);\n if (response.status === 206) return new Uint8Array(await response.arrayBuffer());\n\n // The whole file: kept, when small enough, for the next ranges\n const size = Number(response.headers.get('Content-Length'));\n\n if (size > WHOLE_FILE_MAX) {\n await response.body?.cancel();\n throw new Error(`isard: ${this.source}: the server ignores range requests (HTTP 206 expected)`);\n }\n\n const whole = response.arrayBuffer().then((b) => new Uint8Array(b));\n\n this.whole = whole;\n whole.catch(() => {\n this.whole = undefined;\n });\n\n return (await whole).subarray(offset, offset + length);\n }\n\n private load() {\n this.head ??= (async () => {\n const first = await this.range(0, FIRST);\n const header = parseHeader(first);\n const { rootDirectoryOffset: o, rootDirectoryLength: n } = header;\n const raw = o + n <= first.length ? first.subarray(o, o + n) : await this.range(o, n);\n const root = parseDirectory(await decompress(raw, header.internalCompression));\n\n return { header, root };\n })();\n // A failure is not kept: asked again next time\n this.head.catch(() => {\n this.head = undefined;\n });\n\n return this.head;\n }\n\n /** The archive's header */\n async header(): Promise<PmtilesHeader> {\n return (await this.load()).header;\n }\n\n /** The archive's JSON metadata (`vector_layers`, `attribution`, `name`…); `{}` if it has none */\n async metadata(): Promise<Record<string, unknown>> {\n const { header } = await this.load();\n\n if (header.metadataLength === 0) return {};\n\n const raw = await this.range(header.metadataOffset, header.metadataLength);\n const text = new TextDecoder().decode(await decompress(raw, header.internalCompression));\n const value: unknown = JSON.parse(text);\n\n return isRecord(value) ? value : {};\n }\n\n private leaf(header: PmtilesHeader, entry: PmtilesEntry): Promise<PmtilesEntry[]> {\n const offset = header.leafDirectoryOffset + entry.offset;\n const cached = this.leaves.get(offset);\n\n if (cached) return cached;\n\n const leaf = this.range(offset, entry.length).then(async (raw) =>\n parseDirectory(await decompress(raw, header.internalCompression)),\n );\n\n leaf.catch(() => this.leaves.delete(offset));\n this.leaves.set(offset, leaf);\n\n return leaf;\n }\n\n /** The bytes of tile z/x/y, decompressed (a vector tile ungzipped); undefined where the archive has none */\n async tile(z: number, x: number, y: number, signal?: AbortSignal): Promise<Uint8Array<ArrayBuffer> | undefined> {\n const { header, root } = await this.load();\n\n if (z < header.minZoom || z > header.maxZoom) return undefined;\n\n const id = zxyToTileId(z, x, y);\n let entries = root;\n\n // The root, then at most three levels of leaves\n for (let depth = 0; depth < 4; depth += 1) {\n const entry = findEntry(entries, id);\n\n if (!entry) return undefined;\n if (entry.runLength > 0) {\n const raw = await this.range(header.tileDataOffset + entry.offset, entry.length, signal);\n\n return decompress(raw, header.tileCompression);\n }\n entries = await this.leaf(header, entry);\n }\n throw new Error('isard: PMTiles directories nested too deep');\n }\n}\n\n/** The archives opened, by URL: one reader (and its directory cache) per archive in a page or worker */\nconst archives = new Lru<string, PMTiles>(16);\n\n/** The reader of an archive URL (without `pmtiles://`), shared */\nexport const pmtiles = (url: string): PMTiles => {\n const cached = archives.get(url);\n\n if (cached) return cached;\n\n const archive = new PMTiles(url);\n\n archives.set(url, archive);\n\n return archive;\n};\n\n/** The URL of the page (or of the worker); undefined out of a browser */\nconst pageUrl = (): string | undefined => {\n const location: unknown = Reflect.get(globalThis, 'location');\n\n return isRecord(location) && typeof location.href === 'string' ? location.href : undefined;\n};\n\n/** The archive URL of a `pmtiles://` URL, absolute (relative to the page), or undefined for another URL */\nexport const pmtilesUrl = (url: string, base?: string): string | undefined => {\n if (!url.startsWith('pmtiles://')) return undefined;\n\n const inner = url.slice('pmtiles://'.length);\n const from = base ?? pageUrl();\n\n try {\n return from ? new URL(inner, from).href : inner;\n } catch {\n return inner;\n }\n};\n\n/** A tile URL `pmtiles://<archive>/{z}/{x}/{y}` (with its numbers in) read from its archive: its bytes, undefined\n * where there is none; undefined too (`false`) for a URL that is not one */\nexport const pmtilesTile = (\n url: string,\n signal?: AbortSignal,\n): Promise<Uint8Array<ArrayBuffer> | undefined> | false => {\n const match = /^pmtiles:\\/\\/(.+)\\/(\\d+)\\/(\\d+)\\/(\\d+)$/.exec(url);\n\n if (!match) return false;\n\n const [, archive = '', z, x, y] = match;\n\n return pmtiles(archive).tile(Number(z), Number(x), Number(y), signal);\n};\n"]}
@@ -1,7 +1,6 @@
1
1
  /** PMTiles archives on the map (`GeoMap.addPmtiles`): their images as a raster layer, or their vector tiles drawn with
2
2
  * the style given or a plain one made from their layers' names */
3
- import type { Layer } from '../layers/layers.ts';
4
- import type { RasterOptions } from '../types.ts';
3
+ import type { Placement, RasterOptions } from '../types.ts';
5
4
  import type { Style } from './vectorstyle.ts';
6
5
  /**
7
6
  * A plain style for vector tiles known only by their layers' names (a PMTiles archive's `vector_layers`, an MBTiles'
@@ -16,7 +15,9 @@ export declare const basicStyle: (source: {
16
15
  maxzoom?: number;
17
16
  }, layers: readonly string[]) => Style;
18
17
  /** Options of `GeoMap.addPmtiles` */
19
- export interface PmtilesOptions {
18
+ export interface PmtilesOptions extends Placement {
19
+ /** The archive's URL (`pmtiles://` or not) */
20
+ url: string;
20
21
  /** What the archive holds (default from its header: raster images or vector tiles) */
21
22
  kind?: 'raster' | 'vector';
22
23
  /** A MapLibre style for vector tiles (its vector source `pmtiles://…`); default `basicStyle` of the archive's layers */
@@ -26,7 +27,6 @@ export interface PmtilesOptions {
26
27
  size?: number;
27
28
  /** Credits, HTML (default the archive's `attribution` metadata, as text) */
28
29
  attribution?: string;
29
- before?: Layer;
30
30
  }
31
31
  /** A raster loader reading the tiles of a `pmtiles://` archive URL (images of any size, drawn at `size`); undefined
32
32
  * for another URL */
@@ -45,7 +45,8 @@ const plainText = (html) => {
45
45
  };
46
46
  /** @internal `GeoMap.addPmtiles`: a raster layer of the archive's images, or vector tiles with their raster layer and
47
47
  * labels */
48
- export const pmtilesLayer = async (map, url, options) => {
48
+ export const pmtilesLayer = async (map, options) => {
49
+ const { url } = options;
49
50
  const archiveUrl = pmtilesUrl(url.startsWith('pmtiles://') ? url : `pmtiles://${url}`) ?? url;
50
51
  const archive = pmtiles(archiveUrl);
51
52
  const [header, metadata] = await Promise.all([
@@ -1 +1 @@
1
- {"version":3,"file":"pmtileslayer.js","sourceRoot":"","sources":["../../src/basemap/pmtileslayer.ts"],"names":[],"mappings":"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","sourcesContent":["/** PMTiles archives on the map (`GeoMap.addPmtiles`): their images as a raster layer, or their vector tiles drawn with\n * the style given or a plain one made from their layers' names */\n\nimport type { Layer, RasterLayer } from '../layers/layers.ts';\nimport type { GeoMap } from '../map.ts';\nimport type { RasterOptions } from '../types.ts';\nimport { isRecord } from '../util/guards.ts';\nimport { pmtiles, pmtilesUrl } from './pmtiles.ts';\nimport type { Style, StyleLayer } from './vectorstyle.ts';\nimport type { VectorTiles } from './vectortiles.ts';\n\n/** Colors of the layers of `basicStyle`, in turn */\nconst BASIC_COLORS = ['#2f6fd1', '#d1495b', '#2a9d8f', '#e9a03b', '#7b5ea7', '#5c7a29', '#c8553d', '#3d8eb9'];\n\n/**\n * A plain style for vector tiles known only by their layers' names (a PMTiles archive's `vector_layers`, an MBTiles'\n * metadata): each layer's polygons filled, its lines and outlines stroked and its points as circles, a color per\n * layer, the `name` of points as labels. `source` is the style's vector source (`url`: TileJSON or `pmtiles://…`, or\n * `tiles`)\n */\nexport const basicStyle = (\n source: { url?: string; tiles?: string[]; minzoom?: number; maxzoom?: number },\n layers: readonly string[],\n): Style => {\n const out: StyleLayer[] = [];\n\n layers.forEach((name, i) => {\n const color = BASIC_COLORS[i % BASIC_COLORS.length] ?? '#2f6fd1';\n const base = { source: 'data', 'source-layer': name };\n\n out.push(\n { id: `${name}-fill`, type: 'fill', ...base, paint: { 'fill-color': color, 'fill-opacity': 0.18 } },\n { id: `${name}-line`, type: 'line', ...base, paint: { 'line-color': color, 'line-width': 1.2 } },\n {\n id: `${name}-circle`,\n type: 'circle',\n ...base,\n paint: { 'circle-color': color, 'circle-radius': 3.5, 'circle-stroke-color': '#fff', 'circle-stroke-width': 1 },\n },\n );\n });\n layers.forEach((name) => {\n out.push({\n id: `${name}-label`,\n type: 'symbol',\n source: 'data',\n 'source-layer': name,\n filter: ['all', ['==', ['geometry-type'], 'Point'], ['has', 'name']],\n layout: { 'text-field': ['get', 'name'], 'text-size': 12, 'text-offset': [0, 0.9], 'text-anchor': 'top' },\n paint: { 'text-color': '#1d2433', 'text-halo-color': '#fff', 'text-halo-width': 1.5 },\n });\n });\n\n return { version: 8, sources: { data: { type: 'vector', ...source } }, layers: out };\n};\n\n/** Options of `GeoMap.addPmtiles` */\nexport interface PmtilesOptions {\n /** What the archive holds (default from its header: raster images or vector tiles) */\n kind?: 'raster' | 'vector';\n /** A MapLibre style for vector tiles (its vector source `pmtiles://…`); default `basicStyle` of the archive's layers */\n style?: Style;\n opacity?: number;\n /** Texture size of raster tiles (default 256; 512 for the sharper tiles of a 512 px archive) */\n size?: number;\n /** Credits, HTML (default the archive's `attribution` metadata, as text) */\n attribution?: string;\n before?: Layer;\n}\n\n/** HTML of a file reduced to its text, escaped: credits from an archive's metadata cannot run in the page */\nconst plainText = (html: string): string => {\n return html\n .replace(/<[^>]*>/g, '')\n .replace(/&(?!(amp|lt|gt|quot|copy|#\\d+);)/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n};\n\n/** @internal `GeoMap.addPmtiles`: a raster layer of the archive's images, or vector tiles with their raster layer and\n * labels */\nexport const pmtilesLayer = async (\n map: GeoMap,\n url: string,\n options: PmtilesOptions,\n): Promise<RasterLayer | VectorTiles> => {\n const archiveUrl = pmtilesUrl(url.startsWith('pmtiles://') ? url : `pmtiles://${url}`) ?? url;\n const archive = pmtiles(archiveUrl);\n const [header, metadata] = await Promise.all([\n archive.header(),\n archive.metadata().catch((): Record<string, unknown> => ({})),\n ]);\n const credit = metadata.attribution;\n const attribution = options.attribution ?? (typeof credit === 'string' && credit ? plainText(credit) : undefined);\n const kind = options.kind ?? (header.tileType === 'mvt' ? 'vector' : 'raster');\n const credits = attribution ? { attribution } : {};\n\n if (kind === 'raster') {\n return map.addRaster({\n url: `pmtiles://${archiveUrl}`,\n minZoom: header.minZoom,\n maxZoom: Math.max(header.maxZoom, 19),\n ...(options.opacity === undefined ? {} : { opacity: options.opacity }),\n ...(options.size === undefined ? {} : { size: options.size }),\n ...(options.before ? { before: options.before } : {}),\n ...credits,\n });\n }\n\n const layers = metadata.vector_layers;\n const names = Array.isArray(layers)\n ? layers.map((l) => (isRecord(l) ? l.id : undefined)).filter((id) => typeof id === 'string')\n : [];\n const style = options.style ?? basicStyle({ url: `pmtiles://${archiveUrl}` }, names);\n const tiles = map.vectorTiles({ style, ...credits });\n\n tiles.raster({\n ...(options.opacity === undefined ? {} : { opacity: options.opacity }),\n ...(options.before ? { before: options.before } : {}),\n });\n tiles.labels();\n\n return tiles;\n};\n\n/** A raster loader reading the tiles of a `pmtiles://` archive URL (images of any size, drawn at `size`); undefined\n * for another URL */\nexport const pmtilesRasterLoader = (url: string, size: number): RasterOptions['loader'] => {\n const archiveUrl = pmtilesUrl(url);\n\n if (!archiveUrl) return undefined;\n\n const archive = pmtiles(archiveUrl);\n\n return async (z, x, y, signal) => {\n const bytes = await archive.tile(z, x, y, signal);\n\n if (!bytes) return null;\n\n return createImageBitmap(new Blob([bytes]), { resizeWidth: size, resizeHeight: size });\n };\n};\n"]}
1
+ {"version":3,"file":"pmtileslayer.js","sourceRoot":"","sources":["../../src/basemap/pmtileslayer.ts"],"names":[],"mappings":"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","sourcesContent":["/** PMTiles archives on the map (`GeoMap.addPmtiles`): their images as a raster layer, or their vector tiles drawn with\n * the style given or a plain one made from their layers' names */\n\nimport type { RasterLayer } from '../layers/raster.ts';\nimport type { GeoMap } from '../map.ts';\nimport type { Placement, RasterOptions } from '../types.ts';\nimport { isRecord } from '../util/guards.ts';\nimport { pmtiles, pmtilesUrl } from './pmtiles.ts';\nimport type { Style, StyleLayer } from './vectorstyle.ts';\nimport type { VectorTiles } from './vectortiles.ts';\n\n/** Colors of the layers of `basicStyle`, in turn */\nconst BASIC_COLORS = ['#2f6fd1', '#d1495b', '#2a9d8f', '#e9a03b', '#7b5ea7', '#5c7a29', '#c8553d', '#3d8eb9'];\n\n/**\n * A plain style for vector tiles known only by their layers' names (a PMTiles archive's `vector_layers`, an MBTiles'\n * metadata): each layer's polygons filled, its lines and outlines stroked and its points as circles, a color per\n * layer, the `name` of points as labels. `source` is the style's vector source (`url`: TileJSON or `pmtiles://…`, or\n * `tiles`)\n */\nexport const basicStyle = (\n source: { url?: string; tiles?: string[]; minzoom?: number; maxzoom?: number },\n layers: readonly string[],\n): Style => {\n const out: StyleLayer[] = [];\n\n layers.forEach((name, i) => {\n const color = BASIC_COLORS[i % BASIC_COLORS.length] ?? '#2f6fd1';\n const base = { source: 'data', 'source-layer': name };\n\n out.push(\n { id: `${name}-fill`, type: 'fill', ...base, paint: { 'fill-color': color, 'fill-opacity': 0.18 } },\n { id: `${name}-line`, type: 'line', ...base, paint: { 'line-color': color, 'line-width': 1.2 } },\n {\n id: `${name}-circle`,\n type: 'circle',\n ...base,\n paint: { 'circle-color': color, 'circle-radius': 3.5, 'circle-stroke-color': '#fff', 'circle-stroke-width': 1 },\n },\n );\n });\n layers.forEach((name) => {\n out.push({\n id: `${name}-label`,\n type: 'symbol',\n source: 'data',\n 'source-layer': name,\n filter: ['all', ['==', ['geometry-type'], 'Point'], ['has', 'name']],\n layout: { 'text-field': ['get', 'name'], 'text-size': 12, 'text-offset': [0, 0.9], 'text-anchor': 'top' },\n paint: { 'text-color': '#1d2433', 'text-halo-color': '#fff', 'text-halo-width': 1.5 },\n });\n });\n\n return { version: 8, sources: { data: { type: 'vector', ...source } }, layers: out };\n};\n\n/** Options of `GeoMap.addPmtiles` */\nexport interface PmtilesOptions extends Placement {\n /** The archive's URL (`pmtiles://` or not) */\n url: string;\n /** What the archive holds (default from its header: raster images or vector tiles) */\n kind?: 'raster' | 'vector';\n /** A MapLibre style for vector tiles (its vector source `pmtiles://…`); default `basicStyle` of the archive's layers */\n style?: Style;\n opacity?: number;\n /** Texture size of raster tiles (default 256; 512 for the sharper tiles of a 512 px archive) */\n size?: number;\n /** Credits, HTML (default the archive's `attribution` metadata, as text) */\n attribution?: string;\n}\n\n/** HTML of a file reduced to its text, escaped: credits from an archive's metadata cannot run in the page */\nconst plainText = (html: string): string => {\n return html\n .replace(/<[^>]*>/g, '')\n .replace(/&(?!(amp|lt|gt|quot|copy|#\\d+);)/g, '&amp;')\n .replace(/</g, '&lt;')\n .replace(/>/g, '&gt;');\n};\n\n/** @internal `GeoMap.addPmtiles`: a raster layer of the archive's images, or vector tiles with their raster layer and\n * labels */\nexport const pmtilesLayer = async (map: GeoMap, options: PmtilesOptions): Promise<RasterLayer | VectorTiles> => {\n const { url } = options;\n const archiveUrl = pmtilesUrl(url.startsWith('pmtiles://') ? url : `pmtiles://${url}`) ?? url;\n const archive = pmtiles(archiveUrl);\n const [header, metadata] = await Promise.all([\n archive.header(),\n archive.metadata().catch((): Record<string, unknown> => ({})),\n ]);\n const credit = metadata.attribution;\n const attribution = options.attribution ?? (typeof credit === 'string' && credit ? plainText(credit) : undefined);\n const kind = options.kind ?? (header.tileType === 'mvt' ? 'vector' : 'raster');\n const credits = attribution ? { attribution } : {};\n\n if (kind === 'raster') {\n return map.addRaster({\n url: `pmtiles://${archiveUrl}`,\n minZoom: header.minZoom,\n maxZoom: Math.max(header.maxZoom, 19),\n ...(options.opacity === undefined ? {} : { opacity: options.opacity }),\n ...(options.size === undefined ? {} : { size: options.size }),\n ...(options.before ? { before: options.before } : {}),\n ...credits,\n });\n }\n\n const layers = metadata.vector_layers;\n const names = Array.isArray(layers)\n ? layers.map((l) => (isRecord(l) ? l.id : undefined)).filter((id) => typeof id === 'string')\n : [];\n const style = options.style ?? basicStyle({ url: `pmtiles://${archiveUrl}` }, names);\n const tiles = map.vectorTiles({ style, ...credits });\n\n tiles.raster({\n ...(options.opacity === undefined ? {} : { opacity: options.opacity }),\n ...(options.before ? { before: options.before } : {}),\n });\n tiles.labels();\n\n return tiles;\n};\n\n/** A raster loader reading the tiles of a `pmtiles://` archive URL (images of any size, drawn at `size`); undefined\n * for another URL */\nexport const pmtilesRasterLoader = (url: string, size: number): RasterOptions['loader'] => {\n const archiveUrl = pmtilesUrl(url);\n\n if (!archiveUrl) return undefined;\n\n const archive = pmtiles(archiveUrl);\n\n return async (z, x, y, signal) => {\n const bytes = await archive.tile(z, x, y, signal);\n\n if (!bytes) return null;\n\n return createImageBitmap(new Blob([bytes]), { resizeWidth: size, resizeHeight: size });\n };\n};\n"]}
@@ -7,8 +7,9 @@
7
7
  * interpolated within its cell (bilinear), its color between the four nearest source pixels (bilinear, alpha
8
8
  * premultiplied). This code knows no projection.
9
9
  */
10
- import { withHeaders } from "../engine/requests.js";
10
+ import { httpError } from "../util/fetch.js";
11
11
  import { Lru } from "../util/lru.js";
12
+ import { withHeaders } from "../util/requests.js";
12
13
  /** Source images kept decoded (by the page, or shared by the workers of a pool): the neighbours of a tile share them */
13
14
  export const SOURCE_CACHE = 96;
14
15
  /**
@@ -118,7 +119,7 @@ export const resampler = (cached = SOURCE_CACHE) => {
118
119
  if (response.status === 404 || response.status === 204 || response.status === 410)
119
120
  return null;
120
121
  if (!response.ok)
121
- throw new Error(`isard: ${response.status} for a raster to reproject`);
122
+ throw httpError(url, response.status);
122
123
  return createImageBitmap(await response.blob());
123
124
  })();
124
125
  // A failure is not kept: the engine's retry fetches again
@@ -1 +1 @@
1
- {"version":3,"file":"resample.js","sourceRoot":"","sources":["../../src/basemap/resample.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Raster reprojection, the drawing half: a Web Mercator tile drawn from the source images it spans (tiles of another\n * grid, or one image of a WMS), in a worker of the map (OffscreenCanvas) or in the page when the map has no workers.\n * The page plans each tile (`grid.ts`): which images, where they go in a mosaic, and a mesh of control points giving,\n * for the corners of 16 × 16 cells of the tile, the mosaic pixel under them. Here the images are fetched (kept for the\n * neighbouring tiles), drawn into the mosaic, and every pixel of the tile sampled from it, its source position\n * interpolated within its cell (bilinear), its color between the four nearest source pixels (bilinear, alpha\n * premultiplied). This code knows no projection.\n */\n\nimport { withHeaders } from '../engine/requests.ts';\nimport { Lru } from '../util/lru.ts';\n\n/** Source images kept decoded (by the page, or shared by the workers of a pool): the neighbours of a tile share them */\nexport const SOURCE_CACHE = 96;\n\n/** A source image and the rectangle of the mosaic it covers (pixels) */\nexport interface Placed {\n url: string;\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/** How to draw a Mercator tile of `size` pixels: the mosaic of the source images, and the mesh of `n` × `n` cells\n * ((n + 1)² points, rows from the north, x then y): the mosaic position of each corner, NaN where the source CRS has\n * none */\nexport interface Job {\n size: number;\n width: number;\n height: number;\n sources: Placed[];\n n: number;\n mesh: Float32Array;\n}\n\n/**\n * Samples the pixels of a `size` × `size` tile (RGBA, straight alpha) from a mosaic of `width` × `height` (RGBA,\n * straight alpha) through the mesh of a job. Pixels whose position falls outside the mosaic, or on a NaN, stay\n * transparent; the mosaic's edge fades over half a pixel\n */\nexport const resample = (\n source: Uint8ClampedArray,\n width: number,\n height: number,\n mesh: Float32Array,\n n: number,\n size: number,\n): Uint8ClampedArray<ArrayBuffer> => {\n const out = new Uint8ClampedArray(size * size * 4);\n const cell = size / n;\n const stride = n + 1;\n\n for (let row = 0; row < size; row += 1) {\n const fy = (row + 0.5) / cell;\n const j = Math.min(n - 1, Math.floor(fy));\n const ty = fy - j;\n\n for (let col = 0; col < size; col += 1) {\n const fx = (col + 0.5) / cell;\n const i = Math.min(n - 1, Math.floor(fx));\n const tx = fx - i;\n const a = 2 * (j * stride + i);\n const b = a + 2 * stride;\n // The corners of the cell, then the position in it\n const w00 = (1 - tx) * (1 - ty);\n const w10 = tx * (1 - ty);\n const w01 = (1 - tx) * ty;\n const w11 = tx * ty;\n const u =\n w00 * (mesh[a] as number) +\n w10 * (mesh[a + 2] as number) +\n w01 * (mesh[b] as number) +\n w11 * (mesh[b + 2] as number);\n const v =\n w00 * (mesh[a + 1] as number) +\n w10 * (mesh[a + 3] as number) +\n w01 * (mesh[b + 1] as number) +\n w11 * (mesh[b + 3] as number);\n // Pixel centers at half pixels: the four around (u, v)\n const sx = u - 0.5;\n const sy = v - 0.5;\n\n if (!(sx > -1 && sy > -1 && sx < width && sy < height)) continue;\n\n const x0 = Math.floor(sx);\n const y0 = Math.floor(sy);\n const kx = sx - x0;\n const ky = sy - y0;\n let r = 0;\n let g = 0;\n let bl = 0;\n let alpha = 0;\n\n for (let k = 0; k < 4; k += 1) {\n const x = x0 + (k & 1);\n const y = y0 + (k >> 1);\n\n if (x < 0 || y < 0 || x >= width || y >= height) continue;\n\n const p = 4 * (y * width + x);\n const wa = (k & 1 ? kx : 1 - kx) * (k >> 1 ? ky : 1 - ky) * (source[p + 3] as number);\n\n r += wa * (source[p] as number);\n g += wa * (source[p + 1] as number);\n bl += wa * (source[p + 2] as number);\n alpha += wa;\n }\n if (alpha <= 0) continue;\n\n const q = 4 * (row * size + col);\n\n out[q] = r / alpha;\n out[q + 1] = g / alpha;\n out[q + 2] = bl / alpha;\n out[q + 3] = alpha;\n }\n }\n\n return out;\n};\n\n/** Draws a planned tile: its image, null where the source has nothing; rejects on errors */\nexport type DrawJob = (job: Job, signal: AbortSignal) => Promise<ImageBitmap | null>;\n\n/**\n * Draws planned tiles, keeping `cached` source images decoded. A missing source image (404, 204, 410) leaves its part\n * empty; a tile with no source at all is missing; other errors reject (retried by the engine). In the page, or in a\n * worker of the map (`close` frees the images kept)\n */\nexport const resampler = (cached = SOURCE_CACHE): { draw: DrawJob; close: () => void; cache: { capacity: number } } => {\n type Image = Promise<ImageBitmap | null>;\n\n /** Tiles being drawn from each source image: an evicted one is closed once none is */\n const users = new Map<Image, number>();\n const evicted = new Set<Image>();\n const close = (image: Image) => {\n evicted.delete(image);\n image.then(\n (bitmap) => bitmap?.close(),\n () => undefined,\n );\n };\n /** Freed now, or once the tiles drawing from it are done */\n const drop = (image: Image) => {\n if (users.has(image)) evicted.add(image);\n else close(image);\n };\n // Source images by URL: a request is shared by the tiles that need it, its signal is not theirs\n const cache = new Lru<string, Image>(cached, drop);\n const release = (image: Image) => {\n const count = (users.get(image) ?? 1) - 1;\n\n if (count > 0) users.set(image, count);\n else {\n users.delete(image);\n if (evicted.has(image)) close(image);\n }\n };\n const fetchImage = (url: string): Image => {\n const load = (): Image => {\n const loading = (async () => {\n const response = await fetch(url, withHeaders(url));\n\n if (response.status === 404 || response.status === 204 || response.status === 410) return null;\n if (!response.ok) throw new Error(`isard: ${response.status} for a raster to reproject`);\n\n return createImageBitmap(await response.blob());\n })();\n\n // A failure is not kept: the engine's retry fetches again\n loading.catch(() => cache.delete(url));\n cache.set(url, loading);\n\n return loading;\n };\n const image = cache.get(url) ?? load();\n\n users.set(image, (users.get(image) ?? 0) + 1);\n\n return image;\n };\n const draw: DrawJob = async (job, signal) => {\n const pending = job.sources.map((s) => [s, fetchImage(s.url)] as const);\n\n try {\n const images = await Promise.all(pending.map(async ([s, image]) => [s, await image] as const));\n\n signal.throwIfAborted();\n if (!images.some(([, image]) => image)) return null;\n\n const canvas = new OffscreenCanvas(job.width, job.height);\n const context = canvas.getContext('2d', { willReadFrequently: true });\n\n if (!context) throw new Error('isard: no 2D canvas to reproject the tiles');\n images.forEach(([s, image]) => {\n if (image) context.drawImage(image, s.x, s.y, s.w, s.h);\n });\n\n const mosaic = context.getImageData(0, 0, job.width, job.height).data;\n const pixels = resample(mosaic, job.width, job.height, job.mesh, job.n, job.size);\n\n return createImageBitmap(new ImageData(pixels, job.size, job.size), { premultiplyAlpha: 'none' });\n } finally {\n pending.forEach(([, image]) => {\n release(image);\n });\n }\n };\n\n return {\n draw,\n cache,\n close: () => {\n [...cache.values()].forEach(drop);\n cache.clear();\n },\n };\n};\n"]}
1
+ {"version":3,"file":"resample.js","sourceRoot":"","sources":["../../src/basemap/resample.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Raster reprojection, the drawing half: a Web Mercator tile drawn from the source images it spans (tiles of another\n * grid, or one image of a WMS), in a worker of the map (OffscreenCanvas) or in the page when the map has no workers.\n * The page plans each tile (`grid.ts`): which images, where they go in a mosaic, and a mesh of control points giving,\n * for the corners of 16 × 16 cells of the tile, the mosaic pixel under them. Here the images are fetched (kept for the\n * neighbouring tiles), drawn into the mosaic, and every pixel of the tile sampled from it, its source position\n * interpolated within its cell (bilinear), its color between the four nearest source pixels (bilinear, alpha\n * premultiplied). This code knows no projection.\n */\n\nimport { httpError } from '../util/fetch.ts';\nimport { Lru } from '../util/lru.ts';\nimport { withHeaders } from '../util/requests.ts';\n\n/** Source images kept decoded (by the page, or shared by the workers of a pool): the neighbours of a tile share them */\nexport const SOURCE_CACHE = 96;\n\n/** A source image and the rectangle of the mosaic it covers (pixels) */\nexport interface Placed {\n url: string;\n x: number;\n y: number;\n w: number;\n h: number;\n}\n\n/** How to draw a Mercator tile of `size` pixels: the mosaic of the source images, and the mesh of `n` × `n` cells\n * ((n + 1)² points, rows from the north, x then y): the mosaic position of each corner, NaN where the source CRS has\n * none */\nexport interface Job {\n size: number;\n width: number;\n height: number;\n sources: Placed[];\n n: number;\n mesh: Float32Array;\n}\n\n/**\n * Samples the pixels of a `size` × `size` tile (RGBA, straight alpha) from a mosaic of `width` × `height` (RGBA,\n * straight alpha) through the mesh of a job. Pixels whose position falls outside the mosaic, or on a NaN, stay\n * transparent; the mosaic's edge fades over half a pixel\n */\nexport const resample = (\n source: Uint8ClampedArray,\n width: number,\n height: number,\n mesh: Float32Array,\n n: number,\n size: number,\n): Uint8ClampedArray<ArrayBuffer> => {\n const out = new Uint8ClampedArray(size * size * 4);\n const cell = size / n;\n const stride = n + 1;\n\n for (let row = 0; row < size; row += 1) {\n const fy = (row + 0.5) / cell;\n const j = Math.min(n - 1, Math.floor(fy));\n const ty = fy - j;\n\n for (let col = 0; col < size; col += 1) {\n const fx = (col + 0.5) / cell;\n const i = Math.min(n - 1, Math.floor(fx));\n const tx = fx - i;\n const a = 2 * (j * stride + i);\n const b = a + 2 * stride;\n // The corners of the cell, then the position in it\n const w00 = (1 - tx) * (1 - ty);\n const w10 = tx * (1 - ty);\n const w01 = (1 - tx) * ty;\n const w11 = tx * ty;\n const u =\n w00 * (mesh[a] as number) +\n w10 * (mesh[a + 2] as number) +\n w01 * (mesh[b] as number) +\n w11 * (mesh[b + 2] as number);\n const v =\n w00 * (mesh[a + 1] as number) +\n w10 * (mesh[a + 3] as number) +\n w01 * (mesh[b + 1] as number) +\n w11 * (mesh[b + 3] as number);\n // Pixel centers at half pixels: the four around (u, v)\n const sx = u - 0.5;\n const sy = v - 0.5;\n\n if (!(sx > -1 && sy > -1 && sx < width && sy < height)) continue;\n\n const x0 = Math.floor(sx);\n const y0 = Math.floor(sy);\n const kx = sx - x0;\n const ky = sy - y0;\n let r = 0;\n let g = 0;\n let bl = 0;\n let alpha = 0;\n\n for (let k = 0; k < 4; k += 1) {\n const x = x0 + (k & 1);\n const y = y0 + (k >> 1);\n\n if (x < 0 || y < 0 || x >= width || y >= height) continue;\n\n const p = 4 * (y * width + x);\n const wa = (k & 1 ? kx : 1 - kx) * (k >> 1 ? ky : 1 - ky) * (source[p + 3] as number);\n\n r += wa * (source[p] as number);\n g += wa * (source[p + 1] as number);\n bl += wa * (source[p + 2] as number);\n alpha += wa;\n }\n if (alpha <= 0) continue;\n\n const q = 4 * (row * size + col);\n\n out[q] = r / alpha;\n out[q + 1] = g / alpha;\n out[q + 2] = bl / alpha;\n out[q + 3] = alpha;\n }\n }\n\n return out;\n};\n\n/** Draws a planned tile: its image, null where the source has nothing; rejects on errors */\nexport type DrawJob = (job: Job, signal: AbortSignal) => Promise<ImageBitmap | null>;\n\n/**\n * Draws planned tiles, keeping `cached` source images decoded. A missing source image (404, 204, 410) leaves its part\n * empty; a tile with no source at all is missing; other errors reject (retried by the engine). In the page, or in a\n * worker of the map (`close` frees the images kept)\n */\nexport const resampler = (cached = SOURCE_CACHE): { draw: DrawJob; close: () => void; cache: { capacity: number } } => {\n type Image = Promise<ImageBitmap | null>;\n\n /** Tiles being drawn from each source image: an evicted one is closed once none is */\n const users = new Map<Image, number>();\n const evicted = new Set<Image>();\n const close = (image: Image) => {\n evicted.delete(image);\n image.then(\n (bitmap) => bitmap?.close(),\n () => undefined,\n );\n };\n /** Freed now, or once the tiles drawing from it are done */\n const drop = (image: Image) => {\n if (users.has(image)) evicted.add(image);\n else close(image);\n };\n // Source images by URL: a request is shared by the tiles that need it, its signal is not theirs\n const cache = new Lru<string, Image>(cached, drop);\n const release = (image: Image) => {\n const count = (users.get(image) ?? 1) - 1;\n\n if (count > 0) users.set(image, count);\n else {\n users.delete(image);\n if (evicted.has(image)) close(image);\n }\n };\n const fetchImage = (url: string): Image => {\n const load = (): Image => {\n const loading = (async () => {\n const response = await fetch(url, withHeaders(url));\n\n if (response.status === 404 || response.status === 204 || response.status === 410) return null;\n if (!response.ok) throw httpError(url, response.status);\n\n return createImageBitmap(await response.blob());\n })();\n\n // A failure is not kept: the engine's retry fetches again\n loading.catch(() => cache.delete(url));\n cache.set(url, loading);\n\n return loading;\n };\n const image = cache.get(url) ?? load();\n\n users.set(image, (users.get(image) ?? 0) + 1);\n\n return image;\n };\n const draw: DrawJob = async (job, signal) => {\n const pending = job.sources.map((s) => [s, fetchImage(s.url)] as const);\n\n try {\n const images = await Promise.all(pending.map(async ([s, image]) => [s, await image] as const));\n\n signal.throwIfAborted();\n if (!images.some(([, image]) => image)) return null;\n\n const canvas = new OffscreenCanvas(job.width, job.height);\n const context = canvas.getContext('2d', { willReadFrequently: true });\n\n if (!context) throw new Error('isard: no 2D canvas to reproject the tiles');\n images.forEach(([s, image]) => {\n if (image) context.drawImage(image, s.x, s.y, s.w, s.h);\n });\n\n const mosaic = context.getImageData(0, 0, job.width, job.height).data;\n const pixels = resample(mosaic, job.width, job.height, job.mesh, job.n, job.size);\n\n return createImageBitmap(new ImageData(pixels, job.size, job.size), { premultiplyAlpha: 'none' });\n } finally {\n pending.forEach(([, image]) => {\n release(image);\n });\n }\n };\n\n return {\n draw,\n cache,\n close: () => {\n [...cache.values()].forEach(drop);\n cache.clear();\n },\n };\n};\n"]}
@@ -1,3 +1,8 @@
1
+ /**
2
+ * Altitudes encoded in the colors of PNG tiles, for the relief: Terrarium (Mapzen, the Terrain Tiles of AWS) and
3
+ * Terrain-RGB (Mapbox, MapTiler). The engine reads raw floats only; a loader gives it the altitudes of each tile,
4
+ * decoded in a worker of the map's pool (OffscreenCanvas), or in the page when the map has no workers.
5
+ */
1
6
  /** The encodings of altitudes in the colors of PNG tiles */
2
7
  export type PngEncoding = 'terrarium' | 'mapbox';
3
8
  /** Altitudes (metres, rows from the north) of RGBA pixels in an encoding; below `floor` raised to it */
@@ -3,7 +3,9 @@
3
3
  * Terrain-RGB (Mapbox, MapTiler). The engine reads raw floats only; a loader gives it the altitudes of each tile,
4
4
  * decoded in a worker of the map's pool (OffscreenCanvas), or in the page when the map has no workers.
5
5
  */
6
- import { withHeaders } from "../engine/requests.js";
6
+ import { httpError } from "../util/fetch.js";
7
+ import { tileUrl } from "../util/geo.js";
8
+ import { withHeaders } from "../util/requests.js";
7
9
  const SIZE = 256;
8
10
  /** Altitudes (metres, rows from the north) of RGBA pixels in an encoding; below `floor` raised to it */
9
11
  export const decodeHeights = (rgba, encoding, floor = Number.NEGATIVE_INFINITY) => {
@@ -33,7 +35,7 @@ export const fetchHeights = async (url, encoding, floor, signal, surface) => {
33
35
  if (response.status === 404 || response.status === 204 || response.status === 410)
34
36
  return null;
35
37
  if (!response.ok)
36
- throw new Error(`${response.url}: ${response.status}`);
38
+ throw httpError(url, response.status);
37
39
  // The colors as stored: no color management, no premultiplied alpha
38
40
  const bitmap = await createImageBitmap(await response.blob(), {
39
41
  premultiplyAlpha: 'none',
@@ -43,7 +45,7 @@ export const fetchHeights = async (url, encoding, floor, signal, surface) => {
43
45
  surface.canvas ??= new OffscreenCanvas(SIZE, SIZE);
44
46
  const g = surface.canvas.getContext('2d', { willReadFrequently: true });
45
47
  if (!g)
46
- throw new Error('no 2D context');
48
+ throw new Error('isard: no 2D context');
47
49
  // Another size is resampled to the nearest pixel: an interpolated color is no altitude
48
50
  g.imageSmoothingEnabled = false;
49
51
  g.clearRect(0, 0, SIZE, SIZE);
@@ -62,7 +64,7 @@ export const fetchHeights = async (url, encoding, floor, signal, surface) => {
62
64
  export const encodedTerrainLoader = (url, encoding, floor, remote) => {
63
65
  const surface = {};
64
66
  return (z, x, y, signal) => {
65
- const tile = url.replaceAll('{z}', String(z)).replaceAll('{x}', String(x)).replaceAll('{y}', String(y));
67
+ const tile = tileUrl(url, z, x, y);
66
68
  return remote?.(tile, encoding, floor, [z, x, y], signal) ?? fetchHeights(tile, encoding, floor, signal, surface);
67
69
  };
68
70
  };
@@ -1 +1 @@
1
- {"version":3,"file":"terrain.js","sourceRoot":"","sources":["../../src/basemap/terrain.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Altitudes encoded in the colors of PNG tiles, for the relief: Terrarium (Mapzen, the Terrain Tiles of AWS) and\n * Terrain-RGB (Mapbox, MapTiler). The engine reads raw floats only; a loader gives it the altitudes of each tile,\n * decoded in a worker of the map's pool (OffscreenCanvas), or in the page when the map has no workers.\n */\nimport { withHeaders } from '../engine/requests.ts';\n\n/** The encodings of altitudes in the colors of PNG tiles */\nexport type PngEncoding = 'terrarium' | 'mapbox';\n\nconst SIZE = 256;\n\n/** Altitudes (metres, rows from the north) of RGBA pixels in an encoding; below `floor` raised to it */\nexport const decodeHeights = (\n rgba: Uint8ClampedArray | Uint8Array,\n encoding: PngEncoding,\n floor = Number.NEGATIVE_INFINITY,\n): Float32Array => {\n const n = rgba.length >> 2;\n const out = new Float32Array(n);\n\n // A loop per encoding, without allocations: 65 536 pixels a tile\n if (encoding === 'terrarium') {\n for (let i = 0, j = 0; i < n; i += 1, j += 4) {\n const h = (rgba[j] as number) * 256 + (rgba[j + 1] as number) + (rgba[j + 2] as number) / 256 - 32768;\n\n out[i] = h > floor ? h : floor;\n }\n } else {\n for (let i = 0, j = 0; i < n; i += 1, j += 4) {\n const h = -10000 + ((rgba[j] as number) * 65536 + (rgba[j + 1] as number) * 256 + (rgba[j + 2] as number)) * 0.1;\n\n out[i] = h > floor ? h : floor;\n }\n }\n\n return out;\n};\n\n/** Where the tiles are drawn and read back, made on first use and kept (each tile drawn and read at once) */\nexport interface Surface {\n canvas?: OffscreenCanvas;\n}\n\n/**\n * The altitudes of the PNG tile at `url`: 256 × 256, null where the server has no tile; a network or server error\n * rejects (the engine retries). Where it runs: in a worker of the map, or in the page without workers\n */\nexport const fetchHeights = async (\n url: string,\n encoding: PngEncoding,\n floor: number | undefined,\n signal: AbortSignal,\n surface: Surface,\n): Promise<Float32Array | null> => {\n const response = await fetch(url, withHeaders(url, { signal }));\n\n if (response.status === 404 || response.status === 204 || response.status === 410) return null;\n if (!response.ok) throw new Error(`${response.url}: ${response.status}`);\n\n // The colors as stored: no color management, no premultiplied alpha\n const bitmap = await createImageBitmap(await response.blob(), {\n premultiplyAlpha: 'none',\n colorSpaceConversion: 'none',\n });\n\n try {\n surface.canvas ??= new OffscreenCanvas(SIZE, SIZE);\n\n const g = surface.canvas.getContext('2d', { willReadFrequently: true });\n\n if (!g) throw new Error('no 2D context');\n // Another size is resampled to the nearest pixel: an interpolated color is no altitude\n g.imageSmoothingEnabled = false;\n g.clearRect(0, 0, SIZE, SIZE);\n g.drawImage(bitmap, 0, 0, SIZE, SIZE);\n\n return decodeHeights(g.getImageData(0, 0, SIZE, SIZE).data, encoding, floor);\n } finally {\n bitmap.close();\n }\n};\n\n/** `fetchHeights` run in a worker for tile `z`/`x`/`y`; undefined when the map has no workers (run in the page) */\nexport type RemoteHeights = (\n url: string,\n encoding: PngEncoding,\n floor: number | undefined,\n tile: [z: number, x: number, y: number],\n signal: AbortSignal,\n) => Promise<Float32Array | null> | undefined;\n\n/**\n * A loader of the engine's relief for PNG tiles of `url` ({z}, {x}, {y}) in an encoding: 256 × 256 altitudes, null\n * where the server has no tile; a network or server error rejects (retried). `floor`: the lowest altitude kept (the\n * sea floor of a worldwide model flattened at sea level). `remote`: decodes in a worker when it can\n */\nexport const encodedTerrainLoader = (\n url: string,\n encoding: PngEncoding,\n floor?: number,\n remote?: RemoteHeights,\n): ((z: number, x: number, y: number, signal: AbortSignal) => Promise<Float32Array | null>) => {\n const surface: Surface = {};\n\n return (z, x, y, signal) => {\n const tile = url.replaceAll('{z}', String(z)).replaceAll('{x}', String(x)).replaceAll('{y}', String(y));\n\n return remote?.(tile, encoding, floor, [z, x, y], signal) ?? fetchHeights(tile, encoding, floor, signal, surface);\n };\n};\n"]}
1
+ {"version":3,"file":"terrain.js","sourceRoot":"","sources":["../../src/basemap/terrain.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Altitudes encoded in the colors of PNG tiles, for the relief: Terrarium (Mapzen, the Terrain Tiles of AWS) and\n * Terrain-RGB (Mapbox, MapTiler). The engine reads raw floats only; a loader gives it the altitudes of each tile,\n * decoded in a worker of the map's pool (OffscreenCanvas), or in the page when the map has no workers.\n */\n\nimport { httpError } from '../util/fetch.ts';\nimport { tileUrl } from '../util/geo.ts';\nimport { withHeaders } from '../util/requests.ts';\n\n/** The encodings of altitudes in the colors of PNG tiles */\nexport type PngEncoding = 'terrarium' | 'mapbox';\n\nconst SIZE = 256;\n\n/** Altitudes (metres, rows from the north) of RGBA pixels in an encoding; below `floor` raised to it */\nexport const decodeHeights = (\n rgba: Uint8ClampedArray | Uint8Array,\n encoding: PngEncoding,\n floor = Number.NEGATIVE_INFINITY,\n): Float32Array => {\n const n = rgba.length >> 2;\n const out = new Float32Array(n);\n\n // A loop per encoding, without allocations: 65 536 pixels a tile\n if (encoding === 'terrarium') {\n for (let i = 0, j = 0; i < n; i += 1, j += 4) {\n const h = (rgba[j] as number) * 256 + (rgba[j + 1] as number) + (rgba[j + 2] as number) / 256 - 32768;\n\n out[i] = h > floor ? h : floor;\n }\n } else {\n for (let i = 0, j = 0; i < n; i += 1, j += 4) {\n const h = -10000 + ((rgba[j] as number) * 65536 + (rgba[j + 1] as number) * 256 + (rgba[j + 2] as number)) * 0.1;\n\n out[i] = h > floor ? h : floor;\n }\n }\n\n return out;\n};\n\n/** Where the tiles are drawn and read back, made on first use and kept (each tile drawn and read at once) */\nexport interface Surface {\n canvas?: OffscreenCanvas;\n}\n\n/**\n * The altitudes of the PNG tile at `url`: 256 × 256, null where the server has no tile; a network or server error\n * rejects (the engine retries). Where it runs: in a worker of the map, or in the page without workers\n */\nexport const fetchHeights = async (\n url: string,\n encoding: PngEncoding,\n floor: number | undefined,\n signal: AbortSignal,\n surface: Surface,\n): Promise<Float32Array | null> => {\n const response = await fetch(url, withHeaders(url, { signal }));\n\n if (response.status === 404 || response.status === 204 || response.status === 410) return null;\n if (!response.ok) throw httpError(url, response.status);\n\n // The colors as stored: no color management, no premultiplied alpha\n const bitmap = await createImageBitmap(await response.blob(), {\n premultiplyAlpha: 'none',\n colorSpaceConversion: 'none',\n });\n\n try {\n surface.canvas ??= new OffscreenCanvas(SIZE, SIZE);\n\n const g = surface.canvas.getContext('2d', { willReadFrequently: true });\n\n if (!g) throw new Error('isard: no 2D context');\n // Another size is resampled to the nearest pixel: an interpolated color is no altitude\n g.imageSmoothingEnabled = false;\n g.clearRect(0, 0, SIZE, SIZE);\n g.drawImage(bitmap, 0, 0, SIZE, SIZE);\n\n return decodeHeights(g.getImageData(0, 0, SIZE, SIZE).data, encoding, floor);\n } finally {\n bitmap.close();\n }\n};\n\n/** `fetchHeights` run in a worker for tile `z`/`x`/`y`; undefined when the map has no workers (run in the page) */\nexport type RemoteHeights = (\n url: string,\n encoding: PngEncoding,\n floor: number | undefined,\n tile: [z: number, x: number, y: number],\n signal: AbortSignal,\n) => Promise<Float32Array | null> | undefined;\n\n/**\n * A loader of the engine's relief for PNG tiles of `url` ({z}, {x}, {y}) in an encoding: 256 × 256 altitudes, null\n * where the server has no tile; a network or server error rejects (retried). `floor`: the lowest altitude kept (the\n * sea floor of a worldwide model flattened at sea level). `remote`: decodes in a worker when it can\n */\nexport const encodedTerrainLoader = (\n url: string,\n encoding: PngEncoding,\n floor?: number,\n remote?: RemoteHeights,\n): ((z: number, x: number, y: number, signal: AbortSignal) => Promise<Float32Array | null>) => {\n const surface: Surface = {};\n\n return (z, x, y, signal) => {\n const tile = tileUrl(url, z, x, y);\n\n return remote?.(tile, encoding, floor, [z, x, y], signal) ?? fetchHeights(tile, encoding, floor, signal, surface);\n };\n};\n"]}
@@ -3,9 +3,10 @@
3
3
  * the instance for its layers only, its own fields staying private.
4
4
  */
5
5
  import type { LoadedSprite } from '../../layers/icons.ts';
6
- import type { Layer, RasterLayer } from '../../layers/layers.ts';
6
+ import type { Layer } from '../../layers/layers.ts';
7
+ import type { RasterLayer } from '../../layers/raster.ts';
7
8
  import type { GeoMap } from '../../map.ts';
8
- import type { BasemapResponse, BasemapWork } from '../../workers/basemap.worker.ts';
9
+ import type { BasemapResponse, BasemapWork } from '../../workers/basemap/protocol.ts';
9
10
  import type { Style, StyleLayer } from '../vectorstyle.ts';
10
11
  import type { BasemapWorkers } from '../workerpool.ts';
11
12
  import type { TileRequests } from './requests.ts';
@@ -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 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
+ {"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 } from '../../layers/layers.ts';\nimport type { RasterLayer } from '../../layers/raster.ts';\nimport type { GeoMap } from '../../map.ts';\nimport type { BasemapResponse, BasemapWork } from '../../workers/basemap/protocol.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 +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 { 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"]}
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/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 { 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"]}
@@ -1,10 +1,11 @@
1
1
  /** The street furniture of a vector basemap (`VectorTiles.furniture`): 3D models placed by the workers from its
2
2
  * points of interest of the street (bus shelters, waste baskets, post boxes, drinking fountains, bicycle racks), each
3
3
  * facing its street, and benches along the pedestrian streets and the parks' paths */
4
- import type { Layer, ModelLayer } from '../../layers/layers.ts';
4
+ import type { ModelLayer } from '../../layers/models.ts';
5
+ import type { Placement } from '../../types.ts';
5
6
  import type { VectorTilesContext } from './context.ts';
6
7
  /** The options of `VectorTiles.furniture` */
7
- export interface FurnitureOptions {
8
+ export interface FurnitureOptions extends Placement {
8
9
  /** From this zoom on (default 16.5) */
9
10
  minZoom?: number;
10
11
  maxTiles?: number;
@@ -12,7 +13,6 @@ export interface FurnitureOptions {
12
13
  maxObjects?: number;
13
14
  /** Pieces drawn at most (default 12000) */
14
15
  maxInstances?: number;
15
- before?: Layer;
16
16
  }
17
17
  /** The layers of the street furniture, a kind each (`FURNITURE`'s order: shelters, bins, post boxes, fountains, racks,
18
18
  * benches): the first holds the others (`Layer.companions`) */
@@ -1,7 +1,8 @@
1
1
  /** The street furniture of a vector basemap (`VectorTiles.furniture`): 3D models placed by the workers from its
2
2
  * points of interest of the street (bus shelters, waste baskets, post boxes, drinking fountains, bicycle racks), each
3
3
  * facing its street, and benches along the pedestrian streets and the parks' paths */
4
- import { FURNITURE, FURNITURE_MODELS } from "../furniture.js";
4
+ import { FURNITURE_MODELS } from "../models/furniture.js";
5
+ import { FURNITURE } from "../placed.js";
5
6
  import { placed } from "./placed.js";
6
7
  /** Metres around the ground under the camera where every piece is drawn at zoom 17 (twice as far a zoom level out);
7
8
  * past them, fewer and fewer */
@@ -1 +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"]}
1
+ {"version":3,"file":"furniture.js","sourceRoot":"","sources":["../../../src/basemap/vectortiles/furniture.ts"],"names":[],"mappings":"AAAA;;sFAEsF;AAItF,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC;gCACgC;AAChC,MAAM,qBAAqB,GAAG,GAAG,CAAC;AAalC;+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 { ModelLayer } from '../../layers/models.ts';\nimport type { Placement } from '../../types.ts';\nimport { FURNITURE_MODELS } from '../models/furniture.ts';\nimport { FURNITURE } from '../placed.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 extends Placement {\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}\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"]}
@@ -6,6 +6,7 @@ import { ExtrusionLayer } from "../../layers/extrusions.js";
6
6
  import { VectorLayer } from "../../layers/vectors.js";
7
7
  import { isRecord } from "../../util/guards.js";
8
8
  import { Lru } from "../../util/lru.js";
9
+ import { clamp } from "../../util/math.js";
9
10
  import { styleFonts } from "./style.js";
10
11
  import { MAX_TILES, nearPriority, parseTileKey, tileKey, tilesAround, tileTriples } from "./tiles.js";
11
12
  /** Pause before the labels of tiles that failed are asked for again, when no move brings an update (ms) */
@@ -160,7 +161,7 @@ export const labels = (context, options = {}) => {
160
161
  }
161
162
  const run = ++generation;
162
163
  const camera = map.getCamera();
163
- const zoom = Math.max(0, Math.min(Math.floor(camera.zoom), 24));
164
+ const zoom = clamp(Math.floor(camera.zoom), 0, 24);
164
165
  const ground = context.ground();
165
166
  const groundTiles = ground && map.hasLayer(ground) ? tileTriples(map.engine.wantedTiles(ground.id)) : [];
166
167
  const keys = [];