isard 0.2.1 → 0.4.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 (93) hide show
  1. package/CHANGELOG.md +93 -0
  2. package/README.md +8 -4
  3. package/dist/animation.d.ts +18 -0
  4. package/dist/animation.js +84 -0
  5. package/dist/animation.js.map +1 -0
  6. package/dist/basemap.worker.d.ts +26 -4
  7. package/dist/basemap.worker.js +2 -2
  8. package/dist/basemap.worker.js.map +9 -5
  9. package/dist/crs.d.ts +72 -0
  10. package/dist/crs.js +243 -0
  11. package/dist/crs.js.map +1 -0
  12. package/dist/decoder.worker.js +4 -4
  13. package/dist/decoder.worker.js.map +4 -4
  14. package/dist/engine-loader.d.ts +28 -0
  15. package/dist/engine-loader.js +112 -0
  16. package/dist/engine-loader.js.map +1 -0
  17. package/dist/features.d.ts +8 -0
  18. package/dist/features.js +17 -10
  19. package/dist/features.js.map +1 -1
  20. package/dist/geo.d.ts +16 -0
  21. package/dist/geo.js +32 -0
  22. package/dist/geo.js.map +1 -0
  23. package/dist/geoplateforme.d.ts +21 -5
  24. package/dist/geoplateforme.js +47 -12
  25. package/dist/geoplateforme.js.map +1 -1
  26. package/dist/glyphs.d.ts +13 -3
  27. package/dist/glyphs.js +26 -4
  28. package/dist/glyphs.js.map +1 -1
  29. package/dist/gpx.d.ts +11 -0
  30. package/dist/gpx.js +74 -0
  31. package/dist/gpx.js.map +1 -0
  32. package/dist/grid.d.ts +81 -0
  33. package/dist/grid.js +270 -0
  34. package/dist/grid.js.map +1 -0
  35. package/dist/icons.d.ts +146 -0
  36. package/dist/icons.js +333 -0
  37. package/dist/icons.js.map +1 -0
  38. package/dist/index.d.ts +11 -4
  39. package/dist/index.js +6 -1
  40. package/dist/index.js.map +1 -1
  41. package/dist/interaction.d.ts +0 -4
  42. package/dist/interaction.js +8 -4
  43. package/dist/interaction.js.map +1 -1
  44. package/dist/isard_bg.wasm +0 -0
  45. package/dist/isard_core_bg.wasm +0 -0
  46. package/dist/kml.d.ts +12 -0
  47. package/dist/kml.js +159 -0
  48. package/dist/kml.js.map +1 -0
  49. package/dist/layers.d.ts +89 -2
  50. package/dist/layers.js +171 -15
  51. package/dist/layers.js.map +1 -1
  52. package/dist/lru.d.ts +22 -0
  53. package/dist/lru.js +52 -0
  54. package/dist/lru.js.map +1 -0
  55. package/dist/map.d.ts +45 -7
  56. package/dist/map.js +138 -310
  57. package/dist/map.js.map +1 -1
  58. package/dist/resample.d.ts +41 -0
  59. package/dist/resample.js +164 -0
  60. package/dist/resample.js.map +1 -0
  61. package/dist/settings.d.ts +39 -0
  62. package/dist/settings.js +104 -0
  63. package/dist/settings.js.map +1 -0
  64. package/dist/symbols.d.ts +54 -9
  65. package/dist/symbols.js +278 -55
  66. package/dist/symbols.js.map +1 -1
  67. package/dist/terrain.d.ts +19 -7
  68. package/dist/terrain.js +40 -28
  69. package/dist/terrain.js.map +1 -1
  70. package/dist/topojson.d.ts +29 -0
  71. package/dist/topojson.js +66 -0
  72. package/dist/topojson.js.map +1 -0
  73. package/dist/types.d.ts +14 -6
  74. package/dist/types.js.map +1 -1
  75. package/dist/vectorstyle.d.ts +32 -3
  76. package/dist/vectorstyle.js.map +1 -1
  77. package/dist/vectortiles.d.ts +19 -7
  78. package/dist/vectortiles.js +117 -69
  79. package/dist/vectortiles.js.map +1 -1
  80. package/dist/wasm/isard.d.ts +55 -7
  81. package/dist/wasm/isard.js +117 -6
  82. package/dist/wasm/isard_core.d.ts +29 -4
  83. package/dist/wasm/isard_core.js +84 -5
  84. package/dist/wmts.d.ts +14 -0
  85. package/dist/wmts.js +76 -0
  86. package/dist/wmts.js.map +1 -0
  87. package/dist/xml.d.ts +26 -0
  88. package/dist/xml.js +109 -0
  89. package/dist/xml.js.map +1 -0
  90. package/package.json +1 -1
  91. package/dist/equirectangular.d.ts +0 -35
  92. package/dist/equirectangular.js +0 -143
  93. package/dist/equirectangular.js.map +0 -1
@@ -29,6 +29,18 @@ export class Engine {
29
29
  }
30
30
  return ret[0] >>> 0;
31
31
  }
