gridviz 2.1.17 → 3.0.1
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 +2 -3
- package/dist/gridviz.js +8659 -9294
- package/dist/gridviz.min.js +1 -1
- package/package.json +3 -2
- package/src/button/Button.js +14 -15
- package/src/button/FullscreenButton.js +14 -14
- package/src/button/ZoomButtons.js +2 -2
- package/src/{DatasetComponent.js → core/Dataset.js} +33 -13
- package/src/core/Drawable.js +60 -0
- package/src/{GeoCanvas.js → core/GeoCanvas.js} +65 -155
- package/src/core/Layer.js +24 -0
- package/src/{Legend.js → core/Legend.js} +24 -1
- package/src/core/Map.js +474 -0
- package/src/core/MultiResolutionDataset.js +96 -0
- package/src/core/Style.js +84 -0
- package/src/dataset/COGeo.js +5 -5
- package/src/dataset/CSVGrid.js +43 -41
- package/src/dataset/GeoTIFF.js +9 -14
- package/src/dataset/{LGrid.js → JSGrid.js} +9 -11
- package/src/dataset/TiledGrid.js +68 -45
- package/src/index.js +22 -29
- package/src/{BackgroundLayer.js → layer/BackgroundLayer.js} +27 -52
- package/src/{BackgroundLayerWMS.js → layer/BackgroundLayerWMS.js} +21 -45
- package/src/{LineLayer.js → layer/GeoJSONLayer.js} +22 -23
- package/src/layer/GridLayer.js +160 -0
- package/src/{LabelLayer.js → layer/LabelLayer.js} +25 -23
- package/src/legend/ColorCategoryLegend.js +9 -24
- package/src/legend/ColorDiscreteLegend.js +20 -24
- package/src/legend/ColorLegend.js +21 -33
- package/src/legend/OrientationLegend.js +90 -0
- package/src/legend/SizeLegend.js +153 -72
- package/src/style/CompositionStyle.js +71 -84
- package/src/style/ContourStyle.js +2 -36
- package/src/style/DotDensityStyle.js +50 -73
- package/src/style/IsoFenceStyle.js +59 -70
- package/src/style/JoyPlotStyle.js +41 -48
- package/src/style/LegoStyle.js +4 -4
- package/src/style/MosaicStyle.js +30 -39
- package/src/style/NinjaStarStyle.js +45 -68
- package/src/style/PillarStyle.js +70 -93
- package/src/style/SegmentStyle.js +37 -75
- package/src/style/ShapeColorSizeStyle.js +49 -98
- package/src/style/SideCategoryStyle.js +112 -0
- package/src/style/SideStyle.js +99 -133
- package/src/style/{SquareColorCatWGLStyle.js → SquareColorCategoryWebGLStyle.js} +28 -41
- package/src/style/{SquareColorWGLStyle.js → SquareColorWebGLStyle.js} +28 -49
- package/src/style/StrokeStyle.js +43 -70
- package/src/style/TanakaStyle.js +34 -132
- package/src/style/TextStyle.js +43 -64
- package/src/style/TimeSeriesStyle.js +44 -75
- package/src/utils/WebGLSquareColoringAdvanced.js +4 -4
- package/src/utils/scale.js +217 -0
- package/src/utils/stretching.js +86 -129
- package/src/utils/{Utils.js → utils.js} +15 -0
- package/src/utils/webGLUtils.js +4 -5
- package/src/utils/zoomUtils.js +30 -30
- package/src/App.js +0 -760
- package/src/Dataset.js +0 -76
- package/src/Layer.js +0 -103
- package/src/Style.js +0 -131
- package/src/dataset/GridTile.js +0 -41
- package/src/legend/SegmentOrientationLegend.js +0 -87
- package/src/legend/SegmentWidthLegend.js +0 -101
- package/src/style/CompositionStyle_.js +0 -293
- package/src/style/ShapeColorSizeStyle_.js +0 -108
- package/src/style/SideCatStyle.js +0 -172
- /package/src/{Tooltip.js → core/Tooltip.js} +0 -0
package/src/style/SideStyle.js
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
//@ts-check
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
-
import { Style } from '../Style.js'
|
|
4
|
+
import { Style } from '../core/Style.js'
|
|
5
5
|
|
|
6
|
-
/** @typedef {{x:number,y:number,or:"v"|"h",
|
|
6
|
+
/** @typedef {{ x:number, y:number, or:"v"|"h", c1:(import('../core/Dataset').Cell)|undefined, c2:(import('../core/Dataset').Cell)|undefined }} Side */
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* @typedef {function(Array.<Side>,number, number):*} SideViewScale */
|
|
7
10
|
|
|
8
11
|
/**
|
|
9
12
|
*
|
|
@@ -11,59 +14,103 @@ import { Style } from '../Style.js'
|
|
|
11
14
|
*/
|
|
12
15
|
export class SideStyle extends Style {
|
|
13
16
|
/** @param {object} opts */
|
|
14
|
-
constructor(opts) {
|
|
17
|
+
constructor(opts = {}) {
|
|
15
18
|
super(opts)
|
|
16
|
-
opts = opts || {}
|
|
17
|
-
|
|
18
|
-
/** The name of the column/attribute of the tabular data where to retrieve the variable for the cell values.
|
|
19
|
-
* @type {string} */
|
|
20
|
-
this.valueCol = opts.valueCol
|
|
21
|
-
|
|
22
|
-
/** A function returning the value of a cell side. This value is computed from the two adjacent cell values.
|
|
23
|
-
* For horizontal sides, v1 is the value of the cell below and v2 the value of the cell above.
|
|
24
|
-
* For vertical sides, v1 is the value of the cell left and v2 the value of the cell right.
|
|
25
|
-
* @type {function(number|undefined,number|undefined,number,import("../Style").Stat|undefined,number):number} */
|
|
26
|
-
this.value = opts.value || ((v1, v2, r, s, zf) => 1)
|
|
27
19
|
|
|
28
20
|
/** A function returning the color of a cell side.
|
|
29
|
-
* @type {function(Side,number,
|
|
30
|
-
this.color = opts.color || (() => '#EA6BAC')
|
|
21
|
+
* @type {function(Side, number, number, object):string} */
|
|
22
|
+
this.color = opts.color || ((side, resolution, z, sideViewScale) => '#EA6BAC')
|
|
31
23
|
|
|
32
24
|
/** A function returning the width of a cell side, in geo unit
|
|
33
|
-
* @type {function(Side,number,
|
|
34
|
-
this.width = opts.width || ((side,
|
|
35
|
-
|
|
36
|
-
/** orientation. Set to 90 to show sides as slope lines for example.
|
|
37
|
-
* @type {number} */
|
|
38
|
-
this.orientation = opts.orientation || 0
|
|
25
|
+
* @type {function(Side, number, number, object):number} */
|
|
26
|
+
this.width = opts.width || ((side, resolution, z, sideViewScale) => resolution / 5)
|
|
39
27
|
|
|
40
|
-
/** A
|
|
41
|
-
* @type {function(
|
|
42
|
-
this.
|
|
28
|
+
/** A function returning the length of a cell side, in geo unit
|
|
29
|
+
* @type {function(Side, number, number, object):number} */
|
|
30
|
+
this.length = opts.length || ((side, resolution, z, sideViewScale) => resolution)
|
|
43
31
|
}
|
|
44
32
|
|
|
45
33
|
/**
|
|
46
|
-
* @param {Array.<import("../Dataset").Cell>} cells
|
|
47
|
-
* @param {number}
|
|
48
|
-
* @param {import("../GeoCanvas").GeoCanvas}
|
|
34
|
+
* @param {Array.<import("../core/Dataset").Cell>} cells
|
|
35
|
+
* @param {number} resolution
|
|
36
|
+
* @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas
|
|
49
37
|
*/
|
|
50
|
-
draw(cells,
|
|
38
|
+
draw(cells, geoCanvas, resolution) {
|
|
39
|
+
|
|
51
40
|
//filter
|
|
52
41
|
if (this.filter) cells = cells.filter(this.filter)
|
|
53
42
|
|
|
54
|
-
//
|
|
55
|
-
const
|
|
43
|
+
//
|
|
44
|
+
const z = geoCanvas.view.z
|
|
56
45
|
|
|
57
|
-
//
|
|
58
|
-
let statValue
|
|
59
|
-
if (this.valueCol) {
|
|
60
|
-
//compute color variable statistics
|
|
61
|
-
statValue = Style.getStatistics(cells, (c) => c[this.valueCol], true)
|
|
62
|
-
}
|
|
46
|
+
//build sides
|
|
63
47
|
|
|
64
48
|
/** @type {Array.<Side>} */
|
|
49
|
+
const sides = SideStyle.buildSides(cells, resolution)
|
|
50
|
+
if (sides.length == 0) return
|
|
51
|
+
|
|
52
|
+
//get side view scale
|
|
53
|
+
const viewScale = this.viewScale ? this.viewScale(sides, resolution, z) : undefined
|
|
54
|
+
|
|
55
|
+
//draw sides
|
|
56
|
+
|
|
57
|
+
geoCanvas.ctx.lineCap = 'butt'
|
|
58
|
+
const r2 = resolution * 0.5
|
|
59
|
+
for (let side of sides) {
|
|
60
|
+
|
|
61
|
+
//color
|
|
62
|
+
/** @type {string|undefined} */
|
|
63
|
+
const col = this.color ? this.color(side, resolution, z, viewScale) : undefined
|
|
64
|
+
if (!col || col == 'none') continue
|
|
65
|
+
|
|
66
|
+
//width
|
|
67
|
+
/** @type {number|undefined} */
|
|
68
|
+
const wG = this.width ? this.width(side, resolution, z, viewScale) : undefined
|
|
69
|
+
if (!wG || wG <= 0) continue
|
|
70
|
+
|
|
71
|
+
//length
|
|
72
|
+
/** @type {number|undefined} */
|
|
73
|
+
const lG = this.length ? this.length(side, resolution, z, viewScale) : undefined
|
|
74
|
+
if (!lG || lG <= 0) continue
|
|
75
|
+
const lG2 = lG * 0.5
|
|
76
|
+
|
|
77
|
+
//set color and width
|
|
78
|
+
geoCanvas.ctx.strokeStyle = col
|
|
79
|
+
geoCanvas.ctx.lineWidth = wG
|
|
80
|
+
|
|
81
|
+
//draw segment with correct orientation
|
|
82
|
+
geoCanvas.ctx.beginPath()
|
|
83
|
+
if (side.or === "v") {
|
|
84
|
+
geoCanvas.ctx.moveTo(side.x, side.y + r2 - lG2)
|
|
85
|
+
geoCanvas.ctx.lineTo(side.x, side.y + r2 + lG2)
|
|
86
|
+
} else {
|
|
87
|
+
geoCanvas.ctx.moveTo(side.x + r2 - lG2, side.y)
|
|
88
|
+
geoCanvas.ctx.lineTo(side.x + r2 + lG2, side.y)
|
|
89
|
+
}
|
|
90
|
+
geoCanvas.ctx.stroke()
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
//update legends
|
|
94
|
+
this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
*
|
|
101
|
+
* @param {Array.<import('../core/Dataset').Cell>} cells The cells to use to build the sides. The side x,y coordinates are those of the left point for horizontal sides, and of the bottom point for vertical sides.
|
|
102
|
+
* @param {number} resolution The cells resolution
|
|
103
|
+
* @param {boolean} withHorizontal Set to true to build horizontal sides, false otherwise.
|
|
104
|
+
* @param {boolean} withVertical Set to true to build vertical sides, false otherwise.
|
|
105
|
+
* @param {boolean} center Set to true so that the side coordinate are those of its center point rather than its left/bottom point.
|
|
106
|
+
* @returns { Array.<Side> }
|
|
107
|
+
*/
|
|
108
|
+
static buildSides(cells, resolution, withHorizontal = true, withVertical = true, center = false) {
|
|
109
|
+
/** @type { Array.<Side> } */
|
|
65
110
|
const sides = []
|
|
66
111
|
|
|
112
|
+
const r2 = center ? resolution / 2 : 0
|
|
113
|
+
|
|
67
114
|
//make horizontal sides
|
|
68
115
|
//sort cells by x and y
|
|
69
116
|
cells.sort((c1, c2) => (c2.x == c1.x ? c1.y - c2.y : c1.x - c2.x))
|
|
@@ -71,29 +118,26 @@ export class SideStyle extends Style {
|
|
|
71
118
|
for (let i = 1; i < cells.length; i++) {
|
|
72
119
|
let c2 = cells[i]
|
|
73
120
|
|
|
74
|
-
if ((c1.y +
|
|
121
|
+
if ((c1.y + resolution == c2.y) && (c1.x == c2.x))
|
|
75
122
|
//cells in same column and touch along horizontal side
|
|
76
123
|
//make shared side
|
|
77
124
|
sides.push({
|
|
78
|
-
x: c1.x,
|
|
79
|
-
y: c2.y,
|
|
80
125
|
or: 'h',
|
|
81
|
-
|
|
126
|
+
x: c1.x + r2, y: c2.y,
|
|
127
|
+
c1: c1, c2: c2
|
|
82
128
|
})
|
|
83
129
|
else {
|
|
84
130
|
//cells do not touch along horizontal side
|
|
85
131
|
//make two sides: top one for c1, bottom for c2
|
|
86
132
|
sides.push({
|
|
87
|
-
x: c1.x,
|
|
88
|
-
y: c1.y + r,
|
|
89
133
|
or: 'h',
|
|
90
|
-
|
|
134
|
+
x: c1.x + r2, y: c1.y + resolution,
|
|
135
|
+
c1: c1, c2: undefined
|
|
91
136
|
})
|
|
92
137
|
sides.push({
|
|
93
|
-
x: c2.x,
|
|
94
|
-
y: c2.y,
|
|
95
138
|
or: 'h',
|
|
96
|
-
|
|
139
|
+
x: c2.x + r2, y: c2.y,
|
|
140
|
+
c1: undefined, c2: c2
|
|
97
141
|
})
|
|
98
142
|
}
|
|
99
143
|
|
|
@@ -107,110 +151,32 @@ export class SideStyle extends Style {
|
|
|
107
151
|
for (let i = 1; i < cells.length; i++) {
|
|
108
152
|
let c2 = cells[i]
|
|
109
153
|
|
|
110
|
-
if ((c1.x +
|
|
154
|
+
if ((c1.x + resolution == c2.x) && (c1.y == c2.y))
|
|
111
155
|
//cells in same row and touch along vertical side
|
|
112
156
|
//make shared side
|
|
113
157
|
sides.push({
|
|
114
|
-
x: c1.x + r,
|
|
115
|
-
y: c1.y,
|
|
116
158
|
or: 'v',
|
|
117
|
-
|
|
159
|
+
x: c1.x + resolution, y: c1.y + r2,
|
|
160
|
+
c1: c1, c2: c2
|
|
118
161
|
})
|
|
119
162
|
else {
|
|
120
163
|
//cells do not touch along vertical side
|
|
121
164
|
//make two sides: right one for c1, left for c2
|
|
122
165
|
sides.push({
|
|
123
|
-
x: c1.x + r,
|
|
124
|
-
y: c1.y,
|
|
125
166
|
or: 'v',
|
|
126
|
-
|
|
167
|
+
x: c1.x + resolution, y: c1.y + r2,
|
|
168
|
+
c1: c1, c2: undefined
|
|
127
169
|
})
|
|
128
170
|
sides.push({
|
|
129
|
-
x: c2.x,
|
|
130
|
-
y: c2.y,
|
|
131
171
|
or: 'v',
|
|
132
|
-
|
|
172
|
+
x: c2.x, y: c2.y + r2,
|
|
173
|
+
c1: undefined, c2: c2
|
|
133
174
|
})
|
|
134
175
|
}
|
|
135
176
|
|
|
136
177
|
c1 = c2
|
|
137
178
|
}
|
|
138
|
-
|
|
139
|
-
//
|
|
140
|
-
if (sides.length == 0) return
|
|
141
|
-
|
|
142
|
-
//compute stats on sides
|
|
143
|
-
const statSides = SideStyle.getSideStatistics(sides, true)
|
|
144
|
-
|
|
145
|
-
//draw in geo coordinates
|
|
146
|
-
cg.setCanvasTransform()
|
|
147
|
-
|
|
148
|
-
//draw cells, if fillColor specified
|
|
149
|
-
if (this.fillColor)
|
|
150
|
-
for (let c of cells) {
|
|
151
|
-
const fc = this.fillColor(c)
|
|
152
|
-
if (!fc || fc == 'none') continue
|
|
153
|
-
cg.ctx.fillStyle = fc
|
|
154
|
-
cg.ctx.fillRect(c.x, c.y, r, r)
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
//draw sides
|
|
158
|
-
cg.ctx.lineCap = 'butt'
|
|
159
|
-
const r2 = r / 2
|
|
160
|
-
for (let s of sides) {
|
|
161
|
-
//color
|
|
162
|
-
/** @type {string|undefined} */
|
|
163
|
-
const col = this.color ? this.color(s, r, statSides, zf) : undefined
|
|
164
|
-
if (!col || col == 'none') continue
|
|
165
|
-
|
|
166
|
-
//width
|
|
167
|
-
/** @type {number|undefined} */
|
|
168
|
-
const wG = this.width ? this.width(s, r, statSides, zf) : undefined
|
|
169
|
-
if (!wG || wG <= 0) continue
|
|
170
|
-
|
|
171
|
-
//set color and width
|
|
172
|
-
cg.ctx.strokeStyle = col
|
|
173
|
-
cg.ctx.lineWidth = wG
|
|
174
|
-
|
|
175
|
-
//draw segment with correct orientation
|
|
176
|
-
cg.ctx.beginPath()
|
|
177
|
-
if (this.orientation == 90) {
|
|
178
|
-
cg.ctx.moveTo(s.x + r2, s.y + r2)
|
|
179
|
-
if (s.or === 'h') cg.ctx.lineTo(s.x + r2, s.y - r2)
|
|
180
|
-
else cg.ctx.lineTo(s.x - r2, s.y + r2)
|
|
181
|
-
} else {
|
|
182
|
-
cg.ctx.moveTo(s.x, s.y)
|
|
183
|
-
cg.ctx.lineTo(s.x + (s.or === 'h' ? r : 0), s.y + (s.or === 'v' ? r : 0))
|
|
184
|
-
}
|
|
185
|
-
cg.ctx.stroke()
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
//update legends
|
|
189
|
-
this.updateLegends({ style: this, r: r, zf: zf })
|
|
179
|
+
return sides
|
|
190
180
|
}
|
|
191
181
|
|
|
192
|
-
/**
|
|
193
|
-
* Compute some statistics on a value of some sides.
|
|
194
|
-
* This is used to define how to draw specifically the sides within the view.
|
|
195
|
-
*
|
|
196
|
-
* @param {Array.<Side>} sides
|
|
197
|
-
* @param {boolean} ignoreZeros
|
|
198
|
-
* @returns {import("../Style").Stat | undefined}
|
|
199
|
-
*/
|
|
200
|
-
static getSideStatistics(sides, ignoreZeros) {
|
|
201
|
-
if (!sides || sides.length == 0) return undefined
|
|
202
|
-
let min = Infinity
|
|
203
|
-
let max = -Infinity
|
|
204
|
-
//let sum = 0
|
|
205
|
-
//let nb = 0
|
|
206
|
-
for (const s of sides) {
|
|
207
|
-
const v = s.value
|
|
208
|
-
if (ignoreZeros && !v) continue
|
|
209
|
-
if (v < min) min = v
|
|
210
|
-
if (v > max) max = v
|
|
211
|
-
//sum += v
|
|
212
|
-
//nb++
|
|
213
|
-
}
|
|
214
|
-
return { min: min, max: max }
|
|
215
|
-
}
|
|
216
182
|
}
|
|
@@ -1,51 +1,49 @@
|
|
|
1
1
|
//@ts-check
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
-
import { Style } from '../Style.js'
|
|
4
|
+
import { Style } from '../core/Style.js'
|
|
5
5
|
import { makeWebGLCanvas } from '../utils/webGLUtils.js'
|
|
6
6
|
import { WebGLSquareColoringCatAdvanced } from '../utils/WebGLSquareColoringCatAdvanced.js'
|
|
7
|
-
import { monitor, monitorDuration } from '../utils/Utils.js'
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* Style based on webGL
|
|
11
10
|
* To show cells as colored squares, from categories.
|
|
12
|
-
*
|
|
11
|
+
* All cells are drawn as squares, with the same size
|
|
13
12
|
*
|
|
14
13
|
* @author Julien Gaffuri
|
|
15
14
|
*/
|
|
16
|
-
export class
|
|
15
|
+
export class SquareColorCategoryWebGLStyle extends Style {
|
|
17
16
|
/** @param {object} opts */
|
|
18
17
|
constructor(opts) {
|
|
19
18
|
super(opts)
|
|
20
19
|
opts = opts || {}
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
|
-
* The name of the column/attribute of the tabular data where to retrieve the category of the cell, for coloring.
|
|
22
|
+
* The name of the column/attribute of the tabular data where to retrieve the category code of the cell, for coloring.
|
|
24
23
|
* @type {string} */
|
|
25
|
-
this.
|
|
24
|
+
this.code = opts.code
|
|
26
25
|
|
|
27
26
|
/**
|
|
28
|
-
* The dictionary (
|
|
27
|
+
* The dictionary (code -> color) which gives the color of each category code.
|
|
29
28
|
* @type {object} */
|
|
30
29
|
opts.color = opts.color || undefined
|
|
31
30
|
|
|
32
|
-
/** @type { Array.<string> }
|
|
33
|
-
const
|
|
31
|
+
/** @type { Array.<string> } */
|
|
32
|
+
const codes = Object.keys(opts.color)
|
|
34
33
|
|
|
35
34
|
/** @type { object } @private */
|
|
36
35
|
this.catToI = {}
|
|
37
|
-
for (let i = 0; i <
|
|
36
|
+
for (let i = 0; i < codes.length; i++) this.catToI[codes[i]] = i + ''
|
|
38
37
|
|
|
39
38
|
/** @type { Array.<string> } @private */
|
|
40
39
|
this.colors = []
|
|
41
|
-
for (
|
|
42
|
-
this.colors.push(opts.color['' +
|
|
43
|
-
}
|
|
40
|
+
for (const code of codes)
|
|
41
|
+
this.colors.push(opts.color['' + code])
|
|
44
42
|
|
|
45
43
|
/**
|
|
46
44
|
* A function returning the size of the cells, in geographical unit. All cells have the same size.
|
|
47
45
|
* @type {function(number,number):number} */
|
|
48
|
-
this.size = opts.size // (resolution,
|
|
46
|
+
this.size = opts.size // (resolution, z) => ...
|
|
49
47
|
|
|
50
48
|
/**
|
|
51
49
|
* @private
|
|
@@ -54,28 +52,26 @@ export class SquareColorCatWGLStyle extends Style {
|
|
|
54
52
|
}
|
|
55
53
|
|
|
56
54
|
/**
|
|
57
|
-
* @param {Array.<import("../Dataset").Cell>} cells
|
|
58
|
-
* @param {
|
|
59
|
-
* @param {
|
|
55
|
+
* @param {Array.<import("../core/Dataset.js").Cell>} cells
|
|
56
|
+
* @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
|
|
57
|
+
* @param {number} resolution
|
|
60
58
|
*/
|
|
61
|
-
draw(cells,
|
|
62
|
-
if (monitor) monitorDuration('*** SquareColorCatWGLStyle draw')
|
|
59
|
+
draw(cells, geoCanvas, resolution) {
|
|
63
60
|
|
|
64
61
|
//filter
|
|
65
62
|
if (this.filter) cells = cells.filter(this.filter)
|
|
66
63
|
|
|
67
|
-
//
|
|
68
|
-
const
|
|
64
|
+
//
|
|
65
|
+
const z = geoCanvas.view.z
|
|
69
66
|
|
|
70
67
|
//add vertice and fragment data
|
|
71
|
-
const r2 =
|
|
72
|
-
let c,
|
|
73
|
-
nb = cells.length
|
|
68
|
+
const r2 = resolution / 2
|
|
69
|
+
let c, nb = cells.length
|
|
74
70
|
const verticesBuffer = []
|
|
75
71
|
const iBuffer = []
|
|
76
72
|
for (let i = 0; i < nb; i++) {
|
|
77
73
|
c = cells[i]
|
|
78
|
-
const cat = c[this.
|
|
74
|
+
const cat = c[this.code]
|
|
79
75
|
if (cat == undefined) {
|
|
80
76
|
console.log('Unexpected category: ' + cat)
|
|
81
77
|
continue
|
|
@@ -90,31 +86,22 @@ export class SquareColorCatWGLStyle extends Style {
|
|
|
90
86
|
iBuffer.push(+i_)
|
|
91
87
|
}
|
|
92
88
|
|
|
93
|
-
if (monitor) monitorDuration(' webgl program inputs preparation')
|
|
94
|
-
|
|
95
89
|
//create canvas and webgl renderer
|
|
96
|
-
const cvWGL = makeWebGLCanvas(
|
|
90
|
+
const cvWGL = makeWebGLCanvas(geoCanvas.w + '', geoCanvas.h + '')
|
|
97
91
|
if (!cvWGL) {
|
|
98
92
|
console.error('No webGL')
|
|
99
93
|
return
|
|
100
94
|
}
|
|
101
|
-
if (monitor) monitorDuration(' web GL canvas creation')
|
|
102
95
|
|
|
103
96
|
//draw
|
|
104
|
-
const sizeGeo = this.size ? this.size(
|
|
105
|
-
this.wgp.draw(cvWGL.gl, verticesBuffer, iBuffer,
|
|
106
|
-
|
|
107
|
-
if (monitor) monitorDuration(' webgl drawing')
|
|
97
|
+
const sizeGeo = this.size ? this.size(resolution, z) : resolution + 0.2 * z
|
|
98
|
+
this.wgp.draw(cvWGL.gl, verticesBuffer, iBuffer, geoCanvas.getWebGLTransform(), sizeGeo / z)
|
|
108
99
|
|
|
109
100
|
//draw in canvas geo
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
if (monitor) monitorDuration(' canvas drawing')
|
|
101
|
+
geoCanvas.initCanvasTransform()
|
|
102
|
+
geoCanvas.ctx.drawImage(cvWGL.canvas, 0, 0)
|
|
114
103
|
|
|
115
104
|
//update legends
|
|
116
|
-
this.updateLegends({ style: this,
|
|
117
|
-
|
|
118
|
-
if (monitor) monitorDuration('*** SquareColorCatWGLStyle end draw')
|
|
105
|
+
this.updateLegends({ style: this, resolution: resolution, z: z })
|
|
119
106
|
}
|
|
120
|
-
}
|
|
107
|
+
}
|
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
//@ts-check
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
-
import { Style } from '../Style.js'
|
|
4
|
+
import { Style } from '../core/Style.js'
|
|
5
5
|
import { makeWebGLCanvas } from '../utils/webGLUtils.js'
|
|
6
6
|
import { WebGLSquareColoringAdvanced } from '../utils/WebGLSquareColoringAdvanced.js'
|
|
7
|
-
import { monitor, monitorDuration } from '../utils/Utils.js'
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* Style based on webGL
|
|
@@ -13,21 +12,16 @@ import { monitor, monitorDuration } from '../utils/Utils.js'
|
|
|
13
12
|
*
|
|
14
13
|
* @author Julien Gaffuri
|
|
15
14
|
*/
|
|
16
|
-
export class
|
|
15
|
+
export class SquareColorWebGLStyle extends Style {
|
|
17
16
|
/** @param {object} opts */
|
|
18
17
|
constructor(opts) {
|
|
19
18
|
super(opts)
|
|
20
19
|
opts = opts || {}
|
|
21
20
|
|
|
22
21
|
/**
|
|
23
|
-
*
|
|
24
|
-
* @type {
|
|
25
|
-
this.
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* A function returning the t value (within [0,1]) of the cell.
|
|
29
|
-
* @type {function(number,number,import("../Style").Stat):number} */
|
|
30
|
-
this.tFun = opts.tFun || ((v, r, s) => v / s.max)
|
|
22
|
+
* A function returning a t value (within [0,1]) for a cell.
|
|
23
|
+
* @type {function(import('../core/Dataset.js').Cell,number,number,object):number} */
|
|
24
|
+
this.tFun = opts.tFun //(c,r,z,vs) => {}
|
|
31
25
|
|
|
32
26
|
/**
|
|
33
27
|
* Distribution stretching method.
|
|
@@ -62,85 +56,70 @@ export class SquareColorWGLStyle extends Style {
|
|
|
62
56
|
* Define the opacity of the style, within [0,1].
|
|
63
57
|
* If this opacity is defined, the individual color opacity will be ignored.
|
|
64
58
|
* @type {function(number,number):number} */
|
|
65
|
-
this.opacity = opts.opacity // (r,
|
|
59
|
+
this.opacity = opts.opacity // (r,z) => ...
|
|
66
60
|
|
|
67
61
|
/**
|
|
68
62
|
* A function returning the size of the cells, in geographical unit. All cells have the same size.
|
|
69
63
|
* @type {function(number,number):number} */
|
|
70
|
-
this.size = opts.size // (resolution,
|
|
64
|
+
this.size = opts.size // (resolution, z) => ...
|
|
71
65
|
}
|
|
72
66
|
|
|
73
67
|
/**
|
|
74
|
-
* @param {Array.<import("../Dataset").Cell>} cells
|
|
75
|
-
* @param {
|
|
76
|
-
* @param {
|
|
68
|
+
* @param {Array.<import("../core/Dataset.js").Cell>} cells
|
|
69
|
+
* @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
|
|
70
|
+
* @param {number} resolution
|
|
77
71
|
*/
|
|
78
|
-
draw(cells,
|
|
79
|
-
if (monitor) monitorDuration('*** SquareColorWGLStyle draw')
|
|
72
|
+
draw(cells, geoCanvas, resolution) {
|
|
80
73
|
|
|
81
74
|
//filter
|
|
82
75
|
if (this.filter) cells = cells.filter(this.filter)
|
|
83
76
|
|
|
84
|
-
//
|
|
85
|
-
const
|
|
86
|
-
|
|
87
|
-
//compute color variable statistics
|
|
88
|
-
const statColor = Style.getStatistics(cells, (c) => c[this.colorCol], true)
|
|
89
|
-
if (monitor) monitorDuration(' color stats computation')
|
|
77
|
+
//
|
|
78
|
+
const z = geoCanvas.view.z
|
|
90
79
|
|
|
91
|
-
|
|
80
|
+
//get view scale
|
|
81
|
+
const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
|
|
92
82
|
|
|
93
83
|
//create canvas and webgl renderer
|
|
94
84
|
//for opacity control, see: https://webglfundamentals.org/webgl/lessons/webgl-and-alpha.html
|
|
95
85
|
const cvWGL = makeWebGLCanvas(
|
|
96
|
-
|
|
97
|
-
|
|
86
|
+
geoCanvas.w + '',
|
|
87
|
+
geoCanvas.h + '',
|
|
98
88
|
this.opacity != undefined ? { premultipliedAlpha: false } : undefined
|
|
99
89
|
)
|
|
100
90
|
if (!cvWGL) {
|
|
101
91
|
console.error('No webGL')
|
|
102
92
|
return
|
|
103
93
|
}
|
|
104
|
-
if (monitor) monitorDuration(' web GL canvas creation')
|
|
105
94
|
|
|
106
95
|
//add vertice and fragment data
|
|
107
|
-
const r2 =
|
|
96
|
+
const r2 = resolution / 2
|
|
108
97
|
const verticesBuffer = []
|
|
109
98
|
const tBuffer = []
|
|
110
|
-
for (let
|
|
111
|
-
const t = this.tFun(
|
|
99
|
+
for (let cell of cells) {
|
|
100
|
+
const t = this.tFun(cell, resolution, z, viewScale)
|
|
112
101
|
if (t == null || t == undefined) continue
|
|
113
|
-
verticesBuffer.push(
|
|
102
|
+
verticesBuffer.push(cell.x + r2, cell.y + r2)
|
|
114
103
|
tBuffer.push(t > 1 ? 1 : t < 0 ? 0 : t)
|
|
115
104
|
}
|
|
116
105
|
|
|
117
|
-
if (monitor) monitorDuration(' webgl drawing data preparation')
|
|
118
|
-
|
|
119
106
|
//compute pixel size
|
|
120
|
-
const sizeGeo = this.size ? this.size(
|
|
107
|
+
const sizeGeo = this.size ? this.size(resolution, z) : resolution + 0.2 * z
|
|
121
108
|
|
|
122
109
|
//compute opacity
|
|
123
|
-
const op = this.opacity ? this.opacity(
|
|
110
|
+
const op = this.opacity ? this.opacity(resolution, z) : undefined
|
|
124
111
|
|
|
125
112
|
//
|
|
126
|
-
const wgp = new WebGLSquareColoringAdvanced(cvWGL.gl, this.colors, this.stretching, sizeGeo /
|
|
127
|
-
|
|
128
|
-
if (monitor) monitorDuration(' webgl program preparation')
|
|
113
|
+
const wgp = new WebGLSquareColoringAdvanced(cvWGL.gl, this.colors, this.stretching, sizeGeo / z, op)
|
|
129
114
|
|
|
130
115
|
//draw
|
|
131
|
-
wgp.draw(verticesBuffer, tBuffer,
|
|
132
|
-
|
|
133
|
-
if (monitor) monitorDuration(' webgl drawing')
|
|
116
|
+
wgp.draw(verticesBuffer, tBuffer, geoCanvas.getWebGLTransform())
|
|
134
117
|
|
|
135
118
|
//draw in canvas geo
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
if (monitor) monitorDuration(' canvas drawing')
|
|
119
|
+
geoCanvas.initCanvasTransform()
|
|
120
|
+
geoCanvas.ctx.drawImage(cvWGL.canvas, 0, 0)
|
|
140
121
|
|
|
141
122
|
//update legends
|
|
142
|
-
this.updateLegends({ style: this,
|
|
143
|
-
|
|
144
|
-
if (monitor) monitorDuration('*** SquareColorWGLStyle end draw')
|
|
123
|
+
this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
|
|
145
124
|
}
|
|
146
125
|
}
|