gridviz 2.0.27 → 2.0.29

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 (56) hide show
  1. package/dist/gridviz.js +34315 -0
  2. package/package.json +4 -2
  3. package/src/App.js +651 -0
  4. package/src/BackgroundLayer.js +182 -0
  5. package/src/BackgroundLayerWMS.js +131 -0
  6. package/src/Dataset.js +76 -0
  7. package/src/DatasetComponent.js +103 -0
  8. package/src/GeoCanvas.js +419 -0
  9. package/src/LabelLayer.js +190 -0
  10. package/src/Layer.js +92 -0
  11. package/src/Legend.js +86 -0
  12. package/src/LineLayer.js +150 -0
  13. package/src/Style.js +114 -0
  14. package/src/Tooltip.js +150 -0
  15. package/src/dataset/COGeo.js +24 -0
  16. package/src/dataset/CSVGrid.js +105 -0
  17. package/src/dataset/GeoTIFF.js +127 -0
  18. package/src/dataset/GridTile.js +41 -0
  19. package/src/dataset/ParquetGrid.js +123 -0
  20. package/src/dataset/TiledGrid.js +294 -0
  21. package/src/index.js +176 -0
  22. package/src/legend/ColorCategoryLegend.js +124 -0
  23. package/src/legend/ColorDiscreteLegend.js +105 -0
  24. package/src/legend/ColorLegend.js +125 -0
  25. package/src/legend/SegmentOrientationLegend.js +87 -0
  26. package/src/legend/SegmentWidthLegend.js +97 -0
  27. package/src/legend/SizeLegend.js +141 -0
  28. package/src/style/CompositionStyle.js +294 -0
  29. package/src/style/ContourStyle.js +54 -0
  30. package/src/style/DotDensityStyle.js +156 -0
  31. package/src/style/JoyPlotStyle.js +135 -0
  32. package/src/style/KernelSmoothingOldStyle.js +221 -0
  33. package/src/style/KernelSmoothingStyle.js +115 -0
  34. package/src/style/KernelSmoothingWGLStyle.js +130 -0
  35. package/src/style/LegoStyle.js +112 -0
  36. package/src/style/MosaicStyle.js +107 -0
  37. package/src/style/NinjaStarStyle.js +124 -0
  38. package/src/style/PillarStyle.js +230 -0
  39. package/src/style/SegmentStyle.js +142 -0
  40. package/src/style/ShapeColorSizeStyle.js +126 -0
  41. package/src/style/SideCatStyle.js +172 -0
  42. package/src/style/SideStyle.js +218 -0
  43. package/src/style/SquareColorCatWGLStyle.js +120 -0
  44. package/src/style/SquareColorWGLStyle.js +146 -0
  45. package/src/style/StrokeStyle.js +131 -0
  46. package/src/style/TanakaStyle.js +160 -0
  47. package/src/style/TextStyle.js +132 -0
  48. package/src/utils/Utils.js +35 -0
  49. package/src/utils/WebGLRectangleColoring.js +106 -0
  50. package/src/utils/WebGLSquareColoring.js +118 -0
  51. package/src/utils/WebGLSquareColoringAdvanced.js +230 -0
  52. package/src/utils/WebGLSquareColoringCatAdvanced.js +133 -0
  53. package/src/utils/WebGLSquareColoringKS.js +153 -0
  54. package/src/utils/stretching.js +131 -0
  55. package/src/utils/webGLUtils.js +71 -0
  56. package/src/utils/zoomUtils.js +142 -0
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "gridviz",
3
- "version": "2.0.27",
3
+ "version": "2.0.29",
4
4
  "description": "Visualization tool for gridded statistics",
5
+ "type": "module",
5
6
  "keywords": [
6
7
  "statistics",
7
8
  "grid",
@@ -42,7 +43,8 @@
42
43
  "test": "jest"
43
44
  },
44
45
  "files": [
45
- "dist/gridviz.min.js"
46
+ "dist/**/*.js",
47
+ "src/**/*.js"
46
48
  ],
