@sjvair/monitor-map 4.3.0 → 5.0.0-beta.0

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 (254) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +59 -138
  3. package/dist/lib/MonitorDetailPanel.svelte +23 -20
  4. package/dist/lib/MonitorMapLayout.svelte +147 -77
  5. package/dist/lib/components/DataBox.svelte +4 -1
  6. package/dist/lib/components/ui/range-calendar/range-calendar.svelte.d.ts +1 -1
  7. package/dist/lib/config.svelte.d.ts +7 -0
  8. package/dist/lib/config.svelte.js +10 -0
  9. package/dist/lib/core.d.ts +2 -2
  10. package/dist/lib/core.js +2 -1
  11. package/dist/lib/data-chart/DataChart.svelte +40 -25
  12. package/dist/lib/data-chart/DateRange.d.ts +13 -4
  13. package/dist/lib/data-chart/DateRange.js +50 -14
  14. package/dist/lib/data-chart/chart-utils.js +5 -7
  15. package/dist/lib/data-chart/level-colors.d.ts +3 -4
  16. package/dist/lib/data-chart/level-colors.js +7 -4
  17. package/dist/lib/data-chart/pacific-time.d.ts +9 -0
  18. package/dist/lib/data-chart/pacific-time.js +25 -0
  19. package/dist/lib/data-chart/tooltip.js +2 -2
  20. package/{src/lib/ev-stations/components/EvStationTooltip.svelte → dist/lib/ev-stations/EvPopup.svelte} +6 -5
  21. package/dist/lib/ev-stations/EvPopup.svelte.d.ts +7 -0
  22. package/dist/lib/ev-stations/ev-plugin.svelte.d.ts +14 -0
  23. package/dist/lib/ev-stations/ev-plugin.svelte.js +71 -0
  24. package/dist/lib/ev-stations/ev-station-icons.d.ts +1 -4
  25. package/dist/lib/ev-stations/ev-station-icons.js +1 -13
  26. package/dist/lib/ev-stations/ev-stations.d.ts +7 -0
  27. package/dist/lib/ev-stations/ev-stations.js +53 -0
  28. package/dist/lib/ev-stations/ev-store.svelte.d.ts +21 -0
  29. package/dist/lib/ev-stations/ev-store.svelte.js +83 -0
  30. package/dist/lib/ev-stations/station-popup.svelte.d.ts +14 -0
  31. package/dist/lib/ev-stations/station-popup.svelte.js +54 -0
  32. package/dist/lib/ev-stations/types.d.ts +0 -29
  33. package/dist/lib/ev-stations/zip-codes.d.ts +11 -0
  34. package/dist/lib/ev-stations/zip-codes.js +28 -16
  35. package/dist/lib/index.d.ts +8 -56
  36. package/dist/lib/index.js +7 -46
  37. package/dist/lib/legend/Legend.svelte +18 -19
  38. package/dist/lib/legend/Legend.svelte.d.ts +2 -2
  39. package/dist/lib/levels.d.ts +7 -0
  40. package/dist/lib/levels.js +19 -0
  41. package/dist/lib/map/MapShell.svelte +17 -24
  42. package/dist/lib/map/MapShell.svelte.d.ts +4 -4
  43. package/dist/lib/map/basemaps.d.ts +25 -0
  44. package/dist/lib/map/basemaps.js +66 -0
  45. package/dist/lib/map/live-map.svelte.d.ts +3 -0
  46. package/dist/lib/map/live-map.svelte.js +22 -0
  47. package/dist/lib/map/sync-plugins.svelte.d.ts +19 -0
  48. package/dist/lib/map/sync-plugins.svelte.js +52 -0
  49. package/dist/lib/monitors/components/MonitorSubscriptionManager.svelte +66 -61
  50. package/dist/lib/monitors/filtered-source.svelte.d.ts +9 -0
  51. package/dist/lib/monitors/filtered-source.svelte.js +28 -0
  52. package/dist/lib/monitors/monitors.svelte.d.ts +25 -35
  53. package/dist/lib/monitors/monitors.svelte.js +35 -218
  54. package/dist/lib/monitors/retry-load.d.ts +8 -0
  55. package/dist/lib/monitors/retry-load.js +11 -0
  56. package/dist/lib/monitors/types.d.ts +1 -41
  57. package/dist/lib/options/map-option-defaults.d.ts +25 -36
  58. package/dist/lib/options/map-option-defaults.js +12 -30
  59. package/dist/lib/options/map-options.svelte.d.ts +13 -0
  60. package/dist/lib/options/map-options.svelte.js +26 -0
  61. package/dist/lib/options/menus/LayersMenu.svelte +8 -20
  62. package/dist/lib/options/menus/LayersMenu.svelte.d.ts +17 -2
  63. package/dist/lib/options/menus/MonitorsMenu.svelte +34 -18
  64. package/dist/lib/options/menus/OverlaysMenu.svelte +2 -2
  65. package/dist/lib/options/menus/PollutantMenu.svelte +4 -9
  66. package/dist/lib/options/menus/SettingsMenu.svelte +32 -25
  67. package/dist/lib/options/menus/SettingsMenu.svelte.d.ts +5 -16
  68. package/dist/lib/options/plugin-order.d.ts +8 -0
  69. package/dist/lib/options/plugin-order.js +36 -0
  70. package/dist/lib/options/pollutant-param.d.ts +7 -5
  71. package/dist/lib/options/pollutant-param.js +9 -5
  72. package/dist/lib/options/row-icons.d.ts +8 -0
  73. package/dist/lib/options/row-icons.js +15 -0
  74. package/dist/lib/options/rows/MarkerIcon.svelte +5 -5
  75. package/dist/lib/options/rows/MarkerIcon.svelte.d.ts +1 -2
  76. package/dist/lib/search/Search.svelte +20 -33
  77. package/dist/lib/search/Search.svelte.d.ts +5 -1
  78. package/dist/lib/search/search-pin.svelte.d.ts +11 -0
  79. package/dist/lib/search/search-pin.svelte.js +28 -0
  80. package/dist/lib/search/service.d.ts +7 -2
  81. package/dist/lib/search/service.js +17 -10
  82. package/dist/lib/stores.svelte.d.ts +8 -0
  83. package/dist/lib/stores.svelte.js +9 -0
  84. package/dist/lib/wind/wind-plugin.d.ts +11 -0
  85. package/dist/lib/wind/wind-plugin.js +25 -0
  86. package/package.json +12 -10
  87. package/src/lib/MonitorDetailPanel.svelte +23 -20
  88. package/src/lib/MonitorMapLayout.svelte +147 -77
  89. package/src/lib/components/DataBox.svelte +4 -1
  90. package/src/lib/config.svelte.ts +16 -0
  91. package/src/lib/core.ts +2 -2
  92. package/src/lib/data-chart/DataChart.svelte +40 -25
  93. package/src/lib/data-chart/DateRange.ts +58 -15
  94. package/src/lib/data-chart/chart-utils.ts +6 -7
  95. package/src/lib/data-chart/level-colors.ts +8 -9
  96. package/src/lib/data-chart/pacific-time.ts +31 -0
  97. package/src/lib/data-chart/tooltip.ts +2 -2
  98. package/{dist/lib/ev-stations/components/EvStationTooltip.svelte → src/lib/ev-stations/EvPopup.svelte} +6 -5
  99. package/src/lib/ev-stations/ev-plugin.svelte.ts +86 -0
  100. package/src/lib/ev-stations/ev-station-icons.ts +1 -17
  101. package/src/lib/ev-stations/ev-stations.ts +72 -0
  102. package/src/lib/ev-stations/ev-store.svelte.ts +117 -0
  103. package/src/lib/ev-stations/station-popup.svelte.ts +64 -0
  104. package/src/lib/ev-stations/types.ts +0 -34
  105. package/src/lib/ev-stations/zip-codes.ts +29 -16
  106. package/src/lib/index.ts +8 -99
  107. package/src/lib/legend/Legend.svelte +18 -19
  108. package/src/lib/levels.ts +24 -0
  109. package/src/lib/map/MapShell.svelte +17 -24
  110. package/src/lib/map/basemaps.ts +76 -0
  111. package/src/lib/map/live-map.svelte.ts +24 -0
  112. package/src/lib/map/sync-plugins.svelte.ts +69 -0
  113. package/src/lib/monitors/components/MonitorSubscriptionManager.svelte +66 -61
  114. package/src/lib/monitors/filtered-source.svelte.ts +38 -0
  115. package/src/lib/monitors/monitors.svelte.ts +58 -261
  116. package/src/lib/monitors/retry-load.ts +14 -0
  117. package/src/lib/monitors/types.ts +1 -47
  118. package/src/lib/options/map-option-defaults.ts +30 -53
  119. package/src/lib/options/map-options.svelte.ts +30 -0
  120. package/src/lib/options/menus/LayersMenu.svelte +8 -20
  121. package/src/lib/options/menus/MonitorsMenu.svelte +34 -18
  122. package/src/lib/options/menus/OverlaysMenu.svelte +2 -2
  123. package/src/lib/options/menus/PollutantMenu.svelte +4 -9
  124. package/src/lib/options/menus/SettingsMenu.svelte +32 -25
  125. package/src/lib/options/plugin-order.ts +38 -0
  126. package/src/lib/options/pollutant-param.ts +14 -9
  127. package/src/lib/options/row-icons.ts +17 -0
  128. package/src/lib/options/rows/MarkerIcon.svelte +5 -5
  129. package/src/lib/search/Search.svelte +20 -33
  130. package/src/lib/search/search-pin.svelte.ts +35 -0
  131. package/src/lib/search/service.ts +34 -15
  132. package/src/lib/stores.svelte.ts +15 -0
  133. package/src/lib/wind/wind-plugin.ts +33 -0
  134. package/dist/lib/collocation-sites/CollocationTooltip.svelte +0 -98
  135. package/dist/lib/collocation-sites/CollocationTooltip.svelte.d.ts +0 -7
  136. package/dist/lib/collocation-sites/collocations-icon-manager.svelte.d.ts +0 -7
  137. package/dist/lib/collocation-sites/collocations-icon-manager.svelte.js +0 -18
  138. package/dist/lib/collocation-sites/collocations-map-integration.svelte.d.ts +0 -21
  139. package/dist/lib/collocation-sites/collocations-map-integration.svelte.js +0 -113
  140. package/dist/lib/collocation-sites/collocations.svelte.d.ts +0 -10
  141. package/dist/lib/collocation-sites/collocations.svelte.js +0 -21
  142. package/dist/lib/collocation-sites/types.d.ts +0 -8
  143. package/dist/lib/collocation-sites/types.js +0 -1
  144. package/dist/lib/ev-stations/components/EvStationClusterTooltip.svelte +0 -16
  145. package/dist/lib/ev-stations/components/EvStationClusterTooltip.svelte.d.ts +0 -7
  146. package/dist/lib/ev-stations/components/EvStationTooltip.svelte.d.ts +0 -7
  147. package/dist/lib/ev-stations/ev-stations-cluster-renderer.d.ts +0 -19
  148. package/dist/lib/ev-stations/ev-stations-cluster-renderer.js +0 -131
  149. package/dist/lib/ev-stations/ev-stations-map-integration.svelte.d.ts +0 -31
  150. package/dist/lib/ev-stations/ev-stations-map-integration.svelte.js +0 -226
  151. package/dist/lib/ev-stations/ev-stations.svelte.d.ts +0 -10
  152. package/dist/lib/ev-stations/ev-stations.svelte.js +0 -57
  153. package/dist/lib/hms/hms-fire-icon-manager.d.ts +0 -13
  154. package/dist/lib/hms/hms-fire-icon-manager.js +0 -39
  155. package/dist/lib/hms/hms-fire-map-integration.svelte.d.ts +0 -23
  156. package/dist/lib/hms/hms-fire-map-integration.svelte.js +0 -94
  157. package/dist/lib/hms/hms-smoke-map-integration.svelte.d.ts +0 -39
  158. package/dist/lib/hms/hms-smoke-map-integration.svelte.js +0 -87
  159. package/dist/lib/hms/hms.svelte.d.ts +0 -20
  160. package/dist/lib/hms/hms.svelte.js +0 -237
  161. package/dist/lib/legend/LegendBar.svelte +0 -45
  162. package/dist/lib/legend/LegendBar.svelte.d.ts +0 -7
  163. package/dist/lib/legend/legend-data.d.ts +0 -40
  164. package/dist/lib/legend/legend-data.js +0 -65
  165. package/dist/lib/map/Map.svelte +0 -13
  166. package/dist/lib/map/Map.svelte.d.ts +0 -8
  167. package/dist/lib/map/basemap.d.ts +0 -14
  168. package/dist/lib/map/basemap.js +0 -10
  169. package/dist/lib/map/icons.d.ts +0 -7
  170. package/dist/lib/map/icons.js +0 -33
  171. package/dist/lib/map/integrations/base-layer-seperator.d.ts +0 -9
  172. package/dist/lib/map/integrations/base-layer-seperator.js +0 -11
  173. package/dist/lib/map/integrations/click-manager.d.ts +0 -14
  174. package/dist/lib/map/integrations/click-manager.js +0 -52
  175. package/dist/lib/map/integrations/integrations-manager.d.ts +0 -8
  176. package/dist/lib/map/integrations/integrations-manager.js +0 -20
  177. package/dist/lib/map/integrations/map-display-option.svelte.d.ts +0 -7
  178. package/dist/lib/map/integrations/map-display-option.svelte.js +0 -10
  179. package/dist/lib/map/integrations/map-geojson-integration.svelte.d.ts +0 -32
  180. package/dist/lib/map/integrations/map-geojson-integration.svelte.js +0 -60
  181. package/dist/lib/map/integrations/map-icon-manager.d.ts +0 -15
  182. package/dist/lib/map/integrations/map-icon-manager.js +0 -52
  183. package/dist/lib/map/integrations/map-integration.svelte.d.ts +0 -6
  184. package/dist/lib/map/integrations/map-integration.svelte.js +0 -2
  185. package/dist/lib/map/integrations/map-layer-integration.svelte.d.ts +0 -11
  186. package/dist/lib/map/integrations/map-layer-integration.svelte.js +0 -40
  187. package/dist/lib/map/integrations/tooltip.svelte.d.ts +0 -36
  188. package/dist/lib/map/integrations/tooltip.svelte.js +0 -131
  189. package/dist/lib/map/integrations/types.d.ts +0 -14
  190. package/dist/lib/map/integrations/types.js +0 -1
  191. package/dist/lib/map/map-manager.svelte.d.ts +0 -20
  192. package/dist/lib/map/map-manager.svelte.js +0 -63
  193. package/dist/lib/map/map-style-state.svelte.d.ts +0 -23
  194. package/dist/lib/map/map-style-state.svelte.js +0 -86
  195. package/dist/lib/map/utils.d.ts +0 -7
  196. package/dist/lib/map/utils.js +0 -36
  197. package/dist/lib/monitors/components/MonitorClusterTooltip.svelte +0 -112
  198. package/dist/lib/monitors/components/MonitorClusterTooltip.svelte.d.ts +0 -7
  199. package/dist/lib/monitors/components/MonitorTooltip.svelte +0 -61
  200. package/dist/lib/monitors/components/MonitorTooltip.svelte.d.ts +0 -7
  201. package/dist/lib/monitors/monitor-utils.d.ts +0 -4
  202. package/dist/lib/monitors/monitor-utils.js +0 -41
  203. package/dist/lib/monitors/monitors-cluster-renderer.d.ts +0 -33
  204. package/dist/lib/monitors/monitors-cluster-renderer.js +0 -221
  205. package/dist/lib/monitors/monitors-icon-manager.svelte.d.ts +0 -15
  206. package/dist/lib/monitors/monitors-icon-manager.svelte.js +0 -78
  207. package/dist/lib/monitors/monitors-map-integration.svelte.d.ts +0 -43
  208. package/dist/lib/monitors/monitors-map-integration.svelte.js +0 -301
  209. package/dist/lib/options/reset-map-options.d.ts +0 -2
  210. package/dist/lib/options/reset-map-options.js +0 -24
  211. package/dist/lib/reactivity.svelte.d.ts +0 -0
  212. package/dist/lib/reactivity.svelte.js +0 -83
  213. package/dist/lib/wind/wind.svelte.d.ts +0 -10
  214. package/dist/lib/wind/wind.svelte.js +0 -13
  215. package/src/lib/collocation-sites/CollocationTooltip.svelte +0 -98
  216. package/src/lib/collocation-sites/collocations-icon-manager.svelte.ts +0 -21
  217. package/src/lib/collocation-sites/collocations-map-integration.svelte.ts +0 -136
  218. package/src/lib/collocation-sites/collocations.svelte.ts +0 -27
  219. package/src/lib/collocation-sites/types.ts +0 -10
  220. package/src/lib/ev-stations/components/EvStationClusterTooltip.svelte +0 -16
  221. package/src/lib/ev-stations/ev-stations-cluster-renderer.ts +0 -162
  222. package/src/lib/ev-stations/ev-stations-map-integration.svelte.ts +0 -248
  223. package/src/lib/ev-stations/ev-stations.svelte.ts +0 -84
  224. package/src/lib/hms/hms-fire-icon-manager.ts +0 -48
  225. package/src/lib/hms/hms-fire-map-integration.svelte.ts +0 -109
  226. package/src/lib/hms/hms-smoke-map-integration.svelte.ts +0 -105
  227. package/src/lib/hms/hms.svelte.ts +0 -270
  228. package/src/lib/legend/LegendBar.svelte +0 -45
  229. package/src/lib/legend/legend-data.ts +0 -101
  230. package/src/lib/map/Map.svelte +0 -13
  231. package/src/lib/map/basemap.ts +0 -24
  232. package/src/lib/map/icons.ts +0 -42
  233. package/src/lib/map/integrations/base-layer-seperator.ts +0 -17
  234. package/src/lib/map/integrations/click-manager.ts +0 -64
  235. package/src/lib/map/integrations/integrations-manager.ts +0 -25
  236. package/src/lib/map/integrations/map-display-option.svelte.ts +0 -13
  237. package/src/lib/map/integrations/map-geojson-integration.svelte.ts +0 -77
  238. package/src/lib/map/integrations/map-icon-manager.ts +0 -67
  239. package/src/lib/map/integrations/map-integration.svelte.ts +0 -8
  240. package/src/lib/map/integrations/map-layer-integration.svelte.ts +0 -49
  241. package/src/lib/map/integrations/tooltip.svelte.ts +0 -153
  242. package/src/lib/map/integrations/types.ts +0 -24
  243. package/src/lib/map/map-manager.svelte.ts +0 -83
  244. package/src/lib/map/map-style-state.svelte.ts +0 -94
  245. package/src/lib/map/utils.ts +0 -53
  246. package/src/lib/monitors/components/MonitorClusterTooltip.svelte +0 -112
  247. package/src/lib/monitors/components/MonitorTooltip.svelte +0 -61
  248. package/src/lib/monitors/monitor-utils.ts +0 -57
  249. package/src/lib/monitors/monitors-cluster-renderer.ts +0 -285
  250. package/src/lib/monitors/monitors-icon-manager.svelte.ts +0 -98
  251. package/src/lib/monitors/monitors-map-integration.svelte.ts +0 -318
  252. package/src/lib/options/reset-map-options.ts +0 -28
  253. package/src/lib/reactivity.svelte.ts +0 -82
  254. package/src/lib/wind/wind.svelte.ts +0 -20
