refactor: abstract feature property panels
This commit is contained in:
@@ -20,10 +20,30 @@ export type FeaturePanelModel = {
|
||||
attributes: LocalizedFeatureProperty[];
|
||||
};
|
||||
|
||||
export type FeatureInsightMetric = {
|
||||
label: string;
|
||||
value: string;
|
||||
};
|
||||
|
||||
const PROPERTY_LABELS: Record<string, string> = {
|
||||
fid: "GeoServer 要素 ID",
|
||||
id: "编号",
|
||||
scada_id: "编号 UUID",
|
||||
sensor_id: "传感器 ID",
|
||||
sensor_name: "传感器名称",
|
||||
swmm_node: "SWMM 节点",
|
||||
topology_order: "拓扑序",
|
||||
distance_to_wwtp_m: "距污水厂距离",
|
||||
upstream_node_count: "上游节点数",
|
||||
upstream_sensors: "上游传感器",
|
||||
downstream_path: "下游路径",
|
||||
x: "X 坐标",
|
||||
y: "Y 坐标",
|
||||
cod_mg_l: "COD",
|
||||
氨氮_mg_l: "氨氮",
|
||||
电导率_us_cm: "电导率",
|
||||
液位_m: "液位",
|
||||
流量_m3_s: "流量",
|
||||
gid: "要素编号",
|
||||
name: "名称",
|
||||
code: "编码",
|
||||
@@ -82,6 +102,19 @@ const PROPERTY_ORDER: Record<string, number> = {
|
||||
fid: 9,
|
||||
id: 10,
|
||||
scada_id: 10,
|
||||
sensor_id: 10,
|
||||
sensor_name: 12,
|
||||
swmm_node: 13,
|
||||
topology_order: 14,
|
||||
distance_to_wwtp_m: 15,
|
||||
upstream_node_count: 16,
|
||||
upstream_sensors: 17,
|
||||
downstream_path: 18,
|
||||
cod_mg_l: 20,
|
||||
氨氮_mg_l: 21,
|
||||
电导率_us_cm: 22,
|
||||
液位_m: 23,
|
||||
流量_m3_s: 24,
|
||||
gid: 11,
|
||||
name: 12,
|
||||
code: 13,
|
||||
@@ -135,19 +168,91 @@ const GATED_LABELS: Record<string, string> = {
|
||||
"1": "是"
|
||||
};
|
||||
|
||||
const SCADA_KIND_LABELS: Record<string, string> = {
|
||||
water_quality: "水质监测",
|
||||
radar_level: "雷达液位",
|
||||
ultrasonic_flow: "超声流量",
|
||||
integrated_monitoring: "综合监测点"
|
||||
};
|
||||
|
||||
export const SCADA_METRIC_PROPERTY_KEYS = [
|
||||
"COD_mg_L",
|
||||
"氨氮_mg_L",
|
||||
"电导率_uS_cm",
|
||||
"液位_m",
|
||||
"流量_m3_s"
|
||||
] as const;
|
||||
|
||||
const PROPERTY_UNITS: Record<string, string> = {
|
||||
cod_mg_l: "mg/L",
|
||||
氨氮_mg_l: "mg/L",
|
||||
电导率_us_cm: "μS/cm",
|
||||
液位_m: "m",
|
||||
流量_m3_s: "m³/s"
|
||||
};
|
||||
|
||||
const FEATURE_PANEL_PROPERTY_KEYS: Record<WaterNetworkSourceId, readonly string[]> = {
|
||||
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"]
|
||||
scada: [
|
||||
"sensor_id",
|
||||
"kind",
|
||||
"swmm_node",
|
||||
"topology_order",
|
||||
"upstream_node_count",
|
||||
"distance_to_wwtp_m"
|
||||
]
|
||||
};
|
||||
|
||||
const FEATURE_PANEL_BADGE_KEYS: Partial<Record<WaterNetworkSourceId, string>> = {
|
||||
pumps: "status",
|
||||
orifices: "gated",
|
||||
scada: "active"
|
||||
scada: undefined
|
||||
};
|
||||
|
||||
type FeatureInsightMetricDefinition = {
|
||||
label: string;
|
||||
key?: string;
|
||||
value?: string;
|
||||
};
|
||||
|
||||
const FEATURE_INSIGHT_METRICS: Record<
|
||||
Exclude<WaterNetworkSourceId, "scada">,
|
||||
readonly FeatureInsightMetricDefinition[]
|
||||
> = {
|
||||
conduits: [
|
||||
{ label: "管径", key: "diameter" },
|
||||
{ label: "长度", key: "length" },
|
||||
{ label: "粗糙系数", key: "roughness" },
|
||||
{ label: "状态", key: "status" }
|
||||
],
|
||||
junctions: [
|
||||
{ label: "最大深度", key: "max_depth" },
|
||||
{ label: "井底高程", key: "invert_elevation" },
|
||||
{ label: "对象类型", value: "检查井" },
|
||||
{ label: "状态", value: "在线" }
|
||||
],
|
||||
orifices: [
|
||||
{ label: "孔口类型", key: "orifice_type" },
|
||||
{ label: "断面形状", key: "shape" },
|
||||
{ label: "流量系数", key: "discharge_coeff" },
|
||||
{ label: "闸门", key: "gated" }
|
||||
],
|
||||
pumps: [
|
||||
{ label: "状态", key: "status" },
|
||||
{ label: "泵曲线", key: "pump_curve" },
|
||||
{ label: "启动水深", key: "startup_depth" },
|
||||
{ label: "停泵水深", key: "shutoff_depth" }
|
||||
],
|
||||
outfalls: [
|
||||
{ label: "排放类型", key: "outfall_type" },
|
||||
{ label: "井底高程", key: "invert_elevation" },
|
||||
{ label: "阶段数据", key: "stage_data" },
|
||||
{ label: "状态", value: "在线" }
|
||||
]
|
||||
};
|
||||
|
||||
export function getLocalizedFeatureProperties(properties: Record<string, unknown>): LocalizedFeatureProperty[] {
|
||||
@@ -164,7 +269,8 @@ export function getFeaturePanelProperties(
|
||||
featureId?: string
|
||||
): LocalizedFeatureProperty[] {
|
||||
return FEATURE_PANEL_PROPERTY_KEYS[layer].map((key) => {
|
||||
const value = key === "id" || key === "scada_id" ? properties[key] ?? featureId : properties[key];
|
||||
const propertyValue = getPropertyValue(properties, key);
|
||||
const value = key === "id" || key === "scada_id" || key === "sensor_id" ? propertyValue ?? featureId : propertyValue;
|
||||
|
||||
return {
|
||||
key,
|
||||
@@ -174,13 +280,39 @@ export function getFeaturePanelProperties(
|
||||
});
|
||||
}
|
||||
|
||||
export function getScadaMetricProperties(
|
||||
properties: Record<string, unknown>
|
||||
): LocalizedFeatureProperty[] {
|
||||
return SCADA_METRIC_PROPERTY_KEYS.map((key) => ({
|
||||
key,
|
||||
label: getFeaturePropertyLabel(key),
|
||||
value: formatFeaturePropertyValue(key, getPropertyValue(properties, key))
|
||||
}));
|
||||
}
|
||||
|
||||
export function getFeatureInsightMetrics(
|
||||
layer: WaterNetworkSourceId,
|
||||
properties: Record<string, unknown>
|
||||
): FeatureInsightMetric[] {
|
||||
if (layer === "scada") {
|
||||
return getScadaMetricProperties(properties).map(({ label, value }) => ({ label, value }));
|
||||
}
|
||||
|
||||
return FEATURE_INSIGHT_METRICS[layer].map((metric) => ({
|
||||
label: metric.label,
|
||||
value: metric.key
|
||||
? formatFeaturePropertyValue(metric.key, getPropertyValue(properties, metric.key))
|
||||
: metric.value ?? "暂无"
|
||||
}));
|
||||
}
|
||||
|
||||
export function getFeaturePanelModel(
|
||||
layer: WaterNetworkSourceId,
|
||||
properties: Record<string, unknown>,
|
||||
featureId?: string
|
||||
): FeaturePanelModel {
|
||||
const entries = getFeaturePanelProperties(layer, properties, featureId);
|
||||
const idKey = layer === "scada" ? "scada_id" : "id";
|
||||
const idKey = layer === "scada" ? "sensor_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;
|
||||
@@ -224,6 +356,15 @@ export function formatFeaturePropertyValue(key: string, value: unknown) {
|
||||
return "空间均匀采样模拟位置";
|
||||
}
|
||||
|
||||
if (normalizedKey === "kind" && typeof value === "string") {
|
||||
return SCADA_KIND_LABELS[value] ?? value;
|
||||
}
|
||||
|
||||
const unit = PROPERTY_UNITS[normalizedKey];
|
||||
if (unit && value !== null && value !== undefined && value !== "") {
|
||||
return `${formatValue(value)} ${unit}`;
|
||||
}
|
||||
|
||||
if ((normalizedKey === "diameter" || normalizedKey === "dn") && value !== null && value !== undefined && value !== "") {
|
||||
const diameterInMeters = typeof value === "number" ? value : Number(value);
|
||||
return Number.isFinite(diameterInMeters)
|
||||
@@ -231,7 +372,7 @@ export function formatFeaturePropertyValue(key: string, value: unknown) {
|
||||
: formatValue(value);
|
||||
}
|
||||
|
||||
if (["length", "elevation", "invert_elevation", "max_depth", "startup_depth", "shutoff_depth"].includes(normalizedKey)
|
||||
if (["length", "elevation", "invert_elevation", "max_depth", "startup_depth", "shutoff_depth", "distance_to_wwtp_m"].includes(normalizedKey)
|
||||
&& value !== null && value !== undefined && value !== "") {
|
||||
return `${formatValue(value)} m`;
|
||||
}
|
||||
@@ -247,6 +388,16 @@ function normalizePropertyKey(key: string) {
|
||||
return key.trim().replaceAll("-", "_").toLowerCase();
|
||||
}
|
||||
|
||||
function getPropertyValue(properties: Record<string, unknown>, key: string) {
|
||||
if (Object.prototype.hasOwnProperty.call(properties, key)) {
|
||||
return properties[key];
|
||||
}
|
||||
|
||||
const normalizedKey = normalizePropertyKey(key);
|
||||
const matchingKey = Object.keys(properties).find((propertyKey) => normalizePropertyKey(propertyKey) === normalizedKey);
|
||||
return matchingKey ? properties[matchingKey] : undefined;
|
||||
}
|
||||
|
||||
function isStatusKey(key: string) {
|
||||
return normalizePropertyKey(key) === "status";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user