gridviz 3.0.23 → 3.0.24
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 +8618 -8579
- package/dist/gridviz.min.js +1 -1
- package/package.json +74 -74
- package/src/button/Button.js +67 -67
- package/src/button/FullscreenButton.js +121 -121
- package/src/button/ZoomButtons.js +103 -101
- package/src/core/Dataset.js +154 -154
- package/src/core/Drawable.js +78 -78
- package/src/core/GeoCanvas.js +437 -430
- package/src/core/Layer.js +23 -23
- package/src/core/Legend.js +108 -108
- package/src/core/Map.js +542 -516
- 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 +77 -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 +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/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/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/core/Tooltip.js
CHANGED
|
@@ -1,182 +1,182 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { select } from 'd3-selection'
|
|
5
|
-
//import { transition } from "d3-transition";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* A generic class to make a tooltip.
|
|
9
|
-
* It is a div element, which can be moved under the mouse pointer and filled with some information in html.
|
|
10
|
-
* @module core
|
|
11
|
-
*/
|
|
12
|
-
export class Tooltip {
|
|
13
|
-
/**
|
|
14
|
-
* @param {object} opts
|
|
15
|
-
*/
|
|
16
|
-
constructor(opts) {
|
|
17
|
-
opts = opts || {}
|
|
18
|
-
|
|
19
|
-
/** @type {string} */
|
|
20
|
-
this.maxWidth = opts.maxWidth || '20em'
|
|
21
|
-
/** @type {string} */
|
|
22
|
-
this.fontSize = opts.fontSize || '1.2em'
|
|
23
|
-
/** @type {string} */
|
|
24
|
-
this.background = opts.background || 'white'
|
|
25
|
-
/** @type {string} */
|
|
26
|
-
this.padding = opts.padding || '5px'
|
|
27
|
-
/** @type {string} */
|
|
28
|
-
this.border = opts.border || '0px'
|
|
29
|
-
/** @type {string} */
|
|
30
|
-
this['border-radius'] = opts['border-radius'] || '0px'
|
|
31
|
-
/** @type {string} */
|
|
32
|
-
this['box-shadow'] = opts['box-shadow'] || '5px 5px 5px grey'
|
|
33
|
-
/** @type {string} */
|
|
34
|
-
this['font-family'] = opts['font-family'] || 'Helvetica, Arial, sans-serif'
|
|
35
|
-
|
|
36
|
-
/** @type {number} */
|
|
37
|
-
this.transitionDuration = opts.transitionDuration || 100
|
|
38
|
-
/** @type {number} */
|
|
39
|
-
this.xOffset = opts.xOffset || 30
|
|
40
|
-
/** @type {number} */
|
|
41
|
-
this.yOffset = opts.yOffset || 20
|
|
42
|
-
/** @type {number} */ // e.g. to prevent mouse cursor covering cell being highlighted
|
|
43
|
-
this.yMouseOffset = opts.yMouseOffset || 0
|
|
44
|
-
/** @type {number} */
|
|
45
|
-
this.xMouseOffset = opts.xMouseOffset || 0
|
|
46
|
-
/** @type {HTMLElement} */
|
|
47
|
-
this.parentElement = opts.parentElement || document.body
|
|
48
|
-
/** @type {HTMLElement} */
|
|
49
|
-
this.tooltipElement = opts.tooltipElement || null
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* @public
|
|
53
|
-
* @type {import("d3-selection").Selection} */
|
|
54
|
-
this.tooltip = opts.tooltipElement
|
|
55
|
-
? select(opts.tooltipElement) // Wrap the provided HTML node in a D3 selection
|
|
56
|
-
: select(this.parentElement).append('div').attr('id', 'gridviz-tooltip').attr('class', 'gridviz-tooltip') // create default element
|
|
57
|
-
|
|
58
|
-
//initialise
|
|
59
|
-
this.tooltip.style('max-width', this.maxWidth)
|
|
60
|
-
this.tooltip.style('overflow', 'hidden')
|
|
61
|
-
this.tooltip.style('font-size', this.fontSize)
|
|
62
|
-
this.tooltip.style('background', this.background)
|
|
63
|
-
this.tooltip.style('padding', this.padding)
|
|
64
|
-
this.tooltip.style('border', this.border)
|
|
65
|
-
this.tooltip.style('border-radius', this['border-radius'])
|
|
66
|
-
this.tooltip.style('box-shadow', this['box-shadow'])
|
|
67
|
-
this.tooltip.style('font-family', this['font-family'])
|
|
68
|
-
this.tooltip.style('position', 'absolute')
|
|
69
|
-
this.tooltip.style('pointer-events', 'none')
|
|
70
|
-
this.tooltip.style('opacity', '0')
|
|
71
|
-
this.tooltip.style('text-wrap', 'nowrap')
|
|
72
|
-
this.tooltip.style('z-index', 99999999) // important for leaflet-gridviz etc
|
|
73
|
-
|
|
74
|
-
// these placeholders are needed to prevent an infinite DOM resizeObserver loop:
|
|
75
|
-
this.tooltip.style('left', '0')
|
|
76
|
-
this.tooltip.style('top', '0')
|
|
77
|
-
|
|
78
|
-
// aria-labels (thanks to wahlatlas)
|
|
79
|
-
this.tooltip.attr('role', 'tooltip').attr('aria-live', 'polite')
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
/** Show the tooltip */
|
|
83
|
-
show() {
|
|
84
|
-
// @ts-ignore
|
|
85
|
-
this.tooltip.transition().duration(this.transitionDuration).style('opacity', 1)
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
/** Hide the tooltip */
|
|
89
|
-
hide() {
|
|
90
|
-
// @ts-ignore
|
|
91
|
-
this.tooltip.transition().duration(this.transitionDuration).style('opacity', 0)
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
/**
|
|
95
|
-
* Set the content of the tooltip.
|
|
96
|
-
* @param {string} html
|
|
97
|
-
*/
|
|
98
|
-
html(html) {
|
|
99
|
-
this.tooltip.html(html)
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Set the position of the tooltip at the mouse event position.
|
|
104
|
-
* @param {MouseEvent} event
|
|
105
|
-
*/
|
|
106
|
-
setPosition(event) {
|
|
107
|
-
// Get the bounding rect of the parent container (map2)
|
|
108
|
-
let parentRect = this.parentElement.getBoundingClientRect()
|
|
109
|
-
|
|
110
|
-
// Get the mouse position (relative to the parent container)
|
|
111
|
-
let x = event.clientX - parentRect.left + this.xOffset // Relative to parent
|
|
112
|
-
let y = event.clientY - parentRect.top - this.yOffset // Relative to parent
|
|
113
|
-
|
|
114
|
-
// Now, apply the position to the tooltip
|
|
115
|
-
this.tooltip.style('left', x + 'px').style('top', y + 'px')
|
|
116
|
-
|
|
117
|
-
// Ensure the tooltip stays inside the parent container
|
|
118
|
-
this.ensureTooltipInsideContainer(event, parentRect, this.tooltip.node())
|
|
119
|
-
}
|
|
120
|
-
/**
|
|
121
|
-
* @function ensureTooltipInsideContainer
|
|
122
|
-
* @description Prevents the tooltip from overflowing out of the App container (ensures that the tooltip is inside the gridviz container)
|
|
123
|
-
* @param {MouseEvent} event
|
|
124
|
-
* @param {DOMRect} parentRect
|
|
125
|
-
* @param {HTMLElement} tooltipNode
|
|
126
|
-
*/
|
|
127
|
-
ensureTooltipInsideContainer(event, parentRect, tooltipNode) {
|
|
128
|
-
let node = tooltipNode
|
|
129
|
-
let parentWidth = parentRect.width
|
|
130
|
-
let parentHeight = parentRect.height
|
|
131
|
-
|
|
132
|
-
// Ensure tooltip doesn't go beyond the right edge
|
|
133
|
-
if (node.offsetLeft + node.clientWidth > parentWidth) {
|
|
134
|
-
let left = event.clientX - node.clientWidth - this.xOffset
|
|
135
|
-
node.style.left = left + 'px'
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
// Ensure tooltip doesn't go beyond the bottom edge
|
|
139
|
-
if (node.offsetTop + node.clientHeight > parentHeight) {
|
|
140
|
-
node.style.top = parentHeight - node.clientHeight + 'px'
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
// Ensure tooltip doesn't go above the top edge
|
|
144
|
-
if (node.offsetTop < 0) {
|
|
145
|
-
node.style.top = 0 + 'px'
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
// Ensure tooltip doesn't go beyond the left edge
|
|
149
|
-
if (node.offsetLeft < 0) {
|
|
150
|
-
node.style.left = 0 + 'px'
|
|
151
|
-
}
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/*
|
|
155
|
-
my.mouseover = function (event, html) {
|
|
156
|
-
if (html) my.html(html);
|
|
157
|
-
my.setPosition(event);
|
|
158
|
-
my.show()
|
|
159
|
-
//this.ensureTooltipInsideContainer();
|
|
160
|
-
};
|
|
161
|
-
|
|
162
|
-
my.mousemove = function (event) {
|
|
163
|
-
my.setPosition(event);
|
|
164
|
-
//this.ensureTooltipInsideContainer();
|
|
165
|
-
};
|
|
166
|
-
|
|
167
|
-
my.mouseout = function () {
|
|
168
|
-
my.hide();
|
|
169
|
-
};*/
|
|
170
|
-
|
|
171
|
-
style(k, v) {
|
|
172
|
-
if (arguments.length == 1) return this.tooltip.style(k)
|
|
173
|
-
this.tooltip.style(k, v)
|
|
174
|
-
return this
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
attr(k, v) {
|
|
178
|
-
if (arguments.length == 1) return this.tooltip.attr(k)
|
|
179
|
-
this.tooltip.attr(k, v)
|
|
180
|
-
return this
|
|
181
|
-
}
|
|
182
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { select } from 'd3-selection'
|
|
5
|
+
//import { transition } from "d3-transition";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* A generic class to make a tooltip.
|
|
9
|
+
* It is a div element, which can be moved under the mouse pointer and filled with some information in html.
|
|
10
|
+
* @module core
|
|
11
|
+
*/
|
|
12
|
+
export class Tooltip {
|
|
13
|
+
/**
|
|
14
|
+
* @param {object} opts
|
|
15
|
+
*/
|
|
16
|
+
constructor(opts) {
|
|
17
|
+
opts = opts || {}
|
|
18
|
+
|
|
19
|
+
/** @type {string} */
|
|
20
|
+
this.maxWidth = opts.maxWidth || '20em'
|
|
21
|
+
/** @type {string} */
|
|
22
|
+
this.fontSize = opts.fontSize || '1.2em'
|
|
23
|
+
/** @type {string} */
|
|
24
|
+
this.background = opts.background || 'white'
|
|
25
|
+
/** @type {string} */
|
|
26
|
+
this.padding = opts.padding || '5px'
|
|
27
|
+
/** @type {string} */
|
|
28
|
+
this.border = opts.border || '0px'
|
|
29
|
+
/** @type {string} */
|
|
30
|
+
this['border-radius'] = opts['border-radius'] || '0px'
|
|
31
|
+
/** @type {string} */
|
|
32
|
+
this['box-shadow'] = opts['box-shadow'] || '5px 5px 5px grey'
|
|
33
|
+
/** @type {string} */
|
|
34
|
+
this['font-family'] = opts['font-family'] || 'Helvetica, Arial, sans-serif'
|
|
35
|
+
|
|
36
|
+
/** @type {number} */
|
|
37
|
+
this.transitionDuration = opts.transitionDuration || 100
|
|
38
|
+
/** @type {number} */
|
|
39
|
+
this.xOffset = opts.xOffset || 30
|
|
40
|
+
/** @type {number} */
|
|
41
|
+
this.yOffset = opts.yOffset || 20
|
|
42
|
+
/** @type {number} */ // e.g. to prevent mouse cursor covering cell being highlighted
|
|
43
|
+
this.yMouseOffset = opts.yMouseOffset || 0
|
|
44
|
+
/** @type {number} */
|
|
45
|
+
this.xMouseOffset = opts.xMouseOffset || 0
|
|
46
|
+
/** @type {HTMLElement} */
|
|
47
|
+
this.parentElement = opts.parentElement || document.body
|
|
48
|
+
/** @type {HTMLElement} */
|
|
49
|
+
this.tooltipElement = opts.tooltipElement || null
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* @public
|
|
53
|
+
* @type {import("d3-selection").Selection} */
|
|
54
|
+
this.tooltip = opts.tooltipElement
|
|
55
|
+
? select(opts.tooltipElement) // Wrap the provided HTML node in a D3 selection
|
|
56
|
+
: select(this.parentElement).append('div').attr('id', 'gridviz-tooltip').attr('class', 'gridviz-tooltip') // create default element
|
|
57
|
+
|
|
58
|
+
//initialise
|
|
59
|
+
this.tooltip.style('max-width', this.maxWidth)
|
|
60
|
+
this.tooltip.style('overflow', 'hidden')
|
|
61
|
+
this.tooltip.style('font-size', this.fontSize)
|
|
62
|
+
this.tooltip.style('background', this.background)
|
|
63
|
+
this.tooltip.style('padding', this.padding)
|
|
64
|
+
this.tooltip.style('border', this.border)
|
|
65
|
+
this.tooltip.style('border-radius', this['border-radius'])
|
|
66
|
+
this.tooltip.style('box-shadow', this['box-shadow'])
|
|
67
|
+
this.tooltip.style('font-family', this['font-family'])
|
|
68
|
+
this.tooltip.style('position', 'absolute')
|
|
69
|
+
this.tooltip.style('pointer-events', 'none')
|
|
70
|
+
this.tooltip.style('opacity', '0')
|
|
71
|
+
this.tooltip.style('text-wrap', 'nowrap')
|
|
72
|
+
this.tooltip.style('z-index', 99999999) // important for leaflet-gridviz etc
|
|
73
|
+
|
|
74
|
+
// these placeholders are needed to prevent an infinite DOM resizeObserver loop:
|
|
75
|
+
this.tooltip.style('left', '0')
|
|
76
|
+
this.tooltip.style('top', '0')
|
|
77
|
+
|
|
78
|
+
// aria-labels (thanks to wahlatlas)
|
|
79
|
+
this.tooltip.attr('role', 'tooltip').attr('aria-live', 'polite')
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
/** Show the tooltip */
|
|
83
|
+
show() {
|
|
84
|
+
// @ts-ignore
|
|
85
|
+
this.tooltip.transition().duration(this.transitionDuration).style('opacity', 1)
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** Hide the tooltip */
|
|
89
|
+
hide() {
|
|
90
|
+
// @ts-ignore
|
|
91
|
+
this.tooltip.transition().duration(this.transitionDuration).style('opacity', 0)
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Set the content of the tooltip.
|
|
96
|
+
* @param {string} html
|
|
97
|
+
*/
|
|
98
|
+
html(html) {
|
|
99
|
+
this.tooltip.html(html)
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
* Set the position of the tooltip at the mouse event position.
|
|
104
|
+
* @param {MouseEvent} event
|
|
105
|
+
*/
|
|
106
|
+
setPosition(event) {
|
|
107
|
+
// Get the bounding rect of the parent container (map2)
|
|
108
|
+
let parentRect = this.parentElement.getBoundingClientRect()
|
|
109
|
+
|
|
110
|
+
// Get the mouse position (relative to the parent container)
|
|
111
|
+
let x = event.clientX - parentRect.left + this.xOffset // Relative to parent
|
|
112
|
+
let y = event.clientY - parentRect.top - this.yOffset // Relative to parent
|
|
113
|
+
|
|
114
|
+
// Now, apply the position to the tooltip
|
|
115
|
+
this.tooltip.style('left', x + 'px').style('top', y + 'px')
|
|
116
|
+
|
|
117
|
+
// Ensure the tooltip stays inside the parent container
|
|
118
|
+
this.ensureTooltipInsideContainer(event, parentRect, this.tooltip.node())
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* @function ensureTooltipInsideContainer
|
|
122
|
+
* @description Prevents the tooltip from overflowing out of the App container (ensures that the tooltip is inside the gridviz container)
|
|
123
|
+
* @param {MouseEvent} event
|
|
124
|
+
* @param {DOMRect} parentRect
|
|
125
|
+
* @param {HTMLElement} tooltipNode
|
|
126
|
+
*/
|
|
127
|
+
ensureTooltipInsideContainer(event, parentRect, tooltipNode) {
|
|
128
|
+
let node = tooltipNode
|
|
129
|
+
let parentWidth = parentRect.width
|
|
130
|
+
let parentHeight = parentRect.height
|
|
131
|
+
|
|
132
|
+
// Ensure tooltip doesn't go beyond the right edge
|
|
133
|
+
if (node.offsetLeft + node.clientWidth > parentWidth) {
|
|
134
|
+
let left = event.clientX - node.clientWidth - this.xOffset
|
|
135
|
+
node.style.left = left + 'px'
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
// Ensure tooltip doesn't go beyond the bottom edge
|
|
139
|
+
if (node.offsetTop + node.clientHeight > parentHeight) {
|
|
140
|
+
node.style.top = parentHeight - node.clientHeight + 'px'
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
// Ensure tooltip doesn't go above the top edge
|
|
144
|
+
if (node.offsetTop < 0) {
|
|
145
|
+
node.style.top = 0 + 'px'
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Ensure tooltip doesn't go beyond the left edge
|
|
149
|
+
if (node.offsetLeft < 0) {
|
|
150
|
+
node.style.left = 0 + 'px'
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
/*
|
|
155
|
+
my.mouseover = function (event, html) {
|
|
156
|
+
if (html) my.html(html);
|
|
157
|
+
my.setPosition(event);
|
|
158
|
+
my.show()
|
|
159
|
+
//this.ensureTooltipInsideContainer();
|
|
160
|
+
};
|
|
161
|
+
|
|
162
|
+
my.mousemove = function (event) {
|
|
163
|
+
my.setPosition(event);
|
|
164
|
+
//this.ensureTooltipInsideContainer();
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
my.mouseout = function () {
|
|
168
|
+
my.hide();
|
|
169
|
+
};*/
|
|
170
|
+
|
|
171
|
+
style(k, v) {
|
|
172
|
+
if (arguments.length == 1) return this.tooltip.style(k)
|
|
173
|
+
this.tooltip.style(k, v)
|
|
174
|
+
return this
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
attr(k, v) {
|
|
178
|
+
if (arguments.length == 1) return this.tooltip.attr(k)
|
|
179
|
+
this.tooltip.attr(k, v)
|
|
180
|
+
return this
|
|
181
|
+
}
|
|
182
|
+
}
|
package/src/dataset/COGeo.js
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
import { Dataset } from '../core/Dataset.js'
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @todo
|
|
8
|
-
* A dataset composed of a COGeo file.
|
|
9
|
-
* @see https://www.cogeo.org/
|
|
10
|
-
*
|
|
11
|
-
* @module dataset
|
|
12
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
13
|
-
*/
|
|
14
|
-
export class COGeo extends Dataset {
|
|
15
|
-
/**
|
|
16
|
-
*
|
|
17
|
-
* @param {String} url
|
|
18
|
-
* @param {{preprocess?:(function(import("../core/Dataset").Cell):boolean)}} opts
|
|
19
|
-
*/
|
|
20
|
-
constructor(map, url, opts = {}) {
|
|
21
|
-
super(map, url, 0, opts)
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
//TODO Use https://geotiffjs.github.io/
|
|
25
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
import { Dataset } from '../core/Dataset.js'
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* @todo
|
|
8
|
+
* A dataset composed of a COGeo file.
|
|
9
|
+
* @see https://www.cogeo.org/
|
|
10
|
+
*
|
|
11
|
+
* @module dataset
|
|
12
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
13
|
+
*/
|
|
14
|
+
export class COGeo extends Dataset {
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
* @param {String} url
|
|
18
|
+
* @param {{preprocess?:(function(import("../core/Dataset").Cell):boolean)}} opts
|
|
19
|
+
*/
|
|
20
|
+
constructor(map, url, opts = {}) {
|
|
21
|
+
super(map, url, 0, opts)
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
//TODO Use https://geotiffjs.github.io/
|
|
25
|
+
}
|
package/src/dataset/CSVGrid.js
CHANGED
|
@@ -1,112 +1,112 @@
|
|
|
1
|
-
//@ts-check
|
|
2
|
-
'use strict'
|
|
3
|
-
|
|
4
|
-
/** @typedef {{ dims: object, crs: string, tileSizeCell: number, originPoint: {x:number,y:number}, resolutionGeo: number, tilingBounds:import("../core/GeoCanvas.js").Envelope }} GridInfo */
|
|
5
|
-
|
|
6
|
-
import { dsv } from 'd3-fetch'
|
|
7
|
-
import { Dataset } from '../core/Dataset.js'
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* A dataset composed of a single CSV file (not tiled).
|
|
11
|
-
*
|
|
12
|
-
* @module dataset
|
|
13
|
-
* @author Joseph Davies, Julien Gaffuri
|
|
14
|
-
*/
|
|
15
|
-
export class CSVGrid extends Dataset {
|
|
16
|
-
/**
|
|
17
|
-
* @param {import("../core/Map.js").Map} map The map.
|
|
18
|
-
* @param {string} url The URL of the dataset.
|
|
19
|
-
* @param {number} resolution The dataset resolution in geographical unit.
|
|
20
|
-
* @param {{preprocess?:(function(import("../core/Dataset.js").Cell):boolean),delimiter?:string}} opts
|
|
21
|
-
*/
|
|
22
|
-
constructor(map, url, resolution, opts = {}) {
|
|
23
|
-
super(map, url, resolution, opts)
|
|
24
|
-
|
|
25
|
-
/**
|
|
26
|
-
* @private
|
|
27
|
-
* @type {Array.<import("../core/Dataset.js").Cell>} */
|
|
28
|
-
this.cells = []
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* @private
|
|
32
|
-
* @type {string} */
|
|
33
|
-
this.delimiter = opts.delimiter || ','
|
|
34
|
-
|
|
35
|
-
/**
|
|
36
|
-
* @type {string}
|
|
37
|
-
* @private */
|
|
38
|
-
this.infoLoadingStatus = 'notLoaded'
|
|
39
|
-
|
|
40
|
-
//get data
|
|
41
|
-
this.getData(undefined)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Request data within a geographic envelope.
|
|
46
|
-
* @param {import("../core/GeoCanvas.js").Envelope|undefined} e
|
|
47
|
-
*/
|
|
48
|
-
getData(e) {
|
|
49
|
-
//check if data already loaded
|
|
50
|
-
if (this.infoLoadingStatus != 'notLoaded') return this
|
|
51
|
-
|
|
52
|
-
//load data
|
|
53
|
-
this.infoLoadingStatus = 'loading'
|
|
54
|
-
;(async () => {
|
|
55
|
-
try {
|
|
56
|
-
const data = await dsv(this.delimiter, this.url)
|
|
57
|
-
|
|
58
|
-
//convert coordinates in numbers
|
|
59
|
-
for (const c of data) {
|
|
60
|
-
c.x = +c.x
|
|
61
|
-
c.y = +c.y
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
//preprocess/filter
|
|
65
|
-
if (this.preprocess) {
|
|
66
|
-
this.cells = []
|
|
67
|
-
for (const c of data) {
|
|
68
|
-
const b = this.preprocess(c)
|
|
69
|
-
if (b == false) continue
|
|
70
|
-
this.cells.push(c)
|
|
71
|
-
}
|
|
72
|
-
} else {
|
|
73
|
-
this.cells = data
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
//TODO check if redraw is necessary
|
|
77
|
-
//that is if the dataset belongs to a layer which is visible at the current zoom level
|
|
78
|
-
|
|
79
|
-
//redraw map
|
|
80
|
-
if (this.map) this.map.redraw()
|
|
81
|
-
|
|
82
|
-
this.infoLoadingStatus = 'loaded'
|
|
83
|
-
} catch (error) {
|
|
84
|
-
//mark as failed
|
|
85
|
-
this.infoLoadingStatus = 'failed'
|
|
86
|
-
this.cells = []
|
|
87
|
-
}
|
|
88
|
-
})()
|
|
89
|
-
|
|
90
|
-
return this
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
/**
|
|
94
|
-
* Fill the view cache with all cells which are within a geographical envelope.
|
|
95
|
-
*
|
|
96
|
-
* @param {import("../core/GeoCanvas.js").Envelope} extGeo
|
|
97
|
-
* @returns {void}
|
|
98
|
-
*/
|
|
99
|
-
updateViewCache(extGeo) {
|
|
100
|
-
//data not loaded yet
|
|
101
|
-
if (!this.cells) return
|
|
102
|
-
|
|
103
|
-
this.cellsViewCache = []
|
|
104
|
-
for (const cell of this.cells) {
|
|
105
|
-
if (+cell.x + this.resolution < extGeo.xMin) continue
|
|
106
|
-
if (+cell.x - this.resolution > extGeo.xMax) continue
|
|
107
|
-
if (+cell.y + this.resolution < extGeo.yMin) continue
|
|
108
|
-
if (+cell.y - this.resolution > extGeo.yMax) continue
|
|
109
|
-
this.cellsViewCache.push(cell)
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
}
|
|
1
|
+
//@ts-check
|
|
2
|
+
'use strict'
|
|
3
|
+
|
|
4
|
+
/** @typedef {{ dims: object, crs: string, tileSizeCell: number, originPoint: {x:number,y:number}, resolutionGeo: number, tilingBounds:import("../core/GeoCanvas.js").Envelope }} GridInfo */
|
|
5
|
+
|
|
6
|
+
import { dsv } from 'd3-fetch'
|
|
7
|
+
import { Dataset } from '../core/Dataset.js'
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* A dataset composed of a single CSV file (not tiled).
|
|
11
|
+
*
|
|
12
|
+
* @module dataset
|
|
13
|
+
* @author Joseph Davies, Julien Gaffuri
|
|
14
|
+
*/
|
|
15
|
+
export class CSVGrid extends Dataset {
|
|
16
|
+
/**
|
|
17
|
+
* @param {import("../core/Map.js").Map} map The map.
|
|
18
|
+
* @param {string} url The URL of the dataset.
|
|
19
|
+
* @param {number} resolution The dataset resolution in geographical unit.
|
|
20
|
+
* @param {{preprocess?:(function(import("../core/Dataset.js").Cell):boolean),delimiter?:string}} opts
|
|
21
|
+
*/
|
|
22
|
+
constructor(map, url, resolution, opts = {}) {
|
|
23
|
+
super(map, url, resolution, opts)
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @private
|
|
27
|
+
* @type {Array.<import("../core/Dataset.js").Cell>} */
|
|
28
|
+
this.cells = []
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* @private
|
|
32
|
+
* @type {string} */
|
|
33
|
+
this.delimiter = opts.delimiter || ','
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* @type {string}
|
|
37
|
+
* @private */
|
|
38
|
+
this.infoLoadingStatus = 'notLoaded'
|
|
39
|
+
|
|
40
|
+
//get data
|
|
41
|
+
this.getData(undefined)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Request data within a geographic envelope.
|
|
46
|
+
* @param {import("../core/GeoCanvas.js").Envelope|undefined} e
|
|
47
|
+
*/
|
|
48
|
+
getData(e) {
|
|
49
|
+
//check if data already loaded
|
|
50
|
+
if (this.infoLoadingStatus != 'notLoaded') return this
|
|
51
|
+
|
|
52
|
+
//load data
|
|
53
|
+
this.infoLoadingStatus = 'loading'
|
|
54
|
+
;(async () => {
|
|
55
|
+
try {
|
|
56
|
+
const data = await dsv(this.delimiter, this.url)
|
|
57
|
+
|
|
58
|
+
//convert coordinates in numbers
|
|
59
|
+
for (const c of data) {
|
|
60
|
+
c.x = +c.x
|
|
61
|
+
c.y = +c.y
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
//preprocess/filter
|
|
65
|
+
if (this.preprocess) {
|
|
66
|
+
this.cells = []
|
|
67
|
+
for (const c of data) {
|
|
68
|
+
const b = this.preprocess(c)
|
|
69
|
+
if (b == false) continue
|
|
70
|
+
this.cells.push(c)
|
|
71
|
+
}
|
|
72
|
+
} else {
|
|
73
|
+
this.cells = data
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
//TODO check if redraw is necessary
|
|
77
|
+
//that is if the dataset belongs to a layer which is visible at the current zoom level
|
|
78
|
+
|
|
79
|
+
//redraw map
|
|
80
|
+
if (this.map) this.map.redraw()
|
|
81
|
+
|
|
82
|
+
this.infoLoadingStatus = 'loaded'
|
|
83
|
+
} catch (error) {
|
|
84
|
+
//mark as failed
|
|
85
|
+
this.infoLoadingStatus = 'failed'
|
|
86
|
+
this.cells = []
|
|
87
|
+
}
|
|
88
|
+
})()
|
|
89
|
+
|
|
90
|
+
return this
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
/**
|
|
94
|
+
* Fill the view cache with all cells which are within a geographical envelope.
|
|
95
|
+
*
|
|
96
|
+
* @param {import("../core/GeoCanvas.js").Envelope} extGeo
|
|
97
|
+
* @returns {void}
|
|
98
|
+
*/
|
|
99
|
+
updateViewCache(extGeo) {
|
|
100
|
+
//data not loaded yet
|
|
101
|
+
if (!this.cells) return
|
|
102
|
+
|
|
103
|
+
this.cellsViewCache = []
|
|
104
|
+
for (const cell of this.cells) {
|
|
105
|
+
if (+cell.x + this.resolution < extGeo.xMin) continue
|
|
106
|
+
if (+cell.x - this.resolution > extGeo.xMax) continue
|
|
107
|
+
if (+cell.y + this.resolution < extGeo.yMin) continue
|
|
108
|
+
if (+cell.y - this.resolution > extGeo.yMax) continue
|
|
109
|
+
this.cellsViewCache.push(cell)
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|