using Yw.WinFrmUI.Q3D; //using Hydro.Inp; using Newtonsoft.Json.Linq; using Newtonsoft.Json; using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Numerics; using System.Text; using System.Threading; using System.Threading.Tasks; using static Yw.WinFrmUI.Q3D.ObjectEnum; using static Yw.WinFrmUI.Q3D.MapViewEnum; using Yw.WinFrmUI.Q3D; using System.Runtime.InteropServices; //using Hydro.HydraulicOptimizer; using Yw.WinFrmUI.Q3D; using System.Xml.Linq; namespace Yw.WinFrmUI.Q3D { [Serializable] public partial class MapViewNetWork { bool use_old = false; public string Name; #region 基础结构 [JsonIgnore] public List MapObjects { get { List objects = new List(); objects.AddRange(Nodes); objects.AddRange(Links); return objects.Select(o => (IBaseViewModel)o).ToList(); } } private LinkViewModelList _links = new LinkViewModelList(); public LinkViewModelList Links { get { return _links; } set { _links = value; } } private NodeViewModelList _nodes = new NodeViewModelList(); public NodeViewModelList Nodes { get { return _nodes; } set { _nodes = value; } } private List _areas = new List(); public List Areas { get { return _areas; } set { _areas = value; } } public NodeViewModel StartPoint { get; set; } public NodeViewModel EndPoint { get; set; } [JsonIgnore] public Dictionary dict_dataset = new Dictionary(); [JsonIgnore] public HashSet Hash_ID; [JsonIgnore] private List junctions { get { return Nodes.FindAll(n => n is JunctionViewModel).Select(n => n as JunctionViewModel).ToList(); } set { if (value == null) return; Nodes.RemoveAll(n => n is JunctionViewModel); Nodes.AddRange(value); } } [JsonIgnore] private List reservoirs { get { return Nodes.FindAll(n => n is ReservoirViewModel).Select(n => n as ReservoirViewModel).ToList(); } set { if (value == null) return; Nodes.RemoveAll(n => n is ReservoirViewModel); Nodes.AddRange(value); } } [JsonIgnore] private List tanks { get { return Nodes.FindAll(n => n is TankViewModel).Select(n => n as TankViewModel).ToList(); } set { if (value == null) return; Nodes.RemoveAll(n => n is TankViewModel); Nodes.AddRange(value); } } [JsonIgnore] private List meters { get { return Nodes.FindAll(n => n is MeterViewModel).Select(n => n as MeterViewModel).ToList(); } set { if (value == null) return; Nodes.RemoveAll(n => n is MeterViewModel); Nodes.AddRange(value); } } [JsonIgnore] private List nozzles { get { return Nodes.FindAll(n => n is NozzleViewModel).Select(n => n as NozzleViewModel).ToList(); } set { if (value == null) return; Nodes.RemoveAll(n => n is NozzleViewModel); Nodes.AddRange(value); } } [JsonIgnore] private List pipes { get { return Links.FindAll(n => n is PipeViewModel).Select(n => n as PipeViewModel).ToList(); } set { if (value == null) return; Links.RemoveAll(n => n is PipeViewModel); Links.AddRange(value); } } [JsonIgnore] private List valves { get { return Links.FindAll(n => n is ValveViewModel).Select(n => n as ValveViewModel).ToList(); } set { if (value == null) return; Links.RemoveAll(n => n is ValveViewModel); Links.AddRange(value); } } [JsonIgnore] private List pumps { get { return Links.FindAll(n => n is PumpViewModel).Select(n => n as PumpViewModel).ToList(); } set { if (value == null) return; Links.RemoveAll(n => n is PumpViewModel); Links.AddRange(value); } } private List areas = new List(); #endregion #region 添加对象 public JunctionViewModel AddJunction(string ID, PointF position, float z = 0) { JunctionViewModel j = new JunctionViewModel(); j.ID = ID; j.Demand = 0; j.PatternID = ""; j.Z = z; j.X = position.X; j.Y = position.Y; Nodes.Add(j); return j; } public JunctionViewModel AddJunction(PointF position, float z = 0) { JunctionViewModel j = new JunctionViewModel(); int i = 0; string ID = $"{Default.GetPreString(j)}{i}"; while (Nodes.Find(p0 => p0.ID == ID) != null) { i++; ID = $"{Default.GetPreString(j)}{i}"; } j.ID = ID; j.Z = 0; j.Demand = 0; j.PatternID = ""; j.Z = z; j.X = position.X; j.Y = position.Y; Nodes.Add(j); return j; } public MeterViewModel AddMeter(PointF position) { MeterViewModel j = new MeterViewModel(); int i = 0; string ID = $"{Default.GetPreString(j)}{i}"; while (Nodes.Find(p0 => p0.ID == ID) != null) { i++; ID = $"{Default.GetPreString(j)}{i}"; } j.ID = ID; j.Z = 0; j.Demand = 0; j.PatternID = ""; j.X = position.X; j.Y = position.Y; Nodes.Add(j); return j; } public ReservoirViewModel AddReservoir(PointF position) { ReservoirViewModel j = new ReservoirViewModel(); int i = 0; string ID = $"{Default.GetPreString(j)}{i}"; while (Nodes.Find(p0 => p0.ID == ID) != null) { i++; ID = $"{Default.GetPreString(j)}{i}"; } j.ID = ID; j.Z = 0; j.Demand = 0; j.PatternID = ""; j.Head = 100; j.X = position.X; j.Y = position.Y; Nodes.Add(j); return j; } public TankViewModel AddTank(PointF position) { TankViewModel j = new TankViewModel(); int i = 0; string ID = $"{Default.GetPreString(j)}{i}"; while (Nodes.Find(p0 => p0.ID == ID) != null) { i++; ID = $"{Default.GetPreString(j)}{i}"; } j.ID = ID; j.Z = 0; j.Demand = 0; j.PatternID = ""; j.X = position.X; j.Y = position.Y; Nodes.Add(j); return j; } public PipeViewModel AddPipe(NodeViewModel node1, NodeViewModel node2) { PipeViewModel pipe = new PipeViewModel(); int i = 0; string ID = $"{Default.GetPreString(pipe)}{i}"; while (Links.Find(p0 => p0.ID == ID) != null) { i++; ID = $"{Default.GetPreString(pipe)}{i}"; } pipe.ID = ID; pipe.Diameter = 100; pipe.MinorLoss = 0; pipe.Roughness = 100; pipe.Status = StatusType.DEFAULT; pipe.StartNode = node1; pipe.EndNode = node2; pipe.Length = -1; Links.Add(pipe); return pipe; } public ValveViewModel AddValve(NodeViewModel node1, NodeViewModel node2) { ValveViewModel valve = new ValveViewModel(); int i = 0; string ID = $"{Default.GetPreString(valve)}{i}"; while (Links.Find(p0 => p0.ID == ID) != null) { i++; ID = $"{Default.GetPreString(valve)}{i}"; } valve.ID = ID; valve.Diameter = 100; valve.Status = StatusType.DEFAULT; valve.StartNode = node1; valve.EndNode = node2; Links.Add(valve); return valve; } public PumpViewModel AddPump(NodeViewModel node1, NodeViewModel node2) { PumpViewModel pump = new PumpViewModel(); int i = 0; string ID = $"{Default.GetPreString(pump)}{i}"; while (Links.Find(p0 => p0.ID == ID) != null) { i++; ID = $"{Default.GetPreString(pump)}{i}"; } pump.ID = ID; pump.StartNode = node1; pump.EndNode = node2; Links.Add(pump); return pump; } #endregion #region 批量操作(暂时不需要,但是保留) public void Rename() { MapObjects.ForEach(o => o.ID = $"{Name}_{o.ID}"); } public void Add(List objects) { Nodes.AddRange(objects.FindAll(o => o is NodeViewModel).Select(o => (NodeViewModel)o)); Links.AddRange(objects.FindAll(o => o is LinkViewModel).Select(o => (LinkViewModel)o)); //BuildRelation(); } public void Clear() { Nodes.Clear(); Links.Clear(); } public List Remove(List list) { List objs = new List(); list.ForEach(o => { if (o == null) return; o.Selected = false; if (o is NodeViewModel n) { n.Links.ForEach(l => { if (this.Links.Remove(l)) objs.Add((LinkViewModel)l); }); if (this.Nodes.Remove(n)) objs.Add(n); } else if (o is LinkViewModel l) { if (this.Links.Remove(l)) objs.Add(l); } }); //BuildRelation(); return objs; } public void ChangePoint(NodeViewModel source, NodeViewModel newPoint) { Links.ForEach(l => { if (l.StartNode == source) { l.StartNode = newPoint; } else if (l.EndNode == source) { l.EndNode = newPoint; } }); source.Visible = false; //Nodes.Remove(source); } public void ChangeNodeID(NodeViewModel node, string ID) { node.ID = ID; node.Links.ForEach(l => { if (l.StartNode == node) { l.Node1 = node.ID; } else { l.Node2 = node.ID; } }); } public string GetValidID(IBaseViewModel obj) { string DefaultString = Default.GetPreString(obj); int i = 0; string ID = obj.ID; //List objs; ID = $"{DefaultString}{i}"; //while ((objs = MapObjects.FindAll(p0 => p0.ID == ID)).Count>1 && objs[0]!=obj) while (Hash_ID.Contains(ID)) { ID = $"{DefaultString}{i}"; i++; } return ID; } public MapViewNetWork CreateNew(PointF3D basepoint) { MapViewNetWork net = this.DeepCopy(); var BasePos = StartPoint.Position3D; net.Nodes.ForEach(n => { n.X += basepoint.X - BasePos.X; n.Y += basepoint.Y - BasePos.Y; n.Z += basepoint.Z - BasePos.Z; }); return net; } public void AddJoinNet(MapViewNetWork network) { if (Nodes.Count == 0) { Nodes.AddRange(network.Nodes); Links.AddRange(network.Links); StartPoint = network.StartPoint; EndPoint = network.EndPoint; } else { ChangePoint(EndPoint, network.StartPoint); Nodes.AddRange(network.Nodes); Links.AddRange(network.Links); //MapObjects.ForEach(n => n.ID = GetValidID(n)); EndPoint = network.EndPoint; } } public List Add(MapViewNetWork net0, PointF3D offset = null, bool isCopy = false, NodeViewModel ConnectNode = null) { if (offset == null) { offset = new PointF3D(0, 0, 0); } List list = new List(); if (Hash_ID == null) Hash_ID = new HashSet(); MapViewNetWork net = isCopy ? net0.DeepCopy() : net0; net.Nodes.ForEach(n0 => { NodeViewModel n = (NodeViewModel)n0; if (Hash_ID.Contains(n.ID)) { string ID = GetValidID(n); net.ChangeNodeID(n, ID); } n.X += offset.X; n.Y += offset.Y; n.Z += offset.Z; Nodes.Add(n); Hash_ID.Add(n.ID); list.Add(n); if (n0 == net.EndPoint && list[0] != n) { int index = list.IndexOf(n); var o = list[0]; list[0] = n; list[index] = o; } }); net.Links.ForEach(l0 => { LinkViewModel l = (LinkViewModel)l0; if (Hash_ID.Contains(l.ID)) { string ID = GetValidID(l); l.ID = ID; } Links.Add(l); Hash_ID.Add(l.ID); list.Add(l); }); if (ConnectNode != null) { var l = AddPipe(ConnectNode, net.StartPoint); list.Add(l); Hash_ID.Add(l.ID); } //BuildRelation(); return list; } #endregion #region 管网遍历/检查相关 // 定义 visited 字典记录已访问过的节点和待访问的节点队列 private Dictionary visited;//= new Dictionary(); private bool _isCalculated = false; private void BFS(MapViewNetWork net, NodeViewModel startNode, Vector3 vector) { Queue queue = new Queue(); // 标记起始节点为已访问,并加入队列 visited[startNode] = true; queue.Enqueue(startNode); // 不断从队列中取出节点进行访问,直到队列为空 while (queue.Count > 0) { // 取出队首节点并输出 NodeViewModel node = queue.Dequeue(); node.Move(vector); // 遍历当前节点的所有未访问邻居节点,并标记为已访问 foreach (LinkViewModel link in net.Links) { if (link.StartNode == node && !visited.ContainsKey(link.EndNode)) { visited[link.EndNode] = true; queue.Enqueue(link.EndNode); } else if (link.EndNode == node && !visited.ContainsKey(link.StartNode)) { visited[link.StartNode] = true; queue.Enqueue(link.StartNode); } } } } private List GetNode(string node) { return Nodes.FindAll(n => n.ID == node).Select(n => (NodeViewModel)n).ToList(); } public Dictionary> CheckValidate() { BuildRelation(); string result = null; Dictionary> result_dict = new Dictionary>(); StringBuilder result_sb = new StringBuilder(); //to-do var objs = Links.Select(o => o as LinkViewModel).ToList(); objs = objs.Distinct().ToList(); var visitedNodes = new HashSet(); FindObjs = new HashSet(); objs.ForEach(o => TraversePipeNetworkALL(o, visitedNodes)); List list_孤立点 = new List(); for (int i = 0; i < Nodes.Count; i++) { if (!FindObjs.Contains(Nodes[i])) { result_sb.AppendLine($"节点{Nodes[i].ID}是孤立点"); list_孤立点.Add(Nodes[i].ID); } } if (list_孤立点.Count > 0) result_dict.Add("孤立点", list_孤立点); //属性判断 var list_管道连接关系异常 = new List(); var list_管道长度小于等于0 = new List(); var list_粗糙系数设置错误 = new List(); var list_管径设置错误 = new List(); pipes.ForEach(p => { if (p.StartNode == null || p.EndNode == null) { result_sb.AppendLine($"{p.ID}管道连接关系异常"); list_管道连接关系异常.Add(p.ID); } if (p.Length <= 0) { result_sb.AppendLine($"{p.ID}管道长度小于等于0"); list_管道长度小于等于0.Add(p.ID); } if (p.Roughness <= 0.1 || p.Roughness > 10000) { result_sb.AppendLine($"{p.ID}粗糙系数设置错误"); list_粗糙系数设置错误.Add(p.ID); } if (p.Diameter <= 0.1 || p.Diameter > 10000) { result_sb.AppendLine($"{p.ID}管径设置错误"); list_管径设置错误.Add(p.ID); } }); if (list_管道连接关系异常.Count > 0) result_dict.Add("管道连接关系异常", list_管道连接关系异常); if (list_管道长度小于等于0.Count > 0) result_dict.Add("管道长度小于等于0", list_管道长度小于等于0); if (list_粗糙系数设置错误.Count > 0) result_dict.Add("粗糙系数设置错误", list_粗糙系数设置错误); if (list_管径设置错误.Count > 0) result_dict.Add("管径设置错误", list_管径设置错误); return result_dict; } HashSet FindObjs; private void TraversePipeNetworkALL(LinkViewModel startLink, HashSet visitedNodes = null, int direction = 0) { Queue queue = new Queue(); queue.Enqueue(startLink); if (visitedNodes == null) visitedNodes = new HashSet(); while (queue.Count > 0) { LinkViewModel currentLink = queue.Dequeue(); foreach (var node in new NodeViewModel[] { currentLink.StartNode, currentLink.EndNode }) { if (direction == 1 && currentLink.EN_FLOW >= 0 && node == currentLink.StartNode) continue; if (direction == -1 && currentLink.EN_FLOW <= 0 && node == currentLink.EndNode) continue; if (node != null && !visitedNodes.Contains(node)) { visitedNodes.Add(node); if (!FindObjs.Contains(node)) FindObjs.Add(node); //Console.WriteLine("Visiting Node: " + node.ID); foreach (var link in node.ViewLinks) { if (!visitedNodes.Contains(link.StartNode) || !visitedNodes.Contains(link.EndNode)) { if (!FindObjs.Contains(link)) FindObjs.Add(link); queue.Enqueue(link); } } } } } } #endregion } //构造一个List类,能够实现List的所有功能 [Serializable] public class LinkViewModelList:List { Dictionary dict; public LinkViewModelList() : base() { this.dict = new Dictionary(); } public List ViewLinks { get { var list = new List(); base.ForEach(l => { //if (l is LinkViewModel) list.Add((LinkViewModel)l); }); return list; //return base.Select(l => (LinkViewModel)l).ToList(); } } /// /// 更新字典 /// public void UpdateDict() { this.dict= new Dictionary(); base.ForEach(link => { if (!dict.ContainsKey(link.ID)) dict.Add(link.ID, (LinkViewModel)link); }); } /// /// 修改某个oldID至newID,同时更新字典 /// /// /// public void ChangeID(string oldID,string newID) { if (dict.ContainsKey(oldID)) { dict[oldID].ID = newID; dict.Add(newID, dict[oldID]); dict.Remove(oldID); } } /// /// 实现Add方法,同时更新字典 /// public void Add(LinkViewModel linkCalcModel) { base.Add(linkCalcModel); if (!dict.ContainsKey(linkCalcModel.ID)) dict.Add(linkCalcModel.ID, linkCalcModel); } /// /// 实现AddRange方法,同时更新字典 /// /// public void AddRange(List linkCalcModels) { base.AddRange(linkCalcModels); linkCalcModels.ForEach(link => { if (!dict.ContainsKey(link.ID)) dict.Add(link.ID, link); }); } public bool RemoveAt(int index) { if (index < 0 || index >= base.Count) return false; var link = base[index]; base.RemoveAt(index); if (dict.ContainsKey(link.ID)) dict.Remove(link.ID); return true; } /// /// 统计数量 /// public int Count { get { return base.Count; } } public LinkViewModel this[string ID] { get { if (dict.ContainsKey(ID)) return dict[ID]; else return (LinkViewModel)base.Find(l => l.ID == ID); } } public LinkViewModel this[int index] { get { return (LinkViewModel)base[index]; } } public void Sort() { base.Sort(); } //实现Sort(Comparison comparison)方法 public void Sort(Comparison comparison) { base.Sort(comparison); } //实现Select方法 public void Select(Action action) { //base.ForEach(action); //base.ForEach(action); ViewLinks.ForEach(action); } //实现Find方法 public LinkViewModel Find(Predicate match) { //base.Find(match); return ViewLinks.Find(match); } //实现FindAll方法 public List FindAll(Predicate match) { return ViewLinks.FindAll(match); } //实现ForEach方法 public void ForEach(Action action) { ViewLinks.ForEach(action); } //实现RemoveAll方法 public int RemoveAll(Predicate match) { return base.RemoveAll(match); } /// /// 实现Remove方法,同时更新字典 /// public bool Remove(LinkViewModel linkCalcModel) { if (base.Remove(linkCalcModel)) { if (dict.ContainsKey(linkCalcModel.ID)) dict.Remove(linkCalcModel.ID); return true; } else return false; } } //构造一个List类,能够实现List的所有功能 [Serializable] public class NodeViewModelList : List { //List base; Dictionary dict;//=new Dictionary();// public NodeViewModelList():base() { this.dict = new Dictionary(); } //public NodeViewModelList(List nodes) //{ // base = nodes; // base.ForEach(node => // { // if (!dict.ContainsKey(node.ID)) // dict.Add(node.ID,node); // }); //} /// /// 更新字典 /// public void UpdateDict() { this.dict = new Dictionary(); base.ForEach(node => { if (!dict.ContainsKey(node.ID)) dict.Add(node.ID, node); }); } /// /// 修改某个oldID至newID,同时更新字典 /// /// /// public void ChangeID(string oldID, string newID) { if (dict.ContainsKey(oldID)) { dict[oldID].ID = newID; dict.Add(newID, dict[oldID]); dict.Remove(oldID); } } /// /// 实现Add方法,同时更新字典 /// public void Add(NodeViewModel nodeCalcModel) { base.Add(nodeCalcModel); if (!dict.ContainsKey(nodeCalcModel.ID)) dict.Add(nodeCalcModel.ID, nodeCalcModel); } /// /// 实现AddRange方法,同时更新字典 /// /// public void AddRange(List nodeCalcModels) { base.AddRange(nodeCalcModels); nodeCalcModels.ForEach(node => { if (!dict.ContainsKey(node.ID)) dict.Add(node.ID, node); }); } /// /// 实现Remove方法,同时更新字典 /// public bool Remove(NodeViewModel nodeCalcModel) { if (base.Remove(nodeCalcModel)) { if (dict.ContainsKey(nodeCalcModel.ID)) dict.Remove(nodeCalcModel.ID); return true; } else return false; } public bool RemoveAt(int index) { if (index < 0 || index >= base.Count) return false; var node = base[index]; base.RemoveAt(index); if (dict.ContainsKey(node.ID)) dict.Remove(node.ID); return true; } /// /// 统计数量 /// public int Count { get { return base.Count; } } public NodeViewModel this[string ID] { get { if (dict.ContainsKey(ID)) return (NodeViewModel)dict[ID]; else return (NodeViewModel)base.Find(l => l.ID == ID); } } public NodeViewModel this[int index] { get { return (NodeViewModel)base[index]; } } //public List ToList() //{ // return base; //} //实现Sort方法 public List ViewNodes { get { //将NodeCalcModel转换为NodeViewModel //return this.Select(l => (NodeViewModel)l).ToList(); List list = new List(); foreach (var item in this) { list.Add((NodeViewModel)item); } return list; } } public void Sort() { base.Sort(); } //实现Sort(Comparison comparison)方法 public void Sort(Comparison comparison) { base.Sort(comparison); } //实现Select方法 public void Select(Action action) { ViewNodes.ForEach(action); //base.ForEach(action); } //实现Find方法 public NodeViewModel Find(Predicate match) { return ViewNodes.Find(match); } //实现FindAll方法 public List FindAll(Predicate match) { return ViewNodes.FindAll(match); } //实现ForEach方法 public void ForEach(Action action) { ViewNodes.ForEach(action); } //实现RemoveAll方法 public int RemoveAll(Predicate match) { return base.RemoveAll(match); } } }