gridviz 3.0.18 → 3.0.20

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/README.md +128 -127
  2. package/dist/gridviz.js +7862 -7819
  3. package/dist/gridviz.min.js +1 -1
  4. package/package.json +74 -74
  5. package/src/button/ZoomButtons.js +101 -101
  6. package/src/core/Dataset.js +154 -154
  7. package/src/core/Drawable.js +60 -60
  8. package/src/core/GeoCanvas.js +430 -419
  9. package/src/core/Layer.js +23 -23
  10. package/src/core/Legend.js +108 -108
  11. package/src/core/Map.js +516 -503
  12. package/src/core/MultiResolutionDataset.js +93 -93
  13. package/src/core/Style.js +98 -98
  14. package/src/core/Tooltip.js +1 -0
  15. package/src/dataset/CSVGrid.js +112 -112
  16. package/src/dataset/GeoTIFF.js +122 -122
  17. package/src/dataset/JSGrid.js +55 -55
  18. package/src/dataset/TiledGrid.js +302 -289
  19. package/src/dataset/worker.js +18 -18
  20. package/src/index.js +77 -77
  21. package/src/layer/BackgroundLayer.js +162 -162
  22. package/src/layer/BackgroundLayerImage.js +81 -81
  23. package/src/layer/BackgroundLayerWMS.js +104 -104
  24. package/src/layer/GeoJSONLayer.js +214 -214
  25. package/src/layer/GridLayer.js +148 -148
  26. package/src/layer/LabelLayer.js +194 -194
  27. package/src/legend/ColorCategoryLegend.js +109 -109
  28. package/src/legend/ColorDiscreteLegend.js +100 -100
  29. package/src/legend/ColorLegend.js +115 -115
  30. package/src/legend/OrientationLegend.js +89 -89
  31. package/src/legend/SizeLegend.js +224 -224
  32. package/src/legend/TernaryLegend.js +302 -302
  33. package/src/style/CompositionStyle.js +291 -291
  34. package/src/style/DotDensityStyle.js +133 -133
  35. package/src/style/ImageStyle.js +100 -100
  36. package/src/style/IsoFenceStyle.js +217 -217
  37. package/src/style/JoyPlotStyle.js +127 -127
  38. package/src/style/LegoStyle.js +110 -110
  39. package/src/style/MosaicStyle.js +99 -99
  40. package/src/style/NinjaStarStyle.js +102 -102
  41. package/src/style/PillarStyle.js +207 -207
  42. package/src/style/SegmentStyle.js +105 -105
  43. package/src/style/ShapeColorSizeStyle.js +147 -147
  44. package/src/style/SideCategoryStyle.js +112 -112
  45. package/src/style/SideStyle.js +212 -212
  46. package/src/style/SquareColorCategoryWebGLStyle.js +107 -107
  47. package/src/style/SquareColorWebGLStyle.js +126 -126
  48. package/src/style/StrokeStyle.js +135 -135
  49. package/src/style/TanakaStyle.js +69 -69
  50. package/src/style/TextStyle.js +110 -110
  51. package/src/style/TimeSeriesStyle.js +222 -222
  52. package/src/utils/scale.js +218 -218
  53. package/src/utils/stretching.js +120 -120
  54. package/src/utils/ternary.js +208 -203
  55. package/src/utils/utils.js +58 -58
  56. package/src/utils/webGLUtils.js +72 -72
