using Hydro.Core.Model;
|
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 Hydro.Core.ObjectEnum;
|
using Hydro.MapView.Common;
|
using static Hydro.MapView.MapViewEnum;
|
using Hydro.CommonBase;
|
using TimePoint = Hydro.CommonBase.TimePoint;
|
using System.Runtime.InteropServices;
|
using Hydro.HydraulicOptimizer;
|
using Hydro.Core;
|
using System.Xml.Linq;
|
|
namespace Hydro.MapView
|
{
|
[Serializable]
|
public partial class MapViewNetWork : NetWork
|
{
|
bool use_old = false;
|
public string Name;
|
private LinkViewModelList _links=new LinkViewModelList();
|
public LinkViewModelList Links { get { return _links; } set { base.Links= _links = value; } }
|
|
private NodeViewModelList _nodes = new NodeViewModelList();
|
public NodeViewModelList Nodes { get { return _nodes; }set { base.Nodes = _nodes = value; } }
|
|
public NodeViewModel StartPoint { get; set; }
|
|
public NodeViewModel EndPoint { get; set; }
|
|
/// <summary>
|
/// 当量集合,当量模板ID,<器具ID,数量>
|
/// </summary>
|
//public Dictionary<long,Dictionary<long,int>> DlList { get; set; }
|
|
/// <summary>
|
/// 核心承载字段
|
/// </summary>
|
//public new List<NodeViewModel> Nodes = new List<NodeViewModel>();
|
|
/// <summary>
|
/// 核心承载字段
|
/// </summary>
|
//public new List<LinkViewModel> Links = new List<LinkViewModel>();
|
[JsonIgnore]
|
public Dictionary<string, Dataset> dict_dataset = new Dictionary<string, Dataset>();
|
[JsonIgnore]
|
public HashSet<string> Hash_ID;
|
|
[JsonIgnore]
|
public List<JunctionViewModel> 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]
|
public List<ReservoirViewModel> 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]
|
public List<TankViewModel> 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]
|
public List<MeterViewModel> 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]
|
public List<NozzleViewModel> 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]
|
public List<PipeViewModel> 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]
|
public List<ValveViewModel> 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]
|
public List<ValveNodeViewModel> valveNodes
|
{
|
get
|
{
|
return Nodes.FindAll(n => n is ValveNodeViewModel).Select(n => n as ValveNodeViewModel).ToList();
|
}
|
set
|
{
|
if (value == null) return;
|
Nodes.RemoveAll(n => n is ValveNodeViewModel);
|
Nodes.AddRange(value);
|
}
|
}
|
|
[JsonIgnore]
|
public List<RepeaterViewModel> repeaters
|
{
|
get
|
{
|
return Links.FindAll(n => n is RepeaterViewModel).Select(n => n as RepeaterViewModel).ToList();
|
}
|
set
|
{
|
if (value == null) return;
|
Links.RemoveAll(n => n is RepeaterViewModel);
|
Links.AddRange(value);
|
}
|
}
|
[JsonIgnore]
|
public List<PumpViewModel> 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);
|
}
|
}
|
[JsonIgnore]
|
public List<PumpNodeViewModel> pumpNodes
|
{
|
get
|
{
|
return Nodes.FindAll(n => n is PumpNodeViewModel).Select(n => n as PumpNodeViewModel).ToList();
|
}
|
set
|
{
|
if (value == null) return;
|
Nodes.RemoveAll(n => n is PumpNodeViewModel);
|
Nodes.AddRange(value);
|
}
|
}
|
public List<JunctionViewModel> Deserialized_junctions { get; set; }
|
public List<TankViewModel> Deserialized_tanks { get; set; }
|
public List<ReservoirViewModel> Deserialized_reservoirs { get; set; }
|
public List<MeterViewModel> Deserialized_meters { get; set; }
|
public List<NozzleViewModel> Deserialized_nozzles { get; set; }
|
public List<PipeViewModel> Deserialized_pipes { get; set; }
|
public List<ValveViewModel> Deserialized_valves { get; set; }
|
public List<ValveNodeViewModel> Deserialized_valveNodes { get; set; }
|
public List<RepeaterViewModel> Deserialized_repeaters { get; set; }
|
public List<PumpViewModel> Deserialized_pumps { get; set; }
|
public List<PumpNodeViewModel> Deserialized_pumpNodes { get; set; }
|
|
public List<AreaViewModel> areas = new List<AreaViewModel>();
|
|
public bool ReadFromJson(string json)
|
{
|
try
|
{
|
var net = JsonConvert.DeserializeObject<MapViewNetWork>(json);
|
//net.junctions.Clear();
|
//net.Nodes.Clear();
|
junctions = net.Deserialized_junctions;
|
tanks = net.Deserialized_tanks;
|
reservoirs = net.Deserialized_reservoirs;
|
meters = net.Deserialized_meters;
|
nozzles = net.Deserialized_nozzles;
|
pipes = net.Deserialized_pipes;
|
valves = net.Deserialized_valves;
|
valveNodes = net.Deserialized_valveNodes;
|
repeaters = net.Deserialized_repeaters;
|
pumps = net.Deserialized_pumps;
|
pumpNodes = net.Deserialized_pumpNodes;
|
StartPoint = net.StartPoint;
|
EndPoint = net.EndPoint;
|
return true;
|
}
|
catch
|
{
|
return false;
|
}
|
|
|
|
}
|
public string WriteToJson()
|
{
|
var net = new MapViewNetWork();
|
net.Deserialized_junctions = junctions;
|
net.Deserialized_tanks = tanks;
|
net.Deserialized_reservoirs = reservoirs;
|
net.Deserialized_meters = meters;
|
net.Deserialized_nozzles = nozzles;
|
net.Deserialized_pipes = pipes;
|
net.Deserialized_valves = valves;
|
//net.Deserialized_valveNodes = valveNodes;
|
net.Deserialized_repeaters = repeaters;
|
net.Deserialized_pumps = pumps;
|
net.StartPoint = StartPoint;
|
net.EndPoint = EndPoint;
|
//net.Deserialized_pumpNodes = pumpNodes;
|
string json = JsonConvert.SerializeObject(net);
|
return json;
|
}
|
|
|
public JunctionViewModel AddJunction(string ID, PointF position, float z = 0)
|
{
|
JunctionViewModel j = new JunctionViewModel();
|
|
j.ID = ID;
|
j.Demand = 0;
|
j.PatternID = "";
|
j.Elev = 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.Elev = 0;
|
j.Demand = 0;
|
j.PatternID = "";
|
j.Elev = 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.Elev = 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.Elev = 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.Elev = 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;
|
|
|
|
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 RepeaterViewModel AddRepeater(NodeViewModel node1, NodeViewModel node2)
|
{
|
RepeaterViewModel repeater = new RepeaterViewModel();
|
int i = 0;
|
string ID = $"{Default.GetPreString(repeater)}{i}";
|
while (Links.Find(p0 => p0.ID == ID) != null)
|
{
|
i++;
|
ID = $"{Default.GetPreString(repeater)}{i}";
|
}
|
repeater.ID = ID;
|
|
|
repeater.StartNode = node1;
|
repeater.EndNode = node2;
|
|
Links.Add(repeater);
|
|
return repeater;
|
}
|
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;
|
}
|
|
public List<IBaseViewModel> Remove(List<IBaseViewModel> list)
|
{
|
|
List<IBaseViewModel> objs = new List<IBaseViewModel>();
|
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<IBaseViewModel> 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<MapViewNetWork>();
|
var BasePos = StartPoint.Position3D;
|
|
net.Nodes.ForEach(n =>
|
{
|
n.X += basepoint.X - BasePos.X;
|
n.Y += basepoint.Y - BasePos.Y;
|
n.Elev += 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<IBaseViewModel> Add(MapViewNetWork net0, PointF3D offset = null, bool isCopy = false,NodeViewModel ConnectNode=null)
|
{
|
if (offset == null)
|
{
|
offset = new PointF3D(0, 0, 0);
|
}
|
List<IBaseViewModel> list = new List<IBaseViewModel>();
|
if (Hash_ID == null) Hash_ID = new HashSet<string>();
|
|
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.Elev += 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;
|
}
|
#region treat
|
public void MatchAndTreat(List<NodeViewModel> listA_source, List<NodeViewModel> listB_source, Action<NodeViewModel, NodeViewModel> treat)
|
{
|
//var item = listA[0];
|
//var propertyDescriptor = TypeDescriptor.GetProperties(item)[PropertyDescriptorName];
|
//listA.Sort();
|
//listB.Sort();
|
// 对 List A 和 List B 按 Key 进行排序
|
var listA = listA_source.OrderBy(a => a.ID).ToList();
|
var listB = listB_source.OrderBy(b => b.ID).ToList();
|
int indexA = 0;
|
int indexB = 0;
|
|
while (indexA < listA.Count && indexB < listB.Count)
|
{
|
//dynamic valueA = propertyDescriptor.GetValue(listA[indexA]);
|
//dynamic valueB = propertyDescriptor.GetValue(listB[indexB]);
|
var valueA = listA[indexA].ID;
|
var valueB = listB[indexB].ID;
|
var cResult = string.Compare(valueA, valueB);
|
if (cResult == 0)
|
{
|
treat(listA[indexA], listB[indexB]);
|
indexA++;
|
indexB++;
|
}
|
else if (string.Compare(valueA, valueB) < 0)
|
{
|
indexA++;
|
}
|
else
|
{
|
indexB++;
|
}
|
}
|
}
|
public void MatchAndTreat(List<LinkViewModel> listA_source, List<LinkViewModel> listB_source, Action<LinkViewModel, LinkViewModel> treat)
|
{
|
//var item = listA[0];
|
//var propertyDescriptor = TypeDescriptor.GetProperties(item)[PropertyDescriptorName];
|
//listA.Sort();
|
//listB.Sort();
|
// 对 List A 和 List B 按 Key 进行排序
|
var listA = listA_source.OrderBy(a => a.ID).ToList();
|
var listB = listB_source.OrderBy(b => b.ID).ToList();
|
int indexA = 0;
|
int indexB = 0;
|
|
while (indexA < listA.Count && indexB < listB.Count)
|
{
|
//dynamic valueA = propertyDescriptor.GetValue(listA[indexA]);
|
//dynamic valueB = propertyDescriptor.GetValue(listB[indexB]);
|
var valueA = listA[indexA].ID;
|
var valueB = listB[indexB].ID;
|
var cResult = string.Compare(valueA, valueB);
|
if (cResult == 0)
|
{
|
treat(listA[indexA], listB[indexB]);
|
indexA++;
|
indexB++;
|
}
|
else if (string.Compare(valueA, valueB) < 0)
|
{
|
indexA++;
|
}
|
else
|
{
|
indexB++;
|
}
|
}
|
}
|
#endregion
|
|
public void Add(List<IBaseViewModel> 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();
|
}
|
|
[JsonIgnore]
|
public List<IBaseViewModel> MapObjects
|
{
|
get
|
{
|
List<BaseModel> objects = new List<BaseModel>();
|
objects.AddRange(Nodes);
|
objects.AddRange(Links);
|
return objects.Select(o=>(IBaseViewModel)o).ToList();
|
}
|
}
|
public void Rename()
|
{
|
MapObjects.ForEach(o => o.ID = $"{Name}_{o.ID}");
|
}
|
public void Add(RepeaterViewModel repeater)
|
{
|
ChangePoint(repeater.StartNode, repeater.StartNode_inner);
|
MoveDownNetwork(repeater);
|
ChangePoint(repeater.EndNode, repeater.EndNode_inner);
|
|
Nodes.AddRange(repeater.netList.Nodes);
|
Links.AddRange(repeater.netList.Links);
|
}
|
public void LoadRepeaters(int MaxLevel, dict<string, dynamic> param, Dictionary<TemplateType, bool> viewModel, bool ViewMode = true)
|
{
|
|
|
repeaters.ForEach(r =>
|
{
|
|
if (!r.Load(MaxLevel, param, viewModel, ViewMode))
|
{
|
r.Status = RepeaterViewModel.RepeatStatus.收起;
|
r.Visible = true;
|
}
|
|
else
|
{
|
Add(r);
|
r.Visible = false;
|
}
|
|
|
});
|
}
|
|
public void MoveDownNetwork(RepeaterViewModel repeater)
|
{
|
visited = new Dictionary<NodeViewModel, bool>();
|
visited.Add(repeater.StartNode, true);
|
var p1 = repeater.EndNode_inner;
|
var p2 = repeater.EndNode;
|
PointF3D p = new PointF3D(p1.X - p2.X, p1.Y - p2.Y, p1.Elev - p2.Elev);
|
BFS(this, repeater.EndNode, new Vector3(p.X, p.Y, p.Z));
|
|
}
|
|
|
// 定义 visited 字典记录已访问过的节点和待访问的节点队列
|
Dictionary<NodeViewModel, bool> visited;//= new Dictionary<Node, bool>();
|
private bool _isCalculated=false;
|
|
public void BFS(MapViewNetWork net, NodeViewModel startNode, Vector3 vector)
|
{
|
|
Queue<NodeViewModel> queue = new Queue<NodeViewModel>();
|
|
// 标记起始节点为已访问,并加入队列
|
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);
|
}
|
}
|
}
|
}
|
|
public List<NodeViewModel> GetNode(string node)
|
{
|
return Nodes.FindAll(n => n.ID == node).Select(n=> (NodeViewModel)n).ToList();
|
}
|
|
public List<TimePoint> Calc(string inpPath, string configPath = null)
|
{
|
|
WdnmoParam wdnmoParam = new WdnmoParam();
|
|
|
Nodes.ForEach(n =>
|
{
|
//if (n is JunctionViewModel || n is MeterViewModel || n is NozzleViewModel)
|
{
|
wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Press_{n.ID}" });
|
wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Head_{n.ID}" });
|
wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Demand_{n.ID}" });
|
}
|
});
|
Links.ForEach(n =>
|
{
|
//if (n is PipeViewModel || n is PumpViewModel || n is ValveViewModel)
|
{
|
wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Flow_{n.ID}" });
|
wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Velocity_{n.ID}" });
|
wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Headloss_{n.ID}" });
|
|
}
|
});
|
|
calc c = new calc();
|
var list = c.GetCalcResult(inpPath, wdnmoParam, configPath);
|
if (list == null) return list;
|
list.Sort((a, b) => string.Compare(a.Key, b.Key));
|
Nodes.Sort((a, b) => string.Compare(a.ID, b.ID));
|
Links.Sort((a, b) => string.Compare(a.ID, b.ID));
|
SetNodeFromWparam(this, list, "Press");
|
SetNodeFromWparam(this, list, "Head");
|
SetNodeFromWparam(this, list, "Demand");
|
|
SetLinkFromWparam(this, list, "Flow");
|
SetLinkFromWparam(this, list, "Velocity");
|
SetLinkFromWparam(this, list, "Headloss");
|
|
Links.ForEach(l=>
|
{
|
l.EN_HEADLOSS_MINOR = (float)Math.Round(l.MinorLoss * Math.Pow(l.EN_VELOCITY, 2) / 2 / 9.8, 4);
|
l.EN_HEADLOSS_LINE = l.EN_HEADLOSS - l.EN_HEADLOSS_MINOR;
|
});
|
this._isCalculated = true;
|
return list;
|
//return new List<TimePoint>();
|
}
|
|
public List<TimePoint> CalcByVal(WDNModelOptimizer wdo, Result val)
|
{
|
|
WdnmoParam wdnmoParam = new WdnmoParam();
|
|
|
Nodes.ForEach(n =>
|
{
|
//if (n is JunctionViewModel || n is MeterViewModel || n is NozzleViewModel)
|
{
|
wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Press_{n.ID}" });
|
wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Head_{n.ID}" });
|
wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Demand_{n.ID}" });
|
}
|
});
|
Links.ForEach(n =>
|
{
|
//if (n is PipeViewModel || n is PumpViewModel || n is ValveViewModel)
|
{
|
wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Flow_{n.ID}" });
|
wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Velocity_{n.ID}" });
|
wdnmoParam.ResultPoints.Add(new TimePoint { Key = $"Headloss_{n.ID}" });
|
|
}
|
});
|
calcParam calcParam = new calcParam();
|
calcParam.vars = val.arrayTryValue;
|
calcParam.setVars = new List<SetVar>();
|
reservoirs.ForEach(r =>
|
{
|
calcParam.setVars.Add(new SetVar (r.ID,true,(int)EpanetEnum.NodeValueType.水池水位,(float)val.ObjFunctionValue));
|
});
|
|
wdnmoParam =wdo.CalcbyResult(calcParam, wdnmoParam);
|
var list = wdnmoParam.ResultPoints;
|
if (list == null) return list;
|
list.Sort((a, b) => string.Compare(a.Key, b.Key));
|
Nodes.Sort((a, b) => string.Compare(a.ID, b.ID));
|
Links.Sort((a, b) => string.Compare(a.ID, b.ID));
|
SetNodeFromWparam(this, list, "Press");
|
SetNodeFromWparam(this, list, "Head");
|
SetNodeFromWparam(this, list, "Demand");
|
|
SetLinkFromWparam(this, list, "Flow");
|
SetLinkFromWparam(this, list, "Velocity");
|
SetLinkFromWparam(this, list, "Headloss");
|
this._isCalculated = true;
|
return list;
|
//return new List<TimePoint>();
|
}
|
|
private void SetNodeFromWparam(MapViewNetWork net, List<TimePoint> list, string valueType)
|
{
|
int k1 = 0;
|
int k2 = 0;
|
k1 = 0;
|
k2 = 0;
|
while (k1 < net.Nodes.Count)
|
{
|
var J = (NodeViewModel)net.Nodes[k1];
|
//if (J is JunctionViewModel || J is NozzleViewModel || J is MeterViewModel)
|
{
|
var re = list[k2];
|
|
while ($"{valueType}_{J.ID}" != re.Key && k2 < list.Count)
|
{
|
k2++;
|
if (k2 < list.Count) re = list[k2];
|
|
}
|
if (k2 == list.Count)
|
{
|
throw new Exception($"未找到Node[{J.ID}]的{valueType}");
|
}
|
switch (valueType)
|
{
|
case "Press":
|
J.EN_PRESSURE = (float)Math.Round(re.Value, 4);
|
break;
|
case "Head":
|
J.EN_HEAD = (float)Math.Round(re.Value, 4);
|
break;
|
case "Demand":
|
J.EN_DEMAND = (float)Math.Round(re.Value, 4);
|
break;
|
}
|
}
|
|
|
k1++;
|
}
|
}
|
private static void SetLinkFromWparam(MapViewNetWork net, List<TimePoint> list, string valueType)
|
{
|
int k1 = 0;
|
int k2 = 0;
|
k1 = 0;
|
k2 = 0;
|
while (k1 < net.Links.Count)
|
{
|
var J = (LinkViewModel)net.Links[k1];
|
//if (J is PipeViewModel || J is ValveViewModel || J is PumpViewModel)
|
{
|
var re = list[k2];
|
|
while ($"{valueType}_{J.ID}" != re.Key && k2 < list.Count)
|
{
|
k2++;
|
if (k2 < list.Count) re = list[k2];
|
|
}
|
if (k2 == list.Count)
|
{
|
throw new Exception($"未找到Link[{J.ID}]的{valueType}");
|
}
|
switch (valueType)
|
{
|
case "Flow":
|
J.EN_FLOW = (float)Math.Round(re.Value, 4);
|
break;
|
case "Velocity":
|
J.EN_VELOCITY = (float)Math.Round(re.Value, 4);
|
break;
|
case "Headloss":
|
J.EN_HEADLOSS = (float)Math.Round(re.Value, 4);
|
break;
|
}
|
}
|
|
|
k1++;
|
}
|
}
|
|
public void SetNodeDemand()
|
{
|
Nodes.ForEach(n =>
|
{
|
if (n is NodeViewModel node && node.Demand == 0)
|
{
|
node.Demand = 0.01f;
|
}
|
else if (n is MeterViewModel meter && meter.Demand == 0)
|
{
|
meter.Demand = 0.01f;
|
}
|
else if (n is NozzleViewModel nozzle && nozzle.Demand == 0)
|
{
|
nozzle.Demand = 0.01f;
|
}
|
});
|
}
|
}
|
|
//构造一个List<LinkViewModel>类,能够实现List的所有功能
|
[Serializable]
|
public class LinkViewModelList:List<LinkCalcModel>
|
{
|
//List<LinkCalcModel> base;
|
Dictionary<string, LinkViewModel> dict;//
|
public LinkViewModelList() : base()
|
{
|
this.dict = new Dictionary<string, LinkViewModel>();
|
}
|
//public LinkViewModelList(List<LinkCalcModel> links)
|
//{
|
// base = links;
|
// base.ForEach(link =>
|
// {
|
// if (!dict.ContainsKey(link.ID))
|
// dict.Add(link.ID,link);
|
// });
|
//}
|
public List<LinkViewModel> ViewLinks
|
{
|
get
|
{
|
var list = new List<LinkViewModel>();
|
base.ForEach(l =>
|
{
|
//if (l is LinkViewModel)
|
list.Add((LinkViewModel)l);
|
});
|
return list;
|
//return base.Select(l => (LinkViewModel)l).ToList();
|
}
|
}
|
/// <summary>
|
/// 更新字典
|
/// </summary>
|
public void UpdateDict()
|
{
|
this.dict= new Dictionary<string, LinkViewModel>();
|
base.ForEach(link =>
|
{
|
if (!dict.ContainsKey(link.ID))
|
dict.Add(link.ID, (LinkViewModel)link);
|
});
|
}
|
/// <summary>
|
/// 修改某个oldID至newID,同时更新字典
|
/// </summary>
|
/// <param name="oldID"></param>
|
/// <param name="newID"></param>
|
public void ChangeID(string oldID,string newID)
|
{
|
if (dict.ContainsKey(oldID))
|
{
|
dict[oldID].ID = newID;
|
dict.Add(newID, dict[oldID]);
|
dict.Remove(oldID);
|
}
|
}
|
/// <summary>
|
/// 实现Add方法,同时更新字典
|
/// </summary>
|
public void Add(LinkViewModel linkCalcModel)
|
{
|
base.Add(linkCalcModel);
|
if (!dict.ContainsKey(linkCalcModel.ID))
|
dict.Add(linkCalcModel.ID, linkCalcModel);
|
}
|
/// <summary>
|
/// 实现AddRange方法,同时更新字典
|
/// </summary>
|
/// <param name="linkCalcModels"></param>
|
public void AddRange(List<LinkViewModel> 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;
|
}
|
/// <summary>
|
/// 统计数量
|
/// </summary>
|
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<LinkViewModel> comparison)方法
|
public void Sort(Comparison<LinkCalcModel> comparison)
|
{
|
base.Sort(comparison);
|
}
|
//实现Select方法
|
public void Select(Action<LinkViewModel> action)
|
{
|
//base.ForEach(action);
|
//base.ForEach(action);
|
ViewLinks.ForEach(action);
|
}
|
//实现Find方法
|
public LinkViewModel Find(Predicate<LinkViewModel> match)
|
{
|
//base.Find(match);
|
return ViewLinks.Find(match);
|
}
|
//实现FindAll方法
|
public List<LinkViewModel> FindAll(Predicate<LinkViewModel> match)
|
{
|
return ViewLinks.FindAll(match);
|
}
|
//实现ForEach方法
|
public void ForEach(Action<LinkViewModel> action)
|
{
|
ViewLinks.ForEach(action);
|
}
|
//实现RemoveAll方法
|
public int RemoveAll(Predicate<LinkCalcModel> match)
|
{
|
return base.RemoveAll(match);
|
}
|
/// <summary>
|
/// 实现Remove方法,同时更新字典
|
/// </summary>
|
public bool Remove(LinkViewModel linkCalcModel)
|
{
|
if (base.Remove(linkCalcModel))
|
{
|
if (dict.ContainsKey(linkCalcModel.ID))
|
dict.Remove(linkCalcModel.ID);
|
return true;
|
}
|
else
|
return false;
|
}
|
|
|
|
|
}
|
|
//构造一个List<NodeViewModel>类,能够实现List的所有功能
|
[Serializable]
|
|
public class NodeViewModelList : List<NodeCalcModel>
|
{
|
//List<NodeCalcModel> base;
|
Dictionary<string, NodeCalcModel> dict;//=new Dictionary<string, NodeCalcModel>();//
|
public NodeViewModelList():base()
|
{
|
this.dict = new Dictionary<string, NodeCalcModel>();
|
}
|
//public NodeViewModelList(List<NodeCalcModel> nodes)
|
//{
|
// base = nodes;
|
// base.ForEach(node =>
|
// {
|
// if (!dict.ContainsKey(node.ID))
|
// dict.Add(node.ID,node);
|
// });
|
//}
|
/// <summary>
|
/// 更新字典
|
/// </summary>
|
public void UpdateDict()
|
{
|
this.dict = new Dictionary<string, NodeCalcModel>();
|
base.ForEach(node =>
|
{
|
if (!dict.ContainsKey(node.ID))
|
dict.Add(node.ID, node);
|
});
|
}
|
/// <summary>
|
/// 修改某个oldID至newID,同时更新字典
|
/// </summary>
|
/// <param name="oldID"></param>
|
/// <param name="newID"></param>
|
public void ChangeID(string oldID, string newID)
|
{
|
if (dict.ContainsKey(oldID))
|
{
|
dict[oldID].ID = newID;
|
dict.Add(newID, dict[oldID]);
|
dict.Remove(oldID);
|
}
|
}
|
/// <summary>
|
/// 实现Add方法,同时更新字典
|
/// </summary>
|
public void Add(NodeViewModel nodeCalcModel)
|
{
|
base.Add(nodeCalcModel);
|
if (!dict.ContainsKey(nodeCalcModel.ID))
|
dict.Add(nodeCalcModel.ID, nodeCalcModel);
|
}
|
/// <summary>
|
/// 实现AddRange方法,同时更新字典
|
/// </summary>
|
/// <param name="nodeCalcModels"></param>
|
public void AddRange(List<NodeViewModel> nodeCalcModels)
|
{
|
base.AddRange(nodeCalcModels);
|
nodeCalcModels.ForEach(node =>
|
{
|
if (!dict.ContainsKey(node.ID))
|
dict.Add(node.ID, node);
|
});
|
}
|
/// <summary>
|
/// 实现Remove方法,同时更新字典
|
/// </summary>
|
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;
|
}
|
/// <summary>
|
/// 统计数量
|
/// </summary>
|
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<NodeCalcModel> ToList()
|
//{
|
// return base;
|
//}
|
//实现Sort方法
|
public List<NodeViewModel> ViewNodes
|
{
|
get
|
{
|
//将NodeCalcModel转换为NodeViewModel
|
//return this.Select(l => (NodeViewModel)l).ToList();
|
List<NodeViewModel> list = new List<NodeViewModel>();
|
foreach (var item in this)
|
{
|
list.Add((NodeViewModel)item);
|
}
|
return list;
|
}
|
|
}
|
|
public void Sort()
|
{
|
base.Sort();
|
}
|
//实现Sort(Comparison<NodeViewModel> comparison)方法
|
public void Sort(Comparison<NodeCalcModel> comparison)
|
{
|
base.Sort(comparison);
|
}
|
//实现Select方法
|
public void Select(Action<NodeViewModel> action)
|
{
|
ViewNodes.ForEach(action);
|
//base.ForEach(action);
|
}
|
//实现Find方法
|
public NodeViewModel Find(Predicate<NodeViewModel> match)
|
{
|
return ViewNodes.Find(match);
|
}
|
//实现FindAll方法
|
public List<NodeViewModel> FindAll(Predicate<NodeViewModel> match)
|
{
|
return ViewNodes.FindAll(match);
|
}
|
//实现ForEach方法
|
public void ForEach(Action<NodeViewModel> action)
|
{
|
ViewNodes.ForEach(action);
|
}
|
//实现RemoveAll方法
|
public int RemoveAll(Predicate<NodeCalcModel> match)
|
{
|
return base.RemoveAll(match);
|
}
|
|
|
|
|
}
|
|
}
|