namespace Yw.Epanet
{
///
/// 管网检查拓展
///
public static class NetworkCheckExtensions
{
///
/// 根据Inp文件计算
///
public static CheckResult Check(this Network nw)
{
if (nw == null)
{
return default;
}
var result = new CheckResult();
//构件重复
var allParterList = nw.GetAllParters();
if (allParterList != null && allParterList.Count > 0)
{
var parters = allParterList.Distinct().ToList();
if (parters.Count != allParterList.Count)
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = string.Empty,
CheckType = eCheckType.RepeatParer,
FailReason = "构件重复,请联系开发人员"
});
}
}
//编码为空
if (allParterList != null && allParterList.Count > 0)
{
foreach (var parter in allParterList)
{
if (string.IsNullOrEmpty(parter.Id?.Trim()))
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = string.Empty,
CheckType = eCheckType.EmptyId,
FailReason = $"[{parter.Name}]构件编码为空,请联系开发人员"
});
}
}
}
//编码重复
if (allParterList != null && allParterList.Count > 0)
{
var parters = allParterList.Distinct().ToList();
var parterIds = parters.Select(x => x.Id).Distinct().ToList();
if (parters.Count != parterIds.Count)
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = string.Empty,
CheckType = eCheckType.RepeatId,
FailReason = $"构件编码重复,请联系开发人员"
});
}
}
//缺少水源
var allSourceList = nw.GetAllSources();
if (allSourceList == null || allSourceList.Count < 1)
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = string.Empty,
CheckType = eCheckType.LackSource,
FailReason = "缺少水源,至少需包含一座水库或水池"
});
}
//缺少连接节点
var allJunctionList = nw.GetAllJunctions();
if (allJunctionList == null || allJunctionList.Count < 1)
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = string.Empty,
CheckType = eCheckType.LackJunction,
FailReason = "缺少连接节点,至少需包含一个连接节点"
});
}
//孤立节点
var allNodeList = nw.GetAllNodes();
if (allNodeList != null && allNodeList.Count > 0)
{
foreach (var node in allNodeList)
{
if (node.Links == null || node.Links.Count < 1)
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = node.Id,
CheckType = eCheckType.AloneNode,
FailReason = $"孤立节点[{node.Name}],没有任何管段连接"
});
}
}
}
//节点连接异常
if (allNodeList != null && allNodeList.Count > 0)
{
foreach (var node in allNodeList)
{
if (node.Links != null && node.Links.Count > 0)
{
var links = node.Links.Distinct().ToList();
if (links.Count != node.Links.Count)
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = node.Id,
CheckType = eCheckType.AbnormalNodeConnected,
FailReason = $"[{node.Name}]节点连接异常"
});
}
}
}
}
//孤立管段
var allLinkList = nw.GetAllLinks();
if (allLinkList != null && allLinkList.Count > 0)
{
foreach (var link in allLinkList)
{
if (link.StartNode == null && link.EndNode == null)
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = link.Id,
CheckType = eCheckType.AloneLink,
FailReason = $"孤立管段[{link.Name}],没有连接任何节点"
});
}
}
}
//管段缺少连接节点
if (allLinkList != null && allLinkList.Count > 0)
{
foreach (var link in allLinkList)
{
if (link.StartNode != null || link.EndNode != null)
{
if (link.StartNode == null)
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = link.Id,
CheckType = eCheckType.LackLinkNode,
FailReason = $"[{link.Name}]缺少上游节点"
});
}
if (link.EndNode == null)
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = link.Id,
CheckType = eCheckType.LackLinkNode,
FailReason = $"[{link.Name}]缺少下游节点"
});
}
}
}
}
//管段异常连接
if (allLinkList != null && allLinkList.Count > 0)
{
foreach (var link in allLinkList)
{
if (link.StartNode == link.EndNode)
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = link.Id,
CheckType = eCheckType.AbnormalLinkConnected,
FailReason = $"[{link.Name}]管段异常连接,上游与下游节点相同"
});
}
}
}
//属性设置错误
var allPipeList = nw.Pipes;
if (allPipeList != null && allPipeList.Count > 0)
{
foreach (var pipe in allPipeList)
{
if (pipe.Length <= 0)
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = pipe.Id,
CheckType = eCheckType.ErrorPropSet,
FailReason = $"[{pipe.Name}]属性设置错误,管道长度必须大于0"
});
}
if (pipe.Roughness <= 10 || pipe.Roughness >= 10000)
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = pipe.Id,
CheckType = eCheckType.ErrorPropSet,
FailReason = $"[{pipe.Name}]属性设置错误,粗糙系数区间(10,10000)"
});
}
if (pipe.Diameter <= 10 || pipe.Diameter >= 10000)
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = pipe.Id,
CheckType = eCheckType.ErrorPropSet,
FailReason = $"[{pipe.Name}]属性设置错误,管径区间(10,10000)"
});
}
}
}
//验证连通性
if (!IsConnectedBFS(nw))
{
result.Succeed = false;
result.FailedList.Add(new CheckFailed()
{
Id = string.Empty,
CheckType = eCheckType.AbnormalConnectivity,
FailReason = $"[广度优先搜索]判断管网连通性异常"
});
}
return result;
}
//采用广度优先搜索判断管网连通性
private static bool IsConnectedBFS(this Network nw)
{
if (nw == null)
{
return false;
}
//没有管段视为不连通
var allLinkList = nw.GetAllLinks();
if (allLinkList == null || allLinkList.Count < 1)
{
return false;
}
//管段开始节点或结束节点为空时视为不连通
if (allLinkList.Exists(x => x.StartNode == null || x.EndNode == null))
{
return false;
}
//管段存在开始节点和结束节点相同视为不连通
if (allLinkList.Exists(x => x.StartNode == x.EndNode))
{
return false;
}
//没有节点视为不连通
var allNodeList = nw.GetAllNodes();
if (allNodeList == null || allNodeList.Count < 1)
{
return false;
}
//收集所有出现在管道中的节点
HashSet nodes = new HashSet();
foreach (var link in allLinkList)
{
nodes.Add(link.StartNode);
nodes.Add(link.EndNode);
}
// 空管网视为不连通
if (nodes.Count < 1)
{
return false;
}
//收集节点与管道所有节点不一致视为不连通
if (nodes.Count != allNodeList.Count)
{
return false;
}
// 构建邻接表
Dictionary> adjacencyList = new Dictionary>();
foreach (var node in nodes)
{
adjacencyList[node] = new List();
}
foreach (var link in allLinkList)
{
adjacencyList[link.StartNode].Add(link.EndNode);
adjacencyList[link.EndNode].Add(link.StartNode);
}
// BFS遍历
HashSet visited = new HashSet();
Queue queue = new Queue();
Node startNode = nodes.First();
queue.Enqueue(startNode);
visited.Add(startNode);
while (queue.Count > 0)
{
Node current = queue.Dequeue();
foreach (Node neighbor in adjacencyList[current])
{
if (!visited.Contains(neighbor))
{
visited.Add(neighbor);
queue.Enqueue(neighbor);
}
}
}
// 检查是否所有节点都被访问
return visited.Count == nodes.Count;
}
//采用深度优先搜索判断管网连通性
private static bool IsConnectedDFS(this Network nw)
{
if (nw == null)
{
return false;
}
//没有管段视为不连通
var allLinkList = nw.GetAllLinks();
if (allLinkList == null || allLinkList.Count < 1)
{
return false;
}
//管段开始节点或结束节点为空时视为不连通
if (allLinkList.Exists(x => x.StartNode == null || x.EndNode == null))
{
return false;
}
//管段存在开始节点和结束节点相同视为不连通
if (allLinkList.Exists(x => x.StartNode == x.EndNode))
{
return false;
}
//没有节点视为不连通
var allNodeList = nw.GetAllNodes();
if (allNodeList == null || allNodeList.Count < 1)
{
return false;
}
//收集所有出现在管道中的节点
HashSet nodes = new HashSet();
foreach (var link in allLinkList)
{
nodes.Add(link.StartNode);
nodes.Add(link.EndNode);
}
// 空管网视为不连通
if (nodes.Count < 1)
{
return false;
}
//收集节点与管道所有节点不一致视为不连通
if (nodes.Count != allNodeList.Count)
{
return false;
}
// 构建邻接表
Dictionary> adjacencyList = new Dictionary>();
foreach (var node in nodes)
{
adjacencyList[node] = new List();
}
foreach (var link in allLinkList)
{
adjacencyList[link.StartNode].Add(link.EndNode);
adjacencyList[link.EndNode].Add(link.StartNode);
}
// DFS遍历(迭代式实现)
HashSet visited = new HashSet();
Stack stack = new Stack();
Node startNode = nodes.First();
stack.Push(startNode);
visited.Add(startNode);
while (stack.Count > 0)
{
Node current = stack.Pop();
foreach (Node neighbor in adjacencyList[current])
{
if (!visited.Contains(neighbor))
{
visited.Add(neighbor);
stack.Push(neighbor); // 邻接节点入栈
}
}
}
// 检查是否所有节点都被访问
return visited.Count == nodes.Count;
}
}
}