@xyo-network/react-map 2.64.0 → 2.64.1

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.
Files changed (130) hide show
  1. package/dist/browser/AnimatedHeatMapSettings.js +56 -3
  2. package/dist/browser/AnimatedHeatMapSettings.js.map +1 -1
  3. package/dist/browser/Colors/index.js +0 -1
  4. package/dist/browser/Colors/index.js.map +1 -1
  5. package/dist/browser/Components/AnimatedHeatMap.js +623 -10
  6. package/dist/browser/Components/AnimatedHeatMap.js.map +1 -1
  7. package/dist/browser/Components/AnimatedHeatMapLoaded.js +864 -13
  8. package/dist/browser/Components/AnimatedHeatMapLoaded.js.map +1 -1
  9. package/dist/browser/Components/HeatMapSettings.js +56 -3
  10. package/dist/browser/Components/HeatMapSettings.js.map +1 -1
  11. package/dist/browser/Components/LayerAnimator.js +5 -4
  12. package/dist/browser/Components/LayerAnimator.js.map +1 -1
  13. package/dist/browser/Components/Legend.js +32 -7
  14. package/dist/browser/Components/Legend.js.map +1 -1
  15. package/dist/browser/Components/Legends/ColorGradient.js +3 -2
  16. package/dist/browser/Components/Legends/ColorGradient.js.map +1 -1
  17. package/dist/browser/Components/Legends/index.js +25 -1
  18. package/dist/browser/Components/Legends/index.js.map +1 -1
  19. package/dist/browser/Components/MapBox.js +66 -12
  20. package/dist/browser/Components/MapBox.js.map +1 -1
  21. package/dist/browser/Components/MapBoxHeat.js +151 -6
  22. package/dist/browser/Components/MapBoxHeat.js.map +1 -1
  23. package/dist/browser/Components/MapBoxPoints.js +207 -14
  24. package/dist/browser/Components/MapBoxPoints.js.map +1 -1
  25. package/dist/browser/Components/MapSettingsComponents/Setting.js +16 -3
  26. package/dist/browser/Components/MapSettingsComponents/Setting.js.map +1 -1
  27. package/dist/browser/Components/MapSettingsComponents/SettingsBox.js +38 -6
  28. package/dist/browser/Components/MapSettingsComponents/SettingsBox.js.map +1 -1
  29. package/dist/browser/Components/MapSettingsComponents/index.js +50 -2
  30. package/dist/browser/Components/MapSettingsComponents/index.js.map +1 -1
  31. package/dist/browser/Components/index.js +1084 -11
  32. package/dist/browser/Components/index.js.map +1 -1
  33. package/dist/browser/Contexts/HeatMapInitializer/Context.js +2 -1
  34. package/dist/browser/Contexts/HeatMapInitializer/Context.js.map +1 -1
  35. package/dist/browser/Contexts/HeatMapInitializer/Provider.js +235 -14
  36. package/dist/browser/Contexts/HeatMapInitializer/Provider.js.map +1 -1
  37. package/dist/browser/Contexts/HeatMapInitializer/index.js +294 -3
  38. package/dist/browser/Contexts/HeatMapInitializer/index.js.map +1 -1
  39. package/dist/browser/Contexts/HeatMapInitializer/useHeatMapInitializer.js +8 -2
  40. package/dist/browser/Contexts/HeatMapInitializer/useHeatMapInitializer.js.map +1 -1
  41. package/dist/browser/Contexts/MapBoxInstance/Context.js +2 -1
  42. package/dist/browser/Contexts/MapBoxInstance/Context.js.map +1 -1
  43. package/dist/browser/Contexts/MapBoxInstance/Provider.js +9 -3
  44. package/dist/browser/Contexts/MapBoxInstance/Provider.js.map +1 -1
  45. package/dist/browser/Contexts/MapBoxInstance/index.js +35 -3
  46. package/dist/browser/Contexts/MapBoxInstance/index.js.map +1 -1
  47. package/dist/browser/Contexts/MapBoxInstance/useMapBoxInstance.js +8 -2
  48. package/dist/browser/Contexts/MapBoxInstance/useMapBoxInstance.js.map +1 -1
  49. package/dist/browser/Contexts/MapSettings/Context.js +2 -1
  50. package/dist/browser/Contexts/MapSettings/Context.js.map +1 -1
  51. package/dist/browser/Contexts/MapSettings/Provider.js +117 -5
  52. package/dist/browser/Contexts/MapSettings/Provider.js.map +1 -1
  53. package/dist/browser/Contexts/MapSettings/index.js +148 -3
  54. package/dist/browser/Contexts/MapSettings/index.js.map +1 -1
  55. package/dist/browser/Contexts/MapSettings/useMapSettings.js +8 -2
  56. package/dist/browser/Contexts/MapSettings/useMapSettings.js.map +1 -1
  57. package/dist/browser/Contexts/MapboxAccessToken/Context.js +2 -1
  58. package/dist/browser/Contexts/MapboxAccessToken/Context.js.map +1 -1
  59. package/dist/browser/Contexts/MapboxAccessToken/Provider.js +9 -3
  60. package/dist/browser/Contexts/MapboxAccessToken/Provider.js.map +1 -1
  61. package/dist/browser/Contexts/MapboxAccessToken/index.js +22 -4
  62. package/dist/browser/Contexts/MapboxAccessToken/index.js.map +1 -1
  63. package/dist/browser/Contexts/MapboxAccessToken/use.js +8 -2
  64. package/dist/browser/Contexts/MapboxAccessToken/use.js.map +1 -1
  65. package/dist/browser/Contexts/index.js +459 -4
  66. package/dist/browser/Contexts/index.js.map +1 -1
  67. package/dist/browser/Layers/Builders/LocationHeatMapLayerBuilder.js +110 -6
  68. package/dist/browser/Layers/Builders/LocationHeatMapLayerBuilder.js.map +1 -1
  69. package/dist/browser/Layers/Builders/LocationHeatMapLayerBuilderAnimated.js +36 -4
  70. package/dist/browser/Layers/Builders/LocationHeatMapLayerBuilderAnimated.js.map +1 -1
  71. package/dist/browser/Layers/Builders/LocationPointsMapLayerBuilder.js +40 -4
  72. package/dist/browser/Layers/Builders/LocationPointsMapLayerBuilder.js.map +1 -1
  73. package/dist/browser/Layers/Builders/index.js +205 -3
  74. package/dist/browser/Layers/Builders/index.js.map +1 -1
  75. package/dist/browser/Layers/CircleLayer.js +3 -2
  76. package/dist/browser/Layers/CircleLayer.js.map +1 -1
  77. package/dist/browser/Layers/Configs/HeatMapFillLayerConfig.js +2 -1
  78. package/dist/browser/Layers/Configs/HeatMapFillLayerConfig.js.map +1 -1
  79. package/dist/browser/Layers/Configs/HeatMapLineLayerConfig.js +2 -1
  80. package/dist/browser/Layers/Configs/HeatMapLineLayerConfig.js.map +1 -1
  81. package/dist/browser/Layers/Configs/HeatMapSymbolLayerConfig.js +2 -1
  82. package/dist/browser/Layers/Configs/HeatMapSymbolLayerConfig.js.map +1 -1
  83. package/dist/browser/Layers/Configs/LocationPointLayerConfig.js +2 -1
  84. package/dist/browser/Layers/Configs/LocationPointLayerConfig.js.map +1 -1
  85. package/dist/browser/Layers/Configs/index.js +62 -4
  86. package/dist/browser/Layers/Configs/index.js.map +1 -1
  87. package/dist/browser/Layers/FillLayer.js +3 -2
  88. package/dist/browser/Layers/FillLayer.js.map +1 -1
  89. package/dist/browser/Layers/LineLayer.js +3 -2
  90. package/dist/browser/Layers/LineLayer.js.map +1 -1
  91. package/dist/browser/Layers/SymbolLayer.js +3 -2
  92. package/dist/browser/Layers/SymbolLayer.js.map +1 -1
  93. package/dist/browser/Layers/index.js +213 -7
  94. package/dist/browser/Layers/index.js.map +1 -1
  95. package/dist/browser/MapBoxClasses/MapBase.js +3 -2
  96. package/dist/browser/MapBoxClasses/MapBase.js.map +1 -1
  97. package/dist/browser/MapBoxClasses/MapHeat.js +41 -11
  98. package/dist/browser/MapBoxClasses/MapHeat.js.map +1 -1
  99. package/dist/browser/MapBoxClasses/MapPoints.js +33 -3
  100. package/dist/browser/MapBoxClasses/MapPoints.js.map +1 -1
  101. package/dist/browser/MapBoxClasses/MapSettings.js +6 -5
  102. package/dist/browser/MapBoxClasses/MapSettings.js.map +1 -1
  103. package/dist/browser/MapBoxClasses/index.js +288 -4
  104. package/dist/browser/MapBoxClasses/index.js.map +1 -1
  105. package/dist/browser/Settings/DefaultMapSettings.js +2 -1
  106. package/dist/browser/Settings/DefaultMapSettings.js.map +1 -1
  107. package/dist/browser/Settings/index.js +55 -2
  108. package/dist/browser/Settings/index.js.map +1 -1
  109. package/dist/browser/hooks/index.js +156 -5
  110. package/dist/browser/hooks/index.js.map +1 -1
  111. package/dist/browser/hooks/useDynamicMapResize.js +2 -1
  112. package/dist/browser/hooks/useDynamicMapResize.js.map +1 -1
  113. package/dist/browser/hooks/useDynamicPositioning.js +7 -6
  114. package/dist/browser/hooks/useDynamicPositioning.js.map +1 -1
  115. package/dist/browser/hooks/useFindHashes.js +4 -3
  116. package/dist/browser/hooks/useFindHashes.js.map +1 -1
  117. package/dist/browser/hooks/useHeatMapColors.js +2 -1
  118. package/dist/browser/hooks/useHeatMapColors.js.map +1 -1
  119. package/dist/browser/hooks/useQuadKeyPayloadsToFeatures.js +4 -3
  120. package/dist/browser/hooks/useQuadKeyPayloadsToFeatures.js.map +1 -1
  121. package/dist/browser/index.js +1298 -10
  122. package/dist/browser/index.js.map +1 -1
  123. package/dist/browser/lib/MapStyle.js +1 -0
  124. package/dist/browser/lib/MapStyle.js.map +1 -1
  125. package/dist/browser/lib/index.js +13 -2
  126. package/dist/browser/lib/index.js.map +1 -1
  127. package/dist/browser/types/index.js +0 -1
  128. package/dist/browser/types/index.js.map +1 -1
  129. package/dist/docs.json +296 -296
  130. package/package.json +14 -14
