@sjvair/monitor-map 3.0.0 → 3.0.2

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 (145) hide show
  1. package/dist/lib/LoadScreen.js +73 -0
  2. package/dist/lib/actions.js +9 -0
  3. package/dist/lib/assets/icons/adjustment-horizontal.js +4 -0
  4. package/dist/lib/collocation-sites/CollocationTooltip.js +105 -0
  5. package/dist/lib/collocation-sites/collocations-icon-manager.svelte.js +21 -0
  6. package/dist/lib/collocation-sites/collocations-map-integration.svelte.js +84 -0
  7. package/dist/lib/collocation-sites/collocations.svelte.js +26 -0
  8. package/dist/lib/colors.js +25 -0
  9. package/dist/lib/components/DataBox.js +30 -0
  10. package/dist/lib/components/DisplayOption.js +10 -0
  11. package/dist/lib/components/MapLayersDisplayOptions.js +78 -0
  12. package/dist/lib/components/SegmentedControl.js +37 -0
  13. package/dist/lib/components/ToggleSwitch.js +17 -0
  14. package/dist/lib/components/ui/button/button.js +34 -0
  15. package/dist/lib/components/ui/range-calendar/range-calendar-caption.js +79 -0
  16. package/dist/lib/components/ui/range-calendar/range-calendar-cell.js +34 -0
  17. package/dist/lib/components/ui/range-calendar/range-calendar-day.js +34 -0
  18. package/dist/lib/components/ui/range-calendar/range-calendar-grid-body.js +26 -0
  19. package/dist/lib/components/ui/range-calendar/range-calendar-grid-head.js +26 -0
  20. package/dist/lib/components/ui/range-calendar/range-calendar-grid-row.js +34 -0
  21. package/dist/lib/components/ui/range-calendar/range-calendar-grid.js +34 -0
  22. package/dist/lib/components/ui/range-calendar/range-calendar-head-cell.js +34 -0
  23. package/dist/lib/components/ui/range-calendar/range-calendar-header.js +34 -0
  24. package/dist/lib/components/ui/range-calendar/range-calendar-month-select.js +61 -0
  25. package/dist/lib/components/ui/range-calendar/range-calendar-month.js +25 -0
  26. package/dist/lib/components/ui/range-calendar/range-calendar-months.js +25 -0
  27. package/dist/lib/components/ui/range-calendar/range-calendar-nav.js +25 -0
  28. package/dist/lib/components/ui/range-calendar/range-calendar-next-button.js +57 -0
  29. package/dist/lib/components/ui/range-calendar/range-calendar-prev-button.js +57 -0
  30. package/dist/lib/components/ui/range-calendar/range-calendar-year-select.js +59 -0
  31. package/dist/lib/components/ui/range-calendar/range-calendar.js +272 -0
  32. package/dist/lib/data-chart/DataChart.js +142 -0
  33. package/dist/lib/data-chart/DateRange.js +15 -0
  34. package/dist/lib/data-chart/chart-utils.js +99 -0
  35. package/dist/lib/data-chart/data-chart.svelte.js +28 -0
  36. package/dist/lib/data-chart/requests.js +30 -0
  37. package/dist/lib/data-chart/tooltip.js +101 -0
  38. package/dist/lib/hms/hms-fire-icon-manager.js +39 -0
  39. package/dist/lib/hms/hms-fire-map-integration.svelte.js +97 -0
  40. package/dist/lib/hms/hms-smoke-map-integration.svelte.js +84 -0
  41. package/dist/lib/hms/hms.svelte.js +78 -0
  42. package/dist/lib/index.js +19 -0
  43. package/dist/lib/map/Map.js +14 -0
  44. package/dist/lib/map/MapStyleDisplayOptions.js +43 -0
  45. package/dist/lib/map/Menu.js +45 -0
  46. package/dist/lib/map/icons.js +31 -0
  47. package/dist/lib/map/integrations/base-layer-seperator.js +12 -0
  48. package/dist/lib/map/integrations/click-manager.js +33 -0
  49. package/dist/lib/map/integrations/integrations-manager.js +12 -0
  50. package/dist/lib/map/integrations/map-display-option.svelte.js +18 -0
  51. package/dist/lib/map/integrations/map-geojson-integration.svelte.js +17 -0
  52. package/dist/lib/map/integrations/map-icon-manager.js +43 -0
  53. package/dist/lib/map/integrations/map-integration.svelte.js +5 -0
  54. package/dist/lib/map/integrations/map-layer-integration.svelte.js +23 -0
  55. package/dist/lib/map/integrations/tooltip.svelte.js +81 -0
  56. package/dist/lib/map/map.svelte.js +51 -0
  57. package/dist/lib/map/utils.js +30 -0
  58. package/dist/lib/monitors/components/MonitorClusterTooltip.js +83 -0
  59. package/dist/lib/monitors/components/MonitorSubscriptionManager.js +104 -0
  60. package/dist/lib/monitors/components/MonitorTooltip.js +59 -0
  61. package/dist/lib/monitors/components/MonitorWidgetModal.js +40 -0
  62. package/dist/lib/monitors/components/MonitorsDisplayOptions.js +76 -0
  63. package/dist/lib/monitors/monitor-utils.js +26 -0
  64. package/dist/lib/monitors/monitors-cluster-renderer.js +212 -0
  65. package/dist/lib/monitors/monitors-icon-manager.svelte.js +71 -0
  66. package/dist/lib/monitors/monitors-map-integration.svelte.js +270 -0
  67. package/dist/lib/monitors/monitors.svelte.js +68 -0
  68. package/dist/lib/node_modules/@internationalized/date/dist/private/CalendarDate.js +122 -0
  69. package/dist/lib/node_modules/@internationalized/date/dist/private/DateFormatter.js +84 -0
  70. package/dist/lib/node_modules/@internationalized/date/dist/private/calendars/GregorianCalendar.js +91 -0
  71. package/dist/lib/node_modules/@internationalized/date/dist/private/conversion.js +104 -0
  72. package/dist/lib/node_modules/@internationalized/date/dist/private/manipulation.js +159 -0
  73. package/dist/lib/node_modules/@internationalized/date/dist/private/queries.js +32 -0
  74. package/dist/lib/node_modules/@internationalized/date/dist/private/string.js +37 -0
  75. package/dist/lib/node_modules/@internationalized/date/dist/private/utils.js +6 -0
  76. package/dist/lib/node_modules/clsx/dist/clsx.js +16 -0
  77. package/dist/lib/node_modules/tailwind-merge/dist/bundle-mjs.js +1723 -0
  78. package/dist/lib/node_modules/tailwind-variants/dist/chunk-LQJYWU4O.js +70 -0
  79. package/dist/lib/node_modules/tailwind-variants/dist/chunk-RZF76H2U.js +166 -0
  80. package/dist/lib/node_modules/tailwind-variants/dist/index.js +19 -0
  81. package/dist/lib/node_modules/uplot/dist/uPlot.esm.js +2147 -0
  82. package/dist/lib/sjvair-air.avif +0 -0
  83. package/dist/lib/sjvair-air.png +0 -0
  84. package/dist/lib/sjvair-air.webp +0 -0
  85. package/dist/lib/sjvair-air2.avif +0 -0
  86. package/dist/lib/sjvair-air2.png +0 -0
  87. package/dist/lib/sjvair-air2.webp +0 -0
  88. package/dist/lib/sjvair-icon.avif +0 -0
  89. package/dist/lib/sjvair-icon.png +0 -0
  90. package/dist/lib/sjvair-icon.webp +0 -0
  91. package/dist/lib/sjvair-icon2.avif +0 -0
  92. package/dist/lib/sjvair-icon2.png +0 -0
  93. package/dist/lib/sjvair-icon2.webp +0 -0
  94. package/dist/lib/sjvair-sjv.avif +0 -0
  95. package/dist/lib/sjvair-sjv.png +0 -0
  96. package/dist/lib/sjvair-sjv.webp +0 -0
  97. package/dist/lib/sjvair-sjv2.avif +0 -0
  98. package/dist/lib/sjvair-sjv2.png +0 -0
  99. package/dist/lib/sjvair-sjv2.webp +0 -0
  100. package/dist/lib/src/MapView.js +7 -0
  101. package/dist/lib/src/MonitorDetailPanel.js +169 -0
  102. package/dist/lib/src/router.js +9 -0
  103. package/dist/lib/utils.js +8 -0
  104. package/dist/lib/weather.js +8 -0
  105. package/dist/lib/wind/wind.svelte.js +21 -0
  106. package/dist/monitor-map/MonitorDetailPanel.css +1 -0
  107. package/dist/monitor-map/assets/MonitorDetailPanel-BU_pXZjp.js +15 -0
  108. package/dist/monitor-map/assets/validate-routes-CgbRa8fT.js +1 -0
  109. package/dist/monitor-map/inter-cyrillic-ext-wght-normal.woff2 +0 -0
  110. package/dist/monitor-map/inter-cyrillic-wght-normal.woff2 +0 -0
  111. package/dist/monitor-map/inter-greek-ext-wght-normal.woff2 +0 -0
  112. package/dist/monitor-map/inter-greek-wght-normal.woff2 +0 -0
  113. package/dist/monitor-map/inter-latin-ext-wght-normal.woff2 +0 -0
  114. package/dist/monitor-map/inter-latin-wght-normal.woff2 +0 -0
  115. package/dist/monitor-map/inter-vietnamese-wght-normal.woff2 +0 -0
  116. package/dist/monitor-map/lungs.svg +99 -0
  117. package/dist/monitor-map/sjvair-air.avif +0 -0
  118. package/dist/monitor-map/sjvair-air.png +0 -0
  119. package/dist/monitor-map/sjvair-air.webp +0 -0
  120. package/dist/monitor-map/sjvair-air2.avif +0 -0
  121. package/dist/monitor-map/sjvair-air2.png +0 -0
  122. package/dist/monitor-map/sjvair-air2.webp +0 -0
  123. package/dist/monitor-map/sjvair-icon.avif +0 -0
  124. package/dist/monitor-map/sjvair-icon.png +0 -0
  125. package/dist/monitor-map/sjvair-icon.webp +0 -0
  126. package/dist/monitor-map/sjvair-icon2.avif +0 -0
  127. package/dist/monitor-map/sjvair-icon2.png +0 -0
  128. package/dist/monitor-map/sjvair-icon2.webp +0 -0
  129. package/dist/monitor-map/sjvair-sjv.avif +0 -0
  130. package/dist/monitor-map/sjvair-sjv.png +0 -0
  131. package/dist/monitor-map/sjvair-sjv.webp +0 -0
  132. package/dist/monitor-map/sjvair-sjv2.avif +0 -0
  133. package/dist/monitor-map/sjvair-sjv2.png +0 -0
  134. package/dist/monitor-map/sjvair-sjv2.webp +0 -0
  135. package/dist/monitor-map/sjvairMonitorMap.css +1 -0
  136. package/dist/monitor-map/sjvairMonitorMap.js +4042 -0
  137. package/package.json +1 -1
  138. package/src/lib/components/MapLayersDisplayOptions.svelte +23 -10
  139. package/src/lib/ev-stations/components/EvStationsDisplayOptions.svelte +14 -2
  140. package/src/lib/ev-stations/ev-stations-map-integration.svelte.ts +4 -4
  141. package/src/lib/map/integrations/map-display-option.svelte.ts +5 -1
  142. package/src/lib/map/integrations/map-icon-manager.ts +4 -3
  143. package/src/lib/monitors/components/MonitorsDisplayOptions.svelte +4 -1
  144. package/src/lib/monitors/monitors-icon-manager.svelte.ts +3 -1
  145. package/src/lib/monitors/monitors-map-integration.svelte.ts +9 -9