32
+ /**
33
+ * A layer drawn by the page: `render()` is called at its place in every frame (`customMatrix` gives the
34
+ * matrices of that frame meanwhile); `depth`: with the depth buffer of the 3D layers (`3d` mode), else over
35
+ * what is drawn before it
36
+ * @param {() => void} render
37
+ * @param {boolean} depth
38
+ * @returns {number}
39
+ */
40
+ addCustomLayer(render, depth) {
41
+ const ret = wasm.engine_addCustomLayer(this.__wbg_ptr, render, depth);
42
+ return ret >>> 0;
43
+ }
32
44
  /**
33
45
  * An empty extrusion layer: its blocks come in batches (`setExtrusionBatch`)
34
46
  * @returns {number}
@@ -110,6 +122,26 @@ export class Engine {
110
122
  }
111
123
  return ret[0] >>> 0;
112
124
  }
125
+ /**
126
+ * A glTF / GLB model (its URL, a `blob:` one for data of the page) drawn at each instance of `instances`
127
+ * (`INSTANCE_NUMBERS` numbers each: longitude, latitude, altitude, heading, pitch, roll in degrees, scale);
128
+ * `ground`: altitudes above the relief, else above the ellipsoid
129
+ * @param {string} url
130
+ * @param {Float64Array} instances
131
+ * @param {boolean} ground
132
+ * @returns {number}
133
+ */
134
+ addModels(url, instances, ground) {
135
+ const ptr0 = passStringToWasm0(url, wasm.__wbindgen_malloc, wasm.__wbindgen_realloc);
136
+ const len0 = WASM_VECTOR_LEN;
137
+ const ptr1 = passArrayF64ToWasm0(instances, wasm.__wbindgen_malloc);
138
+ const len1 = WASM_VECTOR_LEN;
139
+ const ret = wasm.engine_addModels(this.__wbg_ptr, ptr0, len0, ptr1, len1, ground);
140
+ if (ret[2]) {
141
+ throw takeFromExternrefTable0(ret[1]);
142
+ }
143
+ return ret[0] >>> 0;
144
+ }
113
145
  /**
114
146
  * Network of `mercator.length / 2` nodes (Mercator [0, 1], y towards the south, interleaved: converted by the
115
147
  * JavaScript side, where `Math.tan` and `Math.log` are much faster than in WebAssembly) and `edges.length / 2`
@@ -213,6 +245,24 @@ export class Engine {
213
245
  clearPreload() {
214
246
  wasm.engine_clearPreload(this.__wbg_ptr);
215
247
  }
248
+ /**
249
+ * Model-view-projection matrix (16 numbers, column-major, for `uniformMatrix4fv`) of the local frame at a
250
+ * longitude, latitude (degrees) and altitude (metres): x east, y north, z up, in metres. Undefined outside the
251
+ * callback of a custom layer. Static: the engine is borrowed while it draws
252
+ * @param {number} lon
253
+ * @param {number} lat
254
+ * @param {number} altitude
255
+ * @returns {Float32Array | undefined}
256
+ */
257
+ static customMatrix(lon, lat, altitude) {
258
+ const ret = wasm.engine_customMatrix(lon, lat, altitude);
259
+ let v1;
260
+ if (ret[0] !== 0) {
261
+ v1 = getArrayF32FromWasm0(ret[0], ret[1]).slice();
262
+ wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
263
+ }
264
+ return v1;
265
+ }
216
266
  /**
217
267
  * Position under a screen point (CSS pixels), undefined above the horizon; on the relief itself
218
268
  * @param {number} x
@@ -401,7 +451,7 @@ export class Engine {
401
451
  * atmosphere around the globe (RGB 0-1 and its strength, 4 numbers; `undefined` for an airless body), and the
402
452
  * lowest and highest altitudes of its ground (metres: what its relief may raise into view). WGS 84, the Earth's
403
453
  * blue halo and the range of its relief worldwide (-450 m to 8900 m) by default; set before the layers and the
404
- * relief, whose shaders may take its size (`ISARD_EARTH` of the ground layers)
454
+ * relief, whose shaders may take its size (`ISARD_CIRCUMFERENCE` of the ground layers)
405
455
  * @param {number} radius
406
456
  * @param {number} flattening
407
457
  * @param {Float32Array | null | undefined} halo
@@ -667,6 +717,18 @@ export class Engine {
667
717
  setGroundVisible(id, visible) {
668
718
  wasm.engine_setGroundVisible(this.__wbg_ptr, id, visible);
669
719
  }
720
+ /**
721
+ * The icon atlas shared by the symbol layers: `width` × `height` RGBA texels, premultiplied, allocated again
722
+ * and empty (`updateIconAtlas` fills it)
723
+ * @param {number} width
724
+ * @param {number} height
725
+ */
726
+ setIconAtlas(width, height) {
727
+ const ret = wasm.engine_setIconAtlas(this.__wbg_ptr, width, height);
728
+ if (ret[1]) {
729
+ throw takeFromExternrefTable0(ret[0]);
730
+ }
731
+ }
670
732
  /**
671
733
  * How tiles load and show: `true`, immediately (everything visible loads, no fade, the default); `false`,
672
734
  * smoothly (levels skipped during flights, off-center tiles waiting while the camera moves, fade-in)
@@ -710,6 +772,17 @@ export class Engine {
710
772
  setMaxPitch(max) {
711
773
  wasm.engine_setMaxPitch(this.__wbg_ptr, max);
712
774
  }
775
+ /**
776
+ * Replaces the instances of a model layer (as for `addModels`) and the reference of their altitudes
777
+ * @param {number} id
778
+ * @param {Float64Array} instances
779
+ * @param {boolean} ground
780
+ */
781
+ setModelInstances(id, instances, ground) {
782
+ const ptr0 = passArrayF64ToWasm0(instances, wasm.__wbindgen_malloc);
783
+ const len0 = WASM_VECTOR_LEN;
784
+ wasm.engine_setModelInstances(this.__wbg_ptr, id, ptr0, len0, ground);
785
+ }
713
786
  /**
714
787
  * Costs of a network's edges (see `addNetwork`), when the way it is travelled changes; null: interpolated values
715
788
  * @param {number} id
@@ -795,9 +868,9 @@ export class Engine {
795
868
  wasm.engine_setSymbolLayer(this.__wbg_ptr, id, ptr0, len0, ptr1, len1, min_zoom, max_zoom, visible);
796
869
  }
797
870
  /**
798
- * Labels of a symbol layer, shaped by the page: anchors (Mercator, interleaved), boxes (min x, min y, max x, max y,
799
- * CSS pixels from the anchor), styles (20 floats each, see `LABEL_FLOATS`) and glyph quads (10 floats each: label, x, y, width, height from the anchor, atlas u0, v0, u1, v1 in
800
- * texels, font scale)
871
+ * Labels of a symbol layer, shaped by the page: anchors (Mercator, interleaved), their texts' boxes (min x, min y,
872
+ * max x, max y, CSS pixels from the anchor), styles (36 floats each, see `LABEL_FLOATS`) and glyph and icon quads
873
+ * (11 floats each, see `QUAD_FLOATS`)
801
874
  * @param {number} id
802
875
  * @param {Float64Array} anchors
803
876
  * @param {Float32Array} boxes
@@ -939,6 +1012,19 @@ export class Engine {
939
1012
  throw takeFromExternrefTable0(ret[0]);
940
1013
  }
941
1014
  }
1015
+ /**
1016
+ * A region of the icon atlas: `width` × `height` RGBA texels (premultiplied) at (`x`, `y`)
1017
+ * @param {number} x
1018
+ * @param {number} y
1019
+ * @param {number} width
1020
+ * @param {number} height
1021
+ * @param {Uint8Array} data
1022
+ */
1023
+ updateIconAtlas(x, y, width, height, data) {
1024
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
1025
+ const len0 = WASM_VECTOR_LEN;
1026
+ wasm.engine_updateIconAtlas(this.__wbg_ptr, x, y, width, height, ptr0, len0);
1027
+ }
942
1028
  /**
943
1029
  * @param {number} delta
944
1030
  * @param {number} x
@@ -952,7 +1038,8 @@ if (Symbol.dispose) Engine.prototype[Symbol.dispose] = Engine.prototype.free;
952
1038
 
953
1039
  /**
954
1040
  * Decodes a `.b3dm` / `.glb` tile: `{ anchor: Float64Array(3), primitives: [{ vertices: Float32Array (x, y, z, u,
955
- * v per vertex, relative to the anchor), indices: Uint32Array, image?: Uint8Array, mime?: string }] }`.
1041
+ * v per vertex, relative to the anchor), indices: Uint32Array, image?: Uint8Array, mime?: string, color?:
1042
+ * Float32Array (the material's base color, when not white) }] }`.
956
1043
  * `transform`: the tile's world transform (16 numbers, column-major).
957
1044
  * `draco`: the decoded geometries of its Draco primitives (`dracoRequests`), if any.
958
1045
  * @param {Uint8Array} bytes
@@ -1096,6 +1183,12 @@ function __wbg_get_imports() {
1096
1183
  __wbg_bindVertexArray_f58af0a346185ec5: function(arg0, arg1) {
1097
1184
  arg0.bindVertexArray(arg1);
1098
1185
  },
1186
+ __wbg_blendEquation_5fb8aee6a55cf900: function(arg0, arg1) {
1187
+ arg0.blendEquation(arg1 >>> 0);
1188
+ },
1189
+ __wbg_blendEquation_d21914e937b14896: function(arg0, arg1) {
1190
+ arg0.blendEquation(arg1 >>> 0);
1191
+ },
1099
1192
  __wbg_blendFuncSeparate_28abe082febb1a26: function(arg0, arg1, arg2, arg3, arg4) {
1100
1193
  arg0.blendFuncSeparate(arg1 >>> 0, arg2 >>> 0, arg3 >>> 0, arg4 >>> 0);
1101
1194
  },
@@ -1252,6 +1345,12 @@ function __wbg_get_imports() {
1252
1345
  const ret = arg0.createVertexArray();
1253
1346
  return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
1254
1347
  },
1348
+ __wbg_cullFace_12123c1c97f1ba2c: function(arg0, arg1) {
1349
+ arg0.cullFace(arg1 >>> 0);
1350
+ },
1351
+ __wbg_cullFace_1a01f0b6d5aeb687: function(arg0, arg1) {
1352
+ arg0.cullFace(arg1 >>> 0);
1353
+ },
1255
1354
  __wbg_deleteBuffer_070e58aaaf2a7a8b: function(arg0, arg1) {
1256
1355
  arg0.deleteBuffer(arg1);
1257
1356
  },
@@ -1309,6 +1408,12 @@ function __wbg_get_imports() {
1309
1408
  __wbg_depthMask_0d7c3dec3b8405ee: function(arg0, arg1) {
1310
1409
  arg0.depthMask(arg1 !== 0);
1311
1410
  },
1411
+ __wbg_depthRange_24c7969249461e8e: function(arg0, arg1, arg2) {
1412
+ arg0.depthRange(arg1, arg2);
1413
+ },
1414
+ __wbg_depthRange_6a4e169ccf314148: function(arg0, arg1, arg2) {
1415
+ arg0.depthRange(arg1, arg2);
1416
+ },
1312
1417
  __wbg_detachShader_1ed15fc2d289cf15: function(arg0, arg1, arg2) {
1313
1418
  arg0.detachShader(arg1, arg2);
1314
1419
  },
@@ -1885,6 +1990,12 @@ function __wbg_get_imports() {
1885
1990
  __wbg_stencilFunc_bab7e0b7c443f093: function(arg0, arg1, arg2, arg3) {
1886
1991
  arg0.stencilFunc(arg1 >>> 0, arg2, arg3 >>> 0);
1887
1992
  },
1993
+ __wbg_stencilMask_9e18cc018897c747: function(arg0, arg1) {
1994
+ arg0.stencilMask(arg1 >>> 0);
1995
+ },
1996
+ __wbg_stencilMask_a22be64c66abd825: function(arg0, arg1) {
1997
+ arg0.stencilMask(arg1 >>> 0);
1998
+ },
1888
1999
  __wbg_stencilOpSeparate_7d01185cbdb89d99: function(arg0, arg1, arg2, arg3, arg4) {
1889
2000
  arg0.stencilOpSeparate(arg1 >>> 0, arg2 >>> 0, arg3 >>> 0, arg4 >>> 0);
1890
2001
  },
@@ -2094,7 +2205,7 @@ function __wbg_get_imports() {
2094
2205
  return ret;
2095
2206
  },
2096
2207
  __wbindgen_generic_0000000000000001: function(arg0, arg1) {
2097
- // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 147, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
2208
+ // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 168, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
2098
2209
  const ret = makeMutClosure(arg0, arg1, wasm_bindgen_2e566c63402fe7fa___convert__closures_____invoke___wasm_bindgen_2e566c63402fe7fa___JsValue__core_37ee0ce0c4cd57d5___result__Result_____wasm_bindgen_2e566c63402fe7fa___JsError___true_);
2099
2210
  return ret;
2100
2211
  },
@@ -68,6 +68,12 @@ export class Engine {
68
68
  * Circle layer of `feature_count` features: points (Mercator [0, 1], interleaved) and the feature of each
69
69
  */
