gridviz 3.0.14 → 3.0.16
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 +127 -128
- package/dist/gridviz.js +7959 -7860
- package/dist/gridviz.min.js +1 -1
- package/package.json +74 -74
- package/src/button/ZoomButtons.js +101 -96
- package/src/core/Dataset.js +154 -157
- package/src/core/Drawable.js +60 -61
- package/src/core/GeoCanvas.js +409 -370
- package/src/core/Layer.js +23 -25
- package/src/core/Legend.js +108 -110
- package/src/core/Map.js +495 -495
- package/src/core/MultiResolutionDataset.js +93 -97
- package/src/core/Style.js +98 -99
- package/src/dataset/CSVGrid.js +112 -112
- package/src/dataset/GeoTIFF.js +122 -123
- package/src/dataset/JSGrid.js +55 -54
- package/src/dataset/TiledGrid.js +289 -288
- package/src/dataset/worker.js +18 -0
- package/src/index.js +77 -71
- package/src/layer/BackgroundLayer.js +162 -158
- package/src/layer/BackgroundLayerImage.js +81 -84
- package/src/layer/BackgroundLayerWMS.js +104 -108
- package/src/layer/GeoJSONLayer.js +214 -220
- package/src/layer/GridLayer.js +148 -157
- package/src/layer/LabelLayer.js +194 -193
- package/src/legend/ColorCategoryLegend.js +109 -110
- package/src/legend/ColorDiscreteLegend.js +100 -102
- package/src/legend/ColorLegend.js +115 -118
- package/src/legend/OrientationLegend.js +89 -91
- package/src/legend/SizeLegend.js +224 -224
- package/src/legend/TernaryLegend.js +302 -210
- package/src/style/CompositionStyle.js +291 -288
- package/src/style/DotDensityStyle.js +133 -134
- package/src/style/ImageStyle.js +100 -102
- package/src/style/IsoFenceStyle.js +217 -203
- package/src/style/JoyPlotStyle.js +127 -128
- 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 -208
- package/src/style/SegmentStyle.js +105 -105
- package/src/style/ShapeColorSizeStyle.js +147 -132
- package/src/style/SideCategoryStyle.js +112 -114
- package/src/style/SideStyle.js +212 -205
- package/src/style/SquareColorCategoryWebGLStyle.js +107 -108
- package/src/style/SquareColorWebGLStyle.js +126 -126
- package/src/style/StrokeStyle.js +135 -136
- package/src/style/TanakaStyle.js +69 -68
- package/src/style/TextStyle.js +110 -111
- package/src/style/TimeSeriesStyle.js +222 -229
- package/src/utils/scale.js +218 -228
- package/src/utils/stretching.js +120 -133
- package/src/utils/ternary.js +203 -203
- package/src/utils/utils.js +58 -63
- package/src/utils/webGLUtils.js +72 -70
|
@@ -1,108 +1,104 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Layer } from '../core/Layer.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
*
|
|
8
|
-
* A map WMS background layer.
|
|
9
|
-
*
|
|
10
|
-
* @module layer
|
|
11
|
-
* @author Julien Gaffuri
|
|
12
|
-
*/
|
|
13
|
-
export class BackgroundLayerWMS extends Layer {
|
|
14
|
-
/**
|
|
15
|
-
* @param {object} opts
|
|
16
|
-
*/
|
|
17
|
-
constructor(opts) {
|
|
18
|
-
super(opts)
|
|
19
|
-
opts = opts || {}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* @type {string} */
|
|
23
|
-
this.url = opts.url
|
|
24
|
-
|
|
25
|
-
/** @type {HTMLImageElement|undefined} */
|
|
26
|
-
this.img = undefined
|
|
27
|
-
|
|
28
|
-
/** @type {number|undefined} */
|
|
29
|
-
this.xMin = undefined
|
|
30
|
-
/** @type {number|undefined} */
|
|
31
|
-
this.xMax = undefined
|
|
32
|
-
/** @type {number|undefined} */
|
|
33
|
-
this.yMin = undefined
|
|
34
|
-
/** @type {number|undefined} */
|
|
35
|
-
this.yMax = undefined
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/** Check if the view has moved and a new image needs to be retrieved.
|
|
39
|
-
* @private */
|
|
40
|
-
hasMoved(extGeo) {
|
|
41
|
-
if (
|
|
42
|
-
else if (
|
|
43
|
-
else if (
|
|
44
|
-
else if (
|
|
45
|
-
else return false
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
* @
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
geoCanvas.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
this.
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
url.push(
|
|
75
|
-
url.push(
|
|
76
|
-
|
|
77
|
-
url.push(
|
|
78
|
-
url.push(geoCanvas.
|
|
79
|
-
|
|
80
|
-
url.push(
|
|
81
|
-
url.push(
|
|
82
|
-
url.push(
|
|
83
|
-
url.push(
|
|
84
|
-
url.push(
|
|
85
|
-
|
|
86
|
-
url.
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
this.img.
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
}
|
|
108
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Layer } from '../core/Layer.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
*
|
|
8
|
+
* A map WMS background layer.
|
|
9
|
+
*
|
|
10
|
+
* @module layer
|
|
11
|
+
* @author Julien Gaffuri
|
|
12
|
+
*/
|
|
13
|
+
export class BackgroundLayerWMS extends Layer {
|
|
14
|
+
/**
|
|
15
|
+
* @param {object} opts
|
|
16
|
+
*/
|
|
17
|
+
constructor(opts) {
|
|
18
|
+
super(opts)
|
|
19
|
+
opts = opts || {}
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* @type {string} */
|
|
23
|
+
this.url = opts.url
|
|
24
|
+
|
|
25
|
+
/** @type {HTMLImageElement|undefined} */
|
|
26
|
+
this.img = undefined
|
|
27
|
+
|
|
28
|
+
/** @type {number|undefined} */
|
|
29
|
+
this.xMin = undefined
|
|
30
|
+
/** @type {number|undefined} */
|
|
31
|
+
this.xMax = undefined
|
|
32
|
+
/** @type {number|undefined} */
|
|
33
|
+
this.yMin = undefined
|
|
34
|
+
/** @type {number|undefined} */
|
|
35
|
+
this.yMax = undefined
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/** Check if the view has moved and a new image needs to be retrieved.
|
|
39
|
+
* @private */
|
|
40
|
+
hasMoved(extGeo) {
|
|
41
|
+
if (extGeo.xMin != this.xMin) return true
|
|
42
|
+
else if (extGeo.xMax != this.xMax) return true
|
|
43
|
+
else if (extGeo.yMin != this.yMin) return true
|
|
44
|
+
else if (extGeo.yMax != this.yMax) return true
|
|
45
|
+
else return false
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* @param {import("../core/GeoCanvas").GeoCanvas} geoCanvas The canvas where to draw the layer.
|
|
50
|
+
* @returns {void}
|
|
51
|
+
*/
|
|
52
|
+
draw(geoCanvas) {
|
|
53
|
+
//update map extent
|
|
54
|
+
geoCanvas.updateExtentGeo(0)
|
|
55
|
+
|
|
56
|
+
if (!this.hasMoved(geoCanvas.extGeo) && this.img) {
|
|
57
|
+
//the map did not move and the image was already downloaded: draw the image
|
|
58
|
+
geoCanvas.initCanvasTransform()
|
|
59
|
+
geoCanvas.offscreenCtx.drawImage(this.img, 0, 0, geoCanvas.w, geoCanvas.h)
|
|
60
|
+
} else {
|
|
61
|
+
//the map moved: retrieve new image
|
|
62
|
+
|
|
63
|
+
//
|
|
64
|
+
this.xMin = geoCanvas.extGeo.xMin
|
|
65
|
+
this.xMax = geoCanvas.extGeo.xMax
|
|
66
|
+
this.yMin = geoCanvas.extGeo.yMin
|
|
67
|
+
this.yMax = geoCanvas.extGeo.yMax
|
|
68
|
+
|
|
69
|
+
//build WMS URL
|
|
70
|
+
const url = []
|
|
71
|
+
url.push(this.url)
|
|
72
|
+
url.push('&width=')
|
|
73
|
+
url.push(geoCanvas.w)
|
|
74
|
+
url.push('&height=')
|
|
75
|
+
url.push(geoCanvas.h)
|
|
76
|
+
//bbox: xmin ymin xmax ymax
|
|
77
|
+
url.push('&bbox=')
|
|
78
|
+
url.push(geoCanvas.extGeo.xMin)
|
|
79
|
+
url.push(',')
|
|
80
|
+
url.push(geoCanvas.extGeo.yMin)
|
|
81
|
+
url.push(',')
|
|
82
|
+
url.push(geoCanvas.extGeo.xMax)
|
|
83
|
+
url.push(',')
|
|
84
|
+
url.push(geoCanvas.extGeo.yMax)
|
|
85
|
+
|
|
86
|
+
const urlS = url.join('')
|
|
87
|
+
//console.log(urlS)
|
|
88
|
+
|
|
89
|
+
if (!this.img) {
|
|
90
|
+
this.img = new Image()
|
|
91
|
+
this.img.onload = () => {
|
|
92
|
+
geoCanvas.redraw()
|
|
93
|
+
}
|
|
94
|
+
this.img.onerror = () => {
|
|
95
|
+
//case when no image
|
|
96
|
+
console.warn('Could not retrieve WMS background image from', urlS)
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
//set URL to launch the download
|
|
101
|
+
this.img.src = urlS
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
}
|
|
@@ -1,220 +1,214 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Layer } from '../core/Layer.js'
|
|
5
|
-
import { json } from 'd3-fetch'
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @module layer
|
|
9
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
10
|
-
*/
|
|
11
|
-
export class GeoJSONLayer extends Layer {
|
|
12
|
-
/**
|
|
13
|
-
* @param {object} opts
|
|
14
|
-
*/
|
|
15
|
-
constructor(opts) {
|
|
16
|
-
super(opts)
|
|
17
|
-
opts = opts || {}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @private
|
|
21
|
-
* @type {string} */
|
|
22
|
-
this.url = opts.url
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* A preprocess to run on each feature after loading.
|
|
26
|
-
* It can be used to apply some specific treatment before, format the label data, project coordinates, etc.
|
|
27
|
-
* Return false if the label should not be kept.
|
|
28
|
-
* @private
|
|
29
|
-
* @type {function(object):boolean} */
|
|
30
|
-
this.preprocess = opts.preprocess
|
|
31
|
-
|
|
32
|
-
//for points
|
|
33
|
-
/**
|
|
34
|
-
* @private
|
|
35
|
-
* @type {function(object,number):string} */
|
|
36
|
-
this.shape = opts.shape || ((f, z) => 'circle')
|
|
37
|
-
/**
|
|
38
|
-
* In pixel
|
|
39
|
-
* @private
|
|
40
|
-
* @type {function(object,number):number} */
|
|
41
|
-
this.size = opts.size || ((f, z) => 10)
|
|
42
|
-
/**
|
|
43
|
-
* @private
|
|
44
|
-
* @type {function(object,number):string} */
|
|
45
|
-
this.strokeStyle = opts.strokeStyle || ((f, z) => 'red')
|
|
46
|
-
/**
|
|
47
|
-
* @private
|
|
48
|
-
* @type {function(object,number):string} */
|
|
49
|
-
this.fillStyle = opts.fillStyle || ((f, z) => 'black')
|
|
50
|
-
/**
|
|
51
|
-
* In pixel
|
|
52
|
-
* @private
|
|
53
|
-
* @type {function(object,number):number} */
|
|
54
|
-
this.lineWidth = opts.lineWidth || ((f, z) => 2)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
*
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
if(
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
//set
|
|
144
|
-
const
|
|
145
|
-
if (!
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
//set
|
|
149
|
-
const
|
|
150
|
-
if (
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
this.
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
console.log('Failed loading boundaries from ' + this.url)
|
|
216
|
-
this.fs = []
|
|
217
|
-
this.loadingStatus = 'failed'
|
|
218
|
-
}
|
|
219
|
-
}
|
|
220
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Layer } from '../core/Layer.js'
|
|
5
|
+
import { json } from 'd3-fetch'
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @module layer
|
|
9
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
10
|
+
*/
|
|
11
|
+
export class GeoJSONLayer extends Layer {
|
|
12
|
+
/**
|
|
13
|
+
* @param {object} opts
|
|
14
|
+
*/
|
|
15
|
+
constructor(opts) {
|
|
16
|
+
super(opts)
|
|
17
|
+
opts = opts || {}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* @private
|
|
21
|
+
* @type {string} */
|
|
22
|
+
this.url = opts.url
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* A preprocess to run on each feature after loading.
|
|
26
|
+
* It can be used to apply some specific treatment before, format the label data, project coordinates, etc.
|
|
27
|
+
* Return false if the label should not be kept.
|
|
28
|
+
* @private
|
|
29
|
+
* @type {function(object):boolean} */
|
|
30
|
+
this.preprocess = opts.preprocess
|
|
31
|
+
|
|
32
|
+
//for points
|
|
33
|
+
/**
|
|
34
|
+
* @private
|
|
35
|
+
* @type {function(object,number):string} */
|
|
36
|
+
this.shape = opts.shape || ((f, z) => 'circle')
|
|
37
|
+
/**
|
|
38
|
+
* In pixel
|
|
39
|
+
* @private
|
|
40
|
+
* @type {function(object,number):number} */
|
|
41
|
+
this.size = opts.size || ((f, z) => 10)
|
|
42
|
+
/**
|
|
43
|
+
* @private
|
|
44
|
+
* @type {function(object,number):string} */
|
|
45
|
+
this.strokeStyle = opts.strokeStyle || ((f, z) => 'red')
|
|
46
|
+
/**
|
|
47
|
+
* @private
|
|
48
|
+
* @type {function(object,number):string} */
|
|
49
|
+
this.fillStyle = opts.fillStyle || ((f, z) => 'black')
|
|
50
|
+
/**
|
|
51
|
+
* In pixel
|
|
52
|
+
* @private
|
|
53
|
+
* @type {function(object,number):number} */
|
|
54
|
+
this.lineWidth = opts.lineWidth || ((f, z) => 2)
|
|
55
|
+
|
|
56
|
+
//for lines
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* @private
|
|
60
|
+
* @type {function(object,number):string} */
|
|
61
|
+
this.color = opts.color || ((f, z) => 'gray')
|
|
62
|
+
/**
|
|
63
|
+
* In pixel
|
|
64
|
+
* @private
|
|
65
|
+
* @type {function(object,number):number} */
|
|
66
|
+
this.width = opts.width || ((f, z) => 2)
|
|
67
|
+
/**
|
|
68
|
+
* @private
|
|
69
|
+
* @type {function(object,number):Array.<number>|undefined} */
|
|
70
|
+
this.lineDash = opts.lineDash || ((f, z) => undefined)
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* @private
|
|
74
|
+
* @type {Array.<object> | undefined} */
|
|
75
|
+
this.fs = undefined
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* @private
|
|
79
|
+
* @type {string} */
|
|
80
|
+
this.loadingStatus = 'notLoaded'
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Draw the layer.
|
|
85
|
+
* @param {import("../core/GeoCanvas.js").GeoCanvas} geoCanvas The canvas where to draw the layer.
|
|
86
|
+
* @returns {void}
|
|
87
|
+
*/
|
|
88
|
+
draw(geoCanvas) {
|
|
89
|
+
//load data, if not done yet.
|
|
90
|
+
if (!this.fs) {
|
|
91
|
+
this.load(geoCanvas.redraw)
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
//
|
|
96
|
+
const z = geoCanvas.view.z
|
|
97
|
+
const ctx = geoCanvas.offscreenCtx
|
|
98
|
+
|
|
99
|
+
for (const f of this.fs) {
|
|
100
|
+
const gt = f.geometry.type
|
|
101
|
+
|
|
102
|
+
if (gt == 'Point') {
|
|
103
|
+
const c = f.geometry.coordinates
|
|
104
|
+
|
|
105
|
+
//get style parameters for the point feature
|
|
106
|
+
const shape = this.shape(f, z)
|
|
107
|
+
if (!shape || shape == 'none') continue
|
|
108
|
+
const size = this.size(f, z) * z
|
|
109
|
+
if (!size) continue
|
|
110
|
+
const strokeStyle = this.strokeStyle(f, z)
|
|
111
|
+
const fillStyle = this.fillStyle(f, z)
|
|
112
|
+
const lineWidth = this.lineWidth(f, z) * z
|
|
113
|
+
|
|
114
|
+
//set canvas drawing parameters
|
|
115
|
+
if (strokeStyle) ctx.strokeStyle = strokeStyle
|
|
116
|
+
if (fillStyle) ctx.fillStyle = fillStyle
|
|
117
|
+
if (lineWidth) ctx.lineWidth = lineWidth
|
|
118
|
+
|
|
119
|
+
if (shape == 'circle') {
|
|
120
|
+
//draw circle - fill and stroke
|
|
121
|
+
ctx.beginPath()
|
|
122
|
+
ctx.arc(c[0], c[1], size / 2, 0, 2 * Math.PI, false)
|
|
123
|
+
if (fillStyle) ctx.fill()
|
|
124
|
+
if (strokeStyle && lineWidth) ctx.stroke()
|
|
125
|
+
} else if (shape == 'square') {
|
|
126
|
+
//draw square - fill and stroke
|
|
127
|
+
ctx.beginPath()
|
|
128
|
+
ctx.rect(c[0] - size / 2, c[1] - size / 2, size, size)
|
|
129
|
+
if (fillStyle) ctx.fill()
|
|
130
|
+
if (strokeStyle && lineWidth) ctx.stroke()
|
|
131
|
+
} else {
|
|
132
|
+
console.error('Unexpected shape for point geojson: ' + shape)
|
|
133
|
+
}
|
|
134
|
+
} else if (gt == 'LineString') {
|
|
135
|
+
const cs = f.geometry.coordinates
|
|
136
|
+
if (cs.length < 2) continue
|
|
137
|
+
|
|
138
|
+
//set color
|
|
139
|
+
const col = this.color(f, z)
|
|
140
|
+
if (!col || col == 'none') continue
|
|
141
|
+
ctx.strokeStyle = col
|
|
142
|
+
|
|
143
|
+
//set linewidth
|
|
144
|
+
const wP = this.width(f, z)
|
|
145
|
+
if (!wP || wP < 0) continue
|
|
146
|
+
ctx.lineWidth = wP * z
|
|
147
|
+
|
|
148
|
+
//set line dash
|
|
149
|
+
const ldP = this.lineDash(f, z)
|
|
150
|
+
if (ldP) ctx.setLineDash(ldP)
|
|
151
|
+
|
|
152
|
+
//draw line
|
|
153
|
+
ctx.beginPath()
|
|
154
|
+
ctx.moveTo(cs[0][0], cs[0][1])
|
|
155
|
+
for (let i = 1; i < cs.length; i++) ctx.lineTo(cs[i][0], cs[i][1])
|
|
156
|
+
ctx.stroke()
|
|
157
|
+
} else {
|
|
158
|
+
console.log('Unsupported geometry type in GeoJSONLayer: ' + gt)
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
//...
|
|
163
|
+
ctx.setLineDash([])
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/**
|
|
167
|
+
* Load data for labels, from URL this.url
|
|
168
|
+
* @param {function():void} callback
|
|
169
|
+
* @private
|
|
170
|
+
*/
|
|
171
|
+
async load(callback) {
|
|
172
|
+
if (!this.url) {
|
|
173
|
+
console.log('Failed loading boundaries: No URL specified. ' + this.url)
|
|
174
|
+
this.loadingStatus = 'failed'
|
|
175
|
+
this.labels = []
|
|
176
|
+
return
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
//check if data already loaded
|
|
180
|
+
if (this.loadingStatus != 'notLoaded') return
|
|
181
|
+
|
|
182
|
+
//load data
|
|
183
|
+
this.loadingStatus = 'loading'
|
|
184
|
+
|
|
185
|
+
try {
|
|
186
|
+
const data_ = await json(this.url)
|
|
187
|
+
|
|
188
|
+
/** @type { Array.<object> } */
|
|
189
|
+
const data = data_.features
|
|
190
|
+
|
|
191
|
+
//preprocess/filter
|
|
192
|
+
if (this.preprocess) {
|
|
193
|
+
this.fs = []
|
|
194
|
+
for (const c of data) {
|
|
195
|
+
const b = this.preprocess(c)
|
|
196
|
+
if (b == false) continue
|
|
197
|
+
this.fs.push(c)
|
|
198
|
+
}
|
|
199
|
+
} else {
|
|
200
|
+
//store labels
|
|
201
|
+
this.fs = data
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
this.loadingStatus = 'loaded'
|
|
205
|
+
|
|
206
|
+
//redraw
|
|
207
|
+
if (callback) callback()
|
|
208
|
+
} catch (error) {
|
|
209
|
+
console.log('Failed loading boundaries from ' + this.url)
|
|
210
|
+
this.fs = []
|
|
211
|
+
this.loadingStatus = 'failed'
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|