@@ -0,0 +1,212 @@
1
+ import { mountPopup as e } from "../map/utils.js";
2
+ import { mapManager as t } from "../map/map.svelte.js";
3
+ import { clickManager as n } from "../map/integrations/click-manager.js";
4
+ import { getTypeShape as r } from "./monitor-utils.js";
5
+ import i from "./components/MonitorTooltip.js";
6
+ import a from "./components/MonitorClusterTooltip.js";
7
+ //#region src/lib/monitors/monitors-cluster-renderer.ts
8
+ var o = [
9
+ "/",
10
+ ["get", "sumValues"],
11
+ [
12
+ "max",
13
+ ["get", "point_count"],
14
+ 1
15
+ ]
16
+ ];
17
+ function s(t) {
18
+ let n = t.features?.sort((e, t) => t.properties.order - e.properties.order)[0];
19
+ if (n) return e(i, { feature: n }, t.lngLat);
20
+ }
21
+ function c(t) {
22
+ let n = t.features?.[0];
23
+ if (n) return e(a, { feature: n }, t.lngLat);
24
+ }
25
+ var l = class {
26
+ ctx;
27
+ _clusterTypes = [];
28
+ constructor(e) {
29
+ this.ctx = e;
30
+ }
31
+ apply(e) {
32
+ if (!t.map) return;
33
+ let i = Object.entries(this.ctx.featuresByType).sort(([, e], [, t]) => {
34
+ let n = (e) => e.reduce((e, t) => Math.max(e, t.properties.order), 0);
35
+ return n(e) - n(t);
36
+ });
37
+ for (let [[a, l], u] of i.map((e, t) => [e, t])) {
38
+ let i = `${this.ctx.referenceId}-${a}`;
39
+ t.map.addSource(i, {
40
+ type: "geojson",
41
+ promoteId: "id",
42
+ data: {
43
+ type: "FeatureCollection",
44
+ features: l
45
+ },
46
+ cluster: !0,
47
+ clusterRadius: 40,
48
+ clusterMaxZoom: 9,
49
+ clusterProperties: { sumValues: [
50
+ "+",
51
+ ["to-number", ["get", "value"]],
52
+ 0
53
+ ] }
54
+ }), this.monitorTypeIconsLayer(i, o, r(a)), this.clusterCountLayer(i, o), this.unclusteredLayer(i);
55
+ let { icon: d, unclustered: f } = this.clusterLayerIds(i);
56
+ this.ctx.tooltipManager.has(d) || this.ctx.tooltipManager.register(d, c, u), this.ctx.tooltipManager.has(f) || this.ctx.tooltipManager.register(f, s, u), n.register([f], e), n.register([d], this.makeClusterClickHandler(i)), this._clusterTypes.push(a);
57
+ }
58
+ }
59
+ remove() {
60
+ if (t.map) {
61
+ for (let e of this._clusterTypes) {
62
+ let r = `${this.ctx.referenceId}-${e}`, i = this.clusterLayerIds(r);
63
+ n.unregister([i.unclustered]), n.unregister([i.icon]);
64
+ for (let e of Object.values(i)) t.map.getLayer(e) && t.map.removeLayer(e);
65
+ t.map.getSource(r) && t.map.removeSource(r);
66
+ }
67
+ this._clusterTypes = [];
68
+ }
69
+ }
70
+ get unclusteredLayerIds() {
71
+ return this._clusterTypes.map((e) => `${this.ctx.referenceId}-${e}-unclustered`);
72
+ }
73
+ syncFeatures() {
74
+ if (t.map) for (let e of this._clusterTypes) {
75
+ let n = `${this.ctx.referenceId}-${e}`;
76
+ t.setDataSource(n, this.ctx.featuresByType[e] ?? []);
77
+ }
78
+ }
79
+ syncFilter() {
80
+ if (t.map) for (let e of this._clusterTypes) {
81
+ let n = `${this.ctx.referenceId}-${e}`, { unclustered: r } = this.clusterLayerIds(n);
82
+ t.map.getLayer(r) && t.map.setFilter(r, [
83
+ "all",
84
+ this.ctx.filters,
85
+ ["!", ["has", "point_count"]]
86
+ ]);
87
+ }
88
+ }
89
+ syncThresholds() {
90
+ if (t.map) for (let e of this._clusterTypes) {
91
+ let n = `${this.ctx.referenceId}-${e}`, { icon: i, average: a } = this.clusterLayerIds(n);
92
+ t.map.getLayer(i) && t.map.setLayoutProperty(i, "icon-image", this.buildClusterIconExpression(o, r(e))), t.map.getLayer(a) && t.map.setPaintProperty(a, "text-color", this.clusterTextColorExpr(o));
93
+ }
94
+ }
95
+ makeClusterClickHandler(e) {
96
+ return async (n) => {
97
+ try {
98
+ let r = n[0];
99
+ if (!r?.properties?.cluster_id) return;
100
+ let i = t.map?.getSource(e);
101
+ if (!i) return;
102
+ let a = await i.getClusterExpansionZoom(r.properties.cluster_id), o = r.geometry.coordinates;
103
+ t.map?.easeTo({
104
+ center: o,
105
+ zoom: a
106
+ });
107
+ } catch (e) {
108
+ console.error("ClickManager: cluster expansion zoom failed", e);
109
+ }
110
+ };
111
+ }
112
+ clusterLayerIds(e) {
113
+ return {
114
+ icon: `${e}-cluster-icon`,
115
+ average: `${e}-cluster-average`,
116
+ unclustered: `${e}-unclustered`
117
+ };
118
+ }
119
+ get clusterTextColorThreshold() {
120
+ return this.ctx.clusterIconThresholds[2]?.range[1] ?? 150.5;
121
+ }
122
+ clusterTextColorExpr(e) {
123
+ return [
124
+ "case",
125
+ [
126
+ "<=",
127
+ e,
128
+ this.clusterTextColorThreshold
129
+ ],
130
+ "#000000",
131
+ "#FFFFFF"
132
+ ];
133
+ }
134
+ buildClusterIconExpression(e, t) {
135
+ let n = this.ctx.clusterIconThresholds;
136
+ if (!n.length) return `outside-default-${t}`;
137
+ let r = ["case"];
138
+ for (let i of n.slice(0, -1)) r.push([
139
+ "<=",
140
+ e,
141
+ i.range[1]
142
+ ], `outside-${i.name}-${t}`);
143
+ return r.push(`outside-${n.at(-1).name}-${t}`), r;
144
+ }
145
+ monitorTypeIconsLayer(e, n, r) {
146
+ let { icon: i } = this.clusterLayerIds(e);
147
+ t.map?.addLayer({
148
+ id: i,
149
+ type: "symbol",
150
+ source: e,
151
+ filter: ["has", "point_count"],
152
+ layout: {
153
+ "icon-image": this.buildClusterIconExpression(n, r),
154
+ "icon-size": [
155
+ "step",
156
+ ["get", "point_count"],
157
+ 1.3,
158
+ 10,
159
+ 1.6,
160
+ 25,
161
+ 2
162
+ ],
163
+ "icon-ignore-placement": !0,
164
+ "icon-allow-overlap": !0
165
+ },
166
+ paint: { "icon-opacity": .8 }
167
+ }, this.ctx.beforeLayer);
168
+ }
169
+ clusterCountLayer(e, n) {
170
+ let { average: r } = this.clusterLayerIds(e);
171
+ t.map?.addLayer({
172
+ id: r,
173
+ type: "symbol",
174
+ source: e,
175
+ filter: ["has", "point_count"],
176
+ layout: {
177
+ "text-field": ["to-string", ["round", n]],
178
+ "text-size": 12,
179
+ "text-ignore-placement": !0,
180
+ "text-allow-overlap": !0
181
+ },
182
+ paint: { "text-color": this.clusterTextColorExpr(n) }
183
+ }, this.ctx.beforeLayer);
184
+ }
185
+ unclusteredLayer(e) {
186
+ let { unclustered: n } = this.clusterLayerIds(e);
187
+ t.map?.addLayer({
188
+ id: n,
189
+ type: "symbol",
190
+ source: e,
191
+ filter: [
192
+ "all",
193
+ this.ctx.filters,
194
+ ["!", ["has", "point_count"]]
195
+ ],
196
+ layout: {
197
+ "symbol-sort-key": [
198
+ "coalesce",
199
+ ["get", "order"],
200
+ 0
201
+ ],
202
+ "icon-allow-overlap": !0,
203
+ "icon-ignore-placement": !0,
204
+ "icon-image": ["get", "icon"],
205
+ "icon-size": 1
206
+ },
207
+ paint: {}
208
+ }, this.ctx.beforeLayer);
209
+ }
210
+ };
211
+ //#endregion
212
+ export { l as MonitorsClusterRenderer, s as monitorTooltip };
@@ -0,0 +1,71 @@
1
+ import { monitorsManager as e } from "./monitors.svelte.js";
2
+ import { mapManager as t } from "../map/map.svelte.js";
3
+ import { asDataURI as n, circle as r, square as i, triangle as a } from "../map/icons.js";
4
+ import { MapIconManager as o } from "../map/integrations/map-icon-manager.js";
5
+ import * as s from "svelte/internal/client";
6
+ //#region src/lib/monitors/monitors-icon-manager.svelte.ts
7
+ var c = {
8
+ circle: r,
9
+ square: i,
10
+ triangle: a
11
+ }, l = 2, u = "#969696", d = "#48c78e";
12
+ function f(e, t) {
13
+ let n = `${e.location}-${e.is_active ? t.name : "default"}`;
14
+ switch (e.type) {
15
+ case "airgradient": return `${n}-circle`;
16
+ case "airnow":
17
+ case "aqview":
18
+ case "bam1022": return `${n}-triangle`;
19
+ case "purpleair": return `${n}-${e.is_sjvair ? "circle" : "square"}`;
20
+ default: throw Error(`Map icon for ${e.device} has not been set`);
21
+ }
22
+ }
23
+ var p = class extends o {
24
+ get iconSize() {
25
+ return 24;
26
+ }
27
+ constructor() {
28
+ super(), s.effect_root(() => {
29
+ s.user_effect(() => {
30
+ if (e.levels) {
31
+ let r = [
32
+ ...e.levels,
33
+ {
34
+ name: "default",
35
+ color: u
36
+ },
37
+ {
38
+ name: "display",
39
+ color: d
40
+ }
41
+ ];
42
+ for (let e of ["inside", "outside"]) for (let [i, a] of Object.entries(c)) for (let o of r) {
43
+ let r = [
44
+ this.idPrefix,
45
+ e,
46
+ o.name,
47
+ i
48
+ ].filter(Boolean).join("-"), s = n(this.transformSvg(a(o.color, l, e === "inside" ? "#000000" : void 0)));
49
+ if (this.icons.has(r)) {
50
+ let e = this.icons.get(r);
51
+ e.image.src !== s && (e.image.src = s, t.map?.hasImage(r) && this.updateImage(e, t.map));
52
+ continue;
53
+ } else {
54
+ let e = new Image();
55
+ e.src = s, e.width = this.iconSize, e.height = this.iconSize, this.register(r, e);
56
+ }
57
+ }
58
+ }
59
+ });
60
+ });
61
+ }
62
+ }, m = class extends p {
63
+ get idPrefix() {
64
+ return "";
65
+ }
66
+ transformSvg(e) {
67
+ return e;
68
+ }
69
+ };
70
+ //#endregion
71
+ export { p as MonitorShapeIconManager, m as MonitorsIconManager, f as getIconId };
@@ -0,0 +1,270 @@
1
+ import { monitorsManager as e } from "./monitors.svelte.js";
2
+ import { mapManager as t } from "../map/map.svelte.js";
3
+ import { clickManager as n } from "../map/integrations/click-manager.js";
4
+ import { MapIconLayerIntegration as r } from "../map/integrations/map-geojson-integration.svelte.js";
5
+ import { MonitorsIconManager as i, getIconId as a } from "./monitors-icon-manager.svelte.js";
6
+ import { TooltipManager as o } from "../map/integrations/tooltip.svelte.js";
7
+ import { MapDisplayOption as s } from "../map/integrations/map-display-option.svelte.js";
8
+ import { getCurrentLevel as c, getOrder as l } from "./monitor-utils.js";
9
+ import { MonitorsClusterRenderer as u, monitorTooltip as d } from "./monitors-cluster-renderer.js";
10
+ import * as f from "svelte/internal/client";
11
+ import { untrack as p } from "svelte";
12
+ //#region src/lib/monitors/monitors-map-integration.svelte.ts
13
+ var m = {
14
+ monitor(e) {
15
+ return [
16
+ "==",
17
+ ["get", "type"],
18
+ e
19
+ ];
20
+ },
21
+ purpleair() {
22
+ return [
23
+ "all",
24
+ [
25
+ "==",
26
+ ["get", "type"],
27
+ "purpleair"
28
+ ],
29
+ [
30
+ "==",
31
+ ["get", "is_sjvair"],
32
+ !1
33
+ ]
34
+ ];
35
+ },
36
+ sjvPurpleair() {
37
+ return [
38
+ "all",
39
+ [
40
+ "==",
41
+ ["get", "type"],
42
+ "purpleair"
43
+ ],
44
+ [
45
+ "==",
46
+ ["get", "is_sjvair"],
47
+ !0
48
+ ]
49
+ ];
50
+ }
51
+ }, h = new class extends r {
52
+ referenceId = "monitors";
53
+ #e = f.state(!0);
54
+ get enabled() {
55
+ return f.get(this.#e);
56
+ }
57
+ set enabled(e) {
58
+ f.set(this.#e, e, !0);
59
+ }
60
+ #t = f.state(!0);
61
+ get clustered() {
62
+ return f.get(this.#t);
63
+ }
64
+ set clustered(e) {
65
+ f.set(this.#t, e, !0);
66
+ }
67
+ icons = new i();
68
+ tooltipManager = new o();
69
+ renderer = new u(this);
70
+ #n = f.derived(() => ({
71
+ purpleair: new s("PurpleAir", !0, this.icons.get("outside-display-square")),
72
+ sjvair: new s("SJVAir non-FEM", !0, this.icons.get("outside-display-circle")),
73
+ aqview: new s("AQview", !0, this.icons.get("outside-display-triangle")),
74
+ bam1022: new s("SJVAir FEM", !0, this.icons.get("outside-display-triangle")),
75
+ airnow: new s("AirNow", !0, this.icons.get("outside-display-triangle")),
76
+ inactive: new s("Inactive", !1, this.icons.get("outside-default-square")),
77
+ inside: new s("Inside", !1, this.icons.get("inside-display-square"))
78
+ }));
79
+ get displayOptions() {
80
+ return f.get(this.#n);
81
+ }
82
+ set displayOptions(e) {
83
+ f.set(this.#n, e);
84
+ }
85
+ onMonitorClick = null;
86
+ #r = f.state(null);
87
+ get selectedMonitorId() {
88
+ return f.get(this.#r);
89
+ }
90
+ set selectedMonitorId(e) {
91
+ f.set(this.#r, e, !0);
92
+ }
93
+ handleMonitorClick = (e) => {
94
+ if (!this.onMonitorClick) return;
95
+ let n = [...e].sort((e, t) => (t.properties?.order ?? 0) - (e.properties?.order ?? 0))[0];
96
+ if (!n?.properties?.id || (this.selectedMonitorId = n.properties.id, this.onMonitorClick(this.selectedMonitorId), n.geometry.type !== "Point")) return;
97
+ let r = n.geometry.coordinates;
98
+ t.map?.easeTo({
99
+ center: r,
100
+ zoom: Math.max(t.map.getZoom(), 12)
101
+ });
102
+ };
103
+ #i = f.derived(() => {
104
+ if (!e.meta || !e.latest || !e.pollutant) return [];
105
+ let t = e.meta.entryType(e.pollutant).asIter.levels;
106
+ return Array.from(e.latest.values().map((e) => {
107
+ let n = {
108
+ type: "Feature",
109
+ properties: {
110
+ icon: "outside-default-square",
111
+ id: e.id,
112
+ is_active: e.is_active,
113
+ is_sjvair: e.is_sjvair,
114
+ location: e.location,
115
+ name: e.name,
116
+ order: l(e),
117
+ type: e.type,
118
+ value: e.latest.value
119
+ },
120
+ geometry: e.position
121
+ };
122
+ if (t) {
123
+ let r = c(e.latest.value, t);
124
+ r && (n.properties.icon = a(e, r));
125
+ }
126
+ return n;
127
+ }));
128
+ });
129
+ get features() {
130
+ return f.get(this.#i);
131
+ }
132
+ set features(e) {
133
+ f.set(this.#i, e);
134
+ }
135
+ #a = f.derived(() => {
136
+ let e = ["any"], t = ["any", [
137
+ "==",
138
+ ["get", "location"],
139
+ "outside"
140
+ ]], n = ["any", [
141
+ "==",
142
+ ["get", "is_active"],
143
+ !0
144
+ ]];
145
+ return this.displayOptions.purpleair.value && e.push(m.purpleair()), this.displayOptions.aqview.value && e.push(m.monitor("aqview")), this.displayOptions.bam1022.value && e.push(m.monitor("bam1022")), this.displayOptions.airnow.value && e.push(m.monitor("airnow")), this.displayOptions.sjvair.value && e.push(m.sjvPurpleair(), m.monitor("airgradient")), this.displayOptions.inside.value && t.push([
146
+ "==",
147
+ ["get", "location"],
148
+ "inside"
149
+ ]), this.displayOptions.inactive.value && n.push([
150
+ "==",
151
+ ["get", "is_active"],
152
+ !1
153
+ ]), [
154
+ "all",
155
+ e,
156
+ t,
157
+ n
158
+ ];
159
+ });
160
+ get filters() {
161
+ return f.get(this.#a);
162
+ }
163
+ set filters(e) {
164
+ f.set(this.#a, e);
165
+ }
166
+ #o = f.derived(() => {
167
+ let e = this.displayOptions, t = {};
168
+ for (let n of this.features) {
169
+ let r = n.properties;
170
+ if (!r.is_active && !e.inactive.value || r.location === "inside" && !e.inside.value || !({
171
+ purpleair: r.is_sjvair ? e.sjvair.value : e.purpleair.value,
172
+ airgradient: e.sjvair.value,
173
+ aqview: e.aqview.value,
174
+ bam1022: e.bam1022.value,
175
+ airnow: e.airnow.value
176
+ }[r.type] ?? !0)) continue;
177
+ let i = r.type === "purpleair" && r.is_sjvair ? "airgradient" : r.type, a = t[i] ?? [];
178
+ a.push(n), t[i] = a;
179
+ }
180
+ return t;
181
+ });
182
+ get featuresByType() {
183
+ return f.get(this.#o);
184
+ }
185
+ set featuresByType(e) {
186
+ f.set(this.#o, e);
187
+ }
188
+ #s = f.derived(() => !e.meta || !e.pollutant ? [] : e.meta.entryType(e.pollutant).asIter.levels ?? []);
189
+ get clusterIconThresholds() {
190
+ return f.get(this.#s);
191
+ }
192
+ set clusterIconThresholds(e) {
193
+ f.set(this.#s, e);
194
+ }
195
+ get mapLayer() {
196
+ return {
197
+ id: this.referenceId,
198
+ type: "symbol",
199
+ source: this.referenceId,
200
+ filter: this.filters,
201
+ layout: {
202
+ "symbol-sort-key": [
203
+ "coalesce",
204
+ ["get", "order"],
205
+ 0
206
+ ],
207
+ "icon-allow-overlap": !0,
208
+ "icon-ignore-placement": !0,
209
+ "icon-image": ["get", "icon"],
210
+ "icon-size": 1
211
+ },
212
+ paint: {}
213
+ };
214
+ }
215
+ get mapSource() {
216
+ return {
217
+ type: "geojson",
218
+ promoteId: "id",
219
+ data: {
220
+ type: "FeatureCollection",
221
+ features: this.features
222
+ }
223
+ };
224
+ }
225
+ constructor() {
226
+ super(), f.effect_root(() => {
227
+ f.user_effect(() => {
228
+ let e = this.filters;
229
+ t.map && (this.clustered ? this.renderer.syncFilter() : t.map.getLayer(this.referenceId) && t.map.setFilter(this.referenceId, e));
230
+ }), f.user_effect(() => {
231
+ let e = this.features;
232
+ !t.map || this.clustered || t.setDataSource(this.referenceId, e);
233
+ }), f.user_effect(() => {
234
+ this.featuresByType, !(!t.map || !this.clustered) && this.renderer.syncFeatures();
235
+ }), f.user_effect(() => {
236
+ let e = this.clusterIconThresholds;
237
+ !t.map || !this.clustered || !e.length || this.renderer.syncThresholds();
238
+ }), f.user_effect(() => {
239
+ this.clustered;
240
+ let e = Object.keys(this.featuresByType).length > 0;
241
+ !p(() => t.map) || !e || p(() => this.apply());
242
+ }), f.user_effect(() => {
243
+ this.selectedMonitorId, t.map && p(() => this.applySelectedState());
244
+ });
245
+ });
246
+ }
247
+ apply() {
248
+ t.map && (this.tooltipManager.has(this.referenceId) || this.tooltipManager.register(this.referenceId, d), this.clustered ? (t.map.getLayer(this.referenceId) && t.map.removeLayer(this.referenceId), t.map.getSource(this.referenceId) && t.map.removeSource(this.referenceId), n.unregister([this.referenceId]), this.tooltipManager.disable(), this.renderer.remove(), this.icons.loadIcons().then(() => {
249
+ this.renderer.apply(this.handleMonitorClick), this.tooltipManager.enable(), this.applySelectedState();
250
+ })) : (this.tooltipManager.disable(), this.renderer.remove(), this.tooltipManager.enable(), n.unregister([this.referenceId]), super.apply(), this.icons.loadIcons().then(() => {
251
+ n.register([this.referenceId], this.handleMonitorClick), this.applySelectedState();
252
+ })));
253
+ }
254
+ remove() {
255
+ n.unregister([this.referenceId]), this.renderer.remove(), super.remove();
256
+ }
257
+ applySelectedState() {
258
+ if (!t.map) return;
259
+ let e = this.clustered ? this.renderer.unclusteredLayerIds : [this.referenceId], n = this.selectedMonitorId ? [
260
+ "match",
261
+ ["get", "id"],
262
+ this.selectedMonitorId,
263
+ 1.3,
264
+ 1
265
+ ] : 1;
266
+ for (let r of e) t.map.getLayer(r) && t.map.setLayoutProperty(r, "icon-size", n);
267
+ }
268
+ }();
269
+ //#endregion
270
+ export { h as monitorsMapIntegration };
@@ -0,0 +1,68 @@
1
+ import { route as e } from "../src/router.js";
2
+ import * as t from "svelte/internal/client";
3
+ import { getMonitors as n, getMonitorsLatest as r, getMonitorsMeta as i } from "@sjvair/sdk";
4
+ import { XMap as a } from "@tstk/builtin-extensions";
5
+ import { Interval as o } from "@tstk/utils";
6
+ //#region src/lib/monitors/monitors.svelte.ts
7
+ var s = class {
8
+ autoUpdate = new o(async () => await this.update(), 120 * 1e3);
9
+ #e = t.state(!1);
10
+ get initialized() {
11
+ return t.get(this.#e);
12
+ }
13
+ set initialized(e) {
14
+ t.set(this.#e, e, !0);
15
+ }
16
+ #t = t.state(null);
17
+ get latest() {
18
+ return t.get(this.#t);
19
+ }
20
+ set latest(e) {
21
+ t.set(this.#t, e, !0);
22
+ }
23
+ #n = t.state(null);
24
+ get list() {
25
+ return t.get(this.#n);
26
+ }
27
+ set list(e) {
28
+ t.set(this.#n, e, !0);
29
+ }
30
+ #r = t.state(null);
31
+ get meta() {
32
+ return t.get(this.#r);
33
+ }
34
+ set meta(e) {
35
+ t.set(this.#r, e, !0);
36
+ }
37
+ #i = t.state(null);
38
+ get pollutant() {
39
+ return t.get(this.#i);
40
+ }
41
+ set pollutant(e) {
42
+ t.set(this.#i, e, !0);
43
+ }
44
+ #a = t.derived(() => this.meta?.entryType(this.pollutant ?? this.meta.default_pollutant).asIter.levels || null);
45
+ get levels() {
46
+ return t.get(this.#a);
47
+ }
48
+ set levels(e) {
49
+ t.set(this.#a, e);
50
+ }
51
+ async init() {
52
+ if (this.initialized) return;
53
+ [this.list, this.meta] = await Promise.all([n(), i()]);
54
+ let t = e.search.pollutant;
55
+ this.pollutant = t === "pm25" || t === "o3" ? t : this.meta.default_pollutant, this.latest = await c(this.pollutant), this.autoUpdate.start(), this.initialized = !0;
56
+ }
57
+ async update() {
58
+ this.initialized && ([this.list, this.latest] = await Promise.all([n(), c(this.pollutant || this.meta?.default_pollutant || "pm25")]));
59
+ }
60
+ };
61
+ async function c(e) {
62
+ let t = await r(e), n = new a();
63
+ for (let e of t) n.set(e.id, e);
64
+ return n;
65
+ }
66
+ var l = new s();
67
+ //#endregion
68
+ export { l as monitorsManager };