using System.Data; using System.Drawing; using System.Text; namespace Yw.EPAnet { /// /// 管网路径分析拓展 /// public static class NetworkPathAnalyseExtensions { internal class InnerLossNode { public string Id { get; set; } /// /// 起始水头 /// public double StartHead { get; set; } /// /// 结束水头 /// public double EndHead { get; set; } /// /// 高程 /// public double Elev { get; set; } /// /// 水头 /// public double Head { get; internal set; } /// /// 局部水头损失 /// public double MinorHeadLoss { get { return StartHead - EndHead; } } public double Distance { get; set; } } public static List GetChartNodeByPathLinks(this Network network, List links,CalcuResult calcuResult) { var dictLinks = calcuResult.LinkList.ToDictionary(p => p.Id); var dictNodes = calcuResult.NodeList.ToDictionary(p => p.Id); double length = 0; InnerLossNode nodeEnd = new InnerLossNode(); List chartNodes = new List(); for (int i = 0; i < links.Count; i++) { var link = links[i]; var node = dictLinks[link.Id].Flow > 0 ? link.StartNode : link.EndNode; double elev = getElev(node); var Cnode = new InnerLossNode() { Id = node.Id, StartHead = dictNodes[node.Id].Head, EndHead = dictNodes[node.Id].Head, Elev = elev, Distance = length }; chartNodes.Add(Cnode); var nodeEnd0 = dictLinks[link.Id].Flow > 0 ? link.EndNode : link.StartNode; nodeEnd.Id = nodeEnd0.Id; nodeEnd.Head = nodeEnd.StartHead = nodeEnd.EndHead = dictNodes[nodeEnd0.Id].Head; nodeEnd.Elev = getElev(nodeEnd0); if (link is Pipe p) length += p.Length; } chartNodes.Add(nodeEnd); for (int i=0;i lossNodes = new List(); for (int i = 0; i < chartNodes.Count; i++) { var node = chartNodes[i]; LossNode lossNode = new LossNode() { Id = node.Id, Elev = node.Elev, Head = node.StartHead, MinorLoss = node.MinorHeadLoss, Distance =node.Distance, }; lossNodes.Add(lossNode); } return lossNodes; } private static double getElev(Node node) { double elev = 0; if (node is Tank tank) { elev = tank.PoolElev + tank.InitLevel; } else if (node is Reservoir reser) { elev = reser.Head; } else if (node is Junction junc) { elev = junc.Elev; } return elev; } /// /// 分析下游主要供水路径 /// public static List AnalyzeDownstreamPath(this Network network, Node startJunc,CalcuResult calcuResult) { var dictLinks = calcuResult.LinkList.ToDictionary(p => p.Id); var dictNodes = calcuResult.NodeList.ToDictionary(p => p.Id); var visitedNodes = new HashSet(); var nextLinks = startJunc.GetNextLinks(calcuResult.LinkList); if (nextLinks.Count <= 0) return nextLinks; var maxlink = nextLinks.OrderByDescending(o => Math.Abs(dictLinks[o.Id].Flow)).ToList()[0]; return network.TraversePipeNetworkALL(maxlink, visitedNodes, 1, true); } /// /// 分析上游主要供水路径 /// /// /// /// public static List AnalyzeUpstreamPath(this Network network, Junction startJunc, CalcuResult calcuResult) { var dictLinks = calcuResult.LinkList.ToDictionary(p => p.Id); var dictNodes = calcuResult.NodeList.ToDictionary(p => p.Id); var visitedNodes = new HashSet(); var maxlink = startJunc.GetPrevLinks(calcuResult.LinkList).OrderByDescending(o => Math.Abs(dictLinks[o.Id].Flow)).ToList()[0]; return network.TraversePipeNetworkALL(maxlink, visitedNodes, -1, true, calcuResult); } /// /// 宽度搜索遍历管网 /// /// /// 起始管线 /// 遍历的哈希表(用于多点遍历) /// 遍历方向,0表示双向,1表示正向,-1表示反向 /// 是否只取最大流量的分支 /// public static List TraversePipeNetworkALL(this Network network, Link startLink, HashSet visitedNodes = null, int direction = 0, bool isOnlyMax = false,CalcuResult calcuResult=null) { var dictLinks = calcuResult.LinkList.ToDictionary(p => p.Id); var dictNodes = calcuResult.NodeList.ToDictionary(p => p.Id); var _links主要路径=new List(); if (isOnlyMax) _links主要路径.Add(startLink); Queue queue = new Queue(); queue.Enqueue(startLink); if (visitedNodes == null) visitedNodes = new HashSet(); while (queue.Count > 0) { Link currentLink = queue.Dequeue(); if (isOnlyMax) _links主要路径.Add(currentLink); foreach (var node in new Node[] { currentLink.StartNode, currentLink.EndNode }) { if (direction == 1 && dictLinks[currentLink.Id].Flow >= 0 && node == currentLink.StartNode) continue; if (direction == -1 && dictLinks[currentLink.Id].Flow <= 0 && node == currentLink.EndNode) continue; if (node != null && !visitedNodes.Contains(node)) { visitedNodes.Add(node); List list = new List(); foreach (var link in node.Links) { if (!visitedNodes.Contains(link.StartNode) || !visitedNodes.Contains(link.EndNode)) { list.Add(link); } } if (!isOnlyMax) { foreach (var link in list) { queue.Enqueue(link); } } else { if (list.Count >= 1) { var maxlist = list.OrderByDescending(p => Math.Abs(dictLinks[p.Id].Flow)).ToList()[0]; queue.Enqueue(maxlist); } } } } } return _links主要路径; } } public class LossNode { public string Id { get; set; } /// /// 高程 /// public double Elev { get; set; } /// /// 水头 /// public double Head { get; set; } /// /// 局部水头损失 /// public double MinorLoss { get; set; } /// /// 距离 /// public double Distance { get; set; } } }