70
70
  addCircles(points: Float64Array, feature: Uint32Array, feature_count: number): number;
71
+ /**
72
+ * A layer drawn by the page: `render()` is called at its place in every frame (`customMatrix` gives the
73
+ * matrices of that frame meanwhile); `depth`: with the depth buffer of the 3D layers (`3d` mode), else over
74
+ * what is drawn before it
75
+ */
76
+ addCustomLayer(render: () => void, depth: boolean): number;
71
77
  /**
72
78
  * An empty extrusion layer: its blocks come in batches (`setExtrusionBatch`)
73
79
  */
@@ -114,6 +120,12 @@ export class Engine {
114
120
  bounds(): Float64Array;
115
121
  camera(): Camera;
116
122
  clearPreload(): void;
123
+ /**
124
+ * Model-view-projection matrix (16 numbers, column-major, for `uniformMatrix4fv`) of the local frame at a
125
+ * longitude, latitude (degrees) and altitude (metres): x east, y north, z up, in metres. Undefined outside the
126
+ * callback of a custom layer. Static: the engine is borrowed while it draws
127
+ */
128
+ static customMatrix(lon: number, lat: number, altitude: number): Float32Array | undefined;
117
129
  /**
118
130
  * Position under a screen point (CSS pixels), undefined above the horizon; on the relief itself
119
131
  */
@@ -193,7 +205,7 @@ export class Engine {
193
205
  * atmosphere around the globe (RGB 0-1 and its strength, 4 numbers; `undefined` for an airless body), and the
194
206
  * lowest and highest altitudes of its ground (metres: what its relief may raise into view). WGS 84, the Earth's
195
207
  * blue halo and the range of its relief worldwide (-450 m to 8900 m) by default; set before the layers and the
196
- * relief, whose shaders may take its size (`ISARD_EARTH` of the ground layers)
208
+ * relief, whose shaders may take its size (`ISARD_CIRCUMFERENCE` of the ground layers)
197
209
  */
198
210
  setBody(radius: number, flattening: number, halo: Float32Array | null | undefined, lowest: number, highest: number): void;
199
211
  setCamera(lon: number, lat: number, zoom: number, pitch: number, bearing: number): void;
@@ -273,6 +285,11 @@ export class Engine {
273
285
  */
274
286
  setGroundUniform(id: number, name: string, values: Float64Array): void;
275
287
  setGroundVisible(id: number, visible: boolean): void;
288
+ /**
289
+ * The icon atlas shared by the symbol layers: `width` × `height` RGBA texels, premultiplied, allocated again
290
+ * and empty (`updateIconAtlas` fills it)
291
+ */
292
+ setIconAtlas(width: number, height: number): void;
276
293
  /**
277
294
  * How tiles load and show: `true`, immediately (everything visible loads, no fade, the default); `false`,
278
295
  * smoothly (levels skipped during flights, off-center tiles waiting while the camera moves, fade-in)
@@ -323,9 +340,9 @@ export class Engine {
323
340
  */
324
341
  setSymbolLayer(id: number, size: Float32Array, opacity: Float32Array, min_zoom: number, max_zoom: number, visible: boolean): void;
325
342
  /**
326
- * Labels of a symbol layer, shaped by the page: anchors (Mercator, interleaved), boxes (min x, min y, max x, max y,
327
- * CSS pixels from the anchor), styles (20 floats each, see `LABEL_FLOATS`) and glyph quads (10 floats each: label, x, y, width, height from the anchor, atlas u0, v0, u1, v1 in
328
- * texels, font scale)
343
+ * Labels of a symbol layer, shaped by the page: anchors (Mercator, interleaved), their texts' boxes (min x, min y,
344
+ * max x, max y, CSS pixels from the anchor), styles (36 floats each, see `LABEL_FLOATS`) and glyph and icon quads
345
+ * (11 floats each, see `QUAD_FLOATS`)
329
346
  */
330
347
  setSymbols(id: number, anchors: Float64Array, boxes: Float32Array, styles: Float32Array, quads: Float32Array): void;
331
348
  /**
@@ -356,6 +373,10 @@ export class Engine {
356
373
  * Replaces a region of a ground layer's texture (one layer of a 2D array)
357
374
  */
358
375
  updateGroundTexture(id: number, name: string, x: number, y: number, layer: number, width: number, height: number, data: Uint8Array): void;
376
+ /**
377
+ * A region of the icon atlas: `width` × `height` RGBA texels (premultiplied) at (`x`, `y`)
378
+ */
379
+ updateIconAtlas(x: number, y: number, width: number, height: number, data: Uint8Array): void;
359
380
  zoomAt(delta: number, x: number, y: number): void;
360
381
  }
361
382
 
@@ -365,6 +386,7 @@ export interface InitOutput {
365
386
  readonly memory: WebAssembly.Memory;
366
387
  readonly __wbg_engine_free: (a: number, b: number) => void;
367
388
  readonly engine_addCircles: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number, number];
389
+ readonly engine_addCustomLayer: (a: number, b: any, c: number) => number;
368
390
  readonly engine_addExtrusions: (a: number) => [number, number, number];
369
391
  readonly engine_addFills: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number) => [number, number, number];
370
392
  readonly engine_addGround: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number) => [number, number, number];
