using System.Text;
|
using System.Text.RegularExpressions;
|
|
namespace Yw.EPAnet
|
{
|
/// <summary>
|
/// Inp交互辅助类
|
/// </summary>
|
public static class InpInteropHelper
|
{
|
/// <summary>
|
/// 转换至Inp字符串
|
/// </summary>
|
public static string ToInpString(this Network network, CalcuResult minorResult = null)
|
{
|
//模板文件
|
var templateFilePath = TemplateHelper.GetPath();
|
if (!File.Exists(templateFilePath))
|
{
|
throw new Exception("模板文件不存在," + templateFilePath);
|
}
|
var templateString = File.ReadAllText(templateFilePath);
|
|
//状态
|
var statusSb = new StringBuilder();
|
statusSb.AppendLine(";ID \tStatus/Setting\r\n");
|
|
//扩散器
|
var emitterSb = new StringBuilder();
|
emitterSb.AppendLine(";Junction \tCoefficient");
|
|
//坐标
|
var coorStringBuilder = new StringBuilder();
|
coorStringBuilder.AppendLine(";Node X-Coord Y-Coord");
|
|
Dictionary<string, string> dictExchange = new Dictionary<string, string>() {
|
{"{junctions}","{0}" },
|
{"{reservoirs}","{1}" },
|
{"{tanks}","{2}" },
|
{"{pipes}","{3}" },
|
{"{valves}","{4}" },
|
{"{pumps}","{5}" },
|
|
{"{coor}","{6}" },
|
{"{curve}","{7}" },
|
{"{emitters}","{8}" },
|
};
|
dictExchange.ToList().ForEach(m => templateString = templateString.Replace(m.Key, m.Value));
|
|
//连接节点
|
var junctionStringBuilder = new StringBuilder();
|
junctionStringBuilder.AppendLine(";ID Elev Demand Pattern Type");
|
//连接节点处理
|
network.Junctions?.ForEach(x =>
|
{
|
var demandPattern = x.DemandPattern;
|
if (string.IsNullOrEmpty(demandPattern) || demandPattern == ";" || demandPattern == "_")
|
{
|
demandPattern = string.Empty;
|
}
|
junctionStringBuilder.AppendLine($"{x.Id}\t{x.Elev}\t{x.Demand}\t{demandPattern}\t;\t" + $"0\tJunction");
|
coorStringBuilder.AppendLine(x.Id + " " + x.Position.X + " " + x.Position.Y);
|
});
|
|
network.GetAllCouplings()?.ForEach(x =>
|
{
|
var demandPattern = x.DemandPattern;
|
if (string.IsNullOrEmpty(demandPattern) || demandPattern == ";" || demandPattern == "_")
|
{
|
demandPattern = string.Empty;
|
}
|
junctionStringBuilder.AppendLine($"{x.Id}\t{x.Elev}\t{x.Demand}\t{demandPattern}\t;\t" + $"0\tCoupling");
|
coorStringBuilder.AppendLine(x.Id + " " + x.Position.X + " " + x.Position.Y);
|
});
|
|
network.GetAllInstruments()?.ForEach(x =>
|
{
|
var demandPattern = x.DemandPattern;
|
if (string.IsNullOrEmpty(demandPattern) || demandPattern == ";" || demandPattern == "_")
|
{
|
demandPattern = string.Empty;
|
}
|
junctionStringBuilder.AppendLine($"{x.Id}\t{x.Elev}\t{x.Demand}\t{demandPattern}\t;\t" + $"0\tInstrument");
|
coorStringBuilder.AppendLine(x.Id + " " + x.Position.X + " " + x.Position.Y);
|
});
|
|
//水表处理
|
network.Meters?.ForEach(x =>
|
{
|
var demandPattern = x.DemandPattern;
|
if (string.IsNullOrEmpty(demandPattern) || demandPattern == ";" || demandPattern == "_")
|
{
|
demandPattern = "";
|
}
|
junctionStringBuilder.AppendLine($"{x.Id}\t{x.Elev}\t{x.Demand}\t{demandPattern}\t;\t" + $"0\tMeters");
|
coorStringBuilder.AppendLine(x.Id + " " + x.Position.X + " " + x.Position.Y);
|
});
|
//喷头处理
|
network.Nozzles?.ForEach(x =>
|
{
|
var demandPattern = x.DemandPattern;
|
if (string.IsNullOrEmpty(demandPattern) || demandPattern == ";" || demandPattern == "_")
|
{
|
demandPattern = "";
|
}
|
junctionStringBuilder.AppendLine($"{x.Id}\t{x.Elev}\t{x.Demand}\t{demandPattern}\t;\t" + $"0\tNozzle\t{x.Coefficient}");
|
double coefficient = x.Coefficient * Math.Pow(10 / 101.972, 0.5) / 1000 * 60;
|
emitterSb.AppendLine(x.Id + " " + coefficient);
|
coorStringBuilder.AppendLine(x.Id + " " + x.Position.X + " " + x.Position.Y);
|
});
|
var junctionString = junctionStringBuilder.ToString();
|
|
//水库处理
|
var reservoirSb = new StringBuilder();
|
reservoirSb.AppendLine(";ID Head Pattern ");
|
network.Reservoirs?.ForEach(x =>
|
{
|
reservoirSb.AppendLine($"{x.Id}\t{x.Head}\t{x.HeadPattern}\t;\t" + $"0\t{x.PoolElev}");
|
coorStringBuilder.AppendLine(x.Id + " " + x.Position.X + " " + x.Position.Y);
|
});
|
string reserverString = reservoirSb.ToString();
|
|
//水池处理
|
var tankSb = new StringBuilder();
|
tankSb.AppendLine(";ID Elevation InitLevel MinLevel MaxLevel Diameter MinVol VolCurve Overflow");
|
network.GetTanks()?.ForEach(o =>
|
{
|
// tankStringBuilder.AppendLine($"{o.Id}\t{o.PoolElev}\t{o.InitLevel}\t{o.MinLevel}\t{o.MaxLevel}\t{o.Diameter}\t{o.MinVol}\t{o.VolCurve}\t{o.Overflow}\t;\t");// + $"0");
|
tankSb.AppendLine($"{o.Id}\t{o.PoolElev}\t{o.InitLevel}\t{o.MinLevel}\t{o.MaxLevel}\t{o.Diameter}\t{o.MinVol}\t{o.VolCurve}\t;\t");// + $"0");
|
coorStringBuilder.AppendLine(o.Id + " " + o.Position.X + " " + o.Position.Y);
|
});
|
string tankString = tankSb.ToString();
|
|
//管道处理
|
var pipeSb = new StringBuilder();
|
pipeSb.AppendLine(";ID Node1 Node2 Length Diameter Roughness MinorLoss Status");
|
network.GetAllPipes()?.ForEach(x =>
|
{
|
if (x.Roughness == 0)
|
{
|
x.Roughness = 110;
|
}
|
string statusString = x.LinkStatus == PipeStatus.Closed ? "CLOSED" : "";
|
double minorLoss = x.MinorLossCoeff + x.EndMinorLossCoeff + x.StartMinorLossCoeff;
|
pipeSb.AppendLine($"{x.Id}\t{x.StartNode.Id}\t{x.EndNode.Id}\t{x.Length}\t{x.Diameter}\t{x.Roughness}\t{minorLoss}\t{statusString}\t;\t");// + $"{p.Level}");
|
if (x.LinkStatus != PipeStatus.Open)
|
{
|
statusSb.AppendLine(x.Id + "\t" + statusString);
|
}
|
});
|
string pipeString = pipeSb.ToString();
|
|
//阀门处理
|
var valveSb = new StringBuilder();
|
valveSb.AppendLine(";ID Node1 Node2 Diameter Type Setting MinorLoss ");
|
network.Valves?.ForEach(x =>
|
{
|
valveSb.AppendLine($"{x.Id}\t{x.StartNode.Id}\t{x.EndNode.Id}\t{x.Diameter:F4}\t{x.ValveType}\t{x.ValveSetting}\t{x.MinorLoss:F4}\t;\t");// + $"0");
|
if (!string.IsNullOrEmpty(x.LinkStatus))
|
{
|
statusSb.AppendLine(x.Id + "\t" + x.LinkStatus);
|
}
|
});
|
network.GetAllResistances()?.ForEach(x =>
|
{
|
string type = null;
|
if (x is Exchanger)
|
{
|
type = "Exchanger";
|
}
|
else if (x is Compressor)
|
{
|
type = "Compressor";
|
}
|
valveSb.AppendLine($"{x.Id}\t{x.StartNode.Id}\t{x.EndNode.Id}\t{x.Diameter:F4}\tGPV\t{x.CurveQL}\t{x.MinorLoss:F4}\t;\t{type}");// + $"0");
|
if (!string.IsNullOrEmpty(x.LinkStatus))
|
{
|
statusSb.AppendLine(x.Id + "\t" + x.LinkStatus);
|
}
|
});
|
string valveString = valveSb.ToString();
|
|
//水泵处理
|
var pumpSb = new StringBuilder();
|
pumpSb.AppendLine(";ID Node1 Node2 Parameters ");
|
network.Pumps?.ForEach(o =>
|
{
|
pumpSb.AppendLine($"{o.Id}\t{o.StartNode.Id}\t{o.EndNode.Id}\tHead\t{o.CurveQH}\t;\t");// + $"0");
|
string statusString = null;
|
if (o.LinkStatus == PipeStatus.Closed)
|
{
|
statusString = "\tCLOSED";
|
}
|
else
|
{
|
if (o.SpeedRatio == null)
|
statusString = "\tOPEN";
|
else
|
statusString = $"\t{o.SpeedRatio}";
|
}
|
statusSb.AppendLine(o.Id + statusString);
|
});
|
string pumpString = pumpSb.ToString();
|
|
//曲线处理
|
var curveSb = new StringBuilder();
|
curveSb.AppendLine(@";ID X-Value Y-Value
|
;HEADLOSS:
|
GPVDefault 0 0
|
GPVDefault 100 0
|
;PUMP:
|
PumpDefault 0 45.38
|
PumpDefault 83.33333333 45.25
|
PumpDefault 111.1111111 45.12
|
PumpDefault 138.8888889 44.96
|
PumpDefault 166.6666667 44.76
|
PumpDefault 194.4444444 44.52
|
PumpDefault 222.2222222 44.24
|
PumpDefault 250 43.92
|
PumpDefault 277.7777778 43.56
|
PumpDefault 305.5555556 43.17
|
PumpDefault 333.3333333 42.73
|
PumpDefault 361.1111111 42.25
|
PumpDefault 388.8888889 41.74
|
PumpDefault 416.6666667 41.18
|
PumpDefault 444.4444444 40.58
|
PumpDefault 472.2222222 39.95
|
PumpDefault 500 39.28
|
PumpDefault 527.7777778 38.56
|
PumpDefault 555.5555556 37.81
|
PumpDefault 583.3333333 37.02
|
PumpDefault 611.1111111 36.19
|
PumpDefault 638.8888889 35.32
|
PumpDefault 666.6666667 34.41
|
PumpDefault 694.4444444 33.46
|
PumpDefault 722.2222222 32.47
|
PumpDefault 750 31.44
|
PumpDefault 777.7777778 30.37
|
PumpDefault 805.5555556 29.27 ");
|
network.Curves?.ForEach(o =>
|
{
|
var curvePtList = o.CurveData?.OrderBy(x => x.X).ToList();
|
foreach (var curvePt in curvePtList)
|
{
|
curveSb.AppendLine($"{o.Id} {curvePt.X} {curvePt.Y}");
|
}
|
//curveStringBuilder.AppendLine(o.ToString());
|
});
|
string curveString = curveSb.ToString();
|
|
string coorString = coorStringBuilder.ToString();
|
string output = "";
|
string emitterString = emitterSb.ToString();
|
string statusString = statusSb.ToString();
|
output = templateString;
|
output = ReplaceContent(output, "JUNCTIONS", junctionString);
|
output = ReplaceContent(output, "RESERVOIRS", reserverString);
|
output = ReplaceContent(output, "TANKS", tankString);
|
output = ReplaceContent(output, "PIPES", pipeString);
|
output = ReplaceContent(output, "VALVES", valveString);
|
output = ReplaceContent(output, "PUMPS", pumpString);
|
output = ReplaceContent(output, "CURVES", curveString);
|
output = ReplaceContent(output, "COORDINATES", coorString);
|
output = ReplaceContent(output, "EMITTERS", emitterString);
|
output = ReplaceContent(output, "STATUS", statusString);
|
|
|
|
|
|
|
return output;
|
}
|
|
|
private static string ReplaceContent(string text, string content, string replaceString)
|
{
|
|
|
string str = replaceString;
|
|
string replacedText = ReplaceCoordinatesSection(text, content, str);
|
|
return replacedText;
|
//Console.WriteLine(replacedText);
|
}
|
public static string ReplaceCoordinatesSection(string text, string content, string str)
|
{
|
string pattern = $@"(\[{content}\]).*?(\[|$)";
|
|
string replacedText = Regex.Replace(text, pattern, match =>
|
{
|
string section = match.Groups[2].Value.Trim();
|
|
if (!string.IsNullOrEmpty(section))
|
{
|
return $"{match.Groups[1].Value}\n{str}\n[";
|
}
|
else
|
{
|
return $"{match.Groups[1].Value}\n{str}\n[";
|
}
|
}, RegexOptions.Singleline);
|
|
return replacedText;
|
}
|
|
/// <summary>
|
/// 从Inp字符串中解析
|
/// </summary>
|
public static Network FromInpString(string inpString)
|
{
|
string InpPath = inpString;
|
var net = new Network();
|
if (InpPath == null || !File.Exists(InpPath)) return null;
|
List<InpCoor> points = new List<InpCoor>();
|
|
StreamReader sr = new StreamReader(InpPath);
|
//try
|
{
|
string line;
|
string section = "";
|
while ((line = sr.ReadLine()) != null)
|
{
|
if (line.Trim().StartsWith("["))
|
{
|
section = line.TrimStart('[').TrimEnd(']');
|
}
|
else
|
{
|
string s = line.Trim('\t').Trim(' ');
|
if (s.Length == 0 || s[0] == ';') continue;
|
line = line.Replace("\t\t", "\t_\t").Replace("\t \t", "\t_\t");
|
InpParts parts = new InpParts(line.Split(new char[] { '\t', ' ', ';' }, StringSplitOptions.RemoveEmptyEntries));
|
switch (section)
|
{
|
case "JUNCTIONS":
|
{
|
var ID = parts[0];
|
float elev;
|
float.TryParse(parts[1], out elev);
|
var Elev = elev;
|
float demand;
|
float.TryParse(parts[2], out demand);
|
var Demand = demand;
|
var PatternID = parts[3];
|
int level;
|
int.TryParse(parts[6], out level);
|
var Level = level;
|
|
if (parts[-2] == "Meter")
|
{
|
net.Meters.Add(new Meter()
|
{
|
Id = ID,
|
Elev = Elev,
|
Demand = Demand,
|
DemandPattern = PatternID,
|
});
|
}
|
else if (parts[-2] == "Nozzle")
|
{
|
net.Nozzles.Add(new Nozzle()
|
{
|
Id = ID,
|
Elev = Elev,
|
Demand = Demand,
|
DemandPattern = PatternID,
|
});
|
}
|
else
|
{
|
net.Junctions.Add(new Junction()
|
{
|
Id = ID,
|
Elev = Elev,
|
Demand = Demand,
|
DemandPattern = PatternID,
|
});
|
}
|
|
}
|
break;
|
case "RESERVOIRS":
|
{
|
var r = new Reservoir();
|
r.Id = parts[0];
|
float head;
|
if (float.TryParse(parts[1], out head))
|
r.Head = head;
|
r.HeadPattern = parts.Length > 2 ? parts[2] : "";
|
int level;
|
//if (int.TryParse(parts[3], out level))
|
// r.Level = level;
|
net.Reservoirs.Add(r);
|
}
|
break;
|
case "TANKS":
|
{
|
//TankModel tank = new TankModel(parts[0], parts[1], parts[2], parts[3], parts[4], parts[5], parts[6], parts[7], parts[8]);
|
float initLevel = 0;
|
float.TryParse(parts[2], out initLevel);
|
|
float minLevel = 0;
|
float.TryParse(parts[3], out minLevel);
|
|
float maxLevel = 0;
|
float.TryParse(parts[4], out maxLevel);
|
|
float diamter = 0;
|
float.TryParse(parts[5], out diamter);
|
|
float minVol = 0;
|
float.TryParse(parts[6], out minVol);
|
var tank = new Tank()
|
{
|
Id = parts[0],
|
PoolElev = float.Parse(parts[1]),
|
InitLevel = initLevel,
|
MinLevel = minLevel,
|
MaxLevel = maxLevel,
|
Diameter = diamter,
|
MinVol = minVol,
|
VolCurve = "",
|
};
|
//int level;
|
//if (int.TryParse(parts[9], out level))
|
// tank.Level = level;
|
net.Tanks.Add(tank);
|
}
|
break;
|
case "PIPES":
|
{
|
InpPipe p = new InpPipe();
|
p.Id = parts[0];
|
p.Node1 = parts[1];
|
p.Node2 = parts[2];
|
float length;
|
if (float.TryParse(parts[3], out length))
|
p.Length = length;
|
float diameter;
|
if (float.TryParse(parts[4], out diameter))
|
p.Diameter = diameter;
|
float roughness;
|
if (float.TryParse(parts[5], out roughness))
|
p.Roughness = roughness;
|
float minorLoss;
|
if (float.TryParse(parts[6], out minorLoss))
|
p.MinorLossCoeff = minorLoss;
|
p.LinkStatus = parts.Length > 7 ? (parts[7].ToUpper().Contains("CLOSE")? PipeStatus.Closed : PipeStatus.Open) : PipeStatus.Open;
|
|
net.Pipes.Add(p);
|
}
|
break;
|
case "VALVES":
|
{
|
|
if (parts[-2] == "Exchanger")
|
{
|
InpHeatExchanger valve = new InpHeatExchanger();
|
valve.Id = parts[0];
|
|
// 取出Node1和Node2中的字母部分,例如“S201326593”被取出为“201326593”
|
valve.Node1 = parts[1]; // Regex.Replace(parts[1], "[^0-9]", "");
|
valve.Node2 = parts[2]; // Regex.Replace(parts[2], "[^0-9]", "");
|
|
float diameter;
|
if (float.TryParse(parts[3], out diameter))
|
valve.Diameter = diameter;
|
valve.CurveQL = parts[5];
|
float minorLoss;
|
if (float.TryParse(parts[6], out minorLoss))
|
valve.MinorLoss = minorLoss;
|
|
net.Exchangers.Add(valve);
|
}
|
else if (parts[-2] == "Compressor")
|
{
|
InpAirCompressor valve = new InpAirCompressor();
|
valve.Id = parts[0];
|
|
// 取出Node1和Node2中的字母部分,例如“S201326593”被取出为“201326593”
|
valve.Node1 = parts[1]; // Regex.Replace(parts[1], "[^0-9]", "");
|
valve.Node2 = parts[2]; // Regex.Replace(parts[2], "[^0-9]", "");
|
|
float diameter;
|
if (float.TryParse(parts[3], out diameter))
|
valve.Diameter = diameter;
|
valve.CurveQL = parts[5];
|
float minorLoss;
|
if (float.TryParse(parts[6], out minorLoss))
|
valve.MinorLoss = minorLoss;
|
|
net.Compressors.Add(valve);
|
}
|
else
|
{
|
InpValve valve = new InpValve();
|
valve.Id = parts[0];
|
|
// 取出Node1和Node2中的字母部分,例如“S201326593”被取出为“201326593”
|
valve.Node1 = parts[1]; // Regex.Replace(parts[1], "[^0-9]", "");
|
valve.Node2 = parts[2]; // Regex.Replace(parts[2], "[^0-9]", "");
|
|
float diameter;
|
if (float.TryParse(parts[3], out diameter))
|
valve.Diameter = diameter;
|
valve.ValveType = parts[4];
|
valve.ValveSetting = parts[5];
|
float minorLoss;
|
if (float.TryParse(parts[6], out minorLoss))
|
valve.MinorLoss = minorLoss;
|
net.Valves.Add(valve);
|
}
|
|
}
|
break;
|
case "PUMPS":
|
{
|
InpPump pump = new InpPump();
|
|
pump.Id = parts.ToString(0, null);
|
|
// 取出Node1和Node2中的字母部分,例如“S201326593”被取出为“201326593”
|
pump.Node1 = parts.ToString(1, null); // Regex.Replace(parts[1], "[^0-9]", "");
|
pump.Node2 = parts.ToString(2, null);// parts.ToString(2, null); // Regex.Replace(parts[2], "[^0-9]", "");
|
int index = 3;
|
string label = null;
|
while ((label = parts.ToString(index, null)) != null)
|
{
|
label = label.ToUpper();
|
switch (label)
|
{
|
case "HEAD":
|
pump.CurveQH = parts.ToString(index + 1, "PumpDefault");
|
break;
|
case "SPEED":
|
pump.SpeedRatio = parts.ToFloat(index + 1, 0);
|
break;
|
}
|
index += 2;
|
}
|
//pump.Diameter = parts.ToFloat(3, 0);
|
|
pump.LinkStatus = "OPEN";
|
net.Pumps.Add(pump);
|
}
|
break;
|
case "STATUS":
|
{
|
Link link = net.GetAllLinks().Find(l => l.Id == parts.ToString(0, null));
|
if (link != null)
|
link.LinkStatus = parts[1];
|
}
|
break;
|
case "COORDINATES":
|
{
|
string id = parts[0];
|
double x;
|
double y;
|
if (double.TryParse(parts[1], out x) && double.TryParse(parts[2], out y))
|
{
|
points.Add(new InpCoor(id, new Position2d(x, y)));
|
}
|
}
|
break;
|
case "EMITTERS":
|
{
|
string id = parts[0];
|
if (double.TryParse(parts[1], out double x))
|
{
|
double Coefficient = x / Math.Pow(10 / 101.972, 0.5) * 1000 / 60;
|
net.Nozzles.Find(o => o.Id == id).Coefficient = Coefficient;
|
}
|
}
|
break;
|
}
|
}
|
}
|
sr.Close();
|
|
|
#region 优化方案
|
int k1 = 0;
|
int k2 = 0;
|
|
var Nodes = net.GetAllNodes();
|
var Links = net.GetAllLinks();
|
Nodes.Sort((a, b) => string.Compare(a.Id, b.Id));
|
points.Sort((a, b) => string.Compare(a.Id, b.Id));
|
k1 = 0;
|
k2 = 0;
|
while (k1 < Nodes.Count)
|
{
|
var J = Nodes[k1];
|
var coor = points[k2];
|
|
while (J.Id != coor.Id && k2 < points.Count)
|
{
|
k2++;
|
if (k2 < points.Count) coor = points[k2];
|
|
}
|
if (k2 == points.Count)
|
{
|
break;
|
//throw new Exception($"未找到Node[{J.Id}]的坐标");
|
}
|
|
J.Position = new Position2d();
|
J.Position.X = coor.Position.X;
|
J.Position.Y = coor.Position.Y;
|
|
k1++;
|
}
|
#endregion
|
|
|
|
//建立点线关系链表StartNode,先将管线以Node1(节点1的ID)排序,再将Nodes按ID排序,建立两个游标k1、k2,正向一次循环,建立链表关系
|
//时间复杂度 O(n)
|
Links.Sort((a, b) => string.Compare(((IInpParser)a).Node1, ((IInpParser)b).Node1));
|
k1 = 0;
|
k2 = 0;
|
while (k2 < Links.Count)
|
{
|
var p = Links[k2];
|
var J = Nodes[k1];
|
while (J.Id != ((IInpParser)p).Node1 && k1 < Nodes.Count)
|
{
|
k1++;
|
if (k1 < Nodes.Count) J = Nodes[k1];
|
|
}
|
if (k1 == Nodes.Count)
|
{
|
break;
|
//throw new Exception($"未找到Link[{p.Id}]的起始节点[{((IInpParser)p).Node1}]");
|
}
|
p.StartNode = J;
|
if (J.Links == null) J.Links = new List<Link>();
|
J.Links.Add(p);
|
k2++;
|
}
|
|
//建立点线关系链表StartNode,先将管线以Node2(节点1的ID)排序,再将Nodes按ID排序,建立两个游标k1、k2,正向一次循环,建立链表关系
|
//时间复杂度 O(n)
|
Links.Sort((a, b) => string.Compare(((IInpParser)a).Node2, ((IInpParser)b).Node2));
|
k1 = 0;
|
k2 = 0;
|
while (k2 < Links.Count)
|
{
|
var p = Links[k2];
|
var J = Nodes[k1];
|
while (J.Id != ((IInpParser)p).Node2 && k1 < Nodes.Count)
|
{
|
k1++;
|
if (k1 < Nodes.Count) J = Nodes[k1];
|
}
|
if (k1 == Nodes.Count)
|
{
|
break;
|
//throw new Exception($"未找到Link[{p.Id}]的终止节点[{((IInpParser)p).Node2}]");
|
}
|
p.EndNode = J;
|
if (J.Links == null) J.Links = new List<Link>();
|
J.Links.Add(p);
|
k2++;
|
}
|
return net;
|
}
|
}
|
|
}
|
}
|