6.3 KiB
6.3 KiB
name, description
| name | description |
|---|---|
| service-area-analysis | 基于实时水力模拟数据的水源追溯供水服务范围分区。通过管段流量确定水流方向,从水库BFS追溯服务节点,环网/零流量节点用无向拓扑补充分配,输出分区可视化。 |
供水服务范围分区工作流
概述
本工作流基于指定时刻的水力模拟结果,通过流向追溯法将全部管网节点分配到各水库的服务范围。核心思路:利用管段流量符号判定水流方向,构建有向图从水库逐级追溯,对环网和零流量节点用无向拓扑修正。
适用场景:供水服务范围评估、DMA分区规划、多水源供水格局分析、管网调度策略评估。
分区方法
第一步:水流方向判定
对于每条管段,根据实时流量 flow 判定水流方向:
| flow 值 | 水流方向 | 说明 |
|---|---|---|
flow > 1e-6 |
node1 → node2 | 正向流量 |
flow < -1e-6 |
node2 → node1 | 反向流量 |
| ` | flow | ≤ 1e-6` |
第二步:多源有向BFS
- 以每个水库为根节点,沿水流方向执行 BFS
- 遍历到的节点归属该水库的服务范围
- 先到先得:一个节点首次被访问到的水库即为归属
- 预期覆盖 85–90% 节点
第三步:无向拓扑修正
有向BFS不可达节点(通常 10–15%)通过无向图邻近性补充分配:
| 不可达原因 | 说明 |
|---|---|
| 环状管网 | 水流回路中下游节点反向连回上游,有向遍历被阻断 |
| 零流量管段 | flow≈0 的管段无方向,其下游节点断开 |
| 多水源交汇 | 交汇区流向往复,非树状拓扑 |
输出统计
每个分区输出:
node_count:分区内节点总数total_demand:总需水量(负数=净供水区)avg_pressure/min_pressure/max_pressure:压力统计
数据依赖
| 步骤 | 命令 | 数据量 | 超时 | 关键字段 |
|---|---|---|---|---|
| ① 管道拓扑 | network get-all-pipes-properties |
~11.7MB / 91K条 | 120s | id, node1, node2 |
| ② 水库属性 | network get-all-reservoirs-properties |
~小 | 120s | id, links |
| ③ 管段流量 | data timeseries realtime links --start-time T --end-time T+15min |
~39MB / 182K条 | 300s | id, flow, time |
| ④ 节点数据 | data timeseries realtime nodes --start-time T --end-time T+15min |
~28MB / 176K条 | 300s | id, pressure, actual_demand, time |
时间窗口:模拟步长 15 分钟,查询 T~T+15min 覆盖 1–2 个时间步。脚本按
--target-time精确筛选。
文件输入:四份调用都使用
store_result=true,包括结果较小的水库属性。脚本读取每次返回的data_file.file_path;文件都属于当前对话,禁止使用/tmp或全局tool-output/。
执行步骤
第 1 步:并行拉取数据
4 个 tjwater_cli 调用(互不依赖),可一次发起:
# ① 管道静态拓扑
tjwater_cli(command="network get-all-pipes-properties", timeout=120, store_result=true)
# ② 水库属性
tjwater_cli(command="network get-all-reservoirs-properties", timeout=120, store_result=true)
# ③ 目标时刻管段流量
tjwater_cli(command="data timeseries realtime links --start-time 2026-04-01T08:00:00+08:00 --end-time 2026-04-01T08:15:00+08:00", timeout=300, store_result=true)
# ④ 目标时刻节点数据
tjwater_cli(command="data timeseries realtime nodes --start-time 2026-04-01T08:00:00+08:00 --end-time 2026-04-01T08:15:00+08:00", timeout=300, store_result=true)
第 2 步:运行分区脚本
python3 <skill_dir>/scripts/service_area_partition.py \
--pipe-props <data_file.file_path-①> \
--reservoirs <data_file.file_path-②> \
--links <data_file.file_path-③> \
--nodes <data_file.file_path-④> \
--target-time '2026-04-01T08:00:00+08:00' \
--output ./service_area_partition_wrapper.json
脚本参数:
| 参数 | 说明 | 必填 |
|---|---|---|
--pipe-props |
管道属性 JSON 文件路径 | 是 |
--reservoirs |
水库属性 JSON 文件路径 | 是 |
--links |
实时管段数据 JSON 文件路径 | 是 |
--nodes |
实时节点数据 JSON 文件路径 | 是 |
--target-time |
目标时刻 ISO8601 | 是 |
--output |
分区结果输出路径 | 是 |
输出:
- stderr:处理日志 + 各分区统计表格
- stdout:紧凑 JSON 摘要(total_nodes, reservoirs, areas)
- 文件:符合
store_render_ref要求的{metadata, location, data}包装 JSON,其中data包含node_area_map、area_ids、area_colors和分析元数据
第 3 步:前端可视化
# 持久化分区结果
store_render_ref(file_path=<output-file>)
# 渲染节点分区
render_junctions(render_ref="res-xxxxxxxx-xxxx-xx")
# 定位水库
locate_features(ids=[...], feature_type="reservoir")
# 展示统计图表
show_chart(title="各水源分区节点数/压力对比", chart_type="bar", ...)
参考数据规模
基于 91,000 管段 / 88,000 节点规模的管网模型:
| 指标 | 实测值 |
|---|---|
| 管道拓扑数据量 | 91,052 条 |
| 水库数量 | 13 个 |
| 总节点数 | 87,907 |
| 有向BFS分配节点 | ~76,900 (87.5%) |
| 无向修正节点 | ~11,000 (12.5%) |
| 分区覆盖率 | 100% |
| 脚本处理时间 | ~15-30 秒 |
| 峰值内存 | ~400-500MB |
已知限制
- 水库顺序敏感:多源 BFS 中先遍历到的水库优先分配,不同水库启动顺序可能影响边界区域分配结果
- 单时刻快照:分区仅反映目标时刻的水力工况,不同时段的泵站启停、阀门切换可能导致分区边界变化
- 零流量阈值:
1e-6阈值过滤极低流量管段,若管网有长期小流量管段可能漏判方向
Learned Patterns
- [6614a914a8f7dcc2fc34c1ba] 实时数据时间匹配必须用 norm_time 归一化为 UTC 再比较(数据 time 为 UTC 格式如 2026-06-03T00:00:00+00:00,target-time 传 +08:00 会因字符串不等而筛出 0 条);links/nodes 记录主键字段为 link_id/node_id(不是 id)。执行分区前先确认目标时刻存在实时数据,可用
data timeseries realtime simulation-by-id-time探测;数据可能只覆盖某几天(本模型覆盖 2026-06-03 附近,2026-04 与 2026-08 均无数据)。