export const FLOW_DISPLAY_UNIT = "m³/h"; export const PRESSURE_DISPLAY_UNIT = "m"; export const VELOCITY_DISPLAY_UNIT = "m/s"; export type MeasurementMetric = "flow" | "pressure" | "velocity"; export interface NetworkResultUnits { flow: string; pressure: string; velocity: string; } export const DEFAULT_NETWORK_RESULT_UNITS: NetworkResultUnits = { flow: "LPS", pressure: "MTR", velocity: "m/s", }; const M3H_FACTOR = 3600; const FLOW_PROPERTIES = new Set([ "flow", "demand", "base_demand", "actual_demand", "actualdemand", ]); const PRESSURE_PROPERTIES = new Set(["pressure"]); const VELOCITY_PROPERTIES = new Set(["velocity"]); const IMPERIAL_FLOW_UNITS = new Set(["CFS", "GPM", "MGD", "IMGD", "AFD"]); export const metricForResultProperty = ( property: string, ): MeasurementMetric | null => { const normalizedProperty = property.trim().toLowerCase(); if (FLOW_PROPERTIES.has(normalizedProperty)) return "flow"; if (PRESSURE_PROPERTIES.has(normalizedProperty)) return "pressure"; if (VELOCITY_PROPERTIES.has(normalizedProperty)) return "velocity"; return null; }; export const networkResultUnitsFromOptions = ( options: Record, ): NetworkResultUnits => { const flow = options.FLOW_UNITS || options.UNITS || "LPS"; const pressure = options.PRESSURE_UNITS || options.PRESSURE || "MTR"; return { flow, pressure, velocity: IMPERIAL_FLOW_UNITS.has(flow.trim().toUpperCase()) ? "ft/s" : "m/s", }; }; export const toM3h = (value: number, sourceUnit: string = "m³/s") => { if (!Number.isFinite(value)) return Number.NaN; const normalizedUnit = sourceUnit.trim().toUpperCase().replace("³", "3"); const factors: Record = { CFS: 101.9406477312, GPM: 0.22712470704, MGD: 157.725491, IMGD: 189.4204167, AFD: 51.39507656, LPS: 3.6, "L/S": 3.6, LPM: 0.06, MLD: 41.6666666667, CMH: 1, "M3/H": 1, CMD: 1 / 24, "M3/D": 1 / 24, "M3/S": M3H_FACTOR, }; const factor = factors[normalizedUnit]; if (factor === undefined) throw new Error(`不支持的流量单位: ${sourceUnit}`); return value * factor; }; export const toMeters = (value: number, sourceUnit: string = "m") => { if (!Number.isFinite(value)) return Number.NaN; const normalizedUnit = sourceUnit.trim().toUpperCase(); const factors: Record = { METERS: 1, METRES: 1, MTR: 1, M: 1, MH2O: 1, "M H2O": 1, KPA: 0.1019716213, PSI: 0.7032496149, }; const factor = factors[normalizedUnit]; if (factor === undefined) throw new Error(`不支持的压力单位: ${sourceUnit}`); return value * factor; }; export const toMetersPerSecond = ( value: number, sourceUnit: string = "m/s", ) => { if (!Number.isFinite(value)) return Number.NaN; const normalizedUnit = sourceUnit.trim().toUpperCase(); if (["M/S", "MPS"].includes(normalizedUnit)) return value; if (["FT/S", "FPS"].includes(normalizedUnit)) return value * 0.3048; throw new Error(`不支持的流速单位: ${sourceUnit}`); }; export const toDisplayValue = ( value: number | null | undefined, metric: MeasurementMetric, sourceUnit: string, ) => { if (value === null || value === undefined) return null; switch (metric) { case "flow": return toM3h(value, sourceUnit); case "pressure": return toMeters(value, sourceUnit); case "velocity": return toMetersPerSecond(value, sourceUnit); } }; export const toModelDisplayValue = ( value: number, property: string, units: NetworkResultUnits, ) => { const metric = metricForResultProperty(property); if (!metric) return value; return toDisplayValue(value, metric, units[metric])!; }; export const toM3s = (value: number, sourceUnit: string = "m³/h") => { if (!Number.isFinite(value)) return Number.NaN; const normalizedUnit = sourceUnit.trim().toLowerCase(); if (normalizedUnit === "m³/s") return value; if (normalizedUnit === "lps" || normalizedUnit === "l/s") return value / 1000; if (normalizedUnit === "m³/h") return value / M3H_FACTOR; return value / M3H_FACTOR; }; export const toLps = (value: number, sourceUnit: string = "m³/s") => { if (!Number.isFinite(value)) return Number.NaN; const normalizedUnit = sourceUnit.trim().toLowerCase(); if (normalizedUnit === "lps" || normalizedUnit === "l/s") return value; if (normalizedUnit === "m³/h") return value / 3.6; if (normalizedUnit === "m³/s") return value * 1000; return value * 1000; };