@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.
- package/LICENSE +21 -0
- package/README.md +59 -138
- package/dist/lib/MonitorDetailPanel.svelte +23 -20
- package/dist/lib/MonitorMapLayout.svelte +147 -77
- package/dist/lib/components/DataBox.svelte +4 -1
- package/dist/lib/components/ui/range-calendar/range-calendar.svelte.d.ts +1 -1
- package/dist/lib/config.svelte.d.ts +7 -0
- package/dist/lib/config.svelte.js +10 -0
- package/dist/lib/core.d.ts +2 -2
- package/dist/lib/core.js +2 -1
- package/dist/lib/data-chart/DataChart.svelte +40 -25
- package/dist/lib/data-chart/DateRange.d.ts +13 -4
- package/dist/lib/data-chart/DateRange.js +50 -14
- package/dist/lib/data-chart/chart-utils.js +5 -7
- package/dist/lib/data-chart/level-colors.d.ts +3 -4
- package/dist/lib/data-chart/level-colors.js +7 -4
- package/dist/lib/data-chart/pacific-time.d.ts +9 -0
- package/dist/lib/data-chart/pacific-time.js +25 -0
- package/dist/lib/data-chart/tooltip.js +2 -2
- package/{src/lib/ev-stations/components/EvStationTooltip.svelte → dist/lib/ev-stations/EvPopup.svelte} +6 -5
- package/dist/lib/ev-stations/EvPopup.svelte.d.ts +7 -0
- package/dist/lib/ev-stations/ev-plugin.svelte.d.ts +14 -0
- package/dist/lib/ev-stations/ev-plugin.svelte.js +71 -0
- package/dist/lib/ev-stations/ev-station-icons.d.ts +1 -4
- package/dist/lib/ev-stations/ev-station-icons.js +1 -13
- package/dist/lib/ev-stations/ev-stations.d.ts +7 -0
- package/dist/lib/ev-stations/ev-stations.js +53 -0
- package/dist/lib/ev-stations/ev-store.svelte.d.ts +21 -0
- package/dist/lib/ev-stations/ev-store.svelte.js +83 -0
- package/dist/lib/ev-stations/station-popup.svelte.d.ts +14 -0
- package/dist/lib/ev-stations/station-popup.svelte.js +54 -0
- package/dist/lib/ev-stations/types.d.ts +0 -29
- package/dist/lib/ev-stations/zip-codes.d.ts +11 -0
- package/dist/lib/ev-stations/zip-codes.js +28 -16
- package/dist/lib/index.d.ts +8 -56
- package/dist/lib/index.js +7 -46
- package/dist/lib/legend/Legend.svelte +18 -19
- package/dist/lib/legend/Legend.svelte.d.ts +2 -2
- package/dist/lib/levels.d.ts +7 -0
- package/dist/lib/levels.js +19 -0
- package/dist/lib/map/MapShell.svelte +17 -24
- package/dist/lib/map/MapShell.svelte.d.ts +4 -4
- package/dist/lib/map/basemaps.d.ts +25 -0
- package/dist/lib/map/basemaps.js +66 -0
- package/dist/lib/map/live-map.svelte.d.ts +3 -0
- package/dist/lib/map/live-map.svelte.js +22 -0
- package/dist/lib/map/sync-plugins.svelte.d.ts +19 -0
- package/dist/lib/map/sync-plugins.svelte.js +52 -0
- package/dist/lib/monitors/components/MonitorSubscriptionManager.svelte +66 -61
- package/dist/lib/monitors/filtered-source.svelte.d.ts +9 -0
- package/dist/lib/monitors/filtered-source.svelte.js +28 -0
- package/dist/lib/monitors/monitors.svelte.d.ts +25 -35
- package/dist/lib/monitors/monitors.svelte.js +35 -218
- package/dist/lib/monitors/retry-load.d.ts +8 -0
- package/dist/lib/monitors/retry-load.js +11 -0
- package/dist/lib/monitors/types.d.ts +1 -41
- package/dist/lib/options/map-option-defaults.d.ts +25 -36
- package/dist/lib/options/map-option-defaults.js +12 -30
- package/dist/lib/options/map-options.svelte.d.ts +13 -0
- package/dist/lib/options/map-options.svelte.js +26 -0
- package/dist/lib/options/menus/LayersMenu.svelte +8 -20
- package/dist/lib/options/menus/LayersMenu.svelte.d.ts +17 -2
- package/dist/lib/options/menus/MonitorsMenu.svelte +34 -18
- package/dist/lib/options/menus/OverlaysMenu.svelte +2 -2
- package/dist/lib/options/menus/PollutantMenu.svelte +4 -9
- package/dist/lib/options/menus/SettingsMenu.svelte +32 -25
- package/dist/lib/options/menus/SettingsMenu.svelte.d.ts +5 -16
- package/dist/lib/options/plugin-order.d.ts +8 -0
- package/dist/lib/options/plugin-order.js +36 -0
- package/dist/lib/options/pollutant-param.d.ts +7 -5
- package/dist/lib/options/pollutant-param.js +9 -5
- package/dist/lib/options/row-icons.d.ts +8 -0
- package/dist/lib/options/row-icons.js +15 -0
- package/dist/lib/options/rows/MarkerIcon.svelte +5 -5
- package/dist/lib/options/rows/MarkerIcon.svelte.d.ts +1 -2
- package/dist/lib/search/Search.svelte +20 -33
- package/dist/lib/search/Search.svelte.d.ts +5 -1
- package/dist/lib/search/search-pin.svelte.d.ts +11 -0
- package/dist/lib/search/search-pin.svelte.js +28 -0
- package/dist/lib/search/service.d.ts +7 -2
- package/dist/lib/search/service.js +17 -10
- package/dist/lib/stores.svelte.d.ts +8 -0
- package/dist/lib/stores.svelte.js +9 -0
- package/dist/lib/wind/wind-plugin.d.ts +11 -0
- package/dist/lib/wind/wind-plugin.js +25 -0
- package/package.json +12 -10
- package/src/lib/MonitorDetailPanel.svelte +23 -20
- package/src/lib/MonitorMapLayout.svelte +147 -77
- package/src/lib/components/DataBox.svelte +4 -1
- package/src/lib/config.svelte.ts +16 -0
- package/src/lib/core.ts +2 -2
- package/src/lib/data-chart/DataChart.svelte +40 -25
- package/src/lib/data-chart/DateRange.ts +58 -15
- package/src/lib/data-chart/chart-utils.ts +6 -7
- package/src/lib/data-chart/level-colors.ts +8 -9
- package/src/lib/data-chart/pacific-time.ts +31 -0
- package/src/lib/data-chart/tooltip.ts +2 -2
- package/{dist/lib/ev-stations/components/EvStationTooltip.svelte → src/lib/ev-stations/EvPopup.svelte} +6 -5
- package/src/lib/ev-stations/ev-plugin.svelte.ts +86 -0
- package/src/lib/ev-stations/ev-station-icons.ts +1 -17
- package/src/lib/ev-stations/ev-stations.ts +72 -0
- package/src/lib/ev-stations/ev-store.svelte.ts +117 -0
- package/src/lib/ev-stations/station-popup.svelte.ts +64 -0
- package/src/lib/ev-stations/types.ts +0 -34
- package/src/lib/ev-stations/zip-codes.ts +29 -16
- package/src/lib/index.ts +8 -99
- package/src/lib/legend/Legend.svelte +18 -19
- package/src/lib/levels.ts +24 -0
- package/src/lib/map/MapShell.svelte +17 -24
- package/src/lib/map/basemaps.ts +76 -0
- package/src/lib/map/live-map.svelte.ts +24 -0
- package/src/lib/map/sync-plugins.svelte.ts +69 -0
- package/src/lib/monitors/components/MonitorSubscriptionManager.svelte +66 -61
- package/src/lib/monitors/filtered-source.svelte.ts +38 -0
- package/src/lib/monitors/monitors.svelte.ts +58 -261
- package/src/lib/monitors/retry-load.ts +14 -0
- package/src/lib/monitors/types.ts +1 -47
- package/src/lib/options/map-option-defaults.ts +30 -53
- package/src/lib/options/map-options.svelte.ts +30 -0
- package/src/lib/options/menus/LayersMenu.svelte +8 -20
- package/src/lib/options/menus/MonitorsMenu.svelte +34 -18
- package/src/lib/options/menus/OverlaysMenu.svelte +2 -2
- package/src/lib/options/menus/PollutantMenu.svelte +4 -9
- package/src/lib/options/menus/SettingsMenu.svelte +32 -25
- package/src/lib/options/plugin-order.ts +38 -0
- package/src/lib/options/pollutant-param.ts +14 -9
- package/src/lib/options/row-icons.ts +17 -0
- package/src/lib/options/rows/MarkerIcon.svelte +5 -5
- package/src/lib/search/Search.svelte +20 -33
- package/src/lib/search/search-pin.svelte.ts +35 -0
- package/src/lib/search/service.ts +34 -15
- package/src/lib/stores.svelte.ts +15 -0
- package/src/lib/wind/wind-plugin.ts +33 -0
- package/dist/lib/collocation-sites/CollocationTooltip.svelte +0 -98
- package/dist/lib/collocation-sites/CollocationTooltip.svelte.d.ts +0 -7
- package/dist/lib/collocation-sites/collocations-icon-manager.svelte.d.ts +0 -7
- package/dist/lib/collocation-sites/collocations-icon-manager.svelte.js +0 -18
- package/dist/lib/collocation-sites/collocations-map-integration.svelte.d.ts +0 -21
- package/dist/lib/collocation-sites/collocations-map-integration.svelte.js +0 -113
- package/dist/lib/collocation-sites/collocations.svelte.d.ts +0 -10
- package/dist/lib/collocation-sites/collocations.svelte.js +0 -21
- package/dist/lib/collocation-sites/types.d.ts +0 -8
- package/dist/lib/collocation-sites/types.js +0 -1
- package/dist/lib/ev-stations/components/EvStationClusterTooltip.svelte +0 -16
- package/dist/lib/ev-stations/components/EvStationClusterTooltip.svelte.d.ts +0 -7
- package/dist/lib/ev-stations/components/EvStationTooltip.svelte.d.ts +0 -7
- package/dist/lib/ev-stations/ev-stations-cluster-renderer.d.ts +0 -19
- package/dist/lib/ev-stations/ev-stations-cluster-renderer.js +0 -131
- package/dist/lib/ev-stations/ev-stations-map-integration.svelte.d.ts +0 -31
- package/dist/lib/ev-stations/ev-stations-map-integration.svelte.js +0 -226
- package/dist/lib/ev-stations/ev-stations.svelte.d.ts +0 -10
- package/dist/lib/ev-stations/ev-stations.svelte.js +0 -57
- package/dist/lib/hms/hms-fire-icon-manager.d.ts +0 -13
- package/dist/lib/hms/hms-fire-icon-manager.js +0 -39
- package/dist/lib/hms/hms-fire-map-integration.svelte.d.ts +0 -23
- package/dist/lib/hms/hms-fire-map-integration.svelte.js +0 -94
- package/dist/lib/hms/hms-smoke-map-integration.svelte.d.ts +0 -39
- package/dist/lib/hms/hms-smoke-map-integration.svelte.js +0 -87
- package/dist/lib/hms/hms.svelte.d.ts +0 -20
- package/dist/lib/hms/hms.svelte.js +0 -237
- package/dist/lib/legend/LegendBar.svelte +0 -45
- package/dist/lib/legend/LegendBar.svelte.d.ts +0 -7
- package/dist/lib/legend/legend-data.d.ts +0 -40
- package/dist/lib/legend/legend-data.js +0 -65
- package/dist/lib/map/Map.svelte +0 -13
- package/dist/lib/map/Map.svelte.d.ts +0 -8
- package/dist/lib/map/basemap.d.ts +0 -14
- package/dist/lib/map/basemap.js +0 -10
- package/dist/lib/map/icons.d.ts +0 -7
- package/dist/lib/map/icons.js +0 -33
- package/dist/lib/map/integrations/base-layer-seperator.d.ts +0 -9
- package/dist/lib/map/integrations/base-layer-seperator.js +0 -11
- package/dist/lib/map/integrations/click-manager.d.ts +0 -14
- package/dist/lib/map/integrations/click-manager.js +0 -52
- package/dist/lib/map/integrations/integrations-manager.d.ts +0 -8
- package/dist/lib/map/integrations/integrations-manager.js +0 -20
- package/dist/lib/map/integrations/map-display-option.svelte.d.ts +0 -7
- package/dist/lib/map/integrations/map-display-option.svelte.js +0 -10
- package/dist/lib/map/integrations/map-geojson-integration.svelte.d.ts +0 -32
- package/dist/lib/map/integrations/map-geojson-integration.svelte.js +0 -60
- package/dist/lib/map/integrations/map-icon-manager.d.ts +0 -15
- package/dist/lib/map/integrations/map-icon-manager.js +0 -52
- package/dist/lib/map/integrations/map-integration.svelte.d.ts +0 -6
- package/dist/lib/map/integrations/map-integration.svelte.js +0 -2
- package/dist/lib/map/integrations/map-layer-integration.svelte.d.ts +0 -11
- package/dist/lib/map/integrations/map-layer-integration.svelte.js +0 -40
- package/dist/lib/map/integrations/tooltip.svelte.d.ts +0 -36
- package/dist/lib/map/integrations/tooltip.svelte.js +0 -131
- package/dist/lib/map/integrations/types.d.ts +0 -14
- package/dist/lib/map/integrations/types.js +0 -1
- package/dist/lib/map/map-manager.svelte.d.ts +0 -20
- package/dist/lib/map/map-manager.svelte.js +0 -63
- package/dist/lib/map/map-style-state.svelte.d.ts +0 -23
- package/dist/lib/map/map-style-state.svelte.js +0 -86
- package/dist/lib/map/utils.d.ts +0 -7
- package/dist/lib/map/utils.js +0 -36
- package/dist/lib/monitors/components/MonitorClusterTooltip.svelte +0 -112
- package/dist/lib/monitors/components/MonitorClusterTooltip.svelte.d.ts +0 -7
- package/dist/lib/monitors/components/MonitorTooltip.svelte +0 -61
- package/dist/lib/monitors/components/MonitorTooltip.svelte.d.ts +0 -7
- package/dist/lib/monitors/monitor-utils.d.ts +0 -4
- package/dist/lib/monitors/monitor-utils.js +0 -41
- package/dist/lib/monitors/monitors-cluster-renderer.d.ts +0 -33
- package/dist/lib/monitors/monitors-cluster-renderer.js +0 -221
- package/dist/lib/monitors/monitors-icon-manager.svelte.d.ts +0 -15
- package/dist/lib/monitors/monitors-icon-manager.svelte.js +0 -78
- package/dist/lib/monitors/monitors-map-integration.svelte.d.ts +0 -43
- package/dist/lib/monitors/monitors-map-integration.svelte.js +0 -301
- package/dist/lib/options/reset-map-options.d.ts +0 -2
- package/dist/lib/options/reset-map-options.js +0 -24
- package/dist/lib/reactivity.svelte.d.ts +0 -0
- package/dist/lib/reactivity.svelte.js +0 -83
- package/dist/lib/wind/wind.svelte.d.ts +0 -10
- package/dist/lib/wind/wind.svelte.js +0 -13
- package/src/lib/collocation-sites/CollocationTooltip.svelte +0 -98
- package/src/lib/collocation-sites/collocations-icon-manager.svelte.ts +0 -21
- package/src/lib/collocation-sites/collocations-map-integration.svelte.ts +0 -136
- package/src/lib/collocation-sites/collocations.svelte.ts +0 -27
- package/src/lib/collocation-sites/types.ts +0 -10
- package/src/lib/ev-stations/components/EvStationClusterTooltip.svelte +0 -16
- package/src/lib/ev-stations/ev-stations-cluster-renderer.ts +0 -162
- package/src/lib/ev-stations/ev-stations-map-integration.svelte.ts +0 -248
- package/src/lib/ev-stations/ev-stations.svelte.ts +0 -84
- package/src/lib/hms/hms-fire-icon-manager.ts +0 -48
- package/src/lib/hms/hms-fire-map-integration.svelte.ts +0 -109
- package/src/lib/hms/hms-smoke-map-integration.svelte.ts +0 -105
- package/src/lib/hms/hms.svelte.ts +0 -270
- package/src/lib/legend/LegendBar.svelte +0 -45
- package/src/lib/legend/legend-data.ts +0 -101
- package/src/lib/map/Map.svelte +0 -13
- package/src/lib/map/basemap.ts +0 -24
- package/src/lib/map/icons.ts +0 -42
- package/src/lib/map/integrations/base-layer-seperator.ts +0 -17
- package/src/lib/map/integrations/click-manager.ts +0 -64
- package/src/lib/map/integrations/integrations-manager.ts +0 -25
- package/src/lib/map/integrations/map-display-option.svelte.ts +0 -13
- package/src/lib/map/integrations/map-geojson-integration.svelte.ts +0 -77
- package/src/lib/map/integrations/map-icon-manager.ts +0 -67
- package/src/lib/map/integrations/map-integration.svelte.ts +0 -8
- package/src/lib/map/integrations/map-layer-integration.svelte.ts +0 -49
- package/src/lib/map/integrations/tooltip.svelte.ts +0 -153
- package/src/lib/map/integrations/types.ts +0 -24
- package/src/lib/map/map-manager.svelte.ts +0 -83
- package/src/lib/map/map-style-state.svelte.ts +0 -94
- package/src/lib/map/utils.ts +0 -53
- package/src/lib/monitors/components/MonitorClusterTooltip.svelte +0 -112
- package/src/lib/monitors/components/MonitorTooltip.svelte +0 -61
- package/src/lib/monitors/monitor-utils.ts +0 -57
- package/src/lib/monitors/monitors-cluster-renderer.ts +0 -285
- package/src/lib/monitors/monitors-icon-manager.svelte.ts +0 -98
- package/src/lib/monitors/monitors-map-integration.svelte.ts +0 -318
- package/src/lib/options/reset-map-options.ts +0 -28
- package/src/lib/reactivity.svelte.ts +0 -82
- package/src/lib/wind/wind.svelte.ts +0 -20
|
@@ -1,112 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { Geometry } from "geojson";
|
|
3
|
-
import { GeoJSONSource } from "@maptiler/sdk";
|
|
4
|
-
import type { SJVAirEntryLevel } from "@sjvair/sdk";
|
|
5
|
-
import type { ComponentProps } from "svelte";
|
|
6
|
-
import { area } from "@turf/area";
|
|
7
|
-
import { convertArea } from "@turf/helpers";
|
|
8
|
-
import DataBox from "../../components/DataBox.svelte";
|
|
9
|
-
import { mapManager } from "../../map/map-manager.svelte.js";
|
|
10
|
-
import type { MonitorClusterMapFeature, MonitorMapFeature } from "../types";
|
|
11
|
-
import { monitorsManager } from "../monitors.svelte";
|
|
12
|
-
import { getCurrentLevel } from "../monitor-utils";
|
|
13
|
-
|
|
14
|
-
interface MonitorClusterTooltipProps {
|
|
15
|
-
feature: MonitorClusterMapFeature;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
interface MonitorClusterTooltipData extends ComponentProps<typeof DataBox> {
|
|
19
|
-
clusterType: string;
|
|
20
|
-
count: number;
|
|
21
|
-
coverage?: string;
|
|
22
|
-
max: number;
|
|
23
|
-
min: number;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
const { feature }: MonitorClusterTooltipProps = $props();
|
|
27
|
-
|
|
28
|
-
let data: MonitorClusterTooltipData | undefined = $state();
|
|
29
|
-
|
|
30
|
-
$effect(() => {
|
|
31
|
-
const source = mapManager.map!.getSource(feature.source)! as GeoJSONSource;
|
|
32
|
-
const latest = monitorsManager.latest;
|
|
33
|
-
const meta = monitorsManager.meta;
|
|
34
|
-
|
|
35
|
-
source
|
|
36
|
-
.getClusterLeaves(feature.properties.cluster_id, feature.properties.point_count, 0)
|
|
37
|
-
.then((features) => {
|
|
38
|
-
//const monitor = monitorsManager.latest?.get(feature.properties.id);
|
|
39
|
-
|
|
40
|
-
if (!features.length || !meta || !latest) return;
|
|
41
|
-
const monitors = (features as Array<MonitorMapFeature>).map((f) =>
|
|
42
|
-
latest?.get(f.properties.id)
|
|
43
|
-
);
|
|
44
|
-
|
|
45
|
-
const firstMonitor = monitors[0];
|
|
46
|
-
if (!firstMonitor) return;
|
|
47
|
-
|
|
48
|
-
const entryType = meta.entryType(firstMonitor.latest.entry_type);
|
|
49
|
-
const monitorType = meta.monitorType(firstMonitor.type);
|
|
50
|
-
|
|
51
|
-
const coords = monitors.map((m) => m!.position!.coordinates);
|
|
52
|
-
const values = monitors.map((m) => parseFloat(m?.latest.value ?? "0"));
|
|
53
|
-
|
|
54
|
-
const avg = Math.round(values.reduce((sum, value) => sum + value, 0) / monitors.length);
|
|
55
|
-
|
|
56
|
-
const level: SJVAirEntryLevel | undefined = getCurrentLevel(avg, entryType.asIter.levels!);
|
|
57
|
-
|
|
58
|
-
data = {
|
|
59
|
-
color: level?.color || "#d3d3d3",
|
|
60
|
-
count: feature.properties.point_count,
|
|
61
|
-
coverage: calculateArea(coords),
|
|
62
|
-
header: entryType.label,
|
|
63
|
-
clusterType: `${firstMonitor.is_sjvair ? "SJVAir " : ""}${monitorType.label} Monitors`,
|
|
64
|
-
subheading: "(cluster avg)",
|
|
65
|
-
max: values.reduce((prev, current) => (prev > current ? prev : current)),
|
|
66
|
-
min: values.reduce((prev, current) => (prev < current ? prev : current)),
|
|
67
|
-
value: avg.toString()
|
|
68
|
-
};
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
function calculateArea(coords: Array<Array<number>>) {
|
|
72
|
-
// TODO: update to handle lines as well as area (only 2 in cluster)
|
|
73
|
-
if (coords.length === 3) {
|
|
74
|
-
coords.push(coords[0]);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
const coverage = area({
|
|
78
|
-
type: "Feature",
|
|
79
|
-
geometry: {
|
|
80
|
-
type: "Polygon",
|
|
81
|
-
coordinates: [coords]
|
|
82
|
-
}
|
|
83
|
-
} as unknown as Geometry);
|
|
84
|
-
|
|
85
|
-
return coverage > 0 ? convertArea(coverage, "meters", "miles").toFixed(3) : undefined;
|
|
86
|
-
}
|
|
87
|
-
});
|
|
88
|
-
</script>
|
|
89
|
-
|
|
90
|
-
{#if data}
|
|
91
|
-
<div class="flex gap-2">
|
|
92
|
-
<DataBox
|
|
93
|
-
color={data.color}
|
|
94
|
-
header={data.header}
|
|
95
|
-
subheading={data.subheading}
|
|
96
|
-
value={data.value}
|
|
97
|
-
/>
|
|
98
|
-
<div class="flex flex-col">
|
|
99
|
-
<h1 class="text-lg font-bold">{data.clusterType}</h1>
|
|
100
|
-
<p>
|
|
101
|
-
{data.count} monitors
|
|
102
|
-
{#if data.coverage}
|
|
103
|
-
<span>covering {data.coverage}mi²</span>
|
|
104
|
-
{/if}
|
|
105
|
-
</p>
|
|
106
|
-
<div class="mt-auto">
|
|
107
|
-
<p class="text-base">Max: {data.max}µg/m³</p>
|
|
108
|
-
<p class="text-base leading-none">Min: {data.min}µg/m³</p>
|
|
109
|
-
</div>
|
|
110
|
-
</div>
|
|
111
|
-
</div>
|
|
112
|
-
{/if}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { MonitorClusterMapFeature } from "../types";
|
|
2
|
-
interface MonitorClusterTooltipProps {
|
|
3
|
-
feature: MonitorClusterMapFeature;
|
|
4
|
-
}
|
|
5
|
-
declare const MonitorClusterTooltip: import("svelte").Component<MonitorClusterTooltipProps, {}, "">;
|
|
6
|
-
type MonitorClusterTooltip = ReturnType<typeof MonitorClusterTooltip>;
|
|
7
|
-
export default MonitorClusterTooltip;
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { SJVAirEntryLevel } from "@sjvair/sdk";
|
|
3
|
-
import { format, formatDistanceToNow } from "date-fns";
|
|
4
|
-
import DataBox from "../../components/DataBox.svelte";
|
|
5
|
-
import { monitorsManager } from "../monitors.svelte";
|
|
6
|
-
import { getCurrentLevel } from "../monitor-utils";
|
|
7
|
-
import type { MonitorMapFeature } from "../types";
|
|
8
|
-
|
|
9
|
-
interface MonitorTooltipProps {
|
|
10
|
-
feature: MonitorMapFeature;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const { feature }: MonitorTooltipProps = $props();
|
|
14
|
-
|
|
15
|
-
const data = $derived.by(() => {
|
|
16
|
-
const monitor = monitorsManager.latest?.get(feature.properties.id);
|
|
17
|
-
|
|
18
|
-
if (!monitor || !monitorsManager.meta) return;
|
|
19
|
-
|
|
20
|
-
const entryType = monitorsManager.meta.entryType(monitor.latest.entry_type);
|
|
21
|
-
const level: SJVAirEntryLevel | undefined = getCurrentLevel(
|
|
22
|
-
monitor.latest.value,
|
|
23
|
-
entryType.asIter.levels!
|
|
24
|
-
);
|
|
25
|
-
|
|
26
|
-
const updateDuration = monitorsManager.meta.monitorType(monitor.type).expected_interval;
|
|
27
|
-
|
|
28
|
-
return {
|
|
29
|
-
color: level?.color ?? "",
|
|
30
|
-
header: entryType.label,
|
|
31
|
-
date: {
|
|
32
|
-
formatted: format(monitor.latest.timestamp, "h:mm:aaa EEEE MMM dd, yyyy"),
|
|
33
|
-
diference: formatDistanceToNow(monitor.latest.timestamp, {
|
|
34
|
-
addSuffix: true,
|
|
35
|
-
includeSeconds: true
|
|
36
|
-
})
|
|
37
|
-
},
|
|
38
|
-
subheading: `(${updateDuration} avg)`,
|
|
39
|
-
value: Math.round(parseInt(monitor.latest.value, 10)).toString()
|
|
40
|
-
};
|
|
41
|
-
});
|
|
42
|
-
</script>
|
|
43
|
-
|
|
44
|
-
{#if data}
|
|
45
|
-
<div class="flex gap-2">
|
|
46
|
-
<DataBox
|
|
47
|
-
color={data.color}
|
|
48
|
-
header={data.header}
|
|
49
|
-
subheading={data.subheading}
|
|
50
|
-
value={data.value}
|
|
51
|
-
/>
|
|
52
|
-
<div class="flex flex-col">
|
|
53
|
-
<p>{data.date.formatted}</p>
|
|
54
|
-
<h1 class="text-lg font-bold underline">{feature.properties.name}</h1>
|
|
55
|
-
<div class="mt-auto">
|
|
56
|
-
<p class="text-base leading-none">Last updated</p>
|
|
57
|
-
<p class="text-base leading-none">{data.date.diference}</p>
|
|
58
|
-
</div>
|
|
59
|
-
</div>
|
|
60
|
-
</div>
|
|
61
|
-
{/if}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { MonitorMapFeature } from "../types";
|
|
2
|
-
interface MonitorTooltipProps {
|
|
3
|
-
feature: MonitorMapFeature;
|
|
4
|
-
}
|
|
5
|
-
declare const MonitorTooltip: import("svelte").Component<MonitorTooltipProps, {}, "">;
|
|
6
|
-
type MonitorTooltip = ReturnType<typeof MonitorTooltip>;
|
|
7
|
-
export default MonitorTooltip;
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import type { MonitorData, SJVAirEntryLevel } from "@sjvair/sdk";
|
|
2
|
-
export declare function getCurrentLevel(value: string | number, levels: Array<SJVAirEntryLevel>): SJVAirEntryLevel | undefined;
|
|
3
|
-
export declare function getOrder(monitor: MonitorData): number;
|
|
4
|
-
export declare function getTypeShape(type: string): string;
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
export function getCurrentLevel(value, levels) {
|
|
2
|
-
value = typeof value === "string" ? parseInt(value, 10) : value;
|
|
3
|
-
return levels.find((lvl) => {
|
|
4
|
-
return value >= lvl.range[0] && value <= lvl.range[1];
|
|
5
|
-
});
|
|
6
|
-
}
|
|
7
|
-
export function getOrder(monitor) {
|
|
8
|
-
switch (monitor.type) {
|
|
9
|
-
case "airgradient":
|
|
10
|
-
return 5;
|
|
11
|
-
case "airnow":
|
|
12
|
-
return 2;
|
|
13
|
-
case "aqview":
|
|
14
|
-
return 3;
|
|
15
|
-
case "bam1022":
|
|
16
|
-
return 6;
|
|
17
|
-
case "purpleair":
|
|
18
|
-
return monitor.is_sjvair ? 4 : 1;
|
|
19
|
-
case "vozbox":
|
|
20
|
-
return 7;
|
|
21
|
-
case "aqlite":
|
|
22
|
-
return 8;
|
|
23
|
-
default:
|
|
24
|
-
throw new Error(`Map ordering for ${monitor.device} has not been set`);
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
export function getTypeShape(type) {
|
|
28
|
-
switch (type) {
|
|
29
|
-
case "airnow":
|
|
30
|
-
case "aqview":
|
|
31
|
-
case "bam1022":
|
|
32
|
-
case "aqlite":
|
|
33
|
-
return "triangle";
|
|
34
|
-
case "airgradient":
|
|
35
|
-
case "purpleair":
|
|
36
|
-
case "vozbox":
|
|
37
|
-
return "circle";
|
|
38
|
-
default:
|
|
39
|
-
return "circle";
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
import type { FilterSpecification, MapLayerEventType, Popup } from "@maptiler/sdk";
|
|
2
|
-
import type { SJVAirEntryLevel } from "@sjvair/sdk";
|
|
3
|
-
import { type ClickHandler } from "../map/integrations/click-manager";
|
|
4
|
-
import { TooltipManager } from "../map/integrations/tooltip.svelte";
|
|
5
|
-
import type { MonitorMapFeature } from "./types";
|
|
6
|
-
export declare function monitorTooltip(evt: MapLayerEventType["mousemove"] & object): Popup | void;
|
|
7
|
-
export interface MonitorsClusterContext {
|
|
8
|
-
referenceId: string;
|
|
9
|
-
featuresByType: Record<string, MonitorMapFeature[]>;
|
|
10
|
-
filters: FilterSpecification;
|
|
11
|
-
clusterIconThresholds: SJVAirEntryLevel[];
|
|
12
|
-
beforeLayer?: string;
|
|
13
|
-
tooltipManager: TooltipManager;
|
|
14
|
-
}
|
|
15
|
-
export declare class MonitorsClusterRenderer {
|
|
16
|
-
private ctx;
|
|
17
|
-
private _clusterTypes;
|
|
18
|
-
constructor(ctx: MonitorsClusterContext);
|
|
19
|
-
apply(monitorClickHandler: ClickHandler): void;
|
|
20
|
-
remove(): void;
|
|
21
|
-
get unclusteredLayerIds(): string[];
|
|
22
|
-
syncFeatures(): void;
|
|
23
|
-
syncFilter(): void;
|
|
24
|
-
syncThresholds(): void;
|
|
25
|
-
private makeClusterClickHandler;
|
|
26
|
-
private clusterLayerIds;
|
|
27
|
-
private get clusterTextColorThreshold();
|
|
28
|
-
private clusterTextColorExpr;
|
|
29
|
-
private buildClusterIconExpression;
|
|
30
|
-
private monitorTypeIconsLayer;
|
|
31
|
-
private clusterCountLayer;
|
|
32
|
-
private unclusteredLayer;
|
|
33
|
-
}
|
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
import { mapManager } from "../map/map-manager.svelte.js";
|
|
2
|
-
import { mountPopup } from "../map/utils";
|
|
3
|
-
import { clickManager } from "../map/integrations/click-manager";
|
|
4
|
-
import { getTypeShape } from "./monitor-utils";
|
|
5
|
-
import MonitorTooltip from "./components/MonitorTooltip.svelte";
|
|
6
|
-
import MonitorClusterTooltip from "./components/MonitorClusterTooltip.svelte";
|
|
7
|
-
const AVG_EXPR = [
|
|
8
|
-
"/",
|
|
9
|
-
["get", "sumValues"],
|
|
10
|
-
["max", ["get", "point_count"], 1]
|
|
11
|
-
];
|
|
12
|
-
export function monitorTooltip(evt) {
|
|
13
|
-
const features = evt.features;
|
|
14
|
-
const feature = features?.sort((a, b) => b.properties.order - a.properties.order)[0];
|
|
15
|
-
if (!feature)
|
|
16
|
-
return;
|
|
17
|
-
return mountPopup(MonitorTooltip, { feature }, evt.lngLat);
|
|
18
|
-
}
|
|
19
|
-
function clusterTooltip(evt) {
|
|
20
|
-
const feature = evt.features?.[0];
|
|
21
|
-
if (!feature)
|
|
22
|
-
return;
|
|
23
|
-
return mountPopup(MonitorClusterTooltip, { feature }, evt.lngLat);
|
|
24
|
-
}
|
|
25
|
-
export class MonitorsClusterRenderer {
|
|
26
|
-
ctx;
|
|
27
|
-
_clusterTypes = [];
|
|
28
|
-
constructor(ctx) {
|
|
29
|
-
this.ctx = ctx;
|
|
30
|
-
}
|
|
31
|
-
apply(monitorClickHandler) {
|
|
32
|
-
if (!mapManager.map)
|
|
33
|
-
return;
|
|
34
|
-
const sortedEntries = Object.entries(this.ctx.featuresByType).sort(([, a], [, b]) => {
|
|
35
|
-
const maxOrder = (fs) => fs.reduce((m, f) => Math.max(m, f.properties.order), 0);
|
|
36
|
-
return maxOrder(a) - maxOrder(b);
|
|
37
|
-
});
|
|
38
|
-
for (const [[type, features], index] of sortedEntries.map((e, i) => [e, i])) {
|
|
39
|
-
const sourceId = `${this.ctx.referenceId}-${type}`;
|
|
40
|
-
mapManager.map.addSource(sourceId, {
|
|
41
|
-
type: "geojson",
|
|
42
|
-
promoteId: "id",
|
|
43
|
-
data: { type: "FeatureCollection", features },
|
|
44
|
-
cluster: true,
|
|
45
|
-
clusterRadius: 40,
|
|
46
|
-
clusterMaxZoom: 9,
|
|
47
|
-
clusterProperties: {
|
|
48
|
-
sumValues: ["+", ["to-number", ["get", "value"]], 0]
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
this.monitorTypeIconsLayer(sourceId, AVG_EXPR, getTypeShape(type));
|
|
52
|
-
this.clusterCountLayer(sourceId, AVG_EXPR);
|
|
53
|
-
this.unclusteredLayer(sourceId);
|
|
54
|
-
const { icon, unclustered } = this.clusterLayerIds(sourceId);
|
|
55
|
-
if (!this.ctx.tooltipManager.has(icon)) {
|
|
56
|
-
this.ctx.tooltipManager.register(icon, clusterTooltip, index);
|
|
57
|
-
}
|
|
58
|
-
if (!this.ctx.tooltipManager.has(unclustered)) {
|
|
59
|
-
this.ctx.tooltipManager.register(unclustered, monitorTooltip, index);
|
|
60
|
-
}
|
|
61
|
-
clickManager.register([unclustered], monitorClickHandler);
|
|
62
|
-
clickManager.register([icon], this.makeClusterClickHandler(sourceId));
|
|
63
|
-
this._clusterTypes.push(type);
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
remove() {
|
|
67
|
-
if (!mapManager.map)
|
|
68
|
-
return;
|
|
69
|
-
for (const type of this._clusterTypes) {
|
|
70
|
-
const sourceId = `${this.ctx.referenceId}-${type}`;
|
|
71
|
-
const layers = this.clusterLayerIds(sourceId);
|
|
72
|
-
clickManager.unregister([layers.unclustered]);
|
|
73
|
-
clickManager.unregister([layers.icon]);
|
|
74
|
-
for (const layerId of Object.values(layers)) {
|
|
75
|
-
if (mapManager.map.getLayer(layerId)) {
|
|
76
|
-
mapManager.map.removeLayer(layerId);
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
if (mapManager.map.getSource(sourceId)) {
|
|
80
|
-
mapManager.map.removeSource(sourceId);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
this._clusterTypes = [];
|
|
84
|
-
}
|
|
85
|
-
get unclusteredLayerIds() {
|
|
86
|
-
return this._clusterTypes.map((type) => `${this.ctx.referenceId}-${type}-unclustered`);
|
|
87
|
-
}
|
|
88
|
-
syncFeatures() {
|
|
89
|
-
if (!mapManager.map)
|
|
90
|
-
return;
|
|
91
|
-
for (const type of this._clusterTypes) {
|
|
92
|
-
const sourceId = `${this.ctx.referenceId}-${type}`;
|
|
93
|
-
mapManager.setDataSource(sourceId, this.ctx.featuresByType[type] ?? []);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
syncFilter() {
|
|
97
|
-
if (!mapManager.map)
|
|
98
|
-
return;
|
|
99
|
-
for (const type of this._clusterTypes) {
|
|
100
|
-
const sourceId = `${this.ctx.referenceId}-${type}`;
|
|
101
|
-
const { unclustered } = this.clusterLayerIds(sourceId);
|
|
102
|
-
if (mapManager.map.getLayer(unclustered)) {
|
|
103
|
-
mapManager.map.setFilter(unclustered, [
|
|
104
|
-
"all",
|
|
105
|
-
this.ctx.filters,
|
|
106
|
-
["!", ["has", "point_count"]]
|
|
107
|
-
]);
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
}
|
|
111
|
-
syncThresholds() {
|
|
112
|
-
if (!mapManager.map)
|
|
113
|
-
return;
|
|
114
|
-
for (const type of this._clusterTypes) {
|
|
115
|
-
const sourceId = `${this.ctx.referenceId}-${type}`;
|
|
116
|
-
const { icon, average } = this.clusterLayerIds(sourceId);
|
|
117
|
-
if (mapManager.map.getLayer(icon)) {
|
|
118
|
-
mapManager.map.setLayoutProperty(icon, "icon-image", this.buildClusterIconExpression(AVG_EXPR, getTypeShape(type)));
|
|
119
|
-
}
|
|
120
|
-
if (mapManager.map.getLayer(average)) {
|
|
121
|
-
mapManager.map.setPaintProperty(average, "text-color", this.clusterTextColorExpr(AVG_EXPR));
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
}
|
|
125
|
-
makeClusterClickHandler(sourceId) {
|
|
126
|
-
return async (features) => {
|
|
127
|
-
try {
|
|
128
|
-
const feature = features[0];
|
|
129
|
-
if (!feature?.properties?.cluster_id)
|
|
130
|
-
return;
|
|
131
|
-
const source = mapManager.map?.getSource(sourceId);
|
|
132
|
-
if (!source)
|
|
133
|
-
return;
|
|
134
|
-
const zoom = await source.getClusterExpansionZoom(feature.properties.cluster_id);
|
|
135
|
-
const coords = feature.geometry.coordinates;
|
|
136
|
-
mapManager.map?.easeTo({ center: coords, zoom });
|
|
137
|
-
}
|
|
138
|
-
catch (err) {
|
|
139
|
-
console.error("ClickManager: cluster expansion zoom failed", err);
|
|
140
|
-
}
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
clusterLayerIds(sourceId) {
|
|
144
|
-
return {
|
|
145
|
-
icon: `${sourceId}-cluster-icon`,
|
|
146
|
-
average: `${sourceId}-cluster-average`,
|
|
147
|
-
unclustered: `${sourceId}-unclustered`
|
|
148
|
-
};
|
|
149
|
-
}
|
|
150
|
-
get clusterTextColorThreshold() {
|
|
151
|
-
// Use the max of the 3rd level (unhealthy_sensitive) so text flips to white at unhealthy+
|
|
152
|
-
return this.ctx.clusterIconThresholds[2]?.range[1] ?? 150.5;
|
|
153
|
-
}
|
|
154
|
-
clusterTextColorExpr(avgExpr) {
|
|
155
|
-
return ["case", ["<=", avgExpr, this.clusterTextColorThreshold], "#000000", "#FFFFFF"];
|
|
156
|
-
}
|
|
157
|
-
buildClusterIconExpression(avgExpr, shape) {
|
|
158
|
-
const thresholds = this.ctx.clusterIconThresholds;
|
|
159
|
-
if (!thresholds.length)
|
|
160
|
-
return `outside-default-${shape}`;
|
|
161
|
-
const expr = ["case"];
|
|
162
|
-
for (const level of thresholds.slice(0, -1)) {
|
|
163
|
-
expr.push(["<=", avgExpr, level.range[1]], `outside-${level.name}-${shape}`);
|
|
164
|
-
}
|
|
165
|
-
expr.push(`outside-${thresholds.at(-1).name}-${shape}`);
|
|
166
|
-
return expr;
|
|
167
|
-
}
|
|
168
|
-
monitorTypeIconsLayer(sourceId, avgExpr, shape) {
|
|
169
|
-
const { icon } = this.clusterLayerIds(sourceId);
|
|
170
|
-
mapManager.map?.addLayer({
|
|
171
|
-
id: icon,
|
|
172
|
-
type: "symbol",
|
|
173
|
-
source: sourceId,
|
|
174
|
-
filter: ["has", "point_count"],
|
|
175
|
-
layout: {
|
|
176
|
-
"icon-image": this.buildClusterIconExpression(avgExpr, shape),
|
|
177
|
-
"icon-size": ["step", ["get", "point_count"], 1.3, 10, 1.6, 25, 2.0],
|
|
178
|
-
"icon-ignore-placement": true,
|
|
179
|
-
"icon-allow-overlap": true
|
|
180
|
-
},
|
|
181
|
-
paint: {
|
|
182
|
-
"icon-opacity": 0.8
|
|
183
|
-
}
|
|
184
|
-
}, this.ctx.beforeLayer);
|
|
185
|
-
}
|
|
186
|
-
clusterCountLayer(sourceId, avgExpr) {
|
|
187
|
-
const { average } = this.clusterLayerIds(sourceId);
|
|
188
|
-
mapManager.map?.addLayer({
|
|
189
|
-
id: average,
|
|
190
|
-
type: "symbol",
|
|
191
|
-
source: sourceId,
|
|
192
|
-
filter: ["has", "point_count"],
|
|
193
|
-
layout: {
|
|
194
|
-
"text-field": ["to-string", ["round", avgExpr]],
|
|
195
|
-
"text-size": 12,
|
|
196
|
-
"text-ignore-placement": true,
|
|
197
|
-
"text-allow-overlap": true
|
|
198
|
-
},
|
|
199
|
-
paint: {
|
|
200
|
-
"text-color": this.clusterTextColorExpr(avgExpr)
|
|
201
|
-
}
|
|
202
|
-
}, this.ctx.beforeLayer);
|
|
203
|
-
}
|
|
204
|
-
unclusteredLayer(sourceId) {
|
|
205
|
-
const { unclustered } = this.clusterLayerIds(sourceId);
|
|
206
|
-
mapManager.map?.addLayer({
|
|
207
|
-
id: unclustered,
|
|
208
|
-
type: "symbol",
|
|
209
|
-
source: sourceId,
|
|
210
|
-
filter: ["all", this.ctx.filters, ["!", ["has", "point_count"]]],
|
|
211
|
-
layout: {
|
|
212
|
-
"symbol-sort-key": ["coalesce", ["get", "order"], 0],
|
|
213
|
-
"icon-allow-overlap": true,
|
|
214
|
-
"icon-ignore-placement": true,
|
|
215
|
-
"icon-image": ["get", "icon"],
|
|
216
|
-
"icon-size": 1
|
|
217
|
-
},
|
|
218
|
-
paint: {}
|
|
219
|
-
}, this.ctx.beforeLayer);
|
|
220
|
-
}
|
|
221
|
-
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import type { MonitorData, SJVAirEntryLevel } from "@sjvair/sdk";
|
|
2
|
-
import { MapIconManager } from "../map/integrations/map-icon-manager";
|
|
3
|
-
import type { MonitorsDataSource } from "./types";
|
|
4
|
-
export declare function getIconId<T extends MonitorData>(monitor: T, level: SJVAirEntryLevel): string;
|
|
5
|
-
export declare abstract class MonitorShapeIconManager extends MapIconManager {
|
|
6
|
-
private dataSource;
|
|
7
|
-
protected abstract get idPrefix(): string;
|
|
8
|
-
protected abstract transformSvg(svg: string): string;
|
|
9
|
-
protected get iconSize(): number;
|
|
10
|
-
constructor(dataSource: Pick<MonitorsDataSource, "levels">);
|
|
11
|
-
}
|
|
12
|
-
export declare class MonitorsIconManager extends MonitorShapeIconManager {
|
|
13
|
-
protected get idPrefix(): string;
|
|
14
|
-
protected transformSvg(svg: string): string;
|
|
15
|
-
}
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
import { asDataURI, circle, square, triangle } from "../map/icons";
|
|
2
|
-
import { MapIconManager } from "../map/integrations/map-icon-manager";
|
|
3
|
-
import { mapManager } from "../map/map-manager.svelte.js";
|
|
4
|
-
const MONITOR_ICONS = { circle, square, triangle };
|
|
5
|
-
const MONITOR_ICON_BORDER_WIDTH = 2;
|
|
6
|
-
const MONITOR_ICON_DEFAULT_COLOR = "#969696"; // light gray
|
|
7
|
-
const MONITOR_ICON_DISPLAY_COLOR = "#48c78e"; // light gray
|
|
8
|
-
export function getIconId(monitor, level) {
|
|
9
|
-
const id = `${monitor.location}-${monitor.is_active ? level.name : "default"}`;
|
|
10
|
-
switch (monitor.type) {
|
|
11
|
-
case "airnow":
|
|
12
|
-
case "aqview":
|
|
13
|
-
case "bam1022":
|
|
14
|
-
case "aqlite":
|
|
15
|
-
return `${id}-triangle`;
|
|
16
|
-
case "airgradient":
|
|
17
|
-
case "purpleair":
|
|
18
|
-
case "vozbox":
|
|
19
|
-
return `${id}-circle`;
|
|
20
|
-
default:
|
|
21
|
-
throw new Error(`Map icon for ${monitor.device} has not been set`);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
export class MonitorShapeIconManager extends MapIconManager {
|
|
25
|
-
dataSource;
|
|
26
|
-
get iconSize() {
|
|
27
|
-
return 24;
|
|
28
|
-
}
|
|
29
|
-
constructor(dataSource) {
|
|
30
|
-
super();
|
|
31
|
-
this.dataSource = dataSource;
|
|
32
|
-
$effect.root(() => {
|
|
33
|
-
$effect(() => {
|
|
34
|
-
if (this.dataSource.levels) {
|
|
35
|
-
const iconLevels = [
|
|
36
|
-
...this.dataSource.levels,
|
|
37
|
-
{ name: "default", color: MONITOR_ICON_DEFAULT_COLOR },
|
|
38
|
-
{ name: "display", color: MONITOR_ICON_DISPLAY_COLOR }
|
|
39
|
-
];
|
|
40
|
-
for (const location of ["inside", "outside"]) {
|
|
41
|
-
for (const [shapeName, shape] of Object.entries(MONITOR_ICONS)) {
|
|
42
|
-
for (const level of iconLevels) {
|
|
43
|
-
const parts = [this.idPrefix, location, level.name, shapeName].filter(Boolean);
|
|
44
|
-
const id = parts.join("-");
|
|
45
|
-
const src = asDataURI(this.transformSvg(shape(level.color, MONITOR_ICON_BORDER_WIDTH, location === "inside" ? "#000000" : undefined)));
|
|
46
|
-
if (this.icons.has(id)) {
|
|
47
|
-
const icon = this.icons.get(id);
|
|
48
|
-
if (icon.image.src !== src) {
|
|
49
|
-
icon.image.src = src;
|
|
50
|
-
if (mapManager.map?.hasImage(id)) {
|
|
51
|
-
this.updateImage(icon, mapManager.map);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
continue;
|
|
55
|
-
}
|
|
56
|
-
else {
|
|
57
|
-
const icon = new Image();
|
|
58
|
-
icon.src = src;
|
|
59
|
-
icon.width = this.iconSize;
|
|
60
|
-
icon.height = this.iconSize;
|
|
61
|
-
this.register(id, icon);
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
});
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
export class MonitorsIconManager extends MonitorShapeIconManager {
|
|
72
|
-
get idPrefix() {
|
|
73
|
-
return "";
|
|
74
|
-
}
|
|
75
|
-
transformSvg(svg) {
|
|
76
|
-
return svg;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import { type FilterSpecification, type Map as MaptilerMap } from "@maptiler/sdk";
|
|
2
|
-
import type { SJVAirEntryLevel } from "@sjvair/sdk";
|
|
3
|
-
import { MapIconLayerIntegration } from "../map/integrations/map-geojson-integration.svelte";
|
|
4
|
-
import { MonitorsIconManager } from "./monitors-icon-manager.svelte";
|
|
5
|
-
import { TooltipManager } from "../map/integrations/tooltip.svelte";
|
|
6
|
-
import { MapDisplayOption } from "../map/integrations/map-display-option.svelte";
|
|
7
|
-
import type { MonitorMapFeature, MonitorMarkerProperties, MonitorsDataSource } from "./types";
|
|
8
|
-
declare class MonitorsMapIntegration extends MapIconLayerIntegration<MonitorMarkerProperties> {
|
|
9
|
-
private dataSource;
|
|
10
|
-
referenceId: string;
|
|
11
|
-
enabled: boolean;
|
|
12
|
-
clustered: boolean;
|
|
13
|
-
icons: MonitorsIconManager;
|
|
14
|
-
tooltipManager: TooltipManager;
|
|
15
|
-
private renderer;
|
|
16
|
-
displayOptions: {
|
|
17
|
-
airnow: MapDisplayOption;
|
|
18
|
-
aqlite: MapDisplayOption;
|
|
19
|
-
aqview: MapDisplayOption;
|
|
20
|
-
bam1022: MapDisplayOption;
|
|
21
|
-
airgradient: MapDisplayOption;
|
|
22
|
-
purpleair: MapDisplayOption;
|
|
23
|
-
vozbox: MapDisplayOption;
|
|
24
|
-
inactive: MapDisplayOption;
|
|
25
|
-
inside: MapDisplayOption;
|
|
26
|
-
};
|
|
27
|
-
/** Set by the app to handle navigation when a monitor is clicked. Receives the monitor ID. */
|
|
28
|
-
onMonitorClick: ((id: string) => void) | null;
|
|
29
|
-
selectedMonitorId: string | null;
|
|
30
|
-
private handleMonitorClick;
|
|
31
|
-
features: Array<MonitorMapFeature>;
|
|
32
|
-
filters: FilterSpecification;
|
|
33
|
-
featuresByType: Record<string, MonitorMapFeature[]>;
|
|
34
|
-
clusterIconThresholds: Array<SJVAirEntryLevel>;
|
|
35
|
-
get mapLayer(): Parameters<MaptilerMap["addLayer"]>[0];
|
|
36
|
-
get mapSource(): Parameters<MaptilerMap["addSource"]>[1];
|
|
37
|
-
constructor(dataSource?: MonitorsDataSource);
|
|
38
|
-
apply(): void;
|
|
39
|
-
remove(): void;
|
|
40
|
-
private applySelectedState;
|
|
41
|
-
}
|
|
42
|
-
export declare const monitorsMapIntegration: MonitorsMapIntegration;
|
|
43
|
-
export { MonitorsMapIntegration };
|