namespace Yw.Epanet
{
///
/// 管网路径分析拓展
///
public static class NetworkAnalysePathExtensions
{
///
/// 遍历下游主要供水路径
///
/// 节点
/// 所有管段计算字典
///
public static List TraverseMainDownStreamPath(this Node node, Dictionary allCalcuLinkDict)
{
if (node == null)
{
return default;
}
if (allCalcuLinkDict == null || allCalcuLinkDict.Count < 1)
{
return default;
}
var visited = new HashSet();
var queue = new Queue();
queue.Enqueue(node);
var pathLinks = new List();
while (queue.Count > 0)
{
var current = queue.Dequeue();
if (visited.Contains(current))
{
break;
}
visited.Add(current);
if (current.Links != null && current.Links.Count > 0)
{
var linkDict = new Dictionary();
foreach (var link in current.Links)
{
var calcuLink = allCalcuLinkDict.GetValue(link.Id);
if (calcuLink != null)
{
if (link.StartNodeId == current.Id)
{
if (calcuLink.Flow > 0)
{
linkDict.Add(link, calcuLink);
}
}
else if (link.EndNodeId == current.Id)
{
if (calcuLink.Flow < 0)
{
linkDict.Add(link, calcuLink);
}
}
}
}
if (linkDict.Count > 0)
{
var linkKeyValue = linkDict.OrderBy(x => Math.Abs(x.Value.Flow)).LastOrDefault();
pathLinks.Add(linkKeyValue.Key);
var nextNode = linkKeyValue.Key.GetEndNode(linkKeyValue.Value);
if (nextNode != null)
{
queue.Enqueue(nextNode);
}
}
}
}
return pathLinks;
}
///
/// 遍历下游主要供水路径
///
/// 节点
/// 所有管段计算列表
///
public static List TraverseMainDownStreamPath(this Node node, List allCalcuLinkList)
{
var dict = allCalcuLinkList?.ToDictionary(x => x.Id);
return node.TraverseMainDownStreamPath(dict);
}
///
/// 遍历上游主要供水路径
///
/// 节点
/// 所有管段计算字典
///
public static List TraverseMainUpStreamPath(this Node node, Dictionary allCalcuLinkDict)
{
if (node == null)
{
return default;
}
if (allCalcuLinkDict == null || allCalcuLinkDict.Count < 1)
{
return default;
}
var visited = new HashSet();
var queue = new Queue();
queue.Enqueue(node);
var pathLinks = new List();
while (queue.Count > 0)
{
var current = queue.Dequeue();
if (visited.Contains(current))
{
break;
}
visited.Add(current);
if (current.Links != null && current.Links.Count > 0)
{
var linkDict = new Dictionary();
foreach (var link in current.Links)
{
var calcuLink = allCalcuLinkDict.GetValue(link.Id);
if (calcuLink != null)
{
if (link.StartNodeId == current.Id)
{
if (calcuLink.Flow < 0)
{
linkDict.Add(link, calcuLink);
}
}
else if (link.EndNodeId == current.Id)
{
if (calcuLink.Flow > 0)
{
linkDict.Add(link, calcuLink);
}
}
}
}
if (linkDict.Count > 0)
{
var linkKeyValue = linkDict.OrderBy(x => Math.Abs(x.Value.Flow)).LastOrDefault();
pathLinks.Add(linkKeyValue.Key);
var nextNode = linkKeyValue.Key.GetStartNode(linkKeyValue.Value);
if (nextNode != null)
{
queue.Enqueue(nextNode);
}
}
}
}
return pathLinks;
}
///
/// 遍历上游主要供水路径
///
/// 节点
/// 所有管段计算列表
///
public static List TraverseMainUpStreamPath(this Node node, List allCalcuLinkList)
{
var dict = allCalcuLinkList?.ToDictionary(x => x.Id);
return node.TraverseMainUpStreamPath(dict);
}
///
/// 遍历主要供水路径
///
/// 节点
/// 所有管段计算字典
/// 方向
///
public static List TraverseMainStreamPath(this Node node, Dictionary allCalcuLinkDict, eTraverseDirection direction = eTraverseDirection.All)
{
if (node == null)
{
return default;
}
if (allCalcuLinkDict == null || allCalcuLinkDict.Count < 1)
{
return default;
}
List pathLinks = null;
switch (direction)
{
case eTraverseDirection.Up:
{
pathLinks = TraverseMainUpStreamPath(node, allCalcuLinkDict);
}
break;
case eTraverseDirection.Down:
{
pathLinks = TraverseMainDownStreamPath(node, allCalcuLinkDict);
}
break;
case eTraverseDirection.All:
{
pathLinks = new List();
var pathUpLinks = TraverseMainUpStreamPath(node, allCalcuLinkDict);
if (pathUpLinks != null && pathUpLinks.Count > 0)
{
pathLinks.AddRange(pathUpLinks);
}
var pathDownLinks = TraverseMainDownStreamPath(node, allCalcuLinkDict);
if (pathDownLinks != null && pathDownLinks.Count > 0)
{
pathLinks.AddRange(pathDownLinks);
}
}
break;
default: break;
}
return pathLinks;
}
///
/// 遍历主要供水路径
///
/// 节点
/// 所有管段计算列表
/// 方向
///
public static List TraverseMainStreamPath(this Node node, List allCalcuLinkList, eTraverseDirection direction = eTraverseDirection.All)
{
var dict = allCalcuLinkList?.ToDictionary(x => x.Id);
return node.TraverseMainStreamPath(dict, direction);
}
///
/// 获取路径损失节点列表
///
/// 管网
/// 管段路径
/// 计算结果
///
public static List GetPathLossNodeList(this Network nw, List pathLinks, CalcuResult calcuResult)
{
#region 验证
if (nw == null)
{
return default;
}
if (pathLinks == null || pathLinks.Count < 1)
{
return default;
}
if (calcuResult == null)
{
return default;
}
if (!calcuResult.Succeed)
{
return default;
}
var allCalcuNodeDict = calcuResult.GetNodeDict();
if (allCalcuNodeDict == null || allCalcuNodeDict.Count < 1)
{
return default;
}
var allCalcuLinkDict = calcuResult.GetLinkDict();
if (allCalcuLinkDict == null || allCalcuLinkDict.Count < 1)
{
return default;
}
#endregion
double distance = 0;
var allPathLossNodeList = new List();
for (int i = 0; i < pathLinks.Count; i++)
{
var link = pathLinks[i];
var calcuLink = allCalcuLinkDict.GetValue(link.Id);
if (calcuLink == null)
{
continue;
}
var startNode = link.GetStartNode(calcuLink);
if (startNode == null)
{
continue;
}
var startCalcuNode = allCalcuNodeDict.GetValue(startNode.Id);
if (startCalcuNode == null)
{
continue;
}
var startPathLossNode = new PathLossNode()
{
Id = startNode.Id,
Elev = startNode.GetElev(),
Distance = distance,
Head = startCalcuNode.Head,
MinorLoss = startCalcuNode.MinorLoss
};
allPathLossNodeList.Add(startPathLossNode);
if (link is Pipe pipe)
{
distance += pipe.Length;
}
else if (link is Pump pump)
{
distance += ConstParas.DefaultPumpLength;
}
else if (link is Valve)
{
distance += ConstParas.DefaultValveLength;
}
if (i == pathLinks.Count - 1)
{
var endNode = link.GetEndNode(calcuLink);
if (endNode == null)
{
continue;
}
var endCalcuNode = allCalcuNodeDict.GetValue(endNode.Id);
if (endCalcuNode == null)
{
continue;
}
var endPathLossNode = new PathLossNode()
{
Id = endNode.Id,
Elev = endNode.GetElev(),
Distance = distance,
Head = endCalcuNode.Head,
MinorLoss = endCalcuNode.MinorLoss
};
allPathLossNodeList.Add(endPathLossNode);
}
}
return allPathLossNodeList;
}
}
}