gridviz 3.0.34 → 3.0.36

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 (67) hide show
  1. package/README.md +129 -129
  2. package/dist/gridviz.js +17487 -17471
  3. package/dist/gridviz.min.js +2 -2
  4. package/package.json +73 -73
  5. package/src/button/Button.js +67 -67
  6. package/src/button/FullscreenButton.js +121 -121
  7. package/src/button/ZoomButtons.js +103 -103
  8. package/src/core/Dataset.js +154 -154
  9. package/src/core/Drawable.js +78 -78
  10. package/src/core/GeoCanvas.js +443 -443
  11. package/src/core/Layer.js +23 -23
  12. package/src/core/Legend.js +108 -108
  13. package/src/core/Map.js +568 -552
  14. package/src/core/MultiResolutionDataset.js +93 -93
  15. package/src/core/Style.js +98 -98
  16. package/src/core/Tooltip.js +182 -182
  17. package/src/dataset/COGeo.js +25 -25
  18. package/src/dataset/CSVGrid.js +112 -112
  19. package/src/dataset/GeoTIFF.js +122 -122
  20. package/src/dataset/JSGrid.js +55 -55
  21. package/src/dataset/TiledGrid.js +302 -302
  22. package/src/dataset/worker.js +18 -18
  23. package/src/index.js +79 -79
  24. package/src/layer/BackgroundLayer.js +173 -173
  25. package/src/layer/BackgroundLayerImage.js +81 -81
  26. package/src/layer/BackgroundLayerWMS.js +104 -104
  27. package/src/layer/GeoJSONLayer.js +276 -276
  28. package/src/layer/GridLayer.js +166 -166
  29. package/src/layer/LabelLayer.js +194 -194
  30. package/src/legend/ColorCategoryLegend.js +109 -109
  31. package/src/legend/ColorDiscreteLegend.js +100 -100
  32. package/src/legend/ColorLegend.js +115 -115
  33. package/src/legend/OrientationLegend.js +89 -89
  34. package/src/legend/SizeLegend.js +224 -224
  35. package/src/legend/TernaryLegend.js +302 -302
  36. package/src/style/CompositionStyle.js +291 -291
  37. package/src/style/DotDensityStyle.js +133 -133
  38. package/src/style/ImageStyle.js +100 -100
  39. package/src/style/Interpolator.js +258 -258
  40. package/src/style/IsoFenceStyle.js +217 -217
  41. package/src/style/JoyPlotStyle.js +180 -180
  42. package/src/style/LegoStyle.js +132 -132
  43. package/src/style/MosaicStyle.js +99 -99
  44. package/src/style/NinjaStarStyle.js +102 -102
  45. package/src/style/PillarStyle.js +207 -207
  46. package/src/style/SegmentStyle.js +105 -105
  47. package/src/style/ShadingRayStyle.js +280 -280
  48. package/src/style/ShadingStyle.js +72 -72
  49. package/src/style/ShapeColorSizeStyle.js +147 -147
  50. package/src/style/SideCategoryStyle.js +112 -112
  51. package/src/style/SideStyle.js +217 -217
  52. package/src/style/SideTanakaStyle.js +154 -154
  53. package/src/style/SquareColorCategoryWebGLStyle.js +307 -294
  54. package/src/style/SquareColorWebGLStyle.js +126 -126
  55. package/src/style/StrokeStyle.js +135 -135
  56. package/src/style/TextStyle.js +110 -110
  57. package/src/style/TimeSeriesStyle.js +222 -222
  58. package/src/utils/WebGLRectangleColoring.js +106 -106
  59. package/src/utils/WebGLSquareColoring.js +118 -118
  60. package/src/utils/WebGLSquareColoringAdvanced.js +227 -227
  61. package/src/utils/WebGLSquareColoringKS.js +153 -153
  62. package/src/utils/scale.js +255 -255
  63. package/src/utils/stretching.js +120 -120
  64. package/src/utils/ternary.js +208 -208
  65. package/src/utils/utils.js +125 -125
  66. package/src/utils/webGLUtils.js +73 -73
  67. package/src/utils/zoomUtils.js +142 -142