@@ -375,6 +397,7 @@ export interface InitOutput {
375
397
  readonly engine_bounds: (a: number) => [number, number];
376
398
  readonly engine_camera: (a: number) => any;
377
399
  readonly engine_clearPreload: (a: number) => void;
400
+ readonly engine_customMatrix: (a: number, b: number, c: number) => [number, number];
378
401
  readonly engine_ground: (a: number, b: number, c: number) => any;
379
402
  readonly engine_linkExtrusionNetwork: (a: number, b: number, c: number, d: number) => void;
380
403
  readonly engine_moveLayer: (a: number, b: number, c: number) => void;
@@ -413,6 +436,7 @@ export interface InitOutput {
413
436
  readonly engine_setGroundTexture: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number, l: number) => [number, number];
414
437
  readonly engine_setGroundUniform: (a: number, b: number, c: number, d: number, e: number, f: number) => [number, number];
415
438
  readonly engine_setGroundVisible: (a: number, b: number, c: number) => void;
439
+ readonly engine_setIconAtlas: (a: number, b: number, c: number) => [number, number];
416
440
  readonly engine_setImmediateLoading: (a: number, b: number) => void;
417
441
  readonly engine_setLineDash: (a: number, b: number, c: number, d: number) => void;
418
442
  readonly engine_setLines: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => [number, number];
@@ -432,6 +456,7 @@ export interface InitOutput {
432
456
  readonly engine_updateGlyphAtlas: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
433
457
  readonly engine_updateGlyphPage: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number) => void;
434
458
  readonly engine_updateGroundTexture: (a: number, b: number, c: number, d: number, e: number, f: number, g: number, h: number, i: number, j: number, k: number) => [number, number];
459
+ readonly engine_updateIconAtlas: (a: number, b: number, c: number, d: number, e: number, f: number, g: number) => void;
435
460
  readonly engine_zoomAt: (a: number, b: number, c: number, d: number) => void;
436
461
  readonly wasm_bindgen_2e566c63402fe7fa___convert__closures_____invoke___js_sys_b1e1c29ba6b0e6b3___Function_fn_wasm_bindgen_2e566c63402fe7fa___JsValue_____wasm_bindgen_2e566c63402fe7fa___sys__Undefined___js_sys_b1e1c29ba6b0e6b3___Function_fn_wasm_bindgen_2e566c63402fe7fa___JsValue_____wasm_bindgen_2e566c63402fe7fa___sys__Undefined_______true_: (a: number, b: number, c: any, d: any) => void;
437
462
  readonly wasm_bindgen_2e566c63402fe7fa___convert__closures_____invoke___wasm_bindgen_2e566c63402fe7fa___JsValue__core_37ee0ce0c4cd57d5___result__Result_____wasm_bindgen_2e566c63402fe7fa___JsError___true_: (a: number, b: number, c: any) => [number, number];
@@ -29,6 +29,18 @@ export class Engine {
29
29
  }
30
30
  return ret[0] >>> 0;
31
31
  }
