feat(map): refine SCADA feature experience

This commit is contained in:
2026-07-14 10:48:24 +08:00
parent 0b7e827024
commit 1c85d938a6
35 changed files with 1020 additions and 842 deletions
+52 -8
View File
@@ -14,9 +14,19 @@ import {
fitNetworkBounds,
getResponsiveWorkbenchPadding
} from "../map/camera";
import { waterNetworkLayers } from "../map/layers";
import {
waterNetworkBusinessLayers,
waterNetworkHitLayers,
waterNetworkInteractionLayers
} from "../map/layers";
import { MAP_MAX_ZOOM } from "../map/map-layer-visuals";
import { setSimulationLayersVisibility } from "../map/simulation-layers";
import {
registerScadaImages,
scadaFallbackLayers,
scadaLayers,
type ScadaImageRegistrationResult
} from "../map/scada";
import {
createBaseStyle,
createWaterNetworkSources,
@@ -60,6 +70,7 @@ export type WorkbenchSourceStatus = {
const SOURCE_STATUS_LABELS: Record<string, string> = {
"mapbox-base": "Mapbox 底图",
"geoserver-mvt": "GeoServer MVT",
"scada-icons": "SCADA 图标",
"annotation-source": "业务标注源"
};
@@ -71,6 +82,7 @@ const SOURCE_GROUP_BY_ID: Record<string, string> = {
orifices: "geoserver-mvt",
outfalls: "geoserver-mvt",
pumps: "geoserver-mvt",
scada: "geoserver-mvt",
[SIMULATION_SOURCE_IDS.impactArea]: "annotation-source",
[SIMULATION_SOURCE_IDS.annotations]: "annotation-source"
};
@@ -117,7 +129,7 @@ export function useWorkbenchMap({
window.__waterNetworkMap = map;
map.on("load", () => {
map.on("load", async () => {
map.resize();
const sources = createWaterNetworkSources();
map.addSource("conduits", sources.conduits);
@@ -125,15 +137,47 @@ export function useWorkbenchMap({
map.addSource("orifices", sources.orifices);
map.addSource("outfalls", sources.outfalls);
map.addSource("pumps", sources.pumps);
map.addSource("scada", sources.scada);
map.addSource(SIMULATION_SOURCE_IDS.impactArea, simulationSources.impactArea);
map.addSource(SIMULATION_SOURCE_IDS.annotations, simulationSources.annotations);
waterNetworkLayers.forEach((layer) => map.addLayer(layer));
simulationAnnotationLayers.forEach((layer) => map.addLayer(layer));
setSimulationLayersVisibility(map, impactVisibleRef.current);
simulationAnnotationLayers.filter((layer) => layer.id === "simulation-impact-fill").forEach((layer) => map.addLayer(layer));
waterNetworkBusinessLayers.forEach((layer) => map.addLayer(layer));
simulationAnnotationLayers.filter((layer) => layer.type !== "symbol" && layer.id !== "simulation-impact-fill").forEach((layer) => map.addLayer(layer));
waterNetworkInteractionLayers.forEach((layer) => map.addLayer(layer));
let scadaRegistration: ScadaImageRegistrationResult = {
status: "unavailable",
failedImageIds: []
};
setMapReady(true);
updateSourceStatus(setSourceStatuses, "annotation-source", "online", "业务标注源已就绪。");
fitNetworkBounds(map, WATER_NETWORK_GLOBAL_VIEW);
try {
scadaRegistration = await registerScadaImages(map);
} finally {
try {
const presentationLayers = scadaRegistration.status === "unavailable"
? scadaFallbackLayers
: scadaLayers;
presentationLayers.slice(0, -1).forEach((layer) => map.addLayer(layer));
simulationAnnotationLayers.filter((layer) => layer.type === "symbol").forEach((layer) => map.addLayer(layer));
waterNetworkHitLayers.forEach((layer) => map.addLayer(layer));
map.addLayer(presentationLayers[presentationLayers.length - 1]);
} finally {
setSimulationLayersVisibility(map, impactVisibleRef.current);
setMapReady(true);
updateSourceStatus(setSourceStatuses, "annotation-source", "online", "业务标注源已就绪。");
fitNetworkBounds(map, WATER_NETWORK_GLOBAL_VIEW);
}
}
if (scadaRegistration.status !== "ready") {
updateSourceStatus(
setSourceStatuses,
"scada-icons",
"degraded",
scadaRegistration.status === "degraded"
? "部分 SCADA 分类图标加载失败,已使用通用图标。"
: "SCADA 图标加载失败,已使用通用点位显示。"
);
}
});
const resizeMap = () => map.resize();