gridviz 3.0.19 → 3.0.21
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 +128 -128
- package/dist/gridviz.js +7875 -7857
- package/dist/gridviz.min.js +1 -1
- package/package.json +74 -74
- package/src/button/ZoomButtons.js +101 -101
- package/src/core/Dataset.js +154 -154
- package/src/core/Drawable.js +78 -60
- package/src/core/GeoCanvas.js +430 -430
- package/src/core/Layer.js +23 -23
- package/src/core/Legend.js +108 -108
- package/src/core/Map.js +516 -516
- package/src/core/MultiResolutionDataset.js +93 -93
- package/src/core/Style.js +98 -98
- package/src/dataset/CSVGrid.js +112 -112
- package/src/dataset/GeoTIFF.js +122 -122
- package/src/dataset/JSGrid.js +55 -55
- package/src/dataset/TiledGrid.js +302 -302
- package/src/dataset/worker.js +18 -18
- package/src/index.js +77 -77
- package/src/layer/BackgroundLayer.js +162 -162
- package/src/layer/BackgroundLayerImage.js +81 -81
- package/src/layer/BackgroundLayerWMS.js +104 -104
- package/src/layer/GeoJSONLayer.js +214 -214
- package/src/layer/GridLayer.js +148 -148
- package/src/layer/LabelLayer.js +194 -194
- package/src/legend/ColorCategoryLegend.js +109 -109
- package/src/legend/ColorDiscreteLegend.js +100 -100
- package/src/legend/ColorLegend.js +115 -115
- package/src/legend/OrientationLegend.js +89 -89
- package/src/legend/SizeLegend.js +224 -224
- package/src/legend/TernaryLegend.js +302 -302
- package/src/style/CompositionStyle.js +291 -291
- package/src/style/DotDensityStyle.js +133 -133
- package/src/style/ImageStyle.js +100 -100
- package/src/style/IsoFenceStyle.js +217 -217
- package/src/style/JoyPlotStyle.js +127 -127
- 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 -207
- package/src/style/SegmentStyle.js +105 -105
- package/src/style/ShapeColorSizeStyle.js +147 -147
- package/src/style/SideCategoryStyle.js +112 -112
- package/src/style/SideStyle.js +212 -212
- package/src/style/SquareColorCategoryWebGLStyle.js +107 -107
- package/src/style/SquareColorWebGLStyle.js +126 -126
- package/src/style/StrokeStyle.js +135 -135
- package/src/style/TanakaStyle.js +69 -69
- package/src/style/TextStyle.js +110 -110
- package/src/style/TimeSeriesStyle.js +222 -222
- package/src/utils/scale.js +218 -218
- package/src/utils/stretching.js +120 -120
- package/src/utils/ternary.js +208 -208
- package/src/utils/utils.js +58 -58
- package/src/utils/webGLUtils.js +72 -72
|
@@ -1,133 +1,133 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Style } from '../core/Style.js'
|
|
5
|
-
import { randomNormal } from 'd3-random'
|
|
6
|
-
import { checkWebGLSupport, makeWebGLCanvas } from '../utils/webGLUtils.js'
|
|
7
|
-
import { WebGLSquareColoring } from '../utils/WebGLSquareColoring.js'
|
|
8
|
-
import { color } from 'd3-color'
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
*
|
|
12
|
-
* @module style
|
|
13
|
-
* @author Julien Gaffuri
|
|
14
|
-
*/
|
|
15
|
-
export class DotDensityStyle extends Style {
|
|
16
|
-
/** @param {object} opts */
|
|
17
|
-
constructor(opts) {
|
|
18
|
-
super(opts)
|
|
19
|
-
opts = opts || {}
|
|
20
|
-
|
|
21
|
-
/** A function returning the number of dots for a cell value.
|
|
22
|
-
* @type {function(import('../core/Dataset.js').Cell, number, number, object):number} */
|
|
23
|
-
this.dotNumber = opts.dotNumber || ((cell, resolution) => resolution / 100) //(c,r,z,vs) => {}
|
|
24
|
-
|
|
25
|
-
/** The color of the dots. Same color for all dots within a cell.
|
|
26
|
-
* @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
|
|
27
|
-
this.color = opts.color || (() => '#FF5733') //(c,r,z,vs) => {}
|
|
28
|
-
|
|
29
|
-
/** A function returning the size of the dots, in geo unit. Same size for all cells.
|
|
30
|
-
* @type {function(number, number,object):number} */
|
|
31
|
-
this.dotSize = opts.dotSize || ((resolution, z) => 1.5 * z) //(c,r,z,vs) => {}
|
|
32
|
-
|
|
33
|
-
/** A function returning the sigma of the dots distribution. Same value for all cells.
|
|
34
|
-
* @type {function(number, number,object):number} */
|
|
35
|
-
this.sigma = opts.sigma || ((resolution, z) => resolution / 2) //(c,r,z,vs) => {}
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Draw cells as text.
|
|
40
|
-
*
|
|
41
|
-
* @param {Array.<import("../core/Dataset").Cell>} cells
|
|
42
|
-
* @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas
|
|
43
|
-
* @param {number} resolution
|
|
44
|
-
*/
|
|
45
|
-
draw(cells, geoCanvas, resolution) {
|
|
46
|
-
//filter
|
|
47
|
-
if (this.filter) cells = cells.filter(this.filter)
|
|
48
|
-
|
|
49
|
-
//
|
|
50
|
-
const z = geoCanvas.view.z
|
|
51
|
-
|
|
52
|
-
//get view scale
|
|
53
|
-
const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
|
|
54
|
-
|
|
55
|
-
//get size
|
|
56
|
-
const sGeo = this.dotSize ? this.dotSize(resolution, z, viewScale) : z
|
|
57
|
-
|
|
58
|
-
//make random function
|
|
59
|
-
const sig = this.sigma ? this.sigma(resolution, z, viewScale) : resolution * 0.4
|
|
60
|
-
const rand = randomNormal(0, sig)
|
|
61
|
-
|
|
62
|
-
const ctx = geoCanvas.offscreenCtx
|
|
63
|
-
|
|
64
|
-
if (checkWebGLSupport()) {
|
|
65
|
-
//create canvas and webgl renderer
|
|
66
|
-
const cvWGL = makeWebGLCanvas(geoCanvas.w + '', geoCanvas.h + '')
|
|
67
|
-
if (!cvWGL) {
|
|
68
|
-
console.error('No webGL')
|
|
69
|
-
return
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
//create webGL program
|
|
73
|
-
const prog = new WebGLSquareColoring(cvWGL.gl, sGeo / z)
|
|
74
|
-
|
|
75
|
-
const r2 = resolution / 2
|
|
76
|
-
|
|
77
|
-
for (let cell of cells) {
|
|
78
|
-
//get color
|
|
79
|
-
const col = this.color(cell, resolution, z, viewScale)
|
|
80
|
-
if (!col || col === 'none') continue
|
|
81
|
-
|
|
82
|
-
//number of dots
|
|
83
|
-
const dotNumber = this.dotNumber(cell, resolution, z, viewScale)
|
|
84
|
-
|
|
85
|
-
//get offset
|
|
86
|
-
const offset = this.offset(cell, resolution, z)
|
|
87
|
-
|
|
88
|
-
//cell center
|
|
89
|
-
const cx = cell.x + offset.dx + r2
|
|
90
|
-
const cy = cell.y + offset.dy + r2
|
|
91
|
-
|
|
92
|
-
//convert color
|
|
93
|
-
const cc = color(col)
|
|
94
|
-
if (!cc) return
|
|
95
|
-
|
|
96
|
-
//random points
|
|
97
|
-
for (let i = 0; i <= dotNumber; i++)
|
|
98
|
-
prog.addPointData2(cx + rand(), cy + rand(), cc.r, cc.g, cc.b, cc.opacity)
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
//draw
|
|
102
|
-
prog.draw(geoCanvas.getWebGLTransform())
|
|
103
|
-
|
|
104
|
-
//draw in canvas geo
|
|
105
|
-
geoCanvas.initCanvasTransform()
|
|
106
|
-
ctx.drawImage(cvWGL.canvas, 0, 0)
|
|
107
|
-
} else {
|
|
108
|
-
for (let cell of cells) {
|
|
109
|
-
//get color
|
|
110
|
-
const col = this.color(cell, resolution, z, viewScale)
|
|
111
|
-
if (!col || col === 'none') continue
|
|
112
|
-
//set color
|
|
113
|
-
ctx.fillStyle = col
|
|
114
|
-
|
|
115
|
-
//number of dots
|
|
116
|
-
const dotNumber = this.dotNumber(cell, resolution, z, viewScale)
|
|
117
|
-
|
|
118
|
-
//get offset
|
|
119
|
-
const offset = this.offset(cell, resolution, z)
|
|
120
|
-
|
|
121
|
-
//draw random dots
|
|
122
|
-
const cx = cell.x + offset.dx + resolution / 2,
|
|
123
|
-
cy = cell.y + offset.dy + resolution / 2
|
|
124
|
-
for (let i = 0; i <= dotNumber; i++) {
|
|
125
|
-
ctx.fillRect(cx + rand(), cy + rand(), sGeo, sGeo)
|
|
126
|
-
}
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
//update legends
|
|
131
|
-
this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
|
|
132
|
-
}
|
|
133
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Style } from '../core/Style.js'
|
|
5
|
+
import { randomNormal } from 'd3-random'
|
|
6
|
+
import { checkWebGLSupport, makeWebGLCanvas } from '../utils/webGLUtils.js'
|
|
7
|
+
import { WebGLSquareColoring } from '../utils/WebGLSquareColoring.js'
|
|
8
|
+
import { color } from 'd3-color'
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @module style
|
|
13
|
+
* @author Julien Gaffuri
|
|
14
|
+
*/
|
|
15
|
+
export class DotDensityStyle extends Style {
|
|
16
|
+
/** @param {object} opts */
|
|
17
|
+
constructor(opts) {
|
|
18
|
+
super(opts)
|
|
19
|
+
opts = opts || {}
|
|
20
|
+
|
|
21
|
+
/** A function returning the number of dots for a cell value.
|
|
22
|
+
* @type {function(import('../core/Dataset.js').Cell, number, number, object):number} */
|
|
23
|
+
this.dotNumber = opts.dotNumber || ((cell, resolution) => resolution / 100) //(c,r,z,vs) => {}
|
|
24
|
+
|
|
25
|
+
/** The color of the dots. Same color for all dots within a cell.
|
|
26
|
+
* @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
|
|
27
|
+
this.color = opts.color || (() => '#FF5733') //(c,r,z,vs) => {}
|
|
28
|
+
|
|
29
|
+
/** A function returning the size of the dots, in geo unit. Same size for all cells.
|
|
30
|
+
* @type {function(number, number,object):number} */
|
|
31
|
+
this.dotSize = opts.dotSize || ((resolution, z) => 1.5 * z) //(c,r,z,vs) => {}
|
|
32
|
+
|
|
33
|
+
/** A function returning the sigma of the dots distribution. Same value for all cells.
|
|
34
|
+
* @type {function(number, number,object):number} */
|
|
35
|
+
this.sigma = opts.sigma || ((resolution, z) => resolution / 2) //(c,r,z,vs) => {}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* Draw cells as text.
|
|
40
|
+
*
|
|
41
|
+
* @param {Array.<import("../core/Dataset").Cell>} cells
|
|
42
|
+
* @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas
|
|
43
|
+
* @param {number} resolution
|
|
44
|
+
*/
|
|
45
|
+
draw(cells, geoCanvas, resolution) {
|
|
46
|
+
//filter
|
|
47
|
+
if (this.filter) cells = cells.filter(this.filter)
|
|
48
|
+
|
|
49
|
+
//
|
|
50
|
+
const z = geoCanvas.view.z
|
|
51
|
+
|
|
52
|
+
//get view scale
|
|
53
|
+
const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
|
|
54
|
+
|
|
55
|
+
//get size
|
|
56
|
+
const sGeo = this.dotSize ? this.dotSize(resolution, z, viewScale) : z
|
|
57
|
+
|
|
58
|
+
//make random function
|
|
59
|
+
const sig = this.sigma ? this.sigma(resolution, z, viewScale) : resolution * 0.4
|
|
60
|
+
const rand = randomNormal(0, sig)
|
|
61
|
+
|
|
62
|
+
const ctx = geoCanvas.offscreenCtx
|
|
63
|
+
|
|
64
|
+
if (checkWebGLSupport()) {
|
|
65
|
+
//create canvas and webgl renderer
|
|
66
|
+
const cvWGL = makeWebGLCanvas(geoCanvas.w + '', geoCanvas.h + '')
|
|
67
|
+
if (!cvWGL) {
|
|
68
|
+
console.error('No webGL')
|
|
69
|
+
return
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
//create webGL program
|
|
73
|
+
const prog = new WebGLSquareColoring(cvWGL.gl, sGeo / z)
|
|
74
|
+
|
|
75
|
+
const r2 = resolution / 2
|
|
76
|
+
|
|
77
|
+
for (let cell of cells) {
|
|
78
|
+
//get color
|
|
79
|
+
const col = this.color(cell, resolution, z, viewScale)
|
|
80
|
+
if (!col || col === 'none') continue
|
|
81
|
+
|
|
82
|
+
//number of dots
|
|
83
|
+
const dotNumber = this.dotNumber(cell, resolution, z, viewScale)
|
|
84
|
+
|
|
85
|
+
//get offset
|
|
86
|
+
const offset = this.offset(cell, resolution, z)
|
|
87
|
+
|
|
88
|
+
//cell center
|
|
89
|
+
const cx = cell.x + offset.dx + r2
|
|
90
|
+
const cy = cell.y + offset.dy + r2
|
|
91
|
+
|
|
92
|
+
//convert color
|
|
93
|
+
const cc = color(col)
|
|
94
|
+
if (!cc) return
|
|
95
|
+
|
|
96
|
+
//random points
|
|
97
|
+
for (let i = 0; i <= dotNumber; i++)
|
|
98
|
+
prog.addPointData2(cx + rand(), cy + rand(), cc.r, cc.g, cc.b, cc.opacity)
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
//draw
|
|
102
|
+
prog.draw(geoCanvas.getWebGLTransform())
|
|
103
|
+
|
|
104
|
+
//draw in canvas geo
|
|
105
|
+
geoCanvas.initCanvasTransform()
|
|
106
|
+
ctx.drawImage(cvWGL.canvas, 0, 0)
|
|
107
|
+
} else {
|
|
108
|
+
for (let cell of cells) {
|
|
109
|
+
//get color
|
|
110
|
+
const col = this.color(cell, resolution, z, viewScale)
|
|
111
|
+
if (!col || col === 'none') continue
|
|
112
|
+
//set color
|
|
113
|
+
ctx.fillStyle = col
|
|
114
|
+
|
|
115
|
+
//number of dots
|
|
116
|
+
const dotNumber = this.dotNumber(cell, resolution, z, viewScale)
|
|
117
|
+
|
|
118
|
+
//get offset
|
|
119
|
+
const offset = this.offset(cell, resolution, z)
|
|
120
|
+
|
|
121
|
+
//draw random dots
|
|
122
|
+
const cx = cell.x + offset.dx + resolution / 2,
|
|
123
|
+
cy = cell.y + offset.dy + resolution / 2
|
|
124
|
+
for (let i = 0; i <= dotNumber; i++) {
|
|
125
|
+
ctx.fillRect(cx + rand(), cy + rand(), sGeo, sGeo)
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
//update legends
|
|
131
|
+
this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
|
|
132
|
+
}
|
|
133
|
+
}
|
package/src/style/ImageStyle.js
CHANGED
|
@@ -1,100 +1,100 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Style } from '../core/Style.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @module style
|
|
8
|
-
* @author Julien Gaffuri
|
|
9
|
-
*/
|
|
10
|
-
export class ImageStyle extends Style {
|
|
11
|
-
/** @param {object} opts */
|
|
12
|
-
constructor(opts) {
|
|
13
|
-
super(opts)
|
|
14
|
-
opts = opts || {}
|
|
15
|
-
|
|
16
|
-
/** A function returning the image URL of a cell.
|
|
17
|
-
* @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
|
|
18
|
-
this.image = opts.image || (() => '') //(c,r,z,vs) => {}
|
|
19
|
-
|
|
20
|
-
/** The image size in ground meters
|
|
21
|
-
* @type {function(import('../core/Dataset.js').Cell, number, number, object):number} */
|
|
22
|
-
this.size = opts.size || ((cell, resolution) => resolution)
|
|
23
|
-
|
|
24
|
-
/** Dictionnary of preloaded images. url -> image
|
|
25
|
-
* @private
|
|
26
|
-
* @type {object} */
|
|
27
|
-
this.cache = {}
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @param {Array.<import("../core/Dataset.js").Cell>} cells
|
|
32
|
-
* @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
|
|
33
|
-
* @param {number} resolution
|
|
34
|
-
* @override
|
|
35
|
-
*/
|
|
36
|
-
async draw(cells, geoCanvas, resolution) {
|
|
37
|
-
//
|
|
38
|
-
const z = geoCanvas.view.z,
|
|
39
|
-
resolutionPix = resolution / z
|
|
40
|
-
|
|
41
|
-
//get view scale
|
|
42
|
-
const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
|
|
43
|
-
|
|
44
|
-
//draw in screen coordinates
|
|
45
|
-
geoCanvas.initCanvasTransform()
|
|
46
|
-
|
|
47
|
-
//
|
|
48
|
-
for (let cell of cells) {
|
|
49
|
-
//get cell image url
|
|
50
|
-
const url = this.image(cell, resolution, z, viewScale)
|
|
51
|
-
if (!url) continue
|
|
52
|
-
|
|
53
|
-
//size and position values
|
|
54
|
-
let sizePix = this.size(cell, resolution, z, viewScale) / z
|
|
55
|
-
if (!sizePix) continue
|
|
56
|
-
|
|
57
|
-
//get image from cache
|
|
58
|
-
const image = this.cache[url]
|
|
59
|
-
|
|
60
|
-
//loading, keep waiting
|
|
61
|
-
if (image == 'loading') return
|
|
62
|
-
//no image: load it
|
|
63
|
-
else if (!image) {
|
|
64
|
-
//tag as loading
|
|
65
|
-
this.cache[url] = 'loading'
|
|
66
|
-
|
|
67
|
-
//define image
|
|
68
|
-
const img = new Image()
|
|
69
|
-
img.onload = () => {
|
|
70
|
-
//store image data in cache and redraw
|
|
71
|
-
this.cache[url] = img
|
|
72
|
-
geoCanvas.redraw()
|
|
73
|
-
}
|
|
74
|
-
img.onerror = () => {
|
|
75
|
-
//case when no image
|
|
76
|
-
console.warn('Could not retrieve image from', url)
|
|
77
|
-
}
|
|
78
|
-
//set URL to launch the download
|
|
79
|
-
img.src = url
|
|
80
|
-
} else {
|
|
81
|
-
//draw image
|
|
82
|
-
const d = (resolutionPix - sizePix) / 2
|
|
83
|
-
try {
|
|
84
|
-
geoCanvas.offscreenCtx.drawImage(
|
|
85
|
-
image,
|
|
86
|
-
geoCanvas.geoToPixX(cell.x) + d,
|
|
87
|
-
geoCanvas.geoToPixY(cell.y) + d - resolutionPix,
|
|
88
|
-
sizePix,
|
|
89
|
-
sizePix
|
|
90
|
-
)
|
|
91
|
-
} catch (error) {
|
|
92
|
-
console.error(error)
|
|
93
|
-
}
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
//update legends
|
|
98
|
-
this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
|
|
99
|
-
}
|
|
100
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Style } from '../core/Style.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @module style
|
|
8
|
+
* @author Julien Gaffuri
|
|
9
|
+
*/
|
|
10
|
+
export class ImageStyle extends Style {
|
|
11
|
+
/** @param {object} opts */
|
|
12
|
+
constructor(opts) {
|
|
13
|
+
super(opts)
|
|
14
|
+
opts = opts || {}
|
|
15
|
+
|
|
16
|
+
/** A function returning the image URL of a cell.
|
|
17
|
+
* @type {function(import('../core/Dataset.js').Cell, number, number, object):string} */
|
|
18
|
+
this.image = opts.image || (() => '') //(c,r,z,vs) => {}
|
|
19
|
+
|
|
20
|
+
/** The image size in ground meters
|
|
21
|
+
* @type {function(import('../core/Dataset.js').Cell, number, number, object):number} */
|
|
22
|
+
this.size = opts.size || ((cell, resolution) => resolution)
|
|
23
|
+
|
|
24
|
+
/** Dictionnary of preloaded images. url -> image
|
|
25
|
+
* @private
|
|
26
|
+
* @type {object} */
|
|
27
|
+
this.cache = {}
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @param {Array.<import("../core/Dataset.js").Cell>} cells
|
|
32
|
+
* @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas
|
|
33
|
+
* @param {number} resolution
|
|
34
|
+
* @override
|
|
35
|
+
*/
|
|
36
|
+
async draw(cells, geoCanvas, resolution) {
|
|
37
|
+
//
|
|
38
|
+
const z = geoCanvas.view.z,
|
|
39
|
+
resolutionPix = resolution / z
|
|
40
|
+
|
|
41
|
+
//get view scale
|
|
42
|
+
const viewScale = this.viewScale ? this.viewScale(cells, resolution, z) : undefined
|
|
43
|
+
|
|
44
|
+
//draw in screen coordinates
|
|
45
|
+
geoCanvas.initCanvasTransform()
|
|
46
|
+
|
|
47
|
+
//
|
|
48
|
+
for (let cell of cells) {
|
|
49
|
+
//get cell image url
|
|
50
|
+
const url = this.image(cell, resolution, z, viewScale)
|
|
51
|
+
if (!url) continue
|
|
52
|
+
|
|
53
|
+
//size and position values
|
|
54
|
+
let sizePix = this.size(cell, resolution, z, viewScale) / z
|
|
55
|
+
if (!sizePix) continue
|
|
56
|
+
|
|
57
|
+
//get image from cache
|
|
58
|
+
const image = this.cache[url]
|
|
59
|
+
|
|
60
|
+
//loading, keep waiting
|
|
61
|
+
if (image == 'loading') return
|
|
62
|
+
//no image: load it
|
|
63
|
+
else if (!image) {
|
|
64
|
+
//tag as loading
|
|
65
|
+
this.cache[url] = 'loading'
|
|
66
|
+
|
|
67
|
+
//define image
|
|
68
|
+
const img = new Image()
|
|
69
|
+
img.onload = () => {
|
|
70
|
+
//store image data in cache and redraw
|
|
71
|
+
this.cache[url] = img
|
|
72
|
+
geoCanvas.redraw()
|
|
73
|
+
}
|
|
74
|
+
img.onerror = () => {
|
|
75
|
+
//case when no image
|
|
76
|
+
console.warn('Could not retrieve image from', url)
|
|
77
|
+
}
|
|
78
|
+
//set URL to launch the download
|
|
79
|
+
img.src = url
|
|
80
|
+
} else {
|
|
81
|
+
//draw image
|
|
82
|
+
const d = (resolutionPix - sizePix) / 2
|
|
83
|
+
try {
|
|
84
|
+
geoCanvas.offscreenCtx.drawImage(
|
|
85
|
+
image,
|
|
86
|
+
geoCanvas.geoToPixX(cell.x) + d,
|
|
87
|
+
geoCanvas.geoToPixY(cell.y) + d - resolutionPix,
|
|
88
|
+
sizePix,
|
|
89
|
+
sizePix
|
|
90
|
+
)
|
|
91
|
+
} catch (error) {
|
|
92
|
+
console.error(error)
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
//update legends
|
|
98
|
+
this.updateLegends({ style: this, resolution: resolution, z: z, viewScale: viewScale })
|
|
99
|
+
}
|
|
100
|
+
}
|