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 CommonBase;
namespace Hydro.MapView
{
public partial class MapViewNetWork : NetWork
{
bool use_old = false;
public string Name;
public NodeViewModel StartPoint { get; set; }
public NodeViewModel EndPoint { get; set; }
///
/// 核心承载字段
///
//public new List Nodes = new List();
///
/// 核心承载字段
///
//public new List Links = new List();
public Dictionary dict_dataset;// = new Dictionary();
public HashSet Hash_ID;
[JsonIgnore]
public 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]
public 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]
public 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]
public 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]
public 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]
public 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]
public 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]
public List 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 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 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 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 Deserialized_junctions { get; set; }
public List Deserialized_tanks { get; set; }
public List Deserialized_reservoirs { get; set; }
public List Deserialized_meters { get; set; }
public List Deserialized_nozzles { get; set; }
public List Deserialized_pipes { get; set; }
public List Deserialized_valves { get; set; }
public List Deserialized_valveNodes { get; set; }
public List Deserialized_repeaters { get; set; }
public List Deserialized_pumps { get; set; }
public List Deserialized_pumpNodes { get; set; }
public List areas = new List();
public bool ReadFromJson(string json)
{
var net = JsonConvert.DeserializeObject(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;
}
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 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(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.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 Add(MapViewNetWork net0, PointF3D offset = null, bool isCopy = false)
{
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 = 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 = 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);
});
//BuildRelation();
return list;
}
#region treat
public void MatchAndTreat(List listA_source, List listB_source, Action 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 listA_source, List listB_source, Action 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 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 MapObjects
{
get
{
List objects = new List();
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 param, Dictionary viewModel, bool ViewMode = true)
{
//repeaters.ForEach(r =>
//{
// r.Load();
// Add(r);
//});
repeaters.ForEach(r =>
{
if (!r.Load(MaxLevel, param, viewModel, ViewMode))
{
r.Status = RepeaterViewModel.RepeatStatus.收起;
r.Visible = true;
}
else
{
Add(r);
r.Visible = false;
}
//if (r.Status == Repeater.RepeatStatus.显示)
//{
//}
});
}
public void MoveDownNetwork(RepeaterViewModel repeater)
{
visited = new Dictionary();
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 visited;//= new Dictionary();
public 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);
}
}
}
}
public List GetNode(string node)
{
return Nodes.FindAll(n => n.ID == node);
}
public List 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");
return list;
//return new List();
}
private void SetNodeFromWparam(MapViewNetWork net, List list, string valueType)
{
int k1 = 0;
int k2 = 0;
k1 = 0;
k2 = 0;
while (k1 < net.Nodes.Count)
{
var J = 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, 2);
break;
case "Head":
J.EN_HEAD = (float)Math.Round(re.Value, 2);
break;
case "Demand":
J.EN_DEMAND = (float)Math.Round(re.Value, 2);
break;
}
}
k1++;
}
}
private static void SetLinkFromWparam(MapViewNetWork net, List list, string valueType)
{
int k1 = 0;
int k2 = 0;
k1 = 0;
k2 = 0;
while (k1 < net.Links.Count)
{
var J = 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.Abs(Math.Round(re.Value, 2));
break;
case "Velocity":
J.EN_VELOCITY = (float)Math.Round(re.Value, 2);
break;
case "Headloss":
J.EN_HEADLOSS = (float)Math.Round(re.Value, 2);
break;
}
}
k1++;
}
}
}
}