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; }
}
}