gridviz 3.0.15 → 3.0.17
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.
- package/README.md +127 -128
- package/dist/gridviz.js +7958 -7861
- package/dist/gridviz.min.js +1 -1
- package/package.json +74 -74
- package/src/button/ZoomButtons.js +101 -96
- package/src/core/Dataset.js +154 -157
- package/src/core/Drawable.js +60 -61
- package/src/core/GeoCanvas.js +409 -370
- package/src/core/Layer.js +23 -25
- package/src/core/Legend.js +108 -110
- package/src/core/Map.js +494 -495
- package/src/core/MultiResolutionDataset.js +93 -97
- package/src/core/Style.js +98 -99
- package/src/dataset/CSVGrid.js +112 -112
- package/src/dataset/GeoTIFF.js +122 -123
- package/src/dataset/JSGrid.js +55 -54
- package/src/dataset/TiledGrid.js +289 -288
- package/src/dataset/worker.js +18 -0
- package/src/index.js +77 -71
- package/src/layer/BackgroundLayer.js +162 -158
- package/src/layer/BackgroundLayerImage.js +81 -84
- package/src/layer/BackgroundLayerWMS.js +104 -108
- package/src/layer/GeoJSONLayer.js +214 -220
- package/src/layer/GridLayer.js +148 -157
- package/src/layer/LabelLayer.js +194 -193
- package/src/legend/ColorCategoryLegend.js +109 -110
- package/src/legend/ColorDiscreteLegend.js +100 -102
- package/src/legend/ColorLegend.js +115 -118
- package/src/legend/OrientationLegend.js +89 -91
- package/src/legend/SizeLegend.js +224 -224
- package/src/legend/TernaryLegend.js +302 -210
- package/src/style/CompositionStyle.js +291 -288
- package/src/style/DotDensityStyle.js +133 -134
- package/src/style/ImageStyle.js +100 -102
- package/src/style/IsoFenceStyle.js +217 -203
- package/src/style/JoyPlotStyle.js +127 -128
- package/src/style/LegoStyle.js +110 -110
- package/src/style/MosaicStyle.js +99 -99
- package/src/style/NinjaStarStyle.js +102 -102
- package/src/style/PillarStyle.js +207 -208
- package/src/style/SegmentStyle.js +105 -105
- package/src/style/ShapeColorSizeStyle.js +147 -132
- package/src/style/SideCategoryStyle.js +112 -114
- package/src/style/SideStyle.js +212 -205
- package/src/style/SquareColorCategoryWebGLStyle.js +107 -108
- package/src/style/SquareColorWebGLStyle.js +126 -126
- package/src/style/StrokeStyle.js +135 -136
- package/src/style/TanakaStyle.js +69 -68
- package/src/style/TextStyle.js +110 -111
- package/src/style/TimeSeriesStyle.js +222 -229
- package/src/utils/scale.js +218 -228
- package/src/utils/stretching.js +120 -133
- package/src/utils/ternary.js +203 -204
- package/src/utils/utils.js +58 -63
- package/src/utils/webGLUtils.js +72 -70
|
@@ -1,97 +1,93 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* A multi resolution dataset of grid cells.
|
|
6
|
-
* It consists of different {@link Dataset}s for each resolution.
|
|
7
|
-
*
|
|
8
|
-
* @abstract
|
|
9
|
-
*
|
|
10
|
-
* @module core
|
|
11
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
12
|
-
*/
|
|
13
|
-
export class MultiResolutionDataset {
|
|
14
|
-
/**
|
|
15
|
-
* @param {Array.<number>} resolutions The resolutions of the datasets, in CRS geographical unit.
|
|
16
|
-
* @param {Array.<import("./Dataset").Dataset>|function(number):import("./Dataset").Dataset} datasets The datasets list, one per resolution. Or a function that returns a dataset from a resolution value.
|
|
17
|
-
* @param { {preprocess?:function(import("./Dataset").Cell):boolean} } opts Options. preprocess: A function to apply on each dataset cell to prepare its values. Can be used also to select cells to keep.
|
|
18
|
-
*/
|
|
19
|
-
constructor(resolutions, datasets, opts = {}) {
|
|
20
|
-
opts = opts || {}
|
|
21
|
-
|
|
22
|
-
/** The resolutions of the datasets, in CRS geographical unit.
|
|
23
|
-
* @type {Array.<number>} */
|
|
24
|
-
this.resolutions = resolutions
|
|
25
|
-
|
|
26
|
-
/** The datasets. If the list is not explictely defined, build it from the resolution list with the function
|
|
27
|
-
* @type {Array.<import("./Dataset").Dataset>} */
|
|
28
|
-
this.datasets =
|
|
29
|
-
|
|
30
|
-
//there must be as many datasets as resolutions
|
|
31
|
-
if (this.datasets.length > 1 && this.datasets.length != this.resolutions.length)
|
|
32
|
-
throw new Error(
|
|
33
|
-
'Uncompatible number of datasets and resolutions: ' +
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
)
|
|
38
|
-
|
|
39
|
-
//set dataset preprocesses if specified
|
|
40
|
-
if (opts.preprocess) this.setPrepocesses(opts.preprocess)
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
*
|
|
46
|
-
* @param {number}
|
|
47
|
-
* @
|
|
48
|
-
*
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
*
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
* A function to
|
|
84
|
-
*
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
//make multi resolution dataset
|
|
95
|
-
return new MultiResolutionDataset(dsc, resolutions, opts)
|
|
96
|
-
}*/
|
|
97
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* A multi resolution dataset of grid cells.
|
|
6
|
+
* It consists of different {@link Dataset}s for each resolution.
|
|
7
|
+
*
|
|
8
|
+
* @abstract
|
|
9
|
+
*
|
|
10
|
+
* @module core
|
|
11
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
12
|
+
*/
|
|
13
|
+
export class MultiResolutionDataset {
|
|
14
|
+
/**
|
|
15
|
+
* @param {Array.<number>} resolutions The resolutions of the datasets, in CRS geographical unit.
|
|
16
|
+
* @param {Array.<import("./Dataset").Dataset>|function(number):import("./Dataset").Dataset} datasets The datasets list, one per resolution. Or a function that returns a dataset from a resolution value.
|
|
17
|
+
* @param { {preprocess?:function(import("./Dataset").Cell):boolean} } opts Options. preprocess: A function to apply on each dataset cell to prepare its values. Can be used also to select cells to keep.
|
|
18
|
+
*/
|
|
19
|
+
constructor(resolutions, datasets, opts = {}) {
|
|
20
|
+
opts = opts || {}
|
|
21
|
+
|
|
22
|
+
/** The resolutions of the datasets, in CRS geographical unit.
|
|
23
|
+
* @type {Array.<number>} */
|
|
24
|
+
this.resolutions = resolutions
|
|
25
|
+
|
|
26
|
+
/** The datasets. If the list is not explictely defined, build it from the resolution list with the function
|
|
27
|
+
* @type {Array.<import("./Dataset").Dataset>} */
|
|
28
|
+
this.datasets = typeof datasets === 'function' ? this.resolutions.map(datasets) : datasets
|
|
29
|
+
|
|
30
|
+
//there must be as many datasets as resolutions
|
|
31
|
+
if (this.datasets.length > 1 && this.datasets.length != this.resolutions.length)
|
|
32
|
+
throw new Error(
|
|
33
|
+
'Uncompatible number of datasets and resolutions: ' +
|
|
34
|
+
this.datasets.length +
|
|
35
|
+
' ' +
|
|
36
|
+
this.resolutions.length
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
//set dataset preprocesses if specified
|
|
40
|
+
if (opts.preprocess) this.setPrepocesses(opts.preprocess)
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Return the relevant dataset for a specified zoom.
|
|
45
|
+
* @param {number} z
|
|
46
|
+
* @param {number} minPixelsPerCell
|
|
47
|
+
* @returns {import("./Dataset").Dataset|undefined}
|
|
48
|
+
* */
|
|
49
|
+
getDataset(z, minPixelsPerCell) {
|
|
50
|
+
//special case whith single dataset
|
|
51
|
+
if (this.datasets.length == 1) return this.datasets[0]
|
|
52
|
+
|
|
53
|
+
const rs = this.resolutions
|
|
54
|
+
let i = 0
|
|
55
|
+
let z_ = rs[i] / minPixelsPerCell
|
|
56
|
+
while (z_ < z && i < rs.length) {
|
|
57
|
+
i++
|
|
58
|
+
z_ = rs[i] / minPixelsPerCell
|
|
59
|
+
}
|
|
60
|
+
//if (i == 0) return this.dataset.datasets[0];
|
|
61
|
+
//return this.dataset.datasets[i - 1];
|
|
62
|
+
if (i == rs.length) return this.datasets[rs.length - 1]
|
|
63
|
+
return this.datasets[i]
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Set a preprocess function for all datasets.
|
|
68
|
+
* This is a function applied on each cell after it has been loaded.
|
|
69
|
+
*
|
|
70
|
+
* @param {function(import("./Dataset").Cell):boolean} preprocess
|
|
71
|
+
* @returns {this}
|
|
72
|
+
*/
|
|
73
|
+
setPrepocesses(preprocess) {
|
|
74
|
+
for (let ds of this.datasets) ds.preprocess = preprocess
|
|
75
|
+
return this
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/**
|
|
79
|
+
* A function to ease the creation of multi resolution datasets.
|
|
80
|
+
*
|
|
81
|
+
* @param {Array.<number>} resolutions The resolutions of the datasets, in CRS geographical unit
|
|
82
|
+
* @param {function(number):import("./Dataset").Dataset} resToDataset Function returning a dataset from a resolution
|
|
83
|
+
* @param { {preprocess?:function(import("./Dataset").Cell):boolean} } opts Options. preprocess: A function to apply on each dataset cell to prepare its values
|
|
84
|
+
* @returns {MultiResolutionDataset}
|
|
85
|
+
*/
|
|
86
|
+
/*static make(resolutions, resToDataset, opts) {
|
|
87
|
+
//make datasets
|
|
88
|
+
const dsc = []
|
|
89
|
+
for (const res of resolutions) dsc.push(resToDataset(res))
|
|
90
|
+
//make multi resolution dataset
|
|
91
|
+
return new MultiResolutionDataset(dsc, resolutions, opts)
|
|
92
|
+
}*/
|
|
93
|
+
}
|
package/src/core/Style.js
CHANGED
|
@@ -1,99 +1,98 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Drawable } from
|
|
5
|
-
|
|
6
|
-
/** @typedef {"square"|"circle"|"diamond"|"donut"|"triangle_up"|"triangle_down"|"triangle_left"|"triangle_right"|"none"} Shape */
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* viewScale type
|
|
10
|
-
* Returns an object from a list of cells,
|
|
11
|
-
* @typedef {function(Array.<import('./Dataset.js').Cell>,number, number):*} ViewScale */
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* A style, to show a grid dataset.
|
|
15
|
-
*
|
|
16
|
-
* @module core
|
|
17
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
18
|
-
*/
|
|
19
|
-
export class Style extends Drawable {
|
|
20
|
-
/**
|
|
21
|
-
* @abstract
|
|
22
|
-
* @param {{filter?:function(import('./Dataset').Cell):boolean, offset?:function(import('./Dataset').Cell, number, number):{dx:number,dy:number}, visible?:function(number):boolean,alpha?:function(number):number,blendOperation?:function(number):GlobalCompositeOperation,drawFun?:function,viewScale?:ViewScale}} opts
|
|
23
|
-
*/
|
|
24
|
-
constructor(opts) {
|
|
25
|
-
super(opts)
|
|
26
|
-
opts = opts || {}
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
|
|
30
|
-
this.viewScale = opts.viewScale
|
|
31
|
-
|
|
32
|
-
/** A filter function to apply to the cell list, to filter out some cells not to be drawn (such as for example the cells with value=0).
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
this.filter = opts.filter ||
|
|
36
|
-
|
|
37
|
-
/** An offset. This is to alter the position of all symbols in a given direction. In geographical unit.
|
|
38
|
-
* @protected
|
|
39
|
-
* @type {function(import('./Dataset').Cell,number,number):{dx:number,dy:number}} */
|
|
40
|
-
this.offset = opts.offset || ((c, r, z) => ({ dx: 0, dy: 0 }))
|
|
41
|
-
|
|
42
|
-
/** A draw function for the style.
|
|
43
|
-
* @type {function|undefined} */
|
|
44
|
-
this.drawFun = opts.drawFun
|
|
45
|
-
|
|
46
|
-
/**
|
|
47
|
-
* @public
|
|
48
|
-
* @type {Array.<import("./Legend").Legend>} */
|
|
49
|
-
this.legends = []
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
/**
|
|
53
|
-
* Draw cells.
|
|
54
|
-
*
|
|
55
|
-
* @param {Array.<import('./Dataset').Cell>} cells The cells to draw.
|
|
56
|
-
* @param {import("./GeoCanvas").GeoCanvas} geoCanvas The canvas where to draw them.
|
|
57
|
-
* @param {number} resolution Their resolution (in geographic unit)
|
|
58
|
-
* @abstract
|
|
59
|
-
*/
|
|
60
|
-
draw(cells, geoCanvas, resolution) {
|
|
61
|
-
if (this.drawFun) this.drawFun(cells, geoCanvas, resolution)
|
|
62
|
-
else throw new Error('Method draw not implemented.')
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
//getters and setters
|
|
66
|
-
|
|
67
|
-
/** @returns {function(import('./Dataset').Cell,number,number):{dx:number,dy:number}} */
|
|
68
|
-
getOffset() {
|
|
69
|
-
return this.offset
|
|
70
|
-
}
|
|
71
|
-
/** @param {function(import('./Dataset').Cell,number,number):{dx:number,dy:number}} val @returns {this} */
|
|
72
|
-
setOffset(val) {
|
|
73
|
-
this.offset = val
|
|
74
|
-
return this
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/** Update legends of the style, if any
|
|
78
|
-
* @param {object} opts
|
|
79
|
-
* @returns {this} */
|
|
80
|
-
updateLegends(opts) {
|
|
81
|
-
Style.updateLegendsRecursive(this.legends, opts)
|
|
82
|
-
return this
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/** @private */
|
|
86
|
-
static updateLegendsRecursive(lg, opts) {
|
|
87
|
-
if (Array.isArray(lg)) for (const lg_ of lg) this.updateLegendsRecursive(lg_, opts)
|
|
88
|
-
else lg.update(opts)
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* @param {Array.<import("./Legend").Legend>} legends
|
|
93
|
-
* @returns {this} */
|
|
94
|
-
addLegends(legends) {
|
|
95
|
-
for (let legend of legends)
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Drawable } from './Drawable.js'
|
|
5
|
+
|
|
6
|
+
/** @typedef {"square"|"circle"|"diamond"|"donut"|"triangle_up"|"triangle_down"|"triangle_left"|"triangle_right"|"none"} Shape */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* viewScale type
|
|
10
|
+
* Returns an object from a list of cells,
|
|
11
|
+
* @typedef {function(Array.<import('./Dataset.js').Cell>,number, number):*} ViewScale */
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* A style, to show a grid dataset.
|
|
15
|
+
*
|
|
16
|
+
* @module core
|
|
17
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
18
|
+
*/
|
|
19
|
+
export class Style extends Drawable {
|
|
20
|
+
/**
|
|
21
|
+
* @abstract
|
|
22
|
+
* @param {{filter?:function(import('./Dataset').Cell):boolean, offset?:function(import('./Dataset').Cell, number, number):{dx:number,dy:number}, visible?:function(number):boolean,alpha?:function(number):number,blendOperation?:function(number):GlobalCompositeOperation,drawFun?:function,viewScale?:ViewScale}} opts
|
|
23
|
+
*/
|
|
24
|
+
constructor(opts) {
|
|
25
|
+
super(opts)
|
|
26
|
+
opts = opts || {}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @type {ViewScale|undefined} */
|
|
30
|
+
this.viewScale = opts.viewScale
|
|
31
|
+
|
|
32
|
+
/** A filter function to apply to the cell list, to filter out some cells not to be drawn (such as for example the cells with value=0).
|
|
33
|
+
* @protected
|
|
34
|
+
* @type {(function(import('./Dataset').Cell):boolean) | undefined} */
|
|
35
|
+
this.filter = opts.filter || undefined
|
|
36
|
+
|
|
37
|
+
/** An offset. This is to alter the position of all symbols in a given direction. In geographical unit.
|
|
38
|
+
* @protected
|
|
39
|
+
* @type {function(import('./Dataset').Cell,number,number):{dx:number,dy:number}} */
|
|
40
|
+
this.offset = opts.offset || ((c, r, z) => ({ dx: 0, dy: 0 }))
|
|
41
|
+
|
|
42
|
+
/** A draw function for the style.
|
|
43
|
+
* @type {function|undefined} */
|
|
44
|
+
this.drawFun = opts.drawFun
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* @public
|
|
48
|
+
* @type {Array.<import("./Legend").Legend>} */
|
|
49
|
+
this.legends = []
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
/**
|
|
53
|
+
* Draw cells.
|
|
54
|
+
*
|
|
55
|
+
* @param {Array.<import('./Dataset').Cell>} cells The cells to draw.
|
|
56
|
+
* @param {import("./GeoCanvas").GeoCanvas} geoCanvas The canvas where to draw them.
|
|
57
|
+
* @param {number} resolution Their resolution (in geographic unit)
|
|
58
|
+
* @abstract
|
|
59
|
+
*/
|
|
60
|
+
draw(cells, geoCanvas, resolution) {
|
|
61
|
+
if (this.drawFun) this.drawFun(cells, geoCanvas, resolution)
|
|
62
|
+
else throw new Error('Method draw not implemented.')
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
//getters and setters
|
|
66
|
+
|
|
67
|
+
/** @returns {function(import('./Dataset').Cell,number,number):{dx:number,dy:number}} */
|
|
68
|
+
getOffset() {
|
|
69
|
+
return this.offset
|
|
70
|
+
}
|
|
71
|
+
/** @param {function(import('./Dataset').Cell,number,number):{dx:number,dy:number}} val @returns {this} */
|
|
72
|
+
setOffset(val) {
|
|
73
|
+
this.offset = val
|
|
74
|
+
return this
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/** Update legends of the style, if any
|
|
78
|
+
* @param {object} opts
|
|
79
|
+
* @returns {this} */
|
|
80
|
+
updateLegends(opts) {
|
|
81
|
+
Style.updateLegendsRecursive(this.legends, opts)
|
|
82
|
+
return this
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
/** @private */
|
|
86
|
+
static updateLegendsRecursive(lg, opts) {
|
|
87
|
+
if (Array.isArray(lg)) for (const lg_ of lg) this.updateLegendsRecursive(lg_, opts)
|
|
88
|
+
else lg.update(opts)
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param {Array.<import("./Legend").Legend>} legends
|
|
93
|
+
* @returns {this} */
|
|
94
|
+
addLegends(legends) {
|
|
95
|
+
for (let legend of legends) this.legends.push(legend)
|
|
96
|
+
return this
|
|
97
|
+
}
|
|
98
|
+
}
|
package/src/dataset/CSVGrid.js
CHANGED
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
/** @typedef {{ dims: object, crs: string, tileSizeCell: number, originPoint: {x:number,y:number}, resolutionGeo: number, tilingBounds:import("../core/GeoCanvas.js").Envelope }} GridInfo */
|
|
5
|
-
|
|
6
|
-
import { dsv } from 'd3-fetch'
|
|
7
|
-
import { Dataset } from '../core/Dataset.js'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* A dataset composed of a single CSV file (not tiled).
|
|
11
|
-
*
|
|
12
|
-
* @module dataset
|
|
13
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
14
|
-
*/
|
|
15
|
-
export class CSVGrid extends Dataset {
|
|
16
|
-
/**
|
|
17
|
-
* @param {import("../core/Map.js").Map} map The map.
|
|
18
|
-
* @param {string} url The URL of the dataset.
|
|
19
|
-
* @param {number} resolution The dataset resolution in geographical unit.
|
|
20
|
-
* @param {{preprocess?:(function(import("../core/Dataset.js").Cell):boolean),delimiter?:string}} opts
|
|
21
|
-
*/
|
|
22
|
-
constructor(map, url, resolution, opts = {}) {
|
|
23
|
-
super(map, url, resolution, opts)
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @private
|
|
27
|
-
* @type {Array.<import("../core/Dataset.js").Cell>} */
|
|
28
|
-
this.cells = []
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @private
|
|
32
|
-
* @type {string} */
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @type {string}
|
|
37
|
-
* @private */
|
|
38
|
-
this.infoLoadingStatus = 'notLoaded'
|
|
39
|
-
|
|
40
|
-
//get data
|
|
41
|
-
this.getData(undefined)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Request data within a geographic envelope.
|
|
46
|
-
* @param {import("../core/GeoCanvas.js").Envelope|undefined} e
|
|
47
|
-
*/
|
|
48
|
-
getData(e) {
|
|
49
|
-
//check if data already loaded
|
|
50
|
-
if (this.infoLoadingStatus != 'notLoaded') return this
|
|
51
|
-
|
|
52
|
-
//load data
|
|
53
|
-
this.infoLoadingStatus = 'loading'
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
return this
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Fill the view cache with all cells which are within a geographical envelope.
|
|
95
|
-
*
|
|
96
|
-
* @param {import("../core/GeoCanvas.js").Envelope} extGeo
|
|
97
|
-
* @returns {void}
|
|
98
|
-
*/
|
|
99
|
-
updateViewCache(extGeo) {
|
|
100
|
-
//data not loaded yet
|
|
101
|
-
if (!this.cells) return
|
|
102
|
-
|
|
103
|
-
this.cellsViewCache = []
|
|
104
|
-
for (const cell of this.cells) {
|
|
105
|
-
if (+cell.x + this.resolution < extGeo.xMin) continue
|
|
106
|
-
if (+cell.x - this.resolution > extGeo.xMax) continue
|
|
107
|
-
if (+cell.y + this.resolution < extGeo.yMin) continue
|
|
108
|
-
if (+cell.y - this.resolution > extGeo.yMax) continue
|
|
109
|
-
this.cellsViewCache.push(cell)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
/** @typedef {{ dims: object, crs: string, tileSizeCell: number, originPoint: {x:number,y:number}, resolutionGeo: number, tilingBounds:import("../core/GeoCanvas.js").Envelope }} GridInfo */
|
|
5
|
+
|
|
6
|
+
import { dsv } from 'd3-fetch'
|
|
7
|
+
import { Dataset } from '../core/Dataset.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A dataset composed of a single CSV file (not tiled).
|
|
11
|
+
*
|
|
12
|
+
* @module dataset
|
|
13
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
14
|
+
*/
|
|
15
|
+
export class CSVGrid extends Dataset {
|
|
16
|
+
/**
|
|
17
|
+
* @param {import("../core/Map.js").Map} map The map.
|
|
18
|
+
* @param {string} url The URL of the dataset.
|
|
19
|
+
* @param {number} resolution The dataset resolution in geographical unit.
|
|
20
|
+
* @param {{preprocess?:(function(import("../core/Dataset.js").Cell):boolean),delimiter?:string}} opts
|
|
21
|
+
*/
|
|
22
|
+
constructor(map, url, resolution, opts = {}) {
|
|
23
|
+
super(map, url, resolution, opts)
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @private
|
|
27
|
+
* @type {Array.<import("../core/Dataset.js").Cell>} */
|
|
28
|
+
this.cells = []
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @private
|
|
32
|
+
* @type {string} */
|
|
33
|
+
this.delimiter = opts.delimiter || ','
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @type {string}
|
|
37
|
+
* @private */
|
|
38
|
+
this.infoLoadingStatus = 'notLoaded'
|
|
39
|
+
|
|
40
|
+
//get data
|
|
41
|
+
this.getData(undefined)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Request data within a geographic envelope.
|
|
46
|
+
* @param {import("../core/GeoCanvas.js").Envelope|undefined} e
|
|
47
|
+
*/
|
|
48
|
+
getData(e) {
|
|
49
|
+
//check if data already loaded
|
|
50
|
+
if (this.infoLoadingStatus != 'notLoaded') return this
|
|
51
|
+
|
|
52
|
+
//load data
|
|
53
|
+
this.infoLoadingStatus = 'loading'
|
|
54
|
+
;(async () => {
|
|
55
|
+
try {
|
|
56
|
+
const data = await dsv(this.delimiter, this.url)
|
|
57
|
+
|
|
58
|
+
//convert coordinates in numbers
|
|
59
|
+
for (const c of data) {
|
|
60
|
+
c.x = +c.x
|
|
61
|
+
c.y = +c.y
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//preprocess/filter
|
|
65
|
+
if (this.preprocess) {
|
|
66
|
+
this.cells = []
|
|
67
|
+
for (const c of data) {
|
|
68
|
+
const b = this.preprocess(c)
|
|
69
|
+
if (b == false) continue
|
|
70
|
+
this.cells.push(c)
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
this.cells = data
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
//TODO check if redraw is necessary
|
|
77
|
+
//that is if the dataset belongs to a layer which is visible at the current zoom level
|
|
78
|
+
|
|
79
|
+
//redraw map
|
|
80
|
+
if (this.map) this.map.redraw()
|
|
81
|
+
|
|
82
|
+
this.infoLoadingStatus = 'loaded'
|
|
83
|
+
} catch (error) {
|
|
84
|
+
//mark as failed
|
|
85
|
+
this.infoLoadingStatus = 'failed'
|
|
86
|
+
this.cells = []
|
|
87
|
+
}
|
|
88
|
+
})()
|
|
89
|
+
|
|
90
|
+
return this
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Fill the view cache with all cells which are within a geographical envelope.
|
|
95
|
+
*
|
|
96
|
+
* @param {import("../core/GeoCanvas.js").Envelope} extGeo
|
|
97
|
+
* @returns {void}
|
|
98
|
+
*/
|
|
99
|
+
updateViewCache(extGeo) {
|
|
100
|
+
//data not loaded yet
|
|
101
|
+
if (!this.cells) return
|
|
102
|
+
|
|
103
|
+
this.cellsViewCache = []
|
|
104
|
+
for (const cell of this.cells) {
|
|
105
|
+
if (+cell.x + this.resolution < extGeo.xMin) continue
|
|
106
|
+
if (+cell.x - this.resolution > extGeo.xMax) continue
|
|
107
|
+
if (+cell.y + this.resolution < extGeo.yMin) continue
|
|
108
|
+
if (+cell.y - this.resolution > extGeo.yMax) continue
|
|
109
|
+
this.cellsViewCache.push(cell)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|