47
49
  "dependencies": {
48
50
  "apache-arrow": "^10.0.1",
package/src/App.js ADDED
@@ -0,0 +1,651 @@
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { GeoCanvas } from './GeoCanvas'
5
+ import { Layer } from './Layer'
6
+ import { Dataset } from './Dataset'
7
+ import { Tooltip } from './Tooltip'
8
+
9
+ import { CSVGrid } from './dataset/CSVGrid'
10
+ //import { ParquetGrid } from './dataset/ParquetGrid';
11
+ import { TiledGrid } from './dataset/TiledGrid'
12
+ import { BackgroundLayer } from './BackgroundLayer'
13
+ import { BackgroundLayerWMS } from './BackgroundLayerWMS'
14
+ import { LabelLayer } from './LabelLayer'
15
+ import { LineLayer } from './LineLayer'
16
+
17
+ import { select } from 'd3-selection'
18
+ import { monitor, monitorDuration } from './utils/Utils'
19
+
20
+ /**
21
+ * A gridviz application.
22
+ *
23
+ * @author Joseph Davies, Julien Gaffuri
24
+ */
25
+ export class App {
26
+ /**
27
+ * @param {HTMLDivElement} container
28
+ * @param {object} opts
29
+ */
30
+ constructor(container, opts) {
31
+ opts = opts || {}
32
+
33
+ /**
34
+ * The layers.
35
+ * @type {Array.<Layer>}
36
+ * */
37
+ this.layers = []
38
+
39
+ //get container element
40
+ container = container || document.getElementById('gridviz')
41
+ if (!container) {
42
+ console.error('Cannot find gridviz container element.')
43
+ return
44
+ }
45
+
46
+ //set dimensions
47
+ /** @type {number} */
48
+ this.w = opts.w || container.offsetWidth
49
+ /** @type {number} */
50
+ this.h = opts.h || container.offsetHeight
51
+
52
+ //create canvas element if user doesnt specify one
53
+ /** @type {HTMLCanvasElement} */
54
+ let canvas = opts.canvas || null
55
+ if (!canvas) {
56
+ canvas = document.createElement('canvas')
57
+ canvas.setAttribute('width', '' + this.w)
58
+ canvas.setAttribute('height', '' + this.h)
59
+ container.appendChild(canvas)
60
+ }
61
+
62
+ /** Make geo canvas
63
+ * @type {GeoCanvas}
64
+ * @private */
65
+ this.cg = new GeoCanvas(canvas, undefined, 1, opts)
66
+ this.cg.redraw = (strong = true) => {
67
+ if (monitor) monitorDuration('Start redraw')
68
+ //console.log("?x=" + this.cg.getCenter().x + "&y=" + this.cg.getCenter().y + "&z=" + this.cg.getZf())
69
+
70
+ //remove legend elements
71
+ if (this.legend && strong) this.legend.selectAll('*').remove()
72
+
73
+ //clear
74
+ this.cg.initCanvasTransform()
75
+ this.cg.clear(this.cg.backgroundColor)
76
+
77
+ const zf = this.getZoomFactor()
78
+ this.updateExtentGeo()
79
+
80
+ //go through the background layers
81
+ for (const layer of this.bgLayers) {
82
+ //check if layer is visible
83
+ if (!layer.visible) continue
84
+ if (zf > layer.maxZoom) continue
85
+ if (zf < layer.minZoom) continue
86
+
87
+ //draw layer
88
+ layer.draw(this.cg)
89
+ }
90
+
91
+ //go through the layers
92
+ for (const layer of this.layers) {
93
+ //check if layer is visible
94
+ if (!layer.visible) continue
95
+ if (zf > layer.maxZoom) continue
96
+ if (zf < layer.minZoom) continue
97
+
98
+ //get layer dataset component
99
+ /** @type {import('./DatasetComponent').DatasetComponent|undefined} */
100
+ const dsc = layer.getDatasetComponent(zf)
101
+ if (!dsc) continue
102
+
103
+ //launch data download, if necessary
104
+ if (strong)
105
+ dsc.getData(this.cg.extGeo, () => {
106
+ this.cg.redraw()
107
+ })
108
+
109
+ //update dataset view cache
110
+ if (strong) dsc.updateViewCache(this.cg.extGeo)
111
+
112
+ //draw cells, style by style
113
+ if (strong)
114
+ for (const s of layer.styles) {
115
+ if (zf > s.maxZoom) continue
116
+ if (zf < s.minZoom) continue
117
+ s.draw(dsc.getViewCache(), dsc.getResolution(), this.cg)
118
+ }
119
+
120
+ //add legend element
121
+ if (this.legend && strong)
122
+ for (const s of layer.styles) {
123
+ if (zf > s.maxZoom) continue
124
+ if (zf < s.minZoom) continue
125
+ for (const lg of s.legends) {
126
+ //console.log(s, lg)
127
+ //this.legend.append(lg.div)
128
+ //s1.node().appendChild(s2.node())
129
+ this.legend.node().append(lg.div.node())
130
+ }
131
+
132
+ //case for styles of styles, like kernel smoothing
133
+ //TODO do better
134
+ if (s['styles']) {
135
+ for (const s2 of s.styles) {
136
+ if (zf > s2.maxZoom) continue
137
+ if (zf < s2.minZoom) continue
138
+ for (const lg of s2.legends) {
139
+ //console.log(s, lg)
140
+ //this.legend.append(lg.div)
141
+ //s1.node().appendChild(s2.node())
142
+ this.legend.node().append(lg.div.node())
143
+ }
144
+ }
145
+ }
146
+ }
147
+ }
148
+
149
+ //draw boundary layer
150
+ //if (strong)
151
+ if (this.showBoundaries && this.boundaryLayer) this.boundaryLayer.draw(this.cg)
152
+
153
+ //draw label layer
154
+ //if (strong)
155
+ if (this.showLabels && this.labelLayer) this.labelLayer.draw(this.cg)
156
+
157
+ //
158
+ this.canvasSave = null
159
+
160
+ if (monitor) monitorDuration('End redraw')
161
+
162
+ return this
163
+ }
164
+
165
+ /** @type {Array.<BackgroundLayer|BackgroundLayerWMS>} */
166
+ this.bgLayers = []
167
+ /** @type {boolean} */
168
+ this.showBgLayers = true
169
+
170
+ /** @type {LabelLayer | undefined} */
171
+ this.labelLayer = undefined
172
+ /** @type {boolean} */
173
+ this.showLabels = true
174
+
175
+ /** @type {LineLayer | undefined} */
176
+ this.boundaryLayer = undefined
177
+ /** @type {boolean} */
178
+ this.showBoundaries = true
179
+
180
+ //legend div
181
+
182
+ this.legendDivId = opts.legendDivId || 'gvizLegend'
183
+ this.legend = select('#' + this.legendDivId)
184
+ if (this.legend.empty()) {
185
+ this.legend = select('body')
186
+ .append('div')
187
+ .attr('id', this.legendDivId)
188
+ .style('position', 'absolute')
189
+ .style('width', 'auto')
190
+ .style('height', 'auto')
191
+ .style('background', '#FFFFFFCC')
192
+ //.style("padding", this.padding)
193
+ .style('border', '0px')
194
+ .style('border-radius', '5px')
195
+ .style('box-shadow', '3px 3px 3px grey, -3px -3px 3px #ddd')
196
+ .style('font-family', 'Helvetica, Arial, sans-serif')
197
+ .style('top', '20px')
198
+ .style('right', '20px')
199
+ //hide
200
+ //.style("visibility", "hidden")
201
+ }
202
+
203
+ //tooltip
204
+
205
+ /**
206
+ * @private
207
+ * @type {Tooltip} */
208
+ this.tooltip = new Tooltip(opts.tooltip)
209
+
210
+ /** @param {MouseEvent} e */
211
+ const focusCell = (e) => {
212
+ //compute mouse geo position
213
+ const mousePositionGeo = {
214
+ x: this.cg.pixToGeoX(e.offsetX + this.tooltip.xMouseOffset),
215
+ y: this.cg.pixToGeoY(e.offsetY + this.tooltip.yMouseOffset),
216
+ }
217
+ /** @type {{cell:import('./Dataset').Cell,html:string,resolution:number} | undefined} */
218
+ const focus = this.getCellFocusInfo(mousePositionGeo)
219
+
220
+ // transparent background (e.g. leaflet) 'red painting' fix
221
+ if (opts.transparentBackground) {
222
+ if (focus) {
223
+ this.tooltip.setPosition(e)
224
+ this.tooltip.show()
225
+ this.tooltip.html(focus.html)
226
+ } else {
227
+ this.tooltip.hide()
228
+ }
229
+ this.canvasSave = document.createElement('canvas')
230
+ this.canvasSave.setAttribute('width', '' + this.w)
231
+ this.canvasSave.setAttribute('height', '' + this.h)
232
+ this.canvasSave.getContext('2d').drawImage(this.cg.canvas, 0, 0)
233
+ this.cg.initCanvasTransform()
234
+ return
235
+ }
236
+
237
+ if (focus) {
238
+ this.tooltip.setPosition(e)
239
+ this.tooltip.show()
240
+ this.tooltip.html(focus.html)
241
+
242
+ //show cell position as a rectangle
243
+ if (!this.canvasSave) {
244
+ this.canvasSave = document.createElement('canvas')
245
+ this.canvasSave.setAttribute('width', '' + this.w)
246
+ this.canvasSave.setAttribute('height', '' + this.h)
247
+ this.canvasSave.getContext('2d').drawImage(this.cg.canvas, 0, 0)
248
+ } else {
249
+ this.cg.ctx.drawImage(this.canvasSave, 0, 0)
250
+ }
251
+
252
+ //draw image saved + draw rectangle
253
+ const rectWPix = this.selectionRectangleWidthPix ? this.selectionRectangleWidthPix(focus.resolution, this.getZoomFactor()) : 4;
254
+ this.cg.initCanvasTransform()
255
+ this.cg.ctx.strokeStyle = this.selectionRectangleColor
256
+ this.cg.ctx.lineWidth = rectWPix
257
+ this.cg.ctx.beginPath()
258
+
259
+ this.cg.ctx.rect(
260
+ this.cg.geoToPixX(focus.cell.x) - rectWPix / 2,
261
+ this.cg.geoToPixY(focus.cell.y) + rectWPix / 2,
262
+ focus.resolution / this.getZoomFactor() + rectWPix,
263
+ -focus.resolution / this.getZoomFactor() - rectWPix
264
+ )
265
+ this.cg.ctx.stroke()
266
+ } else {
267
+ this.tooltip.hide()
268
+ if (this.canvasSave) this.cg.ctx.drawImage(this.canvasSave, 0, 0)
269
+ }
270
+ }
271
+ container.addEventListener('mouseover', (e) => {
272
+ focusCell(e)
273
+ })
274
+ container.addEventListener('mousemove', (e) => {
275
+ focusCell(e)
276
+ })
277
+ container.addEventListener('mouseout', () => {
278
+ this.tooltip.hide()
279
+ })
280
+ this.cg.onZoomStartFun = () => {
281
+ this.tooltip.hide()
282
+ }
283
+
284
+ //for mouse over
285
+ /**
286
+ * @private
287
+ * @type {HTMLCanvasElement|null} */
288
+ this.canvasSave = null
289
+
290
+ this.selectionRectangleColor = opts.selectionRectangleColor || 'red'
291
+ this.selectionRectangleWidthPix = opts.selectionRectangleWidthPix || (() => 4) //(r,zf) => {}
292
+
293
+ //
294
+ //canvas.addEventListener("keydown", e => { console.log(arguments) });
295
+ }
296
+
297
+ /**
298
+ * @param {number} marginPx
299
+ * @returns {import('./Dataset').Envelope}
300
+ * @public
301
+ */
302
+ updateExtentGeo(marginPx = 20) {
303
+ return this.cg.updateExtentGeo(marginPx)
304
+ }
305
+
306
+ /**
307
+ * Return the cell HTML info at a given geo position.
308
+ * This is usefull for user interactions, to show this info where the user clicks for example.
309
+ *
310
+ * @param {{x:number,y:number}} posGeo
311
+ * @returns {{cell:import('./Dataset').Cell,html:string,resolution:number} | undefined}
312
+ * @protected
313
+ */
314
+ getCellFocusInfo(posGeo) {
315
+ //go through the layers, starting from top
316
+ const zf = this.getZoomFactor()
317
+ for (let i = this.layers.length - 1; i >= 0; i--) {
318
+ /** @type {Layer} */
319
+ const layer = this.layers[i]
320
+ if (!layer.visible) continue
321
+ if (!layer.cellInfoHTML) continue
322
+ if (layer.cellInfoHTML === 'none') continue
323
+ const dsc = layer.getDatasetComponent(zf)
324
+ if (!dsc) continue
325
+
326
+ //get cell at mouse position
327
+ /** @type {import('./Dataset').Cell|undefined} */
328
+ const cell = dsc.getCellFromPosition(posGeo, dsc.getViewCache())
329
+ if (!cell) return undefined
330
+ const html = layer.cellInfoHTML(cell, dsc.getResolution())
331
+ if (!html) return undefined
332
+ return { cell: cell, html: html, resolution: dsc.getResolution() }
333
+ }
334
+ }
335
+
336
+ //getters and setters
337
+
338
+ /** @returns {{x:number,y:number}} */
339
+ getGeoCenter() {
340
+ return this.cg.getCenter()
341
+ }
342
+ /** @param {{x:number,y:number}} val @returns {this} */
343
+ setGeoCenter(val) {
344
+ this.cg.setCenter(val)
345
+ return this
346
+ }
347
+
348
+ /** @returns {number} */
349
+ getZoomFactor() {
350
+ return this.cg.getZf()
351
+ }
352
+ /** @param {number} val @returns {this} */
353
+ setZoomFactor(val) {
354
+ this.cg.setZf(val)
355
+ return this
356
+ }
357
+
358
+ /** @returns {Array.<number>} */
359
+ getZoomFactorExtent() {
360
+ return this.cg.getZfExtent()
361
+ }
362
+ /** @param {Array.<number>} val @returns {this} */
363
+ setZoomFactorExtent(val) {
364
+ this.cg.setZfExtent(val)
365
+ return this
366
+ }
367
+
368
+ /** @returns {string} */
369
+ getBackgroundColor() {
370
+ return this.cg.backgroundColor
371
+ }
372
+ /** @param {string} val @returns {this} */
373
+ setBackgroundColor(val) {
374
+ this.cg.backgroundColor = val
375
+ return this
376
+ }
377
+
378
+ /** @returns {LineLayer | undefined} */
379
+ getBoundaryLayer() {
380
+ return this.boundaryLayer
381
+ }
382
+ /** @param {object} opts @returns {this} */
383
+ setBoundaryLayer(opts) {
384
+ this.boundaryLayer = new LineLayer(opts)
385
+ return this
386
+ }
387
+
388
+ /** @returns {LabelLayer | undefined} */
389
+ getLabelLayer() {
390
+ return this.labelLayer
391
+ }
392
+ /** @param {object} opts @returns {this} */
393
+ setLabelLayer(opts) {
394
+ this.labelLayer = new LabelLayer(opts)
395
+ return this
396
+ }
397
+
398
+ /** @returns {this} */
399
+ redraw() {
400
+ this.cg.redraw()
401
+ return this
402
+ }
403
+
404
+ /**
405
+ * Add a layer to the app.
406
+ *
407
+ * @param {Dataset} dataset The dataset of the layer
408
+ * @param {Array.<import('./Style').Style>} styles The styles of the layer
409
+ * @param {{visible?:boolean,minZoom?:number,maxZoom?:number,pixNb?:number,cellInfoHTML?:function(import('./Dataset').Cell):string}} opts The layer options.
410
+ * @returns {this}
411
+ */
412
+ addLayerFromDataset(dataset, styles, opts) {
413
+ const lay = new Layer(dataset, styles, opts)
414
+ this.layers.push(lay)
415
+ return this
416
+ }
417
+
418
+ //dataset creation
419
+
420
+ /**
421
+ * Make a CSV grid dataset.
422
+ *
423
+ * @param {string} url The URL of the dataset.
424
+ * @param {number} resolution The dataset resolution in geographical unit.
425
+ * @param {object=} opts The parameters of the dataset.
426
+ * @returns {Dataset}
427
+ */
428
+ makeCSVGridDataset(url, resolution, opts) {
429
+ return new Dataset(
430
+ [
431
+ new CSVGrid(url, resolution, opts).getData(undefined, () => {
432
+ this.cg.redraw()
433
+ }),
434
+ ],
435
+ [],
436
+ opts
437
+ )
438
+ }
439
+
440
+ /**
441
+ * Make a parquet grid dataset.
442
+ *
443
+ * @param {string} url The URL of the dataset.
444
+ * @param {number} resolution The dataset resolution in geographical unit.
445
+ * @param {object=} opts The parameters of the dataset.
446
+ * @returns {Dataset}
447
+ */
448
+ /*makeParquetGridDataset(url, resolution, opts) {
449
+ return new Dataset([new ParquetGrid(url, resolution, opts).getData(undefined, () => { this.cg.redraw(); })], [], opts)
450
+ }*/
451
+
452
+ /**
453
+ * Make a tiled grid dataset.
454
+ *
455
+ * @param {string} url
456
+ * @param {{preprocess?:function(import('./Dataset').Cell):boolean}} opts
457
+ * @returns {Dataset}
458
+ */
459
+ makeTiledGridDataset(url, opts) {
460
+ return new Dataset(
461
+ [
462
+ new TiledGrid(url, this, opts).loadInfo(() => {
463
+ this.cg.redraw()
464
+ }),
465
+ ],
466
+ [],
467
+ opts
468
+ )
469
+ }
470
+
471
+ //multi scale dataset creation
472
+
473
+ /**
474
+ * Make a multi scale parquet grid dataset.
475
+ *
476
+ * @param {Array.<number>} resolutions
477
+ * @param {function(number):string} resToURL
478
+ * @param {{preprocess?:function(import('./Dataset').Cell):boolean}} opts
479
+ * @returns {Dataset}
480
+ */
481
+ /*makeMultiScaleParquetGridDataset(resolutions, resToURL, opts) {
482
+ return Dataset.make(
483
+ resolutions,
484
+ (res) => new ParquetGrid(resToURL(res), res, opts).getData(undefined, () => { this.cg.redraw(); }),
485
+ opts
486
+ )
487
+ }*/
488
+
489
+ /**
490
+ * Make a multi scale CSV grid dataset.
491
+ *
492
+ * @param {Array.<number>} resolutions
493
+ * @param {function(number):string} resToURL
494
+ * @param {{preprocess?:function(import('./Dataset').Cell):boolean}} opts
495
+ * @returns {Dataset}
496
+ */
497
+ makeMultiScaleCSVGridDataset(resolutions, resToURL, opts) {
498
+ return Dataset.make(
499
+ resolutions,
500
+ (res) =>
501
+ new CSVGrid(resToURL(res), res, opts).getData(undefined, () => {
502
+ this.cg.redraw()
503
+ }),
504
+ opts
505
+ )
506
+ }
507
+
508
+ //tiled multiscale
509
+
510
+ /**
511
+ * Make a multi scale tiled grid dataset.
512
+ *
513
+ * @param {Array.<number>} resolutions
514
+ * @param {function(number):string} resToURL
515
+ * @param {{preprocess?:function(import('./Dataset').Cell):boolean}} opts
516
+ * @returns {Dataset}
517
+ */
518
+ makeMultiScaleTiledGridDataset(resolutions, resToURL, opts) {
519
+ return Dataset.make(
520
+ resolutions,
521
+ (res) =>
522
+ new TiledGrid(resToURL(res), this, opts).loadInfo(() => {
523
+ this.cg.redraw()
524
+ }),
525
+ opts
526
+ )
527
+ }
528
+
529
+ // direct layer creation
530
+
531
+ /**
532
+ * Add a layer from a CSV grid dataset.
533
+ *
534
+ * @param {string} url The URL of the dataset.
535
+ * @param {number} resolution The dataset resolution in geographical unit.
536
+ * @param {Array.<import('./Style').Style>} styles The styles, ordered in drawing order.
537
+ * @param {object=} opts The parameters of the dataset and layer.
538
+ * @returns {this}
539
+ */
540
+ addCSVGridLayer(url, resolution, styles, opts) {
541
+ const ds = this.makeCSVGridDataset(url, resolution, opts)
542
+ return this.addLayerFromDataset(ds, styles, opts)
543
+ }
544
+
545
+ /**
546
+ * Add a layer from a parquet grid dataset.
547
+ *
548
+ * @param {string} url The URL of the dataset.
549
+ * @param {number} resolution The dataset resolution in geographical unit.
550
+ * @param {Array.<import('./Style').Style>} styles The styles, ordered in drawing order.
551
+ * @param {object=} opts The parameters of the dataset and layer.
552
+ * @returns {this}
553
+ */
554
+ /*addParquetGridLayer(url, resolution, styles, opts) {
555
+ const ds = this.makeParquetGridDataset(url, resolution, opts)
556
+ return this.addLayerFromDataset(ds, styles, opts);
557
+ }*/
558
+
559
+ /**
560
+ *
561
+ * @param {string} url
562
+ * @param {Array.<import('./Style').Style>} styles
563
+ * @param {{visible?:boolean,minZoom?:number,maxZoom?:number,pixNb?:number,cellInfoHTML?:function(import('./Dataset').Cell):string, preprocess?:function(import('./Dataset').Cell):boolean}} opts
564
+ * @returns {this}
565
+ */
566
+ addTiledGridLayer(url, styles, opts) {
567
+ const ds = this.makeTiledGridDataset(url, opts)
568
+ return this.addLayerFromDataset(ds, styles, opts)
569
+ }
570
+
571
+ /**
572
+ * Add a layer from a CSV grid dataset.
573
+ *
574
+ * @param {Array.<number>} resolutions
575
+ * @param {function(number):string} resToURL
576
+ * @param {Array.<import('./Style').Style>} styles The styles, ordered in drawing order.
577
+ * @param {object=} opts The parameters of the dataset and layer.
578
+ * @returns {this}
579
+ */
580
+ addMultiScaleCSVGridLayer(resolutions, resToURL, styles, opts) {
581
+ const ds = this.makeMultiScaleCSVGridDataset(resolutions, resToURL, opts)
582
+ return this.addLayerFromDataset(ds, styles, opts)
583
+ }
584
+
585
+ /**
586
+ * Add a layer from a parquet grid dataset.
587
+ *
588
+ * @param {Array.<number>} resolutions
589
+ * @param {function(number):string} resToURL
590
+ * @param {Array.<import('./Style').Style>} styles The styles, ordered in drawing order.
591
+ * @param {object=} opts The parameters of the dataset and layer.
592
+ * @returns {this}
593
+ */
594
+ /*addMultiScaleParquetGridLayer(resolutions, resToURL, styles, opts) {
595
+ const ds = this.makeMultiScaleParquetGridDataset(resolutions, resToURL, opts)
596
+ return this.addLayerFromDataset(ds, styles, opts);
597
+ }*/
598
+
599
+ /**
600
+ * @param {Array.<number>} resolutions
601
+ * @param {function(number):string} resToURL
602
+ * @param {Array.<import('./Style').Style>} styles
603
+ * @param {{visible?:boolean,minZoom?:number,maxZoom?:number,pixNb?:number,cellInfoHTML?:function(import('./Dataset').Cell):string, preprocess?:function(import('./Dataset').Cell):boolean}} opts
604
+ * @returns {this}
605
+ */
606
+ addMultiScaleTiledGridLayer(resolutions, resToURL, styles, opts) {
607
+ const ds = this.makeMultiScaleTiledGridDataset(resolutions, resToURL, opts)
608
+ return this.addLayerFromDataset(ds, styles, opts)
609
+ }
610
+
611
+ /**
612
+ * Add a background layer to the app.
613
+ *
614
+ * @param {object} opts
615
+ * @returns {this}
616
+ */
617
+ addBackgroundLayer(opts) {
618
+ this.bgLayers.push(new BackgroundLayer(opts))
619
+ this.redraw()
620
+ return this
621
+ }
622
+
623
+ /**
624
+ * Add a WMS background layer to the app.
625
+ *
626
+ * @param {object} opts
627
+ * @returns {this}
628
+ */
629
+ addBackgroundLayerWMS(opts) {
630
+ this.bgLayers.push(new BackgroundLayerWMS(opts))
631
+ this.redraw()
632
+ return this
633
+ }
634
+
635
+ /**
636
+ *
637
+ * @param {string} id
638
+ * @param {object} opts
639
+ * @returns {this}
640
+ */
641
+ addZoomSlider(id, opts) {
642
+ this.cg.addZoomSlider(id, opts)
643
+ return this
644
+ }
645
+
646
+ /** @returns {this} */
647
+ setViewFromURL() {
648
+ this.cg.setViewFromURL()
649
+ return this
650
+ }
651
+ }