package/package.json CHANGED
@@ -1,74 +1,74 @@
1
- {
2
- "name": "gridviz",
3
- "version": "3.0.18",
4
- "description": "Visualization tool for gridded statistics",
5
- "keywords": [
6
- "statistics",
7
- "grid",
8
- "gridded",
9
- "grids",
10
- "gridded statistics",
11
- "dataviz",
12
- "csv",
13
- "GIS",
14
- "WebGL",
15
- "d3",
16
- "cartography",
17
- "bertin",
18
- "geospatial",
19
- "mapping"
20
- ],
21
- "homepage": "https://github.com/eurostat/gridviz",
22
- "author": "Joseph Davies, Julien Gaffuri",
23
- "license": "EUPL-1.2",
24
- "repository": {
25
- "type": "git",
26
- "url": "git+https://github.com/eurostat/gridviz.git"
27
- },
28
- "bugs": {
29
- "url": "https://github.com/eurostat/gridviz/issues",
30
- "email": "Joseph.DAVIES@ext.ec.europa.eu"
31
- },
32
- "type": "module",
33
- "main": "dist/gridviz.min.js",
34
- "module": "dist/gridviz.min.js",
35
- "exports": {
36
- "umd": "./dist/gridviz.min.js",
37
- "default": "./src/index.js"
38
- },
39
- "scripts": {
40
- "start": "webpack --config webpack.config.dev.cjs",
41
- "server": "webpack serve -c webpack.config.dev.cjs",
42
- "doc": "jsdoc -c docs/jsdoc/jsdoc.conf.json",
43
- "build-prod": "webpack --config webpack.config.prod.cjs",
44
- "test": "jest",
45
- "format": "prettier --write ."
46
- },
47
- "files": [
48
- "dist/**/*.js",
49
- "src/**/*.js"
50
- ],
51
- "dependencies": {
52
- "d3-array": "^3.2.4",
53
- "d3-color": "^3.1.0",
54
- "d3-fetch": "^3.0.1",
55
- "d3-random": "^3.0.1",
56
- "d3-scale": "^4.0.2",
57
- "d3-selection": "^3.0.0",
58
- "d3-zoom": "^3.0.0",
59
- "jsdoc": "^4.0.4"
60
- },
61
- "devDependencies": {
62
- "@babel/preset-env": "^7.25.4",
63
- "babel-loader": "^8.1.0",
64
- "jshint": "^2.12.0",
65
- "prettier": "^2.8.8",
66
- "webpack": "^5.96.1",
67
- "webpack-cli": "^5.1.4",
68
- "webpack-dev-server": "^5.1.0",
69
- "webpack-livereload-plugin": "^3.0.2"
70
- },
71
- "engines": {
72
- "node": ">=14"
73
- }
74
- }
1
+ {
2
+ "name": "gridviz",
3
+ "version": "3.0.20",
4
+ "description": "Visualization tool for gridded statistics",
5
+ "keywords": [
6
+ "statistics",
7
+ "grid",
8
+ "gridded",
9
+ "grids",
10
+ "gridded statistics",
11
+ "dataviz",
12
+ "csv",
13
+ "GIS",
14
+ "WebGL",
15
+ "d3",
16
+ "cartography",
17
+ "bertin",
18
+ "geospatial",
19
+ "mapping"
20
+ ],
21
+ "homepage": "https://github.com/eurostat/gridviz",
22
+ "author": "Joseph Davies, Julien Gaffuri",
23
+ "license": "EUPL-1.2",
24
+ "repository": {
25
+ "type": "git",
26
+ "url": "git+https://github.com/eurostat/gridviz.git"
27
+ },
28
+ "bugs": {
29
+ "url": "https://github.com/eurostat/gridviz/issues",
30
+ "email": "Joseph.DAVIES@ext.ec.europa.eu"
31
+ },
32
+ "type": "module",
33
+ "main": "dist/gridviz.min.js",
34
+ "module": "dist/gridviz.min.js",
35
+ "exports": {
36
+ "umd": "./dist/gridviz.min.js",
37
+ "default": "./src/index.js"
38
+ },
39
+ "scripts": {
40
+ "start": "webpack --config webpack.config.dev.cjs",
41
+ "server": "webpack serve -c webpack.config.dev.cjs",
42
+ "doc": "jsdoc -c docs/jsdoc/jsdoc.conf.json",
43
+ "build-prod": "webpack --config webpack.config.prod.cjs",
44
+ "test": "jest",
45
+ "format": "prettier --write ."
46
+ },
47
+ "files": [
48
+ "dist/**/*.js",
49
+ "src/**/*.js"
50
+ ],
51
+ "dependencies": {
52
+ "d3-array": "^3.2.4",
53
+ "d3-color": "^3.1.0",
54
+ "d3-fetch": "^3.0.1",
55
+ "d3-random": "^3.0.1",
56
+ "d3-scale": "^4.0.2",
57
+ "d3-selection": "^3.0.0",
58
+ "d3-zoom": "^3.0.0",
59
+ "jsdoc": "^4.0.4"
60
+ },
61
+ "devDependencies": {
62
+ "@babel/preset-env": "^7.25.4",
63
+ "babel-loader": "^8.1.0",
64
+ "jshint": "^2.12.0",
65
+ "prettier": "^2.8.8",
66
+ "webpack": "^5.96.1",
67
+ "webpack-cli": "^5.1.4",
68
+ "webpack-dev-server": "^5.1.0",
69
+ "webpack-livereload-plugin": "^3.0.2"
70
+ },
71
+ "engines": {
72
+ "node": ">=14"
73
+ }
74
+ }
@@ -1,101 +1,101 @@
1
- import { Button } from './Button.js'
2
-
3
- /**
4
- * Button for toggling fullscreen mode
5
- *
6
- * @module button
7
- * @author Joseph Davies, Julien Gaffuri
8
- */
9
- export class ZoomButtons extends Button {
10
- /**
11
- * @param {Object} opts
12
- */
13
- constructor(opts) {
14
- super(opts)
15
-
16
- this.onZoom = opts.onZoom // custom user event handler
17
- this.delta = opts.delta || 0.2
18
-
19
- // Create zoom in button
20
- this.zoomInBtn = document.createElement('a')
21
- this.zoomInBtn.id = 'zoom-in'
22
- this.zoomInBtn.className = 'gridviz-zoom-button'
23
- this.zoomInBtn.title = 'Zoom in'
24
- this.zoomInBtn.textContent = '+'
25
- this.zoomInBtn.addEventListener('click', (e) => {
26
- this.zoomIn(e)
27
- })
28
- this.zoomInBtn.addEventListener('mouseover', () => {
29
- this.zoomInBtn.style.backgroundColor = 'lightgrey'
30
- })
31
- this.zoomInBtn.addEventListener('mouseout', () => {
32
- this.zoomInBtn.style.backgroundColor = '#ffffff'
33
- })
34
-
35
- // Create zoom out button
36
- this.zoomOutBtn = document.createElement('a')
37
- this.zoomOutBtn.id = 'zoom-out'
38
- this.zoomOutBtn.className = 'gridviz-zoom-button'
39
- this.zoomOutBtn.title = 'Zoom out'
40
- this.zoomOutBtn.textContent = '-'
41
- this.zoomOutBtn.addEventListener('click', (e) => {
42
- this.zoomOut(e)
43
- })
44
- this.zoomOutBtn.addEventListener('mouseover', () => {
45
- this.zoomOutBtn.style.backgroundColor = 'lightgrey'
46
- })
47
- this.zoomOutBtn.addEventListener('mouseout', () => {
48
- this.zoomOutBtn.style.backgroundColor = '#ffffff'
49
- })
50
-
51
- // Set common styles for buttons
52
- const buttons = [this.zoomInBtn, this.zoomOutBtn]
53
- buttons.forEach((btn, index) => {
54
- btn.style.alignItems = 'center'
55
- btn.style.justifyContent = 'center'
56
- btn.style.display = 'flex'
57
- btn.style.border = 'none'
58
- btn.style.color = 'black'
59
- btn.style.textAlign = 'center'
60
- btn.style.textDecoration = 'none'
61
- btn.style.padding = '4px'
62
- btn.style.fontSize = '24px'
63
- btn.style.fontWeight = 'bold'
64
- btn.style.userSelect = 'none'
65
- btn.style.backgroundColor = '#ffffff'
66
- if (index === 0) btn.style.borderBottom = '1px solid grey' // Zoom in button only
67
- })
68
-
69
- // Unset parent class height and display for dual buttons
70
- this.style('height', 'unset')
71
- this.style('display', 'unset')
72
-
73
- // Set position
74
- if (opts.x) {
75
- this.style('left', opts.x + 'px')
76
- } else {
77
- this.style('right', '10px')
78
- }
79
- if (opts.y) {
80
- this.style('top', opts.y + 'px')
81
- } else {
82
- this.style('top', '10px')
83
- }
84
-
85
- // Append buttons to the container
86
- this.div.node().appendChild(this.zoomInBtn)
87
- this.div.node().appendChild(this.zoomOutBtn)
88
- }
89
-
90
- /* Zoom in */
91
- zoomIn(e) {
92
- this.map.setZoom(this.map.getZoom() * (1 - this.delta)).redraw()
93
- if (this.onZoom) this.onZoom(e)
94
- }
95
-
96
- /* Zoom out */
97
- zoomOut(e) {
98
- this.map.setZoom(this.map.getZoom() * (1 + this.delta)).redraw()
99
- if (this.onZoom) this.onZoom(e)
100
- }
101
- }
1
+ import { Button } from './Button.js'
2
+
3
+ /**
4
+ * Button for toggling fullscreen mode
5
+ *
6
+ * @module button
7
+ * @author Joseph Davies, Julien Gaffuri
8
+ */
9
+ export class ZoomButtons extends Button {
10
+ /**
11
+ * @param {Object} opts
12
+ */
13
+ constructor(opts) {
14
+ super(opts)
15
+
16
+ this.onZoom = opts.onZoom // custom user event handler
17
+ this.delta = opts.delta || 0.2
18
+
19
+ // Create zoom in button
20
+ this.zoomInBtn = document.createElement('a')
21
+ this.zoomInBtn.id = 'zoom-in'
22
+ this.zoomInBtn.className = 'gridviz-zoom-button'
23
+ this.zoomInBtn.title = 'Zoom in'
24
+ this.zoomInBtn.textContent = '+'
25
+ this.zoomInBtn.addEventListener('click', (e) => {
26
+ this.zoomIn(e)
27
+ })
28
+ this.zoomInBtn.addEventListener('mouseover', () => {
29
+ this.zoomInBtn.style.backgroundColor = 'lightgrey'
30
+ })
31
+ this.zoomInBtn.addEventListener('mouseout', () => {
32
+ this.zoomInBtn.style.backgroundColor = '#ffffff'
33
+ })
34
+
35
+ // Create zoom out button
36
+ this.zoomOutBtn = document.createElement('a')
37
+ this.zoomOutBtn.id = 'zoom-out'
38
+ this.zoomOutBtn.className = 'gridviz-zoom-button'
39
+ this.zoomOutBtn.title = 'Zoom out'
40
+ this.zoomOutBtn.textContent = '-'
41
+ this.zoomOutBtn.addEventListener('click', (e) => {
42
+ this.zoomOut(e)
43
+ })
44
+ this.zoomOutBtn.addEventListener('mouseover', () => {
45
+ this.zoomOutBtn.style.backgroundColor = 'lightgrey'
46
+ })
47
+ this.zoomOutBtn.addEventListener('mouseout', () => {
48
+ this.zoomOutBtn.style.backgroundColor = '#ffffff'
49
+ })
50
+
51
+ // Set common styles for buttons
52
+ const buttons = [this.zoomInBtn, this.zoomOutBtn]
53
+ buttons.forEach((btn, index) => {
54
+ btn.style.alignItems = 'center'
55
+ btn.style.justifyContent = 'center'
56
+ btn.style.display = 'flex'
57
+ btn.style.border = 'none'
58
+ btn.style.color = 'black'
59
+ btn.style.textAlign = 'center'
60
+ btn.style.textDecoration = 'none'
61
+ btn.style.padding = '4px'
62
+ btn.style.fontSize = '24px'
63
+ btn.style.fontWeight = 'bold'
64
+ btn.style.userSelect = 'none'
65
+ btn.style.backgroundColor = '#ffffff'
66
+ if (index === 0) btn.style.borderBottom = '1px solid grey' // Zoom in button only
67
+ })
68
+
69
+ // Unset parent class height and display for dual buttons
70
+ this.style('height', 'unset')
71
+ this.style('display', 'unset')
72
+
73
+ // Set position
74
+ if (opts.x) {
75
+ this.style('left', opts.x + 'px')
76
+ } else {
77
+ this.style('right', '10px')
78
+ }
79
+ if (opts.y) {
80
+ this.style('top', opts.y + 'px')
81
+ } else {
82
+ this.style('top', '10px')
83
+ }
84
+
85
+ // Append buttons to the container
86
+ this.div.node().appendChild(this.zoomInBtn)
87
+ this.div.node().appendChild(this.zoomOutBtn)
88
+ }
89
+
90
+ /* Zoom in */
91
+ zoomIn(e) {
92
+ this.map.setZoom(this.map.getZoom() * (1 - this.delta)).redraw()
93
+ if (this.onZoom) this.onZoom(e)
94
+ }
95
+
96
+ /* Zoom out */
97
+ zoomOut(e) {
98
+ this.map.setZoom(this.map.getZoom() * (1 + this.delta)).redraw()
99
+ if (this.onZoom) this.onZoom(e)
100
+ }
101
+ }
@@ -1,154 +1,154 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- /**
5
- * A grid cell.
6
- * @typedef {{x: number, y: number}} Cell */
7
-
8
- /**
9
- * A dataset component, of grid cells.
10
- * @abstract
11
- *
12
- * @module core
13
- * @author Joseph Davies, Julien Gaffuri
14
- */
15
- export class Dataset {
16
- /**
17
- * @param {import("./Map.js").Map} map The map.
18
- * @param {string} url The URL of the dataset.
19
- * @param {number} resolution The dataset resolution, in the CRS geographical unit.
20
- * @param {{preprocess?:function(Cell):boolean, mixedResolution?:function(Cell):number}} opts
21
- * @abstract
22
- */
23
- constructor(map, url, resolution, opts = {}) {
24
- /**
25
- * The map.
26
- * @protected
27
- * @type {import("./Map.js").Map} */
28
- this.map = map
29
-
30
- /**
31
- * The url of the dataset.
32
- * @protected
33
- * @type {string} */
34
- this.url = url
35
-
36
- /**
37
- * The dataset resolution in geographical unit.
38
- * @protected
39
- * @type {number} */
40
- this.resolution = resolution
41
-
42
- /**
43
- * In case the dataset is a dataset with cells having different resolution,
44
- * this is the function returning the resolution of each cell.
45
- * @protected
46
- * @type {(function(Cell):number )| undefined } */
47
- this.mixedResolution = opts.mixedResolution
48
-
49
- /**
50
- * A preprocess to run on each cell after loading. It can be used to apply some specific treatment before or compute a new column. And also to determine which cells to keep after loading.
51
- * @type {(function(Cell):boolean )| undefined } */
52
- this.preprocess = opts.preprocess || undefined
53
-
54
- /** The cells within the view
55
- * @protected
56
- * @type {Array.<Cell>} */
57
- this.cellsViewCache = []
58
- }
59
-
60
- /**
61
- * Request data within a geographic envelope.
62
- *
63
- * @abstract
64
- * @param {import("./GeoCanvas").Envelope|undefined} extGeo
65
- * @returns {this}
66
- */
67
- getData(extGeo = undefined) {
68
- throw new Error('Method getData not implemented.')
69
- }
70
-
71
- /**
72
- * Fill the view cache with all cells which are within a geographical envelope.
73
- * @abstract
74
- * @param {import("./GeoCanvas").Envelope} extGeo The view geographical envelope.
75
- * @returns {void}
76
- */
77
- updateViewCache(extGeo) {
78
- throw new Error('Method updateViewCache not implemented.')
79
- }
80
-
81
- /**
82
- * Get a cell under a given position, if any.
83
- *
84
- * @param {{x:number,y:number}} posGeo
85
- * @param {Array.<Cell>} cells Some cells from the dataset (a subset if necessary, usually the view cache).
86
- * @returns {Cell|undefined}
87
- */
88
- getCellFromPosition(posGeo, cells) {
89
- //compute candidate cell position
90
- /** @type {number} */
91
- //const r = this.getResolution()
92
- /** @type {number} */
93
- //const cellX = r * Math.floor(posGeo.x / r)
94
- /** @type {number} */
95
- //const cellY = r * Math.floor(posGeo.y / r)
96
-
97
- /*/get cell
98
- for (const cell of cells) {
99
- if (cell.x != cellX) continue
100
- if (cell.y != cellY) continue
101
- return cell
102
- }
103
- return undefined*/
104
-
105
- //rare case of mixed resolution dataset
106
- if (this.mixedResolution) {
107
- for (const c of cells) {
108
- /** @type {number} */
109
- const r = +this.mixedResolution(c)
110
- if (posGeo.x < c.x) continue
111
- else if (c.x + r < posGeo.x) continue
112
- else if (posGeo.y < c.y) continue
113
- else if (c.y + r < posGeo.y) continue
114
- else return c
115
- }
116
- return undefined
117
- }
118
-
119
- //common case
120
-
121
- /** @type {number} */
122
- const r = this.getResolution()
123
- for (const cell of cells) {
124
- if (posGeo.x < cell.x) continue
125
- else if (cell.x + r < posGeo.x) continue
126
- else if (posGeo.y < cell.y) continue
127
- else if (cell.y + r < posGeo.y) continue
128
- else return cell
129
- }
130
- return undefined
131
- }
132
-
133
- //getters and setters
134
-
135
- /** @returns {number} */
136
- getResolution() {
137
- return this.resolution
138
- }
139
-
140
- /** @returns {Array.<Cell>} */
141
- getViewCache() {
142
- return this.cellsViewCache
143
- }
144
-
145
- /**
146
- * Return the relevant dataset for a specified zoom.
147
- * @param {number} z
148
- * @param {number} minPixelsPerCell
149
- * @returns {Dataset|undefined}
150
- * */
151
- getDataset(z, minPixelsPerCell) {
152
- return this
153
- }
154
- }
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ /**
5
+ * A grid cell.
6
+ * @typedef {{x: number, y: number}} Cell */
7
+
8
+ /**
9
+ * A dataset component, of grid cells.
10
+ * @abstract
11
+ *
12
+ * @module core
13
+ * @author Joseph Davies, Julien Gaffuri
14
+ */
15
+ export class Dataset {
16
+ /**
17
+ * @param {import("./Map.js").Map} map The map.
18
+ * @param {string} url The URL of the dataset.
19
+ * @param {number} resolution The dataset resolution, in the CRS geographical unit.
20
+ * @param {{preprocess?:function(Cell):boolean, mixedResolution?:function(Cell):number}} opts
21
+ * @abstract
22
+ */
23
+ constructor(map, url, resolution, opts = {}) {
24
+ /**
25
+ * The map.
26
+ * @protected
27
+ * @type {import("./Map.js").Map} */
28
+ this.map = map
29
+
30
+ /**
31
+ * The url of the dataset.
32
+ * @protected
33
+ * @type {string} */
34
+ this.url = url
35
+
36
+ /**
37
+ * The dataset resolution in geographical unit.
38
+ * @protected
39
+ * @type {number} */
40
+ this.resolution = resolution
41
+
42
+ /**
43
+ * In case the dataset is a dataset with cells having different resolution,
44
+ * this is the function returning the resolution of each cell.
45
+ * @protected
46
+ * @type {(function(Cell):number )| undefined } */
47
+ this.mixedResolution = opts.mixedResolution
48
+
49
+ /**
50
+ * A preprocess to run on each cell after loading. It can be used to apply some specific treatment before or compute a new column. And also to determine which cells to keep after loading.
51
+ * @type {(function(Cell):boolean )| undefined } */
52
+ this.preprocess = opts.preprocess || undefined
53
+
54
+ /** The cells within the view
55
+ * @protected
56
+ * @type {Array.<Cell>} */
57
+ this.cellsViewCache = []
58
+ }
59
+
60
+ /**
61
+ * Request data within a geographic envelope.
62
+ *
63
+ * @abstract
64
+ * @param {import("./GeoCanvas").Envelope|undefined} extGeo
65
+ * @returns {this}
66
+ */
67
+ getData(extGeo = undefined) {
68
+ throw new Error('Method getData not implemented.')
69
+ }
70
+
71
+ /**
72
+ * Fill the view cache with all cells which are within a geographical envelope.
73
+ * @abstract
74
+ * @param {import("./GeoCanvas").Envelope} extGeo The view geographical envelope.
75
+ * @returns {void}
76
+ */
77
+ updateViewCache(extGeo) {
78
+ throw new Error('Method updateViewCache not implemented.')
79
+ }
80
+
81
+ /**
82
+ * Get a cell under a given position, if any.
83
+ *
84
+ * @param {{x:number,y:number}} posGeo
85
+ * @param {Array.<Cell>} cells Some cells from the dataset (a subset if necessary, usually the view cache).
86
+ * @returns {Cell|undefined}
87
+ */
88
+ getCellFromPosition(posGeo, cells) {
89
+ //compute candidate cell position
90
+ /** @type {number} */
91
+ //const r = this.getResolution()
92
+ /** @type {number} */
93
+ //const cellX = r * Math.floor(posGeo.x / r)
94
+ /** @type {number} */
95
+ //const cellY = r * Math.floor(posGeo.y / r)
96
+
97
+ /*/get cell
98
+ for (const cell of cells) {
99
+ if (cell.x != cellX) continue
100
+ if (cell.y != cellY) continue
101
+ return cell
102
+ }
103
+ return undefined*/
104
+
105
+ //rare case of mixed resolution dataset
106
+ if (this.mixedResolution) {
107
+ for (const c of cells) {
108
+ /** @type {number} */
109
+ const r = +this.mixedResolution(c)
110
+ if (posGeo.x < c.x) continue
111
+ else if (c.x + r < posGeo.x) continue
112
+ else if (posGeo.y < c.y) continue
113
+ else if (c.y + r < posGeo.y) continue
114
+ else return c
115
+ }
116
+ return undefined
117
+ }
118
+
119
+ //common case
120
+
121
+ /** @type {number} */
122
+ const r = this.getResolution()
123
+ for (const cell of cells) {
124
+ if (posGeo.x < cell.x) continue
125
+ else if (cell.x + r < posGeo.x) continue
126
+ else if (posGeo.y < cell.y) continue
127
+ else if (cell.y + r < posGeo.y) continue
128
+ else return cell
129
+ }
130
+ return undefined
131
+ }
132
+
133
+ //getters and setters
134
+
135
+ /** @returns {number} */
136
+ getResolution() {
137
+ return this.resolution
138
+ }
139
+
140
+ /** @returns {Array.<Cell>} */
141
+ getViewCache() {
142
+ return this.cellsViewCache
143
+ }
144
+
145
+ /**
146
+ * Return the relevant dataset for a specified zoom.
147
+ * @param {number} z
148
+ * @param {number} minPixelsPerCell
149
+ * @returns {Dataset|undefined}
150
+ * */
151
+ getDataset(z, minPixelsPerCell) {
152
+ return this
153
+ }
154
+ }