@@ -1,226 +0,0 @@
1
- import { untrack } from "svelte";
2
- import { mapManager } from "../map/map-manager.svelte.js";
3
- import { clickManager } from "../map/integrations/click-manager";
4
- import { MapIconLayerIntegration } from "../map/integrations/map-geojson-integration.svelte";
5
- import { MapDisplayOption } from "../map/integrations/map-display-option.svelte";
6
- import { TooltipManager } from "../map/integrations/tooltip.svelte";
7
- import { mountClickPopup } from "../map/utils";
8
- import { evStationsManager } from "./ev-stations.svelte";
9
- import { EvStationIconManager } from "./ev-station-icons";
10
- import { EvStationsClusterRenderer } from "./ev-stations-cluster-renderer";
11
- import EvStationTooltip from "./components/EvStationTooltip.svelte";
12
- class EvStationsMapIntegration extends MapIconLayerIntegration {
13
- referenceId = "ev-stations";
14
- enabled = $state(false);
15
- clustered = $state(true);
16
- icons = new EvStationIconManager();
17
- tooltipManager = new TooltipManager();
18
- renderer = new EvStationsClusterRenderer(this);
19
- currentPopup = null;
20
- displayOptions = $derived.by(() => ({
21
- lvl2: new MapDisplayOption("Level 2", true, this.icons.get("ev-station-lvl2")),
22
- lvl3: new MapDisplayOption("Level 3", true, this.icons.get("ev-station-lvl3"))
23
- }));
24
- features = $derived.by(() => {
25
- const result = [];
26
- if (evStationsManager.lvl2Stations) {
27
- for (const station of evStationsManager.lvl2Stations) {
28
- result.push(toFeature(station, "lvl2"));
29
- }
30
- }
31
- if (evStationsManager.lvl3Stations) {
32
- for (const station of evStationsManager.lvl3Stations) {
33
- result.push(toFeature(station, "lvl3"));
34
- }
35
- }
36
- return result;
37
- });
38
- featuresByLevel = $derived.by(() => {
39
- const byLevel = {};
40
- for (const feature of this.features) {
41
- const level = feature.properties.level;
42
- if (level === "lvl2" && !this.displayOptions.lvl2.value)
43
- continue;
44
- if (level === "lvl3" && !this.displayOptions.lvl3.value)
45
- continue;
46
- const arr = byLevel[level] ?? [];
47
- arr.push(feature);
48
- byLevel[level] = arr;
49
- }
50
- return byLevel;
51
- });
52
- filters = $derived.by(() => {
53
- const levels = [];
54
- if (this.displayOptions.lvl2.value)
55
- levels.push("lvl2");
56
- if (this.displayOptions.lvl3.value)
57
- levels.push("lvl3");
58
- if (levels.length === 0)
59
- return ["==", ["get", "level"], "none"];
60
- if (levels.length === 2)
61
- return ["boolean", true];
62
- return ["==", ["get", "level"], levels[0]];
63
- });
64
- handleStationClick = (features, evt) => {
65
- this.currentPopup?.remove();
66
- const feature = features[0];
67
- if (!feature)
68
- return;
69
- this.currentPopup = mountClickPopup(EvStationTooltip, { feature }, evt.lngLat);
70
- this.currentPopup.addTo(mapManager.map);
71
- };
72
- get mapLayer() {
73
- return {
74
- id: this.referenceId,
75
- type: "symbol",
76
- source: this.referenceId,
77
- filter: this.filters,
78
- layout: {
79
- "icon-allow-overlap": true,
80
- "icon-ignore-placement": true,
81
- "icon-image": ["get", "icon"],
82
- "icon-size": 1
83
- },
84
- paint: {}
85
- };
86
- }
87
- get mapSource() {
88
- return {
89
- type: "geojson",
90
- promoteId: "id",
91
- data: {
92
- type: "FeatureCollection",
93
- features: this.features
94
- }
95
- };
96
- }
97
- constructor() {
98
- super();
99
- $effect.root(() => {
100
- // Lazy-fetch level data only once the integration is enabled and the level is on
101
- $effect(() => {
102
- if (this.enabled &&
103
- this.displayOptions.lvl2.value &&
104
- evStationsManager.lvl2Stations === undefined) {
105
- evStationsManager.loadLvl2Stations();
106
- }
107
- });
108
- $effect(() => {
109
- if (this.enabled &&
110
- this.displayOptions.lvl3.value &&
111
- evStationsManager.lvl3Stations === undefined) {
112
- evStationsManager.loadLvl3Stations();
113
- }
114
- });
115
- // Every effect below early-returns while disabled so a data refresh can't re-add the layer.
116
- // `enabled` is read untracked: the base class's own effect already applies/removes on
117
- // enabled changes, and tracking it here would apply twice. The guard comes after each
118
- // effect's tracked reads so its dependencies are always collected; returning before
119
- // reading anything would leave the effect permanently dead.
120
- // Push filter changes to the unclustered layer
121
- $effect(() => {
122
- const filter = this.filters;
123
- if (!mapManager.map || this.clustered)
124
- return;
125
- if (!untrack(() => this.enabled))
126
- return;
127
- if (mapManager.map.getLayer(this.referenceId)) {
128
- mapManager.map.setFilter(this.referenceId, filter);
129
- }
130
- });
131
- // Sync unclustered source when features change
132
- $effect(() => {
133
- const features = this.features;
134
- if (!mapManager.map || this.clustered)
135
- return;
136
- if (!untrack(() => this.enabled))
137
- return;
138
- mapManager.setDataSource(this.referenceId, features);
139
- });
140
- // Sync clustered sources when featuresByLevel changes
141
- $effect(() => {
142
- void this.featuresByLevel;
143
- if (!mapManager.map || !this.clustered)
144
- return;
145
- if (!untrack(() => this.enabled))
146
- return;
147
- this.renderer.syncFeatures();
148
- });
149
- // Re-apply when clustered mode switches or data first arrives
150
- $effect(() => {
151
- void this.clustered;
152
- const hasFeatures = Object.keys(this.featuresByLevel).length > 0;
153
- if (!untrack(() => mapManager.map) || !hasFeatures)
154
- return;
155
- if (!untrack(() => this.enabled))
156
- return;
157
- untrack(() => this.apply());
158
- });
159
- });
160
- }
161
- apply() {
162
- if (!mapManager.map)
163
- return;
164
- if (this.clustered) {
165
- if (mapManager.map.getLayer(this.referenceId))
166
- mapManager.map.removeLayer(this.referenceId);
167
- if (mapManager.map.getSource(this.referenceId))
168
- mapManager.map.removeSource(this.referenceId);
169
- clickManager.unregister([this.referenceId]);
170
- this.tooltipManager.disable();
171
- this.renderer.remove();
172
- // Clustering may be toggled again before the icons arrive; only the latest apply runs.
173
- this.supersedePending();
174
- this.whenIconsLoad(() => {
175
- this.renderer.apply(this.handleStationClick);
176
- this.tooltipManager.enable();
177
- });
178
- }
179
- else {
180
- this.renderer.remove();
181
- this.tooltipManager.disable();
182
- clickManager.unregister([this.referenceId]);
183
- super.apply();
184
- this.whenIconsLoad(() => {
185
- clickManager.register([this.referenceId], this.handleStationClick);
186
- this.tooltipManager.enable();
187
- });
188
- }
189
- }
190
- remove() {
191
- clickManager.unregister([this.referenceId]);
192
- clickManager.unregister(this.renderer.unclusteredLayerIds);
193
- this.renderer.remove();
194
- this.currentPopup?.remove();
195
- this.currentPopup = null;
196
- super.remove();
197
- }
198
- }
199
- function toFeature(station, level) {
200
- return {
201
- type: "Feature",
202
- properties: {
203
- icon: `ev-station-${level}`,
204
- id: station.id,
205
- level,
206
- station_name: station.station_name ?? "",
207
- facility_type: station.facility_type ?? "",
208
- ev_network: station.ev_network ?? "",
209
- station_phone: station.station_phone ?? "",
210
- street_address: station.street_address ?? "",
211
- city: station.city ?? "",
212
- state: station.state ?? "",
213
- zip: station.zip ?? "",
214
- access_days_time: station.access_days_time ?? "",
215
- access_detail_code: station.access_detail_code ?? "",
216
- cards_accepted: station.cards_accepted ?? null,
217
- ev_pricing: station.ev_pricing ?? "",
218
- ev_connector_types: JSON.stringify(station.ev_connector_types ?? [])
219
- },
220
- geometry: {
221
- type: "Point",
222
- coordinates: [station.longitude, station.latitude]
223
- }
224
- };
225
- }
226
- export const evStationsMapIntegration = new EvStationsMapIntegration();
@@ -1,10 +0,0 @@
1
- import type { SignalOptions } from "../abort";
2
- import type { EvStation } from "./types";
3
- declare class EvStationsManager {
4
- lvl2Stations: Array<EvStation> | undefined;
5
- lvl3Stations: Array<EvStation> | undefined;
6
- loadLvl3Stations({ signal }?: SignalOptions): Promise<void>;
7
- loadLvl2Stations({ signal }?: SignalOptions): Promise<void>;
8
- }
9
- export declare const evStationsManager: EvStationsManager;
10
- export type { EvStationsManager };
@@ -1,57 +0,0 @@
1
- import { accessDetailCodeTypes, creditCardTypes, evConnectorTypes, evNetworkTypes, facilityTypes } from "./data-maps";
2
- import * as ZipCodes from "./zip-codes";
3
- class EvStationsManager {
4
- lvl2Stations = $state();
5
- lvl3Stations = $state();
6
- async loadLvl3Stations({ signal } = {}) {
7
- this.lvl3Stations = await fetchEvStations("dc_fast", signal);
8
- }
9
- async loadLvl2Stations({ signal } = {}) {
10
- this.lvl2Stations = await fetchEvStations("2", signal);
11
- }
12
- }
13
- const zipCodes = Object.values(ZipCodes)
14
- .reduce((prev, curr) => prev.concat(curr))
15
- .join(",");
16
- async function fetchEvStations(chargingLevel, signal) {
17
- if (signal?.aborted)
18
- throw signal.reason;
19
- const url = new URL(`https://developer.nlr.gov/api/alt-fuel-stations/v1.json`);
20
- url.searchParams.set("fuel_type", "ELEC");
21
- url.searchParams.set("state", "CA");
22
- url.searchParams.set("status", "E");
23
- url.searchParams.set("access", "public");
24
- url.searchParams.set("ev_charging_level", chargingLevel);
25
- url.searchParams.set("zip", zipCodes);
26
- url.searchParams.set("api_key", import.meta.env.VITE_NREL_KEY);
27
- return await fetch(url, { signal })
28
- .then(async (res) => await res.json())
29
- .then((data) => {
30
- const fuelStations = data.fuel_stations;
31
- return (fuelStations
32
- .map((station) => {
33
- if (station.access_detail_code) {
34
- station.access_detail_code = accessDetailCodeTypes.get(station.access_detail_code);
35
- }
36
- if (station.cards_accepted) {
37
- station.cards_accepted = station.cards_accepted
38
- .split(" ")
39
- .map((c) => creditCardTypes.get(c))
40
- .join(", ");
41
- }
42
- if (station.ev_connector_types && station.ev_connector_types.length) {
43
- station.ev_connector_types = station.ev_connector_types.map((t) => evConnectorTypes.get(t));
44
- }
45
- if (station.ev_network) {
46
- station.ev_network = evNetworkTypes.get(station.ev_network);
47
- }
48
- if (station.facility_type) {
49
- station.facility_type = facilityTypes.get(station.facility_type);
50
- }
51
- return station;
52
- })
53
- // remove stations with invalid coordinates
54
- .filter((station) => station.id !== 226154));
55
- });
56
- }
57
- export const evStationsManager = new EvStationsManager();
@@ -1,13 +0,0 @@
1
- import { MapIconManager } from "../map/integrations/map-icon-manager";
2
- import type { LegendCategory } from "../legend/legend-data";
3
- export type FRPTier = "sm" | "md" | "lg" | "xl" | "xxl";
4
- export declare const FRP_TIERS: Record<FRPTier, {
5
- color: string;
6
- size: number;
7
- }>;
8
- /** Fire legend blocks (MW), in tier order, using the same colors as the map icons. */
9
- export declare const FIRE_LEGEND_CATEGORIES: Array<LegendCategory>;
10
- export declare function getTierIconId(frp: number): string;
11
- export declare class HMSFireIconManager extends MapIconManager {
12
- constructor();
13
- }
@@ -1,39 +0,0 @@
1
- import { asDataURI, fireIcon } from "../map/icons";
2
- import { MapIconManager } from "../map/integrations/map-icon-manager";
3
- export const FRP_TIERS = {
4
- sm: { color: "#FFD700", size: 20 },
5
- md: { color: "#FF8C00", size: 24 },
6
- lg: { color: "#FF4500", size: 28 },
7
- xl: { color: "#DC143C", size: 32 },
8
- xxl: { color: "#8B0000", size: 36 }
9
- };
10
- const FRP_TIER_LABELS = {
11
- sm: "<10",
12
- md: "10-49",
13
- lg: "50-149",
14
- xl: "150-349",
15
- xxl: "≥350"
16
- };
17
- /** Fire legend blocks (MW), in tier order, using the same colors as the map icons. */
18
- export const FIRE_LEGEND_CATEGORIES = Object.keys(FRP_TIERS).map((tier) => ({ color: FRP_TIERS[tier].color, label: FRP_TIER_LABELS[tier] }));
19
- export function getTierIconId(frp) {
20
- if (frp < 10)
21
- return "hms-fire-sm";
22
- if (frp < 50)
23
- return "hms-fire-md";
24
- if (frp < 150)
25
- return "hms-fire-lg";
26
- if (frp < 350)
27
- return "hms-fire-xl";
28
- return "hms-fire-xxl";
29
- }
30
- export class HMSFireIconManager extends MapIconManager {
31
- constructor() {
32
- super();
33
- for (const [tier, { color, size }] of Object.entries(FRP_TIERS)) {
34
- const img = new Image(size, size);
35
- img.src = asDataURI(fireIcon(color, size));
36
- this.register(`hms-fire-${tier}`, img);
37
- }
38
- }
39
- }
@@ -1,23 +0,0 @@
1
- import type { Map as MaptilerMap } from "@maptiler/sdk";
2
- import type { Feature } from "geojson";
3
- import type { Point } from "geojson";
4
- import { MapIconLayerIntegration } from "../map/integrations/map-geojson-integration.svelte";
5
- import { HMSFireIconManager } from "./hms-fire-icon-manager";
6
- type FireProperties = Record<string, unknown>;
7
- declare class HMSFireMapIntegration extends MapIconLayerIntegration<FireProperties> {
8
- referenceId: string;
9
- enabled: boolean;
10
- icons: HMSFireIconManager;
11
- private zoomedIn;
12
- get features(): Array<Feature<Point, FireProperties>>;
13
- get mapLayer(): Parameters<MaptilerMap["addLayer"]>[0];
14
- get mapSource(): Parameters<MaptilerMap["addSource"]>[1];
15
- private get groupFeatures();
16
- private get hotspotFeatures();
17
- private onZoom;
18
- constructor();
19
- apply(): void;
20
- remove(): void;
21
- }
22
- export declare const hmsFireMapIntegration: HMSFireMapIntegration;
23
- export type { HMSFireMapIntegration };
@@ -1,94 +0,0 @@
1
- import { mapManager } from "../map/map-manager.svelte.js";
2
- import { MapIconLayerIntegration } from "../map/integrations/map-geojson-integration.svelte";
3
- import { hmsManager } from "./hms.svelte";
4
- import { HMSFireIconManager, getTierIconId } from "./hms-fire-icon-manager";
5
- const ZOOM_THRESHOLD = 10;
6
- class HMSFireMapIntegration extends MapIconLayerIntegration {
7
- referenceId = "hms-fire";
8
- enabled = $state(true);
9
- icons = new HMSFireIconManager();
10
- zoomedIn = $state(false);
11
- get features() {
12
- return this.zoomedIn ? this.hotspotFeatures : this.groupFeatures;
13
- }
14
- get mapLayer() {
15
- return {
16
- id: this.referenceId,
17
- type: "symbol",
18
- source: this.referenceId,
19
- layout: {
20
- "icon-image": ["get", "icon"],
21
- "icon-allow-overlap": true,
22
- "icon-ignore-placement": true
23
- },
24
- paint: {}
25
- };
26
- }
27
- get mapSource() {
28
- return {
29
- type: "geojson",
30
- promoteId: "id",
31
- data: { type: "FeatureCollection", features: this.features }
32
- };
33
- }
34
- get groupFeatures() {
35
- return (hmsManager.fireGroups ?? []).map((g) => ({
36
- type: "Feature",
37
- properties: {
38
- id: g.id,
39
- icon: getTierIconId(g.avgFrp),
40
- avgFrp: g.avgFrp,
41
- count: g.count
42
- },
43
- geometry: { type: "Point", coordinates: g.coordinates }
44
- }));
45
- }
46
- get hotspotFeatures() {
47
- return (hmsManager.fire ?? []).map((d) => ({
48
- type: "Feature",
49
- properties: {
50
- id: d.id,
51
- icon: getTierIconId(d.frp),
52
- frp: d.frp
53
- },
54
- geometry: d.geometry
55
- }));
56
- }
57
- onZoom = () => {
58
- if (!mapManager.map)
59
- return;
60
- this.zoomedIn = mapManager.map.getZoom() >= ZOOM_THRESHOLD;
61
- };
62
- constructor() {
63
- super();
64
- $effect.root(() => {
65
- $effect(() => {
66
- const features = this.features;
67
- if (!mapManager.map || !this.enabled)
68
- return;
69
- mapManager.setDataSource(this.referenceId, features);
70
- });
71
- });
72
- }
73
- apply() {
74
- if (!mapManager.map)
75
- return;
76
- this.icons
77
- .loadIcons()
78
- .then(() => {
79
- if (!mapManager.map || !this.enabled || mapManager.styleLoading)
80
- return;
81
- this.remove();
82
- this.zoomedIn = mapManager.map.getZoom() >= ZOOM_THRESHOLD;
83
- mapManager.map.addSource(this.referenceId, this.mapSource);
84
- mapManager.map.addLayer(this.mapLayer, this.beforeLayer);
85
- mapManager.map.on("zoom", this.onZoom);
86
- })
87
- .catch(console.error);
88
- }
89
- remove() {
90
- mapManager.map?.off("zoom", this.onZoom);
91
- super.remove();
92
- }
93
- }
94
- export const hmsFireMapIntegration = new HMSFireMapIntegration();
@@ -1,39 +0,0 @@
1
- import type { Map as MaptilerMap } from "@maptiler/sdk";
2
- import type { Feature, MultiPolygon } from "geojson";
3
- import type { HMSSmokeGeoJSON } from "@sjvair/sdk/hms";
4
- import { MapGeoJSONIntegration } from "../map/integrations/map-geojson-integration.svelte";
5
- import type { SmokeDensityStyle } from "../legend/legend-data";
6
- /** Smoke fill styles, shared by the map layer and the legend so they can't drift apart. */
7
- export declare const SMOKE_DENSITY_STYLES: {
8
- light: {
9
- label: string;
10
- color: string;
11
- opacity: number;
12
- };
13
- medium: {
14
- label: string;
15
- color: string;
16
- opacity: number;
17
- };
18
- heavy: {
19
- label: string;
20
- color: string;
21
- opacity: number;
22
- };
23
- };
24
- export declare const SMOKE_LEGEND: Array<SmokeDensityStyle>;
25
- type SmokeProperties = {
26
- id: string;
27
- density: HMSSmokeGeoJSON["density"];
28
- };
29
- declare class HMSSmokeMapIntegration extends MapGeoJSONIntegration<SmokeProperties> {
30
- referenceId: string;
31
- enabled: boolean;
32
- get features(): Array<Feature<MultiPolygon, SmokeProperties>>;
33
- get mapLayer(): Parameters<MaptilerMap["addLayer"]>[0];
34
- get mapSource(): Parameters<MaptilerMap["addSource"]>[1];
35
- constructor();
36
- apply(): void;
37
- }
38
- export declare const hmsSmokeMapIntegration: HMSSmokeMapIntegration;
39
- export type { HMSSmokeMapIntegration };
@@ -1,87 +0,0 @@
1
- import { mapManager } from "../map/map-manager.svelte.js";
2
- import { MapGeoJSONIntegration } from "../map/integrations/map-geojson-integration.svelte";
3
- import { hmsManager } from "./hms.svelte";
4
- /** Smoke fill styles, shared by the map layer and the legend so they can't drift apart. */
5
- export const SMOKE_DENSITY_STYLES = {
6
- light: { label: "Light", color: "#bfc8c3", opacity: 0.2 },
7
- medium: { label: "Medium", color: "#757b78", opacity: 0.3 },
8
- heavy: { label: "Heavy", color: "#333634", opacity: 0.4 }
9
- };
10
- export const SMOKE_LEGEND = Object.values(SMOKE_DENSITY_STYLES);
11
- class HMSSmokeMapIntegration extends MapGeoJSONIntegration {
12
- referenceId = "hms-smoke";
13
- enabled = $state(true);
14
- get features() {
15
- return (hmsManager.smoke ?? []).map((d) => ({
16
- type: "Feature",
17
- properties: {
18
- id: d.id,
19
- density: d.density
20
- },
21
- geometry: d.geometry
22
- }));
23
- }
24
- get mapLayer() {
25
- return {
26
- id: this.referenceId,
27
- type: "fill",
28
- source: this.referenceId,
29
- layout: {},
30
- paint: {
31
- "fill-color": [
32
- "match",
33
- ["get", "density"],
34
- "light",
35
- SMOKE_DENSITY_STYLES.light.color,
36
- "medium",
37
- SMOKE_DENSITY_STYLES.medium.color,
38
- SMOKE_DENSITY_STYLES.heavy.color
39
- ],
40
- "fill-opacity": [
41
- "match",
42
- ["get", "density"],
43
- "light",
44
- SMOKE_DENSITY_STYLES.light.opacity,
45
- "medium",
46
- SMOKE_DENSITY_STYLES.medium.opacity,
47
- SMOKE_DENSITY_STYLES.heavy.opacity
48
- ],
49
- "fill-outline-color": [
50
- "match",
51
- ["get", "density"],
52
- "light",
53
- SMOKE_DENSITY_STYLES.light.color,
54
- "medium",
55
- SMOKE_DENSITY_STYLES.medium.color,
56
- SMOKE_DENSITY_STYLES.heavy.color
57
- ]
58
- }
59
- };
60
- }
61
- get mapSource() {
62
- return {
63
- type: "geojson",
64
- promoteId: "id",
65
- data: { type: "FeatureCollection", features: this.features }
66
- };
67
- }
68
- constructor() {
69
- super();
70
- $effect.root(() => {
71
- $effect(() => {
72
- const features = this.features;
73
- if (!mapManager.map || !this.enabled)
74
- return;
75
- mapManager.setDataSource(this.referenceId, features);
76
- });
77
- });
78
- }
79
- apply() {
80
- if (!mapManager.map)
81
- return;
82
- this.remove();
83
- mapManager.map.addSource(this.referenceId, this.mapSource);
84
- super.apply();
85
- }
86
- }
87
- export const hmsSmokeMapIntegration = new HMSSmokeMapIntegration();
@@ -1,20 +0,0 @@
1
- import { type HMSFireGeoJSON, type HMSSmokeGeoJSON } from "@sjvair/sdk/hms";
2
- import type { SignalOptions } from "../abort";
3
- export interface HMSFireGroup {
4
- id: string;
5
- coordinates: [number, number];
6
- avgFrp: number;
7
- count: number;
8
- }
9
- declare class HmsManager {
10
- smoke: Array<HMSSmokeGeoJSON> | undefined;
11
- fire: Array<HMSFireGeoJSON & {
12
- frp: number;
13
- }> | undefined;
14
- fireGroups: Array<HMSFireGroup> | undefined;
15
- init({ signal }?: SignalOptions): Promise<void>;
16
- loadSmoke({ signal }?: SignalOptions): Promise<void>;
17
- loadFire({ signal }?: SignalOptions): Promise<void>;
18
- }
19
- export declare const hmsManager: HmsManager;
20
- export type { HmsManager as HMSManager };