@@ -1,295 +1,308 @@
1
- //@ts-check
2
- 'use strict'
3
-
4
- import { Style } from '../core/Style.js'
5
- import { initShaderProgram, createShader, makeWebGLCanvas } from '../utils/webGLUtils.js'
6
- import { color } from 'd3-color'
7
-
8
- /**
9
- * Style based on webGL
10
- * To show cells as colored squares, from categories.
11
- * All cells are drawn as squares, with the same size
12
- *
13
- * @module style
14
- * @author Julien Gaffuri
15
- */
16
- export class SquareColorCategoryWebGLStyle extends Style {
17
- /** @param {object} opts */
18
- constructor(opts) {
19
- super(opts)
20
- opts = opts || {}
21
-
22
- /**
23
- * A function returning the category code of the cell, for coloring.
24
- * @type {function(import('../core/Dataset.js').Cell, number, number, viewScale):string} */
25
- this.code = opts.code // (c, resolution, z, viewScale) => "code1"
26
-
27
- /**
28
- * The dictionary (code -> color) which gives the color of each category code.
29
- * @type {object} */
30
- opts.color = opts.color || undefined
31
-
32
- /** @type { Array.<string> } */
33
- const codes = Object.keys(opts.color)
34
-
35
- /** @type { object } @private */
36
- this.catToI = {}
37
- for (let i = 0; i < codes.length; i++) this.catToI[codes[i]] = i + ''
38
-
39
- /** @type { Array.<string> } @private */
40
- this.colors = []
41
- for (const code of codes) this.colors.push(opts.color['' + code])
42
-
43
- /**
44
- * A function returning the size of the cells, in geographical unit. All cells have the same size.
45
- * @type {function(number,number):number} */
46
- this.size = opts.size // (resolution, z) => ...
47
-
48
- /** * @type {{canvas:HTMLCanvasElement, gl:WebGLRenderingContext, width:number, height:number }}*/
49
- this.cvWGL = undefined
50
- this.programm = undefined
51
-
52
- this.x = undefined
53
- this.y = undefined
54
- this.z = undefined
55
- this.cellsNb = undefined
56
- }
57
-
58
- init(w, h) {
59
- this.cvWGL = makeWebGLCanvas(w + '', h + '')
60
- if (!this.cvWGL) { console.error('No webGL'); return }
61
-
62
- const gl = this.cvWGL.gl
63
-
64
- //draw
65
- const vectorShader = `
66
- attribute vec2 pos;
67
- uniform float sizePix;
68
- uniform mat3 mat;
69
- attribute float i;
70
- varying float vi;
71
- void main() {
72
- gl_Position = vec4(mat * vec3(pos, 1.0), 1.0);
73
- gl_PointSize = sizePix;
74
- vi = i;
75
- }`
76
- /** @type {WebGLShader} */
77
- const vShader = createShader(gl, gl.VERTEX_SHADER, vectorShader)
78
-
79
- const fragmentShader = `
80
- precision highp float;
81
- varying float vi;
82
- uniform sampler2D colorLUT;
83
- uniform float lutSize;
84
- void main(void) {
85
- float idx = floor(vi + 0.5);
86
- float u = (idx + 0.5) / lutSize;
87
- gl_FragColor = texture2D(colorLUT, vec2(u, 0.5));
88
- }`
89
- /** @type {WebGLShader} */
90
- const fShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShader)
91
-
92
- /** @type {WebGLProgram} */
93
- this.program = initShaderProgram(gl, vShader, fShader)
94
- gl.useProgram(this.program)
95
- }
96
-
97
- bindColors() {
98
- const gl = this.cvWGL.gl
99
- const lutSize = this.colors.length;
100
- const lutData = new Uint8Array(lutSize * 4); // RGBA for each entry
101
-
102
- // Fill lutData with your color values (e.g., rainbow, grayscale, etc.)
103
- for (let i = 0; i < lutSize; i++) {
104
- const c = color(this.colors[i])
105
- lutData[i * 4] = +c.r; // R
106
- lutData[i * 4 + 1] = c.g; // G
107
- lutData[i * 4 + 2] = c.b; // B
108
- lutData[i * 4 + 3] = c?.opacity * 255; // A
109
- }
110
-
111
- // Create and bind texture
112
- const lutTexture = gl.createTexture();
113
- gl.bindTexture(gl.TEXTURE_2D, lutTexture);
114
- gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, lutSize, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, lutData);
115
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
116
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
117
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
118
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
119
-
120
- // Get uniform locations
121
- const uColorLUT = gl.getUniformLocation(this.program, 'colorLUT');
122
- const uLutSize = gl.getUniformLocation(this.program, 'lutSize');
123
-
124
- // Set uniform values
125
- gl.uniform1i(uColorLUT, 0); // Texture unit 0
126
- gl.uniform1f(uLutSize, lutSize);
127
-
128
- // Bind the texture to texture unit 0
129
- gl.activeTexture(gl.TEXTURE0);
130
- gl.bindTexture(gl.TEXTURE_2D, lutTexture);
131
- }
132
-
133
- bindVertices(cells, resolution, z, viewScale) {
134
- const gl = this.cvWGL.gl
135
- //add vertice and fragment data
136
- const r2 = resolution / 2
137
- let c, nb = cells.length
138
- const verticesBuffer = []
139
- const iBuffer = []
140
- for (let i = 0; i < nb; i++) {
141
- c = cells[i]
142
- const cat = this.code(c, resolution, z, viewScale)
143
- if (cat == undefined) {
144
- //console.log('Unexpected category: ' + cat)
145
- continue
146
- }
147
- const i_ = this.catToI[cat]
148
- if (isNaN(+i_)) {
149
- console.log('Unexpected category index: ' + cat + ' ' + i_)
150
- continue
151
- }
152
- verticesBuffer.push(c.x + r2, c.y + r2)
153
- iBuffer.push(+i_)
154
- }
155
-
156
- //bind vertice data
157
- gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer())
158
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticesBuffer), gl.STATIC_DRAW)
159
- const position = gl.getAttribLocation(this.program, 'pos')
160
- gl.vertexAttribPointer(
161
- position,
162
- 2, //numComponents
163
- gl.FLOAT, //type
164
- false, //normalise
165
- 0, //stride
166
- 0 //offset
167
- )
168
- gl.enableVertexAttribArray(position)
169
-
170
- //i data
171
- gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer())
172
- gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(iBuffer), gl.STATIC_DRAW)
173
- const i = gl.getAttribLocation(this.program, 'i')
174
- gl.vertexAttribPointer(i, 1, gl.FLOAT, false, 0, 0)
175
- gl.enableVertexAttribArray(i)
176
- }
177
-
178
-
179
-
180
- // check if the vertices have to be bound again
181
- mapContentChanged(v, cellsNb) {
182
- if (v.x == this.x && v.y == this.y && v.z == this.z && this.cellsNb == cellsNb) return false
183
- this.x = v.x
184
- this.y = v.y
185
- this.z = v.z
186
- this.cellsNb = cellsNb
187
- return true
188
- }
189
-
190
-
191
- /**
192
- * @param {Array.<import("../core/Dataset.js").Cell>} cells
193
- * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
194
- * @param {number} resolution
195
- */
196
- draw(cells, geoCanvas, resolution) {
197
- //filter
198
- if (this.filter) cells = cells.filter(this.filter)
199
-
200
- //
201
- const z = geoCanvas.view.z
202
-
203
- //get view scale
204
- const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
205
-
206
- //create canvas and webgl renderer
207
- if (!this.cvWGL || geoCanvas.w != this.cvWGL.width || geoCanvas.h != this.cvWGL.height) {
208
- this.init(geoCanvas.w, geoCanvas.h)
209
- this.bindColors()
210
- }
211
- const gl = this.cvWGL.gl
212
- const canvas = this.cvWGL.canvas
213
-
214
- //bind sizePix
215
- const sizePix = this.size ? this.size(resolution, z) / z : resolution / z + 0.2
216
- gl.uniform1f(gl.getUniformLocation(this.program, 'sizePix'), 1.0 * sizePix)
217
-
218
- //
219
- if (this.mapContentChanged(geoCanvas.view, cells.length))
220
- //bind vertices
221
- this.bindVertices(cells, resolution, z, viewScale)
222
- //transformation
223
- gl.uniformMatrix3fv(gl.getUniformLocation(this.program, 'mat'), false, new Float32Array(geoCanvas.getWebGLTransform()))
224
-
225
- // Enable the depth test
226
- //gl.enable(gl.DEPTH_TEST);
227
- // Clear the color buffer bit
228
- gl.clear(gl.COLOR_BUFFER_BIT)
229
- // Set the view port
230
- //gl.viewport(0, 0, cg.w, cg.h);
231
-
232
- gl.drawArrays(gl.POINTS, 0, cells.length)
233
-
234
- //draw in canvas geo
235
- geoCanvas.initCanvasTransform()
236
- geoCanvas.offscreenCtx.drawImage(canvas, 0, 0)
237
-
238
- //update legends
239
- this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
240
- }
241
- }
242
-
243
-
244
-
245
- // early tests for webgl2 migration
246
-
247
- /*
248
- function getVectorShader2() {
249
- return `
250
- #version 300 es
251
- precision highp float;
252
-
253
- in vec2 pos;
254
- in int i;
255
-
256
- uniform float sizePix;
257
- uniform mat3 mat;
258
-
259
- flat out int vi;
260
-
261
- void main() {
262
- gl_Position = vec4(mat * vec3(pos, 1.0), 1.0);
263
- gl_PointSize = sizePix;
264
- vi = i;
265
- }
266
- `
267
- }
268
-
269
-
270
- function getFragmentShader2(colors) {
271
-
272
- //prepare fragment shader code
273
- //declare the uniform and other variables
274
- const out = []
275
- out.push('#version 300 es\nprecision highp float;\nflat in int vi;\n')
276
-
277
- //add color uniforms
278
- //uniform vec4 colors[12];
279
- out.push('uniform vec4 colors[')
280
- out.push(colors.length)
281
- out.push('];\n')
282
-
283
- out.push('out vec4 fragColor;\n')
284
-
285
- //start the main function
286
- //void main() { fragColor = colors[clamp(vi, 0, 11)]; }
287
- out.push('void main() { fragColor = colors[vi]; }\n')
288
-
289
- /** Fragment shader program
290
- const fshString = out.join('')
291
- console.log(fshString)
292
- return fshString
293
- }
294
-
1
+ //@ts-check
2
+ 'use strict'
3
+
4
+ import { Style } from '../core/Style.js'
5
+ import { initShaderProgram, createShader, makeWebGLCanvas } from '../utils/webGLUtils.js'
6
+ import { color } from 'd3-color'
7
+
8
+ /**
9
+ * Style based on webGL
10
+ * To show cells as colored squares, from categories.
11
+ * All cells are drawn as squares, with the same size
12
+ *
13
+ * @module style
14
+ * @author Julien Gaffuri
15
+ */
16
+ export class SquareColorCategoryWebGLStyle extends Style {
17
+ /** @param {object} opts */
18
+ constructor(opts) {
19
+ super(opts)
20
+ opts = opts || {}
21
+
22
+ /**
23
+ * A function returning the category code of the cell, for coloring.
24
+ * @type {function(import('../core/Dataset.js').Cell, number, number, viewScale):string} */
25
+ this.code = opts.code // (c, resolution, z, viewScale) => "code1"
26
+
27
+ /**
28
+ * The dictionary (code -> color) which gives the color of each category code.
29
+ * @type {object} */
30
+ opts.color = opts.color || undefined
31
+
32
+ /** @type { Array.<string> } */
33
+ const codes = Object.keys(opts.color)
34
+
35
+ /** @type { object } @private */
36
+ this.catToI = {}
37
+ for (let i = 0; i < codes.length; i++) this.catToI[codes[i]] = i + ''
38
+
39
+ /** @type { Array.<string> } @private */
40
+ this.colors = []
41
+ for (const code of codes) this.colors.push(opts.color['' + code])
42
+
43
+ /**
44
+ * A function returning the size of the cells, in geographical unit. All cells have the same size.
45
+ * @type {function(number,number):number} */
46
+ this.size = opts.size // (resolution, z) => ...
47
+
48
+ /** * @type {{canvas:HTMLCanvasElement, gl:WebGLRenderingContext, width:number, height:number }}*/
49
+ this.cvWGL = undefined
50
+ this.programm = undefined
51
+
52
+ this.x = undefined
53
+ this.y = undefined
54
+ this.z = undefined
55
+ this.cellsNb = undefined
56
+ }
57
+
58
+ init(w, h) {
59
+ this.cvWGL = makeWebGLCanvas(w + '', h + '')
60
+ if (!this.cvWGL) { console.error('No webGL'); return }
61
+
62
+ const gl = this.cvWGL.gl
63
+
64
+ //draw
65
+ const vectorShader = `
66
+ attribute vec2 pos;
67
+ uniform float sizePix;
68
+ uniform mat3 mat;
69
+ attribute float i;
70
+ varying float vi;
71
+ void main() {
72
+ gl_Position = vec4(mat * vec3(pos, 1.0), 1.0);
73
+ gl_PointSize = sizePix;
74
+ vi = i;
75
+ }`
76
+ /** @type {WebGLShader} */
77
+ const vShader = createShader(gl, gl.VERTEX_SHADER, vectorShader)
78
+
79
+ const fragmentShader = `
80
+ precision highp float;
81
+ varying float vi;
82
+ uniform sampler2D colorLUT;
83
+ uniform float lutSize;
84
+ void main(void) {
85
+ float idx = floor(vi + 0.5);
86
+ float u = (idx + 0.5) / lutSize;
87
+ gl_FragColor = texture2D(colorLUT, vec2(u, 0.5));
88
+ }`
89
+ /** @type {WebGLShader} */
90
+ const fShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShader)
91
+
92
+ /** @type {WebGLProgram} */
93
+ this.program = initShaderProgram(gl, vShader, fShader)
94
+ gl.useProgram(this.program)
95
+ }
96
+
97
+ bindColors() {
98
+ const gl = this.cvWGL.gl
99
+ const lutSize = this.colors.length;
100
+ const lutData = new Uint8Array(lutSize * 4); // RGBA for each entry
101
+
102
+ // Fill lutData with your color values (e.g., rainbow, grayscale, etc.)
103
+ for (let i = 0; i < lutSize; i++) {
104
+ const c = color(this.colors[i])
105
+ lutData[i * 4] = +c.r; // R
106
+ lutData[i * 4 + 1] = c.g; // G
107
+ lutData[i * 4 + 2] = c.b; // B
108
+ lutData[i * 4 + 3] = c?.opacity * 255; // A
109
+ }
110
+
111
+ // Create and bind texture
112
+ const lutTexture = gl.createTexture();
113
+ gl.bindTexture(gl.TEXTURE_2D, lutTexture);
114
+ gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, lutSize, 1, 0, gl.RGBA, gl.UNSIGNED_BYTE, lutData);
115
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
116
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
117
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
118
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
119
+
120
+ // Get uniform locations
121
+ const uColorLUT = gl.getUniformLocation(this.program, 'colorLUT');
122
+ const uLutSize = gl.getUniformLocation(this.program, 'lutSize');
123
+
124
+ // Set uniform values
125
+ gl.uniform1i(uColorLUT, 0); // Texture unit 0
126
+ gl.uniform1f(uLutSize, lutSize);
127
+
128
+ // Bind the texture to texture unit 0
129
+ gl.activeTexture(gl.TEXTURE0);
130
+ gl.bindTexture(gl.TEXTURE_2D, lutTexture);
131
+ }
132
+
133
+ bindVertices(cells, resolution, z, viewScale) {
134
+ const gl = this.cvWGL.gl
135
+ //add vertice and fragment data
136
+ const r2 = resolution / 2
137
+ let c, nb = cells.length
138
+ const verticesBuffer = []
139
+ const iBuffer = []
140
+ for (let i = 0; i < nb; i++) {
141
+ c = cells[i]
142
+ const cat = this.code(c, resolution, z, viewScale)
143
+ if (cat == undefined) {
144
+ //console.log('Unexpected category: ' + cat)
145
+ continue
146
+ }
147
+ const i_ = this.catToI[cat]
148
+ if (isNaN(+i_)) {
149
+ console.log('Unexpected category index: ' + cat + ' ' + i_)
150
+ continue
151
+ }
152
+ verticesBuffer.push(c.x + r2, c.y + r2)
153
+ iBuffer.push(+i_)
154
+ }
155
+
156
+ //bind vertice data
157
+ gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer())
158
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(verticesBuffer), gl.STATIC_DRAW)
159
+ const position = gl.getAttribLocation(this.program, 'pos')
160
+ gl.vertexAttribPointer(
161
+ position,
162
+ 2, //numComponents
163
+ gl.FLOAT, //type
164
+ false, //normalise
165
+ 0, //stride
166
+ 0 //offset
167
+ )
168
+ gl.enableVertexAttribArray(position)
169
+
170
+ //i data
171
+ gl.bindBuffer(gl.ARRAY_BUFFER, gl.createBuffer())
172
+ gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(iBuffer), gl.STATIC_DRAW)
173
+ const i = gl.getAttribLocation(this.program, 'i')
174
+ gl.vertexAttribPointer(i, 1, gl.FLOAT, false, 0, 0)
175
+ gl.enableVertexAttribArray(i)
176
+ }
177
+
178
+
179
+
180
+ // check if the vertices have to be bound again
181
+ mapContentChanged(v, cellsNb) {
182
+ if (v.x == this.x && v.y == this.y && v.z == this.z && this.cellsNb == cellsNb) return false
183
+ this.x = v.x
184
+ this.y = v.y
185
+ this.z = v.z
186
+ this.cellsNb = cellsNb
187
+ return true
188
+ }
189
+
190
+
191
+ /**
192
+ * @param {Array.<import("../core/Dataset.js").Cell>} cells
193
+ * @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
194
+ * @param {number} resolution
195
+ */
196
+ draw(cells, geoCanvas, resolution) {
197
+ //filter
198
+ if (this.filter) cells = cells.filter(this.filter)
199
+
200
+ //
201
+ const z = geoCanvas.view.z
202
+
203
+ //get view scale
204
+ const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
205
+
206
+ //create canvas and webgl renderer
207
+ let contextRecreated = false
208
+ if (!this.cvWGL || geoCanvas.w != this.cvWGL.width || geoCanvas.h != this.cvWGL.height) {
209
+ contextRecreated = true
210
+ this.init(geoCanvas.w, geoCanvas.h)
211
+ this.bindColors()
212
+ }
213
+ const gl = this.cvWGL.gl
214
+ const canvas = this.cvWGL.canvas
215
+
216
+ //bind sizePix
217
+ const sizePix = this.size ? this.size(resolution, z) / z : resolution / z + 0.2
218
+ gl.uniform1f(gl.getUniformLocation(this.program, 'sizePix'), 1.0 * sizePix)
219
+
220
+ //
221
+ // mapContentChanged() is a cheap proxy for "did the content change" based
222
+ // on view x/y/z and cell count alone - it has no idea the WebGL context
223
+ // itself was just thrown away and recreated a few lines up (geoCanvas.w/h
224
+ // changing, e.g. from a browser/devtools resize, recreates cvWGL with a
225
+ // fresh, empty vertex buffer). A resize alone often leaves the geographic
226
+ // view and cell count identical to the previous draw, so without forcing
227
+ // a rebind here, mapContentChanged reports "unchanged" and the rebind gets
228
+ // skipped - leaving the new context's vertex buffer never populated and
229
+ // gl.drawArrays() drawing nothing, silently (confirmed via a resize-storm
230
+ // test: reinit-without-rebind happened on 5 of 9 context recreations).
231
+ const shouldRebind = this.mapContentChanged(geoCanvas.view, cells.length) || contextRecreated
232
+ if (shouldRebind)
233
+ //bind vertices
234
+ this.bindVertices(cells, resolution, z, viewScale)
235
+ //transformation
236
+ gl.uniformMatrix3fv(gl.getUniformLocation(this.program, 'mat'), false, new Float32Array(geoCanvas.getWebGLTransform()))
237
+
238
+ // Enable the depth test
239
+ //gl.enable(gl.DEPTH_TEST);
240
+ // Clear the color buffer bit
241
+ gl.clear(gl.COLOR_BUFFER_BIT)
242
+ // Set the view port
243
+ //gl.viewport(0, 0, cg.w, cg.h);
244
+
245
+ gl.drawArrays(gl.POINTS, 0, cells.length)
246
+
247
+ //draw in canvas geo
248
+ geoCanvas.initCanvasTransform()
249
+ geoCanvas.offscreenCtx.drawImage(canvas, 0, 0)
250
+
251
+ //update legends
252
+ this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
253
+ }
254
+ }
255
+
256
+
257
+
258
+ // early tests for webgl2 migration
259
+
260
+ /*
261
+ function getVectorShader2() {
262
+ return `
263
+ #version 300 es
264
+ precision highp float;
265
+
266
+ in vec2 pos;
267
+ in int i;
268
+
269
+ uniform float sizePix;
270
+ uniform mat3 mat;
271
+
272
+ flat out int vi;
273
+
274
+ void main() {
275
+ gl_Position = vec4(mat * vec3(pos, 1.0), 1.0);
276
+ gl_PointSize = sizePix;
277
+ vi = i;
278
+ }
279
+ `
280
+ }
281
+
282
+
283
+ function getFragmentShader2(colors) {
284
+
285
+ //prepare fragment shader code
286
+ //declare the uniform and other variables
287
+ const out = []
288
+ out.push('#version 300 es\nprecision highp float;\nflat in int vi;\n')
289
+
290
+ //add color uniforms
291
+ //uniform vec4 colors[12];
292
+ out.push('uniform vec4 colors[')
293
+ out.push(colors.length)
294
+ out.push('];\n')
295
+
296
+ out.push('out vec4 fragColor;\n')
297
+
298
+ //start the main function
299
+ //void main() { fragColor = colors[clamp(vi, 0, 11)]; }
300
+ out.push('void main() { fragColor = colors[vi]; }\n')
301
+
302
+ /** Fragment shader program
303
+ const fshString = out.join('')
304
+ console.log(fshString)
305
+ return fshString
306
+ }
307
+
295
308
  */