@@ -1,11 +1,624 @@
1
- import { jsx } from "react/jsx-runtime";
1
+ // src/Components/AnimatedHeatMap.tsx
2
2
  import { darken, useTheme } from "@mui/material";
3
+ import { FlexCol as FlexCol2 } from "@xylabs/react-flexbox";
4
+ import { useState as useState7 } from "react";
5
+
6
+ // src/Contexts/HeatMapInitializer/Provider.tsx
7
+ import { forget as forget2 } from "@xylabs/forget";
8
+ import { useEffect as useEffect5, useState as useState5 } from "react";
9
+
10
+ // src/hooks/useDynamicMapResize.tsx
11
+ import { useEffect, useMemo, useState } from "react";
12
+ var useDynamicMapResize = (mapContainerRef, mapCanvasRef, mapInstance, active = true) => {
13
+ const [dependenciesReady, setDependenciesReady] = useState(false);
14
+ const resizer = useMemo(
15
+ () => new ResizeObserver(() => {
16
+ const width = mapContainerRef.current?.getBoundingClientRect().width;
17
+ if (width && mapCanvasRef.current) {
18
+ mapCanvasRef.current.style.width = `${width}px`;
19
+ setTimeout(() => mapInstance?.resize());
20
+ }
21
+ }),
22
+ [mapCanvasRef, mapContainerRef, mapInstance]
23
+ );
24
+ useEffect(() => {
25
+ const dependenciesReady2 = !!(active && mapInstance && mapContainerRef?.current && mapCanvasRef.current);
26
+ setDependenciesReady(dependenciesReady2);
27
+ }, [active, mapCanvasRef, mapContainerRef, mapInstance]);
28
+ useEffect(() => {
29
+ if (dependenciesReady) {
30
+ if (mapContainerRef.current) {
31
+ resizer.observe(mapContainerRef.current);
32
+ }
33
+ return () => {
34
+ resizer.disconnect();
35
+ };
36
+ }
37
+ }, [active, dependenciesReady, mapCanvasRef, mapContainerRef, mapInstance, resizer]);
38
+ };
39
+
40
+ // src/hooks/useDynamicPositioning.tsx
41
+ import { useWindowSize } from "@xylabs/react-shared";
42
+ import { useEffect as useEffect2, useState as useState2 } from "react";
43
+ var defaultZoom = 1.6;
44
+ var defaultAspectRatioRange = [0.5, 2];
45
+ var latRange = [0.9121644205263664, 1.71785031559439];
46
+ var lngRange = [-81.4742014851959, 12.788958675506933];
47
+ var linearInterpolate = (aspectRatio, degreeRange, aspectRatioRange) => {
48
+ const [degreeMin, degreeMax] = degreeRange;
49
+ const [aspectRatioMin, aspectRatioMax] = aspectRatioRange || defaultAspectRatioRange;
50
+ const aspectRatioRangeSpan = aspectRatioMax - aspectRatioMin;
51
+ const degreeRangeSpan = degreeMax - degreeMin;
52
+ const percent = (aspectRatio - aspectRatioMin) / aspectRatioRangeSpan;
53
+ const scaledDegree = percent * degreeRangeSpan + degreeMin;
54
+ return scaledDegree;
55
+ };
56
+ var useDynamicPositioning = () => {
57
+ const [options, setOptions] = useState2({});
58
+ const { width, height } = useWindowSize();
59
+ useEffect2(() => {
60
+ if (width && height) {
61
+ const aspectRatio = width / height;
62
+ setOptions({
63
+ center: [linearInterpolate(aspectRatio, lngRange), linearInterpolate(aspectRatio, latRange)],
64
+ zoom: defaultZoom
65
+ });
66
+ }
67
+ }, [height, width]);
68
+ return { options };
69
+ };
70
+
71
+ // src/MapBoxClasses/MapBase.ts
72
+ import { assertEx } from "@xylabs/assert";
73
+ import { GeoJson } from "@xyo-network/sdk-geo";
74
+ var MapBase = class {
75
+ _config;
76
+ constructor(config) {
77
+ this._config = { requestLocation: true, zoom: 2, ...config };
78
+ }
79
+ get isMapReady() {
80
+ return !!this._config.map;
81
+ }
82
+ initializeMapSource(layer) {
83
+ const getSource = () => {
84
+ const featuresCollection = GeoJson.featureCollection(this._config.features);
85
+ return GeoJson.featuresSource(featuresCollection);
86
+ };
87
+ const existingSource = this._config.map.getSource(layer.source);
88
+ const source = getSource();
89
+ if (existingSource) {
90
+ existingSource.setData(assertEx(source.data));
91
+ } else {
92
+ this._config.map.addSource(layer.source, source);
93
+ }
94
+ layer.update(this._config.map, true);
95
+ return this;
96
+ }
97
+ };
98
+
99
+ // src/MapBoxClasses/MapHeat.ts
100
+ import { assertEx as assertEx2 } from "@xylabs/assert";
101
+ import { delay } from "@xylabs/delay";
102
+ import { forget } from "@xylabs/forget";
103
+ import { GeoJson as GeoJson2 } from "@xyo-network/sdk-geo";
104
+ import { LngLatBounds } from "mapbox-gl";
105
+ var MapHeat = class extends MapBase {
106
+ static animationStarted = false;
107
+ config;
108
+ constructor(config) {
109
+ super(config);
110
+ this.config = config;
111
+ }
112
+ static initialMapPositioning(options, map, features, initialBounds) {
113
+ if (!features) {
114
+ return;
115
+ }
116
+ let bounds;
117
+ if (initialBounds) {
118
+ bounds = initialBounds;
119
+ } else {
120
+ bounds = new LngLatBounds();
121
+ features.forEach((feature) => {
122
+ feature.geometry.coordinates.forEach((coordinates) => {
123
+ coordinates.forEach((position) => {
124
+ bounds.extend(position);
125
+ });
126
+ });
127
+ });
128
+ }
129
+ map.setCenter(bounds.getCenter());
130
+ map.fitBounds(bounds, options);
131
+ return this;
132
+ }
133
+ static async initializeAnimatedHeatMapSource(layers, featureSet, map, startColor, endColor) {
134
+ this.animationStarted = true;
135
+ let layerTick = 0;
136
+ let sourceTick = 0;
137
+ const sources = featureSet.map((feature) => {
138
+ const featuresCollection = GeoJson2.featureCollection(feature);
139
+ return GeoJson2.featuresSource(featuresCollection);
140
+ });
141
+ this.updateLayer(map, layers[0], sources[0]);
142
+ this.updateLayer(map, layers[1], sources[1]);
143
+ layers.forEach((layer) => {
144
+ map.setPaintProperty(layer.id, "fill-opacity", 0);
145
+ });
146
+ const frameLength = 3e3;
147
+ const initialPad = 0.5;
148
+ const factor = 10;
149
+ const steps = 30;
150
+ const stepLength = frameLength / steps;
151
+ const lowUsageColor = startColor ?? "#FFB3B3";
152
+ const highUsageColor = endColor ?? "#FF0000";
153
+ const dynamicFillColor = (factor2, initialPad2, i) => {
154
+ const sinFade = Math.sin(i / steps * Math.PI / 2);
155
+ const cosFade = Math.cos(i / steps * Math.PI / 2);
156
+ const divisor = factor2 + factor2 * sinFade;
157
+ const offset = initialPad2 * cosFade;
158
+ return [
159
+ "let",
160
+ "density",
161
+ ["+", ["/", ["number", ["get", "value"]], divisor], offset],
162
+ ["interpolate", ["linear"], ["var", "density"], 0, lowUsageColor, 0.5, highUsageColor]
163
+ ];
164
+ };
165
+ const fadedIn = layers.map((_) => false);
166
+ const fadeIn = async (id, index) => {
167
+ for (let i = steps; i >= 1; i--) {
168
+ map.setPaintProperty(id, "fill-color", dynamicFillColor(factor, initialPad, i * (180 / stepLength)));
169
+ await delay(stepLength);
170
+ }
171
+ fadedIn[index] = true;
172
+ };
173
+ const fadeOut = async (id, index) => {
174
+ for (let i = 1; i <= steps; i++) {
175
+ map.setPaintProperty(id, "fill-color", dynamicFillColor(factor, initialPad, i * (180 / stepLength)));
176
+ await delay(stepLength);
177
+ }
178
+ fadedIn[index] = false;
179
+ };
180
+ let started = false;
181
+ const startAnimation = async () => {
182
+ assertEx2(!started, "Animation Already Started");
183
+ started = true;
184
+ while (this.animationStarted) {
185
+ const upLayer = layerTick % layers.length;
186
+ const downLayer = (layerTick + 1) % layers.length;
187
+ const incomingSource = sourceTick % featureSet.length;
188
+ const outgoingSource = (sourceTick + 1) % featureSet.length;
189
+ if (fadedIn[upLayer]) {
190
+ this.updateLayer(map, layers[upLayer], sources[incomingSource]);
191
+ forget(fadeOut(layers[upLayer].id, upLayer));
192
+ }
193
+ if (!fadedIn[downLayer]) {
194
+ this.updateLayer(map, layers[downLayer], sources[outgoingSource]);
195
+ forget(fadeIn(layers[downLayer].id, downLayer));
196
+ }
197
+ while ((fadedIn[upLayer] || !fadedIn[downLayer]) && this.animationStarted) {
198
+ await delay(1e3);
199
+ }
200
+ layerTick++;
201
+ sourceTick++;
202
+ }
203
+ };
204
+ await startAnimation();
205
+ }
206
+ static updateLayer(map, layer, source) {
207
+ const existingSource = map.getSource(layer.source);
208
+ if (existingSource && source.data) {
209
+ existingSource.setData(source.data);
210
+ } else if (source) {
211
+ map.addSource(layer.source, source);
212
+ }
213
+ layer.update(map, true);
214
+ }
215
+ // Build layers each with the same features
216
+ initializeHeatMapSource(layers) {
217
+ const getSource = (_) => {
218
+ const featuresCollection = GeoJson2.featureCollection(this.config.features);
219
+ return GeoJson2.featuresSource(featuresCollection);
220
+ };
221
+ layers.forEach((layer, index) => {
222
+ const existingSource = this.config.map.getSource(layer.source);
223
+ const source = getSource(index);
224
+ if (existingSource) {
225
+ existingSource.setData(assertEx2(source.data));
226
+ } else {
227
+ this.config.map.addSource(layer.source, source);
228
+ }
229
+ layer.update(this.config.map, true);
230
+ });
231
+ return this;
232
+ }
233
+ };
234
+
235
+ // src/MapBoxClasses/MapSettings.ts
236
+ import { GeolocateControl, NavigationControl } from "mapbox-gl";
237
+ var MapSettings = class _MapSettings {
238
+ static geoLocateControl;
239
+ static mapListeners = {
240
+ logData: (ev, map) => {
241
+ const target = map || ev?.target;
242
+ if (target) {
243
+ console.log("zoom", target.getZoom());
244
+ console.log("center", target.getCenter());
245
+ }
246
+ }
247
+ };
248
+ static navControl;
249
+ static requestLocation;
250
+ static toggleControls(value, map, zoom, requestLocation) {
251
+ if (value) {
252
+ _MapSettings.addControls(map, zoom, requestLocation);
253
+ } else {
254
+ _MapSettings.removeControls(map);
255
+ }
256
+ return this;
257
+ }
258
+ static toggleDebugLayer(value, map, layerName) {
259
+ const debugLayer = map.getLayer(layerName);
260
+ if (debugLayer) {
261
+ if (value) {
262
+ map.setLayoutProperty(layerName, "visibility", "visible");
263
+ } else {
264
+ map.setLayoutProperty(layerName, "visibility", "none");
265
+ }
266
+ }
267
+ return this;
268
+ }
269
+ static toggleDebugLogging(value, map) {
270
+ const debugEvents = ["resize", "zoomend", "dragend"];
271
+ if (value) {
272
+ this.mapListeners.logData(void 0, map);
273
+ debugEvents.forEach((event) => map.on(event, this.mapListeners.logData));
274
+ } else {
275
+ debugEvents.forEach((event) => map.off(event, this.mapListeners.logData));
276
+ }
277
+ }
278
+ static toggleScrollToZoom(value, map) {
279
+ if (value) {
280
+ map.scrollZoom.enable();
281
+ } else {
282
+ map.scrollZoom.disable();
283
+ }
284
+ return this;
285
+ }
286
+ static updateSettings(config) {
287
+ const { settings, map, zoom, requestLocation, debugLayerName = "" } = config;
288
+ const { scrollToZoom, enableControls, debugLayer, debugLogging } = settings;
289
+ _MapSettings.toggleControls(enableControls?.value, map, zoom, requestLocation).toggleScrollToZoom(scrollToZoom?.value, map).toggleDebugLayer(debugLayer?.value, map, debugLayerName).toggleDebugLogging(debugLogging.value, map);
290
+ }
291
+ // Needs to be static so we ensure controls are only instantiated once
292
+ static addControls(map, zoom, requestLocation) {
293
+ const geolocateControl = new GeolocateControl({
294
+ fitBoundsOptions: {
295
+ zoom: zoom || 2
296
+ },
297
+ positionOptions: {
298
+ enableHighAccuracy: true
299
+ },
300
+ trackUserLocation: true
301
+ });
302
+ const navControl = new NavigationControl({
303
+ showCompass: false
304
+ });
305
+ this.geoLocateControl = this.geoLocateControl || geolocateControl;
306
+ this.navControl = this.navControl || navControl;
307
+ if (!map.hasControl(this.geoLocateControl)) {
308
+ if (requestLocation) {
309
+ map.addControl(this.geoLocateControl);
310
+ }
311
+ }
312
+ if (!map.hasControl(this.navControl)) {
313
+ map.addControl(this.navControl, "top-left");
314
+ }
315
+ return this;
316
+ }
317
+ static removeControls(map) {
318
+ if (this.geoLocateControl && map.hasControl(this.geoLocateControl)) {
319
+ if (this.requestLocation) {
320
+ map.removeControl(this.geoLocateControl);
321
+ }
322
+ }
323
+ if (this.navControl && map.hasControl(this.navControl)) {
324
+ map.removeControl(this.navControl);
325
+ }
326
+ return this;
327
+ }
328
+ };
329
+
330
+ // src/Contexts/MapBoxInstance/Provider.tsx
331
+ import { useEffect as useEffect3, useState as useState3 } from "react";
332
+
333
+ // src/Contexts/MapBoxInstance/Context.ts
334
+ import { createContext } from "react";
335
+ var MapBoxInstanceContext = createContext({});
336
+
337
+ // src/Contexts/MapBoxInstance/Provider.tsx
338
+ import { jsx } from "react/jsx-runtime";
339
+ var MapBoxInstanceProvider = ({ children }) => {
340
+ const [map, setMapBoxInstance] = useState3();
341
+ const [mapInitialized, setMapInitialized] = useState3(false);
342
+ const value = { map, mapInitialized, setMapBoxInstance };
343
+ useEffect3(() => {
344
+ if (!mapInitialized && map) {
345
+ map?.on("load", () => {
346
+ setMapInitialized(true);
347
+ });
348
+ }
349
+ }, [map, mapInitialized, setMapInitialized]);
350
+ return /* @__PURE__ */ jsx(MapBoxInstanceContext.Provider, { value, children });
351
+ };
352
+
353
+ // src/Contexts/MapBoxInstance/useMapBoxInstance.tsx
354
+ import { assertEx as assertEx3 } from "@xylabs/assert";
355
+ import { useContext } from "react";
356
+ var useMapBoxInstance = () => {
357
+ const context = useContext(MapBoxInstanceContext);
358
+ assertEx3("map" in context, "useMapBoxInstance must be used within a MapBoxInstanceContext");
359
+ return context;
360
+ };
361
+
362
+ // src/Contexts/MapSettings/Provider.tsx
363
+ import { useEffect as useEffect4, useState as useState4 } from "react";
364
+
365
+ // src/Contexts/MapSettings/Context.ts
366
+ import { createContext as createContext2 } from "react";
367
+ var MapSettingsContext = createContext2({});
368
+
369
+ // src/Contexts/MapSettings/Provider.tsx
370
+ import { jsx as jsx2 } from "react/jsx-runtime";
371
+ var MapSettingsProvider = ({
372
+ children,
373
+ debugLayerName,
374
+ defaultMapSettings,
375
+ requestLocation,
376
+ zoom = 1
377
+ }) => {
378
+ const [mapSettings, setMapSettings] = useState4(defaultMapSettings || {});
379
+ const { map, mapInitialized } = useMapBoxInstance();
380
+ const value = {
381
+ mapSettings,
382
+ setMapSettings
383
+ };
384
+ useEffect4(() => {
385
+ if (mapSettings && map && mapInitialized) {
386
+ MapSettings.updateSettings({ debugLayerName, map, requestLocation, settings: mapSettings, zoom });
387
+ }
388
+ }, [debugLayerName, map, mapInitialized, mapSettings, requestLocation, zoom]);
389
+ return /* @__PURE__ */ jsx2(MapSettingsContext.Provider, { value, children });
390
+ };
391
+
392
+ // src/Contexts/MapSettings/useMapSettings.tsx
393
+ import { useContext as useContext2 } from "react";
394
+ var useMapSettings = () => {
395
+ const context = useContext2(MapSettingsContext);
396
+ return context;
397
+ };
398
+
399
+ // src/Contexts/HeatMapInitializer/Context.ts
400
+ import { createContext as createContext3 } from "react";
401
+ var HeatMapInitializerContext = createContext3({});
402
+
403
+ // src/Contexts/HeatMapInitializer/Provider.tsx
404
+ import { jsx as jsx3 } from "react/jsx-runtime";
405
+ var HeatMapInitializerProvider = ({
406
+ children,
407
+ featureSets,
408
+ featureSetsLayers,
409
+ features,
410
+ fitToPadding,
411
+ heatMapColorProps,
412
+ layers,
413
+ zoom
414
+ }) => {
415
+ const [mapHeat, setMapHeat] = useState5();
416
+ const { options } = useDynamicPositioning();
417
+ const { mapSettings } = useMapSettings();
418
+ const { map, mapInitialized } = useMapBoxInstance();
419
+ const value = {
420
+ MapHeat: mapHeat,
421
+ heatMapColorProps
422
+ };
423
+ useEffect5(() => {
424
+ if (mapInitialized && featureSets?.length && featureSets[0].length && map && featureSetsLayers?.length) {
425
+ const { lowUsageColor, highUsageColor } = heatMapColorProps;
426
+ forget2(MapHeat.initializeAnimatedHeatMapSource(featureSetsLayers, featureSets, map, lowUsageColor, highUsageColor));
427
+ }
428
+ return () => {
429
+ MapHeat.animationStarted = false;
430
+ };
431
+ }, [featureSets, featureSetsLayers, mapInitialized, map, heatMapColorProps]);
432
+ useEffect5(() => {
433
+ if (mapHeat && mapInitialized && features?.length && layers?.length) {
434
+ mapHeat.initializeHeatMapSource(layers);
435
+ }
436
+ }, [mapHeat, features?.length, layers, mapInitialized]);
437
+ useEffect5(() => {
438
+ if (mapInitialized) {
439
+ const { fitToPoints } = mapSettings || {};
440
+ if (map) {
441
+ if (fitToPoints?.value === true) {
442
+ MapHeat.initialMapPositioning({ padding: fitToPadding }, map, features);
443
+ } else if (options.zoom && options.center) {
444
+ map.setZoom(options.zoom);
445
+ map.setCenter(options.center);
446
+ }
447
+ }
448
+ }
449
+ }, [mapHeat, map, mapSettings, fitToPadding, options, mapInitialized, features]);
450
+ useEffect5(() => {
451
+ if (map && features?.length) {
452
+ setMapHeat(new MapHeat({ features, map, zoom }));
453
+ }
454
+ }, [map, features, zoom]);
455
+ return /* @__PURE__ */ jsx3(HeatMapInitializerContext.Provider, { value, children });
456
+ };
457
+
458
+ // src/Layers/Configs/HeatMapFillLayerConfig.ts
459
+ var HeatMapFillLayerConfig = (color) => ({
460
+ paint: {
461
+ "fill-color": color,
462
+ "fill-opacity": [
463
+ "let",
464
+ "density",
465
+ ["+", ["/", ["number", ["get", "value"]], 4], 0.125],
466
+ ["interpolate", ["linear"], ["var", "density"], 0.8, ["var", "density"], 1, 0.85]
467
+ ]
468
+ }
469
+ });
470
+
471
+ // src/Layers/FillLayer.ts
472
+ import { LayerBase } from "@xyo-network/sdk-geo";
473
+ var FillLayerBuilder = class extends LayerBase {
474
+ FillLayerOptions;
475
+ // ensures this class passes for `AnyLayer` type in MapBox
476
+ type = "fill";
477
+ constructor(id, source, FillLayerOptions) {
478
+ super(id, source);
479
+ this.FillLayerOptions = FillLayerOptions || { id: this.id, source: this.source };
480
+ }
481
+ buildLayer() {
482
+ return {
483
+ ...this.FillLayerOptions,
484
+ id: this.id,
485
+ source: this.source,
486
+ type: this.type
487
+ };
488
+ }
489
+ };
490
+
491
+ // src/Layers/Builders/LocationHeatMapLayerBuilder.ts
492
+ var MapHeatConstants = {
493
+ LocationDebugLayerId: "location-debug-id",
494
+ LocationDebugLayerSource: "location-debug-source",
495
+ LocationFillLayerId: "location-fill-id",
496
+ LocationFillLayerSource: "location-fill-source",
497
+ LocationLineLayerId: "location-line-id",
498
+ LocationLineLayerSource: "location-line-source"
499
+ };
500
+
501
+ // src/Layers/Builders/LocationHeatMapLayerBuilderAnimated.ts
502
+ var MapHeatConstants2 = (index, type) => ({
503
+ LocationDebugLayerId: `location-${type}-debug-id-${index}`,
504
+ LocationDebugLayerSource: `location-${type}-debug-source-${index}`,
505
+ LocationFillLayerId: `location-${type}-fill-id-${index}`,
506
+ LocationFillLayerSource: `location-${type}-fill-source-${index}`,
507
+ LocationLineLayerId: `location-${type}-line-id-${index}`,
508
+ LocationLineLayerSource: `location-${type}-line-source-${index}`
509
+ });
510
+ var LocationHeatMapLayerBuilderAnimated = (color, index, type = "") => {
511
+ const { LocationFillLayerId, LocationFillLayerSource } = MapHeatConstants2(index, type);
512
+ const fillLayerConfig = HeatMapFillLayerConfig(color);
513
+ const fillLayer = new FillLayerBuilder(LocationFillLayerId, LocationFillLayerSource, fillLayerConfig);
514
+ return fillLayer;
515
+ };
516
+
517
+ // src/Components/MapBoxHeat.tsx
3
518
  import { FlexCol } from "@xylabs/react-flexbox";
