@sjvair/monitor-map 4.2.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 +61 -126
- package/dist/lib/MonitorDetailPanel.svelte +23 -20
- package/dist/lib/MonitorMapLayout.svelte +147 -77
- package/dist/lib/abort.d.ts +16 -0
- package/dist/lib/abort.js +51 -0
- 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 +54 -24
- 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/requests.d.ts +2 -1
- package/dist/lib/data-chart/requests.js +5 -2
- 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 +82 -82
- 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/monitor-details.svelte.js +11 -3
- package/dist/lib/monitors/monitors.svelte.d.ts +29 -26
- package/dist/lib/monitors/monitors.svelte.js +35 -126
- package/dist/lib/monitors/retry-load.d.ts +8 -0
- package/dist/lib/monitors/retry-load.js +11 -0
- package/dist/lib/monitors/subscriptions.d.ts +3 -0
- package/dist/lib/monitors/subscriptions.js +9 -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/abort.ts +59 -0
- 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 +54 -24
- 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/requests.ts +14 -7
- 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 +82 -82
- package/src/lib/monitors/filtered-source.svelte.ts +38 -0
- package/src/lib/monitors/monitor-details.svelte.ts +12 -3
- package/src/lib/monitors/monitors.svelte.ts +62 -153
- package/src/lib/monitors/retry-load.ts +14 -0
- package/src/lib/monitors/subscriptions.ts +17 -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 -9
- package/dist/lib/collocation-sites/collocations.svelte.js +0 -17
- 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 -9
- package/dist/lib/ev-stations/ev-stations.svelte.js +0 -55
- 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 -19
- package/dist/lib/hms/hms.svelte.js +0 -227
- 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 -24
- 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 -79
- 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 -264
- 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,19 +1,24 @@
|
|
|
1
1
|
<script lang="ts">
|
|
2
|
-
import { onDestroy } from "svelte";
|
|
3
|
-
import { Marker } from "@maptiler/sdk";
|
|
4
2
|
import { MapPinIcon, SearchIcon } from "@lucide/svelte";
|
|
3
|
+
import type { MapContext } from "@sjvair/map-sdk";
|
|
5
4
|
import { useMonitorMapRouter } from "../router-context";
|
|
6
|
-
import { mapManager } from "$lib/map/map-manager.svelte.js";
|
|
7
5
|
import { debounce } from "$lib/utils";
|
|
6
|
+
import { searchPin } from "./search-pin.svelte.js";
|
|
8
7
|
import { monitorSearch, geocode, type SearchResult } from "./service";
|
|
9
|
-
import { monitorsMapIntegration } from "$lib/monitors/monitors-map-integration.svelte";
|
|
10
8
|
|
|
9
|
+
interface SearchProps {
|
|
10
|
+
map: MapContext;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
const { map }: SearchProps = $props();
|
|
11
14
|
const { navigate, basePath } = useMonitorMapRouter();
|
|
12
15
|
|
|
13
16
|
let collapsed = $state(true);
|
|
14
17
|
let searchText = $state("");
|
|
15
18
|
let results: SearchResult[] = $state([]);
|
|
16
|
-
|
|
19
|
+
// The layout passes one MapContext for the widget's lifetime.
|
|
20
|
+
// svelte-ignore state_referenced_locally
|
|
21
|
+
const pin = searchPin(map);
|
|
17
22
|
let inputEl: HTMLInputElement | null = $state(null);
|
|
18
23
|
|
|
19
24
|
function clickOutside(node: HTMLElement) {
|
|
@@ -42,16 +47,14 @@
|
|
|
42
47
|
function clearSearch() {
|
|
43
48
|
searchText = "";
|
|
44
49
|
results = [];
|
|
45
|
-
|
|
46
|
-
marker = null;
|
|
50
|
+
pin.clear();
|
|
47
51
|
}
|
|
48
52
|
|
|
49
53
|
async function handleInput() {
|
|
50
54
|
const query = searchText;
|
|
51
55
|
if (!query) {
|
|
52
56
|
results = [];
|
|
53
|
-
|
|
54
|
-
marker = null;
|
|
57
|
+
pin.clear();
|
|
55
58
|
return;
|
|
56
59
|
}
|
|
57
60
|
const monitorResults = await monitorSearch(query);
|
|
@@ -73,40 +76,24 @@
|
|
|
73
76
|
collapsed = true;
|
|
74
77
|
searchText = "";
|
|
75
78
|
results = [];
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
if (mapManager.map && result.monitor.position) {
|
|
79
|
+
pin.clear();
|
|
80
|
+
if (result.monitor.position) {
|
|
79
81
|
const { coordinates } = result.monitor.position;
|
|
80
|
-
|
|
81
|
-
mapManager.map.flyTo({
|
|
82
|
-
center,
|
|
83
|
-
zoom: 12
|
|
84
|
-
});
|
|
82
|
+
map.flyTo({ center: [coordinates[0], coordinates[1]], zoom: 12 });
|
|
85
83
|
}
|
|
86
84
|
await navigate(`${basePath}/monitor/:id`, { params: { id: result.monitor.id } });
|
|
87
|
-
monitorsMapIntegration.selectedMonitorId = result.monitor.id;
|
|
88
85
|
}
|
|
89
86
|
|
|
90
87
|
function selectGeocode(result: Extract<SearchResult, { type: "geocode" }>) {
|
|
91
88
|
const { feature } = result;
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
const isAddress = feature.place_type?.[0] === "address";
|
|
98
|
-
mapManager.map.flyTo({
|
|
99
|
-
center,
|
|
100
|
-
...(isAddress && { zoom: 16 })
|
|
101
|
-
});
|
|
102
|
-
}
|
|
89
|
+
pin.clear();
|
|
90
|
+
const center: [number, number] = [feature.center[0], feature.center[1]];
|
|
91
|
+
pin.place(center);
|
|
92
|
+
const isAddress = feature.place_type?.[0] === "address";
|
|
93
|
+
map.flyTo({ center, ...(isAddress && { zoom: 16 }) });
|
|
103
94
|
results = [];
|
|
104
95
|
collapsed = true;
|
|
105
96
|
}
|
|
106
|
-
|
|
107
|
-
onDestroy(() => {
|
|
108
|
-
marker?.remove();
|
|
109
|
-
});
|
|
110
97
|
</script>
|
|
111
98
|
|
|
112
99
|
<div
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Marker } from "@maptiler/sdk";
|
|
2
|
+
import { maptilerMap, type MapContext } from "@sjvair/map-sdk";
|
|
3
|
+
|
|
4
|
+
export interface SearchPin {
|
|
5
|
+
place(center: [number, number]): void;
|
|
6
|
+
clear(): void;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* The pin a geocoded place leaves on the map. It follows the map: when the GL map is replaced
|
|
11
|
+
* (a basemap or style rebuild), the pin leaves the old one and is added to the new one. Call it
|
|
12
|
+
* during component init; the pin is removed when the component is destroyed.
|
|
13
|
+
*/
|
|
14
|
+
export function searchPin(map: MapContext): SearchPin {
|
|
15
|
+
let center = $state.raw<[number, number] | null>(null);
|
|
16
|
+
|
|
17
|
+
$effect(() => {
|
|
18
|
+
const gl = maptilerMap(map);
|
|
19
|
+
const at = center;
|
|
20
|
+
if (!gl || !at) return;
|
|
21
|
+
const marker = new Marker().setLngLat(at).addTo(gl);
|
|
22
|
+
return () => {
|
|
23
|
+
marker.remove();
|
|
24
|
+
};
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
place(next) {
|
|
29
|
+
center = next;
|
|
30
|
+
},
|
|
31
|
+
clear() {
|
|
32
|
+
center = null;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
35
|
+
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { geocoding, type GeocodingFeature } from "@maptiler/sdk";
|
|
2
|
-
import type {
|
|
3
|
-
import {
|
|
2
|
+
import type { MonitorData } from "@sjvair/sdk";
|
|
3
|
+
import { monitorMapConfig } from "$lib/config.svelte.js";
|
|
4
|
+
import { monitorsStore } from "$lib/stores.svelte.js";
|
|
4
5
|
import AirGradientLogo from "../assets/logos/airgradient-blue.svg";
|
|
5
6
|
import AirNowLogo from "../assets/logos/airnow-compact.jpg";
|
|
6
7
|
import CarbLogo from "../assets/logos/carb-compact.jpg";
|
|
@@ -9,7 +10,7 @@ import SJVAirLogo from "../assets/logos/sjvair.svg";
|
|
|
9
10
|
|
|
10
11
|
export type MonitorResult = {
|
|
11
12
|
type: "monitor";
|
|
12
|
-
monitor:
|
|
13
|
+
monitor: MonitorData;
|
|
13
14
|
logo: { url: string; alt: string };
|
|
14
15
|
};
|
|
15
16
|
|
|
@@ -22,7 +23,7 @@ export type SearchResult = MonitorResult | GeocodeResult;
|
|
|
22
23
|
|
|
23
24
|
const SJV_CENTER: [number, number] = [-119.8, 36.76];
|
|
24
25
|
|
|
25
|
-
function getMonitorLogo(monitor:
|
|
26
|
+
function getMonitorLogo(monitor: MonitorData): { url: string; alt: string } {
|
|
26
27
|
switch (monitor.data_source.name) {
|
|
27
28
|
case "AQview":
|
|
28
29
|
return { url: CarbLogo, alt: "AQview" };
|
|
@@ -66,29 +67,43 @@ function resolveProximity(): Promise<[number, number]> {
|
|
|
66
67
|
});
|
|
67
68
|
}
|
|
68
69
|
|
|
69
|
-
|
|
70
|
-
|
|
70
|
+
/** Monitors whose name matches `query`: exact, then prefix, then substring; at most 4. */
|
|
71
|
+
export function searchMonitors(
|
|
72
|
+
query: string,
|
|
73
|
+
monitors: Iterable<MonitorData>,
|
|
74
|
+
latest: ReadonlyMap<string, { value: number | null }>
|
|
75
|
+
): MonitorData[] {
|
|
71
76
|
const normalized = query.toLowerCase();
|
|
72
|
-
const exact:
|
|
73
|
-
const prefix:
|
|
74
|
-
const substr:
|
|
77
|
+
const exact: MonitorData[] = [];
|
|
78
|
+
const prefix: MonitorData[] = [];
|
|
79
|
+
const substr: MonitorData[] = [];
|
|
75
80
|
|
|
76
|
-
for
|
|
81
|
+
// Only monitors with a reading for the current pollutant, as the map shows them.
|
|
82
|
+
for (const monitor of monitors) {
|
|
83
|
+
if (latest.get(monitor.id)?.value == null) continue;
|
|
77
84
|
const name = monitor.name.toLowerCase();
|
|
78
85
|
if (name === normalized) exact.push(monitor);
|
|
79
86
|
else if (name.startsWith(normalized)) prefix.push(monitor);
|
|
80
87
|
else if (name.includes(normalized)) substr.push(monitor);
|
|
81
88
|
}
|
|
82
89
|
|
|
83
|
-
return [...exact, ...prefix, ...substr]
|
|
84
|
-
.slice(0, 4)
|
|
85
|
-
.map((monitor) => ({ type: "monitor" as const, monitor, logo: getMonitorLogo(monitor) }));
|
|
90
|
+
return [...exact, ...prefix, ...substr].slice(0, 4);
|
|
86
91
|
}
|
|
87
92
|
|
|
88
|
-
export async function
|
|
89
|
-
|
|
93
|
+
export async function monitorSearch(query: string): Promise<SearchResult[]> {
|
|
94
|
+
return searchMonitors(query, monitorsStore.monitors.values(), monitorsStore.latest).map(
|
|
95
|
+
(monitor) => ({ type: "monitor" as const, monitor, logo: getMonitorLogo(monitor) })
|
|
96
|
+
);
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
export async function geocodeQuery(
|
|
100
|
+
query: string,
|
|
101
|
+
proximity: [number, number],
|
|
102
|
+
key: string
|
|
103
|
+
): Promise<SearchResult[]> {
|
|
90
104
|
try {
|
|
91
105
|
const result = await geocoding.forward(query, {
|
|
106
|
+
apiKey: key,
|
|
92
107
|
country: ["us"],
|
|
93
108
|
fuzzyMatch: true,
|
|
94
109
|
limit: 4,
|
|
@@ -99,3 +114,7 @@ export async function geocode(query: string): Promise<SearchResult[]> {
|
|
|
99
114
|
return [];
|
|
100
115
|
}
|
|
101
116
|
}
|
|
117
|
+
|
|
118
|
+
export async function geocode(query: string): Promise<SearchResult[]> {
|
|
119
|
+
return geocodeQuery(query, await getProximity(), monitorMapConfig().maptilerKey);
|
|
120
|
+
}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createCollocationSitesStore,
|
|
3
|
+
createHmsFireStore,
|
|
4
|
+
createHmsSmokeStore,
|
|
5
|
+
createMonitorsStore
|
|
6
|
+
} from "@sjvair/map-sdk/stores";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* The app-wide data stores, created once. This module imports only `@sjvair/map-sdk/stores`, so
|
|
10
|
+
* the light `/core` entry can reach it without loading the map engine.
|
|
11
|
+
*/
|
|
12
|
+
export const monitorsStore = createMonitorsStore();
|
|
13
|
+
export const hmsSmokeStore = createHmsSmokeStore();
|
|
14
|
+
export const hmsFireStore = createHmsFireStore();
|
|
15
|
+
export const collocationSitesStore = createCollocationSitesStore({ monitors: monitorsStore });
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { config, type CustomLayerInterface } from "@maptiler/sdk";
|
|
2
|
+
import { WindLayer } from "@maptiler/weather";
|
|
3
|
+
import type { MapPlugin } from "@sjvair/map-sdk";
|
|
4
|
+
import { monitorMapConfig } from "../config.svelte.js";
|
|
5
|
+
|
|
6
|
+
export interface WindPluginOptions {
|
|
7
|
+
/** Builds the layer; runs again on each restyle. Defaults to a `@maptiler/weather` WindLayer. */
|
|
8
|
+
createLayer?: (id: string) => CustomLayerInterface;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
// The weather layer fetches its data with the SDK's global key, which map-sdk (it passes the key
|
|
12
|
+
// to the map only) never sets.
|
|
13
|
+
const defaultCreateLayer = (id: string) => {
|
|
14
|
+
config.apiKey = monitorMapConfig().maptilerKey;
|
|
15
|
+
return new WindLayer({ id, opacity: 0.5 }) as unknown as CustomLayerInterface;
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Wind particles as a map-sdk custom layer. `@maptiler/weather` can't be a map-sdk dependency, so
|
|
20
|
+
* the host adds it here; only the layout chunk reaches this module.
|
|
21
|
+
*/
|
|
22
|
+
export function windPlugin(options: WindPluginOptions = {}): MapPlugin {
|
|
23
|
+
const createLayer = options.createLayer ?? defaultCreateLayer;
|
|
24
|
+
return {
|
|
25
|
+
id: "wind",
|
|
26
|
+
label: "Wind",
|
|
27
|
+
selectable: false,
|
|
28
|
+
setup(ctx) {
|
|
29
|
+
ctx.addCustomLayer("wind", createLayer);
|
|
30
|
+
return () => {};
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
@@ -1,98 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import { format, formatDistanceToNow } from "date-fns";
|
|
3
|
-
import DataBox from "../components/DataBox.svelte";
|
|
4
|
-
import type { CollocationSiteMapFeature } from "./types";
|
|
5
|
-
import { monitorsManager } from "../monitors/monitors.svelte";
|
|
6
|
-
import { getCurrentLevel } from "../monitors/monitor-utils";
|
|
7
|
-
import type { MonitorLatest, SJVAirEntryLevel } from "@sjvair/sdk";
|
|
8
|
-
|
|
9
|
-
interface CollocationTooltipProps {
|
|
10
|
-
feature: CollocationSiteMapFeature;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const { feature }: CollocationTooltipProps = $props();
|
|
14
|
-
|
|
15
|
-
const data = $derived.by(() => {
|
|
16
|
-
const collocated = monitorsManager.latest?.get(feature.properties.colocated_id);
|
|
17
|
-
const reference = monitorsManager.latest?.get(feature.properties.reference_id);
|
|
18
|
-
|
|
19
|
-
return {
|
|
20
|
-
collocated: getMonitorData(collocated),
|
|
21
|
-
reference: getMonitorData(reference)
|
|
22
|
-
};
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
function getMonitorData(monitor: MonitorLatest | undefined) {
|
|
26
|
-
if (!monitor || !("value" in monitor.latest) || !monitorsManager.meta) return;
|
|
27
|
-
|
|
28
|
-
const entryType = monitorsManager.meta.entryType(monitor.latest.entry_type);
|
|
29
|
-
const level: SJVAirEntryLevel | undefined = getCurrentLevel(
|
|
30
|
-
monitor.latest.value,
|
|
31
|
-
entryType.asIter.levels!
|
|
32
|
-
);
|
|
33
|
-
|
|
34
|
-
const updateDuration = monitorsManager.meta.monitorType(monitor.type).expected_interval;
|
|
35
|
-
|
|
36
|
-
return {
|
|
37
|
-
color: level?.color ?? "",
|
|
38
|
-
header: entryType.label,
|
|
39
|
-
date: {
|
|
40
|
-
formatted: format(monitor.latest.timestamp, "h:mm:aaa EEEE MMM dd, yyyy"),
|
|
41
|
-
diference: formatDistanceToNow(monitor.latest.timestamp, {
|
|
42
|
-
addSuffix: true,
|
|
43
|
-
includeSeconds: true
|
|
44
|
-
})
|
|
45
|
-
},
|
|
46
|
-
monitorName: monitor.name,
|
|
47
|
-
subheading: `(${updateDuration} avg)`,
|
|
48
|
-
value: Math.round(parseInt(monitor.latest.value, 10)).toString()
|
|
49
|
-
};
|
|
50
|
-
}
|
|
51
|
-
</script>
|
|
52
|
-
|
|
53
|
-
{#if data}
|
|
54
|
-
<div class="flex flex-col gap-4">
|
|
55
|
-
{#if data.reference}
|
|
56
|
-
<div class="flex gap-2">
|
|
57
|
-
<DataBox
|
|
58
|
-
color={data.reference.color}
|
|
59
|
-
header={data.reference.header}
|
|
60
|
-
subheading={data.reference.subheading}
|
|
61
|
-
value={data.reference.value}
|
|
62
|
-
/>
|
|
63
|
-
<div class="flex flex-col">
|
|
64
|
-
<p class="leading-none">{data.reference.date.formatted}</p>
|
|
65
|
-
<h1 class="text-lg font-bold underline">{data.reference.monitorName}</h1>
|
|
66
|
-
<p class="leading-none">Reference monitor</p>
|
|
67
|
-
<div class="mt-auto">
|
|
68
|
-
<p class="text-base leading-none">Last updated</p>
|
|
69
|
-
<p class="text-base leading-none">{data.reference.date.diference}</p>
|
|
70
|
-
</div>
|
|
71
|
-
</div>
|
|
72
|
-
</div>
|
|
73
|
-
{:else}
|
|
74
|
-
<h1>Reference monitor disabled</h1>
|
|
75
|
-
{/if}
|
|
76
|
-
{#if data.collocated}
|
|
77
|
-
<div class="flex flex-row-reverse gap-2">
|
|
78
|
-
<DataBox
|
|
79
|
-
color={data.collocated.color}
|
|
80
|
-
header={data.collocated.header}
|
|
81
|
-
subheading={data.collocated.subheading}
|
|
82
|
-
value={data.collocated.value}
|
|
83
|
-
/>
|
|
84
|
-
<div class="flex flex-col">
|
|
85
|
-
<p class="leading-none">{data.collocated.date.formatted}</p>
|
|
86
|
-
<h1 class="text-lg font-bold underline">{data.collocated.monitorName}</h1>
|
|
87
|
-
<p class="leading-none">Collocated monitor</p>
|
|
88
|
-
<div class="mt-auto">
|
|
89
|
-
<p class="text-base leading-none">Last updated</p>
|
|
90
|
-
<p class="text-base leading-none">{data.collocated.date.diference}</p>
|
|
91
|
-
</div>
|
|
92
|
-
</div>
|
|
93
|
-
</div>
|
|
94
|
-
{:else}
|
|
95
|
-
<h1>Collocated monitor disabled</h1>
|
|
96
|
-
{/if}
|
|
97
|
-
</div>
|
|
98
|
-
{/if}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { CollocationSiteMapFeature } from "./types";
|
|
2
|
-
interface CollocationTooltipProps {
|
|
3
|
-
feature: CollocationSiteMapFeature;
|
|
4
|
-
}
|
|
5
|
-
declare const CollocationTooltip: import("svelte").Component<CollocationTooltipProps, {}, "">;
|
|
6
|
-
type CollocationTooltip = ReturnType<typeof CollocationTooltip>;
|
|
7
|
-
export default CollocationTooltip;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import { MonitorShapeIconManager } from "../monitors/monitors-icon-manager.svelte";
|
|
2
|
-
export declare function getCollocationIconId(baseIconId: string): string;
|
|
3
|
-
export declare class CollocationIconManager extends MonitorShapeIconManager {
|
|
4
|
-
protected get idPrefix(): string;
|
|
5
|
-
protected get iconSize(): number;
|
|
6
|
-
protected transformSvg(svg: string): string;
|
|
7
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import { CROSSHAIR_ICON_SIZE, withCrosshair } from "../map/icons";
|
|
2
|
-
import { MonitorShapeIconManager } from "../monitors/monitors-icon-manager.svelte";
|
|
3
|
-
const COLLOCATION_ICON_PREFIX = "collocation";
|
|
4
|
-
const CROSSHAIR_COLOR = "#4A5FC6";
|
|
5
|
-
export function getCollocationIconId(baseIconId) {
|
|
6
|
-
return `${COLLOCATION_ICON_PREFIX}-${baseIconId}`;
|
|
7
|
-
}
|
|
8
|
-
export class CollocationIconManager extends MonitorShapeIconManager {
|
|
9
|
-
get idPrefix() {
|
|
10
|
-
return COLLOCATION_ICON_PREFIX;
|
|
11
|
-
}
|
|
12
|
-
get iconSize() {
|
|
13
|
-
return CROSSHAIR_ICON_SIZE;
|
|
14
|
-
}
|
|
15
|
-
transformSvg(svg) {
|
|
16
|
-
return withCrosshair(svg, CROSSHAIR_COLOR);
|
|
17
|
-
}
|
|
18
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
import { type Map as MaptilerMap } from "@maptiler/sdk";
|
|
2
|
-
import { MapIconLayerIntegration } from "../map/integrations/map-geojson-integration.svelte";
|
|
3
|
-
import { CollocationIconManager } from "./collocations-icon-manager.svelte";
|
|
4
|
-
import { TooltipManager } from "../map/integrations/tooltip.svelte";
|
|
5
|
-
import type { CollocationSiteMapFeature, CollocationSiteMarkerProperties } from "./types";
|
|
6
|
-
declare class CollocationSitesMapIntegration extends MapIconLayerIntegration<CollocationSiteMarkerProperties> {
|
|
7
|
-
referenceId: string;
|
|
8
|
-
enabled: boolean;
|
|
9
|
-
icons: CollocationIconManager;
|
|
10
|
-
tooltipManager: TooltipManager;
|
|
11
|
-
/** The option only applies while monitors are shown with PM2.5. */
|
|
12
|
-
get available(): boolean;
|
|
13
|
-
features: Array<CollocationSiteMapFeature>;
|
|
14
|
-
mapLayer: Parameters<MaptilerMap["addLayer"]>[0];
|
|
15
|
-
get mapSource(): Parameters<MaptilerMap["addSource"]>[1];
|
|
16
|
-
constructor();
|
|
17
|
-
apply(): void;
|
|
18
|
-
remove(): void;
|
|
19
|
-
}
|
|
20
|
-
export declare const collocationSitesMapIntegration: CollocationSitesMapIntegration;
|
|
21
|
-
export type { CollocationSitesMapIntegration as MonitorsMapIntegration };
|
|
@@ -1,113 +0,0 @@
|
|
|
1
|
-
import { mapManager } from "../map/map-manager.svelte.js";
|
|
2
|
-
import { MapIconLayerIntegration } from "../map/integrations/map-geojson-integration.svelte";
|
|
3
|
-
import { CollocationIconManager, getCollocationIconId } from "./collocations-icon-manager.svelte";
|
|
4
|
-
import { TooltipManager } from "../map/integrations/tooltip.svelte";
|
|
5
|
-
import { collocationSitesManager } from "./collocations.svelte";
|
|
6
|
-
import { monitorsManager } from "../monitors/monitors.svelte";
|
|
7
|
-
import { monitorsMapIntegration } from "../monitors/monitors-map-integration.svelte";
|
|
8
|
-
import { untrack } from "svelte";
|
|
9
|
-
import CollocationTooltip from "./CollocationTooltip.svelte";
|
|
10
|
-
import { mountPopup } from "../map/utils";
|
|
11
|
-
function collocationTooltip(evt) {
|
|
12
|
-
const feature = evt.features?.[0];
|
|
13
|
-
if (!feature)
|
|
14
|
-
return;
|
|
15
|
-
return mountPopup(CollocationTooltip, { feature }, evt.lngLat);
|
|
16
|
-
}
|
|
17
|
-
class CollocationSitesMapIntegration extends MapIconLayerIntegration {
|
|
18
|
-
referenceId = "collocation-sites";
|
|
19
|
-
enabled = $state(false);
|
|
20
|
-
icons = new CollocationIconManager(monitorsManager);
|
|
21
|
-
tooltipManager = new TooltipManager();
|
|
22
|
-
/** The option only applies while monitors are shown with PM2.5. */
|
|
23
|
-
get available() {
|
|
24
|
-
return monitorsMapIntegration.enabled && monitorsManager.pollutant === "pm25";
|
|
25
|
-
}
|
|
26
|
-
features = $derived.by(() => {
|
|
27
|
-
if (!monitorsManager.meta ||
|
|
28
|
-
!monitorsManager.pollutant ||
|
|
29
|
-
!collocationSitesManager.collocationSites ||
|
|
30
|
-
monitorsMapIntegration.features.length === 0) {
|
|
31
|
-
return [];
|
|
32
|
-
}
|
|
33
|
-
return collocationSitesManager.collocationSites
|
|
34
|
-
.map((c) => {
|
|
35
|
-
const referenceMonitorFeature = monitorsMapIntegration.features.find((m) => m.properties.id === c.reference_id);
|
|
36
|
-
if (!referenceMonitorFeature)
|
|
37
|
-
return;
|
|
38
|
-
const feature = {
|
|
39
|
-
type: "Feature",
|
|
40
|
-
properties: {
|
|
41
|
-
icon: getCollocationIconId(referenceMonitorFeature.properties.icon),
|
|
42
|
-
colocated_id: c.colocated_id,
|
|
43
|
-
reference_id: c.reference_id,
|
|
44
|
-
name: c.name
|
|
45
|
-
},
|
|
46
|
-
geometry: c.position
|
|
47
|
-
};
|
|
48
|
-
return feature;
|
|
49
|
-
})
|
|
50
|
-
.filter((f) => f !== undefined);
|
|
51
|
-
});
|
|
52
|
-
mapLayer = {
|
|
53
|
-
id: this.referenceId,
|
|
54
|
-
type: "symbol",
|
|
55
|
-
source: this.referenceId,
|
|
56
|
-
layout: {
|
|
57
|
-
"icon-allow-overlap": true,
|
|
58
|
-
"icon-ignore-placement": true,
|
|
59
|
-
"icon-image": ["get", "icon"],
|
|
60
|
-
"icon-size": 1
|
|
61
|
-
},
|
|
62
|
-
paint: {}
|
|
63
|
-
};
|
|
64
|
-
get mapSource() {
|
|
65
|
-
return {
|
|
66
|
-
type: "geojson",
|
|
67
|
-
promoteId: "id",
|
|
68
|
-
data: {
|
|
69
|
-
type: "FeatureCollection",
|
|
70
|
-
features: this.features
|
|
71
|
-
}
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
constructor() {
|
|
75
|
-
super();
|
|
76
|
-
$effect.root(() => {
|
|
77
|
-
$effect(() => {
|
|
78
|
-
const features = this.features;
|
|
79
|
-
if (!mapManager.map || !this.enabled)
|
|
80
|
-
return;
|
|
81
|
-
mapManager.setDataSource(this.referenceId, features);
|
|
82
|
-
});
|
|
83
|
-
// Remove the layer while the option is unavailable (Ozone or Pollutant = None); restore
|
|
84
|
-
// it when it becomes available again if the user still has it checked.
|
|
85
|
-
$effect(() => {
|
|
86
|
-
if (!this.available) {
|
|
87
|
-
untrack(() => this.remove());
|
|
88
|
-
}
|
|
89
|
-
else if (untrack(() => this.enabled)) {
|
|
90
|
-
untrack(() => this.apply());
|
|
91
|
-
}
|
|
92
|
-
});
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
apply() {
|
|
96
|
-
if (!this.available) {
|
|
97
|
-
this.remove();
|
|
98
|
-
return;
|
|
99
|
-
}
|
|
100
|
-
if (!mapManager.map)
|
|
101
|
-
return;
|
|
102
|
-
if (!this.tooltipManager.has(this.referenceId)) {
|
|
103
|
-
this.tooltipManager.register(this.referenceId, collocationTooltip, Number.MAX_SAFE_INTEGER);
|
|
104
|
-
}
|
|
105
|
-
this.tooltipManager.enable();
|
|
106
|
-
super.apply();
|
|
107
|
-
}
|
|
108
|
-
remove() {
|
|
109
|
-
this.tooltipManager.disable();
|
|
110
|
-
super.remove();
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
export const collocationSitesMapIntegration = new CollocationSitesMapIntegration();
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import { type CollocationSite } from "@sjvair/sdk";
|
|
2
|
-
declare class CollocationSitesManager {
|
|
3
|
-
initialized: boolean;
|
|
4
|
-
collocationSites: Array<CollocationSite> | null;
|
|
5
|
-
init(): Promise<void>;
|
|
6
|
-
update(): Promise<void>;
|
|
7
|
-
}
|
|
8
|
-
export declare const collocationSitesManager: CollocationSitesManager;
|
|
9
|
-
export type { CollocationSitesManager };
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { getCollocationSites } from "@sjvair/sdk";
|
|
2
|
-
class CollocationSitesManager {
|
|
3
|
-
initialized = $state(false);
|
|
4
|
-
collocationSites = $state(null);
|
|
5
|
-
async init() {
|
|
6
|
-
if (this.initialized)
|
|
7
|
-
return;
|
|
8
|
-
this.collocationSites = await getCollocationSites();
|
|
9
|
-
this.initialized = true;
|
|
10
|
-
}
|
|
11
|
-
async update() {
|
|
12
|
-
if (!this.initialized)
|
|
13
|
-
return;
|
|
14
|
-
this.collocationSites = await getCollocationSites();
|
|
15
|
-
}
|
|
16
|
-
}
|
|
17
|
-
export const collocationSitesManager = new CollocationSitesManager();
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
import type { Feature, Geometry } from "geojson";
|
|
2
|
-
export type CollocationSiteMapFeature = Feature<Geometry, CollocationSiteMarkerProperties>;
|
|
3
|
-
export interface CollocationSiteMarkerProperties {
|
|
4
|
-
icon: string;
|
|
5
|
-
colocated_id: string;
|
|
6
|
-
reference_id: string;
|
|
7
|
-
name: string;
|
|
8
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
<script lang="ts">
|
|
2
|
-
import type { EvStationClusterMapFeature } from "../types";
|
|
3
|
-
|
|
4
|
-
interface Props {
|
|
5
|
-
feature: EvStationClusterMapFeature;
|
|
6
|
-
}
|
|
7
|
-
|
|
8
|
-
const { feature }: Props = $props();
|
|
9
|
-
|
|
10
|
-
const levelLabel = $derived(feature.source.includes("lvl2") ? "Level 2" : "Level 3");
|
|
11
|
-
</script>
|
|
12
|
-
|
|
13
|
-
<div class="flex flex-col gap-1 p-1">
|
|
14
|
-
<p class="font-semibold">{levelLabel} Chargers</p>
|
|
15
|
-
<p class="text-sm">{feature.properties.point_count} stations</p>
|
|
16
|
-
</div>
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { EvStationClusterMapFeature } from "../types";
|
|
2
|
-
interface Props {
|
|
3
|
-
feature: EvStationClusterMapFeature;
|
|
4
|
-
}
|
|
5
|
-
declare const EvStationClusterTooltip: import("svelte").Component<Props, {}, "">;
|
|
6
|
-
type EvStationClusterTooltip = ReturnType<typeof EvStationClusterTooltip>;
|
|
7
|
-
export default EvStationClusterTooltip;
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import type { EvStationMapFeature } from "../types";
|
|
2
|
-
interface Props {
|
|
3
|
-
feature: EvStationMapFeature;
|
|
4
|
-
}
|
|
5
|
-
declare const EvStationTooltip: import("svelte").Component<Props, {}, "">;
|
|
6
|
-
type EvStationTooltip = ReturnType<typeof EvStationTooltip>;
|
|
7
|
-
export default EvStationTooltip;
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import { type ClickHandler } from "../map/integrations/click-manager";
|
|
2
|
-
import { TooltipManager } from "../map/integrations/tooltip.svelte";
|
|
3
|
-
import type { EvStationMapFeature } from "./types";
|
|
4
|
-
export interface EvStationsClusterContext {
|
|
5
|
-
referenceId: string;
|
|
6
|
-
featuresByLevel: Record<string, EvStationMapFeature[]>;
|
|
7
|
-
beforeLayer?: string;
|
|
8
|
-
tooltipManager: TooltipManager;
|
|
9
|
-
}
|
|
10
|
-
export declare class EvStationsClusterRenderer {
|
|
11
|
-
private ctx;
|
|
12
|
-
private _levels;
|
|
13
|
-
constructor(ctx: EvStationsClusterContext);
|
|
14
|
-
apply(stationClickHandler: ClickHandler): void;
|
|
15
|
-
remove(): void;
|
|
16
|
-
get unclusteredLayerIds(): string[];
|
|
17
|
-
syncFeatures(): void;
|
|
18
|
-
private makeClusterClickHandler;
|
|
19
|
-
}
|