isard 1.0.0 → 1.2.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 (268) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/dist/{basemaps.d.ts → basemap/basemaps.d.ts} +3 -3
  3. package/dist/{basemaps.js → basemap/basemaps.js} +3 -3
  4. package/dist/basemap/basemaps.js.map +1 -0
  5. package/dist/{grid.d.ts → basemap/grid.d.ts} +6 -6
  6. package/dist/{grid.js → basemap/grid.js} +61 -67
  7. package/dist/basemap/grid.js.map +1 -0
  8. package/dist/{mvt.d.ts → basemap/mvt.d.ts} +1 -1
  9. package/dist/{mvt.js → basemap/mvt.js} +6 -6
  10. package/dist/basemap/mvt.js.map +1 -0
  11. package/dist/{pmtiles.d.ts → basemap/pmtiles.d.ts} +16 -10
  12. package/dist/{pmtiles.js → basemap/pmtiles.js} +41 -33
  13. package/dist/basemap/pmtiles.js.map +1 -0
  14. package/dist/{resample.d.ts → basemap/resample.d.ts} +11 -2
  15. package/dist/{resample.js → basemap/resample.js} +18 -16
  16. package/dist/basemap/resample.js.map +1 -0
  17. package/dist/{terrain.d.ts → basemap/terrain.d.ts} +3 -3
  18. package/dist/{terrain.js → basemap/terrain.js} +7 -7
  19. package/dist/basemap/terrain.js.map +1 -0
  20. package/dist/{vectorstyle.d.ts → basemap/vectorstyle.d.ts} +12 -10
  21. package/dist/{vectorstyle.js → basemap/vectorstyle.js} +129 -111
  22. package/dist/basemap/vectorstyle.js.map +1 -0
  23. package/dist/{vectortiles.d.ts → basemap/vectortiles.d.ts} +18 -18
  24. package/dist/{vectortiles.js → basemap/vectortiles.js} +157 -109
  25. package/dist/basemap/vectortiles.js.map +1 -0
  26. package/dist/{wmts.d.ts → basemap/wmts.d.ts} +3 -3
  27. package/dist/{wmts.js → basemap/wmts.js} +19 -14
  28. package/dist/basemap/wmts.js.map +1 -0
  29. package/dist/basemap.worker.js +2 -2
  30. package/dist/basemap.worker.js.map +14 -13
  31. package/dist/bind/layers.d.ts +46 -0
  32. package/dist/bind/layers.js +154 -0
  33. package/dist/bind/layers.js.map +1 -0
  34. package/dist/{crs.d.ts → data/crs.d.ts} +11 -11
  35. package/dist/{crs.js → data/crs.js} +38 -34
  36. package/dist/data/crs.js.map +1 -0
  37. package/dist/{gpx.d.ts → data/gpx.d.ts} +2 -2
  38. package/dist/{gpx.js → data/gpx.js} +20 -20
  39. package/dist/data/gpx.js.map +1 -0
  40. package/dist/{kml.d.ts → data/kml.d.ts} +2 -2
  41. package/dist/{kml.js → data/kml.js} +42 -39
  42. package/dist/data/kml.js.map +1 -0
  43. package/dist/{topojson.d.ts → data/topojson.d.ts} +2 -2
  44. package/dist/{topojson.js → data/topojson.js} +15 -10
  45. package/dist/data/topojson.js.map +1 -0
  46. package/dist/{xml.d.ts → data/xml.d.ts} +5 -5
  47. package/dist/{xml.js → data/xml.js} +19 -18
  48. package/dist/data/xml.js.map +1 -0
  49. package/dist/decoder.worker.js +4 -4
  50. package/dist/decoder.worker.js.map +7 -7
  51. package/dist/{decoders.d.ts → engine/decoders.d.ts} +3 -3
  52. package/dist/{decoders.js → engine/decoders.js} +28 -25
  53. package/dist/engine/decoders.js.map +1 -0
  54. package/dist/{loader.d.ts → engine/loader.d.ts} +1 -1
  55. package/dist/{loader.js → engine/loader.js} +17 -14
  56. package/dist/engine/loader.js.map +1 -0
  57. package/dist/{protocol.d.ts → engine/protocol.d.ts} +1 -1
  58. package/dist/engine/protocol.js +3 -0
  59. package/dist/engine/protocol.js.map +1 -0
  60. package/dist/{requests.d.ts → engine/requests.d.ts} +1 -1
  61. package/dist/{requests.js → engine/requests.js} +19 -16
  62. package/dist/engine/requests.js.map +1 -0
  63. package/dist/engine-loader.d.ts +13 -9
  64. package/dist/engine-loader.js +30 -30
  65. package/dist/engine-loader.js.map +1 -1
  66. package/dist/formats.d.ts +3 -3
  67. package/dist/formats.js +3 -3
  68. package/dist/formats.js.map +1 -1
  69. package/dist/geoplateforme.d.ts +13 -13
  70. package/dist/geoplateforme.js +23 -21
  71. package/dist/geoplateforme.js.map +1 -1
  72. package/dist/index.d.ts +30 -29
  73. package/dist/index.js +18 -18
  74. package/dist/index.js.map +1 -1
  75. package/dist/isard_bg.wasm +0 -0
  76. package/dist/isard_core_bg.wasm +0 -0
  77. package/dist/isard_points_bg.wasm +0 -0
  78. package/dist/{extrusions.d.ts → layers/extrusions.d.ts} +1 -1
  79. package/dist/{extrusions.js → layers/extrusions.js} +10 -5
  80. package/dist/layers/extrusions.js.map +1 -0
  81. package/dist/{features.d.ts → layers/features.d.ts} +10 -10
  82. package/dist/{features.js → layers/features.js} +44 -45
  83. package/dist/layers/features.js.map +1 -0
  84. package/dist/{glyphs.d.ts → layers/glyphs.d.ts} +6 -6
  85. package/dist/{glyphs.js → layers/glyphs.js} +45 -41
  86. package/dist/layers/glyphs.js.map +1 -0
  87. package/dist/{icons.d.ts → layers/icons.d.ts} +10 -10
  88. package/dist/{icons.js → layers/icons.js} +84 -69
  89. package/dist/layers/icons.js.map +1 -0
  90. package/dist/{layers.d.ts → layers/layers.d.ts} +9 -4
  91. package/dist/{layers.js → layers/layers.js} +35 -31
  92. package/dist/layers/layers.js.map +1 -0
  93. package/dist/{panoramas.d.ts → layers/panoramas.d.ts} +3 -3
  94. package/dist/{panoramas.js → layers/panoramas.js} +54 -43
  95. package/dist/layers/panoramas.js.map +1 -0
  96. package/dist/{pointclouds.d.ts → layers/pointclouds.d.ts} +5 -5
  97. package/dist/{pointclouds.js → layers/pointclouds.js} +26 -34
  98. package/dist/layers/pointclouds.js.map +1 -0
  99. package/dist/{symbols.d.ts → layers/symbols.d.ts} +3 -3
  100. package/dist/{symbols.js → layers/symbols.js} +69 -72
  101. package/dist/layers/symbols.js.map +1 -0
  102. package/dist/map/basemap-layers.d.ts +26 -0
  103. package/dist/map/basemap-layers.js +61 -0
  104. package/dist/map/basemap-layers.js.map +1 -0
  105. package/dist/map/canvas.d.ts +17 -0
  106. package/dist/map/canvas.js +56 -0
  107. package/dist/map/canvas.js.map +1 -0
  108. package/dist/map/checks.d.ts +11 -0
  109. package/dist/map/checks.js +39 -0
  110. package/dist/map/checks.js.map +1 -0
  111. package/dist/map/credits.d.ts +17 -0
  112. package/dist/map/credits.js +34 -0
  113. package/dist/map/credits.js.map +1 -0
  114. package/dist/map/engine-settings.d.ts +15 -0
  115. package/dist/map/engine-settings.js +45 -0
  116. package/dist/map/engine-settings.js.map +1 -0
  117. package/dist/map/engines.d.ts +41 -0
  118. package/dist/map/engines.js +77 -0
  119. package/dist/map/engines.js.map +1 -0
  120. package/dist/map/events.d.ts +14 -0
  121. package/dist/map/events.js +46 -0
  122. package/dist/map/events.js.map +1 -0
  123. package/dist/map/frame-loop.d.ts +61 -0
  124. package/dist/map/frame-loop.js +139 -0
  125. package/dist/map/frame-loop.js.map +1 -0
  126. package/dist/map/hover-pick.d.ts +30 -0
  127. package/dist/map/hover-pick.js +56 -0
  128. package/dist/map/hover-pick.js.map +1 -0
  129. package/dist/map/layer-spec.d.ts +42 -0
  130. package/dist/map/layer-spec.js +34 -0
  131. package/dist/map/layer-spec.js.map +1 -0
  132. package/dist/map/layer-stack.d.ts +36 -0
  133. package/dist/map/layer-stack.js +101 -0
  134. package/dist/map/layer-stack.js.map +1 -0
  135. package/dist/map/overlay-host.d.ts +36 -0
  136. package/dist/map/overlay-host.js +101 -0
  137. package/dist/map/overlay-host.js.map +1 -0
  138. package/dist/map/panorama-host.d.ts +5 -0
  139. package/dist/map/panorama-host.js +32 -0
  140. package/dist/map/panorama-host.js.map +1 -0
  141. package/dist/map/raster-source.d.ts +11 -0
  142. package/dist/map/raster-source.js +26 -0
  143. package/dist/map/raster-source.js.map +1 -0
  144. package/dist/map/symbol-atlases.d.ts +26 -0
  145. package/dist/map/symbol-atlases.js +59 -0
  146. package/dist/map/symbol-atlases.js.map +1 -0
  147. package/dist/map/viewshed.d.ts +5 -0
  148. package/dist/map/viewshed.js +28 -0
  149. package/dist/map/viewshed.js.map +1 -0
  150. package/dist/map/workers.d.ts +46 -0
  151. package/dist/map/workers.js +73 -0
  152. package/dist/map/workers.js.map +1 -0
  153. package/dist/map.d.ts +46 -127
  154. package/dist/map.js +183 -698
  155. package/dist/map.js.map +1 -1
  156. package/dist/projections.d.ts +3 -3
  157. package/dist/projections.js +2 -2
  158. package/dist/projections.js.map +1 -1
  159. package/dist/react/Control.d.ts +11 -0
  160. package/dist/react/Control.js +18 -0
  161. package/dist/react/Control.js.map +1 -0
  162. package/dist/react/CustomLayer.d.ts +11 -0
  163. package/dist/react/CustomLayer.js +30 -0
  164. package/dist/react/CustomLayer.js.map +1 -0
  165. package/dist/react/IsardMap.d.ts +43 -0
  166. package/dist/react/IsardMap.js +146 -0
  167. package/dist/react/IsardMap.js.map +1 -0
  168. package/dist/react/Layer.d.ts +42 -0
  169. package/dist/react/Layer.js +74 -0
  170. package/dist/react/Layer.js.map +1 -0
  171. package/dist/react/Marker.d.ts +24 -0
  172. package/dist/react/Marker.js +53 -0
  173. package/dist/react/Marker.js.map +1 -0
  174. package/dist/react/Panel.d.ts +11 -0
  175. package/dist/react/Panel.js +37 -0
  176. package/dist/react/Panel.js.map +1 -0
  177. package/dist/react/Popup.d.ts +18 -0
  178. package/dist/react/Popup.js +60 -0
  179. package/dist/react/Popup.js.map +1 -0
  180. package/dist/react/Swipe.d.ts +9 -0
  181. package/dist/react/Swipe.js +41 -0
  182. package/dist/react/Swipe.js.map +1 -0
  183. package/dist/react/Viewshed.d.ts +5 -0
  184. package/dist/react/Viewshed.js +28 -0
  185. package/dist/react/Viewshed.js.map +1 -0
  186. package/dist/react/context.d.ts +32 -0
  187. package/dist/react/context.js +20 -0
  188. package/dist/react/context.js.map +1 -0
  189. package/dist/react/index.d.ts +26 -0
  190. package/dist/react/index.js +22 -0
  191. package/dist/react/index.js.map +1 -0
  192. package/dist/settings.d.ts +6 -10
  193. package/dist/settings.js +19 -17
  194. package/dist/settings.js.map +1 -1
  195. package/dist/types.d.ts +8 -8
  196. package/dist/types.js +1 -0
  197. package/dist/types.js.map +1 -1
  198. package/dist/{controls.d.ts → ui/controls.d.ts} +1 -1
  199. package/dist/{controls.js → ui/controls.js} +6 -4
  200. package/dist/ui/controls.js.map +1 -0
  201. package/dist/{interaction.d.ts → ui/interaction.d.ts} +9 -5
  202. package/dist/{interaction.js → ui/interaction.js} +9 -8
  203. package/dist/ui/interaction.js.map +1 -0
  204. package/dist/{overlay.d.ts → ui/overlay.d.ts} +2 -2
  205. package/dist/{overlay.js → ui/overlay.js} +18 -20
  206. package/dist/ui/overlay.js.map +1 -0
  207. package/dist/{style.d.ts → ui/style.d.ts} +1 -1
  208. package/dist/{style.js → ui/style.js} +2 -2
  209. package/dist/ui/style.js.map +1 -0
  210. package/dist/{animation.d.ts → util/animation.d.ts} +9 -5
  211. package/dist/{animation.js → util/animation.js} +6 -6
  212. package/dist/util/animation.js.map +1 -0
  213. package/dist/{color.d.ts → util/color.d.ts} +1 -1
  214. package/dist/{color.js → util/color.js} +14 -16
  215. package/dist/util/color.js.map +1 -0
  216. package/dist/{geo.d.ts → util/geo.d.ts} +6 -6
  217. package/dist/{geo.js → util/geo.js} +12 -12
  218. package/dist/util/geo.js.map +1 -0
  219. package/dist/util/guards.d.ts +7 -0
  220. package/dist/util/guards.js +8 -0
  221. package/dist/util/guards.js.map +1 -0
  222. package/dist/util/lru.js.map +1 -0
  223. package/dist/wasm/isard.d.ts +168 -0
  224. package/dist/wasm/isard.js +146 -0
  225. package/dist/wasm/isard_core.d.ts +144 -0
  226. package/dist/wasm/isard_core.js +122 -0
  227. package/dist/{basemap.worker.d.ts → workers/basemap.worker.d.ts} +17 -7
  228. package/dist/workers/basemap.worker.js +658 -0
  229. package/dist/workers/basemap.worker.js.map +1 -0
  230. package/package.json +24 -1
  231. package/vite.js +1 -1
  232. package/dist/animation.js.map +0 -1
  233. package/dist/basemaps.js.map +0 -1
  234. package/dist/color.js.map +0 -1
  235. package/dist/controls.js.map +0 -1
  236. package/dist/crs.js.map +0 -1
  237. package/dist/decoders.js.map +0 -1
  238. package/dist/extrusions.js.map +0 -1
  239. package/dist/features.js.map +0 -1
  240. package/dist/geo.js.map +0 -1
  241. package/dist/glyphs.js.map +0 -1
  242. package/dist/gpx.js.map +0 -1
  243. package/dist/grid.js.map +0 -1
  244. package/dist/icons.js.map +0 -1
  245. package/dist/interaction.js.map +0 -1
  246. package/dist/kml.js.map +0 -1
  247. package/dist/layers.js.map +0 -1
  248. package/dist/loader.js.map +0 -1
  249. package/dist/lru.js.map +0 -1
  250. package/dist/mvt.js.map +0 -1
  251. package/dist/overlay.js.map +0 -1
  252. package/dist/panoramas.js.map +0 -1
  253. package/dist/pmtiles.js.map +0 -1
  254. package/dist/pointclouds.js.map +0 -1
  255. package/dist/protocol.js +0 -2
  256. package/dist/protocol.js.map +0 -1
  257. package/dist/requests.js.map +0 -1
  258. package/dist/resample.js.map +0 -1
  259. package/dist/style.js.map +0 -1
  260. package/dist/symbols.js.map +0 -1
  261. package/dist/terrain.js.map +0 -1
  262. package/dist/topojson.js.map +0 -1
  263. package/dist/vectorstyle.js.map +0 -1
  264. package/dist/vectortiles.js.map +0 -1
  265. package/dist/wmts.js.map +0 -1
  266. package/dist/xml.js.map +0 -1
  267. /package/dist/{lru.d.ts → util/lru.d.ts} +0 -0
  268. /package/dist/{lru.js → util/lru.js} +0 -0
