@longline/aqua-ui 1.0.339 → 1.0.340
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/containers/Anchor/Anchor.d.ts +5 -0
- package/containers/Anchor/Anchor.js +20 -8
- package/containers/Dock/Dock.d.ts +5 -0
- package/containers/Dock/Dock.js +1 -1
- package/containers/Dock/Dockable.d.ts +5 -0
- package/containers/Dock/Dockable.js +20 -12
- package/containers/DragBar/DragBar.d.ts +5 -0
- package/containers/DragBar/DragBar.js +16 -5
- package/containers/Form/Field.d.ts +0 -3
- package/containers/Form/Field.js +3 -6
- package/containers/Form/Form.js +5 -36
- package/containers/Form/Validation.d.ts +1 -1
- package/containers/Form/Validation.js +6 -6
- package/containers/Form/context/FormContext.d.ts +1 -2
- package/containers/Form/context/useForm.d.ts +1 -1
- package/containers/Form/elements/BoxWrapper.js +2 -0
- package/containers/GlassPane/GlassPane.d.ts +7 -2
- package/containers/GlassPane/GlassPane.js +3 -3
- package/containers/InfoBox/InfoBox.d.ts +5 -0
- package/containers/InfoBox/InfoBox.js +1 -1
- package/containers/List/List.d.ts +5 -0
- package/containers/List/List.js +1 -1
- package/containers/List/ListCell.d.ts +5 -0
- package/containers/List/ListCell.js +1 -1
- package/containers/List/ListRow.d.ts +7 -2
- package/containers/List/ListRow.js +1 -1
- package/containers/Message/Error.d.ts +2 -0
- package/containers/Message/Error.js +1 -1
- package/containers/Message/Message.d.ts +5 -0
- package/containers/Message/Message.js +1 -1
- package/containers/Message/NoData.d.ts +2 -0
- package/containers/Message/NoData.js +1 -1
- package/containers/Message/NoFilteredData.d.ts +2 -0
- package/containers/Message/NoFilteredData.js +1 -1
- package/containers/Openable/Openable.d.ts +5 -0
- package/containers/Openable/Openable.js +8 -8
- package/containers/PublicRoute/PublicRoute.d.ts +9 -1
- package/containers/PublicRoute/PublicRoute.js +3 -7
- package/containers/Tabs/Pane.d.ts +5 -0
- package/containers/Tabs/Pane.js +3 -3
- package/containers/Tabs/Tabs.d.ts +5 -0
- package/containers/Tabs/Tabs.js +3 -3
- package/controls/Chip/Chip.d.ts +15 -3
- package/controls/Chip/Chip.js +7 -6
- package/controls/CircularProgress/CircularProgress.d.ts +11 -0
- package/controls/CircularProgress/CircularProgress.js +19 -11
- package/controls/Dropzone/Dropzone.d.ts +11 -1
- package/controls/Dropzone/Dropzone.js +18 -7
- package/controls/Fab/Fab.d.ts +14 -6
- package/controls/Fab/Fab.js +7 -20
- package/controls/Ghost/Ghost.js +3 -3
- package/controls/Gradient/Gradient.d.ts +5 -0
- package/controls/Gradient/Gradient.js +7 -4
- package/controls/Histogram/Histogram.d.ts +8 -2
- package/controls/Histogram/Histogram.js +9 -9
- package/controls/Histogram/HistogramBar.d.ts +2 -2
- package/controls/Icon/Icon.d.ts +10 -4
- package/controls/Icon/Icon.js +23 -6
- package/controls/Key/Key.d.ts +5 -0
- package/controls/Key/Key.js +2 -5
- package/controls/LinearChart/LinearChart.d.ts +9 -0
- package/controls/LinearChart/LinearChart.js +11 -6
- package/controls/ListButton/ListButton.d.ts +46 -3
- package/controls/ListButton/ListButton.js +70 -9
- package/controls/ListView/ColumnsManager/ColumnDraggable.js +11 -5
- package/controls/ListView/ColumnsManager/SourceColumns.js +1 -1
- package/controls/ListView/IListViewProps.d.ts +9 -2
- package/controls/ListView/ListView.js +13 -12
- package/controls/ListView/defaults.d.ts +3 -0
- package/controls/ListView/defaults.js +6 -0
- package/controls/ListView/elements/Body.d.ts +1 -1
- package/controls/ListView/elements/Body.js +23 -12
- package/controls/ListView/elements/Ghost.js +3 -2
- package/controls/ListView/elements/Header.js +3 -2
- package/controls/ListView/elements/HeaderCell.js +3 -3
- package/controls/ListView/elements/Table.js +16 -10
- package/controls/Mouse/Mouse.d.ts +6 -4
- package/controls/Mouse/Mouse.js +15 -8
- package/controls/PrimaryButton/PrimaryButton.d.ts +9 -3
- package/controls/PrimaryButton/PrimaryButton.js +5 -5
- package/controls/Progress/Progress.d.ts +9 -0
- package/controls/Progress/Progress.js +12 -8
- package/controls/SecondaryButton/SecondaryButton.d.ts +8 -3
- package/controls/SecondaryButton/SecondaryButton.js +1 -1
- package/controls/SpeechRecognizer/EditorRegistry.js +1 -2
- package/controls/SpeechRecognizer/SpeechRecognizer.d.ts +9 -1
- package/controls/SpeechRecognizer/SpeechRecognizer.js +16 -9
- package/controls/TabBar/TabBar.d.ts +5 -0
- package/controls/TabBar/TabBar.js +14 -6
- package/controls/TabBar/Underliner.js +1 -1
- package/controls/TertiaryButton/TertiaryButton.d.ts +9 -3
- package/controls/TertiaryButton/TertiaryButton.js +5 -3
- package/controls/ToggleButton/ToggleButton.d.ts +8 -2
- package/controls/ToggleButton/ToggleButton.js +1 -1
- package/controls/View/View.d.ts +5 -0
- package/controls/View/View.js +1 -1
- package/formatters/CountryFormatter/CountryFormatter.d.ts +3 -2
- package/formatters/CountryFormatter/CountryUtil.d.ts +3 -3
- package/formatters/DateTimeFormatter/DateTimeFormatter.d.ts +11 -10
- package/formatters/DateTimeFormatter/elements/Custom.d.ts +1 -1
- package/formatters/DateTimeFormatter/elements/DistanceDate.d.ts +1 -1
- package/formatters/DateTimeFormatter/elements/LongDate.d.ts +1 -1
- package/formatters/DateTimeFormatter/elements/LongDateTime.d.ts +1 -1
- package/formatters/DateTimeFormatter/elements/LongTime.d.ts +1 -1
- package/formatters/DateTimeFormatter/elements/Month.d.ts +1 -1
- package/formatters/DateTimeFormatter/elements/ShortDate.d.ts +1 -1
- package/formatters/DateTimeFormatter/elements/ShortDateTime.d.ts +1 -1
- package/formatters/DateTimeFormatter/elements/ShortTime.d.ts +1 -1
- package/formatters/DivisionFormatter/DivisionFormatter.d.ts +2 -2
- package/formatters/DivisionFormatter/DivisionFormatter.js +1 -1
- package/formatters/DivisionFormatter/DivisionUtil.d.ts +1 -1
- package/formatters/DivisionFormatter/DivisionUtil.js +5 -3
- package/formatters/FilesizeFormatter/FilesizeFormatter.d.ts +3 -3
- package/formatters/GIS/CoordinateFormatter.d.ts +2 -2
- package/formatters/GIS/LatitudeFormatter.d.ts +2 -2
- package/formatters/GIS/LongitudeFormatter.d.ts +2 -2
- package/formatters/HumanFormatter/HumanFormatter.d.ts +3 -3
- package/formatters/NumberFormatter/NumberFormatter.d.ts +3 -3
- package/formatters/PhoneFormatter/PhoneFormatter.d.ts +3 -3
- package/formatters/StringFormatter/StringFormatter.d.ts +3 -3
- package/formatters/StringFormatter/StringFormatter.js +1 -4
- package/helper/DMS.d.ts +1 -1
- package/helper/DMS.js +2 -2
- package/hooks/useOutsideClose/useOutsideClose.js +20 -11
- package/hooks/useSpeechAIRecorder/useSpeechAIRecorder.js +10 -7
- package/index.js +1 -0
- package/inputs/DateInput/Body.d.ts +2 -2
- package/inputs/DateInput/Body.js +11 -7
- package/inputs/DateInput/Calendar.d.ts +1 -1
- package/inputs/DateInput/Calendar.js +3 -5
- package/inputs/DateInput/DateInput.d.ts +11 -3
- package/inputs/DateInput/DateInput.js +11 -3
- package/inputs/DateInput/Day.d.ts +1 -1
- package/inputs/DateInput/InfiniteList.js +6 -3
- package/inputs/DateInput/Navbar.js +3 -2
- package/inputs/DateInput/NumericInput.js +3 -0
- package/inputs/DateInput/Selector.d.ts +1 -1
- package/inputs/DateInput/Selector.js +9 -6
- package/inputs/Dropdown/Body.d.ts +2 -2
- package/inputs/Dropdown/Column.d.ts +1 -1
- package/inputs/Dropdown/Dropdown.d.ts +5 -0
- package/inputs/Dropdown/Dropdown.js +36 -63
- package/inputs/Dropdown/Pill.js +1 -1
- package/inputs/Dropdown/Selection.js +1 -1
- package/inputs/Editor/Editor.d.ts +5 -0
- package/inputs/Editor/Editor.js +16 -6
- package/inputs/Editor/buttons/SpeechAIButton.js +2 -0
- package/inputs/Editor/buttons/TextAIButton.d.ts +0 -13
- package/inputs/Editor/buttons/TextAIButton.js +30 -14
- package/inputs/Editor/buttons/TextAIMenu.js +1 -1
- package/inputs/Editor/menu/MenuBar.d.ts +1 -1
- package/inputs/Editor/menu/MenuBar.js +1 -1
- package/inputs/Editor/menu/MenuButton.js +1 -1
- package/inputs/Input/Clear.js +1 -1
- package/inputs/Input/Input.d.ts +5 -0
- package/inputs/Input/Input.js +8 -6
- package/inputs/Input/InputWrapper.d.ts +2 -0
- package/inputs/Input/InputWrapper.js +1 -1
- package/inputs/Input/Reveal.js +1 -1
- package/inputs/MonthRange/Body.d.ts +1 -1
- package/inputs/MonthRange/Calendar.d.ts +2 -2
- package/inputs/MonthRange/Calendar.js +6 -9
- package/inputs/MonthRange/MonthRange.d.ts +7 -1
- package/inputs/MonthRange/MonthRange.js +14 -6
- package/inputs/MonthRange/Selector.d.ts +1 -1
- package/inputs/MonthRange/Selector.js +12 -11
- package/inputs/PhoneInput/PhoneInput.d.ts +5 -0
- package/inputs/PhoneInput/PhoneInput.js +2 -2
- package/inputs/Selector/Selector.d.ts +5 -0
- package/inputs/Selector/Selector.js +4 -1
- package/inputs/Slider/Slider.d.ts +75 -22
- package/inputs/Slider/Slider.js +104 -22
- package/inputs/Textarea/Textarea.d.ts +5 -5
- package/inputs/Textarea/Textarea.js +3 -2
- package/map/Map/Map.d.ts +2 -2
- package/map/Map/Map.js +20 -14
- package/map/PositionsManager/PositionBox.js +7 -3
- package/map/PositionsManager/PositionsManager.js +33 -13
- package/map/controls/CompassButton/CompassButton.js +1 -1
- package/map/controls/FullscreenButton/FullscreenButton.js +1 -1
- package/map/controls/Geocoder/Geocoder.js +28 -14
- package/map/controls/Geocoder/GeocoderApi.js +2 -0
- package/map/controls/Geocoder/GeocoderSelector.js +1 -1
- package/map/controls/Graticule/Graticule.js +1 -5
- package/map/controls/MapLoader/MapLoader.js +1 -1
- package/map/controls/ScaleControl/ScaleControl.js +1 -1
- package/map/controls/ZoomInButton/ZoomInButton.js +1 -1
- package/map/controls/ZoomOutButton/ZoomOutButton.d.ts +1 -1
- package/map/controls/ZoomOutButton/ZoomOutButton.js +2 -2
- package/map/controls/base/MapButton/MapButton.d.ts +8 -2
- package/map/controls/base/MapButton/MapButton.js +11 -2
- package/map/controls/base/MapControl/MapControl.d.ts +5 -0
- package/map/controls/base/MapControl/MapControl.js +10 -7
- package/map/layers/ClusterLayer/ClusterLayer.d.ts +1 -1
- package/map/layers/ClusterLayer/ClusterLayer.js +7 -3
- package/map/layers/HtmlMarkerLayer/HtmlMarkerLayer.js +8 -4
- package/map/layers/IdwBlendLayer/IdwBlendLayer.js +9 -4
- package/map/layers/IdwLayer/IdwLayer.d.ts +2 -1
- package/map/layers/IdwLayer/IdwLayer.js +271 -215
- package/map/layers/InterpolationLayer/ContoursFragmentShader.d.ts +1 -1
- package/map/layers/InterpolationLayer/ContoursFragmentShader.js +1 -1
- package/map/layers/InterpolationLayer/InterpolationLayer.d.ts +4 -3
- package/map/layers/InterpolationLayer/InterpolationLayer.js +362 -275
- package/map/layers/ParticlesLayer/ParticlesLayer.d.ts +8 -7
- package/map/layers/ParticlesLayer/ParticlesLayer.js +528 -404
- package/map/markers/ClusterMarker/ClusterMarker.d.ts +6 -1
- package/map/markers/ClusterMarker/ClusterMarker.js +15 -6
- package/map/markers/RiskMarker/RiskMarker.d.ts +5 -1
- package/map/markers/RiskMarker/RiskMarker.js +4 -4
- package/modules/CountryDropdown/CountryDropdown.js +10 -1
- package/modules/Filter/Filter.d.ts +5 -0
- package/modules/Filter/Filter.js +10 -6
- package/modules/Globe/Globe.d.ts +5 -0
- package/modules/Globe/Globe.js +4 -4
- package/modules/MainMenu/Item.d.ts +9 -2
- package/modules/MainMenu/Item.js +8 -5
- package/modules/MainMenu/MainMenu.d.ts +5 -0
- package/modules/MainMenu/MainMenu.js +1 -1
- package/modules/ParticleGlobe/GL.d.ts +1 -1
- package/modules/ParticleGlobe/ParticleGlobe.d.ts +5 -0
- package/modules/ParticleGlobe/ParticleGlobe.js +69 -40
- package/modules/Public/Public.d.ts +5 -0
- package/modules/Public/Public.js +3 -3
- package/package.json +1 -1
- package/services/Auth/Auth.js +13 -7
- package/services/Auth/AuthContext.js +9 -1
- package/services/Dialog/Dialog.d.ts +7 -2
- package/services/Dialog/Dialog.js +7 -6
- package/services/Dialog/DialogWindow.d.ts +3 -1
- package/services/Dialog/DialogWindow.js +1 -1
- package/services/Dialog/XhrDialog.d.ts +1 -1
- package/services/Toast/Toast.js +5 -3
- package/services/Toast/ToastContainer.js +3 -1
- package/services/Toast/ToastContext.d.ts +1 -1
- package/services/Toast/ToastProvider.js +2 -0
- package/map/layers/HtmlMarkerLayer/HtmlMarkerLayer copy.d.ts +0 -35
- package/map/layers/HtmlMarkerLayer/HtmlMarkerLayer copy.js +0 -176
- package/modules/Root/Content.d.ts +0 -16
- package/modules/Root/Content.js +0 -25
- package/modules/Root/Overlay.d.ts +0 -23
- package/modules/Root/Overlay.js +0 -33
- package/modules/Root/Root.d.ts +0 -10
- package/modules/Root/Root.js +0 -46
- package/modules/Root/Shader.d.ts +0 -15
- package/modules/Root/Shader.js +0 -24
- package/modules/Root/Sidebar.d.ts +0 -13
- package/modules/Root/Sidebar.js +0 -24
- package/modules/Root/index.d.ts +0 -1
- package/modules/Root/index.js +0 -1
- package/modules/Root/stories/SampleContent.d.ts +0 -7
- package/modules/Root/stories/SampleContent.js +0 -44
|
@@ -43,283 +43,370 @@ import { DotsVertexShader } from './DotsVertexShader';
|
|
|
43
43
|
import { DotsFragmentShader } from './DotsFragmentShader';
|
|
44
44
|
var TEXTURE_WIDTH = 1024;
|
|
45
45
|
var TEXTURE_HEIGHT = 1024;
|
|
46
|
+
// Default prop values, referenced both by the InterpolationLayerBase fallbacks
|
|
47
|
+
// and the InterpolationLayer wrapper below.
|
|
48
|
+
var DEFAULT_LEVELS = 0;
|
|
49
|
+
var MAX_LEVELS = 99;
|
|
50
|
+
var DEFAULT_CONTOUR_COLOR = '#35ABE2';
|
|
51
|
+
var DEFAULT_CONTOUR_THICKNESS = 1;
|
|
52
|
+
var MAX_CONTOUR_THICKNESS = 9;
|
|
53
|
+
var DEFAULT_MIN_ZOOM = 0;
|
|
54
|
+
var DEFAULT_MAX_ZOOM = 99;
|
|
55
|
+
//
|
|
56
|
+
// Clamp the contour count to a safe non-negative integer (0..MAX_LEVELS). Guards
|
|
57
|
+
// against empty/negative/fractional/runaway values reaching the shader.
|
|
58
|
+
//
|
|
59
|
+
var clampLevels = function (value) {
|
|
60
|
+
var n = Math.floor(Number(value));
|
|
61
|
+
if (!Number.isFinite(n))
|
|
62
|
+
return DEFAULT_LEVELS;
|
|
63
|
+
return Math.max(0, Math.min(MAX_LEVELS, n));
|
|
64
|
+
};
|
|
65
|
+
//
|
|
66
|
+
// Clamp the contour line thickness (in pixels) to 0..MAX_CONTOUR_THICKNESS.
|
|
67
|
+
// Fractional widths are allowed. Guards against empty/negative/NaN values.
|
|
68
|
+
//
|
|
69
|
+
var clampThickness = function (value) {
|
|
70
|
+
var n = Number(value);
|
|
71
|
+
if (!Number.isFinite(n))
|
|
72
|
+
return DEFAULT_CONTOUR_THICKNESS;
|
|
73
|
+
return Math.max(0, Math.min(MAX_CONTOUR_THICKNESS, n));
|
|
74
|
+
};
|
|
75
|
+
//
|
|
76
|
+
// Convert a hex color (e.g. #ff0022) to an [r,g,b,a] array,
|
|
77
|
+
// where r,g,b,a are in the 0.0-1.0 range.
|
|
78
|
+
//
|
|
79
|
+
var colorToRGBA = function (color) {
|
|
80
|
+
var rgb = RgbColor.FromString(color);
|
|
81
|
+
return [rgb.red / 255.0, rgb.green / 255.0, rgb.blue / 255.0, rgb.alpha];
|
|
82
|
+
};
|
|
46
83
|
var InterpolationLayerBase = function (props) {
|
|
47
84
|
var map = useMap();
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
var
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
85
|
+
// The custom-layer callbacks are captured by Mapbox at add-time, so render
|
|
86
|
+
// reads live prop values through this ref rather than a stale closure.
|
|
87
|
+
var propsRef = React.useRef(props);
|
|
88
|
+
propsRef.current = props;
|
|
89
|
+
// Build a fresh custom layer — with its own private WebGL resource holder —
|
|
90
|
+
// whenever the data changes (the only input that requires re-triangulating and
|
|
91
|
+
// re-uploading GL state). Each generation owns its resources and frees only
|
|
92
|
+
// those in its own onRemove, so the overlapping add/remove during a
|
|
93
|
+
// react-map-gl remount never clobbers the live generation.
|
|
94
|
+
var layer = React.useMemo(function () {
|
|
95
|
+
// Unique id per generation so the old and new layers coexist cleanly during
|
|
96
|
+
// the remount (old removeLayer + new addLayer both run).
|
|
97
|
+
var id = 'interp-' + Math.random().toString(36).slice(2);
|
|
98
|
+
// Private per-generation GL resources.
|
|
99
|
+
var levelsProgram = null;
|
|
100
|
+
var contoursProgram = null;
|
|
101
|
+
var dotsProgram = null;
|
|
102
|
+
var levelsBuffer = null;
|
|
103
|
+
var contoursBuffer = null;
|
|
104
|
+
var fbo = null;
|
|
105
|
+
var numTriangles = 0;
|
|
106
|
+
var texture = null;
|
|
107
|
+
var removed = false;
|
|
108
|
+
var data = props.data;
|
|
109
|
+
//
|
|
110
|
+
// Convert IPoint array to polygons.
|
|
111
|
+
//
|
|
112
|
+
var getGeometry = function () {
|
|
113
|
+
// Each poly (triangle) gets a,b,c properties: one depth value for each point.
|
|
114
|
+
// Convert dataset points to Turf feature collection:
|
|
115
|
+
var points = featureCollection((data !== null && data !== void 0 ? data : [])
|
|
116
|
+
.filter(function (dp) { return !isNaN(dp.value); }) // Filter out any NaN values.
|
|
117
|
+
.map(function (dp) {
|
|
118
|
+
return point([dp.longitude, dp.latitude], { 'v': dp.value });
|
|
119
|
+
}));
|
|
120
|
+
var polys = tin(points, 'v');
|
|
121
|
+
/* // Calculate average side length of triangles.
|
|
122
|
+
let total = 0;
|
|
123
|
+
polys.features.forEach(p => {
|
|
124
|
+
const a = p.geometry.coordinates[0][0];
|
|
125
|
+
const b = p.geometry.coordinates[0][1];
|
|
126
|
+
const c = p.geometry.coordinates[0][2];
|
|
127
|
+
const d1 = Math.sqrt((a[0] - b[0])*(a[0]-b[0]) + (a[1] - b[1]) * (a[1] - b[1]));
|
|
128
|
+
const d2 = Math.sqrt((b[0] - c[0])*(b[0]-c[0]) + (b[1] - c[1]) * (b[1] - c[1]));
|
|
129
|
+
const d3 = Math.sqrt((a[0] - c[0])*(a[0]-c[0]) + (a[1] - c[1]) * (a[1] - c[1]));
|
|
130
|
+
const avg = (d1 + d2 + d3) / 3;
|
|
131
|
+
total += avg;
|
|
132
|
+
});
|
|
133
|
+
const avg = total / polys.features.length;
|
|
134
|
+
|
|
135
|
+
// Remove any triangles with a side of more than 2x avg
|
|
136
|
+
const factor = 4;
|
|
137
|
+
polys.features = polys.features.filter(p => {
|
|
138
|
+
const a = p.geometry.coordinates[0][0];
|
|
139
|
+
const b = p.geometry.coordinates[0][1];
|
|
140
|
+
const c = p.geometry.coordinates[0][2];
|
|
141
|
+
const d1 = Math.sqrt((a[0] - b[0])*(a[0]-b[0]) + (a[1] - b[1]) * (a[1] - b[1]));
|
|
142
|
+
const d2 = Math.sqrt((b[0] - c[0])*(b[0]-c[0]) + (b[1] - c[1]) * (b[1] - c[1]));
|
|
143
|
+
const d3 = Math.sqrt((a[0] - c[0])*(a[0]-c[0]) + (a[1] - c[1]) * (a[1] - c[1]));
|
|
144
|
+
if(d1 > factor * avg || d2 > factor * avg || d3 > factor * avg) return false;
|
|
145
|
+
return true;
|
|
146
|
+
});
|
|
147
|
+
|
|
148
|
+
// Remove any triangles with a long side:
|
|
149
|
+
const sidefactor = 4;
|
|
150
|
+
polys.features = polys.features.filter(p => {
|
|
151
|
+
const a = p.geometry.coordinates[0][0];
|
|
152
|
+
const b = p.geometry.coordinates[0][1];
|
|
153
|
+
const c = p.geometry.coordinates[0][2];
|
|
154
|
+
const d1 = Math.sqrt((a[0] - b[0])*(a[0]-b[0]) + (a[1] - b[1]) * (a[1] - b[1]));
|
|
155
|
+
const d2 = Math.sqrt((b[0] - c[0])*(b[0]-c[0]) + (b[1] - c[1]) * (b[1] - c[1]));
|
|
156
|
+
const d3 = Math.sqrt((a[0] - c[0])*(a[0]-c[0]) + (a[1] - c[1]) * (a[1] - c[1]));
|
|
157
|
+
if(d1 > sidefactor * d2 || d1 > sidefactor * d3 || d2 > sidefactor * d3) return false;
|
|
158
|
+
return true;
|
|
159
|
+
});*/
|
|
160
|
+
return polys;
|
|
161
|
+
};
|
|
162
|
+
var createTexture = function (gl) {
|
|
163
|
+
texture = gl.createTexture();
|
|
164
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
165
|
+
// Define size and format of level 0:
|
|
166
|
+
gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, TEXTURE_WIDTH, TEXTURE_HEIGHT, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
|
|
167
|
+
// Set filtering to NEAREST so there's no interpolation:
|
|
168
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
169
|
+
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
170
|
+
};
|
|
171
|
+
var createFrameBuffer = function (gl) {
|
|
172
|
+
// Create and bind the framebuffer:
|
|
173
|
+
fbo = gl.createFramebuffer();
|
|
174
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
|
175
|
+
// Attach the texture as the first color attachment:
|
|
176
|
+
gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
|
|
177
|
+
};
|
|
178
|
+
var createLevelsProgram = function (gl) {
|
|
179
|
+
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
|
180
|
+
gl.shaderSource(vertexShader, LevelsVertexShader);
|
|
181
|
+
gl.compileShader(vertexShader);
|
|
182
|
+
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
183
|
+
gl.shaderSource(fragmentShader, LevelsFragmentShader);
|
|
184
|
+
gl.compileShader(fragmentShader);
|
|
185
|
+
levelsProgram = gl.createProgram();
|
|
186
|
+
gl.attachShader(levelsProgram, vertexShader);
|
|
187
|
+
gl.attachShader(levelsProgram, fragmentShader);
|
|
188
|
+
gl.linkProgram(levelsProgram);
|
|
189
|
+
// Shaders are linked into the program now; flag them for deletion.
|
|
190
|
+
gl.deleteShader(vertexShader);
|
|
191
|
+
gl.deleteShader(fragmentShader);
|
|
192
|
+
};
|
|
193
|
+
var createContoursProgram = function (gl) {
|
|
194
|
+
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
|
195
|
+
gl.shaderSource(vertexShader, ContoursVertexShader);
|
|
196
|
+
gl.compileShader(vertexShader);
|
|
197
|
+
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
198
|
+
gl.shaderSource(fragmentShader, ContoursFragmentShader);
|
|
199
|
+
gl.compileShader(fragmentShader);
|
|
200
|
+
contoursProgram = gl.createProgram();
|
|
201
|
+
gl.attachShader(contoursProgram, vertexShader);
|
|
202
|
+
gl.attachShader(contoursProgram, fragmentShader);
|
|
203
|
+
gl.linkProgram(contoursProgram);
|
|
204
|
+
// Shaders are linked into the program now; flag them for deletion.
|
|
205
|
+
gl.deleteShader(vertexShader);
|
|
206
|
+
gl.deleteShader(fragmentShader);
|
|
207
|
+
};
|
|
208
|
+
var createDotsProgram = function (gl) {
|
|
209
|
+
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
|
210
|
+
gl.shaderSource(vertexShader, DotsVertexShader);
|
|
211
|
+
gl.compileShader(vertexShader);
|
|
212
|
+
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
213
|
+
gl.shaderSource(fragmentShader, DotsFragmentShader);
|
|
214
|
+
gl.compileShader(fragmentShader);
|
|
215
|
+
dotsProgram = gl.createProgram();
|
|
216
|
+
gl.attachShader(dotsProgram, vertexShader);
|
|
217
|
+
gl.attachShader(dotsProgram, fragmentShader);
|
|
218
|
+
gl.linkProgram(dotsProgram);
|
|
219
|
+
// Shaders are linked into the program now; flag them for deletion.
|
|
220
|
+
gl.deleteShader(vertexShader);
|
|
221
|
+
gl.deleteShader(fragmentShader);
|
|
222
|
+
};
|
|
223
|
+
var onAdd = function (mbMap, gl) {
|
|
224
|
+
if (!gl)
|
|
225
|
+
return;
|
|
226
|
+
var geometry = getGeometry();
|
|
227
|
+
var minValue = Infinity;
|
|
228
|
+
var maxValue = -Infinity;
|
|
229
|
+
var len = geometry.features.length;
|
|
230
|
+
while (len--) {
|
|
231
|
+
var properties = geometry.features[len].properties;
|
|
232
|
+
// Each triangle carries three vertex values (a, b, c). A data point may
|
|
233
|
+
// only ever appear as b or c, so scan all three to find the true range.
|
|
234
|
+
for (var _i = 0, _a = ['a', 'b', 'c']; _i < _a.length; _i++) {
|
|
235
|
+
var key = _a[_i];
|
|
236
|
+
var value = properties[key];
|
|
237
|
+
minValue = value < minValue ? value : minValue;
|
|
238
|
+
maxValue = value > maxValue ? value : maxValue;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
createLevelsProgram(gl);
|
|
242
|
+
createContoursProgram(gl);
|
|
243
|
+
createDotsProgram(gl);
|
|
244
|
+
createTexture(gl);
|
|
245
|
+
createFrameBuffer(gl);
|
|
246
|
+
// Convert dataset to triangle geometry.
|
|
247
|
+
// Result is a list of v1,v2,v3, v1,v2,v3, ...
|
|
248
|
+
// where each vector has (x,y,value).
|
|
249
|
+
var points = [];
|
|
250
|
+
var LAT = 1;
|
|
251
|
+
var LON = 0;
|
|
252
|
+
numTriangles = geometry.features.length;
|
|
253
|
+
// Avoid a 0/0 = NaN normalization when all values are equal.
|
|
254
|
+
var deltaValue = (maxValue - minValue) || 1;
|
|
255
|
+
geometry.features.map(function (feature) {
|
|
256
|
+
var coord = MercatorCoordinate.fromLngLat({ lng: feature.geometry.coordinates[0][0][LON], lat: feature.geometry.coordinates[0][0][LAT] });
|
|
257
|
+
points.push(coord.x, coord.y, (feature.properties['a'] - minValue) / deltaValue);
|
|
258
|
+
coord = MercatorCoordinate.fromLngLat({ lng: feature.geometry.coordinates[0][1][LON], lat: feature.geometry.coordinates[0][1][LAT] });
|
|
259
|
+
points.push(coord.x, coord.y, (feature.properties['b'] - minValue) / deltaValue);
|
|
260
|
+
coord = MercatorCoordinate.fromLngLat({ lng: feature.geometry.coordinates[0][2][LON], lat: feature.geometry.coordinates[0][2][LAT] });
|
|
261
|
+
points.push(coord.x, coord.y, (feature.properties['c'] - minValue) / deltaValue);
|
|
262
|
+
});
|
|
263
|
+
// Create and initialize a WebGLBuffer to store vertex data.
|
|
264
|
+
// Each element will have 3 components (x,y,value).
|
|
265
|
+
levelsBuffer = gl.createBuffer();
|
|
266
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, levelsBuffer);
|
|
267
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(points), gl.STATIC_DRAW);
|
|
268
|
+
// Create a vertex buffer with only two triangles in it, which
|
|
269
|
+
// cover the viewport. TODO: the world, it seems
|
|
270
|
+
contoursBuffer = gl.createBuffer();
|
|
271
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, contoursBuffer);
|
|
272
|
+
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
|
273
|
+
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
|
|
274
|
+
0.0, 0.0, 1.0, 1.0, 0.0, 1.0
|
|
275
|
+
]), gl.STATIC_DRAW);
|
|
276
|
+
// The map is idle after a prop-driven remount, so force a repaint to draw
|
|
277
|
+
// the freshly-added layer (there is no animation loop to do it otherwise).
|
|
278
|
+
mbMap.triggerRepaint();
|
|
279
|
+
};
|
|
280
|
+
var renderLevels = function (gl, matrix) {
|
|
281
|
+
gl.useProgram(levelsProgram);
|
|
282
|
+
// Pass a matrix uniform in:
|
|
283
|
+
gl.uniformMatrix4fv(gl.getUniformLocation(levelsProgram, 'u_matrix'), false, matrix);
|
|
284
|
+
var aPos = gl.getAttribLocation(levelsProgram, 'a_pos');
|
|
285
|
+
var aValue = gl.getAttribLocation(levelsProgram, 'a_value');
|
|
286
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, levelsBuffer);
|
|
287
|
+
gl.enableVertexAttribArray(aPos);
|
|
288
|
+
gl.enableVertexAttribArray(aValue);
|
|
289
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 12, 0);
|
|
290
|
+
gl.vertexAttribPointer(aValue, 1, gl.FLOAT, false, 12, 8);
|
|
291
|
+
gl.enable(gl.BLEND);
|
|
292
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
293
|
+
gl.drawArrays(gl.TRIANGLES, 0, numTriangles * 3);
|
|
294
|
+
// Attribute-array enable state is global in WebGL1; disable what we
|
|
295
|
+
// enabled so a later draw with fewer attributes can't reference a
|
|
296
|
+
// stale (freed) buffer left bound to a still-enabled index.
|
|
297
|
+
gl.disableVertexAttribArray(aPos);
|
|
298
|
+
gl.disableVertexAttribArray(aValue);
|
|
299
|
+
};
|
|
300
|
+
var renderContours = function (gl, matrix, width, height) {
|
|
301
|
+
var _a, _b, _c;
|
|
302
|
+
var p = propsRef.current;
|
|
303
|
+
gl.useProgram(contoursProgram);
|
|
304
|
+
// Pass a matrix uniform in:
|
|
305
|
+
gl.uniformMatrix4fv(gl.getUniformLocation(contoursProgram, 'u_matrix'), false, matrix);
|
|
306
|
+
// Pass in levels for contours:
|
|
307
|
+
gl.uniform1i(gl.getUniformLocation(contoursProgram, 'levels'), clampLevels(p.levels));
|
|
308
|
+
// Pass in contour thickness:
|
|
309
|
+
gl.uniform1f(gl.getUniformLocation(contoursProgram, 'u_contourThickness'), clampThickness(p.contourThickness));
|
|
310
|
+
// Pass in contours color:
|
|
311
|
+
var clr = colorToRGBA((_a = p.contourColor) !== null && _a !== void 0 ? _a : DEFAULT_CONTOUR_COLOR);
|
|
312
|
+
gl.uniform4f(gl.getUniformLocation(contoursProgram, 'u_contourColor'), clr[0], clr[1], clr[2], clr[3]);
|
|
313
|
+
// Stops - fill up to 12 stops by using values > 1 for filler stops.
|
|
314
|
+
// e.g. [0.0, 0.5, 1.0, 2.0....] means that only the first 3 stops are used.
|
|
315
|
+
var stops = __spreadArray([], ((_b = p.gradientStops) !== null && _b !== void 0 ? _b : []).map(function (s) { return s.pos; }), true);
|
|
316
|
+
while (stops.length < 12)
|
|
317
|
+
stops.push(2.0);
|
|
318
|
+
gl.uniform1fv(gl.getUniformLocation(contoursProgram, 'u_gradientStops'), new Float32Array(stops));
|
|
319
|
+
var colors = ((_c = p.gradientStops) !== null && _c !== void 0 ? _c : []).map(function (s) { return colorToRGBA(s.color); }).flat();
|
|
320
|
+
gl.uniform4fv(gl.getUniformLocation(contoursProgram, 'u_gradientColors'), new Float32Array(colors));
|
|
321
|
+
gl.activeTexture(gl.TEXTURE0);
|
|
322
|
+
gl.bindTexture(gl.TEXTURE_2D, texture);
|
|
323
|
+
// Pass data texture in (use texture unit 0):
|
|
324
|
+
gl.uniform1i(gl.getUniformLocation(contoursProgram, 'dataTexture'), 0);
|
|
325
|
+
// Pass a screen resolution uniform in:
|
|
326
|
+
gl.uniform2f(gl.getUniformLocation(contoursProgram, 'u_resolution'), width * window.devicePixelRatio, height * window.devicePixelRatio);
|
|
327
|
+
var aPos = gl.getAttribLocation(contoursProgram, 'a_pos');
|
|
328
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, contoursBuffer);
|
|
329
|
+
gl.enableVertexAttribArray(aPos);
|
|
330
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
|
|
331
|
+
gl.enable(gl.BLEND);
|
|
332
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
333
|
+
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
334
|
+
gl.disableVertexAttribArray(aPos);
|
|
335
|
+
};
|
|
336
|
+
var renderDots = function (gl, matrix) {
|
|
337
|
+
gl.useProgram(dotsProgram);
|
|
338
|
+
// Pass a matrix uniform in:
|
|
339
|
+
gl.uniformMatrix4fv(gl.getUniformLocation(dotsProgram, 'u_matrix'), false, matrix);
|
|
340
|
+
var aPos = gl.getAttribLocation(dotsProgram, 'a_pos');
|
|
341
|
+
gl.bindBuffer(gl.ARRAY_BUFFER, levelsBuffer);
|
|
342
|
+
gl.enableVertexAttribArray(aPos);
|
|
343
|
+
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 12, 0);
|
|
344
|
+
gl.enable(gl.BLEND);
|
|
345
|
+
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
346
|
+
gl.drawArrays(gl.POINTS, 0, numTriangles * 3);
|
|
347
|
+
gl.disableVertexAttribArray(aPos);
|
|
348
|
+
};
|
|
349
|
+
var render = function (gl, matrix) {
|
|
350
|
+
var _a, _b;
|
|
351
|
+
// Render is called many times while the map is panned/zoomed.
|
|
352
|
+
if (removed)
|
|
353
|
+
return; // Resources freed; ignore any trailing frame.
|
|
354
|
+
var m = map.current;
|
|
355
|
+
if (!m)
|
|
356
|
+
return;
|
|
357
|
+
var p = propsRef.current;
|
|
358
|
+
var zoom = m.getZoom();
|
|
359
|
+
if (zoom < ((_a = p.minZoom) !== null && _a !== void 0 ? _a : DEFAULT_MIN_ZOOM))
|
|
360
|
+
return;
|
|
361
|
+
if (zoom > ((_b = p.maxZoom) !== null && _b !== void 0 ? _b : DEFAULT_MAX_ZOOM))
|
|
362
|
+
return;
|
|
363
|
+
var width = m.getContainer().clientWidth;
|
|
364
|
+
var height = m.getContainer().clientHeight;
|
|
365
|
+
// Bind & clear framebuffer, then render levels into it:
|
|
366
|
+
// It is crucial to set the viewport size to match the resolution of the
|
|
367
|
+
// texture we're rendering into.
|
|
368
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo);
|
|
369
|
+
gl.viewport(0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
|
370
|
+
gl.clearColor(0, 0, 0, 0); // clear to transparent
|
|
371
|
+
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
372
|
+
renderLevels(gl, matrix);
|
|
373
|
+
// Unbind framebuffer so we're rendering to the screen:
|
|
374
|
+
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
375
|
+
// Reset the viewport size to equal the map size:
|
|
376
|
+
gl.viewport(0, 0, width * window.devicePixelRatio, height * window.devicePixelRatio);
|
|
377
|
+
renderContours(gl, matrix, width, height);
|
|
378
|
+
if (p.dots)
|
|
379
|
+
renderDots(gl, matrix);
|
|
380
|
+
};
|
|
381
|
+
// Free all WebGL resources when this generation's layer is removed (Mapbox
|
|
382
|
+
// calls this on removeLayer). gl.deleteX(null) is a safe no-op.
|
|
383
|
+
var onRemove = function (_mbMap, gl) {
|
|
384
|
+
removed = true;
|
|
385
|
+
gl.deleteProgram(levelsProgram);
|
|
386
|
+
gl.deleteProgram(contoursProgram);
|
|
387
|
+
gl.deleteProgram(dotsProgram);
|
|
388
|
+
gl.deleteBuffer(levelsBuffer);
|
|
389
|
+
gl.deleteBuffer(contoursBuffer);
|
|
390
|
+
gl.deleteFramebuffer(fbo);
|
|
391
|
+
gl.deleteTexture(texture);
|
|
392
|
+
levelsProgram = null;
|
|
393
|
+
contoursProgram = null;
|
|
394
|
+
dotsProgram = null;
|
|
395
|
+
levelsBuffer = null;
|
|
396
|
+
contoursBuffer = null;
|
|
397
|
+
fbo = null;
|
|
398
|
+
texture = null;
|
|
399
|
+
};
|
|
400
|
+
return { id: id, onAdd: onAdd, render: render, onRemove: onRemove };
|
|
401
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
402
|
+
}, [props.data]);
|
|
403
|
+
// Render-only prop changes don't rebuild GL state (render reads them live via
|
|
404
|
+
// propsRef), but the idle map needs a nudge to repaint with the new values.
|
|
59
405
|
React.useEffect(function () {
|
|
60
|
-
setTime(Date.now());
|
|
61
|
-
}, [props.levels, props.data, props.contourColor, props.contourThickness, props.gradientStops]);
|
|
62
|
-
//
|
|
63
|
-
// Convert IPoint array to polygons.
|
|
64
|
-
//
|
|
65
|
-
var getGeometry = function () {
|
|
66
406
|
var _a;
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
.filter(function (dp) { return !isNaN(dp.value); }) // Filter out any NaN values.
|
|
71
|
-
.map(function (dp) {
|
|
72
|
-
return point([dp.longitude, dp.latitude], { 'v': dp.value });
|
|
73
|
-
}));
|
|
74
|
-
var polys = tin(points, 'v');
|
|
75
|
-
/* // Calculate average side length of triangles.
|
|
76
|
-
let total = 0;
|
|
77
|
-
polys.features.forEach(p => {
|
|
78
|
-
const a = p.geometry.coordinates[0][0];
|
|
79
|
-
const b = p.geometry.coordinates[0][1];
|
|
80
|
-
const c = p.geometry.coordinates[0][2];
|
|
81
|
-
const d1 = Math.sqrt((a[0] - b[0])*(a[0]-b[0]) + (a[1] - b[1]) * (a[1] - b[1]));
|
|
82
|
-
const d2 = Math.sqrt((b[0] - c[0])*(b[0]-c[0]) + (b[1] - c[1]) * (b[1] - c[1]));
|
|
83
|
-
const d3 = Math.sqrt((a[0] - c[0])*(a[0]-c[0]) + (a[1] - c[1]) * (a[1] - c[1]));
|
|
84
|
-
const avg = (d1 + d2 + d3) / 3;
|
|
85
|
-
total += avg;
|
|
86
|
-
});
|
|
87
|
-
const avg = total / polys.features.length;
|
|
88
|
-
|
|
89
|
-
// Remove any triangles with a side of more than 2x avg
|
|
90
|
-
const factor = 4;
|
|
91
|
-
polys.features = polys.features.filter(p => {
|
|
92
|
-
const a = p.geometry.coordinates[0][0];
|
|
93
|
-
const b = p.geometry.coordinates[0][1];
|
|
94
|
-
const c = p.geometry.coordinates[0][2];
|
|
95
|
-
const d1 = Math.sqrt((a[0] - b[0])*(a[0]-b[0]) + (a[1] - b[1]) * (a[1] - b[1]));
|
|
96
|
-
const d2 = Math.sqrt((b[0] - c[0])*(b[0]-c[0]) + (b[1] - c[1]) * (b[1] - c[1]));
|
|
97
|
-
const d3 = Math.sqrt((a[0] - c[0])*(a[0]-c[0]) + (a[1] - c[1]) * (a[1] - c[1]));
|
|
98
|
-
if(d1 > factor * avg || d2 > factor * avg || d3 > factor * avg) return false;
|
|
99
|
-
return true;
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
// Remove any triangles with a long side:
|
|
103
|
-
const sidefactor = 4;
|
|
104
|
-
polys.features = polys.features.filter(p => {
|
|
105
|
-
const a = p.geometry.coordinates[0][0];
|
|
106
|
-
const b = p.geometry.coordinates[0][1];
|
|
107
|
-
const c = p.geometry.coordinates[0][2];
|
|
108
|
-
const d1 = Math.sqrt((a[0] - b[0])*(a[0]-b[0]) + (a[1] - b[1]) * (a[1] - b[1]));
|
|
109
|
-
const d2 = Math.sqrt((b[0] - c[0])*(b[0]-c[0]) + (b[1] - c[1]) * (b[1] - c[1]));
|
|
110
|
-
const d3 = Math.sqrt((a[0] - c[0])*(a[0]-c[0]) + (a[1] - c[1]) * (a[1] - c[1]));
|
|
111
|
-
if(d1 > sidefactor * d2 || d1 > sidefactor * d3 || d2 > sidefactor * d3) return false;
|
|
112
|
-
return true;
|
|
113
|
-
});*/
|
|
114
|
-
return polys;
|
|
115
|
-
};
|
|
116
|
-
//
|
|
117
|
-
// Convert a hex color (e.g. #ff0022) to an [r,g,b,a] array,
|
|
118
|
-
// where r,g,b,a are in the 0.0-1.0 range.
|
|
119
|
-
//
|
|
120
|
-
var colorToRGBA = function (color) {
|
|
121
|
-
var rgb = RgbColor.FromString(color);
|
|
122
|
-
return [rgb.red / 255.0, rgb.green / 255.0, rgb.blue / 255.0, rgb.alpha];
|
|
123
|
-
};
|
|
124
|
-
var createTexture = function (gl) {
|
|
125
|
-
texture.current = gl.createTexture();
|
|
126
|
-
gl.bindTexture(gl.TEXTURE_2D, texture.current);
|
|
127
|
-
// Define size and format of level 0:
|
|
128
|
-
var level = 0;
|
|
129
|
-
var internalFormat = gl.RGBA;
|
|
130
|
-
var border = 0;
|
|
131
|
-
var format = gl.RGBA;
|
|
132
|
-
var type = gl.UNSIGNED_BYTE;
|
|
133
|
-
gl.texImage2D(gl.TEXTURE_2D, level, internalFormat, TEXTURE_WIDTH, TEXTURE_HEIGHT, border, format, type, null);
|
|
134
|
-
// Set filtering to NEAREST so there's no interpolation:
|
|
135
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);
|
|
136
|
-
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
|
|
137
|
-
};
|
|
138
|
-
var createFrameBuffer = function (gl) {
|
|
139
|
-
// Create and bind the framebuffer:
|
|
140
|
-
fbo.current = gl.createFramebuffer();
|
|
141
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo.current);
|
|
142
|
-
// Attach the texture as the first color attachment:
|
|
143
|
-
var attachmentPoint = gl.COLOR_ATTACHMENT0;
|
|
144
|
-
gl.framebufferTexture2D(gl.FRAMEBUFFER, attachmentPoint, gl.TEXTURE_2D, texture.current, 0);
|
|
145
|
-
};
|
|
146
|
-
var createLevelsProgram = function (gl) {
|
|
147
|
-
// create a vertex shader
|
|
148
|
-
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
|
149
|
-
gl.shaderSource(vertexShader, LevelsVertexShader);
|
|
150
|
-
gl.compileShader(vertexShader);
|
|
151
|
-
// create a fragment shader
|
|
152
|
-
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
153
|
-
gl.shaderSource(fragmentShader, LevelsFragmentShader);
|
|
154
|
-
gl.compileShader(fragmentShader);
|
|
155
|
-
// link the two shaders into a WebGL program
|
|
156
|
-
levelsProgram.current = gl.createProgram();
|
|
157
|
-
gl.attachShader(levelsProgram.current, vertexShader);
|
|
158
|
-
gl.attachShader(levelsProgram.current, fragmentShader);
|
|
159
|
-
gl.linkProgram(levelsProgram.current);
|
|
160
|
-
};
|
|
161
|
-
var createContoursProgram = function (gl) {
|
|
162
|
-
// create a vertex shader
|
|
163
|
-
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
|
164
|
-
gl.shaderSource(vertexShader, ContoursVertexShader);
|
|
165
|
-
gl.compileShader(vertexShader);
|
|
166
|
-
// create a fragment shader
|
|
167
|
-
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
168
|
-
gl.shaderSource(fragmentShader, ContoursFragmentShader);
|
|
169
|
-
gl.compileShader(fragmentShader);
|
|
170
|
-
// link the two shaders into a WebGL program
|
|
171
|
-
contoursProgram.current = gl.createProgram();
|
|
172
|
-
gl.attachShader(contoursProgram.current, vertexShader);
|
|
173
|
-
gl.attachShader(contoursProgram.current, fragmentShader);
|
|
174
|
-
gl.linkProgram(contoursProgram.current);
|
|
175
|
-
};
|
|
176
|
-
var createDotsProgram = function (gl) {
|
|
177
|
-
// create a vertex shader
|
|
178
|
-
var vertexShader = gl.createShader(gl.VERTEX_SHADER);
|
|
179
|
-
gl.shaderSource(vertexShader, DotsVertexShader);
|
|
180
|
-
gl.compileShader(vertexShader);
|
|
181
|
-
// create a fragment shader
|
|
182
|
-
var fragmentShader = gl.createShader(gl.FRAGMENT_SHADER);
|
|
183
|
-
gl.shaderSource(fragmentShader, DotsFragmentShader);
|
|
184
|
-
gl.compileShader(fragmentShader);
|
|
185
|
-
// link the two shaders into a WebGL program
|
|
186
|
-
dotsProgram.current = gl.createProgram();
|
|
187
|
-
gl.attachShader(dotsProgram.current, vertexShader);
|
|
188
|
-
gl.attachShader(dotsProgram.current, fragmentShader);
|
|
189
|
-
gl.linkProgram(dotsProgram.current);
|
|
190
|
-
};
|
|
191
|
-
var onAddLayer = function (map, gl) {
|
|
192
|
-
// AddLayer is only called once.
|
|
193
|
-
if (!gl)
|
|
194
|
-
return;
|
|
195
|
-
var geometry = getGeometry();
|
|
196
|
-
var minValue = Infinity;
|
|
197
|
-
var maxValue = -Infinity;
|
|
198
|
-
var len = geometry.features.length;
|
|
199
|
-
while (len--) {
|
|
200
|
-
var value = geometry.features[len].properties['a'];
|
|
201
|
-
minValue = value < minValue ? value : minValue;
|
|
202
|
-
maxValue = value > maxValue ? value : maxValue;
|
|
203
|
-
}
|
|
204
|
-
createLevelsProgram(gl);
|
|
205
|
-
createContoursProgram(gl);
|
|
206
|
-
createDotsProgram(gl);
|
|
207
|
-
createTexture(gl);
|
|
208
|
-
createFrameBuffer(gl);
|
|
209
|
-
// Convert dataset to triangle geometry.
|
|
210
|
-
// Result is a list of v1,v2,v3, v1,v2,v3, ...
|
|
211
|
-
// where each vector has (x,y,value).
|
|
212
|
-
var points = [];
|
|
213
|
-
var LAT = 1;
|
|
214
|
-
var LON = 0;
|
|
215
|
-
numTriangles.current = geometry.features.length;
|
|
216
|
-
var deltaValue = maxValue - minValue;
|
|
217
|
-
geometry.features.map(function (feature) {
|
|
218
|
-
var coord = MercatorCoordinate.fromLngLat({ lng: feature.geometry.coordinates[0][0][LON], lat: feature.geometry.coordinates[0][0][LAT] });
|
|
219
|
-
points.push(coord.x, coord.y, (feature.properties['a'] - minValue) / deltaValue);
|
|
220
|
-
coord = MercatorCoordinate.fromLngLat({ lng: feature.geometry.coordinates[0][1][LON], lat: feature.geometry.coordinates[0][1][LAT] });
|
|
221
|
-
points.push(coord.x, coord.y, (feature.properties['b'] - minValue) / deltaValue);
|
|
222
|
-
coord = MercatorCoordinate.fromLngLat({ lng: feature.geometry.coordinates[0][2][LON], lat: feature.geometry.coordinates[0][2][LAT] });
|
|
223
|
-
points.push(coord.x, coord.y, (feature.properties['c'] - minValue) / deltaValue);
|
|
224
|
-
});
|
|
225
|
-
// Create and initialize a WebGLBuffer to store vertex data.
|
|
226
|
-
// Each element will have 3 components (x,y,value).
|
|
227
|
-
levelsBuffer.current = gl.createBuffer();
|
|
228
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, levelsBuffer.current);
|
|
229
|
-
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(points), gl.STATIC_DRAW);
|
|
230
|
-
// Create a vertex buffer with only two triangles in it, which
|
|
231
|
-
// cover the viewport. TODO: the world, it seems
|
|
232
|
-
contoursBuffer.current = gl.createBuffer();
|
|
233
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, contoursBuffer.current);
|
|
234
|
-
gl.bufferData(gl.ARRAY_BUFFER, new Float32Array([
|
|
235
|
-
0.0, 0.0, 1.0, 0.0, 1.0, 1.0,
|
|
236
|
-
0.0, 0.0, 1.0, 1.0, 0.0, 1.0
|
|
237
|
-
]), gl.STATIC_DRAW);
|
|
238
|
-
};
|
|
239
|
-
var renderLevels = function (gl, matrix) {
|
|
240
|
-
gl.useProgram(levelsProgram.current);
|
|
241
|
-
// Pass a matrix uniform in:
|
|
242
|
-
gl.uniformMatrix4fv(gl.getUniformLocation(levelsProgram.current, 'u_matrix'), false, matrix);
|
|
243
|
-
var aPos = gl.getAttribLocation(levelsProgram.current, 'a_pos');
|
|
244
|
-
var aValue = gl.getAttribLocation(levelsProgram.current, 'a_value');
|
|
245
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, levelsBuffer.current);
|
|
246
|
-
gl.enableVertexAttribArray(aPos);
|
|
247
|
-
gl.enableVertexAttribArray(aValue);
|
|
248
|
-
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 12, 0);
|
|
249
|
-
gl.vertexAttribPointer(aValue, 1, gl.FLOAT, false, 12, 8);
|
|
250
|
-
gl.enable(gl.BLEND);
|
|
251
|
-
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
252
|
-
gl.drawArrays(gl.TRIANGLES, 0, numTriangles.current * 3);
|
|
253
|
-
};
|
|
254
|
-
var renderContours = function (gl, matrix, width, height) {
|
|
255
|
-
gl.useProgram(contoursProgram.current);
|
|
256
|
-
// Pass a matrix uniform in:
|
|
257
|
-
gl.uniformMatrix4fv(gl.getUniformLocation(contoursProgram.current, 'u_matrix'), false, matrix);
|
|
258
|
-
// Pass in levels for contours:
|
|
259
|
-
gl.uniform1i(gl.getUniformLocation(contoursProgram.current, 'levels'), props.levels);
|
|
260
|
-
// Pass in contour thickness:
|
|
261
|
-
gl.uniform1f(gl.getUniformLocation(contoursProgram.current, 'u_contourThickness'), props.contourThickness);
|
|
262
|
-
// Pass in contours color:
|
|
263
|
-
var clr = colorToRGBA(props.contourColor);
|
|
264
|
-
gl.uniform4f(gl.getUniformLocation(contoursProgram.current, 'u_contourColor'), clr[0], clr[1], clr[2], clr[3]);
|
|
265
|
-
// Stops - fill up to 12 stops by using values > 1 for filler stops.
|
|
266
|
-
// e.g. [0.0, 0.5, 1.0, 2.0....] means that only the first 3 stops are used.
|
|
267
|
-
var stops = __spreadArray([], props.gradientStops.map(function (s) { return s.pos; }), true);
|
|
268
|
-
while (stops.length < 12)
|
|
269
|
-
stops.push(2.0);
|
|
270
|
-
gl.uniform1fv(gl.getUniformLocation(contoursProgram.current, 'u_gradientStops'), new Float32Array(stops));
|
|
271
|
-
var colors = props.gradientStops.map(function (s) { return colorToRGBA(s.color); }).flat();
|
|
272
|
-
gl.uniform4fv(gl.getUniformLocation(contoursProgram.current, 'u_gradientColors'), new Float32Array(colors));
|
|
273
|
-
gl.activeTexture(gl.TEXTURE0);
|
|
274
|
-
gl.bindTexture(gl.TEXTURE_2D, texture.current);
|
|
275
|
-
// Pass data texture in (use texture unit 0):
|
|
276
|
-
gl.uniform1i(gl.getUniformLocation(contoursProgram.current, "dataTexture"), 0);
|
|
277
|
-
// Pass a screen resolution uniform in:
|
|
278
|
-
gl.uniform2f(gl.getUniformLocation(contoursProgram.current, 'u_resolution'), width * window.devicePixelRatio, height * window.devicePixelRatio);
|
|
279
|
-
var aPos = gl.getAttribLocation(contoursProgram.current, 'a_pos');
|
|
280
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, contoursBuffer.current);
|
|
281
|
-
gl.enableVertexAttribArray(aPos);
|
|
282
|
-
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 0, 0);
|
|
283
|
-
gl.enable(gl.BLEND);
|
|
284
|
-
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
285
|
-
gl.drawArrays(gl.TRIANGLES, 0, 6);
|
|
286
|
-
};
|
|
287
|
-
var renderDots = function (gl, matrix) {
|
|
288
|
-
gl.useProgram(dotsProgram.current);
|
|
289
|
-
// Pass a matrix uniform in:
|
|
290
|
-
gl.uniformMatrix4fv(gl.getUniformLocation(dotsProgram.current, 'u_matrix'), false, matrix);
|
|
291
|
-
var aPos = gl.getAttribLocation(dotsProgram.current, 'a_pos');
|
|
292
|
-
gl.bindBuffer(gl.ARRAY_BUFFER, levelsBuffer.current);
|
|
293
|
-
gl.enableVertexAttribArray(aPos);
|
|
294
|
-
gl.vertexAttribPointer(aPos, 2, gl.FLOAT, false, 12, 0);
|
|
295
|
-
gl.enable(gl.BLEND);
|
|
296
|
-
gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA);
|
|
297
|
-
gl.drawArrays(gl.POINTS, 0, numTriangles.current * 3);
|
|
298
|
-
};
|
|
299
|
-
var onRender = function (gl, matrix, zoom, width, height) {
|
|
300
|
-
// Render is called many times while the map is panned/zoomed.
|
|
301
|
-
// You cannot have access to the map though.
|
|
302
|
-
if (zoom < props.minZoom)
|
|
303
|
-
return;
|
|
304
|
-
if (zoom > props.maxZoom)
|
|
305
|
-
return;
|
|
306
|
-
// Bind & clear framebuffer, then render levels into it:
|
|
307
|
-
// It is crucial to set the viewport size to match the resolution of the
|
|
308
|
-
// texture we're rendering into.
|
|
309
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, fbo.current);
|
|
310
|
-
gl.viewport(0, 0, TEXTURE_WIDTH, TEXTURE_HEIGHT);
|
|
311
|
-
gl.clearColor(0, 0, 0, 0); // clear to transparent
|
|
312
|
-
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
|
|
313
|
-
renderLevels(gl, matrix);
|
|
314
|
-
// Unbind framebuffer so we're rendering to the screen:
|
|
315
|
-
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
|
|
316
|
-
// Reset the viewport size to equal the map size:
|
|
317
|
-
gl.viewport(0, 0, width * window.devicePixelRatio, height * window.devicePixelRatio);
|
|
318
|
-
renderContours(gl, matrix, width, height);
|
|
319
|
-
if (props.dots)
|
|
320
|
-
renderDots(gl, matrix);
|
|
321
|
-
};
|
|
322
|
-
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); } }));
|
|
407
|
+
(_a = map.current) === null || _a === void 0 ? void 0 : _a.triggerRepaint();
|
|
408
|
+
}, [map, props.levels, props.contourColor, props.contourThickness, props.gradientStops, props.minZoom, props.maxZoom, props.dots]);
|
|
409
|
+
return (React.createElement(Layer, { id: layer.id, key: layer.id, type: "custom", beforeId: "overlay", onAdd: layer.onAdd, onRemove: layer.onRemove, render: layer.render }));
|
|
323
410
|
};
|
|
324
411
|
/**
|
|
325
412
|
* A custom WebGL map layer that renders interpolated data with optional contour lines.
|
|
@@ -370,10 +457,10 @@ var InterpolationLayerBase = function (props) {
|
|
|
370
457
|
* - Values are automatically normalized to 0-1 range
|
|
371
458
|
*/
|
|
372
459
|
var InterpolationLayer = function (_a) {
|
|
373
|
-
var _b = _a.levels, levels = _b === void 0 ?
|
|
460
|
+
var _b = _a.levels, levels = _b === void 0 ? DEFAULT_LEVELS : _b, _c = _a.contourColor, contourColor = _c === void 0 ? DEFAULT_CONTOUR_COLOR : _c, _d = _a.contourThickness, contourThickness = _d === void 0 ? DEFAULT_CONTOUR_THICKNESS : _d, _e = _a.gradientStops, gradientStops = _e === void 0 ? [
|
|
374
461
|
{ pos: 0.0, color: '#0000ffff' },
|
|
375
462
|
{ pos: 1.0, color: '#000000ff' }
|
|
376
|
-
] : _e, _f = _a.minZoom, minZoom = _f === void 0 ?
|
|
463
|
+
] : _e, _f = _a.minZoom, minZoom = _f === void 0 ? DEFAULT_MIN_ZOOM : _f, _g = _a.maxZoom, maxZoom = _g === void 0 ? DEFAULT_MAX_ZOOM : _g, _h = _a.dots, dots = _h === void 0 ? false : _h, props = __rest(_a, ["levels", "contourColor", "contourThickness", "gradientStops", "minZoom", "maxZoom", "dots"]);
|
|
377
464
|
return React.createElement(InterpolationLayerBase, __assign({ levels: levels, contourColor: contourColor, contourThickness: contourThickness, gradientStops: gradientStops, minZoom: minZoom, maxZoom: maxZoom, dots: dots }, props));
|
|
378
465
|
};
|
|
379
466
|
InterpolationLayer.displayName = 'InterpolationLayer';
|