feat: extend supply workbench demo and map navigation
This commit is contained in:
@@ -11,11 +11,7 @@ import {
|
||||
SUPPLY_LAYER_CATALOG,
|
||||
type WaterNetworkSourceId
|
||||
} from "./sources";
|
||||
import {
|
||||
SCADA_ICON_PATHS,
|
||||
SCADA_LAYER_CONTROL_ITEMS,
|
||||
SCADA_LAYER_GROUPS
|
||||
} from "./scada";
|
||||
import { SCADA_ICON_PATHS, SCADA_LAYER_CONTROL_ITEMS, SCADA_LAYER_GROUPS } from "./scada";
|
||||
import { SUPPLY_ASSET_ICON_PATHS } from "./supply-icons";
|
||||
|
||||
export const WORKBENCH_LAYER_GROUPS: Record<string, string[]> = {
|
||||
@@ -33,18 +29,17 @@ export const WORKBENCH_LAYER_GROUPS: Record<string, string[]> = {
|
||||
|
||||
export const INITIAL_LAYER_VISIBILITY: Record<string, boolean> = {
|
||||
...Object.fromEntries(
|
||||
SUPPLY_LAYER_CATALOG
|
||||
.filter((layer) => layer.id !== "scada")
|
||||
.map((layer) => [layer.id, layer.initialVisible])
|
||||
SUPPLY_LAYER_CATALOG.filter((layer) => layer.id !== "scada").map((layer) => [
|
||||
layer.id,
|
||||
layer.initialVisible
|
||||
])
|
||||
),
|
||||
...Object.fromEntries(SCADA_LAYER_CONTROL_ITEMS.map((item) => [item.id, true])),
|
||||
simulation: false
|
||||
};
|
||||
|
||||
const SOURCE_CONTROL_LABELS = Object.fromEntries(
|
||||
SUPPLY_LAYER_CATALOG
|
||||
.filter((layer) => layer.available)
|
||||
.map((layer) => [layer.id, layer.label])
|
||||
SUPPLY_LAYER_CATALOG.filter((layer) => layer.available).map((layer) => [layer.id, layer.label])
|
||||
) as Record<WaterNetworkSourceId, string>;
|
||||
|
||||
type LayerControlPresentation = {
|
||||
@@ -55,7 +50,10 @@ type LayerControlPresentation = {
|
||||
visual: MapLayerControlVisual;
|
||||
};
|
||||
|
||||
const LAYER_CONTROL_PRESENTATION: Record<Exclude<WaterNetworkSourceId, "scada">, LayerControlPresentation> = {
|
||||
const LAYER_CONTROL_PRESENTATION: Record<
|
||||
Exclude<WaterNetworkSourceId, "scada">,
|
||||
LayerControlPresentation
|
||||
> = {
|
||||
pipes: {
|
||||
description: "按管径分级",
|
||||
minZoom: 8.5,
|
||||
@@ -258,14 +256,70 @@ export const MAP_LEGEND_ITEMS: MapLegendItem[] = [
|
||||
layerControlId: "pipes",
|
||||
...MODEL_PIPE_LEGEND_GROUP
|
||||
},
|
||||
{ id: "junction", label: "节点", color: MAP_STYLE_TOKENS.supply.junction, shape: "dot", layerControlId: "junctions", ...MODEL_FACILITY_LEGEND_GROUP },
|
||||
{ id: "valve", label: "阀门", color: MAP_STYLE_TOKENS.supply.valve, imageSrc: SUPPLY_ASSET_ICON_PATHS.valve, layerControlId: "valves", ...MODEL_FACILITY_LEGEND_GROUP },
|
||||
{ id: "reservoir", label: "水库", color: MAP_STYLE_TOKENS.supply.reservoir, imageSrc: SUPPLY_ASSET_ICON_PATHS.reservoir, layerControlId: "reservoirs", ...MODEL_FACILITY_LEGEND_GROUP },
|
||||
{ id: "pump", label: "水泵", color: MAP_STYLE_TOKENS.supply.pump, imageSrc: SUPPLY_ASSET_ICON_PATHS.pump, layerControlId: "pumps", ...MODEL_FACILITY_LEGEND_GROUP },
|
||||
{ id: "tank", label: "水箱", color: MAP_STYLE_TOKENS.supply.tank, imageSrc: SUPPLY_ASSET_ICON_PATHS.tank, layerControlId: "tanks", ...MODEL_FACILITY_LEGEND_GROUP },
|
||||
{ id: "scada-flow", label: "流量监测", color: MAP_STYLE_TOKENS.supply.scadaFlow, imageSrc: SCADA_ICON_PATHS.flow, layerControlId: "scada-flow", ...MONITORING_LEGEND_GROUP },
|
||||
{ id: "scada-pressure", label: "压力监测", color: MAP_STYLE_TOKENS.supply.scadaPressure, imageSrc: SCADA_ICON_PATHS.pressure, layerControlId: "scada-pressure", ...MONITORING_LEGEND_GROUP },
|
||||
{ id: "water-quality-monitoring", label: "水质监测", color: MAP_STYLE_TOKENS.supply.waterQuality, imageSrc: SUPPLY_ASSET_ICON_PATHS.waterQuality, layerControlId: "water_quality_monitoring_points", ...MONITORING_LEGEND_GROUP },
|
||||
{
|
||||
id: "junction",
|
||||
label: "节点",
|
||||
color: MAP_STYLE_TOKENS.supply.junction,
|
||||
shape: "dot",
|
||||
layerControlId: "junctions",
|
||||
...MODEL_FACILITY_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "valve",
|
||||
label: "阀门",
|
||||
color: MAP_STYLE_TOKENS.supply.valve,
|
||||
imageSrc: SUPPLY_ASSET_ICON_PATHS.valve,
|
||||
layerControlId: "valves",
|
||||
...MODEL_FACILITY_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "reservoir",
|
||||
label: "水库",
|
||||
color: MAP_STYLE_TOKENS.supply.reservoir,
|
||||
imageSrc: SUPPLY_ASSET_ICON_PATHS.reservoir,
|
||||
layerControlId: "reservoirs",
|
||||
...MODEL_FACILITY_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "pump",
|
||||
label: "水泵",
|
||||
color: MAP_STYLE_TOKENS.supply.pump,
|
||||
imageSrc: SUPPLY_ASSET_ICON_PATHS.pump,
|
||||
layerControlId: "pumps",
|
||||
...MODEL_FACILITY_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "tank",
|
||||
label: "水箱",
|
||||
color: MAP_STYLE_TOKENS.supply.tank,
|
||||
imageSrc: SUPPLY_ASSET_ICON_PATHS.tank,
|
||||
layerControlId: "tanks",
|
||||
...MODEL_FACILITY_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "scada-flow",
|
||||
label: "流量监测",
|
||||
color: MAP_STYLE_TOKENS.supply.scadaFlow,
|
||||
imageSrc: SCADA_ICON_PATHS.flow,
|
||||
layerControlId: "scada-flow",
|
||||
...MONITORING_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "scada-pressure",
|
||||
label: "压力监测",
|
||||
color: MAP_STYLE_TOKENS.supply.scadaPressure,
|
||||
imageSrc: SCADA_ICON_PATHS.pressure,
|
||||
layerControlId: "scada-pressure",
|
||||
...MONITORING_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "water-quality-monitoring",
|
||||
label: "水质监测",
|
||||
color: MAP_STYLE_TOKENS.supply.waterQuality,
|
||||
imageSrc: SUPPLY_ASSET_ICON_PATHS.waterQuality,
|
||||
layerControlId: "water_quality_monitoring_points",
|
||||
...MONITORING_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "source-major-pipe",
|
||||
label: "DN600 及以上",
|
||||
@@ -311,36 +365,101 @@ export const MAP_LEGEND_ITEMS: MapLegendItem[] = [
|
||||
layerControlId: "fx_20200811_dn100_pipes",
|
||||
...SOURCE_AUGUST_PIPE_LEGEND_GROUP
|
||||
},
|
||||
{ id: "source-valve", label: "GIS 阀门", color: MAP_STYLE_TOKENS.supply.sourceValve, imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceValve, layerControlId: "fx_20200423_valves", ...SOURCE_FACILITY_LEGEND_GROUP },
|
||||
{ id: "source-drain-valve", label: "排水阀", color: MAP_STYLE_TOKENS.supply.sourceDrainValve, imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceDrainValve, layerControlId: "fx_20200423_drain_valves", ...SOURCE_FACILITY_LEGEND_GROUP },
|
||||
{ id: "source-flow-meter", label: "流量仪", color: MAP_STYLE_TOKENS.supply.sourceFlowMeter, imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceFlowMeter, layerControlId: "fx_20200423_flow_meters", ...SOURCE_FACILITY_LEGEND_GROUP },
|
||||
{ id: "source-hydrant", label: "消火栓", color: MAP_STYLE_TOKENS.supply.sourceHydrant, imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceHydrant, layerControlId: "fx_20200423_hydrants", ...SOURCE_FACILITY_LEGEND_GROUP },
|
||||
{ id: "source-connection", label: "接水点", color: MAP_STYLE_TOKENS.supply.sourceConnection, imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceConnection, layerControlId: "fx_20200423_service_connections", ...SOURCE_FACILITY_LEGEND_GROUP },
|
||||
{ id: "source-customer-meter", label: "用户水表", color: MAP_STYLE_TOKENS.supply.sourceCustomerMeter, imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceCustomerMeter, layerControlId: "fx_20200423_customer_meters", ...SOURCE_FACILITY_LEGEND_GROUP },
|
||||
{ id: "source-non-residential-meter", label: "非居民水表", color: MAP_STYLE_TOKENS.supply.sourceNonResidentialMeter, imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceNonResidentialMeter, layerControlId: "fx_20200423_non_residential_meters", ...SOURCE_FACILITY_LEGEND_GROUP },
|
||||
{ id: "impact-area", label: "影响范围", description: "事故或分析结果", color: MAP_STYLE_TOKENS.state.incident, shape: "area", layerControlId: "simulation", ...ANALYSIS_LEGEND_GROUP }
|
||||
{
|
||||
id: "source-valve",
|
||||
label: "GIS 阀门",
|
||||
color: MAP_STYLE_TOKENS.supply.sourceValve,
|
||||
imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceValve,
|
||||
layerControlId: "fx_20200423_valves",
|
||||
...SOURCE_FACILITY_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "source-drain-valve",
|
||||
label: "排水阀",
|
||||
color: MAP_STYLE_TOKENS.supply.sourceDrainValve,
|
||||
imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceDrainValve,
|
||||
layerControlId: "fx_20200423_drain_valves",
|
||||
...SOURCE_FACILITY_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "source-flow-meter",
|
||||
label: "流量仪",
|
||||
color: MAP_STYLE_TOKENS.supply.sourceFlowMeter,
|
||||
imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceFlowMeter,
|
||||
layerControlId: "fx_20200423_flow_meters",
|
||||
...SOURCE_FACILITY_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "source-hydrant",
|
||||
label: "消火栓",
|
||||
color: MAP_STYLE_TOKENS.supply.sourceHydrant,
|
||||
imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceHydrant,
|
||||
layerControlId: "fx_20200423_hydrants",
|
||||
...SOURCE_FACILITY_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "source-connection",
|
||||
label: "接水点",
|
||||
color: MAP_STYLE_TOKENS.supply.sourceConnection,
|
||||
imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceConnection,
|
||||
layerControlId: "fx_20200423_service_connections",
|
||||
...SOURCE_FACILITY_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "source-customer-meter",
|
||||
label: "用户水表",
|
||||
color: MAP_STYLE_TOKENS.supply.sourceCustomerMeter,
|
||||
imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceCustomerMeter,
|
||||
layerControlId: "fx_20200423_customer_meters",
|
||||
...SOURCE_FACILITY_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "source-non-residential-meter",
|
||||
label: "非居民水表",
|
||||
color: MAP_STYLE_TOKENS.supply.sourceNonResidentialMeter,
|
||||
imageSrc: SUPPLY_ASSET_ICON_PATHS.sourceNonResidentialMeter,
|
||||
layerControlId: "fx_20200423_non_residential_meters",
|
||||
...SOURCE_FACILITY_LEGEND_GROUP
|
||||
},
|
||||
{
|
||||
id: "impact-area",
|
||||
label: "影响范围",
|
||||
description: "事故或分析结果",
|
||||
color: MAP_STYLE_TOKENS.state.incident,
|
||||
shape: "area",
|
||||
layerControlId: "simulation",
|
||||
...ANALYSIS_LEGEND_GROUP
|
||||
}
|
||||
];
|
||||
|
||||
export function createVisibleMapLegendItems(
|
||||
layerItems: readonly Pick<MapLayerControlItem, "id" | "visible">[]
|
||||
) {
|
||||
const visibleLayerIds = new Set(
|
||||
layerItems.filter((item) => item.visible).map((item) => item.id)
|
||||
);
|
||||
const visibleLayerIds = new Set(layerItems.filter((item) => item.visible).map((item) => item.id));
|
||||
return MAP_LEGEND_ITEMS.filter((item) =>
|
||||
item.layerControlId ? visibleLayerIds.has(item.layerControlId) : true
|
||||
);
|
||||
}
|
||||
|
||||
export const BASE_LAYER_IDS = ["mapbox-light", "mapbox-satellite"] as const;
|
||||
export const BASE_LAYER_GROUPS = {
|
||||
"mapbox-light": ["mapbox-light"],
|
||||
"mapbox-satellite": ["mapbox-satellite"],
|
||||
"tianditu-vector": ["tianditu-vector", "tianditu-vector-annotation"],
|
||||
"tianditu-image": ["tianditu-image", "tianditu-image-annotation"]
|
||||
} as const;
|
||||
|
||||
export const BASE_LAYER_IDS = Object.values(BASE_LAYER_GROUPS).flat();
|
||||
|
||||
export function applyBaseLayerVisibility(map: MapLibreMap, activeBaseLayerId: string) {
|
||||
const activeLayerIds = new Set<string>(
|
||||
BASE_LAYER_GROUPS[activeBaseLayerId as keyof typeof BASE_LAYER_GROUPS] ?? []
|
||||
);
|
||||
BASE_LAYER_IDS.forEach((layerId) => {
|
||||
if (map.getLayer(layerId)) {
|
||||
map.setLayoutProperty(
|
||||
layerId,
|
||||
"visibility",
|
||||
activeBaseLayerId === layerId ? "visible" : "none"
|
||||
activeLayerIds.has(layerId) ? "visible" : "none"
|
||||
);
|
||||
}
|
||||
});
|
||||
@@ -359,6 +478,18 @@ export const BASE_LAYER_OPTIONS: BaseLayerOption[] = [
|
||||
description: "卫星街道",
|
||||
swatchClassName: "bg-gradient-to-br from-emerald-950 via-emerald-700 to-yellow-200"
|
||||
},
|
||||
{
|
||||
id: "tianditu-vector",
|
||||
label: "天地图矢量",
|
||||
description: "矢量与中文注记",
|
||||
swatchClassName: "bg-gradient-to-br from-sky-50 via-stone-100 to-emerald-100"
|
||||
},
|
||||
{
|
||||
id: "tianditu-image",
|
||||
label: "天地图影像",
|
||||
description: "影像与中文注记",
|
||||
swatchClassName: "bg-gradient-to-br from-slate-950 via-emerald-800 to-stone-300"
|
||||
},
|
||||
{
|
||||
id: "none",
|
||||
label: "无底图",
|
||||
@@ -390,20 +521,23 @@ export function createLayerControlItems(
|
||||
groupLabel: "管网模型",
|
||||
groupDescription: "计算模型与基础设施"
|
||||
})),
|
||||
...(available.has("scada") ? SCADA_LAYER_CONTROL_ITEMS.map((item) => ({
|
||||
id: item.id,
|
||||
label: item.label,
|
||||
description: item.description,
|
||||
minZoom: 8.5,
|
||||
visual: {
|
||||
kind: "image" as const,
|
||||
imageSrc: item.id === "scada-pressure" ? SCADA_ICON_PATHS.pressure : SCADA_ICON_PATHS.flow
|
||||
},
|
||||
visible: layerVisibility[item.id],
|
||||
group: "monitoring",
|
||||
groupLabel: "监测点",
|
||||
groupDescription: "在线监测与分析选点"
|
||||
})) : []),
|
||||
...(available.has("scada")
|
||||
? SCADA_LAYER_CONTROL_ITEMS.map((item) => ({
|
||||
id: item.id,
|
||||
label: item.label,
|
||||
description: item.description,
|
||||
minZoom: 8.5,
|
||||
visual: {
|
||||
kind: "image" as const,
|
||||
imageSrc:
|
||||
item.id === "scada-pressure" ? SCADA_ICON_PATHS.pressure : SCADA_ICON_PATHS.flow
|
||||
},
|
||||
visible: layerVisibility[item.id],
|
||||
group: "monitoring",
|
||||
groupLabel: "监测点",
|
||||
groupDescription: "在线监测与分析选点"
|
||||
}))
|
||||
: []),
|
||||
...monitoringItems.map((layer) => ({
|
||||
id: layer.id,
|
||||
label: SOURCE_CONTROL_LABELS[layer.id],
|
||||
@@ -443,8 +577,9 @@ export function getWorkbenchLayerIds(
|
||||
groupId: string
|
||||
) {
|
||||
if (groupId in SCADA_LAYER_GROUPS) {
|
||||
return SCADA_LAYER_GROUPS[groupId as keyof typeof SCADA_LAYER_GROUPS]
|
||||
.filter((layerId) => map.getLayer(layerId));
|
||||
return SCADA_LAYER_GROUPS[groupId as keyof typeof SCADA_LAYER_GROUPS].filter((layerId) =>
|
||||
map.getLayer(layerId)
|
||||
);
|
||||
}
|
||||
if (isWaterNetworkSourceId(groupId)) {
|
||||
return map
|
||||
|
||||
Reference in New Issue
Block a user