import type { WaterNetworkSourceId } from "../map/sources"; import { formatValue } from "./format-value"; export type LocalizedFeatureProperty = { key: string; label: string; value: string; }; export type FeaturePanelBadgeTone = "active" | "inactive" | "warning" | "critical" | "info"; export type FeaturePanelBadge = { label: string; tone: FeaturePanelBadgeTone; }; export type FeaturePanelModel = { id: string; badge?: FeaturePanelBadge; attributes: LocalizedFeatureProperty[]; }; const PROPERTY_LABELS: Record = { fid: "GeoServer 要素 ID", id: "编号", scada_id: "编号 UUID", gid: "要素编号", name: "名称", code: "编码", type: "类型", node1: "起点节点", node2: "终点节点", from_node: "起点节点", to_node: "终点节点", diameter: "管径", dn: "管径", length: "长度", roughness: "粗糙系数", shape: "断面形状", max_depth: "最大深度", invert_elevation: "井底高程", orifice_type: "孔口类型", discharge_coeff: "流量系数", gated: "闸门", offset_height: "偏移高度", geom1: "几何参数 1", geom2: "几何参数 2", pump_curve: "泵曲线", startup_depth: "启动水深", shutoff_depth: "停泵水深", outfall_type: "排放类型", stage_data: "阶段数据", status: "状态", material: "材质", elevation: "高程", demand: "需水量", pressure: "压力", flow: "流量", velocity: "流速", zone: "分区", district: "片区", source: "来源", updated_at: "更新时间", point_id: "测点 ID", point_external_id: "测点编号", point_name: "测点名称", device_id: "设备 ID", device_external_id: "设备编号", device_type_id: "设备类型 ID", device_type_name: "设备类型", device_icon_code: "设备图标编码", active: "运行状态", external_id: "设备编号", junction_id: "关联检查井", kind: "设备类型", location_source: "位置来源", site_external_id: "站点编号", synced_at: "同步时间" }; const PROPERTY_ORDER: Record = { fid: 9, id: 10, scada_id: 10, gid: 11, name: 12, code: 13, diameter: 20, dn: 20, length: 21, roughness: 22, max_depth: 30, invert_elevation: 31, orifice_type: 32, outfall_type: 32, shape: 33, pump_curve: 34, material: 23, node1: 24, from_node: 24, node2: 25, to_node: 25, elevation: 30, demand: 31, pressure: 32, flow: 33, velocity: 34, status: 90 }; const STATUS_LABELS: Record = { on: "运行", off: "停止", active: "运行中", inactive: "停用", online: "在线", offline: "离线", open: "开启", closed: "关闭", normal: "正常", warning: "告警", critical: "严重" }; const OUTFALL_TYPE_LABELS: Record = { free: "自由出流" }; const GATED_LABELS: Record = { no: "否", false: "否", "0": "否", yes: "是", true: "是", "1": "是" }; const FEATURE_PANEL_PROPERTY_KEYS: Record = { pumps: ["id", "status", "startup_depth", "shutoff_depth"], conduits: ["id", "length", "diameter"], junctions: ["id", "invert_elevation", "max_depth"], orifices: ["id", "discharge_coeff", "gated", "shape", "geom1", "geom2"], outfalls: ["id", "invert_elevation", "outfall_type"], scada: ["scada_id", "site_external_id", "name", "external_id", "kind", "active", "junction_id", "synced_at"] }; const FEATURE_PANEL_BADGE_KEYS: Partial> = { pumps: "status", orifices: "gated", scada: "active" }; export function getLocalizedFeatureProperties(properties: Record): LocalizedFeatureProperty[] { return Object.entries(properties).filter(([key]) => normalizePropertyKey(key) !== "cluster_size").map(([key, value]) => ({ key, label: getFeaturePropertyLabel(key), value: formatFeaturePropertyValue(key, value) })).sort((first, second) => getPropertyOrder(first.key) - getPropertyOrder(second.key)); } export function getFeaturePanelProperties( layer: WaterNetworkSourceId, properties: Record, featureId?: string ): LocalizedFeatureProperty[] { return FEATURE_PANEL_PROPERTY_KEYS[layer].map((key) => { const value = key === "id" || key === "scada_id" ? properties[key] ?? featureId : properties[key]; return { key, label: getFeaturePropertyLabel(key), value: formatFeaturePropertyValue(key, value) }; }); } export function getFeaturePanelModel( layer: WaterNetworkSourceId, properties: Record, featureId?: string ): FeaturePanelModel { const entries = getFeaturePanelProperties(layer, properties, featureId); const idKey = layer === "scada" ? "scada_id" : "id"; const id = entries.find((entry) => entry.key === idKey)?.value ?? "暂无"; const badgeKey = FEATURE_PANEL_BADGE_KEYS[layer]; const badgeEntry = badgeKey ? entries.find((entry) => entry.key === badgeKey) : undefined; return { id, badge: badgeEntry ? getFeaturePanelBadge(layer, badgeEntry.value) : undefined, attributes: entries.filter((entry) => entry.key !== idKey && entry.key !== badgeKey) }; } export function getFeaturePropertyLabel(key: string) { const normalizedKey = normalizePropertyKey(key); return PROPERTY_LABELS[normalizedKey] ?? key; } export function formatFeaturePropertyValue(key: string, value: unknown) { const normalizedKey = normalizePropertyKey(key); if (isStatusKey(key) && typeof value === "string") { return STATUS_LABELS[value.toLowerCase()] ?? value; } if (normalizedKey === "outfall_type" && typeof value === "string") { return OUTFALL_TYPE_LABELS[value.toLowerCase()] ?? value; } if (normalizedKey === "gated" && value !== null && value !== undefined && value !== "") { return GATED_LABELS[String(value).toLowerCase()] ?? formatValue(value); } if (normalizedKey === "active" && typeof value === "boolean") { return value ? "在线" : "离线"; } if (normalizedKey === "location_source" && value === "density_cluster_demo") { return "密度聚类模拟位置"; } if (normalizedKey === "location_source" && value === "uniform_farthest_point_demo") { return "空间均匀采样模拟位置"; } if ((normalizedKey === "diameter" || normalizedKey === "dn") && value !== null && value !== undefined && value !== "") { const diameterInMeters = typeof value === "number" ? value : Number(value); return Number.isFinite(diameterInMeters) ? `${formatValue(diameterInMeters * 1000)} mm` : formatValue(value); } if (["length", "elevation", "invert_elevation", "max_depth", "startup_depth", "shutoff_depth"].includes(normalizedKey) && value !== null && value !== undefined && value !== "") { return `${formatValue(value)} m`; } return formatValue(value); } function getPropertyOrder(key: string) { return PROPERTY_ORDER[normalizePropertyKey(key)] ?? 100; } function normalizePropertyKey(key: string) { return key.trim().replaceAll("-", "_").toLowerCase(); } function isStatusKey(key: string) { return normalizePropertyKey(key) === "status"; } function getFeaturePanelBadge( layer: WaterNetworkSourceId, value: string ): FeaturePanelBadge { if (layer === "orifices") { return value === "是" ? { label: "有闸门", tone: "info" } : value === "否" ? { label: "无闸门", tone: "inactive" } : { label: `闸门 ${value}`, tone: "inactive" }; } const normalizedValue = value.toLowerCase(); if (["运行", "运行中", "在线", "开启", "正常"].includes(value)) { return { label: value, tone: "active" }; } if (["停止", "停用", "离线", "关闭"].includes(value)) { return { label: value, tone: "inactive" }; } if (normalizedValue === "warning" || value === "告警") { return { label: value, tone: "warning" }; } if (normalizedValue === "critical" || value === "严重") { return { label: value, tone: "critical" }; } return { label: value, tone: "inactive" }; }