feat(workbench): integrate runtime data and map tooling
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import type { WaterNetworkSourceId } from "../map/sources";
|
||||
import { isSourceGisSourceId, type WaterNetworkSourceId } from "../map/sources";
|
||||
import { formatValue } from "./format-value";
|
||||
|
||||
export type LocalizedFeatureProperty = {
|
||||
@@ -110,9 +110,14 @@ const PROPERTY_LABELS: Record<string, string> = {
|
||||
node_id: "关联节点",
|
||||
link_id: "关联连线",
|
||||
api_query_id: "采集接口",
|
||||
measurement_unit: "计量单位",
|
||||
transmission_mode: "传输方式",
|
||||
transmission_frequency: "传输频率",
|
||||
reliability: "可靠性",
|
||||
latest_value: "最新监测值",
|
||||
latest_value_with_unit: "最新监测值",
|
||||
latest_observed_at: "监测时间",
|
||||
latest_value_source: "数值来源",
|
||||
device_id: "设备 ID",
|
||||
device_external_id: "设备编号",
|
||||
device_type_id: "设备类型 ID",
|
||||
@@ -124,7 +129,17 @@ const PROPERTY_LABELS: Record<string, string> = {
|
||||
kind: "设备类型",
|
||||
location_source: "位置来源",
|
||||
site_external_id: "站点编号",
|
||||
synced_at: "同步时间"
|
||||
synced_at: "同步时间",
|
||||
source_fid: "源要素编号",
|
||||
source_object_id: "源对象编号",
|
||||
source_layer_name: "源图层",
|
||||
dataset_title: "数据集",
|
||||
source_date: "数据日期",
|
||||
monitoring_point_no: "监测点序号",
|
||||
selection_method: "选点依据",
|
||||
minimum_diameter: "关联管径下限",
|
||||
source_analysis: "来源分析",
|
||||
run_id: "分析运行编号"
|
||||
};
|
||||
|
||||
const PROPERTY_ORDER: Record<string, number> = {
|
||||
@@ -292,16 +307,47 @@ const PROPERTY_UNITS: Record<string, string> = {
|
||||
流量_m3_s: "m³/s"
|
||||
};
|
||||
|
||||
const FEATURE_PANEL_PROPERTY_KEYS: Record<WaterNetworkSourceId, readonly string[]> = {
|
||||
const FEATURE_PANEL_PROPERTY_KEYS: Partial<Record<WaterNetworkSourceId, readonly string[]>> = {
|
||||
pipes: ["id", "start_node_id", "end_node_id", "diameter", "length", "roughness", "status"],
|
||||
junctions: ["id", "elevation", "base_demand"],
|
||||
valves: ["id", "start_node_id", "end_node_id", "diameter", "valve_type", "setting", "minor_loss"],
|
||||
reservoirs: ["id", "head", "pattern_id"],
|
||||
scada: ["device_id", "device_type", "node_id", "link_id", "api_query_id", "transmission_mode", "transmission_frequency", "reliability"],
|
||||
scada: [
|
||||
"device_id",
|
||||
"device_type",
|
||||
"latest_value_with_unit",
|
||||
"latest_observed_at",
|
||||
"node_id",
|
||||
"link_id",
|
||||
"api_query_id",
|
||||
"measurement_unit",
|
||||
"transmission_mode",
|
||||
"transmission_frequency",
|
||||
"reliability"
|
||||
],
|
||||
pumps: ["id", "start_node_id", "end_node_id", "power", "head_curve_id", "speed", "pattern_id"],
|
||||
tanks: ["id", "elevation", "initial_level", "minimum_level", "maximum_level", "diameter", "minimum_volume", "volume_curve_id", "overflow"]
|
||||
tanks: ["id", "elevation", "initial_level", "minimum_level", "maximum_level", "diameter", "minimum_volume", "volume_curve_id", "overflow"],
|
||||
water_quality_monitoring_points: [
|
||||
"id",
|
||||
"monitoring_point_no",
|
||||
"node_id",
|
||||
"selection_method",
|
||||
"minimum_diameter",
|
||||
"elevation",
|
||||
"source_analysis"
|
||||
]
|
||||
};
|
||||
|
||||
const SOURCE_GIS_PANEL_PROPERTY_KEYS = [
|
||||
"id",
|
||||
"source_layer_name",
|
||||
"source_date",
|
||||
"source_object_id",
|
||||
"diameter",
|
||||
"length",
|
||||
"dataset_title"
|
||||
] as const;
|
||||
|
||||
const FEATURE_PANEL_BADGE_KEYS: Partial<Record<WaterNetworkSourceId, string>> = {
|
||||
pipes: "status",
|
||||
valves: "setting"
|
||||
@@ -313,7 +359,7 @@ type FeatureInsightMetricDefinition = {
|
||||
value?: string;
|
||||
};
|
||||
|
||||
const FEATURE_INSIGHT_METRICS: Record<WaterNetworkSourceId, readonly FeatureInsightMetricDefinition[]> = {
|
||||
const FEATURE_INSIGHT_METRICS: Partial<Record<WaterNetworkSourceId, readonly FeatureInsightMetricDefinition[]>> = {
|
||||
pipes: [
|
||||
{ label: "管径", key: "diameter" },
|
||||
{ label: "长度", key: "length" },
|
||||
@@ -339,10 +385,11 @@ const FEATURE_INSIGHT_METRICS: Record<WaterNetworkSourceId, readonly FeatureInsi
|
||||
{ label: "Y 坐标", key: "y" }
|
||||
],
|
||||
scada: [
|
||||
{ label: "类型", key: "device_type" },
|
||||
{ label: "最新监测值", key: "latest_value_with_unit" },
|
||||
{ label: "监测时间", key: "latest_observed_at" },
|
||||
{ label: "关联节点", key: "node_id" },
|
||||
{ label: "关联连线", key: "link_id" },
|
||||
{ label: "传输方式", key: "transmission_mode" }
|
||||
{ label: "类型", key: "device_type" }
|
||||
],
|
||||
pumps: [
|
||||
{ label: "功率", key: "power" },
|
||||
@@ -355,6 +402,12 @@ const FEATURE_INSIGHT_METRICS: Record<WaterNetworkSourceId, readonly FeatureInsi
|
||||
{ label: "初始水位", key: "initial_level" },
|
||||
{ label: "最低水位", key: "minimum_level" },
|
||||
{ label: "最高水位", key: "maximum_level" }
|
||||
],
|
||||
water_quality_monitoring_points: [
|
||||
{ label: "监测点序号", key: "monitoring_point_no" },
|
||||
{ label: "关联节点", key: "node_id" },
|
||||
{ label: "关联管径下限", key: "minimum_diameter" },
|
||||
{ label: "选点依据", value: "灵敏度分析" }
|
||||
]
|
||||
};
|
||||
|
||||
@@ -371,7 +424,9 @@ export function getFeaturePanelProperties(
|
||||
properties: Record<string, unknown>,
|
||||
featureId?: string
|
||||
): LocalizedFeatureProperty[] {
|
||||
return FEATURE_PANEL_PROPERTY_KEYS[layer].map((key) => {
|
||||
const keys = FEATURE_PANEL_PROPERTY_KEYS[layer]
|
||||
?? (isSourceGisSourceId(layer) ? SOURCE_GIS_PANEL_PROPERTY_KEYS : ["id"]);
|
||||
return keys.map((key) => {
|
||||
const propertyValue = getPropertyValue(properties, key);
|
||||
const value = key === "id" || key === "scada_id" || key === "device_id" ? propertyValue ?? featureId : propertyValue;
|
||||
|
||||
@@ -397,7 +452,15 @@ export function getFeatureInsightMetrics(
|
||||
layer: WaterNetworkSourceId,
|
||||
properties: Record<string, unknown>
|
||||
): FeatureInsightMetric[] {
|
||||
return FEATURE_INSIGHT_METRICS[layer].map((metric) => ({
|
||||
const definitions = FEATURE_INSIGHT_METRICS[layer]
|
||||
?? (isSourceGisSourceId(layer)
|
||||
? [
|
||||
{ label: "源图层", key: "source_layer_name" },
|
||||
{ label: "源要素", key: "source_fid" },
|
||||
{ label: "数据日期", key: "source_date" }
|
||||
]
|
||||
: []);
|
||||
return definitions.map((metric) => ({
|
||||
label: metric.label,
|
||||
value: metric.key
|
||||
? formatFeaturePropertyValue(metric.key, getPropertyValue(properties, metric.key))
|
||||
@@ -448,6 +511,24 @@ export function formatFeaturePropertyValue(key: string, value: unknown) {
|
||||
return value ? "在线" : "离线";
|
||||
}
|
||||
|
||||
if (normalizedKey === "latest_observed_at" && typeof value === "string") {
|
||||
const timestamp = Date.parse(value);
|
||||
if (Number.isFinite(timestamp)) {
|
||||
return new Intl.DateTimeFormat("zh-CN", {
|
||||
month: "2-digit",
|
||||
day: "2-digit",
|
||||
hour: "2-digit",
|
||||
minute: "2-digit",
|
||||
second: "2-digit",
|
||||
hour12: false
|
||||
}).format(new Date(timestamp));
|
||||
}
|
||||
}
|
||||
|
||||
if (normalizedKey === "latest_value_source" && value === "monitored_value") {
|
||||
return "SCADA 原始监测值";
|
||||
}
|
||||
|
||||
if (normalizedKey === "location_source" && value === "density_cluster_demo") {
|
||||
return "密度聚类模拟位置";
|
||||
}
|
||||
@@ -456,6 +537,10 @@ export function formatFeaturePropertyValue(key: string, value: unknown) {
|
||||
return "空间均匀采样模拟位置";
|
||||
}
|
||||
|
||||
if (normalizedKey === "selection_method" && value === "sensitivity") {
|
||||
return "灵敏度分析";
|
||||
}
|
||||
|
||||
if (normalizedKey === "kind" && typeof value === "string") {
|
||||
return SCADA_KIND_LABELS[value] ?? value;
|
||||
}
|
||||
@@ -465,7 +550,7 @@ export function formatFeaturePropertyValue(key: string, value: unknown) {
|
||||
return `${formatValue(value)} ${unit}`;
|
||||
}
|
||||
|
||||
if ((normalizedKey === "diameter" || normalizedKey === "dn") && value !== null && value !== undefined && value !== "") {
|
||||
if (["diameter", "dn", "minimum_diameter"].includes(normalizedKey) && value !== null && value !== undefined && value !== "") {
|
||||
const diameterInMillimeters = typeof value === "number" ? value : Number(value);
|
||||
return Number.isFinite(diameterInMillimeters)
|
||||
? `${formatValue(diameterInMillimeters)} mm`
|
||||
|
||||
Reference in New Issue
Block a user