gridviz 3.0.26 → 3.0.28
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 +126 -128
- package/dist/gridviz.js +8798 -8706
- package/dist/gridviz.min.js +1 -1
- package/package.json +73 -73
- package/src/button/Button.js +67 -67
- package/src/button/FullscreenButton.js +121 -121
- package/src/button/ZoomButtons.js +103 -103
- package/src/core/Dataset.js +154 -154
- package/src/core/Drawable.js +78 -78
- package/src/core/GeoCanvas.js +443 -443
- package/src/core/Layer.js +23 -23
- package/src/core/Legend.js +108 -108
- package/src/core/Map.js +544 -544
- package/src/core/MultiResolutionDataset.js +93 -93
- package/src/core/Style.js +98 -98
- package/src/core/Tooltip.js +182 -182
- package/src/dataset/COGeo.js +25 -25
- 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 +78 -77
- package/src/layer/BackgroundLayer.js +173 -173
- package/src/layer/BackgroundLayerImage.js +81 -81
- package/src/layer/BackgroundLayerWMS.js +104 -104
- package/src/layer/GeoJSONLayer.js +224 -214
- package/src/layer/GridLayer.js +149 -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/ContourStyle.js +21 -21
- 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/ShadingStyle.js +61 -0
- 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/WebGLRectangleColoring.js +106 -106
- package/src/utils/WebGLSquareColoring.js +118 -118
- package/src/utils/WebGLSquareColoringAdvanced.js +230 -230
- package/src/utils/WebGLSquareColoringCatAdvanced.js +133 -133
- package/src/utils/WebGLSquareColoringKS.js +153 -153
- 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
- package/src/utils/zoomUtils.js +142 -142
package/src/index.js
CHANGED
|
@@ -1,77 +1,78 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
// the application
|
|
5
|
-
export { Map } from './core/Map.js'
|
|
6
|
-
export { GeoCanvas } from './core/GeoCanvas.js'
|
|
7
|
-
export { Style } from './core/Style.js'
|
|
8
|
-
export { Layer } from './core/Layer.js'
|
|
9
|
-
export { Dataset } from './core/Dataset.js'
|
|
10
|
-
export { MultiResolutionDataset } from './core/MultiResolutionDataset.js'
|
|
11
|
-
|
|
12
|
-
// export dataset types
|
|
13
|
-
export { TiledGrid } from './dataset/TiledGrid.js'
|
|
14
|
-
export { CSVGrid } from './dataset/CSVGrid.js'
|
|
15
|
-
export { JSGrid } from './dataset/JSGrid.js'
|
|
16
|
-
|
|
17
|
-
// export styles
|
|
18
|
-
export { ShapeColorSizeStyle } from './style/ShapeColorSizeStyle.js'
|
|
19
|
-
export { StrokeStyle } from './style/StrokeStyle.js'
|
|
20
|
-
export { JoyPlotStyle } from './style/JoyPlotStyle.js'
|
|
21
|
-
export { CompositionStyle } from './style/CompositionStyle.js'
|
|
22
|
-
export { SegmentStyle } from './style/SegmentStyle.js'
|
|
23
|
-
export { TextStyle } from './style/TextStyle.js'
|
|
24
|
-
export { PillarStyle } from './style/PillarStyle.js'
|
|
25
|
-
export { SideStyle } from './style/SideStyle.js'
|
|
26
|
-
|
|
27
|
-
export {
|
|
28
|
-
export {
|
|
29
|
-
export {
|
|
30
|
-
export {
|
|
31
|
-
export {
|
|
32
|
-
export {
|
|
33
|
-
export {
|
|
34
|
-
export {
|
|
35
|
-
export {
|
|
36
|
-
export {
|
|
37
|
-
export {
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
export
|
|
41
|
-
export {
|
|
42
|
-
export {
|
|
43
|
-
export {
|
|
44
|
-
export {
|
|
45
|
-
export {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
export
|
|
49
|
-
export {
|
|
50
|
-
export {
|
|
51
|
-
export {
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
export {
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
export
|
|
63
|
-
export * from './utils/
|
|
64
|
-
export * from './utils/
|
|
65
|
-
export
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
formatDefaultLocale
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
// the application
|
|
5
|
+
export { Map } from './core/Map.js'
|
|
6
|
+
export { GeoCanvas } from './core/GeoCanvas.js'
|
|
7
|
+
export { Style } from './core/Style.js'
|
|
8
|
+
export { Layer } from './core/Layer.js'
|
|
9
|
+
export { Dataset } from './core/Dataset.js'
|
|
10
|
+
export { MultiResolutionDataset } from './core/MultiResolutionDataset.js'
|
|
11
|
+
|
|
12
|
+
// export dataset types
|
|
13
|
+
export { TiledGrid } from './dataset/TiledGrid.js'
|
|
14
|
+
export { CSVGrid } from './dataset/CSVGrid.js'
|
|
15
|
+
export { JSGrid } from './dataset/JSGrid.js'
|
|
16
|
+
|
|
17
|
+
// export styles
|
|
18
|
+
export { ShapeColorSizeStyle } from './style/ShapeColorSizeStyle.js'
|
|
19
|
+
export { StrokeStyle } from './style/StrokeStyle.js'
|
|
20
|
+
export { JoyPlotStyle } from './style/JoyPlotStyle.js'
|
|
21
|
+
export { CompositionStyle } from './style/CompositionStyle.js'
|
|
22
|
+
export { SegmentStyle } from './style/SegmentStyle.js'
|
|
23
|
+
export { TextStyle } from './style/TextStyle.js'
|
|
24
|
+
export { PillarStyle } from './style/PillarStyle.js'
|
|
25
|
+
export { SideStyle } from './style/SideStyle.js'
|
|
26
|
+
export { ShadingStyle } from './style/ShadingStyle.js'
|
|
27
|
+
//export { ContourStyle } from './style/ContourStyle.js'
|
|
28
|
+
export { SideCategoryStyle } from './style/SideCategoryStyle.js'
|
|
29
|
+
export { DotDensityStyle } from './style/DotDensityStyle.js'
|
|
30
|
+
export { TanakaStyle } from './style/TanakaStyle.js'
|
|
31
|
+
export { LegoStyle } from './style/LegoStyle.js'
|
|
32
|
+
export { SquareColorWebGLStyle } from './style/SquareColorWebGLStyle.js'
|
|
33
|
+
export { SquareColorCategoryWebGLStyle } from './style/SquareColorCategoryWebGLStyle.js'
|
|
34
|
+
export { MosaicStyle } from './style/MosaicStyle.js'
|
|
35
|
+
export { NinjaStarStyle } from './style/NinjaStarStyle.js'
|
|
36
|
+
export { TimeSeriesStyle } from './style/TimeSeriesStyle.js'
|
|
37
|
+
export { IsoFenceStyle } from './style/IsoFenceStyle.js'
|
|
38
|
+
export { ImageStyle } from './style/ImageStyle.js'
|
|
39
|
+
|
|
40
|
+
// export additional layers
|
|
41
|
+
export { GridLayer } from './layer/GridLayer.js'
|
|
42
|
+
export { BackgroundLayer } from './layer/BackgroundLayer.js'
|
|
43
|
+
export { BackgroundLayerWMS } from './layer/BackgroundLayerWMS.js'
|
|
44
|
+
export { BackgroundLayerImage } from './layer/BackgroundLayerImage.js'
|
|
45
|
+
export { LabelLayer } from './layer/LabelLayer.js'
|
|
46
|
+
export { GeoJSONLayer } from './layer/GeoJSONLayer.js'
|
|
47
|
+
|
|
48
|
+
// export legends
|
|
49
|
+
export { ColorLegend } from './legend/ColorLegend.js'
|
|
50
|
+
export { ColorDiscreteLegend } from './legend/ColorDiscreteLegend.js'
|
|
51
|
+
export { ColorCategoryLegend } from './legend/ColorCategoryLegend.js'
|
|
52
|
+
export {
|
|
53
|
+
SizeLegend,
|
|
54
|
+
sizeLegend,
|
|
55
|
+
sizeLegendViewScale,
|
|
56
|
+
sizeDiscreteLegend,
|
|
57
|
+
sizeDiscreteViewScaleLegend,
|
|
58
|
+
} from './legend/SizeLegend.js'
|
|
59
|
+
export { OrientationLegend, orientationLegend } from './legend/OrientationLegend.js'
|
|
60
|
+
export { TernaryLegend } from './legend/TernaryLegend.js'
|
|
61
|
+
|
|
62
|
+
// export { goToStraight, zoomTo } from "./utils/zoomUtils"
|
|
63
|
+
export * from './utils/stretching.js'
|
|
64
|
+
export * from './utils/scale.js'
|
|
65
|
+
export * from './utils/ternary.js'
|
|
66
|
+
export { nice } from './utils/utils.js'
|
|
67
|
+
|
|
68
|
+
import { GeoCanvas } from './core/GeoCanvas.js'
|
|
69
|
+
export const getParameterByName = GeoCanvas.getParameterByName
|
|
70
|
+
|
|
71
|
+
// set default d3 locale
|
|
72
|
+
import { formatDefaultLocale } from 'd3-format'
|
|
73
|
+
formatDefaultLocale({
|
|
74
|
+
decimal: '.',
|
|
75
|
+
thousands: ' ',
|
|
76
|
+
grouping: [3],
|
|
77
|
+
currency: ['', '€'],
|
|
78
|
+
})
|
|
@@ -1,173 +1,173 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Layer } from '../core/Layer.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
*
|
|
8
|
-
* A map background layer in "Slippy map" XYZ standard.
|
|
9
|
-
* See https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
|
|
10
|
-
* https://www.maptiler.com/google-maps-coordinates-tile-bounds-projection/#6/27.88/44.48
|
|
11
|
-
*
|
|
12
|
-
* @module layer
|
|
13
|
-
* @author Julien Gaffuri
|
|
14
|
-
*/
|
|
15
|
-
export class BackgroundLayer extends Layer {
|
|
16
|
-
/**
|
|
17
|
-
* @param {object} opts
|
|
18
|
-
*/
|
|
19
|
-
constructor(opts) {
|
|
20
|
-
super(opts)
|
|
21
|
-
opts = opts || {}
|
|
22
|
-
|
|
23
|
-
/** The image cache, indexed by z/y/x
|
|
24
|
-
* @private */
|
|
25
|
-
this.cache = {}
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* @type {string} */
|
|
29
|
-
this.url = opts.url
|
|
30
|
-
/** @type {function(number,number,number):string} */
|
|
31
|
-
this.urlFun = opts.urlFun || ((x, y, z) => this.url + z + '/' + x + '/' + y + '.png')
|
|
32
|
-
|
|
33
|
-
/** The ground resolutions of the zoom levels, starting from the smallest (most zoomed-out, usually 0) to the largest (most zoomed-in).
|
|
34
|
-
* Usually divided by 2 for each zoom level increment.
|
|
35
|
-
* @type {Array.<number>} */
|
|
36
|
-
this.resolutions = opts.resolutions
|
|
37
|
-
if (!this.resolutions || this.resolutions.length == 0)
|
|
38
|
-
throw new Error('No resolutions provided for background layer')
|
|
39
|
-
|
|
40
|
-
/** The tile size, in number of pixels
|
|
41
|
-
* @type {number} */
|
|
42
|
-
this.nbPix = opts.nbPix || 256
|
|
43
|
-
|
|
44
|
-
/** CRS coordinates of top left corner of the top left tile, the one with code /0/0.png.
|
|
45
|
-
* @type {Array.<number>} */
|
|
46
|
-
this.origin = opts.origin || [0, 0]
|
|
47
|
-
|
|
48
|
-
/** The code of the smallest (most zoomed-out) zoom level, in case it is not 0.
|
|
49
|
-
* @type {number} */
|
|
50
|
-
this.z0 = opts.z0 || 0
|
|
51
|
-
|
|
52
|
-
/** A coefficient to adjust the backgroun resolution with the screen resolution.
|
|
53
|
-
* If the background images are too pixelised, reduce the value.
|
|
54
|
-
* If there are too many images to download, increase the value.
|
|
55
|
-
* Default value is 1.0
|
|
56
|
-
* @type {number} */
|
|
57
|
-
this.pixelationCoefficient = opts.pixelationCoefficient || 1.0
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Get z/x/y cache data.
|
|
62
|
-
* @param {number} z
|
|
63
|
-
* @param {number} x
|
|
64
|
-
* @param {number} y
|
|
65
|
-
* @returns {HTMLImageElement|string|undefined}
|
|
66
|
-
* @private
|
|
67
|
-
*/
|
|
68
|
-
get(z, x, y) {
|
|
69
|
-
let d = this.cache[z]
|
|
70
|
-
if (!d) return
|
|
71
|
-
d = d[x]
|
|
72
|
-
if (!d) return
|
|
73
|
-
return d[y]
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
/**
|
|
77
|
-
* Put image in cache.
|
|
78
|
-
* @param {HTMLImageElement|string} img
|
|
79
|
-
* @param {number} z
|
|
80
|
-
* @param {number} x
|
|
81
|
-
* @param {number} y
|
|
82
|
-
* @returns
|
|
83
|
-
* @private
|
|
84
|
-
*/
|
|
85
|
-
put(img, z, x, y) {
|
|
86
|
-
if (!this.cache[z]) this.cache[z] = {}
|
|
87
|
-
if (!this.cache[z][x]) this.cache[z][x] = {}
|
|
88
|
-
this.cache[z][x][y] = img
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/**
|
|
92
|
-
* @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas The canvas where to draw the layer.
|
|
93
|
-
* @returns {void}
|
|
94
|
-
*/
|
|
95
|
-
draw(geoCanvas) {
|
|
96
|
-
if (!this.resolutions || this.resolutions.length == 0) {
|
|
97
|
-
console.error('No resolutions provided for background layer')
|
|
98
|
-
return
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
//
|
|
102
|
-
const z = geoCanvas.view.z
|
|
103
|
-
const x0 = this.origin[0], y0 = this.origin[1]
|
|
104
|
-
|
|
105
|
-
//get zoom level and resolution
|
|
106
|
-
let z_ = 0
|
|
107
|
-
for (z_ = 0; z_ < this.resolutions.length; z_++) if (this.resolutions[z_] < z * this.pixelationCoefficient) break
|
|
108
|
-
z_ -= 1
|
|
109
|
-
z_ = Math.max(0, z_)
|
|
110
|
-
z_ = Math.min(z_, this.resolutions.length - 1)
|
|
111
|
-
const res = this.resolutions[z_]
|
|
112
|
-
z_ += this.z0
|
|
113
|
-
|
|
114
|
-
const sizeG = this.nbPix * res
|
|
115
|
-
const size = sizeG / z
|
|
116
|
-
|
|
117
|
-
//get tile numbers
|
|
118
|
-
const xGeoToTMS = (x) => Math.ceil((x - x0) / sizeG)
|
|
119
|
-
const yGeoToTMS = (y) => Math.ceil(-(y - y0) / sizeG)
|
|
120
|
-
const xMin = xGeoToTMS(geoCanvas.extGeo.xMin) - 1
|
|
121
|
-
const xMax = xGeoToTMS(geoCanvas.extGeo.xMax)
|
|
122
|
-
const yMax = yGeoToTMS(geoCanvas.extGeo.yMin)
|
|
123
|
-
const yMin = yGeoToTMS(geoCanvas.extGeo.yMax) - 1
|
|
124
|
-
|
|
125
|
-
//handle images
|
|
126
|
-
for (let x = xMin; x < xMax; x++) {
|
|
127
|
-
for (let y = yMin; y < yMax; y++) {
|
|
128
|
-
//get image
|
|
129
|
-
let img = this.get(z_, x, y)
|
|
130
|
-
|
|
131
|
-
//no image: load image from URL
|
|
132
|
-
if (!img) {
|
|
133
|
-
const img = new Image()
|
|
134
|
-
this.put(img, z_, x, y)
|
|
135
|
-
img.onload = () => {
|
|
136
|
-
geoCanvas.redraw()
|
|
137
|
-
}
|
|
138
|
-
img.onerror = () => {
|
|
139
|
-
//case when no image
|
|
140
|
-
this.put('failed', z_, x, y)
|
|
141
|
-
}
|
|
142
|
-
img.src = this.urlFun(x, y, z_)
|
|
143
|
-
continue
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
//case when no image available
|
|
147
|
-
if (img === 'failed') continue
|
|
148
|
-
if (!(img instanceof HTMLImageElement)) {
|
|
149
|
-
console.log(img)
|
|
150
|
-
continue
|
|
151
|
-
}
|
|
152
|
-
if (img.width == 0 || img.height == 0) continue
|
|
153
|
-
|
|
154
|
-
//draw image
|
|
155
|
-
const xGeo = x0 + x * sizeG
|
|
156
|
-
const yGeo = y0 - y * sizeG
|
|
157
|
-
try {
|
|
158
|
-
geoCanvas.initCanvasTransform()
|
|
159
|
-
geoCanvas.offscreenCtx.drawImage(
|
|
160
|
-
img,
|
|
161
|
-
geoCanvas.geoToPixX(xGeo),
|
|
162
|
-
geoCanvas.geoToPixY(yGeo),
|
|
163
|
-
size,
|
|
164
|
-
size
|
|
165
|
-
)
|
|
166
|
-
//cg.ctx.drawImage(img, xGeo, yGeo, sizeG, -sizeG)
|
|
167
|
-
} catch (error) {
|
|
168
|
-
console.error(error)
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
}
|
|
173
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Layer } from '../core/Layer.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* A map background layer in "Slippy map" XYZ standard.
|
|
9
|
+
* See https://wiki.openstreetmap.org/wiki/Slippy_map_tilenames
|
|
10
|
+
* https://www.maptiler.com/google-maps-coordinates-tile-bounds-projection/#6/27.88/44.48
|
|
11
|
+
*
|
|
12
|
+
* @module layer
|
|
13
|
+
* @author Julien Gaffuri
|
|
14
|
+
*/
|
|
15
|
+
export class BackgroundLayer extends Layer {
|
|
16
|
+
/**
|
|
17
|
+
* @param {object} opts
|
|
18
|
+
*/
|
|
19
|
+
constructor(opts) {
|
|
20
|
+
super(opts)
|
|
21
|
+
opts = opts || {}
|
|
22
|
+
|
|
23
|
+
/** The image cache, indexed by z/y/x
|
|
24
|
+
* @private */
|
|
25
|
+
this.cache = {}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @type {string} */
|
|
29
|
+
this.url = opts.url
|
|
30
|
+
/** @type {function(number,number,number):string} */
|
|
31
|
+
this.urlFun = opts.urlFun || ((x, y, z) => this.url + z + '/' + x + '/' + y + '.png')
|
|
32
|
+
|
|
33
|
+
/** The ground resolutions of the zoom levels, starting from the smallest (most zoomed-out, usually 0) to the largest (most zoomed-in).
|
|
34
|
+
* Usually divided by 2 for each zoom level increment.
|
|
35
|
+
* @type {Array.<number>} */
|
|
36
|
+
this.resolutions = opts.resolutions
|
|
37
|
+
if (!this.resolutions || this.resolutions.length == 0)
|
|
38
|
+
throw new Error('No resolutions provided for background layer')
|
|
39
|
+
|
|
40
|
+
/** The tile size, in number of pixels
|
|
41
|
+
* @type {number} */
|
|
42
|
+
this.nbPix = opts.nbPix || 256
|
|
43
|
+
|
|
44
|
+
/** CRS coordinates of top left corner of the top left tile, the one with code /0/0.png.
|
|
45
|
+
* @type {Array.<number>} */
|
|
46
|
+
this.origin = opts.origin || [0, 0]
|
|
47
|
+
|
|
48
|
+
/** The code of the smallest (most zoomed-out) zoom level, in case it is not 0.
|
|
49
|
+
* @type {number} */
|
|
50
|
+
this.z0 = opts.z0 || 0
|
|
51
|
+
|
|
52
|
+
/** A coefficient to adjust the backgroun resolution with the screen resolution.
|
|
53
|
+
* If the background images are too pixelised, reduce the value.
|
|
54
|
+
* If there are too many images to download, increase the value.
|
|
55
|
+
* Default value is 1.0
|
|
56
|
+
* @type {number} */
|
|
57
|
+
this.pixelationCoefficient = opts.pixelationCoefficient || 1.0
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Get z/x/y cache data.
|
|
62
|
+
* @param {number} z
|
|
63
|
+
* @param {number} x
|
|
64
|
+
* @param {number} y
|
|
65
|
+
* @returns {HTMLImageElement|string|undefined}
|
|
66
|
+
* @private
|
|
67
|
+
*/
|
|
68
|
+
get(z, x, y) {
|
|
69
|
+
let d = this.cache[z]
|
|
70
|
+
if (!d) return
|
|
71
|
+
d = d[x]
|
|
72
|
+
if (!d) return
|
|
73
|
+
return d[y]
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Put image in cache.
|
|
78
|
+
* @param {HTMLImageElement|string} img
|
|
79
|
+
* @param {number} z
|
|
80
|
+
* @param {number} x
|
|
81
|
+
* @param {number} y
|
|
82
|
+
* @returns
|
|
83
|
+
* @private
|
|
84
|
+
*/
|
|
85
|
+
put(img, z, x, y) {
|
|
86
|
+
if (!this.cache[z]) this.cache[z] = {}
|
|
87
|
+
if (!this.cache[z][x]) this.cache[z][x] = {}
|
|
88
|
+
this.cache[z][x][y] = img
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas The canvas where to draw the layer.
|
|
93
|
+
* @returns {void}
|
|
94
|
+
*/
|
|
95
|
+
draw(geoCanvas) {
|
|
96
|
+
if (!this.resolutions || this.resolutions.length == 0) {
|
|
97
|
+
console.error('No resolutions provided for background layer')
|
|
98
|
+
return
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
//
|
|
102
|
+
const z = geoCanvas.view.z
|
|
103
|
+
const x0 = this.origin[0], y0 = this.origin[1]
|
|
104
|
+
|
|
105
|
+
//get zoom level and resolution
|
|
106
|
+
let z_ = 0
|
|
107
|
+
for (z_ = 0; z_ < this.resolutions.length; z_++) if (this.resolutions[z_] < z * this.pixelationCoefficient) break
|
|
108
|
+
z_ -= 1
|
|
109
|
+
z_ = Math.max(0, z_)
|
|
110
|
+
z_ = Math.min(z_, this.resolutions.length - 1)
|
|
111
|
+
const res = this.resolutions[z_]
|
|
112
|
+
z_ += this.z0
|
|
113
|
+
|
|
114
|
+
const sizeG = this.nbPix * res
|
|
115
|
+
const size = sizeG / z
|
|
116
|
+
|
|
117
|
+
//get tile numbers
|
|
118
|
+
const xGeoToTMS = (x) => Math.ceil((x - x0) / sizeG)
|
|
119
|
+
const yGeoToTMS = (y) => Math.ceil(-(y - y0) / sizeG)
|
|
120
|
+
const xMin = xGeoToTMS(geoCanvas.extGeo.xMin) - 1
|
|
121
|
+
const xMax = xGeoToTMS(geoCanvas.extGeo.xMax)
|
|
122
|
+
const yMax = yGeoToTMS(geoCanvas.extGeo.yMin)
|
|
123
|
+
const yMin = yGeoToTMS(geoCanvas.extGeo.yMax) - 1
|
|
124
|
+
|
|
125
|
+
//handle images
|
|
126
|
+
for (let x = xMin; x < xMax; x++) {
|
|
127
|
+
for (let y = yMin; y < yMax; y++) {
|
|
128
|
+
//get image
|
|
129
|
+
let img = this.get(z_, x, y)
|
|
130
|
+
|
|
131
|
+
//no image: load image from URL
|
|
132
|
+
if (!img) {
|
|
133
|
+
const img = new Image()
|
|
134
|
+
this.put(img, z_, x, y)
|
|
135
|
+
img.onload = () => {
|
|
136
|
+
geoCanvas.redraw()
|
|
137
|
+
}
|
|
138
|
+
img.onerror = () => {
|
|
139
|
+
//case when no image
|
|
140
|
+
this.put('failed', z_, x, y)
|
|
141
|
+
}
|
|
142
|
+
img.src = this.urlFun(x, y, z_)
|
|
143
|
+
continue
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
//case when no image available
|
|
147
|
+
if (img === 'failed') continue
|
|
148
|
+
if (!(img instanceof HTMLImageElement)) {
|
|
149
|
+
console.log(img)
|
|
150
|
+
continue
|
|
151
|
+
}
|
|
152
|
+
if (img.width == 0 || img.height == 0) continue
|
|
153
|
+
|
|
154
|
+
//draw image
|
|
155
|
+
const xGeo = x0 + x * sizeG
|
|
156
|
+
const yGeo = y0 - y * sizeG
|
|
157
|
+
try {
|
|
158
|
+
geoCanvas.initCanvasTransform()
|
|
159
|
+
geoCanvas.offscreenCtx.drawImage(
|
|
160
|
+
img,
|
|
161
|
+
geoCanvas.geoToPixX(xGeo),
|
|
162
|
+
geoCanvas.geoToPixY(yGeo),
|
|
163
|
+
size,
|
|
164
|
+
size
|
|
165
|
+
)
|
|
166
|
+
//cg.ctx.drawImage(img, xGeo, yGeo, sizeG, -sizeG)
|
|
167
|
+
} catch (error) {
|
|
168
|
+
console.error(error)
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
}
|