package/CHANGELOG.md CHANGED
@@ -3,6 +3,57 @@
3
3
  Every notable change of `isard` (published as `@ign-junn/isard` up to 0.1.1). The format follows [Keep a Changelog](https://keepachangelog.com), the
4
4
  versions [Semantic Versioning](https://semver.org) (before 1.0.0, a minor version may change an API).
5
5
 
6
+ ## [1.2.0] - 2026-10-22
7
+
8
+ ### Added
9
+
10
+ - `isard/react`: `<Layer>` typed by the properties of its features and its handle by its `type`, a `values` prop
11
+ (`setValues`) and its `filter` sent by `setFilter`; `<IsardMap hoverPicking>`; `<Control>` and `<CustomLayer>`. Each
12
+ component in its own file. The `HoverPicking` type exported.
13
+ - Every example also in React (`examples/react/`), side by side in the docs (TypeScript and React groups); the live
14
+ example above the code in the React pages; the install commands for npm, bun, yarn and pnpm.
15
+
16
+ ### Changed
17
+
18
+ - Arrow functions, array methods and `const` across the TypeScript sources (loops kept where they are hot); blank
19
+ lines around declarations and before returns, in TypeScript and Rust.
20
+ - Type guards in place of type assertions: the data read from outside (MapLibre styles, TileJSON, sprite indexes,
21
+ panoramas' orientations and calibrations, WFS pages, TopoJSON, the viewer's messages) checked at run time, a clear
22
+ error when it is not what it should be; `GeoMap`'s internals in `src/map/`.
23
+ - The Rust crates read by a newcomer: every public item documented (`missing_docs`), every `unsafe` justified
24
+ (`undocumented_unsafe_blocks`), the failures of the functions returning a `Result` (`# Errors`), the long functions
25
+ of a frame, a tile's arrival or a request split into named steps, the lint exceptions as `#[expect(…, reason)]`, one
26
+ module layout (no `mod.rs`), the crates' shared fields in `[workspace.package]`; an Architecture page in the guide
27
+ (the engines, the SDK, the workers, a frame, a tile).
28
+ - The Rust files grouped and split by subject: `render/features/` (lines, circles, fills), `render/backdrop/` (globe,
29
+ sky), the camera, the shapes, the labels and the COPC point clouds in submodules, meshopt under `decode/`; the few
30
+ duplicated blocks as shared helpers (0.41 % of the lines duplicated to 0.03 %).
31
+ - The crates' dependencies vetted by the checks (`cargo-deny`: known vulnerabilities, licences, sources); the
32
+ Architecture page of its own, its diagram played step by step (a frame, a raster tile, a vector basemap tile, 3D
33
+ Tiles), each part's role and files on click.
34
+
35
+ ### Fixed
36
+
37
+ - A marker's popup opened before the marker is added to the map stays open (`Marker.addTo`).
38
+
39
+ ## [1.1.0] - 2026-10-21
40
+
41
+ ### Added
42
+
43
+ - `isard/react`: the map and what it shows as components, for React 18 and 19 (optional peer dependencies).
44
+ `<IsardMap>` creates the map when it mounts and destroys it when it unmounts (StrictMode and the asynchronous
45
+ creation handled), its options as props (the basemap, the relief, the zoom range… taken again when they change; a
46
+ camera followed with `camera`), its events as `onClick`, `onMoveEnd`…; `<Layer type … />` takes the options of
47
+ `map.add`, a change of its data or style sent by `setData` / `setStyle`, the layer made anew in its place when what
48
+ changed is set at creation, the layers in their mounting order or by `order`; `<Marker>`, `<Popup>` and `<Panel>`
49
+ of JSX content (portals); `<Viewshed>` (several drawn together) and `<Swipe>` (the layers in it); `useMap()` and
50
+ `useMapEvent()`. A React section in the docs, and its example.
51
+
52
+ ### Changed
53
+
54
+ - The package's sources in folders by theme (`engine/`, `layers/`, `basemap/`, `data/`, `ui/`, `util/`, `workers/`),
55
+ their tests in the same folders; the entry points and their public API unchanged.
56
+
6
57
  ## [1.0.0] - 2026-10-21
7
58
 
8
59
  The first stable version: its API is kept until 2.0 (additions only in between).
@@ -1,7 +1,7 @@
1
1
  /** The basemaps by name: OpenFreeMap's vector styles (OpenStreetMap data, worldwide) and the Géoplateforme's (IGN,
2
2
  * France), the credits of the sources, and the relief of each body */
3
- import { IGN_ATTRIBUTION } from './geoplateforme.ts';
4
- import type { BasemapName, RasterOptions } from './types.ts';
3
+ import { IGN_ATTRIBUTION } from '../geoplateforme.ts';
4
+ import type { BasemapName, RasterOptions } from '../types.ts';
5
5
  export { IGN_ATTRIBUTION };
6
6
  /** The raster basemaps of the Géoplateforme (WMTS, Web Mercator), crediting the IGN */
7
7
  export declare const BASEMAPS: Record<'ign-plan' | 'ign-plan-grey' | 'ign-ortho', RasterOptions>;
@@ -37,7 +37,7 @@ export declare const IMAGE_SERVER: RegExp;
37
37
  * by its validity mask) of the box `{bbox}` in the Mercator of the body. On the Earth, Web Mercator (EPSG:3857);
38
38
  * elsewhere, a Mercator on the sphere of `radius` metres (Web Mercator's own formulas), given in WKT.
39
39
  */
40
- export declare function imageServerTerrain(url: string, earth: boolean, radius: number): string;
40
+ export declare const imageServerTerrain: (url: string, earth: boolean, radius: number) => string;
41
41
  /** The Earth's relief for `terrain: true`: the Terrain Tiles of AWS's open data registry, worldwide (SRTM, EU-DEM,
42
42
  * GMTED… merged by Mapzen), Terrarium PNGs of 256 px to level 14, altitudes above the mean sea level */
43
43
  export declare const TERRAIN_TILES: {
@@ -1,6 +1,6 @@
1
1
  /** The basemaps by name: OpenFreeMap's vector styles (OpenStreetMap data, worldwide) and the Géoplateforme's (IGN,
2
2
  * France), the credits of the sources, and the relief of each body */
3
- import { geoplateformeWmts, IGN_ATTRIBUTION } from "./geoplateforme.js";
3
+ import { geoplateformeWmts, IGN_ATTRIBUTION } from "../geoplateforme.js";
4
4
  export { IGN_ATTRIBUTION };
5
5
  const PLAN = 'GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2';
6
6
  /** The raster basemaps of the Géoplateforme (WMTS, Web Mercator), crediting the IGN */
@@ -52,7 +52,7 @@ export const IMAGE_SERVER = /\/ImageServer\/?$/;
52
52
  * by its validity mask) of the box `{bbox}` in the Mercator of the body. On the Earth, Web Mercator (EPSG:3857);
53
53
  * elsewhere, a Mercator on the sphere of `radius` metres (Web Mercator's own formulas), given in WKT.
54
54
  */
55
- export function imageServerTerrain(url, earth, radius) {
55
+ export const imageServerTerrain = (url, earth, radius) => {
56
56
  const crs = earth
57
57
  ? '3857'
58
58
  : encodeURIComponent(JSON.stringify({
@@ -63,7 +63,7 @@ export function imageServerTerrain(url, earth, radius) {
63
63
  }));
64
64
  return (`${url.replace(/\/$/, '')}/exportImage?f=image&format=bsq&pixelType=F32&size=256,256` +
65
65
  `&bboxSR=${crs}&imageSR=${crs}&bbox={bbox}`);
66
- }
66
+ };
67
67
  /** The Earth's relief for `terrain: true`: the Terrain Tiles of AWS's open data registry, worldwide (SRTM, EU-DEM,
68
68
  * GMTED… merged by Mapzen), Terrarium PNGs of 256 px to level 14, altitudes above the mean sea level */
69
69
  export const TERRAIN_TILES = {
@@ -0,0 +1 @@
1
+ {"version":3,"file":"basemaps.js","sourceRoot":"","sources":["../../src/basemap/basemaps.ts"],"names":[],"mappings":"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","sourcesContent":["/** The basemaps by name: OpenFreeMap's vector styles (OpenStreetMap data, worldwide) and the Géoplateforme's (IGN,\n * France), the credits of the sources, and the relief of each body */\nimport { geoplateformeWmts, IGN_ATTRIBUTION } from '../geoplateforme.ts';\nimport type { BasemapName, RasterOptions } from '../types.ts';\n\nexport { IGN_ATTRIBUTION };\n\nconst PLAN = 'GEOGRAPHICALGRIDSYSTEMS.PLANIGNV2';\n\n/** The raster basemaps of the Géoplateforme (WMTS, Web Mercator), crediting the IGN */\nexport const BASEMAPS: Record<'ign-plan' | 'ign-plan-grey' | 'ign-ortho', RasterOptions> = {\n 'ign-plan': geoplateformeWmts(PLAN),\n 'ign-plan-grey': geoplateformeWmts(PLAN, { saturation: 0 }),\n 'ign-ortho': geoplateformeWmts('ORTHOIMAGERY.ORTHOPHOTOS', { format: 'image/jpeg' }),\n};\n\n/** The former names of the Géoplateforme basemaps (before 0.5), and their names now: an error tells it */\nexport const RENAMED_BASEMAPS: Record<string, BasemapName> = {\n plan: 'ign-plan',\n 'plan-grey': 'ign-plan-grey',\n ortho: 'ign-ortho',\n 'plan-vector': 'ign-plan-vector',\n 'plan-grey-vector': 'ign-plan-grey-vector',\n};\n\n/** Credits of OpenFreeMap's basemaps, as its TileJSON gives them */\nexport const OPENFREEMAP_ATTRIBUTION =\n '<a href=\"https://openfreemap.org\">OpenFreeMap</a> <a href=\"https://www.openmaptiles.org/\">© OpenMapTiles</a> ' +\n 'Data from <a href=\"https://www.openstreetmap.org/copyright\">OpenStreetMap</a>';\n\n/** Credits of the Terrain Tiles of AWS's open data registry (Mapzen's Terrarium tiles) and of their sources */\nexport const TERRAIN_TILES_ATTRIBUTION =\n '<a href=\"https://github.com/tilezen/joerd/blob/master/docs/attribution.md\">Terrain Tiles</a> (Mapzen, AWS)';\n\n/** IGN hillshade, grey on transparent, zooms 6 to 17 */\nexport const HILLSHADE: RasterOptions = geoplateformeWmts('IGNF_ELEVATION.ELEVATIONGRIDCOVERAGE.SHADOW', {\n minZoom: 6,\n maxZoom: 17,\n});\n\n/** IGN terrain model (RGE ALTI and its fill-ins, France), raw altitudes in metres from the Géoplateforme WMS */\nexport const TERRAIN_URL =\n 'https://data.geopf.fr/wms-r/wms?SERVICE=WMS&VERSION=1.3.0&REQUEST=GetMap&LAYERS=ELEVATION.ELEVATIONGRIDCOVERAGE.HIGHRES' +\n '&STYLES=&CRS=EPSG:3857&BBOX={bbox}&WIDTH=256&HEIGHT=256&FORMAT=image/x-bil;bits=32';\n\n/** The relief of the Moon and Mars by default: NASA's Trek image services (ArcGIS), raw 32-bit altitudes in metres\n * asked for in the body's Mercator, with their credits. The Moon: LOLA's global model, 128 pixels per degree (237 m);\n * Mars: MOLA's, 128 and 64 pixels per degree merged (463 m), above the areoid */\nexport const BODY_TERRAINS = {\n moon: {\n url: 'https://trek.nasa.gov/moon/trekarcgis/rest/services/LRO_LOLA_DEM_Global_128ppd_v04/ImageServer',\n maxZoom: 8,\n attribution: '<a href=\"https://trek.nasa.gov/moon/\">NASA Moon Trek</a>: LOLA terrain model, NASA/GSFC/MIT',\n },\n mars: {\n url: 'https://trek.nasa.gov/mars/trekarcgis/rest/services/mola128_mola64_merge_90Nto90S_SimpleC_clon0/ImageServer',\n maxZoom: 8,\n attribution: '<a href=\"https://trek.nasa.gov/mars/\">NASA Mars Trek</a>: MOLA terrain model, NASA/JPL/GSFC',\n },\n} as const;\n\n/** An ArcGIS image service (a URL ending in `/ImageServer`) */\nexport const IMAGE_SERVER = /\\/ImageServer\\/?$/;\n\n/**\n * The `exportImage` template of an ArcGIS image service for the relief: 256 × 256 raw 32-bit floats (`bsq`, followed\n * by its validity mask) of the box `{bbox}` in the Mercator of the body. On the Earth, Web Mercator (EPSG:3857);\n * elsewhere, a Mercator on the sphere of `radius` metres (Web Mercator's own formulas), given in WKT.\n */\nexport const imageServerTerrain = (url: string, earth: boolean, radius: number): string => {\n const crs = earth\n ? '3857'\n : encodeURIComponent(\n JSON.stringify({\n wkt:\n `PROJCS[\"Mercator\",GEOGCS[\"GCS\",DATUM[\"D\",SPHEROID[\"S\",${radius},0]],PRIMEM[\"Reference_Meridian\",0],` +\n 'UNIT[\"Degree\",0.0174532925199433]],PROJECTION[\"Mercator\"],PARAMETER[\"False_Easting\",0],' +\n 'PARAMETER[\"False_Northing\",0],PARAMETER[\"Central_Meridian\",0],PARAMETER[\"Standard_Parallel_1\",0],' +\n 'UNIT[\"Meter\",1]]',\n }),\n );\n\n return (\n `${url.replace(/\\/$/, '')}/exportImage?f=image&format=bsq&pixelType=F32&size=256,256` +\n `&bboxSR=${crs}&imageSR=${crs}&bbox={bbox}`\n );\n};\n\n/** The Earth's relief for `terrain: true`: the Terrain Tiles of AWS's open data registry, worldwide (SRTM, EU-DEM,\n * GMTED… merged by Mapzen), Terrarium PNGs of 256 px to level 14, altitudes above the mean sea level */\nexport const TERRAIN_TILES = {\n url: 'https://s3.amazonaws.com/elevation-tiles-prod/terrarium/{z}/{x}/{y}.png',\n maxZoom: 14,\n} as const;\n\n/** Sea color of each basemap, for the globe under the tiles (polar caps), RGB 0-1 */\nexport const SEA: Record<BasemapName, [r: number, g: number, b: number]> = {\n 'osm-positron': [0.761, 0.784, 0.792],\n 'osm-liberty': [0.62, 0.741, 1],\n 'osm-bright': [0.682, 0.812, 0.886],\n 'ign-plan': [0.667, 0.835, 0.914],\n 'ign-plan-grey': [0.792, 0.792, 0.792],\n 'ign-plan-vector': [0.667, 0.835, 0.914],\n 'ign-plan-grey-vector': [0.792, 0.792, 0.792],\n 'ign-ortho': [0.039, 0.231, 0.349],\n none: [0.85, 0.85, 0.83],\n};\n"]}
@@ -5,7 +5,7 @@
5
5
  * work: 289 points a tile, whatever its size), picks the source level of the same pixel size, and lists the source
6
6
  * images the tile spans; the drawing (`resample.ts`) is done by a worker of the map, or in the page without workers.
7
7
  */
8
- import { type Crs, type CrsLike } from './crs.ts';
8
+ import { type Crs, type CrsLike } from '../data/crs.ts';
9
9
  import { type Job } from './resample.ts';
10
10
  /** One level of a tile grid, as a `TileMatrix` of WMTS */
11
11
  export interface TileMatrix {
@@ -52,20 +52,20 @@ interface Resolved {
52
52
  extent: [number, number, number, number] | undefined;
53
53
  }
54
54
  /** A tile grid ready to plan tiles: its CRS found, its matrices completed, its bounds projected */
55
- export declare function resolveGrid(grid: TileGrid): Resolved;
55
+ export declare const resolveGrid: (grid: TileGrid) => Resolved;
56
56
  /** The longitudes and latitudes of tiles in longitudes and latitudes, two 256 px tiles side by side at level 0, rows
57
57
  * from the north (NASA's Trek, WorldCRS84Quad), levels `minLevel` to `maxLevel` ({z} is the level) */
58
- export declare function equirectangularGrid(minLevel: number, maxLevel: number): TileGrid;
58
+ export declare const equirectangularGrid: (minLevel: number, maxLevel: number) => TileGrid;
59
59
  /**
60
60
  * The plan of Mercator tile `z`/`x`/`y` (`size` pixels a side) from a source of URL template `url` in grid `g`; null
61
61
  * where the source has nothing
62
62
  */
63
- export declare function planTile(g: Resolved, url: string, z: number, x: number, y: number, size: number): Job | null;
63
+ export declare const planTile: (g: Resolved, url: string, z: number, x: number, y: number, size: number) => Job | null;
64
64
  /**
65
65
  * The map zooms a grid's matrices span (the pixel size of the finest and of the coarsest, two levels coarser, where
66
66
  * the tiles still fit a mosaic), measured at the middle of its bounds, or of its coarsest matrix
67
67
  */
68
- export declare function gridZooms(g: Resolved): {
68
+ export declare const gridZooms: (g: Resolved) => {
69
69
  minZoom: number;
70
70
  maxZoom: number;
71
71
  };
@@ -77,5 +77,5 @@ export type RemoteReprojection = (job: Job, tile: [z: number, x: number, y: numb
77
77
  * A raster loader drawing Web Mercator tiles of `size` pixels from a source of URL template `url` in tile grid `grid`:
78
78
  * planned here, drawn in a worker of the map through `remote` when it can, else in the page
79
79
  */
80
- export declare function gridLoader(url: string, grid: Resolved, size: number, remote?: RemoteReprojection): Draw;
80
+ export declare const gridLoader: (url: string, grid: Resolved, size: number, remote?: RemoteReprojection) => Draw;
81
81
  export {};
@@ -5,8 +5,8 @@
5
5
  * work: 289 points a tile, whatever its size), picks the source level of the same pixel size, and lists the source
6
6
  * images the tile spans; the drawing (`resample.ts`) is done by a worker of the map, or in the page without workers.
7
7
  */
8
- import { getCrs } from "./crs.js";
9
- import { latitude, longitude, mercatorX, mercatorY } from "./geo.js";
8
+ import { getCrs } from "../data/crs.js";
9
+ import { latitude, longitude, mercatorX, mercatorY } from "../util/geo.js";
10
10
  import { resampler } from "./resample.js";
11
11
  /** Cells of the mesh along each side of a tile */
12
12
  const N = 16;
@@ -16,7 +16,7 @@ const MAX_BOOST = 3;
16
16
  /** Pixels of a mosaic at most: coarser levels beyond, nothing if even the coarsest is larger */
17
17
  const MAX_MOSAIC = 2048 * 2048;
18
18
  /** A box of the CRS around points of it (x, y, x, y…), NaN ignored; undefined without any */
19
- function box(points) {
19
+ const box = (points) => {
20
20
  let [x0, y0, x1, y1] = [Infinity, Infinity, -Infinity, -Infinity];
21
21
  for (let k = 0; k + 1 < points.length; k += 2) {
22
22
  const [x, y] = [points[k], points[k + 1]];
@@ -28,9 +28,9 @@ function box(points) {
28
28
  y1 = Math.max(y1, y);
29
29
  }
30
30
  return x0 <= x1 ? [x0, y0, x1, y1] : undefined;
31
- }
31
+ };
32
32
  /** A tile grid ready to plan tiles: its CRS found, its matrices completed, its bounds projected */
33
- export function resolveGrid(grid) {
33
+ export const resolveGrid = (grid) => {
34
34
  const crs = getCrs(grid.crs);
35
35
  const matrices = (grid.matrices ?? [])
36
36
  .map((m, i) => ({
@@ -44,35 +44,32 @@ export function resolveGrid(grid) {
44
44
  limits: m.limits,
45
45
  }))
46
46
  .sort((a, b) => b.resolution - a.resolution);
47
- let extent;
48
- if (grid.bounds) {
47
+ const projected = (bounds) => {
49
48
  // Its outline and inside, projected: the box of the CRS around them, a little larger (curved edges)
50
- const [w, s, e, n] = grid.bounds;
51
- const points = [];
52
- for (let i = 0; i <= 8; i += 1) {
53
- for (let j = 0; j <= 8; j += 1)
54
- points.push(...crs.forward([w + ((e - w) * i) / 8, s + ((n - s) * j) / 8]));
55
- }
49
+ const [w, s, e, n] = bounds;
50
+ const steps = Array.from({ length: 9 }, (_, i) => i);
51
+ const points = steps.flatMap((i) => steps.flatMap((j) => crs.forward([w + ((e - w) * i) / 8, s + ((n - s) * j) / 8])));
56
52
  const b = box(points);
57
- if (b) {
58
- const margin = 0.01 * Math.max(b[2] - b[0], b[3] - b[1]);
59
- extent = [b[0] - margin, b[1] - margin, b[2] + margin, b[3] + margin];
60
- }
61
- }
53
+ if (!b)
54
+ return undefined;
55
+ const margin = 0.01 * Math.max(b[2] - b[0], b[3] - b[1]);
56
+ return [b[0] - margin, b[1] - margin, b[2] + margin, b[3] + margin];
57
+ };
58
+ const extent = grid.bounds ? projected(grid.bounds) : undefined;
62
59
  return { crs, matrices, bounds: grid.bounds, extent };
63
- }
60
+ };
64
61
  /** The longitudes and latitudes of tiles in longitudes and latitudes, two 256 px tiles side by side at level 0, rows
65
62
  * from the north (NASA's Trek, WorldCRS84Quad), levels `minLevel` to `maxLevel` ({z} is the level) */
66
- export function equirectangularGrid(minLevel, maxLevel) {
67
- const matrices = [];
68
- for (let level = minLevel; level <= maxLevel; level += 1) {
63
+ export const equirectangularGrid = (minLevel, maxLevel) => {
64
+ const matrices = Array.from({ length: maxLevel - minLevel + 1 }, (_, i) => {
65
+ const level = minLevel + i;
69
66
  const n = 2 ** level;
70
- matrices.push({ id: level, resolution: 180 / 256 / n, origin: [-180, 90], matrixWidth: 2 * n, matrixHeight: n });
71
- }
67
+ return { id: level, resolution: 180 / 256 / n, origin: [-180, 90], matrixWidth: 2 * n, matrixHeight: n };
68
+ });
72
69
  return { crs: 'EPSG:4326', matrices };
73
- }
70
+ };
74
71
  /** A URL of the source: {z}, {x}, {y}, {bbox}, {width} and {height} replaced */
75
- function sourceUrl(template, z, x, y, bbox, w, h) {
72
+ const sourceUrl = (template, z, x, y, bbox, w, h) => {
76
73
  return template
77
74
  .replaceAll('{z}', String(z))
78
75
  .replaceAll('{x}', String(x))
@@ -80,20 +77,20 @@ function sourceUrl(template, z, x, y, bbox, w, h) {
80
77
  .replaceAll('{bbox}', bbox.join(','))
81
78
  .replaceAll('{width}', String(w))
82
79
  .replaceAll('{height}', String(h));
83
- }
80
+ };
84
81
  /** CRS units per pixel along the mesh's x and y around its middle (NaN where the CRS has nothing there) */
85
- function pixelSize(points, size) {
82
+ const pixelSize = (points, size) => {
86
83
  const c = N / 2;
87
84
  const at = (i, j) => 2 * (j * (N + 1) + i);
88
- const d = (p, q) => Math.hypot(points[q] - points[p], points[q + 1] - points[p + 1]);
85
+ const d = (p, q) => Math.hypot((points[q] ?? Number.NaN) - (points[p] ?? Number.NaN), (points[q + 1] ?? Number.NaN) - (points[p + 1] ?? Number.NaN));
89
86
  const step = (2 * size) / N;
90
87
  return [d(at(c - 1, c), at(c + 1, c)) / step, d(at(c, c - 1), at(c, c + 1)) / step];
91
- }
88
+ };
92
89
  /**
93
90
  * The box (CRS) of the points a tile samples: the centers of its edge pixels, interpolated in the mesh as `resample`
94
91
  * does, and the inner points of the mesh (should the projection bend); within `clip`. Undefined if none is
95
92
  */
96
- function sampled(points, size, clip) {
93
+ const sampled = (points, size, clip) => {
97
94
  const at = (i, j, k) => points[2 * (j * (N + 1) + i) + k];
98
95
  const centers = [];
99
96
  for (let j = 1; j < N; j += 1)
@@ -126,12 +123,12 @@ function sampled(points, size, clip) {
126
123
  Math.min(b[3], clip[3]),
127
124
  ];
128
125
  return out[0] <= out[2] && out[1] <= out[3] ? out : undefined;
129
- }
126
+ };
130
127
  /**
131
128
  * The plan of Mercator tile `z`/`x`/`y` (`size` pixels a side) from a source of URL template `url` in grid `g`; null
132
129
  * where the source has nothing
133
130
  */
134
- export function planTile(g, url, z, x, y, size) {
131
+ export const planTile = (g, url, z, x, y, size) => {
135
132
  const tiles = 2 ** z;
136
133
  if (g.bounds) {
137
134
  const [w, s, e, n] = g.bounds;
@@ -150,15 +147,15 @@ export function planTile(g, url, z, x, y, size) {
150
147
  points[2 * (j * (N + 1) + i) + 1] = py;
151
148
  }
152
149
  }
153
- let b = box(points);
154
- if (!b)
150
+ const outer = box(points);
151
+ if (!outer)
152
+ return null;
153
+ const e = g.extent;
154
+ const b = e
155
+ ? [Math.max(outer[0], e[0]), Math.max(outer[1], e[1]), Math.min(outer[2], e[2]), Math.min(outer[3], e[3])]
156
+ : outer;
157
+ if (e && (b[0] >= b[2] || b[1] >= b[3]))
155
158
  return null;
156
- if (g.extent) {
157
- const e = g.extent;
158
- b = [Math.max(b[0], e[0]), Math.max(b[1], e[1]), Math.min(b[2], e[2]), Math.min(b[3], e[3])];
159
- if (b[0] >= b[2] || b[1] >= b[3])
160
- return null;
161
- }
162
159
  const mesh = new Float32Array(points.length);
163
160
  if (g.matrices.length === 0) {
164
161
  // One image of the tile's box, a pixel larger on each side
@@ -180,14 +177,14 @@ export function planTile(g, url, z, x, y, size) {
180
177
  const centers = sampled(points, size, b);
181
178
  if (!centers)
182
179
  return null;
183
- let best = 0;
184
- g.matrices.forEach((m, i) => {
185
- const r = g.matrices[best]?.resolution ?? m.resolution;
186
- if (Math.abs(Math.log2(m.resolution / target)) < Math.abs(Math.log2(r / target)))
187
- best = i;
188
- });
180
+ const best = g.matrices.reduce((found, m, i) => {
181
+ const r = g.matrices[found]?.resolution ?? m.resolution;
182
+ return Math.abs(Math.log2(m.resolution / target)) < Math.abs(Math.log2(r / target)) ? i : found;
183
+ }, 0);
189
184
  for (let level = best; level >= 0; level -= 1) {
190
185
  const m = g.matrices[level];
186
+ if (!m)
187
+ continue;
191
188
  const [ox, oy] = m.origin;
192
189
  const [tw, th, res] = [m.tileWidth, m.tileHeight, m.resolution];
193
190
  const [l0, r0, l1, r1] = m.limits ?? [0, 0, Infinity, Infinity];
@@ -202,14 +199,12 @@ export function planTile(g, url, z, x, y, size) {
202
199
  const [width, height] = [(c1 - c0 + 1) * tw, (t1 - t0 + 1) * th];
203
200
  if (width * height > MAX_MOSAIC)
204
201
  continue;
205
- const sources = [];
206
- for (let row = t0; row <= t1; row += 1) {
207
- for (let col = c0; col <= c1; col += 1) {
208
- const bbox = [ox + col * tw * res, oy - (row + 1) * th * res, ox + (col + 1) * tw * res, oy - row * th * res];
209
- const placed = { x: (col - c0) * tw, y: (row - t0) * th, w: tw, h: th };
210
- sources.push({ url: sourceUrl(url, m.id, col, row, bbox, tw, th), ...placed });
211
- }
212
- }
202
+ const sources = Array.from({ length: t1 - t0 + 1 }, (_, r) => t0 + r).flatMap((row) => Array.from({ length: c1 - c0 + 1 }, (_, c) => {
203
+ const col = c0 + c;
204
+ const bbox = [ox + col * tw * res, oy - (row + 1) * th * res, ox + (col + 1) * tw * res, oy - row * th * res];
205
+ const placed = { x: (col - c0) * tw, y: (row - t0) * th, w: tw, h: th };
206
+ return { url: sourceUrl(url, m.id, col, row, bbox, tw, th), ...placed };
207
+ }));
213
208
  for (let k = 0; k < points.length; k += 2) {
214
209
  mesh[k] = (points[k] - ox) / res - c0 * tw;
215
210
  mesh[k + 1] = (oy - points[k + 1]) / res - t0 * th;
@@ -217,26 +212,25 @@ export function planTile(g, url, z, x, y, size) {
217
212
  return { size, width, height, sources, n: N, mesh };
218
213
  }
219
214
  return null;
220
- }
215
+ };
221
216
  /**
222
217
  * The map zooms a grid's matrices span (the pixel size of the finest and of the coarsest, two levels coarser, where
223
218
  * the tiles still fit a mosaic), measured at the middle of its bounds, or of its coarsest matrix
224
219
  */
225
- export function gridZooms(g) {
220
+ export const gridZooms = (g) => {
226
221
  const coarse = g.matrices[0];
227
222
  const fine = g.matrices.at(-1);
228
223
  if (!coarse || !fine)
229
224
  return { minZoom: 0, maxZoom: 19 };
230
- let lonLat = [0, 0];
231
- if (g.bounds)
232
- lonLat = [(g.bounds[0] + g.bounds[2]) / 2, (g.bounds[1] + g.bounds[3]) / 2];
233
- else {
225
+ const middle = () => {
234
226
  const [l0, r0, l1, r1] = coarse.limits ?? [0, 0, coarse.matrixWidth - 1, coarse.matrixHeight - 1];
235
227
  const span = coarse.resolution * coarse.tileWidth;
236
228
  const [cx, cy] = [(l0 + l1 + 1) / 2, (r0 + r1 + 1) / 2];
237
- if (Number.isFinite(cx + cy))
238
- lonLat = g.crs.inverse([coarse.origin[0] + cx * span, coarse.origin[1] - cy * span]);
239
- }
229
+ return Number.isFinite(cx + cy)
230
+ ? g.crs.inverse([coarse.origin[0] + cx * span, coarse.origin[1] - cy * span])
231
+ : [0, 0];
232
+ };
233
+ const lonLat = g.bounds ? [(g.bounds[0] + g.bounds[2]) / 2, (g.bounds[1] + g.bounds[3]) / 2] : middle();
240
234
  // CRS units per pixel of a 256 px tile at zoom 0 there
241
235
  const [mx, my] = [mercatorX(lonLat[0] ?? 0), mercatorY(lonLat[1] ?? 0)];
242
236
  const d = 1e-7;
@@ -249,12 +243,12 @@ export function gridZooms(g) {
249
243
  minZoom: Math.max(0, Math.floor(Math.log2(zero / coarse.resolution)) - 2),
250
244
  maxZoom: Math.max(0, Math.round(Math.log2(zero / fine.resolution))),
251
245
  };
252
- }
246
+ };
253
247
  /**
254
248
  * A raster loader drawing Web Mercator tiles of `size` pixels from a source of URL template `url` in tile grid `grid`:
255
249
  * planned here, drawn in a worker of the map through `remote` when it can, else in the page
256
250
  */
257
- export function gridLoader(url, grid, size, remote) {
251
+ export const gridLoader = (url, grid, size, remote) => {
258
252
  let local;
259
253
  return async (z, x, y, signal) => {
260
254
  const job = planTile(grid, url, z, x, y, size);
@@ -266,5 +260,5 @@ export function gridLoader(url, grid, size, remote) {
266
260
  local ??= resampler().draw;
267
261
  return local(job, signal);
268
262
  };
269
- }
263
+ };
270
264
  //# sourceMappingURL=grid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grid.js","sourceRoot":"","sources":["../../src/basemap/grid.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Rasters in another tile grid, the planning half: a WMTS-like tile matrix set in any CRS (Lambert-93, UTM, longitudes\n * and latitudes…), or a WMS asked for a box in that CRS, reprojected into the Web Mercator tiles the engine draws. For\n * each Mercator tile the page projects a mesh of 17 × 17 points of the tile into the source CRS (the only projection\n * work: 289 points a tile, whatever its size), picks the source level of the same pixel size, and lists the source\n * images the tile spans; the drawing (`resample.ts`) is done by a worker of the map, or in the page without workers.\n */\nimport { type Crs, type CrsLike, getCrs } from '../data/crs.ts';\nimport { latitude, longitude, mercatorX, mercatorY } from '../util/geo.ts';\nimport { type Job, type Placed, resampler } from './resample.ts';\n\n/** One level of a tile grid, as a `TileMatrix` of WMTS */\nexport interface TileMatrix {\n /** What replaces {z} in the URL (the `TILEMATRIX` of a WMTS; default the index of the matrix in the grid) */\n id?: string | number;\n /** Size of a pixel, CRS units (WMTS: its `ScaleDenominator` × 0.00028 m, in CRS units) */\n resolution: number;\n /** Top-left corner of the tile (0, 0), CRS units (x east, y north) */\n origin: [x: number, y: number];\n /** Size of a tile, pixels (default 256) */\n tileWidth?: number;\n tileHeight?: number;\n /** Tiles across and down (default unbounded) */\n matrixWidth?: number;\n matrixHeight?: number;\n /** The tiles the source has (a WMTS's `TileMatrixLimits`), inclusive: none is asked for outside */\n limits?: [minCol: number, minRow: number, maxCol: number, maxRow: number];\n}\n\n/**\n * A raster's tile grid in a CRS of its own, reprojected into Web Mercator by the map: `matrices` for tiles ({z}, {x},\n * {y} in the URL: matrix, column, row, rows from the north), none for a WMS whose URL has `{bbox}` (the box of each\n * Mercator tile in that CRS: minimum x, minimum y, maximum x, maximum y, asked for at the tile's size)\n */\nexport interface TileGrid {\n /** `'EPSG:2154'`, another built-in or registered name, or an object with `forward` and `inverse` (proj4's) */\n crs: CrsLike;\n /** The levels of the grid, in any order */\n matrices?: TileMatrix[];\n /** Longitudes and latitudes the source covers (west, south, east, north): nothing is asked for outside */\n bounds?: [west: number, south: number, east: number, north: number];\n /** Identifier of the tile matrix set (a WMTS's `TILEMATRIXSET`), for the helpers that write the URL */\n name?: string;\n}\n\n/** Cells of the mesh along each side of a tile */\nconst N = 16;\n/** Source levels finer at most than the pixel size across, where the grid stretches one axis (towards the poles in\n * longitudes and latitudes) */\nconst MAX_BOOST = 3;\n/** Pixels of a mosaic at most: coarser levels beyond, nothing if even the coarsest is larger */\nconst MAX_MOSAIC = 2048 * 2048;\n\ninterface Matrix extends Required<Omit<TileMatrix, 'limits' | 'id'>> {\n id: string | number;\n limits: [number, number, number, number] | undefined;\n}\n\ninterface Resolved {\n crs: Crs;\n /** Coarsest first */\n matrices: Matrix[];\n bounds: [number, number, number, number] | undefined;\n /** The bounds in the CRS: minimum x, minimum y, maximum x, maximum y */\n extent: [number, number, number, number] | undefined;\n}\n\n/** A box of the CRS around points of it (x, y, x, y…), NaN ignored; undefined without any */\nconst box = (points: ArrayLike<number>): [number, number, number, number] | undefined => {\n let [x0, y0, x1, y1] = [Infinity, Infinity, -Infinity, -Infinity];\n\n for (let k = 0; k + 1 < points.length; k += 2) {\n const [x, y] = [points[k] as number, points[k + 1] as number];\n\n if (!Number.isFinite(x) || !Number.isFinite(y)) continue;\n x0 = Math.min(x0, x);\n y0 = Math.min(y0, y);\n x1 = Math.max(x1, x);\n y1 = Math.max(y1, y);\n }\n\n return x0 <= x1 ? [x0, y0, x1, y1] : undefined;\n};\n\n/** A tile grid ready to plan tiles: its CRS found, its matrices completed, its bounds projected */\nexport const resolveGrid = (grid: TileGrid): Resolved => {\n const crs = getCrs(grid.crs);\n const matrices = (grid.matrices ?? [])\n .map(\n (m, i): Matrix => ({\n id: m.id ?? i,\n resolution: m.resolution,\n origin: m.origin,\n tileWidth: m.tileWidth ?? 256,\n tileHeight: m.tileHeight ?? 256,\n matrixWidth: m.matrixWidth ?? Infinity,\n matrixHeight: m.matrixHeight ?? Infinity,\n limits: m.limits,\n }),\n )\n .sort((a, b) => b.resolution - a.resolution);\n const projected = (bounds: [number, number, number, number]): Resolved['extent'] => {\n // Its outline and inside, projected: the box of the CRS around them, a little larger (curved edges)\n const [w, s, e, n] = bounds;\n const steps = Array.from({ length: 9 }, (_, i) => i);\n const points = steps.flatMap((i) =>\n steps.flatMap((j) => crs.forward([w + ((e - w) * i) / 8, s + ((n - s) * j) / 8])),\n );\n const b = box(points);\n\n if (!b) return undefined;\n\n const margin = 0.01 * Math.max(b[2] - b[0], b[3] - b[1]);\n\n return [b[0] - margin, b[1] - margin, b[2] + margin, b[3] + margin];\n };\n const extent = grid.bounds ? projected(grid.bounds) : undefined;\n\n return { crs, matrices, bounds: grid.bounds, extent };\n};\n\n/** The longitudes and latitudes of tiles in longitudes and latitudes, two 256 px tiles side by side at level 0, rows\n * from the north (NASA's Trek, WorldCRS84Quad), levels `minLevel` to `maxLevel` ({z} is the level) */\nexport const equirectangularGrid = (minLevel: number, maxLevel: number): TileGrid => {\n const matrices = Array.from({ length: maxLevel - minLevel + 1 }, (_, i): TileMatrix => {\n const level = minLevel + i;\n const n = 2 ** level;\n\n return { id: level, resolution: 180 / 256 / n, origin: [-180, 90], matrixWidth: 2 * n, matrixHeight: n };\n });\n\n return { crs: 'EPSG:4326', matrices };\n};\n\n/** A URL of the source: {z}, {x}, {y}, {bbox}, {width} and {height} replaced */\nconst sourceUrl = (\n template: string,\n z: string | number,\n x: number,\n y: number,\n bbox: number[],\n w: number,\n h: number,\n) => {\n return template\n .replaceAll('{z}', String(z))\n .replaceAll('{x}', String(x))\n .replaceAll('{y}', String(y))\n .replaceAll('{bbox}', bbox.join(','))\n .replaceAll('{width}', String(w))\n .replaceAll('{height}', String(h));\n};\n\n/** CRS units per pixel along the mesh's x and y around its middle (NaN where the CRS has nothing there) */\nconst pixelSize = (points: Float64Array, size: number): [number, number] => {\n const c = N / 2;\n const at = (i: number, j: number) => 2 * (j * (N + 1) + i);\n const d = (p: number, q: number) =>\n Math.hypot(\n (points[q] ?? Number.NaN) - (points[p] ?? Number.NaN),\n (points[q + 1] ?? Number.NaN) - (points[p + 1] ?? Number.NaN),\n );\n const step = (2 * size) / N;\n\n return [d(at(c - 1, c), at(c + 1, c)) / step, d(at(c, c - 1), at(c, c + 1)) / step];\n};\n\n/**\n * The box (CRS) of the points a tile samples: the centers of its edge pixels, interpolated in the mesh as `resample`\n * does, and the inner points of the mesh (should the projection bend); within `clip`. Undefined if none is\n */\nconst sampled = (\n points: Float64Array,\n size: number,\n clip: [number, number, number, number],\n): [number, number, number, number] | undefined => {\n const at = (i: number, j: number, k: number) => points[2 * (j * (N + 1) + i) + k] as number;\n const centers: number[] = [];\n\n for (let j = 1; j < N; j += 1) for (let i = 1; i < N; i += 1) centers.push(at(i, j, 0), at(i, j, 1));\n\n const cell = size / N;\n const add = (px: number, py: number) => {\n const [fx, fy] = [px / cell, py / cell];\n const [i, j] = [Math.min(N - 1, Math.floor(fx)), Math.min(N - 1, Math.floor(fy))];\n const [tx, ty] = [fx - i, fy - j];\n\n for (const k of [0, 1]) {\n const top = at(i, j, k) + (at(i + 1, j, k) - at(i, j, k)) * tx;\n const bottom = at(i, j + 1, k) + (at(i + 1, j + 1, k) - at(i, j + 1, k)) * tx;\n\n centers.push(top + (bottom - top) * ty);\n }\n };\n\n for (let p = 0.5; p < size; p += 1) {\n add(p, 0.5);\n add(p, size - 0.5);\n add(0.5, p);\n add(size - 0.5, p);\n }\n\n const b = box(centers);\n\n if (!b) return undefined;\n\n const out: [number, number, number, number] = [\n Math.max(b[0], clip[0]),\n Math.max(b[1], clip[1]),\n Math.min(b[2], clip[2]),\n Math.min(b[3], clip[3]),\n ];\n\n return out[0] <= out[2] && out[1] <= out[3] ? out : undefined;\n};\n\n/**\n * The plan of Mercator tile `z`/`x`/`y` (`size` pixels a side) from a source of URL template `url` in grid `g`; null\n * where the source has nothing\n */\nexport const planTile = (g: Resolved, url: string, z: number, x: number, y: number, size: number): Job | null => {\n const tiles = 2 ** z;\n\n if (g.bounds) {\n const [w, s, e, n] = g.bounds;\n\n if (longitude((x + 1) / tiles) <= w || longitude(x / tiles) >= e) return null;\n if (latitude(y / tiles) <= s || latitude((y + 1) / tiles) >= n) return null;\n }\n\n // The mesh in the source CRS\n const points = new Float64Array(2 * (N + 1) ** 2);\n\n for (let j = 0; j <= N; j += 1) {\n const lat = latitude((y + j / N) / tiles);\n\n for (let i = 0; i <= N; i += 1) {\n const [px = Number.NaN, py = Number.NaN] = g.crs.forward([longitude((x + i / N) / tiles), lat]);\n\n points[2 * (j * (N + 1) + i)] = px;\n points[2 * (j * (N + 1) + i) + 1] = py;\n }\n }\n\n const outer = box(points);\n\n if (!outer) return null;\n\n const e = g.extent;\n const b: [number, number, number, number] = e\n ? [Math.max(outer[0], e[0]), Math.max(outer[1], e[1]), Math.min(outer[2], e[2]), Math.min(outer[3], e[3])]\n : outer;\n\n if (e && (b[0] >= b[2] || b[1] >= b[3])) return null;\n\n const mesh = new Float32Array(points.length);\n\n if (g.matrices.length === 0) {\n // One image of the tile's box, a pixel larger on each side\n const [sx, sy] = pixelSize(points, size);\n const m = Number.isFinite(sx + sy) ? Math.max(sx, sy) : 0;\n const [x0, y0, x1, y1] = [b[0] - m, b[1] - m, b[2] + m, b[3] + m];\n\n for (let k = 0; k < points.length; k += 2) {\n mesh[k] = (((points[k] as number) - x0) / (x1 - x0)) * size;\n mesh[k + 1] = ((y1 - (points[k + 1] as number)) / (y1 - y0)) * size;\n }\n\n const source = { url: sourceUrl(url, z, x, y, [x0, y0, x1, y1], size, size), x: 0, y: 0, w: size, h: size };\n\n return { size, width: size, height: size, sources: [source], n: N, mesh };\n }\n\n // The level of the same pixel size, along the axis the grid stretches least (up to MAX_BOOST levels finer)\n const [sx, sy] = pixelSize(points, size);\n const across = Math.max(sx, sy);\n const target = Number.isFinite(across) ? Math.max(Math.min(sx, sy), across / 2 ** MAX_BOOST) : (b[2] - b[0]) / size;\n // Where the pixels of the tile are sampled: the centers of its edge pixels and the mesh, within the source's extent\n const centers = sampled(points, size, b);\n\n if (!centers) return null;\n\n const best = g.matrices.reduce((found, m, i) => {\n const r = g.matrices[found]?.resolution ?? m.resolution;\n\n return Math.abs(Math.log2(m.resolution / target)) < Math.abs(Math.log2(r / target)) ? i : found;\n }, 0);\n\n for (let level = best; level >= 0; level -= 1) {\n const m = g.matrices[level];\n\n if (!m) continue;\n\n const [ox, oy] = m.origin;\n const [tw, th, res] = [m.tileWidth, m.tileHeight, m.resolution];\n const [l0, r0, l1, r1] = m.limits ?? [0, 0, Infinity, Infinity];\n // The tiles of the source pixels sampled (those of a weight over a thousandth: a tile edge on a source tile edge\n // does not fetch the next source tile for nothing)\n const c0 = Math.max(0, l0, Math.floor(((centers[0] - ox) / res - 0.5 + 1e-3) / tw));\n const c1 = Math.min(m.matrixWidth - 1, l1, Math.floor(((centers[2] - ox) / res + 0.5 - 1e-3) / tw));\n const t0 = Math.max(0, r0, Math.floor(((oy - centers[3]) / res - 0.5 + 1e-3) / th));\n const t1 = Math.min(m.matrixHeight - 1, r1, Math.floor(((oy - centers[1]) / res + 0.5 - 1e-3) / th));\n\n if (c0 > c1 || t0 > t1) return null;\n\n const [width, height] = [(c1 - c0 + 1) * tw, (t1 - t0 + 1) * th];\n\n if (width * height > MAX_MOSAIC) continue;\n\n const sources = Array.from({ length: t1 - t0 + 1 }, (_, r) => t0 + r).flatMap((row) =>\n Array.from({ length: c1 - c0 + 1 }, (_, c): Placed => {\n const col = c0 + c;\n const bbox = [ox + col * tw * res, oy - (row + 1) * th * res, ox + (col + 1) * tw * res, oy - row * th * res];\n const placed = { x: (col - c0) * tw, y: (row - t0) * th, w: tw, h: th };\n\n return { url: sourceUrl(url, m.id, col, row, bbox, tw, th), ...placed };\n }),\n );\n\n for (let k = 0; k < points.length; k += 2) {\n mesh[k] = ((points[k] as number) - ox) / res - c0 * tw;\n mesh[k + 1] = (oy - (points[k + 1] as number)) / res - t0 * th;\n }\n\n return { size, width, height, sources, n: N, mesh };\n }\n\n return null;\n};\n\n/**\n * The map zooms a grid's matrices span (the pixel size of the finest and of the coarsest, two levels coarser, where\n * the tiles still fit a mosaic), measured at the middle of its bounds, or of its coarsest matrix\n */\nexport const gridZooms = (g: Resolved): { minZoom: number; maxZoom: number } => {\n const coarse = g.matrices[0];\n const fine = g.matrices.at(-1);\n\n if (!coarse || !fine) return { minZoom: 0, maxZoom: 19 };\n\n const middle = (): readonly number[] => {\n const [l0, r0, l1, r1] = coarse.limits ?? [0, 0, coarse.matrixWidth - 1, coarse.matrixHeight - 1];\n const span = coarse.resolution * coarse.tileWidth;\n const [cx, cy] = [(l0 + l1 + 1) / 2, (r0 + r1 + 1) / 2];\n\n return Number.isFinite(cx + cy)\n ? g.crs.inverse([coarse.origin[0] + cx * span, coarse.origin[1] - cy * span])\n : [0, 0];\n };\n const lonLat = g.bounds ? [(g.bounds[0] + g.bounds[2]) / 2, (g.bounds[1] + g.bounds[3]) / 2] : middle();\n // CRS units per pixel of a 256 px tile at zoom 0 there\n const [mx, my] = [mercatorX(lonLat[0] ?? 0), mercatorY(lonLat[1] ?? 0)];\n const d = 1e-7;\n const p = g.crs.forward([longitude(mx), latitude(my)]);\n const q = g.crs.forward([longitude(mx + d), latitude(my)]);\n const zero = Math.hypot((q[0] ?? 0) - (p[0] ?? 0), (q[1] ?? 0) - (p[1] ?? 0)) / (d * 256);\n\n if (!(zero > 0)) return { minZoom: 0, maxZoom: 19 };\n\n return {\n minZoom: Math.max(0, Math.floor(Math.log2(zero / coarse.resolution)) - 2),\n maxZoom: Math.max(0, Math.round(Math.log2(zero / fine.resolution))),\n };\n};\n\n/** Draws a Mercator tile `z`/`x`/`y`: its image, null where the source has nothing; rejects on errors */\ntype Draw = (z: number, x: number, y: number, signal: AbortSignal) => Promise<ImageBitmap | null>;\n\n/** A planned tile drawn in a worker; undefined when the map has no workers (drawn in the page) */\nexport type RemoteReprojection = (\n job: Job,\n tile: [z: number, x: number, y: number],\n signal: AbortSignal,\n) => Promise<ImageBitmap | null> | undefined;\n\n/**\n * A raster loader drawing Web Mercator tiles of `size` pixels from a source of URL template `url` in tile grid `grid`:\n * planned here, drawn in a worker of the map through `remote` when it can, else in the page\n */\nexport const gridLoader = (url: string, grid: Resolved, size: number, remote?: RemoteReprojection): Draw => {\n let local: ReturnType<typeof resampler>['draw'] | undefined;\n\n return async (z, x, y, signal) => {\n const job = planTile(grid, url, z, x, y, size);\n\n if (!job) return null;\n\n const drawn = remote?.(job, [z, x, y], signal);\n\n if (drawn) return drawn;\n local ??= resampler().draw;\n\n return local(job, signal);\n };\n};\n"]}
@@ -16,4 +16,4 @@ export interface TileLayer {
16
16
  features: TileFeature[];
17
17
  }
18
18
  /** Decodes a tile; only the layers in `wanted` (all if undefined) */
19
- export declare function decode(bytes: Uint8Array, wanted?: Set<string>): Map<string, TileLayer>;
19
+ export declare const decode: (bytes: Uint8Array, wanted?: Set<string>) => Map<string, TileLayer>;
@@ -94,7 +94,7 @@ class Pbf {
94
94
  }
95
95
  }
96
96
  const decoder = new TextDecoder();
97
- function value(p) {
97
+ const value = (p) => {
98
98
  let v = '';
99
99
  while (p.more) {
100
100
  const tag = p.varint();
@@ -125,9 +125,9 @@ function value(p) {
125
125
  }
126
126
  }
127
127
  return v;
128
- }
128
+ };
129
129
  /** Point lists of a geometry's commands (MoveTo, LineTo, ClosePath) */
130
- function geometry(p) {
130
+ const geometry = (p) => {
131
131
  const out = [];
132
132
  let current;
133
133
  let [x, y] = [0, 0];
@@ -153,9 +153,9 @@ function geometry(p) {
153
153
  }
154
154
  }
155
155
  return out;
156
- }
156
+ };
157
157
  /** Decodes a tile; only the layers in `wanted` (all if undefined) */
158
- export function decode(bytes, wanted) {
158
+ export const decode = (bytes, wanted) => {
159
159
  const layers = new Map();
160
160
  const tile = new Pbf(bytes);
161
161
  while (tile.more) {
@@ -227,5 +227,5 @@ export function decode(bytes, wanted) {
227
227
  layers.set(name, { extent, features });
228
228
  }
229
229
  return layers;
230
- }
230
+ };
231
231
  //# sourceMappingURL=mvt.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mvt.js","sourceRoot":"","sources":["../../src/basemap/mvt.ts"],"names":[],"mappings":"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","sourcesContent":["/**\n * Mapbox Vector Tiles (MVT 2.1) decoding: layers of features with their properties and geometry, in tile units\n * (`extent`, usually 4096 across). Points are lists of points, lines lists of lines, polygons lists of rings (the\n * outer ones clockwise in tile coordinates, y down, holes the other way round, as the specification says).\n */\n\nexport type Value = string | number | boolean;\n\nexport interface TileFeature {\n /** 1 point, 2 line, 3 polygon */\n type: 1 | 2 | 3;\n properties: Record<string, Value>;\n /** Point lists: x0, y0, x1, y1… in tile units */\n geometry: number[][];\n}\n\nexport interface TileLayer {\n extent: number;\n features: TileFeature[];\n}\n\n/** Protobuf reader of a buffer range */\nclass Pbf {\n pos: number;\n constructor(\n private readonly buf: Uint8Array,\n start = 0,\n readonly end = buf.length,\n ) {\n this.pos = start;\n }\n /** An unsigned varint, approximated beyond 2^53; all its bytes are read (up to 10), so the next field is right */\n varint(): number {\n let value = 0;\n\n for (let shift = 0; shift < 70; shift += 7) {\n const b = this.buf[this.pos++] ?? 0;\n\n value += (b & 0x7f) * 2 ** shift;\n if (b < 0x80) break;\n }\n\n return value;\n }\n /** A signed 64-bit varint (two's complement: a negative value takes 10 bytes) */\n int64(): number {\n let lo = 0;\n let hi = 0;\n\n for (let i = 0; i < 10; i += 1) {\n const b = this.buf[this.pos++] ?? 0;\n const bits = b & 0x7f;\n\n // Bits 0-27 in the low word, bits 28-31 split, the rest in the high word\n if (i < 4) lo |= bits << (7 * i);\n else if (i === 4) {\n lo |= (bits & 0x0f) << 28;\n hi |= bits >> 4;\n } else hi |= bits << (7 * i - 32);\n if (b < 0x80) break;\n }\n\n // The high word signed: values from 2^63 up are negative\n return (hi | 0) * 2 ** 32 + (lo >>> 0);\n }\n sint(): number {\n const v = this.varint();\n\n return v % 2 === 1 ? -(v + 1) / 2 : v / 2;\n }\n /** A length-delimited field as a sub-reader */\n sub(): Pbf {\n const n = this.varint();\n // A length past the end (a truncated tile) stops at the end\n const end = Math.min(this.pos + n, this.end);\n const r = new Pbf(this.buf, this.pos, end);\n\n this.pos = end;\n\n return r;\n }\n string(): string {\n const n = this.varint();\n const end = Math.min(this.pos + n, this.end);\n const s = decoder.decode(this.buf.subarray(this.pos, end));\n\n this.pos = end;\n\n return s;\n }\n float(): number {\n const v = this.pos + 4 <= this.end ? this.view().getFloat32(this.pos, true) : 0;\n\n this.pos += 4;\n\n return v;\n }\n double(): number {\n const v = this.pos + 8 <= this.end ? this.view().getFloat64(this.pos, true) : 0;\n\n this.pos += 8;\n\n return v;\n }\n private view(): DataView {\n return new DataView(this.buf.buffer, this.buf.byteOffset, this.buf.byteLength);\n }\n skip(wire: number): void {\n if (wire === 0) this.varint();\n else if (wire === 1) this.pos += 8;\n else if (wire === 2) this.pos += this.varint();\n else if (wire === 5) this.pos += 4;\n }\n get more(): boolean {\n return this.pos < this.end;\n }\n}\n\nconst decoder = new TextDecoder();\n\nconst value = (p: Pbf): Value => {\n let v: Value = '';\n\n while (p.more) {\n const tag = p.varint();\n\n switch (tag >> 3) {\n case 1:\n v = p.string();\n break;\n case 2:\n v = p.float();\n break;\n case 3:\n v = p.double();\n break;\n case 4:\n v = p.int64();\n break;\n case 5:\n v = p.varint();\n break;\n case 6:\n v = p.sint();\n break;\n case 7:\n v = p.varint() !== 0;\n break;\n default:\n p.skip(tag & 7);\n }\n }\n\n return v;\n};\n\n/** Point lists of a geometry's commands (MoveTo, LineTo, ClosePath) */\nconst geometry = (p: Pbf): number[][] => {\n const out: number[][] = [];\n let current: number[] | undefined;\n let [x, y] = [0, 0];\n\n while (p.more) {\n const command = p.varint();\n const id = command & 7;\n const count = command >> 3;\n\n if (id === 7) {\n // ClosePath: back to the first point\n if (current && current.length >= 2) current.push(current[0] ?? 0, current[1] ?? 0);\n continue;\n }\n // A count past the end (a truncated geometry) stops there\n for (let i = 0; i < count && p.more; i += 1) {\n x += p.sint();\n y += p.sint();\n if (id === 1) {\n current = [];\n out.push(current);\n }\n current?.push(x, y);\n }\n }\n\n return out;\n};\n\n/** Decodes a tile; only the layers in `wanted` (all if undefined) */\nexport const decode = (bytes: Uint8Array, wanted?: Set<string>): Map<string, TileLayer> => {\n const layers = new Map<string, TileLayer>();\n const tile = new Pbf(bytes);\n\n while (tile.more) {\n const tag = tile.varint();\n\n if (tag >> 3 !== 3) {\n tile.skip(tag & 7);\n continue;\n }\n\n const l = tile.sub();\n let name = '';\n let extent = 4096;\n const keys: string[] = [];\n const values: Value[] = [];\n const raw: Pbf[] = [];\n\n while (l.more) {\n const t = l.varint();\n\n switch (t >> 3) {\n case 1:\n name = l.string();\n break;\n case 2:\n raw.push(l.sub());\n break;\n case 3:\n keys.push(l.string());\n break;\n case 4:\n values.push(value(l.sub()));\n break;\n case 5:\n extent = l.varint();\n break;\n default:\n l.skip(t & 7);\n }\n }\n if (wanted && !wanted.has(name)) continue;\n\n const features: TileFeature[] = [];\n\n for (const f of raw) {\n let type: 1 | 2 | 3 = 1;\n const properties: Record<string, Value> = {};\n let geom: number[][] = [];\n\n while (f.more) {\n const t = f.varint();\n\n switch (t >> 3) {\n case 2: {\n const tags = f.sub();\n\n while (tags.more) {\n const k = keys[tags.varint()];\n const v = values[tags.varint()];\n\n if (k !== undefined && v !== undefined) properties[k] = v;\n }\n break;\n }\n case 3:\n type = Math.min(3, Math.max(1, f.varint())) as 1 | 2 | 3;\n break;\n case 4:\n geom = geometry(f.sub());\n break;\n default:\n f.skip(t & 7);\n }\n }\n features.push({ type, properties, geometry: geom });\n }\n layers.set(name, { extent, features });\n }\n\n return layers;\n};\n"]}