gridviz 2.1.17 → 3.0.0
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 +4971 -5654
- 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 -12
- 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 +460 -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 -10
- 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 +140 -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 +202 -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/index.js
CHANGED
|
@@ -2,65 +2,58 @@
|
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
4
|
// the application
|
|
5
|
-
export {
|
|
6
|
-
export { GeoCanvas } from './GeoCanvas.js'
|
|
7
|
-
export { Style } from './Style.js'
|
|
8
|
-
export { Layer } from './Layer.js'
|
|
9
|
-
export {
|
|
10
|
-
export { DatasetComponent } from './DatasetComponent.js'
|
|
5
|
+
export { Map } from './core/Map.js'
|
|
6
|
+
//export { GeoCanvas } from './GeoCanvas.js'
|
|
7
|
+
export { Style } from './core/Style.js'
|
|
8
|
+
export { Layer } from './core/Layer.js'
|
|
9
|
+
export { MultiResolutionDataset } from './core/MultiResolutionDataset.js'
|
|
11
10
|
|
|
12
11
|
// export dataset types
|
|
13
12
|
export { TiledGrid } from './dataset/TiledGrid.js'
|
|
14
|
-
export { GridTile } from './dataset/GridTile.js'
|
|
15
13
|
export { CSVGrid } from './dataset/CSVGrid.js'
|
|
16
|
-
export {
|
|
17
|
-
//export { GeoTIFF } from "./dataset/GeoTIFF"
|
|
14
|
+
export { JSGrid } from './dataset/JSGrid.js'
|
|
18
15
|
|
|
19
16
|
// export styles
|
|
20
17
|
export { ShapeColorSizeStyle } from './style/ShapeColorSizeStyle.js'
|
|
21
|
-
export { ShapeColorSizeStyle_ } from './style/ShapeColorSizeStyle_.js'
|
|
22
18
|
export { StrokeStyle } from './style/StrokeStyle.js'
|
|
23
19
|
export { JoyPlotStyle } from './style/JoyPlotStyle.js'
|
|
24
20
|
export { CompositionStyle } from './style/CompositionStyle.js'
|
|
25
|
-
export { CompositionStyle_ } from './style/CompositionStyle_.js'
|
|
26
21
|
export { SegmentStyle } from './style/SegmentStyle.js'
|
|
27
22
|
export { TextStyle } from './style/TextStyle.js'
|
|
28
23
|
export { PillarStyle } from './style/PillarStyle.js'
|
|
29
24
|
export { SideStyle } from './style/SideStyle.js'
|
|
30
|
-
export { ContourStyle } from './style/ContourStyle.js'
|
|
31
|
-
export {
|
|
25
|
+
//export { ContourStyle } from './style/ContourStyle.js'
|
|
26
|
+
export { SideCategoryStyle } from './style/SideCategoryStyle.js'
|
|
32
27
|
export { DotDensityStyle } from './style/DotDensityStyle.js'
|
|
33
|
-
export { TanakaStyle } from './style/TanakaStyle.js'
|
|
34
|
-
export { LegoStyle } from './style/LegoStyle.js'
|
|
35
|
-
export {
|
|
36
|
-
export {
|
|
28
|
+
//export { TanakaStyle } from './style/TanakaStyle.js'
|
|
29
|
+
//export { LegoStyle } from './style/LegoStyle.js'
|
|
30
|
+
export { SquareColorWebGLStyle } from './style/SquareColorWebGLStyle.js'
|
|
31
|
+
export { SquareColorCategoryWebGLStyle } from './style/SquareColorCategoryWebGLStyle.js'
|
|
37
32
|
export { MosaicStyle } from './style/MosaicStyle.js'
|
|
38
33
|
export { NinjaStarStyle } from './style/NinjaStarStyle.js'
|
|
39
34
|
export { TimeSeriesStyle } from './style/TimeSeriesStyle.js'
|
|
40
35
|
export { IsoFenceStyle } from './style/IsoFenceStyle.js'
|
|
41
36
|
|
|
42
37
|
// export additional layers
|
|
43
|
-
export {
|
|
44
|
-
export {
|
|
45
|
-
export {
|
|
46
|
-
export {
|
|
38
|
+
export { GridLayer } from './layer/GridLayer.js'
|
|
39
|
+
export { BackgroundLayer } from './layer/BackgroundLayer.js'
|
|
40
|
+
export { BackgroundLayerWMS } from './layer/BackgroundLayerWMS.js'
|
|
41
|
+
export { LabelLayer } from './layer/LabelLayer.js'
|
|
42
|
+
export { GeoJSONLayer } from './layer/GeoJSONLayer.js'
|
|
47
43
|
|
|
48
44
|
// export legends
|
|
49
45
|
export { ColorLegend } from './legend/ColorLegend.js'
|
|
50
46
|
export { ColorDiscreteLegend } from './legend/ColorDiscreteLegend.js'
|
|
51
47
|
export { ColorCategoryLegend } from './legend/ColorCategoryLegend.js'
|
|
52
|
-
export { SizeLegend } from './legend/SizeLegend.js'
|
|
53
|
-
export {
|
|
54
|
-
export { SegmentOrientationLegend } from './legend/SegmentOrientationLegend.js'
|
|
48
|
+
export { SizeLegend, sizeLegend, sizeLegendViewScale, sizeDiscreteLegend, sizeDiscreteViewScaleLegend } from './legend/SizeLegend.js'
|
|
49
|
+
export { OrientationLegend, orientationLegend } from './legend/OrientationLegend.js'
|
|
55
50
|
|
|
56
51
|
// export { goToStraight, zoomTo } from "./utils/zoomUtils"
|
|
57
52
|
export * from './utils/stretching.js'
|
|
53
|
+
export * from './utils/scale.js'
|
|
54
|
+
export { nice } from './utils/utils.js'
|
|
58
55
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
import { GeoCanvas } from './GeoCanvas.js'
|
|
56
|
+
import { GeoCanvas } from './core/GeoCanvas.js'
|
|
64
57
|
export const getParameterByName = GeoCanvas.getParameterByName
|
|
65
58
|
|
|
66
59
|
// set default d3 locale
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
//@ts-check
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
+
import { Layer } from '../core/Layer.js'
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
*
|
|
6
8
|
* A map background layer in "Slippy map" XYZ standard.
|
|
@@ -9,29 +11,14 @@
|
|
|
9
11
|
*
|
|
10
12
|
* @author Julien Gaffuri
|
|
11
13
|
*/
|
|
12
|
-
export class BackgroundLayer {
|
|
14
|
+
export class BackgroundLayer extends Layer {
|
|
13
15
|
/**
|
|
14
16
|
* @param {object} opts
|
|
15
17
|
*/
|
|
16
18
|
constructor(opts) {
|
|
19
|
+
super(opts)
|
|
17
20
|
opts = opts || {}
|
|
18
21
|
|
|
19
|
-
/** An attribute to specify if a layer should be drawn or not
|
|
20
|
-
* @type {boolean} */
|
|
21
|
-
this.visible = opts.visible == false ? false : true
|
|
22
|
-
|
|
23
|
-
/** The minimum zoom factor: Below this level, the layer is not shown.
|
|
24
|
-
* @type {number} */
|
|
25
|
-
this.minZoom = opts.minZoom || 0
|
|
26
|
-
|
|
27
|
-
/** The maximum zoom factor: Above this level, the layer is not shown.
|
|
28
|
-
* @type {number} */
|
|
29
|
-
this.maxZoom = opts.maxZoom || Infinity
|
|
30
|
-
|
|
31
|
-
//ensure acceptable values for the zoom limits.
|
|
32
|
-
if (this.minZoom >= this.maxZoom)
|
|
33
|
-
throw new Error('Unexpected zoom limits for layer. Zoom min should be smaller than zoom max.')
|
|
34
|
-
|
|
35
22
|
/** The image cache, indexed by z/y/x */
|
|
36
23
|
this.cache = {}
|
|
37
24
|
|
|
@@ -53,9 +40,6 @@ export class BackgroundLayer {
|
|
|
53
40
|
this.origin = opts.origin || [0, 0]
|
|
54
41
|
/** @type {number} */
|
|
55
42
|
this.z0 = opts.z0 || 0
|
|
56
|
-
|
|
57
|
-
/** @type {function(number):string} */
|
|
58
|
-
this.filterColor = opts.filterColor // (zf) => "#eee7"
|
|
59
43
|
}
|
|
60
44
|
|
|
61
45
|
/**
|
|
@@ -90,63 +74,61 @@ export class BackgroundLayer {
|
|
|
90
74
|
}
|
|
91
75
|
|
|
92
76
|
/**
|
|
93
|
-
* @param {import("
|
|
77
|
+
* @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas The canvas where to draw the layer.
|
|
94
78
|
* @returns {void}
|
|
95
79
|
*/
|
|
96
|
-
draw(
|
|
80
|
+
draw(geoCanvas) {
|
|
81
|
+
|
|
97
82
|
if (!this.resolutions || this.resolutions.length == 0) {
|
|
98
83
|
console.error('No resolutions provided for background layer')
|
|
99
84
|
return
|
|
100
85
|
}
|
|
101
86
|
|
|
102
87
|
//
|
|
103
|
-
const
|
|
88
|
+
const z = geoCanvas.view.z
|
|
104
89
|
const x0 = this.origin[0],
|
|
105
90
|
y0 = this.origin[1]
|
|
106
91
|
|
|
107
92
|
//get zoom level and resolution
|
|
108
|
-
let
|
|
109
|
-
for (
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
93
|
+
let z_ = 0
|
|
94
|
+
for (z_ = 0; z_ < this.resolutions.length; z_++) if (this.resolutions[z_] < z) break
|
|
95
|
+
z_ -= 1
|
|
96
|
+
z_ = Math.max(0, z_)
|
|
97
|
+
z_ = Math.min(z_, this.resolutions.length - 1)
|
|
113
98
|
//console.log(this.resolutions.length, z)
|
|
114
|
-
const res = this.resolutions[
|
|
99
|
+
const res = this.resolutions[z_]
|
|
115
100
|
|
|
116
|
-
|
|
101
|
+
z_ += this.z0
|
|
117
102
|
|
|
118
103
|
const sizeG = this.nbPix * res
|
|
119
|
-
const size = sizeG /
|
|
104
|
+
const size = sizeG / z
|
|
120
105
|
|
|
121
106
|
//get tile numbers
|
|
122
107
|
const xGeoToTMS = (x) => Math.ceil((x - x0) / sizeG)
|
|
123
108
|
const yGeoToTMS = (y) => Math.ceil(-(y - y0) / sizeG)
|
|
124
|
-
const xMin = xGeoToTMS(
|
|
125
|
-
const xMax = xGeoToTMS(
|
|
126
|
-
const yMax = yGeoToTMS(
|
|
127
|
-
const yMin = yGeoToTMS(
|
|
128
|
-
|
|
129
|
-
//TODO ?
|
|
130
|
-
//cg.setCanvasTransform()
|
|
109
|
+
const xMin = xGeoToTMS(geoCanvas.extGeo.xMin) - 1
|
|
110
|
+
const xMax = xGeoToTMS(geoCanvas.extGeo.xMax)
|
|
111
|
+
const yMax = yGeoToTMS(geoCanvas.extGeo.yMin)
|
|
112
|
+
const yMin = yGeoToTMS(geoCanvas.extGeo.yMax) - 1
|
|
131
113
|
|
|
132
114
|
//handle images
|
|
133
115
|
for (let x = xMin; x < xMax; x++) {
|
|
134
116
|
for (let y = yMin; y < yMax; y++) {
|
|
135
117
|
//get image
|
|
136
|
-
let img = this.get(
|
|
118
|
+
let img = this.get(z_, x, y)
|
|
137
119
|
|
|
138
120
|
//load image
|
|
139
121
|
if (!img) {
|
|
140
122
|
const img = new Image()
|
|
141
|
-
this.put(img,
|
|
123
|
+
this.put(img, z_, x, y)
|
|
142
124
|
img.onload = () => {
|
|
143
|
-
|
|
125
|
+
geoCanvas.redraw()
|
|
144
126
|
}
|
|
145
127
|
img.onerror = () => {
|
|
146
128
|
//case when no image
|
|
147
|
-
this.put('failed',
|
|
129
|
+
this.put('failed', z_, x, y)
|
|
148
130
|
}
|
|
149
|
-
img.src = this.urlFun(x, y,
|
|
131
|
+
img.src = this.urlFun(x, y, z_)
|
|
150
132
|
continue
|
|
151
133
|
}
|
|
152
134
|
|
|
@@ -162,7 +144,8 @@ export class BackgroundLayer {
|
|
|
162
144
|
const xGeo = x0 + x * sizeG
|
|
163
145
|
const yGeo = y0 - y * sizeG
|
|
164
146
|
try {
|
|
165
|
-
|
|
147
|
+
geoCanvas.initCanvasTransform()
|
|
148
|
+
geoCanvas.ctx.drawImage(img, geoCanvas.geoToPixX(xGeo), geoCanvas.geoToPixY(yGeo), size, size)
|
|
166
149
|
//cg.ctx.drawImage(img, xGeo, yGeo, sizeG, -sizeG)
|
|
167
150
|
} catch (error) {
|
|
168
151
|
console.error(error)
|
|
@@ -170,13 +153,5 @@ export class BackgroundLayer {
|
|
|
170
153
|
}
|
|
171
154
|
}
|
|
172
155
|
|
|
173
|
-
//apply filter
|
|
174
|
-
if (this.filterColor) {
|
|
175
|
-
const fc = this.filterColor(zf)
|
|
176
|
-
if (fc && fc != 'none') {
|
|
177
|
-
cg.ctx.fillStyle = fc
|
|
178
|
-
cg.ctx.fillRect(0, 0, cg.w, cg.h)
|
|
179
|
-
}
|
|
180
|
-
}
|
|
181
156
|
}
|
|
182
157
|
}
|
|
@@ -1,42 +1,26 @@
|
|
|
1
1
|
//@ts-check
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
+
import { Layer } from '../core/Layer.js'
|
|
5
|
+
|
|
4
6
|
/**
|
|
5
7
|
*
|
|
6
8
|
* A map WMS background layer.
|
|
7
9
|
*
|
|
8
10
|
* @author Julien Gaffuri
|
|
9
11
|
*/
|
|
10
|
-
export class BackgroundLayerWMS {
|
|
12
|
+
export class BackgroundLayerWMS extends Layer {
|
|
11
13
|
/**
|
|
12
14
|
* @param {object} opts
|
|
13
15
|
*/
|
|
14
16
|
constructor(opts) {
|
|
17
|
+
super(opts)
|
|
15
18
|
opts = opts || {}
|
|
16
19
|
|
|
17
|
-
/** An attribute to specify if a layer should be drawn or not
|
|
18
|
-
* @type {boolean} */
|
|
19
|
-
this.visible = opts.visible == false ? false : true
|
|
20
|
-
|
|
21
|
-
/** The minimum zoom factor: Below this level, the layer is not shown.
|
|
22
|
-
* @type {number} */
|
|
23
|
-
this.minZoom = opts.minZoom || 0
|
|
24
|
-
|
|
25
|
-
/** The maximum zoom factor: Above this level, the layer is not shown.
|
|
26
|
-
* @type {number} */
|
|
27
|
-
this.maxZoom = opts.maxZoom || Infinity
|
|
28
|
-
|
|
29
|
-
//ensure acceptable values for the zoom limits.
|
|
30
|
-
if (this.minZoom >= this.maxZoom)
|
|
31
|
-
throw new Error('Unexpected zoom limits for layer. Zoom min should be smaller than zoom max.')
|
|
32
|
-
|
|
33
20
|
/**
|
|
34
21
|
* @type {string} */
|
|
35
22
|
this.url = opts.url
|
|
36
23
|
|
|
37
|
-
/** @type {function(number):string} */
|
|
38
|
-
this.filterColor = opts.filterColor // (zf) => "#eee7"
|
|
39
|
-
|
|
40
24
|
/** @type {HTMLImageElement|undefined} */
|
|
41
25
|
this.img = undefined;
|
|
42
26
|
|
|
@@ -62,43 +46,44 @@ export class BackgroundLayerWMS {
|
|
|
62
46
|
|
|
63
47
|
|
|
64
48
|
/**
|
|
65
|
-
* @param {import("
|
|
49
|
+
* @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas The canvas where to draw the layer.
|
|
66
50
|
* @returns {void}
|
|
67
51
|
*/
|
|
68
|
-
draw(
|
|
52
|
+
draw(geoCanvas) {
|
|
69
53
|
|
|
70
54
|
//update map extent
|
|
71
|
-
|
|
55
|
+
geoCanvas.updateExtentGeo(0)
|
|
72
56
|
|
|
73
|
-
if (!this.hasMoved(
|
|
57
|
+
if (!this.hasMoved(geoCanvas.extGeo) && this.img) {
|
|
74
58
|
//the map did not move and the image was already downloaded: draw the image
|
|
75
|
-
|
|
59
|
+
geoCanvas.initCanvasTransform()
|
|
60
|
+
geoCanvas.ctx.drawImage(this.img, 0, 0, geoCanvas.w, geoCanvas.h)
|
|
76
61
|
|
|
77
62
|
} else {
|
|
78
63
|
//the map moved: retrieve new image
|
|
79
64
|
|
|
80
65
|
//
|
|
81
|
-
this.xMin =
|
|
82
|
-
this.xMax =
|
|
83
|
-
this.yMin =
|
|
84
|
-
this.yMax =
|
|
66
|
+
this.xMin = geoCanvas.extGeo.xMin
|
|
67
|
+
this.xMax = geoCanvas.extGeo.xMax
|
|
68
|
+
this.yMin = geoCanvas.extGeo.yMin
|
|
69
|
+
this.yMax = geoCanvas.extGeo.yMax
|
|
85
70
|
|
|
86
71
|
//build WMS URL
|
|
87
72
|
const url = []
|
|
88
73
|
url.push(this.url)
|
|
89
74
|
url.push("&width=")
|
|
90
|
-
url.push(
|
|
75
|
+
url.push(geoCanvas.w)
|
|
91
76
|
url.push("&height=")
|
|
92
|
-
url.push(
|
|
77
|
+
url.push(geoCanvas.h)
|
|
93
78
|
//bbox: xmin ymin xmax ymax
|
|
94
79
|
url.push("&bbox=")
|
|
95
|
-
url.push(
|
|
80
|
+
url.push(geoCanvas.extGeo.xMin)
|
|
96
81
|
url.push(",")
|
|
97
|
-
url.push(
|
|
82
|
+
url.push(geoCanvas.extGeo.yMin)
|
|
98
83
|
url.push(",")
|
|
99
|
-
url.push(
|
|
84
|
+
url.push(geoCanvas.extGeo.xMax)
|
|
100
85
|
url.push(",")
|
|
101
|
-
url.push(
|
|
86
|
+
url.push(geoCanvas.extGeo.yMax)
|
|
102
87
|
|
|
103
88
|
const urlS = url.join("")
|
|
104
89
|
//console.log(urlS)
|
|
@@ -106,7 +91,7 @@ export class BackgroundLayerWMS {
|
|
|
106
91
|
if (!this.img) {
|
|
107
92
|
this.img = new Image()
|
|
108
93
|
this.img.onload = () => {
|
|
109
|
-
|
|
94
|
+
geoCanvas.redraw()
|
|
110
95
|
}
|
|
111
96
|
this.img.onerror = () => {
|
|
112
97
|
//case when no image
|
|
@@ -118,14 +103,5 @@ export class BackgroundLayerWMS {
|
|
|
118
103
|
this.img.src = urlS
|
|
119
104
|
}
|
|
120
105
|
|
|
121
|
-
//apply filter
|
|
122
|
-
const zf = cg.getZf()
|
|
123
|
-
if (this.filterColor) {
|
|
124
|
-
const fc = this.filterColor(zf)
|
|
125
|
-
if (fc && fc != 'none') {
|
|
126
|
-
cg.ctx.fillStyle = fc
|
|
127
|
-
cg.ctx.fillRect(0, 0, cg.w, cg.h)
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
106
|
}
|
|
131
107
|
}
|
|
@@ -1,16 +1,18 @@
|
|
|
1
1
|
//@ts-check
|
|
2
2
|
'use strict'
|
|
3
3
|
|
|
4
|
+
import { Layer } from '../core/Layer.js'
|
|
4
5
|
import { json } from 'd3-fetch'
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* @author Joseph Davies, Julien Gaffuri
|
|
8
9
|
*/
|
|
9
|
-
export class
|
|
10
|
+
export class GeoJSONLayer extends Layer {
|
|
10
11
|
/**
|
|
11
12
|
* @param {object} opts
|
|
12
13
|
*/
|
|
13
14
|
constructor(opts) {
|
|
15
|
+
super(opts)
|
|
14
16
|
opts = opts || {}
|
|
15
17
|
|
|
16
18
|
/**
|
|
@@ -29,15 +31,15 @@ export class LineLayer {
|
|
|
29
31
|
/**
|
|
30
32
|
* @private
|
|
31
33
|
* @type {function(object,number):string} */
|
|
32
|
-
this.color = opts.color || ((f,
|
|
34
|
+
this.color = opts.color || ((f, z) => 'gray')
|
|
33
35
|
/**
|
|
34
36
|
* @private
|
|
35
37
|
* @type {function(object,number):number} */
|
|
36
|
-
this.width = opts.width || ((f,
|
|
38
|
+
this.width = opts.width || ((f, z) => 2)
|
|
37
39
|
/**
|
|
38
40
|
* @private
|
|
39
41
|
* @type {function(object,number):Array.<number>|undefined} */
|
|
40
|
-
this.lineDash = opts.lineDash || ((f,
|
|
42
|
+
this.lineDash = opts.lineDash || ((f, z) => undefined)
|
|
41
43
|
|
|
42
44
|
/**
|
|
43
45
|
* @private
|
|
@@ -52,51 +54,48 @@ export class LineLayer {
|
|
|
52
54
|
|
|
53
55
|
/**
|
|
54
56
|
* Draw the layer.
|
|
55
|
-
* @param {import("
|
|
57
|
+
* @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas The canvas where to draw the layer.
|
|
56
58
|
* @returns {void}
|
|
57
59
|
*/
|
|
58
|
-
draw(
|
|
60
|
+
draw(geoCanvas) {
|
|
59
61
|
//load data, if not done yet.
|
|
60
62
|
if (!this.fs) {
|
|
61
|
-
this.load(
|
|
63
|
+
this.load(geoCanvas.redraw)
|
|
62
64
|
return
|
|
63
65
|
}
|
|
64
66
|
|
|
65
67
|
//TODO sort lines by width ?
|
|
66
68
|
|
|
67
|
-
//
|
|
68
|
-
const
|
|
69
|
-
|
|
70
|
-
//draw in geo coordinates
|
|
71
|
-
cg.setCanvasTransform()
|
|
69
|
+
//
|
|
70
|
+
const z = geoCanvas.view.z
|
|
72
71
|
|
|
73
72
|
for (const f of this.fs) {
|
|
74
73
|
const cs = f.geometry.coordinates
|
|
75
74
|
if (cs.length < 2) continue
|
|
76
75
|
|
|
77
76
|
//set color
|
|
78
|
-
const col = this.color(f,
|
|
77
|
+
const col = this.color(f, z)
|
|
79
78
|
if (!col || col == 'none') continue
|
|
80
|
-
|
|
79
|
+
geoCanvas.ctx.strokeStyle = col
|
|
81
80
|
|
|
82
81
|
//set linewidth
|
|
83
|
-
const wP = this.width(f,
|
|
82
|
+
const wP = this.width(f, z)
|
|
84
83
|
if (!wP || wP < 0) continue
|
|
85
|
-
|
|
84
|
+
geoCanvas.ctx.lineWidth = wP * z
|
|
86
85
|
|
|
87
86
|
//set line dash
|
|
88
|
-
const ldP = this.lineDash(f,
|
|
89
|
-
if (ldP)
|
|
87
|
+
const ldP = this.lineDash(f, z)
|
|
88
|
+
if (ldP) geoCanvas.ctx.setLineDash(ldP)
|
|
90
89
|
|
|
91
90
|
//draw line
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
for (let i = 1; i < cs.length; i++)
|
|
95
|
-
|
|
91
|
+
geoCanvas.ctx.beginPath()
|
|
92
|
+
geoCanvas.ctx.moveTo(cs[0][0], cs[0][1])
|
|
93
|
+
for (let i = 1; i < cs.length; i++) geoCanvas.ctx.lineTo(cs[i][0], cs[i][1])
|
|
94
|
+
geoCanvas.ctx.stroke()
|
|
96
95
|
}
|
|
97
96
|
|
|
98
97
|
//...
|
|
99
|
-
|
|
98
|
+
geoCanvas.ctx.setLineDash([])
|
|
100
99
|
}
|
|
101
100
|
|
|
102
101
|
/**
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Layer } from '../core/Layer.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* A layer, which specifies a dataset to be shown with specified styles.
|
|
8
|
+
*
|
|
9
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
10
|
+
*/
|
|
11
|
+
export class GridLayer extends Layer {
|
|
12
|
+
/**
|
|
13
|
+
* @param {import("../core/Dataset").Dataset|import("../core/MultiResolutionDataset").MultiResolutionDataset} dataset The dataset to show.
|
|
14
|
+
* @param {Array.<import("../core/Style").Style>} styles The styles, ordered in drawing order.
|
|
15
|
+
* @param {{visible?:function(number):boolean,alpha?:function(number):number,blendOperation?:function(number):GlobalCompositeOperation,minPixelsPerCell?:number,cellInfoHTML?:function(import("../core/Dataset").Cell):string}} opts
|
|
16
|
+
*/
|
|
17
|
+
constructor(dataset, styles, opts = {}) {
|
|
18
|
+
super(opts)
|
|
19
|
+
opts = opts || {}
|
|
20
|
+
|
|
21
|
+
/** @type {import("../core/Dataset").Dataset|import("../core/MultiResolutionDataset").MultiResolutionDataset} */
|
|
22
|
+
this.dataset = dataset
|
|
23
|
+
/** @type {Array.<import("../core/Style").Style>} */
|
|
24
|
+
this.styles = styles
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* This parameter is used when the dataset is a MultiResolutionDataset.
|
|
28
|
+
* It defines the minimum number of pixels a grid cell should have to select the dataset to display based on its resolution.
|
|
29
|
+
* A low value, means that the map will be more detailled (smaller cells).
|
|
30
|
+
* A high value, means that the map will be less detailled (larger cells).
|
|
31
|
+
* This value should be higher than 1, otherwise it means a grid cell is smaller than the screen resolution.
|
|
32
|
+
* For more complex cell representations that require some more map space, this value should be higher.
|
|
33
|
+
* @type {number} */
|
|
34
|
+
this.minPixelsPerCell = opts.minPixelsPerCell || 3
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* The function returning cell information as HTML.
|
|
38
|
+
* This is typically used for tooltip information.
|
|
39
|
+
* @type {function(import("../core/Dataset").Cell, number):string} */
|
|
40
|
+
this.cellInfoHTML = opts.cellInfoHTML || GridLayer.defaultCellInfoHTML
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
/** */
|
|
44
|
+
draw(geoCanvas, legend) {
|
|
45
|
+
|
|
46
|
+
//get zoom level
|
|
47
|
+
const z = geoCanvas.view.z
|
|
48
|
+
|
|
49
|
+
//get layer dataset component
|
|
50
|
+
/** @type {import('../core/Dataset.js').Dataset|undefined} */
|
|
51
|
+
const dsc = this.getDataset(z)
|
|
52
|
+
if (!dsc) return
|
|
53
|
+
|
|
54
|
+
//launch data download, if necessary
|
|
55
|
+
dsc.getData(geoCanvas.extGeo)
|
|
56
|
+
|
|
57
|
+
//update dataset view cache
|
|
58
|
+
dsc.updateViewCache(geoCanvas.extGeo)
|
|
59
|
+
|
|
60
|
+
//draw cells, style by style
|
|
61
|
+
for (const s of this.styles) {
|
|
62
|
+
|
|
63
|
+
//check if style is visible
|
|
64
|
+
if (s.visible && !s.visible(z)) continue
|
|
65
|
+
|
|
66
|
+
//set style alpha and blend mode
|
|
67
|
+
//TODO: multiply by layer alpha ?
|
|
68
|
+
geoCanvas.ctx.globalAlpha = s.alpha ? s.alpha(z) : 1.0
|
|
69
|
+
geoCanvas.ctx.globalCompositeOperation = s.blendOperation(z)
|
|
70
|
+
|
|
71
|
+
//set affin transform to draw with geographical coordinates
|
|
72
|
+
geoCanvas.setCanvasTransform()
|
|
73
|
+
|
|
74
|
+
//draw with style
|
|
75
|
+
s.draw(dsc.getViewCache(), geoCanvas, dsc.getResolution())
|
|
76
|
+
|
|
77
|
+
//draw style filter
|
|
78
|
+
if (s.filterColor)
|
|
79
|
+
s.drawFilter(geoCanvas)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
//add legend element
|
|
83
|
+
if (legend) {
|
|
84
|
+
for (const s of this.styles) {
|
|
85
|
+
//check if style is visible
|
|
86
|
+
if (s.visible && !s.visible(z)) continue
|
|
87
|
+
for (const lg of s.legends) {
|
|
88
|
+
//console.log(s, lg)
|
|
89
|
+
//this.legend.append(lg.div)
|
|
90
|
+
//s1.node().appendChild(s2.node())
|
|
91
|
+
legend.node().append(lg.div.node())
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
//case for styles of styles, like kernel smoothing
|
|
95
|
+
//TODO do better
|
|
96
|
+
if (s['styles']) {
|
|
97
|
+
for (const s2 of s['styles']) {
|
|
98
|
+
if (s2.visible && !s2.visible(z)) continue
|
|
99
|
+
for (const lg of s2.legends) {
|
|
100
|
+
//console.log(s, lg)
|
|
101
|
+
//this.legend.append(lg.div)
|
|
102
|
+
//s1.node().appendChild(s2.node())
|
|
103
|
+
legend.node().append(lg.div.node())
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
|
|
114
|
+
/**
|
|
115
|
+
* Return the relevant dataset component for a specified zoom.
|
|
116
|
+
*
|
|
117
|
+
* @param {number} z
|
|
118
|
+
* @returns {import("../core/Dataset").Dataset|undefined}
|
|
119
|
+
* */
|
|
120
|
+
getDataset(z) {
|
|
121
|
+
return this.dataset.getDataset(z, this.minPixelsPerCell);
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* The default function returning cell information as HTML.
|
|
126
|
+
* This is typically used for tooltip information.
|
|
127
|
+
*
|
|
128
|
+
* @param {import("../core/Dataset").Cell} cell
|
|
129
|
+
* @returns {string}
|
|
130
|
+
*/
|
|
131
|
+
static defaultCellInfoHTML(cell) {
|
|
132
|
+
const buf = []
|
|
133
|
+
for (const key of Object.keys(cell)) {
|
|
134
|
+
if (key === 'x') continue
|
|
135
|
+
if (key === 'y') continue
|
|
136
|
+
buf.push('<b>', key, '</b>', ' : ', cell[key], '<br>')
|
|
137
|
+
}
|
|
138
|
+
return buf.join('')
|
|
139
|
+
}
|
|
140
|
+
}
|