gridviz 2.1.13 → 2.1.15
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 +124 -125
- package/dist/gridviz.js +8900 -8368
- package/dist/gridviz.min.js +1 -1
- package/package.json +77 -77
- package/src/App.js +760 -758
- package/src/BackgroundLayer.js +182 -182
- package/src/BackgroundLayerWMS.js +131 -131
- package/src/Dataset.js +76 -76
- package/src/DatasetComponent.js +113 -113
- package/src/GeoCanvas.js +420 -420
- package/src/LabelLayer.js +190 -190
- package/src/Layer.js +103 -103
- package/src/Legend.js +86 -86
- package/src/LineLayer.js +150 -150
- package/src/Style.js +131 -129
- package/src/Tooltip.js +182 -180
- package/src/button/Button.js +66 -54
- package/src/button/FullscreenButton.js +120 -98
- package/src/button/ZoomButtons.js +95 -72
- package/src/dataset/COGeo.js +24 -24
- package/src/dataset/CSVGrid.js +104 -104
- package/src/dataset/GeoTIFF.js +127 -127
- package/src/dataset/GridTile.js +41 -41
- package/src/dataset/LGrid.js +54 -54
- package/src/dataset/TiledGrid.js +264 -264
- package/src/index.js +73 -71
- package/src/legend/ColorCategoryLegend.js +124 -124
- package/src/legend/ColorDiscreteLegend.js +103 -103
- package/src/legend/ColorLegend.js +128 -128
- package/src/legend/SegmentOrientationLegend.js +87 -87
- package/src/legend/SegmentWidthLegend.js +101 -101
- package/src/legend/SizeLegend.js +141 -141
- package/src/style/CompositionStyle.js +300 -300
- package/src/style/CompositionStyle_.js +293 -0
- package/src/style/ContourStyle.js +54 -54
- package/src/style/DotDensityStyle.js +156 -156
- package/src/style/IsoFenceStyle.js +262 -262
- package/src/style/JoyPlotStyle.js +135 -135
- package/src/style/LegoStyle.js +112 -112
- package/src/style/MosaicStyle.js +107 -107
- package/src/style/NinjaStarStyle.js +125 -125
- package/src/style/PillarStyle.js +230 -230
- package/src/style/SegmentStyle.js +142 -142
- package/src/style/ShapeColorSizeStyle.js +152 -152
- package/src/style/ShapeColorSizeStyle_.js +108 -0
- package/src/style/SideCatStyle.js +172 -172
- package/src/style/SideStyle.js +216 -216
- package/src/style/SquareColorCatWGLStyle.js +120 -120
- package/src/style/SquareColorWGLStyle.js +146 -146
- package/src/style/StrokeStyle.js +131 -131
- package/src/style/TanakaStyle.js +160 -160
- package/src/style/TextStyle.js +132 -132
- package/src/style/TimeSeriesStyle.js +259 -259
- package/src/utils/Utils.js +35 -35
- 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/stretching.js +154 -131
- package/src/utils/webGLUtils.js +71 -71
- package/src/utils/zoomUtils.js +142 -142
package/src/dataset/TiledGrid.js
CHANGED
|
@@ -1,264 +1,264 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
/** @typedef {{ dims: object, crs: string, tileSizeCell: number, originPoint: {x:number,y:number}, resolutionGeo: number, tilingBounds:import("../Dataset").Envelope, format:import("../DatasetComponent").Format }} GridInfo */
|
|
5
|
-
|
|
6
|
-
// internal
|
|
7
|
-
import { GridTile } from './GridTile.js'
|
|
8
|
-
import { App } from '../App.js'
|
|
9
|
-
import { DatasetComponent } from '../DatasetComponent.js'
|
|
10
|
-
import { monitor, monitorDuration } from '../utils/Utils.js'
|
|
11
|
-
|
|
12
|
-
// external
|
|
13
|
-
import { json, csv } from 'd3-fetch'
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* A tiled dataset, composed of CSV tiles.
|
|
17
|
-
*
|
|
18
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
19
|
-
*/
|
|
20
|
-
export class TiledGrid extends DatasetComponent {
|
|
21
|
-
/**
|
|
22
|
-
* @param {string} url The URL of the dataset.
|
|
23
|
-
* @param {App} app The application.
|
|
24
|
-
* @param {{preprocess?:(function(import("../Dataset").Cell):boolean) }} opts
|
|
25
|
-
*/
|
|
26
|
-
constructor(url, app, opts = {}) {
|
|
27
|
-
super(url, 0, opts)
|
|
28
|
-
|
|
29
|
-
/**
|
|
30
|
-
* The app being used.
|
|
31
|
-
* @type {App}
|
|
32
|
-
*/
|
|
33
|
-
this.app = app
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* The grid info object, from the info.json file.
|
|
37
|
-
* @type {GridInfo | undefined}
|
|
38
|
-
* @private
|
|
39
|
-
* */
|
|
40
|
-
this.info = undefined
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* @type {string}
|
|
44
|
-
* @private */
|
|
45
|
-
this.infoLoadingStatus = 'notLoaded'
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* The cache of the loaded tiles. It is double indexed: by xT and then yT.
|
|
49
|
-
* Example: this.cache[xT][yT] returns the tile at [xT][yT] location.
|
|
50
|
-
*
|
|
51
|
-
* @type {object}
|
|
52
|
-
* */
|
|
53
|
-
this.cache = {}
|
|
54
|
-
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* Load the info.json from the url.
|
|
59
|
-
*
|
|
60
|
-
* @param {function():void} callback
|
|
61
|
-
* @returns this
|
|
62
|
-
*/
|
|
63
|
-
loadInfo(callback) {
|
|
64
|
-
if (!this.info && this.infoLoadingStatus === 'notLoaded') {
|
|
65
|
-
; (async () => {
|
|
66
|
-
try {
|
|
67
|
-
const data = await json(this.url + 'info.json')
|
|
68
|
-
this.info = data
|
|
69
|
-
this.resolution = data.resolutionGeo
|
|
70
|
-
this.infoLoadingStatus = 'loaded'
|
|
71
|
-
if (callback) callback()
|
|
72
|
-
} catch (error) {
|
|
73
|
-
//mark as failed
|
|
74
|
-
this.infoLoadingStatus = 'failed'
|
|
75
|
-
}
|
|
76
|
-
})()
|
|
77
|
-
} else if (callback && (this.infoLoadingStatus === 'loaded' || this.infoLoadingStatus === 'failed'))
|
|
78
|
-
callback()
|
|
79
|
-
return this
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/**
|
|
83
|
-
* Compute a tiling envelope from a geographical envelope.
|
|
84
|
-
* This is the function to use to know which tiles to download for a geographical view.
|
|
85
|
-
*
|
|
86
|
-
* @param {import("../Dataset").Envelope} e
|
|
87
|
-
* @returns {import("../Dataset").Envelope|undefined}
|
|
88
|
-
*/
|
|
89
|
-
getTilingEnvelope(e) {
|
|
90
|
-
if (!this.info) {
|
|
91
|
-
this.loadInfo(() => { })
|
|
92
|
-
return
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
const po = this.info.originPoint,
|
|
96
|
-
r = this.info.resolutionGeo,
|
|
97
|
-
s = this.info.tileSizeCell
|
|
98
|
-
|
|
99
|
-
return {
|
|
100
|
-
xMin: Math.floor((e.xMin - po.x) / (r * s)),
|
|
101
|
-
xMax: Math.floor((e.xMax - po.x) / (r * s)),
|
|
102
|
-
yMin: Math.floor((e.yMin - po.y) / (r * s)),
|
|
103
|
-
yMax: Math.floor((e.yMax - po.y) / (r * s)),
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
/**
|
|
108
|
-
* Request data within a geographic envelope.
|
|
109
|
-
*
|
|
110
|
-
* @param {import("../Dataset").Envelope} extGeo
|
|
111
|
-
* @param {function():void} redrawFun
|
|
112
|
-
* @returns {this}
|
|
113
|
-
*/
|
|
114
|
-
getData(extGeo, redrawFun) {
|
|
115
|
-
//TODO empty cache when it gets too big ?
|
|
116
|
-
|
|
117
|
-
//check if info has been loaded
|
|
118
|
-
if (!this.info) return this
|
|
119
|
-
|
|
120
|
-
//tiles within the scope
|
|
121
|
-
/** @type {import("../Dataset").Envelope|undefined} */
|
|
122
|
-
const tb = this.getTilingEnvelope(extGeo)
|
|
123
|
-
if (!tb) return this
|
|
124
|
-
|
|
125
|
-
//grid bounds
|
|
126
|
-
/** @type {import("../Dataset").Envelope} */
|
|
127
|
-
const gb = this.info.tilingBounds
|
|
128
|
-
|
|
129
|
-
for (let xT = Math.max(tb.xMin, gb.xMin); xT <= Math.min(tb.xMax, gb.xMax); xT++) {
|
|
130
|
-
for (let yT = Math.max(tb.yMin, gb.yMin); yT <= Math.min(tb.yMax, gb.yMax); yT++) {
|
|
131
|
-
//prepare cache
|
|
132
|
-
if (!this.cache[xT]) this.cache[xT] = {}
|
|
133
|
-
|
|
134
|
-
//check if tile exists in the cache
|
|
135
|
-
/** @type {GridTile} */
|
|
136
|
-
let tile = this.cache[xT][yT]
|
|
137
|
-
if (tile) continue
|
|
138
|
-
|
|
139
|
-
//mark tile as loading
|
|
140
|
-
this.cache[xT][yT] = "loading";
|
|
141
|
-
(async () => {
|
|
142
|
-
//request tile
|
|
143
|
-
/** @type {Array.<import("../Dataset").Cell>} */
|
|
144
|
-
let cells
|
|
145
|
-
|
|
146
|
-
try {
|
|
147
|
-
/** @type {Array.<import("../Dataset").Cell>} */
|
|
148
|
-
// @ts-ignore
|
|
149
|
-
const data = await csv(this.url + xT + '/' + yT + '.csv')
|
|
150
|
-
|
|
151
|
-
//if (monitor) monitorDuration('*** TiledGrid parse start')
|
|
152
|
-
|
|
153
|
-
//preprocess/filter
|
|
154
|
-
if (this.preprocess) {
|
|
155
|
-
cells = []
|
|
156
|
-
for (const c of data) {
|
|
157
|
-
const b = this.preprocess(c)
|
|
158
|
-
if (b == false) continue
|
|
159
|
-
cells.push(c)
|
|
160
|
-
}
|
|
161
|
-
} else {
|
|
162
|
-
cells = data
|
|
163
|
-
}
|
|
164
|
-
|
|
165
|
-
//if (monitor) monitorDuration('preprocess / filter')
|
|
166
|
-
} catch (error) {
|
|
167
|
-
//mark as failed
|
|
168
|
-
this.cache[xT][yT] = 'failed'
|
|
169
|
-
return
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
//store tile in cache
|
|
173
|
-
if (!this.info) {
|
|
174
|
-
console.error('Tile info inknown')
|
|
175
|
-
return
|
|
176
|
-
}
|
|
177
|
-
const tile_ = new GridTile(cells, xT, yT, this.info)
|
|
178
|
-
this.cache[xT][yT] = tile_
|
|
179
|
-
|
|
180
|
-
//if (monitor) monitorDuration('storage')
|
|
181
|
-
|
|
182
|
-
//if no redraw is specified, then leave
|
|
183
|
-
if (!redrawFun) return
|
|
184
|
-
|
|
185
|
-
//check if redraw is really needed, that is if:
|
|
186
|
-
|
|
187
|
-
// 1. the dataset belongs to a layer which is visible at the current zoom level
|
|
188
|
-
let redraw = false
|
|
189
|
-
//go through the layers
|
|
190
|
-
const zf = this.app.getZoomFactor()
|
|
191
|
-
for (const lay of this.app.layers) {
|
|
192
|
-
if (!lay.visible) continue
|
|
193
|
-
if (lay.getDatasetComponent(zf) != this) continue
|
|
194
|
-
//found one layer. No need to seek more.
|
|
195
|
-
redraw = true
|
|
196
|
-
break
|
|
197
|
-
}
|
|
198
|
-
//if (monitor) monitorDuration('check redraw 1')
|
|
199
|
-
|
|
200
|
-
if (!redraw) return
|
|
201
|
-
|
|
202
|
-
// 2. the tile is within the view, that is its geo envelope intersects the viewer geo envelope.
|
|
203
|
-
const env = this.app.updateExtentGeo()
|
|
204
|
-
const envT = tile_.extGeo
|
|
205
|
-
if (env.xMax <= envT.xMin) return
|
|
206
|
-
if (env.xMin >= envT.xMax) return
|
|
207
|
-
if (env.yMax <= envT.yMin) return
|
|
208
|
-
if (env.yMin >= envT.yMax) return
|
|
209
|
-
|
|
210
|
-
//if (monitor) monitorDuration('check redraw 2')
|
|
211
|
-
//if (monitor) monitorDuration('*** TiledGrid parse end')
|
|
212
|
-
|
|
213
|
-
//redraw
|
|
214
|
-
redrawFun()
|
|
215
|
-
})()
|
|
216
|
-
}
|
|
217
|
-
}
|
|
218
|
-
return this
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Fill the view cache with all cells which are within a geographical envelope.
|
|
223
|
-
* @abstract
|
|
224
|
-
* @param {import("../Dataset").Envelope} extGeo
|
|
225
|
-
* @returns {void}
|
|
226
|
-
*/
|
|
227
|
-
updateViewCache(extGeo) {
|
|
228
|
-
//
|
|
229
|
-
this.cellsViewCache = []
|
|
230
|
-
|
|
231
|
-
//check if info has been loaded
|
|
232
|
-
if (!this.info) return
|
|
233
|
-
|
|
234
|
-
//tiles within the scope
|
|
235
|
-
/** @type {import("../Dataset").Envelope|undefined} */
|
|
236
|
-
const tb = this.getTilingEnvelope(extGeo)
|
|
237
|
-
if (!tb) return
|
|
238
|
-
|
|
239
|
-
//grid bounds
|
|
240
|
-
/** @type {import("../Dataset").Envelope} */
|
|
241
|
-
const gb = this.info.tilingBounds
|
|
242
|
-
|
|
243
|
-
for (let xT = Math.max(tb.xMin, gb.xMin); xT <= Math.min(tb.xMax, gb.xMax); xT++) {
|
|
244
|
-
if (!this.cache[xT]) continue
|
|
245
|
-
for (let yT = Math.max(tb.yMin, gb.yMin); yT <= Math.min(tb.yMax, gb.yMax); yT++) {
|
|
246
|
-
//get tile
|
|
247
|
-
/** @type {GridTile} */
|
|
248
|
-
const tile = this.cache[xT][yT]
|
|
249
|
-
if (!tile || typeof tile === 'string') continue
|
|
250
|
-
|
|
251
|
-
//get cells
|
|
252
|
-
//this.cellsViewCache = this.cellsViewCache.concat(tile.cells)
|
|
253
|
-
|
|
254
|
-
for (const cell of tile.cells) {
|
|
255
|
-
if (+cell.x + this.resolution < extGeo.xMin) continue
|
|
256
|
-
if (+cell.x - this.resolution > extGeo.xMax) continue
|
|
257
|
-
if (+cell.y + this.resolution < extGeo.yMin) continue
|
|
258
|
-
if (+cell.y - this.resolution > extGeo.yMax) continue
|
|
259
|
-
this.cellsViewCache.push(cell)
|
|
260
|
-
}
|
|
261
|
-
}
|
|
262
|
-
}
|
|
263
|
-
}
|
|
264
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
/** @typedef {{ dims: object, crs: string, tileSizeCell: number, originPoint: {x:number,y:number}, resolutionGeo: number, tilingBounds:import("../Dataset").Envelope, format:import("../DatasetComponent").Format }} GridInfo */
|
|
5
|
+
|
|
6
|
+
// internal
|
|
7
|
+
import { GridTile } from './GridTile.js'
|
|
8
|
+
import { App } from '../App.js'
|
|
9
|
+
import { DatasetComponent } from '../DatasetComponent.js'
|
|
10
|
+
import { monitor, monitorDuration } from '../utils/Utils.js'
|
|
11
|
+
|
|
12
|
+
// external
|
|
13
|
+
import { json, csv } from 'd3-fetch'
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* A tiled dataset, composed of CSV tiles.
|
|
17
|
+
*
|
|
18
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
19
|
+
*/
|
|
20
|
+
export class TiledGrid extends DatasetComponent {
|
|
21
|
+
/**
|
|
22
|
+
* @param {string} url The URL of the dataset.
|
|
23
|
+
* @param {App} app The application.
|
|
24
|
+
* @param {{preprocess?:(function(import("../Dataset").Cell):boolean) }} opts
|
|
25
|
+
*/
|
|
26
|
+
constructor(url, app, opts = {}) {
|
|
27
|
+
super(url, 0, opts)
|
|
28
|
+
|
|
29
|
+
/**
|
|
30
|
+
* The app being used.
|
|
31
|
+
* @type {App}
|
|
32
|
+
*/
|
|
33
|
+
this.app = app
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* The grid info object, from the info.json file.
|
|
37
|
+
* @type {GridInfo | undefined}
|
|
38
|
+
* @private
|
|
39
|
+
* */
|
|
40
|
+
this.info = undefined
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* @type {string}
|
|
44
|
+
* @private */
|
|
45
|
+
this.infoLoadingStatus = 'notLoaded'
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* The cache of the loaded tiles. It is double indexed: by xT and then yT.
|
|
49
|
+
* Example: this.cache[xT][yT] returns the tile at [xT][yT] location.
|
|
50
|
+
*
|
|
51
|
+
* @type {object}
|
|
52
|
+
* */
|
|
53
|
+
this.cache = {}
|
|
54
|
+
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Load the info.json from the url.
|
|
59
|
+
*
|
|
60
|
+
* @param {function():void} callback
|
|
61
|
+
* @returns this
|
|
62
|
+
*/
|
|
63
|
+
loadInfo(callback) {
|
|
64
|
+
if (!this.info && this.infoLoadingStatus === 'notLoaded') {
|
|
65
|
+
; (async () => {
|
|
66
|
+
try {
|
|
67
|
+
const data = await json(this.url + 'info.json')
|
|
68
|
+
this.info = data
|
|
69
|
+
this.resolution = data.resolutionGeo
|
|
70
|
+
this.infoLoadingStatus = 'loaded'
|
|
71
|
+
if (callback) callback()
|
|
72
|
+
} catch (error) {
|
|
73
|
+
//mark as failed
|
|
74
|
+
this.infoLoadingStatus = 'failed'
|
|
75
|
+
}
|
|
76
|
+
})()
|
|
77
|
+
} else if (callback && (this.infoLoadingStatus === 'loaded' || this.infoLoadingStatus === 'failed'))
|
|
78
|
+
callback()
|
|
79
|
+
return this
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Compute a tiling envelope from a geographical envelope.
|
|
84
|
+
* This is the function to use to know which tiles to download for a geographical view.
|
|
85
|
+
*
|
|
86
|
+
* @param {import("../Dataset").Envelope} e
|
|
87
|
+
* @returns {import("../Dataset").Envelope|undefined}
|
|
88
|
+
*/
|
|
89
|
+
getTilingEnvelope(e) {
|
|
90
|
+
if (!this.info) {
|
|
91
|
+
this.loadInfo(() => { })
|
|
92
|
+
return
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
const po = this.info.originPoint,
|
|
96
|
+
r = this.info.resolutionGeo,
|
|
97
|
+
s = this.info.tileSizeCell
|
|
98
|
+
|
|
99
|
+
return {
|
|
100
|
+
xMin: Math.floor((e.xMin - po.x) / (r * s)),
|
|
101
|
+
xMax: Math.floor((e.xMax - po.x) / (r * s)),
|
|
102
|
+
yMin: Math.floor((e.yMin - po.y) / (r * s)),
|
|
103
|
+
yMax: Math.floor((e.yMax - po.y) / (r * s)),
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
/**
|
|
108
|
+
* Request data within a geographic envelope.
|
|
109
|
+
*
|
|
110
|
+
* @param {import("../Dataset").Envelope} extGeo
|
|
111
|
+
* @param {function():void} redrawFun
|
|
112
|
+
* @returns {this}
|
|
113
|
+
*/
|
|
114
|
+
getData(extGeo, redrawFun) {
|
|
115
|
+
//TODO empty cache when it gets too big ?
|
|
116
|
+
|
|
117
|
+
//check if info has been loaded
|
|
118
|
+
if (!this.info) return this
|
|
119
|
+
|
|
120
|
+
//tiles within the scope
|
|
121
|
+
/** @type {import("../Dataset").Envelope|undefined} */
|
|
122
|
+
const tb = this.getTilingEnvelope(extGeo)
|
|
123
|
+
if (!tb) return this
|
|
124
|
+
|
|
125
|
+
//grid bounds
|
|
126
|
+
/** @type {import("../Dataset").Envelope} */
|
|
127
|
+
const gb = this.info.tilingBounds
|
|
128
|
+
|
|
129
|
+
for (let xT = Math.max(tb.xMin, gb.xMin); xT <= Math.min(tb.xMax, gb.xMax); xT++) {
|
|
130
|
+
for (let yT = Math.max(tb.yMin, gb.yMin); yT <= Math.min(tb.yMax, gb.yMax); yT++) {
|
|
131
|
+
//prepare cache
|
|
132
|
+
if (!this.cache[xT]) this.cache[xT] = {}
|
|
133
|
+
|
|
134
|
+
//check if tile exists in the cache
|
|
135
|
+
/** @type {GridTile} */
|
|
136
|
+
let tile = this.cache[xT][yT]
|
|
137
|
+
if (tile) continue
|
|
138
|
+
|
|
139
|
+
//mark tile as loading
|
|
140
|
+
this.cache[xT][yT] = "loading";
|
|
141
|
+
(async () => {
|
|
142
|
+
//request tile
|
|
143
|
+
/** @type {Array.<import("../Dataset").Cell>} */
|
|
144
|
+
let cells
|
|
145
|
+
|
|
146
|
+
try {
|
|
147
|
+
/** @type {Array.<import("../Dataset").Cell>} */
|
|
148
|
+
// @ts-ignore
|
|
149
|
+
const data = await csv(this.url + xT + '/' + yT + '.csv')
|
|
150
|
+
|
|
151
|
+
//if (monitor) monitorDuration('*** TiledGrid parse start')
|
|
152
|
+
|
|
153
|
+
//preprocess/filter
|
|
154
|
+
if (this.preprocess) {
|
|
155
|
+
cells = []
|
|
156
|
+
for (const c of data) {
|
|
157
|
+
const b = this.preprocess(c)
|
|
158
|
+
if (b == false) continue
|
|
159
|
+
cells.push(c)
|
|
160
|
+
}
|
|
161
|
+
} else {
|
|
162
|
+
cells = data
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
//if (monitor) monitorDuration('preprocess / filter')
|
|
166
|
+
} catch (error) {
|
|
167
|
+
//mark as failed
|
|
168
|
+
this.cache[xT][yT] = 'failed'
|
|
169
|
+
return
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
//store tile in cache
|
|
173
|
+
if (!this.info) {
|
|
174
|
+
console.error('Tile info inknown')
|
|
175
|
+
return
|
|
176
|
+
}
|
|
177
|
+
const tile_ = new GridTile(cells, xT, yT, this.info)
|
|
178
|
+
this.cache[xT][yT] = tile_
|
|
179
|
+
|
|
180
|
+
//if (monitor) monitorDuration('storage')
|
|
181
|
+
|
|
182
|
+
//if no redraw is specified, then leave
|
|
183
|
+
if (!redrawFun) return
|
|
184
|
+
|
|
185
|
+
//check if redraw is really needed, that is if:
|
|
186
|
+
|
|
187
|
+
// 1. the dataset belongs to a layer which is visible at the current zoom level
|
|
188
|
+
let redraw = false
|
|
189
|
+
//go through the layers
|
|
190
|
+
const zf = this.app.getZoomFactor()
|
|
191
|
+
for (const lay of this.app.layers) {
|
|
192
|
+
if (!lay.visible) continue
|
|
193
|
+
if (lay.getDatasetComponent(zf) != this) continue
|
|
194
|
+
//found one layer. No need to seek more.
|
|
195
|
+
redraw = true
|
|
196
|
+
break
|
|
197
|
+
}
|
|
198
|
+
//if (monitor) monitorDuration('check redraw 1')
|
|
199
|
+
|
|
200
|
+
if (!redraw) return
|
|
201
|
+
|
|
202
|
+
// 2. the tile is within the view, that is its geo envelope intersects the viewer geo envelope.
|
|
203
|
+
const env = this.app.updateExtentGeo()
|
|
204
|
+
const envT = tile_.extGeo
|
|
205
|
+
if (env.xMax <= envT.xMin) return
|
|
206
|
+
if (env.xMin >= envT.xMax) return
|
|
207
|
+
if (env.yMax <= envT.yMin) return
|
|
208
|
+
if (env.yMin >= envT.yMax) return
|
|
209
|
+
|
|
210
|
+
//if (monitor) monitorDuration('check redraw 2')
|
|
211
|
+
//if (monitor) monitorDuration('*** TiledGrid parse end')
|
|
212
|
+
|
|
213
|
+
//redraw
|
|
214
|
+
redrawFun()
|
|
215
|
+
})()
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
return this
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/**
|
|
222
|
+
* Fill the view cache with all cells which are within a geographical envelope.
|
|
223
|
+
* @abstract
|
|
224
|
+
* @param {import("../Dataset").Envelope} extGeo
|
|
225
|
+
* @returns {void}
|
|
226
|
+
*/
|
|
227
|
+
updateViewCache(extGeo) {
|
|
228
|
+
//
|
|
229
|
+
this.cellsViewCache = []
|
|
230
|
+
|
|
231
|
+
//check if info has been loaded
|
|
232
|
+
if (!this.info) return
|
|
233
|
+
|
|
234
|
+
//tiles within the scope
|
|
235
|
+
/** @type {import("../Dataset").Envelope|undefined} */
|
|
236
|
+
const tb = this.getTilingEnvelope(extGeo)
|
|
237
|
+
if (!tb) return
|
|
238
|
+
|
|
239
|
+
//grid bounds
|
|
240
|
+
/** @type {import("../Dataset").Envelope} */
|
|
241
|
+
const gb = this.info.tilingBounds
|
|
242
|
+
|
|
243
|
+
for (let xT = Math.max(tb.xMin, gb.xMin); xT <= Math.min(tb.xMax, gb.xMax); xT++) {
|
|
244
|
+
if (!this.cache[xT]) continue
|
|
245
|
+
for (let yT = Math.max(tb.yMin, gb.yMin); yT <= Math.min(tb.yMax, gb.yMax); yT++) {
|
|
246
|
+
//get tile
|
|
247
|
+
/** @type {GridTile} */
|
|
248
|
+
const tile = this.cache[xT][yT]
|
|
249
|
+
if (!tile || typeof tile === 'string') continue
|
|
250
|
+
|
|
251
|
+
//get cells
|
|
252
|
+
//this.cellsViewCache = this.cellsViewCache.concat(tile.cells)
|
|
253
|
+
|
|
254
|
+
for (const cell of tile.cells) {
|
|
255
|
+
if (+cell.x + this.resolution < extGeo.xMin) continue
|
|
256
|
+
if (+cell.x - this.resolution > extGeo.xMax) continue
|
|
257
|
+
if (+cell.y + this.resolution < extGeo.yMin) continue
|
|
258
|
+
if (+cell.y - this.resolution > extGeo.yMax) continue
|
|
259
|
+
this.cellsViewCache.push(cell)
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
}
|