32
+ /**
33
+ * A layer drawn by the page: `render()` is called at its place in every frame (`customMatrix` gives the
34
+ * matrices of that frame meanwhile); `depth`: with the depth buffer of the 3D layers (`3d` mode), else over
35
+ * what is drawn before it
36
+ * @param {() => void} render
37
+ * @param {boolean} depth
38
+ * @returns {number}
39
+ */
40
+ addCustomLayer(render, depth) {
41
+ const ret = wasm.engine_addCustomLayer(this.__wbg_ptr, render, depth);
42
+ return ret >>> 0;
43
+ }
32
44
  /**
33
45
  * An empty extrusion layer: its blocks come in batches (`setExtrusionBatch`)
34
46
  * @returns {number}
@@ -197,6 +209,24 @@ export class Engine {
197
209
  clearPreload() {
198
210
  wasm.engine_clearPreload(this.__wbg_ptr);
199
211
  }
212
+ /**
213
+ * Model-view-projection matrix (16 numbers, column-major, for `uniformMatrix4fv`) of the local frame at a
214
+ * longitude, latitude (degrees) and altitude (metres): x east, y north, z up, in metres. Undefined outside the
215
+ * callback of a custom layer. Static: the engine is borrowed while it draws
216
+ * @param {number} lon
217
+ * @param {number} lat
218
+ * @param {number} altitude
219
+ * @returns {Float32Array | undefined}
220
+ */
221
+ static customMatrix(lon, lat, altitude) {
222
+ const ret = wasm.engine_customMatrix(lon, lat, altitude);
223
+ let v1;
224
+ if (ret[0] !== 0) {
225
+ v1 = getArrayF32FromWasm0(ret[0], ret[1]).slice();
226
+ wasm.__wbindgen_free(ret[0], ret[1] * 4, 4);
227
+ }
228
+ return v1;
229
+ }
200
230
  /**
201
231
  * Position under a screen point (CSS pixels), undefined above the horizon; on the relief itself
202
232
  * @param {number} x
@@ -385,7 +415,7 @@ export class Engine {
385
415
  * atmosphere around the globe (RGB 0-1 and its strength, 4 numbers; `undefined` for an airless body), and the
386
416
  * lowest and highest altitudes of its ground (metres: what its relief may raise into view). WGS 84, the Earth's
387
417
  * blue halo and the range of its relief worldwide (-450 m to 8900 m) by default; set before the layers and the
388
- * relief, whose shaders may take its size (`ISARD_EARTH` of the ground layers)
418
+ * relief, whose shaders may take its size (`ISARD_CIRCUMFERENCE` of the ground layers)
389
419
  * @param {number} radius
390
420
  * @param {number} flattening
391
421
  * @param {Float32Array | null | undefined} halo
@@ -651,6 +681,18 @@ export class Engine {
651
681
  setGroundVisible(id, visible) {
652
682
  wasm.engine_setGroundVisible(this.__wbg_ptr, id, visible);
653
683
  }
684
+ /**
685
+ * The icon atlas shared by the symbol layers: `width` × `height` RGBA texels, premultiplied, allocated again
686
+ * and empty (`updateIconAtlas` fills it)
687
+ * @param {number} width
688
+ * @param {number} height
689
+ */
690
+ setIconAtlas(width, height) {
691
+ const ret = wasm.engine_setIconAtlas(this.__wbg_ptr, width, height);
692
+ if (ret[1]) {
693
+ throw takeFromExternrefTable0(ret[0]);
694
+ }
695
+ }
654
696
  /**
655
697
  * How tiles load and show: `true`, immediately (everything visible loads, no fade, the default); `false`,
656
698
  * smoothly (levels skipped during flights, off-center tiles waiting while the camera moves, fade-in)
@@ -779,9 +821,9 @@ export class Engine {
779
821
  wasm.engine_setSymbolLayer(this.__wbg_ptr, id, ptr0, len0, ptr1, len1, min_zoom, max_zoom, visible);
780
822
  }
781
823
  /**
782
- * Labels of a symbol layer, shaped by the page: anchors (Mercator, interleaved), boxes (min x, min y, max x, max y,
783
- * CSS pixels from the anchor), styles (20 floats each, see `LABEL_FLOATS`) and glyph quads (10 floats each: label, x, y, width, height from the anchor, atlas u0, v0, u1, v1 in
784
- * texels, font scale)
824
+ * Labels of a symbol layer, shaped by the page: anchors (Mercator, interleaved), their texts' boxes (min x, min y,
825
+ * max x, max y, CSS pixels from the anchor), styles (36 floats each, see `LABEL_FLOATS`) and glyph and icon quads
826
+ * (11 floats each, see `QUAD_FLOATS`)
785
827
  * @param {number} id
786
828
  * @param {Float64Array} anchors
787
829
  * @param {Float32Array} boxes
@@ -888,6 +930,19 @@ export class Engine {
888
930
  throw takeFromExternrefTable0(ret[0]);
889
931
  }
890
932
  }
933
+ /**
934
+ * A region of the icon atlas: `width` × `height` RGBA texels (premultiplied) at (`x`, `y`)
935
+ * @param {number} x
936
+ * @param {number} y
937
+ * @param {number} width
938
+ * @param {number} height
939
+ * @param {Uint8Array} data
940
+ */
941
+ updateIconAtlas(x, y, width, height, data) {
942
+ const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_malloc);
943
+ const len0 = WASM_VECTOR_LEN;
944
+ wasm.engine_updateIconAtlas(this.__wbg_ptr, x, y, width, height, ptr0, len0);
945
+ }
891
946
  /**
892
947
  * @param {number} delta
893
948
  * @param {number} x
@@ -998,6 +1053,12 @@ function __wbg_get_imports() {
998
1053
  __wbg_bindVertexArray_f58af0a346185ec5: function(arg0, arg1) {
999
1054
  arg0.bindVertexArray(arg1);
1000
1055
  },
1056
+ __wbg_blendEquation_5fb8aee6a55cf900: function(arg0, arg1) {
1057
+ arg0.blendEquation(arg1 >>> 0);
1058
+ },
1059
+ __wbg_blendEquation_d21914e937b14896: function(arg0, arg1) {
1060
+ arg0.blendEquation(arg1 >>> 0);
1061
+ },
1001
1062
  __wbg_blendFuncSeparate_28abe082febb1a26: function(arg0, arg1, arg2, arg3, arg4) {
1002
1063
  arg0.blendFuncSeparate(arg1 >>> 0, arg2 >>> 0, arg3 >>> 0, arg4 >>> 0);
1003
1064
  },
@@ -1135,6 +1196,12 @@ function __wbg_get_imports() {
1135
1196
  const ret = arg0.createVertexArray();
1136
1197
  return isLikeNone(ret) ? 0 : addToExternrefTable0(ret);
1137
1198
  },
1199
+ __wbg_cullFace_12123c1c97f1ba2c: function(arg0, arg1) {
1200
+ arg0.cullFace(arg1 >>> 0);
1201
+ },
1202
+ __wbg_cullFace_1a01f0b6d5aeb687: function(arg0, arg1) {
1203
+ arg0.cullFace(arg1 >>> 0);
1204
+ },
1138
1205
  __wbg_deleteBuffer_070e58aaaf2a7a8b: function(arg0, arg1) {
1139
1206
  arg0.deleteBuffer(arg1);
1140
1207
  },
@@ -1192,6 +1259,12 @@ function __wbg_get_imports() {
1192
1259
  __wbg_depthMask_0d7c3dec3b8405ee: function(arg0, arg1) {
1193
1260
  arg0.depthMask(arg1 !== 0);
1194
1261
  },
1262
+ __wbg_depthRange_24c7969249461e8e: function(arg0, arg1, arg2) {
1263
+ arg0.depthRange(arg1, arg2);
1264
+ },
1265
+ __wbg_depthRange_6a4e169ccf314148: function(arg0, arg1, arg2) {
1266
+ arg0.depthRange(arg1, arg2);
1267
+ },
1195
1268
  __wbg_detachShader_1ed15fc2d289cf15: function(arg0, arg1, arg2) {
1196
1269
  arg0.detachShader(arg1, arg2);
1197
1270
  },
@@ -1653,6 +1726,12 @@ function __wbg_get_imports() {
1653
1726
  __wbg_stencilFunc_bab7e0b7c443f093: function(arg0, arg1, arg2, arg3) {
1654
1727
  arg0.stencilFunc(arg1 >>> 0, arg2, arg3 >>> 0);
1655
1728
  },
1729
+ __wbg_stencilMask_9e18cc018897c747: function(arg0, arg1) {
1730
+ arg0.stencilMask(arg1 >>> 0);
1731
+ },
1732
+ __wbg_stencilMask_a22be64c66abd825: function(arg0, arg1) {
1733
+ arg0.stencilMask(arg1 >>> 0);
1734
+ },
1656
1735
  __wbg_stencilOpSeparate_7d01185cbdb89d99: function(arg0, arg1, arg2, arg3, arg4) {
1657
1736
  arg0.stencilOpSeparate(arg1 >>> 0, arg2 >>> 0, arg3 >>> 0, arg4 >>> 0);
1658
1737
  },
@@ -1856,7 +1935,7 @@ function __wbg_get_imports() {
1856
1935
  return ret;
1857
1936
  },
1858
1937
  __wbindgen_generic_0000000000000001: function(arg0, arg1) {
1859
- // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 77, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
1938
+ // Cast intrinsic for `Closure(Closure { owned: true, function: Function { arguments: [Externref], shim_idx: 87, ret: Result(Unit), inner_ret: Some(Result(Unit)) }, mutable: true }) -> Externref`.
1860
1939
  const ret = makeMutClosure(arg0, arg1, wasm_bindgen_2e566c63402fe7fa___convert__closures_____invoke___wasm_bindgen_2e566c63402fe7fa___JsValue__core_37ee0ce0c4cd57d5___result__Result_____wasm_bindgen_2e566c63402fe7fa___JsError___true_);
1861
1940
  return ret;
1862
1941
  },
package/dist/wmts.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import type { TileGrid } from './grid.ts';
2
+ /**
3
+ * The tile grid of `layer` in the capabilities document `xml`: its tile matrix set `matrixSet` (default the layer's
4
+ * first), with the layer's tile limits and longitude-latitude extent. Throws if the layer or the set is missing
5
+ */
6
+ export declare function parseWmtsGrid(xml: string, layer: string, matrixSet?: string): TileGrid;
7
+ /**
8
+ * The tile grid of a WMTS layer, from the service's capabilities at `capabilities` (fetched with CORS), for
9
+ * `addRaster`: `await wmtsGrid('https://…/wmts?SERVICE=WMTS&REQUEST=GetCapabilities', 'LAYER', 'MATRIXSET')`. The
10
+ * raster's URL writes the matrix set, {z} for the matrix, {x} and {y} for the column and the row
11
+ */
12
+ export declare function wmtsGrid(capabilities: string | URL, layer: string, matrixSet?: string, options?: {
13
+ signal?: AbortSignal;
14
+ }): Promise<TileGrid>;
package/dist/wmts.js ADDED
@@ -0,0 +1,76 @@
1
+ /**
2
+ * The tile grid of a WMTS layer, read from the service's capabilities: its tile matrix set (CRS, levels, origin, tile
3
+ * sizes), the layer's limits in it and its extent, for `addRaster({ url, grid })`.
4
+ */
5
+ import { epsgCode, isGeographic } from "./crs.js";
6
+ import { child, children, childText, parseXml } from "./xml.js";
7
+ /** Metres per degree, as WMTS counts the scale of a grid in degrees (OGC 07-057r7, 6.1) */
8
+ const METRES_PER_DEGREE = (2 * Math.PI * 6378137) / 360;
9
+ /** The size of a pixel by which WMTS turns scale denominators into resolutions, metres */
10
+ const PIXEL = 0.00028;
11
+ const numbers = (text) => (text ?? '').trim().split(/\s+/).map(Number);
12
+ /**
13
+ * The tile grid of `layer` in the capabilities document `xml`: its tile matrix set `matrixSet` (default the layer's
14
+ * first), with the layer's tile limits and longitude-latitude extent. Throws if the layer or the set is missing
15
+ */
16
+ export function parseWmtsGrid(xml, layer, matrixSet) {
17
+ const contents = child(parseXml(xml), 'Contents');
18
+ const entry = children(contents, 'Layer').find((l) => childText(l, 'Identifier') === layer);
19
+ if (!entry)
20
+ throw new Error(`isard: no WMTS layer ${layer}`);
21
+ const links = children(entry, 'TileMatrixSetLink');
22
+ const link = matrixSet === undefined ? links[0] : links.find((l) => childText(l, 'TileMatrixSet') === matrixSet);
23
+ const name = childText(link, 'TileMatrixSet');
24
+ const set = children(contents, 'TileMatrixSet').find((s) => childText(s, 'Identifier') === name);
25
+ if (!name || !set)
26
+ throw new Error(`isard: no tile matrix set ${matrixSet ?? ''} for the WMTS layer ${layer}`);
27
+ const crs = childText(set, 'SupportedCRS') ?? '';
28
+ const geographic = isGeographic(crs);
29
+ // EPSG's geographic CRSs have their latitude first (CRS:84 and the IGN's WGS84G do not)
30
+ const latFirst = geographic && epsgCode(crs) === 4326 && /EPSG/i.test(crs);
31
+ const unit = geographic ? METRES_PER_DEGREE : 1;
32
+ const limits = new Map();
33
+ for (const l of children(child(link, 'TileMatrixSetLimits'), 'TileMatrixLimits')) {
34
+ const [minRow, maxRow, minCol, maxCol] = ['MinTileRow', 'MaxTileRow', 'MinTileCol', 'MaxTileCol'].map((k) => Number(childText(l, k)));
35
+ limits.set(childText(l, 'TileMatrix') ?? '', [minCol, minRow, maxCol, maxRow]);
36
+ }
37
+ const matrices = children(set, 'TileMatrix').map((m) => {
38
+ const id = childText(m, 'Identifier') ?? '';
39
+ const [a = 0, b = 0] = numbers(childText(m, 'TopLeftCorner'));
40
+ const limit = limits.get(id);
41
+ return {
42
+ id,
43
+ resolution: (Number(childText(m, 'ScaleDenominator')) * PIXEL) / unit,
44
+ origin: latFirst ? [b, a] : [a, b],
45
+ tileWidth: Number(childText(m, 'TileWidth') ?? 256),
46
+ tileHeight: Number(childText(m, 'TileHeight') ?? 256),
47
+ matrixWidth: Number(childText(m, 'MatrixWidth') ?? Infinity),
48
+ matrixHeight: Number(childText(m, 'MatrixHeight') ?? Infinity),
49
+ ...(limit ? { limits: limit } : {}),
50
+ };
51
+ });
52
+ // A layer's limits leave out the matrices it does not have
53
+ const served = limits.size > 0 ? matrices.filter((m) => limits.has(String(m.id))) : matrices;
54
+ const box = child(entry, 'WGS84BoundingBox');
55
+ const [west, south] = numbers(childText(box, 'LowerCorner'));
56
+ const [east, north] = numbers(childText(box, 'UpperCorner'));
57
+ const bounds = [west, south, east, north];
58
+ return {
59
+ crs,
60
+ matrices: served,
61
+ name,
62
+ ...(bounds.every(Number.isFinite) ? { bounds: bounds } : {}),
63
+ };
64
+ }
65
+ /**
66
+ * The tile grid of a WMTS layer, from the service's capabilities at `capabilities` (fetched with CORS), for
67
+ * `addRaster`: `await wmtsGrid('https://…/wmts?SERVICE=WMTS&REQUEST=GetCapabilities', 'LAYER', 'MATRIXSET')`. The
68
+ * raster's URL writes the matrix set, {z} for the matrix, {x} and {y} for the column and the row
69
+ */
70
+ export async function wmtsGrid(capabilities, layer, matrixSet, options = {}) {
71
+ const response = await fetch(capabilities, options.signal ? { signal: options.signal } : {});
72
+ if (!response.ok)
73
+ throw new Error(`isard: ${response.status} for the WMTS capabilities`);
74
+ return parseWmtsGrid(await response.text(), layer, matrixSet);
75
+ }
76
+ //# sourceMappingURL=wmts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wmts.js","sourceRoot":"","sources":["../src/wmts.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAElD,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAEhE,2FAA2F;AAC3F,MAAM,iBAAiB,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,EAAE,GAAG,OAAO,CAAC,GAAG,GAAG,CAAC;AACxD,0FAA0F;AAC1F,MAAM,KAAK,GAAG,OAAO,CAAC;AAEtB,MAAM,OAAO,GAAG,CAAC,IAAwB,EAAE,EAAE,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;AAE3F;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW,EAAE,KAAa,EAAE,SAAkB;IAC1E,MAAM,QAAQ,GAAG,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,EAAE,UAAU,CAAC,CAAC;IAClD,MAAM,KAAK,GAAG,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,YAAY,CAAC,KAAK,KAAK,CAAC,CAAC;IAC5F,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,KAAK,EAAE,CAAC,CAAC;IAC7D,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,EAAE,mBAAmB,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,eAAe,CAAC,KAAK,SAAS,CAAC,CAAC;IACjH,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,EAAE,eAAe,CAAC,CAAC;IAC9C,MAAM,GAAG,GAAG,QAAQ,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,SAAS,CAAC,CAAC,EAAE,YAAY,CAAC,KAAK,IAAI,CAAC,CAAC;IACjG,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,SAAS,IAAI,EAAE,uBAAuB,KAAK,EAAE,CAAC,CAAC;IAC/G,MAAM,GAAG,GAAG,SAAS,CAAC,GAAG,EAAE,cAAc,CAAC,IAAI,EAAE,CAAC;IACjD,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,CAAC;IACrC,wFAAwF;IACxF,MAAM,QAAQ,GAAG,UAAU,IAAI,QAAQ,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAC3E,MAAM,IAAI,GAAG,UAAU,CAAC,CAAC,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC;IAChD,MAAM,MAAM,GAAG,IAAI,GAAG,EAAgC,CAAC;IACvD,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,IAAI,EAAE,qBAAqB,CAAC,EAAE,kBAAkB,CAAC,EAAE,CAAC;QACjF,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,EAAE,YAAY,EAAE,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAC1G,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CACY,CAAC;QACtC,MAAM,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,EAAE,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IACjF,CAAC;IACD,MAAM,QAAQ,GAAG,QAAQ,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAc,EAAE;QACjE,MAAM,EAAE,GAAG,SAAS,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,EAAE,CAAC;QAC5C,MAAM,CAAC,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,CAAC;QAC9D,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC7B,OAAO;YACL,EAAE;YACF,UAAU,EAAE,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC,GAAG,KAAK,CAAC,GAAG,IAAI;YACrE,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClC,SAAS,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,CAAC,IAAI,GAAG,CAAC;YACnD,UAAU,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,YAAY,CAAC,IAAI,GAAG,CAAC;YACrD,WAAW,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,aAAa,CAAC,IAAI,QAAQ,CAAC;YAC5D,YAAY,EAAE,MAAM,CAAC,SAAS,CAAC,CAAC,EAAE,cAAc,CAAC,IAAI,QAAQ,CAAC;YAC9D,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SACpC,CAAC;IACJ,CAAC,CAAC,CAAC;IACH,2DAA2D;IAC3D,MAAM,MAAM,GAAG,MAAM,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;IAC7F,MAAM,GAAG,GAAG,KAAK,CAAC,KAAK,EAAE,kBAAkB,CAAC,CAAC;IAC7C,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC;IAC7D,MAAM,CAAC,IAAI,EAAE,KAAK,CAAC,GAAG,OAAO,CAAC,SAAS,CAAC,GAAG,EAAE,aAAa,CAAC,CAAC,CAAC;IAC7D,MAAM,MAAM,GAAG,CAAC,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,CAAC,CAAC;IAC1C,OAAO;QACL,GAAG;QACH,QAAQ,EAAE,MAAM;QAChB,IAAI;QACJ,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,MAA0C,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KACjG,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,YAA0B,EAC1B,KAAa,EACb,SAAkB,EAClB,UAAoC,EAAE;IAEtC,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,YAAY,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC7F,IAAI,CAAC,QAAQ,CAAC,EAAE;QAAE,MAAM,IAAI,KAAK,CAAC,UAAU,QAAQ,CAAC,MAAM,4BAA4B,CAAC,CAAC;IACzF,OAAO,aAAa,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;AAChE,CAAC","sourcesContent":["/**\n * The tile grid of a WMTS layer, read from the service's capabilities: its tile matrix set (CRS, levels, origin, tile\n * sizes), the layer's limits in it and its extent, for `addRaster({ url, grid })`.\n */\nimport { epsgCode, isGeographic } from './crs.ts';\nimport type { TileGrid, TileMatrix } from './grid.ts';\nimport { child, children, childText, parseXml } from './xml.ts';\n\n/** Metres per degree, as WMTS counts the scale of a grid in degrees (OGC 07-057r7, 6.1) */\nconst METRES_PER_DEGREE = (2 * Math.PI * 6378137) / 360;\n/** The size of a pixel by which WMTS turns scale denominators into resolutions, metres */\nconst PIXEL = 0.00028;\n\nconst numbers = (text: string | undefined) => (text ?? '').trim().split(/\\s+/).map(Number);\n\n/**\n * The tile grid of `layer` in the capabilities document `xml`: its tile matrix set `matrixSet` (default the layer's\n * first), with the layer's tile limits and longitude-latitude extent. Throws if the layer or the set is missing\n */\nexport function parseWmtsGrid(xml: string, layer: string, matrixSet?: string): TileGrid {\n const contents = child(parseXml(xml), 'Contents');\n const entry = children(contents, 'Layer').find((l) => childText(l, 'Identifier') === layer);\n if (!entry) throw new Error(`isard: no WMTS layer ${layer}`);\n const links = children(entry, 'TileMatrixSetLink');\n const link = matrixSet === undefined ? links[0] : links.find((l) => childText(l, 'TileMatrixSet') === matrixSet);\n const name = childText(link, 'TileMatrixSet');\n const set = children(contents, 'TileMatrixSet').find((s) => childText(s, 'Identifier') === name);\n if (!name || !set) throw new Error(`isard: no tile matrix set ${matrixSet ?? ''} for the WMTS layer ${layer}`);\n const crs = childText(set, 'SupportedCRS') ?? '';\n const geographic = isGeographic(crs);\n // EPSG's geographic CRSs have their latitude first (CRS:84 and the IGN's WGS84G do not)\n const latFirst = geographic && epsgCode(crs) === 4326 && /EPSG/i.test(crs);\n const unit = geographic ? METRES_PER_DEGREE : 1;\n const limits = new Map<string, TileMatrix['limits']>();\n for (const l of children(child(link, 'TileMatrixSetLimits'), 'TileMatrixLimits')) {\n const [minRow, maxRow, minCol, maxCol] = ['MinTileRow', 'MaxTileRow', 'MinTileCol', 'MaxTileCol'].map((k) =>\n Number(childText(l, k)),\n ) as [number, number, number, number];\n limits.set(childText(l, 'TileMatrix') ?? '', [minCol, minRow, maxCol, maxRow]);\n }\n const matrices = children(set, 'TileMatrix').map((m): TileMatrix => {\n const id = childText(m, 'Identifier') ?? '';\n const [a = 0, b = 0] = numbers(childText(m, 'TopLeftCorner'));\n const limit = limits.get(id);\n return {\n id,\n resolution: (Number(childText(m, 'ScaleDenominator')) * PIXEL) / unit,\n origin: latFirst ? [b, a] : [a, b],\n tileWidth: Number(childText(m, 'TileWidth') ?? 256),\n tileHeight: Number(childText(m, 'TileHeight') ?? 256),\n matrixWidth: Number(childText(m, 'MatrixWidth') ?? Infinity),\n matrixHeight: Number(childText(m, 'MatrixHeight') ?? Infinity),\n ...(limit ? { limits: limit } : {}),\n };\n });\n // A layer's limits leave out the matrices it does not have\n const served = limits.size > 0 ? matrices.filter((m) => limits.has(String(m.id))) : matrices;\n const box = child(entry, 'WGS84BoundingBox');\n const [west, south] = numbers(childText(box, 'LowerCorner'));\n const [east, north] = numbers(childText(box, 'UpperCorner'));\n const bounds = [west, south, east, north];\n return {\n crs,\n matrices: served,\n name,\n ...(bounds.every(Number.isFinite) ? { bounds: bounds as [number, number, number, number] } : {}),\n };\n}\n\n/**\n * The tile grid of a WMTS layer, from the service's capabilities at `capabilities` (fetched with CORS), for\n * `addRaster`: `await wmtsGrid('https://…/wmts?SERVICE=WMTS&REQUEST=GetCapabilities', 'LAYER', 'MATRIXSET')`. The\n * raster's URL writes the matrix set, {z} for the matrix, {x} and {y} for the column and the row\n */\nexport async function wmtsGrid(\n capabilities: string | URL,\n layer: string,\n matrixSet?: string,\n options: { signal?: AbortSignal } = {},\n): Promise<TileGrid> {\n const response = await fetch(capabilities, options.signal ? { signal: options.signal } : {});\n if (!response.ok) throw new Error(`isard: ${response.status} for the WMTS capabilities`);\n return parseWmtsGrid(await response.text(), layer, matrixSet);\n}\n"]}
package/dist/xml.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * A small XML reader for the formats read here (KML, GPX, WMTS capabilities): elements, their attributes and text,
3
+ * CDATA, comments, entities. The same in the page, in workers and in tests (which have no `DOMParser`), and lenient:
4
+ * a closing tag without its opening one is ignored, an unclosed element ends with its parent. Names are kept without
5
+ * their namespace prefix (`ows:Identifier` is `Identifier`): the formats read here never mix two meanings of a name.
6
+ * No DTD is read (no external entity, no entity expansion).
7
+ */
8
+ export interface XmlElement {
9
+ /** Local name, without its prefix */
10
+ name: string;
11
+ /** Attributes by local name */
12
+ attributes: Record<string, string>;
13
+ children: XmlElement[];
14
+ /** Text directly inside, CDATA included, entities decoded */
15
+ text: string;
16
+ }
17
+ /** The document's root element; throws if there is none */
18
+ export declare function parseXml(source: string): XmlElement;
19
+ /** The first child element of a name */
20
+ export declare function child(element: XmlElement | undefined, name: string): XmlElement | undefined;
21
+ /** The child elements of a name */
22
+ export declare function children(element: XmlElement | undefined, name: string): XmlElement[];
23
+ /** The trimmed text of the first child of a name; undefined without one */
24
+ export declare function childText(element: XmlElement | undefined, name: string): string | undefined;
25
+ /** Every element of a name under an element, in document order (not inside a match) */
26
+ export declare function descendants(element: XmlElement, name: string, out?: XmlElement[]): XmlElement[];