@longline/aqua-ui 1.0.225 → 1.0.227
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/controls/Gradient/PresetGradients.d.ts +4 -4
- package/controls/ListView/elements/Body.js +8 -18
- package/controls/ListView/elements/Table.js +17 -16
- package/map/layers/IdwBlendLayer/FragmentShader.d.ts +2 -0
- package/map/layers/IdwBlendLayer/FragmentShader.js +2 -0
- package/map/layers/IdwBlendLayer/IdwBlendLayer.d.ts +47 -0
- package/map/layers/IdwBlendLayer/IdwBlendLayer.js +129 -0
- package/map/layers/IdwBlendLayer/VertexShader.d.ts +2 -0
- package/map/layers/IdwBlendLayer/VertexShader.js +2 -0
- package/map/layers/IdwLayer/CopyFragmentShader.d.ts +2 -0
- package/map/layers/IdwLayer/CopyFragmentShader.js +2 -0
- package/map/layers/IdwLayer/CopyVertexShader.d.ts +2 -0
- package/map/layers/IdwLayer/CopyVertexShader.js +2 -0
- package/map/layers/IdwLayer/IdwFragmentShader.d.ts +2 -0
- package/map/layers/IdwLayer/IdwFragmentShader.js +2 -0
- package/map/layers/IdwLayer/IdwLayer.d.ts +69 -0
- package/map/layers/IdwLayer/IdwLayer.js +285 -0
- package/map/layers/IdwLayer/IdwVertexShader.d.ts +2 -0
- package/map/layers/IdwLayer/IdwVertexShader.js +2 -0
- package/package.json +1 -1
|
@@ -4,12 +4,12 @@ import { IGradientStop } from "../../Types";
|
|
|
4
4
|
*/
|
|
5
5
|
declare class PresetGradients {
|
|
6
6
|
/** Green gradient from light lime to dark teal */
|
|
7
|
-
static
|
|
7
|
+
static Green: IGradientStop[];
|
|
8
8
|
/** Blue gradient from pale cyan to deep navy */
|
|
9
|
-
static
|
|
9
|
+
static Blue: IGradientStop[];
|
|
10
10
|
/** Red gradient from dark maroon to bright red */
|
|
11
|
-
static
|
|
11
|
+
static Red: IGradientStop[];
|
|
12
12
|
/** Rainbow gradient from teal to yellow */
|
|
13
|
-
static
|
|
13
|
+
static Rainbow: IGradientStop[];
|
|
14
14
|
}
|
|
15
15
|
export { PresetGradients };
|
|
@@ -1,15 +1,14 @@
|
|
|
1
1
|
import * as React from 'react';
|
|
2
2
|
import { Selector } from '../../../inputs/Selector';
|
|
3
3
|
var Body = React.forwardRef(function (props, ref) {
|
|
4
|
-
var _a;
|
|
5
4
|
// The scrolling container's height is necessary to determine how many
|
|
6
5
|
// rows must be rendered.
|
|
7
|
-
var
|
|
6
|
+
var _a = React.useState(0), height = _a[0], setHeight = _a[1];
|
|
8
7
|
// Current container scrollTop. This is updated by polling it using
|
|
9
8
|
// animation frames.
|
|
10
9
|
var scrollTop = React.useRef(0);
|
|
11
10
|
// This state is only used to trigger renders
|
|
12
|
-
var
|
|
11
|
+
var _b = React.useState(0), setTick = _b[1];
|
|
13
12
|
// Watch resize of scrolling container using ResizeObserver.
|
|
14
13
|
React.useEffect(function () {
|
|
15
14
|
if (!props.container)
|
|
@@ -67,7 +66,6 @@ var Body = React.forwardRef(function (props, ref) {
|
|
|
67
66
|
var getRows = function () {
|
|
68
67
|
var rows = [];
|
|
69
68
|
var _a = getOffsets(), startIndex = _a[0], endIndex = _a[1];
|
|
70
|
-
var offset = startIndex * props.rowHeight;
|
|
71
69
|
var _loop_1 = function (i) {
|
|
72
70
|
var item = props.data[i];
|
|
73
71
|
rows.push(React.createElement("div", { key: i,
|
|
@@ -77,9 +75,7 @@ var Body = React.forwardRef(function (props, ref) {
|
|
|
77
75
|
props.active == item ? 'active' : null,
|
|
78
76
|
props.expanded && props.active == item ? 'expanded' : null,
|
|
79
77
|
(props.onClick || props.onDoubleClick) ? 'clickable' : null
|
|
80
|
-
].join(' '),
|
|
81
|
-
top: (props.expanded && props.active == item) ? "48px" : "".concat(offset, "px")
|
|
82
|
-
}, onClick: props.onClick ? function () { return props.onClick(item); } : null, onDoubleClick: props.onDoubleClick ? function () { return props.onDoubleClick(item); } : null },
|
|
78
|
+
].join(' '), onClick: props.onClick ? function () { return props.onClick(item); } : null, onDoubleClick: props.onDoubleClick ? function () { return props.onDoubleClick(item); } : null },
|
|
83
79
|
props.onCheck && React.createElement("div", { className: "cell check" },
|
|
84
80
|
React.createElement(Selector, { checked: !!item.checked, onChange: function () { return props.onCheck(i); } })),
|
|
85
81
|
props.columns.map(function (col, index) {
|
|
@@ -93,25 +89,19 @@ var Body = React.forwardRef(function (props, ref) {
|
|
|
93
89
|
}),
|
|
94
90
|
props.columnsEditable && React.createElement("div", { className: "cell columns" })));
|
|
95
91
|
if (props.expanded && props.active == item) {
|
|
96
|
-
rows.push(React.createElement("div", { key: "".concat(i, "_expand") },
|
|
97
|
-
React.createElement("div", { style: {
|
|
98
|
-
position: "absolute",
|
|
99
|
-
width: "100%",
|
|
100
|
-
top: "".concat(offset + props.rowHeight, "px"),
|
|
101
|
-
scrollMargin: "".concat(props.rowHeight * 2, "px")
|
|
102
|
-
} }, props.expansion)));
|
|
103
|
-
offset += props.rowHeight * 5;
|
|
92
|
+
rows.push(React.createElement("div", { key: "".concat(i, "_expand") }, props.expansion));
|
|
104
93
|
}
|
|
105
|
-
offset += props.rowHeight;
|
|
106
94
|
};
|
|
107
95
|
for (var i = startIndex; i <= endIndex; i++) {
|
|
108
96
|
_loop_1(i);
|
|
109
97
|
}
|
|
110
|
-
|
|
98
|
+
// Here we add an offset above the rows what were actually rendered:
|
|
99
|
+
var offset = startIndex * props.rowHeight;
|
|
100
|
+
return (React.createElement("div", { style: { position: "absolute", width: "100%", top: "".concat(offset, "px") } }, rows));
|
|
111
101
|
};
|
|
112
102
|
return (
|
|
113
103
|
// Wrap the body in an element that is as tall as the number of items
|
|
114
104
|
// in the list.
|
|
115
|
-
React.createElement("div", { style: { position: 'relative', width: '100%', height: ((
|
|
105
|
+
React.createElement("div", { style: { position: 'relative', width: '100%', height: (Array.isArray(props.data) ? props.data.length : 0) * props.rowHeight } }, Array.isArray(props.data) && getRows()));
|
|
116
106
|
});
|
|
117
107
|
export { Body };
|
|
@@ -60,7 +60,7 @@ var TableBase = function (_a) {
|
|
|
60
60
|
options: {
|
|
61
61
|
boundary: innerRef.current ? innerRef.current.getElement() : null,
|
|
62
62
|
tether: false,
|
|
63
|
-
padding: { top:
|
|
63
|
+
padding: { top: 0, bottom: 16 }
|
|
64
64
|
}
|
|
65
65
|
}
|
|
66
66
|
]
|
|
@@ -114,24 +114,25 @@ var TableBase = function (_a) {
|
|
|
114
114
|
React.createElement(ColumnsManager, { columns: props.columns, onChange: props.onChangeColumns, onClose: props.onCloseColumns, onReset: props.onResetColumns })),
|
|
115
115
|
showingNoData && React.createElement(NoData, { dark: props.dark, component: props.noData }),
|
|
116
116
|
React.createElement(AuxHolder, __assign({ ref: auxRef, style: __assign({ visibility: (props.active && props.aux && Array.isArray(props.data) && props.data.includes(props.active)) ? 'visible' : 'hidden' }, styles.popper) }, attributes.popper), (props.active && props.aux && Array.isArray(props.data) && props.data.includes(props.active)) && React.cloneElement(props.aux, { value: props.active })),
|
|
117
|
-
React.createElement(
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
React.createElement(
|
|
117
|
+
React.createElement("div", { className: className },
|
|
118
|
+
props.noheader != true && React.createElement(Header, __assign({}, props, { columns: activeColumns, onOpenColumns: props.onOpenColumns })),
|
|
119
|
+
React.createElement(OverlayScrollbarsComponent, { ref: innerRef, defer: true, options: {
|
|
120
|
+
scrollbars: { theme: 'os-theme-light', autoHide: 'leave' }
|
|
121
|
+
}, style: {
|
|
122
|
+
position: "absolute",
|
|
123
|
+
left: 0,
|
|
124
|
+
top: props.noheader ? 0 : "".concat(HEADER_HEIGHT, "px"),
|
|
125
|
+
right: 0,
|
|
126
|
+
bottom: 0,
|
|
127
|
+
overflowY: "auto",
|
|
128
|
+
} },
|
|
129
|
+
React.createElement("div", { className: "inner" },
|
|
130
|
+
React.createElement(Body, __assign({ ref: setActiveRef }, props, { columns: activeColumns, container: innerRef.current }))))),
|
|
130
131
|
props.total && Array.isArray(props.data) && React.createElement(Total, { value: props.data.length, singular: props.singular, plural: props.plural })));
|
|
131
132
|
};
|
|
132
133
|
var AuxHolder = styled.div(templateObject_1 || (templateObject_1 = __makeTemplateObject(["\n z-index: 1;\n pointer-events: none;\n // Children must turn pointer-events back on.\n"], ["\n z-index: 1;\n pointer-events: none;\n // Children must turn pointer-events back on.\n"])));
|
|
133
134
|
var Wrapper = styled.div(templateObject_2 || (templateObject_2 = __makeTemplateObject(["\n // Size and position. A table fills its container.\n position: relative;\n width: 100%;\n height: 100%;\n background-color: ", ";\n"], ["\n // Size and position. A table fills its container.\n position: relative;\n width: 100%;\n height: 100%;\n background-color: ", ";\n"])), function (p) { return p.$dark ? p.theme.colors.primary[3] : p.theme.colors.neutral[100]; });
|
|
134
|
-
var TableStyled = styled(TableBase)(templateObject_10 || (templateObject_10 = __makeTemplateObject(["\n position: absolute;\n
|
|
135
|
+
var TableStyled = styled(TableBase)(templateObject_10 || (templateObject_10 = __makeTemplateObject(["\n .inner {\n position: absolute;\n box-sizing: border-box;\n left: 0;\n top: 0;\n width: 100%;\n padding-bottom: 48px;\n }\n\n // Appearance:\n font: ", ";\n color: ", ";\n background-color: ", ";\n\n .row {\n width: 100%;\n height: ", "px;\n display: flex;\n flex-direction: row;\n }\n .row.clickable {\n cursor: pointer;\n }\n\n // Optional row hover effect:\n ", "\n\n // Striped rows:\n ", "\n\n // General styles for cells:\n .cell {\n position: relative;\n box-sizing: border-box;\n white-space: nowrap;\n text-align: left;\n user-select: none;\n outline: none;\n padding-left: 16px;\n padding-right: 16px; \n min-width: 0; \n\n // use flexbox to vertical-align content:\n display: flex;\n align-items: center;\n justify-content: left;\n\n // Underline.\n &:after {\n content: '';\n position: absolute;\n left: 0;\n bottom: 0;\n right: 0;\n height: 1px;\n transition: background-color ", "ms ease-in-out;\n } \n }\n\n // Cell widths:\n ", "\n\n .cell.check {\n width: 48px;\n }\n\n .cell.columns {\n width: 48px;\n }\n\n .header {\n // Position and size:\n position: absolute;\n top: 0;\n z-index: 200;\n height: ", "px;\n }\n\n .header .cell {\n gap: 8px;\n justify-content: space-between;\n // Appearance\n background: ", ";\n &.sort {\n background: ", ";\n }\n &:after { \n background-color: ", "; \n }\n // Header shadow:\n ", "\n }\n // cell bottom border color:\n .cell {\n &:after {\n background-color: ", ";\n } \n }\n // Active row cells:\n .row.active .cell {\n background-color: ", ";\n }\n // Last column has double right margin:\n .cell:last-child {\n padding-right: 32px;\n }\n // Last row has no bottom border:\n .row:last-child .cell {\n &:after {\n visibility: hidden;\n } \n }\n // Spans in cells are ellipsized:\n .cell > span {\n width: 100%;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n }\n\n // Grid:\n ", "\n\n // If onColumns is present, remove last column header's hover underline:\n // Also remove last gridline.\n ", "\n\n // Expanded row makes its cells sticky:\n .row.expanded {\n position: sticky;\n top: 0;\n z-index: 100;\n }\n"], ["\n .inner {\n position: absolute;\n box-sizing: border-box;\n left: 0;\n top: 0;\n width: 100%;\n padding-bottom: 48px;\n }\n\n // Appearance:\n font: ", ";\n color: ", ";\n background-color: ", ";\n\n .row {\n width: 100%;\n height: ", "px;\n display: flex;\n flex-direction: row;\n }\n .row.clickable {\n cursor: pointer;\n }\n\n // Optional row hover effect:\n ", "\n\n // Striped rows:\n ", "\n\n // General styles for cells:\n .cell {\n position: relative;\n box-sizing: border-box;\n white-space: nowrap;\n text-align: left;\n user-select: none;\n outline: none;\n padding-left: 16px;\n padding-right: 16px; \n min-width: 0; \n\n // use flexbox to vertical-align content:\n display: flex;\n align-items: center;\n justify-content: left;\n\n // Underline.\n &:after {\n content: '';\n position: absolute;\n left: 0;\n bottom: 0;\n right: 0;\n height: 1px;\n transition: background-color ", "ms ease-in-out;\n } \n }\n\n // Cell widths:\n ", "\n\n .cell.check {\n width: 48px;\n }\n\n .cell.columns {\n width: 48px;\n }\n\n .header {\n // Position and size:\n position: absolute;\n top: 0;\n z-index: 200;\n height: ", "px;\n }\n\n .header .cell {\n gap: 8px;\n justify-content: space-between;\n // Appearance\n background: ", ";\n &.sort {\n background: ", ";\n }\n &:after { \n background-color: ", "; \n }\n // Header shadow:\n ", "\n }\n // cell bottom border color:\n .cell {\n &:after {\n background-color: ", ";\n } \n }\n // Active row cells:\n .row.active .cell {\n background-color: ", ";\n }\n // Last column has double right margin:\n .cell:last-child {\n padding-right: 32px;\n }\n // Last row has no bottom border:\n .row:last-child .cell {\n &:after {\n visibility: hidden;\n } \n }\n // Spans in cells are ellipsized:\n .cell > span {\n width: 100%;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n }\n\n // Grid:\n ", "\n\n // If onColumns is present, remove last column header's hover underline:\n // Also remove last gridline.\n ", "\n\n // Expanded row makes its cells sticky:\n .row.expanded {\n position: sticky;\n top: 0;\n z-index: 100;\n }\n"])), function (p) { return p.theme.font.bodyMedium; }, function (p) { return p.dark ? p.theme.colors.neutral[100] : p.theme.colors.neutral[10]; }, function (p) { return p.dark ? p.theme.colors.primary[3] : p.theme.colors.neutral[100]; }, function (p) { return p.rowHeight; }, function (p) { return p.hover && css(templateObject_3 || (templateObject_3 = __makeTemplateObject(["\n .row:hover .cell { background-color: ", "; }\n "], ["\n .row:hover .cell { background-color: ", "; }\n "])), p.dark ? p.theme.colors.primary[4] : p.theme.colors.neutral[95]); }, function (p) { return p.striped && css(templateObject_4 || (templateObject_4 = __makeTemplateObject(["\n .row:nth-child(2n+2) .cell {\n background-color: ", ";\n }\n "], ["\n .row:nth-child(2n+2) .cell {\n background-color: ", ";\n }\n "])), darken(0.02, p.dark ? p.theme.colors.primary[3] : p.theme.colors.neutral[100])); }, function (p) { return p.theme.animation.duration; }, function (p) { return p.columns.filter(function (c) { return c.active; }).map(function (c, i) {
|
|
135
136
|
var _a;
|
|
136
137
|
var width_definition = (_a = c.width) !== null && _a !== void 0 ? _a : 1;
|
|
137
138
|
var cellIndex = p.onCheck ? i + 2 : i + 1;
|
|
@@ -141,7 +142,7 @@ var TableStyled = styled(TableBase)(templateObject_10 || (templateObject_10 = __
|
|
|
141
142
|
else {
|
|
142
143
|
return css(templateObject_6 || (templateObject_6 = __makeTemplateObject(["\n .cell:nth-child(", ") {\n width: ", ";\n }\n "], ["\n .cell:nth-child(", ") {\n width: ", ";\n }\n "])), cellIndex, width_definition);
|
|
143
144
|
}
|
|
144
|
-
}); }, HEADER_HEIGHT, function (p) { return p.dark ? p.theme.colors.primary[5] : p.theme.colors.neutral[100]; }, function (p) { return p.dark ? p.theme.colors.neutral[10] : p.theme.colors.neutral[95]; }, function (p) { return p.dark ? p.theme.colors.primary[2] : p.theme.colors.neutral[80]; }, function (p) { return p.shadow && css(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n &:before {\n position: absolute;\n pointer-events: none;\n content: '';\n z-index: 1;\n top: calc(100%);\n left: 0;\n right: 0;\n height: 8px;\n background: linear-gradient(rgba(0,0,0,0.1), transparent);\n }\n "], ["\n &:before {\n position: absolute;\n pointer-events: none;\n content: '';\n z-index: 1;\n top: calc(100%);\n left: 0;\n right: 0;\n height: 8px;\n background: linear-gradient(rgba(0,0,0,0.1), transparent);\n }\n "]))); }, function (p) { return p.dark ? p.theme.colors.primary[2] : p.theme.colors.neutral[80]; }, function (p) { var _a; return (_a = p.activeColor) !== null && _a !== void 0 ? _a : p.theme.colors.primary[1]; }, function (p) { return p.grid && css(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n .cell:not(:last-child) {\n border-right: dashed 1px ", ";\n }\n "], ["\n .cell:not(:last-child) {\n border-right: dashed 1px ", ";\n }\n "])), p.dark ? p.theme.colors.primary[2] : p.theme.colors.neutral[80]); }, function (p) { return p.columnsEditable && css(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n .header .cell:last-child {\n &:hover {\n &:after { \n background-color: ", ";\n }\n }\n }\n .cell:nth-last-child(2) {\n border-right: none;\n }\n "], ["\n .header .cell:last-child {\n &:hover {\n &:after { \n background-color: ", ";\n }\n }\n }\n .cell:nth-last-child(2) {\n border-right: none;\n }\n "])), function (p) { return p.theme.colors.primary[2]; }); }
|
|
145
|
+
}); }, HEADER_HEIGHT, function (p) { return p.dark ? p.theme.colors.primary[5] : p.theme.colors.neutral[100]; }, function (p) { return p.dark ? p.theme.colors.neutral[10] : p.theme.colors.neutral[95]; }, function (p) { return p.dark ? p.theme.colors.primary[2] : p.theme.colors.neutral[80]; }, function (p) { return p.shadow && css(templateObject_7 || (templateObject_7 = __makeTemplateObject(["\n &:before {\n position: absolute;\n pointer-events: none;\n content: '';\n z-index: 1;\n top: calc(100%);\n left: 0;\n right: 0;\n height: 8px;\n background: linear-gradient(rgba(0,0,0,0.1), transparent);\n }\n "], ["\n &:before {\n position: absolute;\n pointer-events: none;\n content: '';\n z-index: 1;\n top: calc(100%);\n left: 0;\n right: 0;\n height: 8px;\n background: linear-gradient(rgba(0,0,0,0.1), transparent);\n }\n "]))); }, function (p) { return p.dark ? p.theme.colors.primary[2] : p.theme.colors.neutral[80]; }, function (p) { var _a; return (_a = p.activeColor) !== null && _a !== void 0 ? _a : p.theme.colors.primary[1]; }, function (p) { return p.grid && css(templateObject_8 || (templateObject_8 = __makeTemplateObject(["\n .cell:not(:last-child) {\n border-right: dashed 1px ", ";\n }\n "], ["\n .cell:not(:last-child) {\n border-right: dashed 1px ", ";\n }\n "])), p.dark ? p.theme.colors.primary[2] : p.theme.colors.neutral[80]); }, function (p) { return p.columnsEditable && css(templateObject_9 || (templateObject_9 = __makeTemplateObject(["\n .header .cell:last-child {\n &:hover {\n &:after { \n background-color: ", ";\n }\n }\n }\n .cell:nth-last-child(2) {\n border-right: none;\n }\n "], ["\n .header .cell:last-child {\n &:hover {\n &:after { \n background-color: ", ";\n }\n }\n }\n .cell:nth-last-child(2) {\n border-right: none;\n }\n "])), function (p) { return p.theme.colors.primary[2]; }); });
|
|
145
146
|
var Table = function (props) { return React.createElement(TableStyled, __assign({}, props)); };
|
|
146
147
|
Table.displayName = "Table";
|
|
147
148
|
export { Table };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const FragmentShader = " \n #ifdef GL_ES\n precision mediump float;\n #endif\n\n // Varyings from vertex shader\n varying vec2 v_pos; // station center in Mercator [0..1]\n varying float v_radius; // quad radius in Mercator units\n\n void main() {\n // Simply color every fragment of the quad red\n gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n }\n";
|
|
2
|
+
export { FragmentShader };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var FragmentShader = /*glsl*/ " \n #ifdef GL_ES\n precision mediump float;\n #endif\n\n // Varyings from vertex shader\n varying vec2 v_pos; // station center in Mercator [0..1]\n varying float v_radius; // quad radius in Mercator units\n\n void main() {\n // Simply color every fragment of the quad red\n gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n }\n";
|
|
2
|
+
export { FragmentShader };
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { IGradientStop } from '../../../Types';
|
|
3
|
+
interface IPoint {
|
|
4
|
+
latitude: number;
|
|
5
|
+
longitude: number;
|
|
6
|
+
value: number;
|
|
7
|
+
}
|
|
8
|
+
interface IIdwBlendLayerProps {
|
|
9
|
+
/**
|
|
10
|
+
* Input data.
|
|
11
|
+
*/
|
|
12
|
+
data: IPoint[];
|
|
13
|
+
/**
|
|
14
|
+
* Gradient stops. A default gradient is preset.
|
|
15
|
+
*/
|
|
16
|
+
gradientStops?: IGradientStop[];
|
|
17
|
+
/**
|
|
18
|
+
* Minimum zoom level at which to render layer.
|
|
19
|
+
* @default 0
|
|
20
|
+
*/
|
|
21
|
+
minZoom?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Maximum zoom level at which to render layer.
|
|
24
|
+
* @default 99
|
|
25
|
+
*/
|
|
26
|
+
maxZoom?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Maximum world distance (in -1..1 coordinate) system away from
|
|
29
|
+
* all stations where a pixel is still drawn.
|
|
30
|
+
* @default 0.0002
|
|
31
|
+
*/
|
|
32
|
+
maxDistance?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Thickness of fading edge of blob (value 0..1)
|
|
35
|
+
* @default 0.15
|
|
36
|
+
*/
|
|
37
|
+
fadeFraction?: number;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* An `IdwLayer` takes a data array of the form `{ latitude, longitude, value }`,
|
|
41
|
+
* and renders a colored surface using inverse distance weighting.
|
|
42
|
+
*/
|
|
43
|
+
declare const IdwBlendLayer: {
|
|
44
|
+
({ gradientStops, minZoom, maxZoom, maxDistance, fadeFraction, ...props }: IIdwBlendLayerProps): React.JSX.Element;
|
|
45
|
+
displayName: string;
|
|
46
|
+
};
|
|
47
|
+
export { IdwBlendLayer };
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
13
|
+
var t = {};
|
|
14
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
15
|
+
t[p] = s[p];
|
|
16
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
17
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
18
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
19
|
+
t[p[i]] = s[p[i]];
|
|
20
|
+
}
|
|
21
|
+
return t;
|
|
22
|
+
};
|
|
23
|
+
import * as React from 'react';
|
|
24
|
+
import { Layer, useMap } from 'react-map-gl/mapbox';
|
|
25
|
+
import { MercatorCoordinate } from 'mapbox-gl';
|
|
26
|
+
import { VertexShader } from './VertexShader';
|
|
27
|
+
import { FragmentShader } from './FragmentShader';
|
|
28
|
+
import { RgbColor } from '../../../helper/RgbColor';
|
|
29
|
+
import { PresetGradients } from '../../../controls/Gradient';
|
|
30
|
+
var IdwBlendLayerBase = function (props) {
|
|
31
|
+
var map = useMap();
|
|
32
|
+
var discProgram = React.useRef(null);
|
|
33
|
+
var discBuffer = React.useRef(null);
|
|
34
|
+
var texture = React.useRef(null);
|
|
35
|
+
var textureWidth = React.useRef(null);
|
|
36
|
+
var textureHeight = React.useRef(null);
|
|
37
|
+
var _a = React.useState(0), time = _a[0], setTime = _a[1];
|
|
38
|
+
// When properties change, make sure that layer is redrawn.
|
|
39
|
+
// Do this by varying its `key` with the current time.
|
|
40
|
+
React.useEffect(function () {
|
|
41
|
+
setTime(Date.now());
|
|
42
|
+
}, [props.data, props.gradientStops]);
|
|
43
|
+
//
|
|
44
|
+
// Convert a hex color (e.g. #ff0022) to an [r,g,b,a] array,
|
|
45
|
+
// where r,g,b,a are in the 0.0-1.0 range.
|
|
46
|
+
//
|
|
47
|
+
var colorToRGBA = function (color) {
|
|
48
|
+
var rgb = RgbColor.FromString(color);
|
|
49
|
+
return [rgb.red / 255.0, rgb.green / 255.0, rgb.blue / 255.0, rgb.alpha];
|
|
50
|
+
};
|
|
51
|
+
var createPointsBuffer = function (gl, points) {
|
|
52
|
+
var offsets = [
|
|
53
|
+
[-1, -1],
|
|
54
|
+
[1, -1],
|
|
55
|
+
[-1, 1],
|
|
56
|
+
[1, 1],
|
|
57
|
+
];
|
|
58
|
+
// Flatten into Float32Array
|
|
59
|
+
var vertexData = [];
|
|
60
|
+
points.forEach(function (p) {
|
|
61
|
+
var _a = MercatorCoordinate.fromLngLat([p.longitude, p.latitude]), x = _a.x, y = _a.y;
|
|
62
|
+
offsets.forEach(function (_a) {
|
|
63
|
+
var ox = _a[0], oy = _a[1];
|
|
64
|
+
vertexData.push(x, y, p.value, ox, oy);
|
|
65
|
+
});
|
|
66
|
+
});
|
|
67
|
+
// Create buffer
|
|
68
|
+
var buffer = gl.createBuffer();
|
|
69
|
+
if (!buffer)
|
|
70
|
+
throw new Error("Failed to create WebGL buffer");
|
|
71
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
|
|
72
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertexData), gl.STATIC_DRAW);
|
|
73
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, null);
|
|
74
|
+
return buffer;
|
|
75
|
+
};
|
|
76
|
+
var onAddLayer = function (map, gl) {
|
|
77
|
+
// AddLayer is only called once.
|
|
78
|
+
// create a vertex shader
|
|
79
|
+
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
|
80
|
+
gl.shaderSource(vertexShader, VertexShader);
|
|
81
|
+
gl.compileShader(vertexShader);
|
|
82
|
+
// create a fragment shader
|
|
83
|
+
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
84
|
+
gl.shaderSource(fragmentShader, FragmentShader);
|
|
85
|
+
gl.compileShader(fragmentShader);
|
|
86
|
+
// link the two shaders into a WebGL program
|
|
87
|
+
discProgram.current = gl.createProgram();
|
|
88
|
+
gl.attachShader(discProgram.current, vertexShader);
|
|
89
|
+
gl.attachShader(discProgram.current, fragmentShader);
|
|
90
|
+
gl.linkProgram(discProgram.current);
|
|
91
|
+
// Create buffer from vertices:
|
|
92
|
+
discBuffer.current = createPointsBuffer(gl, props.data);
|
|
93
|
+
};
|
|
94
|
+
var onRender = function (gl, matrix, zoom, width, height) {
|
|
95
|
+
// Render is called many times while the map is panned/zoomed.
|
|
96
|
+
// You cannot have access to the map though.
|
|
97
|
+
if (zoom < props.minZoom)
|
|
98
|
+
return;
|
|
99
|
+
if (zoom > props.maxZoom)
|
|
100
|
+
return;
|
|
101
|
+
// Render is called many times while the map is panned/zoomed.
|
|
102
|
+
// You cannot have access to the map though.
|
|
103
|
+
gl.useProgram(discProgram.current);
|
|
104
|
+
// Pass a matrix uniform in:
|
|
105
|
+
gl.uniformMatrix4fv(gl.getUniformLocation(discProgram.current, 'u_matrix'), false, matrix);
|
|
106
|
+
gl.uniform1f(gl.getUniformLocation(discProgram.current, "u_radius"), 0.0001);
|
|
107
|
+
var aPos = gl.getAttribLocation(discProgram.current, 'a_pos');
|
|
108
|
+
var aOffset = gl.getAttribLocation(discProgram.current, 'a_offset');
|
|
109
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, discBuffer.current);
|
|
110
|
+
gl.enableVertexAttribArray(aPos);
|
|
111
|
+
gl.vertexAttribPointer(aPos, 3, gl.FLOAT, false, 5 * 4, 0);
|
|
112
|
+
gl.enableVertexAttribArray(aOffset);
|
|
113
|
+
gl.vertexAttribPointer(aOffset, 2, gl.FLOAT, false, 5 * 4, 3 * 4);
|
|
114
|
+
//gl.enable(gl.BLEND);
|
|
115
|
+
//gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
116
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, props.data.length * 4);
|
|
117
|
+
};
|
|
118
|
+
return (React.createElement(Layer, { id: null, type: "custom", beforeId: "overlay", key: time, onAdd: onAddLayer, render: function (gl, matrix) { return onRender(gl, matrix, map.current.getZoom(), map.current.getContainer().clientWidth, map.current.getContainer().clientHeight); } }));
|
|
119
|
+
};
|
|
120
|
+
/**
|
|
121
|
+
* An `IdwLayer` takes a data array of the form `{ latitude, longitude, value }`,
|
|
122
|
+
* and renders a colored surface using inverse distance weighting.
|
|
123
|
+
*/
|
|
124
|
+
var IdwBlendLayer = function (_a) {
|
|
125
|
+
var _b = _a.gradientStops, gradientStops = _b === void 0 ? PresetGradients.Blue : _b, _c = _a.minZoom, minZoom = _c === void 0 ? 0 : _c, _d = _a.maxZoom, maxZoom = _d === void 0 ? 99 : _d, _e = _a.maxDistance, maxDistance = _e === void 0 ? 0.0002 : _e, _f = _a.fadeFraction, fadeFraction = _f === void 0 ? 0.15 : _f, props = __rest(_a, ["gradientStops", "minZoom", "maxZoom", "maxDistance", "fadeFraction"]);
|
|
126
|
+
return React.createElement(IdwBlendLayerBase, __assign({ gradientStops: gradientStops, minZoom: minZoom, maxZoom: maxZoom, maxDistance: maxDistance, fadeFraction: fadeFraction }, props));
|
|
127
|
+
};
|
|
128
|
+
IdwBlendLayer.displayName = 'IdwBlendLayer';
|
|
129
|
+
export { IdwBlendLayer };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const VertexShader = " \n// Attributes\nattribute vec2 a_offset; // quad corner: [-1,-1], [1,-1], [-1,1], [1,1]\nattribute vec2 a_pos; // point position in Mercator [0..1]\n\n// Uniforms\nuniform mat4 u_matrix; // Mapbox projection matrix\nuniform float u_radius; // radius in Mercator units (e.g., 1 km converted)\n \n// Varyings\nvarying vec2 v_pos; // pass to fragment shader\nvarying float v_radius;\n\nvoid main() {\n // Offset the quad corner by radius in world coordinates\n vec2 offset = a_offset * u_radius;\n vec2 pos = a_pos + offset;\n\n // Pass station position & radius to fragment shader\n v_pos = a_pos;\n v_radius = u_radius;\n\n // Transform to clip space\n gl_Position = u_matrix * vec4(pos, 0.0, 1.0);\n}\n";
|
|
2
|
+
export { VertexShader };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var VertexShader = /*glsl*/ " \n// Attributes\nattribute vec2 a_offset; // quad corner: [-1,-1], [1,-1], [-1,1], [1,1]\nattribute vec2 a_pos; // point position in Mercator [0..1]\n\n// Uniforms\nuniform mat4 u_matrix; // Mapbox projection matrix\nuniform float u_radius; // radius in Mercator units (e.g., 1 km converted)\n \n// Varyings\nvarying vec2 v_pos; // pass to fragment shader\nvarying float v_radius;\n\nvoid main() {\n // Offset the quad corner by radius in world coordinates\n vec2 offset = a_offset * u_radius;\n vec2 pos = a_pos + offset;\n\n // Pass station position & radius to fragment shader\n v_pos = a_pos;\n v_radius = u_radius;\n\n // Transform to clip space\n gl_Position = u_matrix * vec4(pos, 0.0, 1.0);\n}\n";
|
|
2
|
+
export { VertexShader };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
declare const IdwFragmentShader = " \n #ifdef GL_ES\n precision mediump float;\n #endif\n\n uniform sampler2D u_dataTexture;\n uniform vec2 u_dataTextureSize;\n uniform int u_numStations;\n varying vec2 v_pos;\n uniform float u_gradientStops[12];\n uniform vec4 u_gradientColors[12];\n uniform float u_maxDistance;\n uniform float u_fadeFraction;\n\n //\n // Given a value, find its corresponding color in the gradient stops.\n //\n vec4 getGradientColor(float position) {\n // Find left and right stop:\n float left = -1.0;\n float right = 99.0;\n vec4 leftColor;\n vec4 rightColor;\n\n for(int i = 0; i < 12; i++) {\n if (u_gradientStops[i] <= position) {\n left = u_gradientStops[i]; \n leftColor = u_gradientColors[i];\n } else break;\n }\n\n for(int i = 12 - 1; i >= 0; i--) {\n if (u_gradientStops[i] >= position) {\n right = u_gradientStops[i]; \n rightColor = u_gradientColors[i];\n } else break;\n }\n\n // Distance between stops:\n float width = right - left;\n // Distance from left stop:\n float dist = position - left;\n // Right stop weight:\n float weight;\n if(dist == 0.0) {\n weight = dist;\n } else {\n weight = dist / width;\n }\n\n float r = leftColor.x + (rightColor.x - leftColor.x) * weight;\n float g = leftColor.y + (rightColor.y - leftColor.y) * weight;\n float b = leftColor.z + (rightColor.z - leftColor.z) * weight;\n float a = leftColor.w + (rightColor.w - leftColor.w) * weight;\n return vec4(r, g, b, a); \n } \n\n // GLSL ES 1.00 compatible\n // rgba: vec4 from texture2D (values in [0..1])\n float decodeFloatRGBA(vec4 rgba) {\n // convert to 0..255 and round\n vec4 b = floor(rgba * 255.0 + 0.5);\n\n float b0 = b.r;\n float b1 = b.g;\n float b2 = b.b;\n float b3 = b.a;\n\n // sign: top bit of b3\n float sign = (b3 >= 128.0) ? -1.0 : 1.0;\n\n // exponent: 8 bits where lowest bit comes from b2's top bit\n float exp_low = floor(b2 / 128.0); // 0 or 1\n float exp_high = mod(b3, 128.0); // bits 1..7 of exponent as 0..127\n float exponent = exp_high * 2.0 + exp_low; // full 0..255\n\n // mantissa: 23 bits from b0,b1 and lower 7 bits of b2\n float mantissa = b0 + b1 * 256.0 + mod(b2, 128.0) * 65536.0;\n\n // handle special cases\n if (exponent == 0.0) {\n // zero or subnormal\n if (mantissa == 0.0) {\n return 0.0;\n } else {\n // subnormal numbers: (-1)^s * (mantissa / 2^23) * 2^-126\n return sign * (mantissa / 8388608.0) * exp2(-126.0);\n }\n } else if (exponent == 255.0) {\n // Inf or NaN -- return a large value for Inf, and 0 for NaN\n if (mantissa == 0.0) {\n return sign * 3.402823466e38; // approx FLT_MAX\n } else {\n return 0.0; // NaN -> 0 (or handle as you prefer)\n }\n } else {\n // normalized number: (-1)^s * (1 + mantissa/2^23) * 2^(exponent-127)\n float m = 1.0 + mantissa / 8388608.0;\n return sign * m * exp2(exponent - 127.0);\n }\n } \n\n vec2 texCoordForIndex(float idx, vec2 texSize) {\n float x = mod(idx, texSize.x);\n float y = floor(idx / texSize.x);\n return (vec2(x + 0.5, y + 0.5) / texSize);\n }\n\n // read triple of pixels: idx*3 + 0,1,2\n vec3 getPoint(int index) {\n float base = float(index) * 3.0;\n vec4 c0 = texture2D(u_dataTexture, texCoordForIndex(base + 0.0, u_dataTextureSize)); // x (mercator)\n vec4 c1 = texture2D(u_dataTexture, texCoordForIndex(base + 1.0, u_dataTextureSize)); // y (mercator)\n vec4 c2 = texture2D(u_dataTexture, texCoordForIndex(base + 2.0, u_dataTextureSize)); // value\n float mx = decodeFloatRGBA(c0);\n float my = decodeFloatRGBA(c1);\n float val = decodeFloatRGBA(c2);\n return vec3(mx, my, val);\n }\n\n void main() {\n float num = 0.0;\n float denom = 0.0;\n float power = 3.0; // IDW power\n float minDist = 1e9;\n\n for (int i = 0; i < 1024; i++) { // 1024 is a safe upper bound\n if (i >= u_numStations) break;\n vec3 station = getPoint(i);\n float dx = v_pos.x - station.x;\n float dy = v_pos.y - station.y;\n float d = sqrt(dx*dx + dy*dy);\n minDist = min(minDist, d);\n\n if (d < 1e-6) {\n // Exact match: use station value directly\n num = station.z;\n denom = 1.0;\n // stop looping, we\u2019re done\n break;\n }\n\n float w = 1.0 / pow(d, power);\n num += w * station.z;\n denom += w;\n }\n\n if (minDist > u_maxDistance) {\n // Too far from any station \u2192 discard pixel (transparent)\n discard;\n } \n\n float value = num / denom;\n\n // Normalize value between 0 and 1\n //float minVal = 0.0; // pass as uniform if needed\n //float maxVal = 1.0;\n //float norm = clamp((value - minVal) / (maxVal - minVal), 0.0, 1.0);\n\n // --- FADE TO TRANSPARENT ---\n float u_fadeDistance = u_maxDistance * u_fadeFraction;\n float alpha = 1.0;\n if (minDist > u_maxDistance - u_fadeDistance) {\n // fade linearly from 1 \u2192 0\n alpha = (u_maxDistance - minDist) / u_fadeDistance;\n alpha = clamp(alpha, 0.0, 1.0);\n }\n\n gl_FragColor = vec4(vec3(getGradientColor(1.0 - value)), alpha);\n }\n\n";
|
|
2
|
+
export { IdwFragmentShader };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
var IdwFragmentShader = /*glsl*/ " \n #ifdef GL_ES\n precision mediump float;\n #endif\n\n uniform sampler2D u_dataTexture;\n uniform vec2 u_dataTextureSize;\n uniform int u_numStations;\n varying vec2 v_pos;\n uniform float u_gradientStops[12];\n uniform vec4 u_gradientColors[12];\n uniform float u_maxDistance;\n uniform float u_fadeFraction;\n\n //\n // Given a value, find its corresponding color in the gradient stops.\n //\n vec4 getGradientColor(float position) {\n // Find left and right stop:\n float left = -1.0;\n float right = 99.0;\n vec4 leftColor;\n vec4 rightColor;\n\n for(int i = 0; i < 12; i++) {\n if (u_gradientStops[i] <= position) {\n left = u_gradientStops[i]; \n leftColor = u_gradientColors[i];\n } else break;\n }\n\n for(int i = 12 - 1; i >= 0; i--) {\n if (u_gradientStops[i] >= position) {\n right = u_gradientStops[i]; \n rightColor = u_gradientColors[i];\n } else break;\n }\n\n // Distance between stops:\n float width = right - left;\n // Distance from left stop:\n float dist = position - left;\n // Right stop weight:\n float weight;\n if(dist == 0.0) {\n weight = dist;\n } else {\n weight = dist / width;\n }\n\n float r = leftColor.x + (rightColor.x - leftColor.x) * weight;\n float g = leftColor.y + (rightColor.y - leftColor.y) * weight;\n float b = leftColor.z + (rightColor.z - leftColor.z) * weight;\n float a = leftColor.w + (rightColor.w - leftColor.w) * weight;\n return vec4(r, g, b, a); \n } \n\n // GLSL ES 1.00 compatible\n // rgba: vec4 from texture2D (values in [0..1])\n float decodeFloatRGBA(vec4 rgba) {\n // convert to 0..255 and round\n vec4 b = floor(rgba * 255.0 + 0.5);\n\n float b0 = b.r;\n float b1 = b.g;\n float b2 = b.b;\n float b3 = b.a;\n\n // sign: top bit of b3\n float sign = (b3 >= 128.0) ? -1.0 : 1.0;\n\n // exponent: 8 bits where lowest bit comes from b2's top bit\n float exp_low = floor(b2 / 128.0); // 0 or 1\n float exp_high = mod(b3, 128.0); // bits 1..7 of exponent as 0..127\n float exponent = exp_high * 2.0 + exp_low; // full 0..255\n\n // mantissa: 23 bits from b0,b1 and lower 7 bits of b2\n float mantissa = b0 + b1 * 256.0 + mod(b2, 128.0) * 65536.0;\n\n // handle special cases\n if (exponent == 0.0) {\n // zero or subnormal\n if (mantissa == 0.0) {\n return 0.0;\n } else {\n // subnormal numbers: (-1)^s * (mantissa / 2^23) * 2^-126\n return sign * (mantissa / 8388608.0) * exp2(-126.0);\n }\n } else if (exponent == 255.0) {\n // Inf or NaN -- return a large value for Inf, and 0 for NaN\n if (mantissa == 0.0) {\n return sign * 3.402823466e38; // approx FLT_MAX\n } else {\n return 0.0; // NaN -> 0 (or handle as you prefer)\n }\n } else {\n // normalized number: (-1)^s * (1 + mantissa/2^23) * 2^(exponent-127)\n float m = 1.0 + mantissa / 8388608.0;\n return sign * m * exp2(exponent - 127.0);\n }\n } \n\n vec2 texCoordForIndex(float idx, vec2 texSize) {\n float x = mod(idx, texSize.x);\n float y = floor(idx / texSize.x);\n return (vec2(x + 0.5, y + 0.5) / texSize);\n }\n\n // read triple of pixels: idx*3 + 0,1,2\n vec3 getPoint(int index) {\n float base = float(index) * 3.0;\n vec4 c0 = texture2D(u_dataTexture, texCoordForIndex(base + 0.0, u_dataTextureSize)); // x (mercator)\n vec4 c1 = texture2D(u_dataTexture, texCoordForIndex(base + 1.0, u_dataTextureSize)); // y (mercator)\n vec4 c2 = texture2D(u_dataTexture, texCoordForIndex(base + 2.0, u_dataTextureSize)); // value\n float mx = decodeFloatRGBA(c0);\n float my = decodeFloatRGBA(c1);\n float val = decodeFloatRGBA(c2);\n return vec3(mx, my, val);\n }\n\n void main() {\n float num = 0.0;\n float denom = 0.0;\n float power = 3.0; // IDW power\n float minDist = 1e9;\n\n for (int i = 0; i < 1024; i++) { // 1024 is a safe upper bound\n if (i >= u_numStations) break;\n vec3 station = getPoint(i);\n float dx = v_pos.x - station.x;\n float dy = v_pos.y - station.y;\n float d = sqrt(dx*dx + dy*dy);\n minDist = min(minDist, d);\n\n if (d < 1e-6) {\n // Exact match: use station value directly\n num = station.z;\n denom = 1.0;\n // stop looping, we\u2019re done\n break;\n }\n\n float w = 1.0 / pow(d, power);\n num += w * station.z;\n denom += w;\n }\n\n if (minDist > u_maxDistance) {\n // Too far from any station \u2192 discard pixel (transparent)\n discard;\n } \n\n float value = num / denom;\n\n // Normalize value between 0 and 1\n //float minVal = 0.0; // pass as uniform if needed\n //float maxVal = 1.0;\n //float norm = clamp((value - minVal) / (maxVal - minVal), 0.0, 1.0);\n\n // --- FADE TO TRANSPARENT ---\n float u_fadeDistance = u_maxDistance * u_fadeFraction;\n float alpha = 1.0;\n if (minDist > u_maxDistance - u_fadeDistance) {\n // fade linearly from 1 \u2192 0\n alpha = (u_maxDistance - minDist) / u_fadeDistance;\n alpha = clamp(alpha, 0.0, 1.0);\n }\n\n gl_FragColor = vec4(vec3(getGradientColor(1.0 - value)), alpha);\n }\n\n";
|
|
2
|
+
export { IdwFragmentShader };
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
import { IGradientStop } from '../../../Types';
|
|
3
|
+
interface IPoint {
|
|
4
|
+
latitude: number;
|
|
5
|
+
longitude: number;
|
|
6
|
+
value: number;
|
|
7
|
+
}
|
|
8
|
+
interface IIdwLayerProps {
|
|
9
|
+
/**
|
|
10
|
+
* Input data.
|
|
11
|
+
*/
|
|
12
|
+
data: IPoint[];
|
|
13
|
+
/**
|
|
14
|
+
* Gradient stops. A default gradient is preset.
|
|
15
|
+
*/
|
|
16
|
+
gradientStops?: IGradientStop[];
|
|
17
|
+
/**
|
|
18
|
+
* Minimum zoom level at which to render layer.
|
|
19
|
+
* @default 0
|
|
20
|
+
*/
|
|
21
|
+
minZoom?: number;
|
|
22
|
+
/**
|
|
23
|
+
* Maximum zoom level at which to render layer.
|
|
24
|
+
* @default 99
|
|
25
|
+
*/
|
|
26
|
+
maxZoom?: number;
|
|
27
|
+
/**
|
|
28
|
+
* Maximum world distance (in -1..1 coordinate) system away from
|
|
29
|
+
* all stations where a pixel is still drawn.
|
|
30
|
+
* @default 0.0002
|
|
31
|
+
*/
|
|
32
|
+
maxDistance?: number;
|
|
33
|
+
/**
|
|
34
|
+
* Thickness of fading edge of blob (value 0..1)
|
|
35
|
+
* @default 0.15
|
|
36
|
+
*/
|
|
37
|
+
fadeFraction?: number;
|
|
38
|
+
/**
|
|
39
|
+
* Offscreen texture resolution. Higher resolution = more pixels,
|
|
40
|
+
* slowing down the fragment shader.
|
|
41
|
+
* @default 256
|
|
42
|
+
*/
|
|
43
|
+
resolution: 16 | 32 | 64 | 128 | 256 | 512 | 1024 | 2048 | 4096;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* An `IdwLayer` takes a data array of points of the form
|
|
47
|
+
* `{ latitude, longitude, value }`, and renders a colored surface using
|
|
48
|
+
* **inverse distance weighting**.
|
|
49
|
+
*
|
|
50
|
+
* To do this, all points are stored in a data texture, which is then read
|
|
51
|
+
* by the fragment shader. For each fragment, the fragment shader consults
|
|
52
|
+
* all points in the data texture and determines their distance to the
|
|
53
|
+
* fragment, the applies inverse distance weighting to calculate the value
|
|
54
|
+
* of the fragment.
|
|
55
|
+
*
|
|
56
|
+
* This process is _O(FxP)_, where _F_ is the number of fragments and _P_ is the
|
|
57
|
+
* number of data points. For a large screen (2048x1024) and a large number
|
|
58
|
+
* of data points (100), this will mean 209M calculations per frame. To
|
|
59
|
+
* reduce this, the actual calculations are done in a first pass to a frame
|
|
60
|
+
* buffer, using a texture of (by default) 256x256. The number of calculations
|
|
61
|
+
* is then reduced to 6M. The resulting texture is then upscaled to fill
|
|
62
|
+
* the original screen. The resolution of the offscreen texture is configurable,
|
|
63
|
+
* as long as it is a power of 2 (32, 64, 128, 256...).
|
|
64
|
+
*/
|
|
65
|
+
declare const IdwLayer: {
|
|
66
|
+
({ gradientStops, minZoom, maxZoom, maxDistance, fadeFraction, resolution, ...props }: IIdwLayerProps): React.JSX.Element;
|
|
67
|
+
displayName: string;
|
|
68
|
+
};
|
|
69
|
+
export { IdwLayer };
|
|
@@ -0,0 +1,285 @@
|
|
|
1
|
+
var __assign = (this && this.__assign) || function () {
|
|
2
|
+
__assign = Object.assign || function(t) {
|
|
3
|
+
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
4
|
+
s = arguments[i];
|
|
5
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
|
|
6
|
+
t[p] = s[p];
|
|
7
|
+
}
|
|
8
|
+
return t;
|
|
9
|
+
};
|
|
10
|
+
return __assign.apply(this, arguments);
|
|
11
|
+
};
|
|
12
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
13
|
+
var t = {};
|
|
14
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
15
|
+
t[p] = s[p];
|
|
16
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
17
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
18
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
19
|
+
t[p[i]] = s[p[i]];
|
|
20
|
+
}
|
|
21
|
+
return t;
|
|
22
|
+
};
|
|
23
|
+
var __spreadArray = (this && this.__spreadArray) || function (to, from, pack) {
|
|
24
|
+
if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
25
|
+
if (ar || !(i in from)) {
|
|
26
|
+
if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
27
|
+
ar[i] = from[i];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
return to.concat(ar || Array.prototype.slice.call(from));
|
|
31
|
+
};
|
|
32
|
+
import * as React from 'react';
|
|
33
|
+
import { Layer, useMap } from 'react-map-gl/mapbox';
|
|
34
|
+
import { MercatorCoordinate } from 'mapbox-gl';
|
|
35
|
+
import { IdwVertexShader } from './IdwVertexShader';
|
|
36
|
+
import { IdwFragmentShader } from './IdwFragmentShader';
|
|
37
|
+
import { RgbColor } from '../../../helper/RgbColor';
|
|
38
|
+
import { PresetGradients } from '../../../controls/Gradient';
|
|
39
|
+
import { CopyVertexShader } from './CopyVertexShader';
|
|
40
|
+
import { CopyFragmentShader } from './CopyFragmentShader';
|
|
41
|
+
var IdwLayerBase = function (props) {
|
|
42
|
+
var map = useMap();
|
|
43
|
+
var idwProgram = React.useRef(null);
|
|
44
|
+
var vertexBuffer = React.useRef(null);
|
|
45
|
+
var dataTexture = React.useRef(null);
|
|
46
|
+
var dataTextureWidth = React.useRef(null);
|
|
47
|
+
var dataTextureHeight = React.useRef(null);
|
|
48
|
+
var offscreenTexture = React.useRef(null);
|
|
49
|
+
var fbo = React.useRef(null);
|
|
50
|
+
var copyProgram = React.useRef(null);
|
|
51
|
+
var copyBuffer = React.useRef(null);
|
|
52
|
+
var _a = React.useState(0), time = _a[0], setTime = _a[1];
|
|
53
|
+
var data = props.data.slice(0, 50);
|
|
54
|
+
// When properties change, make sure that layer is redrawn.
|
|
55
|
+
// Do this by varying its `key` with the current time.
|
|
56
|
+
React.useEffect(function () {
|
|
57
|
+
setTime(Date.now());
|
|
58
|
+
}, [props.data, props.gradientStops]);
|
|
59
|
+
//
|
|
60
|
+
// Convert a hex color (e.g. #ff0022) to an [r,g,b,a] array,
|
|
61
|
+
// where r,g,b,a are in the 0.0-1.0 range.
|
|
62
|
+
//
|
|
63
|
+
var colorToRGBA = function (color) {
|
|
64
|
+
var rgb = RgbColor.FromString(color);
|
|
65
|
+
return [rgb.red / 255.0, rgb.green / 255.0, rgb.blue / 255.0, rgb.alpha];
|
|
66
|
+
};
|
|
67
|
+
var floatToRGBABytesLE = function (value) {
|
|
68
|
+
var buf = new ArrayBuffer(4);
|
|
69
|
+
var dv = new DataView(buf);
|
|
70
|
+
dv.setFloat32(0, value, true); // little-endian
|
|
71
|
+
return [
|
|
72
|
+
dv.getUint8(0),
|
|
73
|
+
dv.getUint8(1),
|
|
74
|
+
dv.getUint8(2),
|
|
75
|
+
dv.getUint8(3),
|
|
76
|
+
];
|
|
77
|
+
};
|
|
78
|
+
var makeTexture = function (gl) {
|
|
79
|
+
var minVal = Math.min.apply(Math, data.map(function (p) { return p.value; }));
|
|
80
|
+
var maxVal = Math.max.apply(Math, data.map(function (p) { return p.value; }));
|
|
81
|
+
var normalized = data.map(function (m) {
|
|
82
|
+
var coord = MercatorCoordinate.fromLngLat({ lng: m.longitude, lat: m.latitude });
|
|
83
|
+
return { x: coord.x, y: coord.y, value: (m.value - minVal) / (maxVal - minVal) };
|
|
84
|
+
});
|
|
85
|
+
var texSize = 1024;
|
|
86
|
+
dataTextureWidth.current = texSize;
|
|
87
|
+
dataTextureHeight.current = texSize;
|
|
88
|
+
var pixels = new Uint8Array(texSize * texSize * 4);
|
|
89
|
+
normalized.forEach(function (p, i) {
|
|
90
|
+
var values = [p.x, p.y, p.value];
|
|
91
|
+
for (var j = 0; j < 3; j++) {
|
|
92
|
+
var _a = floatToRGBABytesLE(values[j]), r = _a[0], g = _a[1], b = _a[2], a = _a[3];
|
|
93
|
+
var pixelIndex = i * 3 + j;
|
|
94
|
+
var offset = pixelIndex * 4;
|
|
95
|
+
if (offset + 3 < pixels.length) {
|
|
96
|
+
pixels[offset + 0] = r;
|
|
97
|
+
pixels[offset + 1] = g;
|
|
98
|
+
pixels[offset + 2] = b;
|
|
99
|
+
pixels[offset + 3] = a;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
});
|
|
103
|
+
// Create / bind / upload texture
|
|
104
|
+
dataTexture.current = gl.createTexture();
|
|
105
|
+
gl.bindTexture(gl.TEXTURE_2D, dataTexture.current);
|
|
106
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, texSize, texSize, 0, gl.RGBA, gl.UNSIGNED_BYTE, pixels);
|
|
107
|
+
// Use nearest sampling — we want exact pixel values
|
|
108
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
109
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
110
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
111
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
112
|
+
};
|
|
113
|
+
var onAddLayer = function (map, gl) {
|
|
114
|
+
// IDW PROGRAM
|
|
115
|
+
// create a vertex shader
|
|
116
|
+
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
|
117
|
+
gl.shaderSource(vertexShader, IdwVertexShader);
|
|
118
|
+
gl.compileShader(vertexShader);
|
|
119
|
+
// create a fragment shader
|
|
120
|
+
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
121
|
+
gl.shaderSource(fragmentShader, IdwFragmentShader);
|
|
122
|
+
gl.compileShader(fragmentShader);
|
|
123
|
+
// link the two shaders into a WebGL program
|
|
124
|
+
idwProgram.current = gl.createProgram();
|
|
125
|
+
gl.attachShader(idwProgram.current, vertexShader);
|
|
126
|
+
gl.attachShader(idwProgram.current, fragmentShader);
|
|
127
|
+
gl.linkProgram(idwProgram.current);
|
|
128
|
+
// Create vertex buffer from vertices:
|
|
129
|
+
vertexBuffer.current = gl.createBuffer();
|
|
130
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer.current);
|
|
131
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
|
132
|
+
0.0, 0.0,
|
|
133
|
+
1.0, 0.0,
|
|
134
|
+
0.0, 1.0,
|
|
135
|
+
1.0, 1.0
|
|
136
|
+
]), gl.STATIC_DRAW);
|
|
137
|
+
// Make an OpenGL texture that contains station data (x,y,value).
|
|
138
|
+
// The texture dimensions are saved and will be passed into a shader
|
|
139
|
+
// uniform. Note that lat/lng is converted to Mercator x,y, which has
|
|
140
|
+
// a range of [0..1].
|
|
141
|
+
makeTexture(gl);
|
|
142
|
+
// create texture to render into
|
|
143
|
+
offscreenTexture.current = gl.createTexture();
|
|
144
|
+
gl.bindTexture(gl.TEXTURE_2D, offscreenTexture.current);
|
|
145
|
+
// allocate empty texture
|
|
146
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, props.resolution, props.resolution, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
147
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); // linear for smoother upsampling; you can use NEAREST if you want blocky
|
|
148
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR);
|
|
149
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
|
|
150
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
|
|
151
|
+
// create framebuffer and attach texture
|
|
152
|
+
fbo.current = gl.createFramebuffer();
|
|
153
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo.current);
|
|
154
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, offscreenTexture.current, 0);
|
|
155
|
+
// check completeness (best-effort)
|
|
156
|
+
var status = gl.checkFramebufferStatus(gl.FRAMEBUFFER);
|
|
157
|
+
if (status !== gl.FRAMEBUFFER_COMPLETE) {
|
|
158
|
+
// Not fatal here — log to console
|
|
159
|
+
// eslint-disable-next-line no-console
|
|
160
|
+
console.warn('Framebuffer not complete: ', status);
|
|
161
|
+
}
|
|
162
|
+
// unbind
|
|
163
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
164
|
+
// COPY PROGRAM
|
|
165
|
+
// create a vertex shader
|
|
166
|
+
var copyVertexShader = gl.createShader(gl.VERTEX_SHADER);
|
|
167
|
+
gl.shaderSource(copyVertexShader, CopyVertexShader);
|
|
168
|
+
gl.compileShader(copyVertexShader);
|
|
169
|
+
// create a fragment shader
|
|
170
|
+
var copyFragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
171
|
+
gl.shaderSource(copyFragmentShader, CopyFragmentShader);
|
|
172
|
+
gl.compileShader(copyFragmentShader);
|
|
173
|
+
// link the two shaders into a WebGL program
|
|
174
|
+
copyProgram.current = gl.createProgram();
|
|
175
|
+
gl.attachShader(copyProgram.current, copyVertexShader);
|
|
176
|
+
gl.attachShader(copyProgram.current, copyFragmentShader);
|
|
177
|
+
gl.linkProgram(copyProgram.current);
|
|
178
|
+
// Create vertex buffer from vertices:
|
|
179
|
+
copyBuffer.current = gl.createBuffer();
|
|
180
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, copyBuffer.current);
|
|
181
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
|
182
|
+
0.0, 0.0,
|
|
183
|
+
1.0, 0.0,
|
|
184
|
+
0.0, 1.0,
|
|
185
|
+
1.0, 1.0
|
|
186
|
+
]), gl.STATIC_DRAW);
|
|
187
|
+
};
|
|
188
|
+
var onRender = function (gl, matrix, zoom, width, height) {
|
|
189
|
+
// Render is called many times while the map is panned/zoomed.
|
|
190
|
+
// You cannot have access to the map though.
|
|
191
|
+
if (zoom < props.minZoom)
|
|
192
|
+
return;
|
|
193
|
+
if (zoom > props.maxZoom)
|
|
194
|
+
return;
|
|
195
|
+
//
|
|
196
|
+
// FIRST PASS
|
|
197
|
+
//
|
|
198
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo.current);
|
|
199
|
+
var vp = gl.getParameter(gl.VIEWPORT);
|
|
200
|
+
gl.viewport(0, 0, props.resolution, props.resolution);
|
|
201
|
+
gl.clearColor(0, 0, 0, 0);
|
|
202
|
+
gl.clear(gl.COLOR_BUFFER_BIT);
|
|
203
|
+
// Render is called many times while the map is panned/zoomed.
|
|
204
|
+
// You cannot have access to the map though.
|
|
205
|
+
gl.useProgram(idwProgram.current);
|
|
206
|
+
// Pass a matrix uniform in:
|
|
207
|
+
gl.uniformMatrix4fv(gl.getUniformLocation(idwProgram.current, 'u_matrix'), false, matrix);
|
|
208
|
+
// Pass in number of stations:
|
|
209
|
+
gl.uniform1i(gl.getUniformLocation(idwProgram.current, "u_numStations"), data.length);
|
|
210
|
+
// put the data texture on texture unit 0
|
|
211
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
212
|
+
gl.bindTexture(gl.TEXTURE_2D, dataTexture.current);
|
|
213
|
+
// Pass data texture in (use texture unit 0):
|
|
214
|
+
gl.uniform1i(gl.getUniformLocation(idwProgram.current, "u_dataTexture"), 0);
|
|
215
|
+
// Pass texture size in:
|
|
216
|
+
// Tell the shader the size of the position texture
|
|
217
|
+
gl.uniform2f(gl.getUniformLocation(idwProgram.current, "u_dataTextureSize"), dataTextureWidth.current, dataTextureHeight.current);
|
|
218
|
+
// Stops - fill up to 12 stops by using values > 1 for filler stops.
|
|
219
|
+
// e.g. [0.0, 0.5, 1.0, 2.0....] means that only the first 3 stops are used.
|
|
220
|
+
var stops = __spreadArray([], props.gradientStops.map(function (s) { return s.pos; }), true);
|
|
221
|
+
while (stops.length < 12)
|
|
222
|
+
stops.push(2.0);
|
|
223
|
+
gl.uniform1fv(gl.getUniformLocation(idwProgram.current, 'u_gradientStops'), new Float32Array(stops));
|
|
224
|
+
var colors = props.gradientStops.map(function (s) { return colorToRGBA(s.color); }).flat();
|
|
225
|
+
gl.uniform4fv(gl.getUniformLocation(idwProgram.current, 'u_gradientColors'), new Float32Array(colors));
|
|
226
|
+
// Max distance from all stations at which a pixel is drawn:
|
|
227
|
+
gl.uniform1f(gl.getUniformLocation(idwProgram.current, "u_maxDistance"), props.maxDistance);
|
|
228
|
+
// Fraction of this max distance where fading begins:
|
|
229
|
+
gl.uniform1f(gl.getUniformLocation(idwProgram.current, "u_fadeFraction"), props.fadeFraction);
|
|
230
|
+
var aPos = gl.getAttribLocation(idwProgram.current, 'a_pos');
|
|
231
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer.current);
|
|
232
|
+
gl.enableVertexAttribArray(aPos);
|
|
233
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
|
|
234
|
+
gl.enable(gl.BLEND);
|
|
235
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
236
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
237
|
+
//
|
|
238
|
+
// SECOND PASS
|
|
239
|
+
//
|
|
240
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
241
|
+
// Restore mapbox viewport:
|
|
242
|
+
gl.viewport(vp[0], vp[1], vp[2], vp[3]);
|
|
243
|
+
gl.useProgram(copyProgram.current);
|
|
244
|
+
// Pass a matrix uniform in:
|
|
245
|
+
gl.uniformMatrix4fv(gl.getUniformLocation(copyProgram.current, 'u_matrix'), false, matrix);
|
|
246
|
+
// bind offscreen texture into unit 0 for copy pass
|
|
247
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
248
|
+
gl.bindTexture(gl.TEXTURE_2D, offscreenTexture.current);
|
|
249
|
+
gl.uniform1i(gl.getUniformLocation(copyProgram.current, 'u_src'), 0);
|
|
250
|
+
var aPos2 = gl.getAttribLocation(copyProgram.current, 'a_pos');
|
|
251
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, copyBuffer.current);
|
|
252
|
+
gl.enableVertexAttribArray(aPos2);
|
|
253
|
+
gl.vertexAttribPointer(aPos2, 2, gl.FLOAT, false, 0, 0);
|
|
254
|
+
gl.enable(gl.BLEND);
|
|
255
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
256
|
+
gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
|
|
257
|
+
};
|
|
258
|
+
return (React.createElement(Layer, { id: null, type: "custom", beforeId: "overlay", key: time, onAdd: onAddLayer, render: function (gl, matrix) { return onRender(gl, matrix, map.current.getZoom(), map.current.getContainer().clientWidth, map.current.getContainer().clientHeight); } }));
|
|
259
|
+
};
|
|
260
|
+
/**
|
|
261
|
+
* An `IdwLayer` takes a data array of points of the form
|
|
262
|
+
* `{ latitude, longitude, value }`, and renders a colored surface using
|
|
263
|
+
* **inverse distance weighting**.
|
|
264
|
+
*
|
|
265
|
+
* To do this, all points are stored in a data texture, which is then read
|
|
266
|
+
* by the fragment shader. For each fragment, the fragment shader consults
|
|
267
|
+
* all points in the data texture and determines their distance to the
|
|
268
|
+
* fragment, the applies inverse distance weighting to calculate the value
|
|
269
|
+
* of the fragment.
|
|
270
|
+
*
|
|
271
|
+
* This process is _O(FxP)_, where _F_ is the number of fragments and _P_ is the
|
|
272
|
+
* number of data points. For a large screen (2048x1024) and a large number
|
|
273
|
+
* of data points (100), this will mean 209M calculations per frame. To
|
|
274
|
+
* reduce this, the actual calculations are done in a first pass to a frame
|
|
275
|
+
* buffer, using a texture of (by default) 256x256. The number of calculations
|
|
276
|
+
* is then reduced to 6M. The resulting texture is then upscaled to fill
|
|
277
|
+
* the original screen. The resolution of the offscreen texture is configurable,
|
|
278
|
+
* as long as it is a power of 2 (32, 64, 128, 256...).
|
|
279
|
+
*/
|
|
280
|
+
var IdwLayer = function (_a) {
|
|
281
|
+
var _b = _a.gradientStops, gradientStops = _b === void 0 ? PresetGradients.Blue : _b, _c = _a.minZoom, minZoom = _c === void 0 ? 0 : _c, _d = _a.maxZoom, maxZoom = _d === void 0 ? 99 : _d, _e = _a.maxDistance, maxDistance = _e === void 0 ? 0.0002 : _e, _f = _a.fadeFraction, fadeFraction = _f === void 0 ? 0.15 : _f, _g = _a.resolution, resolution = _g === void 0 ? 256 : _g, props = __rest(_a, ["gradientStops", "minZoom", "maxZoom", "maxDistance", "fadeFraction", "resolution"]);
|
|
282
|
+
return React.createElement(IdwLayerBase, __assign({ gradientStops: gradientStops, minZoom: minZoom, maxZoom: maxZoom, maxDistance: maxDistance, fadeFraction: fadeFraction, resolution: resolution }, props));
|
|
283
|
+
};
|
|
284
|
+
IdwLayer.displayName = 'IdwLayer';
|
|
285
|
+
export { IdwLayer };
|