4
- import { useState } from "react";
5
- import { HeatMapInitializerProvider, MapBoxInstanceProvider, MapSettingsProvider } from "../Contexts";
6
- import { LocationHeatMapLayerBuilderAnimated, MapHeatConstants } from "../Layers";
7
- import { MapboxHeatFlexBox } from "./MapBoxHeat";
8
- const AnimatedHeatMap = ({
519
+
520
+ // src/Components/MapBox.tsx
521
+ import "mapbox-gl/dist/mapbox-gl.css";
522
+ import { Map as Map3 } from "mapbox-gl";
523
+ import { useEffect as useEffect6, useRef, useState as useState6 } from "react";
524
+ import { jsx as jsx4 } from "react/jsx-runtime";
525
+ var MapBox = ({ accessToken, darkMode = false, options, zoom = 2, ...props }) => {
526
+ const [map, setMap] = useState6();
527
+ const mapContainerRef = useRef(null);
528
+ const mapCanvasRef = useRef(null);
529
+ const { setMapBoxInstance, map: mapInstance } = useMapBoxInstance();
530
+ const { mapSettings } = useMapSettings();
531
+ const activeResize = mapSettings?.dynamicMapResize.value;
532
+ useDynamicMapResize(mapContainerRef, mapCanvasRef, mapInstance, activeResize);
533
+ useEffect6(() => {
534
+ if (mapSettings?.preferDark?.value === true) {
535
+ map?.setStyle(`mapbox://styles/${"mapbox/dark-v10" /* Dark */}`);
536
+ } else {
537
+ map?.setStyle(`mapbox://styles/${darkMode ? "mapbox/dark-v10" /* Dark */ : "mapbox/light-v10" /* Light */}`);
538
+ }
539
+ }, [map, darkMode, mapSettings]);
540
+ useEffect6(() => {
541
+ const map2 = new Map3({
542
+ accessToken,
543
+ center: [0, 0],
544
+ container: mapContainerRef.current ?? "",
545
+ style: `mapbox://styles/${"mapbox/light-v10" /* Light */}`,
546
+ zoom,
547
+ ...options
548
+ });
549
+ setMapBoxInstance?.(map2);
550
+ setMap(map2);
551
+ mapCanvasRef.current = document.querySelector(".mapboxgl-canvas");
552
+ console.log("Created Map");
553
+ return () => {
554
+ console.log("Removing Map");
555
+ map2.remove();
556
+ };
557
+ }, [mapContainerRef, setMap, options, zoom, setMapBoxInstance, accessToken]);
558
+ return /* @__PURE__ */ jsx4(
559
+ "div",
560
+ {
561
+ ref: (el) => mapContainerRef.current = el,
562
+ style: {
563
+ bottom: 0,
564
+ left: 0,
565
+ position: "absolute",
566
+ right: 0,
567
+ top: 0,
568
+ ...props
569
+ }
570
+ }
571
+ );
572
+ };
573
+
574
+ // src/Components/MapSettingsComponents/Setting.tsx
575
+ import { FormControlLabel, Switch } from "@mui/material";
576
+ import { jsx as jsx5 } from "react/jsx-runtime";
577
+ var MapSettingSwitch = ({ developerMode, field, ...props }) => {
578
+ const { mapSettings, setMapSettings } = useMapSettings();
579
+ const setting = mapSettings?.[field];
580
+ const onLocalChange = (event) => {
581
+ if (setting) {
582
+ setMapSettings?.((previous) => {
583
+ previous[setting.field].value = event.target.checked;
584
+ return { ...previous };
585
+ });
586
+ }
587
+ };
588
+ if (setting?.devMode && developerMode === false) {
589
+ return null;
590
+ }
591
+ return setting?.hidden ? null : /* @__PURE__ */ jsx5(FormControlLabel, { label: setting?.label, control: /* @__PURE__ */ jsx5(Switch, { checked: setting?.value, onChange: onLocalChange, ...props }) });
592
+ };
593
+
594
+ // src/Components/MapSettingsComponents/SettingsBox.tsx
595
+ import { Paper, Stack } from "@mui/material";
596
+ import { FlexGrowRow, FlexRow } from "@xylabs/react-flexbox";
597
+ import { useAppSettings } from "@xyo-network/react-app-settings";
598
+ import { jsx as jsx6 } from "react/jsx-runtime";
599
+ var MapSettingsBox = ({ developerMode, ...props }) => {
600
+ const { mapSettings } = useMapSettings();
601
+ const { developerMode: devModeFromContext } = useAppSettings();
602
+ const resolveDeveloperMode = developerMode ?? devModeFromContext;
603
+ return mapSettings && resolveDeveloperMode ? /* @__PURE__ */ jsx6(FlexGrowRow, { bottom: 36, left: 10, position: "absolute", ...props, children: /* @__PURE__ */ jsx6(FlexRow, { paddingX: 2, children: /* @__PURE__ */ jsx6(Paper, { children: /* @__PURE__ */ jsx6(Stack, { direction: "row", spacing: 1, marginX: 1, children: Object.keys(mapSettings).map((key, index) => {
604
+ return /* @__PURE__ */ jsx6(MapSettingSwitch, { field: mapSettings[key].field, developerMode }, index);
605
+ }) }) }) }) }) : null;
606
+ };
607
+
608
+ // src/Components/MapBoxHeat.tsx
609
+ import { jsx as jsx7, jsxs } from "react/jsx-runtime";
610
+ var MapboxHeatFlexBox = ({ accessToken, children, mapBoxOptions, zoom, legend, developerMode, ...props }) => {
611
+ return /* @__PURE__ */ jsxs(FlexCol, { ...props, children: [
612
+ /* @__PURE__ */ jsx7(MapBox, { accessToken, options: mapBoxOptions, zoom }),
613
+ /* @__PURE__ */ jsx7(MapSettingsBox, { developerMode }),
614
+ legend,
615
+ children
616
+ ] });
617
+ };
618
+
619
+ // src/Components/AnimatedHeatMap.tsx
620
+ import { jsx as jsx8 } from "react/jsx-runtime";
621
+ var AnimatedHeatMap = ({
9
622
  accessToken,
10
623
  animatedFeatureSets,
11
624
  defaultMapSettings,
@@ -16,12 +629,12 @@ const AnimatedHeatMap = ({
16
629
  const theme = useTheme();
17
630
  const { staticMapColor, lowUsageColor, highUsageColor } = heatMapColorProps || {};
18
631
  const localStaticMapColor = staticMapColor ?? theme.palette.primary.light;
19
- const [layers] = useState([
632
+ const [layers] = useState7([
20
633
  LocationHeatMapLayerBuilderAnimated(localStaticMapColor, 0, "static"),
21
634
  LocationHeatMapLayerBuilderAnimated(lowUsageColor || localStaticMapColor, 0, "animated"),
22
635
  LocationHeatMapLayerBuilderAnimated(highUsageColor || darken(localStaticMapColor, 0.9), 1, "animated")
23
636
  ]);
24
- return animatedFeatureSets?.length ? /* @__PURE__ */ jsx(MapBoxInstanceProvider, { children: /* @__PURE__ */ jsx(MapSettingsProvider, { defaultMapSettings, debugLayerName: MapHeatConstants.LocationDebugLayerId, children: /* @__PURE__ */ jsx(
637
+ return animatedFeatureSets?.length ? /* @__PURE__ */ jsx8(MapBoxInstanceProvider, { children: /* @__PURE__ */ jsx8(MapSettingsProvider, { defaultMapSettings, debugLayerName: MapHeatConstants.LocationDebugLayerId, children: /* @__PURE__ */ jsx8(
25
638
  HeatMapInitializerProvider,
26
639
  {
27
640
  features: staticFeatureSet,
@@ -29,9 +642,9 @@ const AnimatedHeatMap = ({
29
642
  featureSets: animatedFeatureSets,
30
643
  featureSetsLayers: layers.slice(1, 3),
31
644
  heatMapColorProps,
32
- children: /* @__PURE__ */ jsx(MapboxHeatFlexBox, { accessToken, ...props })
645
+ children: /* @__PURE__ */ jsx8(MapboxHeatFlexBox, { accessToken, ...props })
33
646
  }
34
- ) }) }) : /* @__PURE__ */ jsx(FlexCol, { minHeight: 160, minWidth: 160, busy: true });
647
+ ) }) }) : /* @__PURE__ */ jsx8(FlexCol2, { minHeight: 160, minWidth: 160, busy: true });
35
648
  };
36
649
  export {
37
650
  AnimatedHeatMap