📄 dlcontrol.pas
字号:
var
Stream:TMemoryStream;
begin
Stream:=TMemoryStream.Create;
try
SaveToStream(Stream);
Stream.SaveToFile(FileName);
finally
Stream.Free;
end;
end;
procedure TLineList.LoadFromStream(Stream:TStream);
var
AObj:TLine;
begin
Clear;
Stream.Position:=0;
while Stream.Position<Stream.Size do
begin
AObj:=Add;
AObj.LoadFromStream(Stream);
end;
end;
procedure TLineList.SaveToStream(Stream:TStream);
var
i:Integer;
AObj:TLine;
begin
Stream.Size:=0;
Stream.Position:=0;
for i:=0 to FList.Count-1 do
begin
AObj:=Items[i];
AObj.SaveToStream(Stream);
end;
end;
{ TLine }
procedure TLine.Assign(aLine: TLine);
begin
FLineId:=aLine.LineId;
FCurState:=aLine.CurState;
FLinkedDots.Assign(aLine.LinkedDots);
end;
constructor TLine.Create;
begin
inherited Create;
FLinkedDots:=TDotList.Create(False);
end;
destructor TLine.Destroy;
begin
FLinkedDots.Free;
inherited Destroy;
end;
procedure TLine.GetDLFromDots(List: TDotList);
begin
end;
procedure TLine.LoadFromStream(Stream: TStream);
begin
//请在此处写代码
end;
procedure TLine.SaveState;
begin
FOldState:=FCurState;
end;
procedure TLine.SaveToStream(Stream: TStream);
begin
//请在此处写代码
end;
function TLine.StateChanged: Boolean;
begin
Result:=FOldState<>FCurState;
end;
{ TDLControl }
procedure TDLControl.SetDotState(aDot:TDot; aState:TDotState;
const bApply:Boolean);
begin
aDot.DotState:=aState;
if bApply then AnalyzeState;
end;
constructor TDLControl.Create;
begin
inherited Create;
FDots:=TDotList.Create(True);
FLines:=TLineList.Create(True);
end;
destructor TDLControl.Destroy;
begin
FDots.Free;
FLines.Free;
inherited Destroy;
end;
procedure TDLControl.LoadFromDataBase(aQuery:TADOQuery);
procedure AddLine(aDot:TDot);
var
Index:Integer;
aLine:TLine;
begin
with aQuery do
begin
Index:=FLines.IndexOf(Fields[3].AsInteger);
if Index=-1 then
begin
aLine:=TLine.Create;
FLines.Add(aLine);
aLine.LineId:=Fields[3].AsInteger;
end
else
aLine:=FLines.Items[Index];
aLine.LinkedDots.Add(aDot);
aDot.LinkedLines.Add(aLine);
end;
end;
var
aDot:TDot;
LastId:Integer;
begin
FDots.Clear;
FLines.Clear;
LastId:=-1;
aDot:=nil;
with aQuery do
begin
Close;
SQL.Clear;
SQL.Add('select a.DotID, a.Type, a.kgState, b.LineID');
SQL.Add('from t_CtrlDotsLayer a, t_DotLines b');
SQL.Add('where a.UnitID=:UnitID and a.DotID=b.DotID');
SQL.Add('order by a.DotID, b.LineID');
SetParamValue(aQuery, 'UnitID', UnitID);
Open;
while not Eof do
begin
if LastId<>Fields[0].AsInteger then
begin
aDot:=TDot.Create;
FDots.Add(aDot);
aDot.DotId:=Fields[0].AsInteger;
aDot.BDSDot:=Fields[1].AsInteger=0;
if Fields[2].AsBoolean then
aDot.DotState:=dsLink
else
aDot.DotState:=dsBreak;
LastId:=Fields[0].AsInteger;
end;
AddLine(aDot);
Next;
end;
Close;
end;
end;
function TDotList.IndexOf(const DotId: Integer): Integer;
var
i:Integer;
begin
Result:=-1;
for i:=0 to FList.Count-1 do
if TDot(FList.Items[i]).DotId=DotId then
begin
Result:=i;
Exit;
end;
end;
function TDotList.FindDot(const DotId: Integer): TDot;
var
Index:Integer;
begin
Index:=IndexOf(DotId);
Result:=TDot(FList.Items[Index]);
end;
procedure TDLControl.AnalyzeState;
var
i:Integer;
aDot:TDot;
aDotList:TDotList;
begin
for i:=0 to FDots.ItemCount-1 do
FDots.Items[i].Checked:=False;
{设置所有线路状态为lsUnknown}
for i:=0 to FLines.ItemCount-1 do
begin
FLines.Items[i].SaveState;
FLines.Items[i].CurState:=lsUnknown;
end;
{分析每一个变电所的有电的线路}
aDotList:=TDotList.Create(False);
try
GetBDSDots(aDotList);
for i:=0 to aDotList.ItemCount-1 do
begin
aDot:=aDotList.Items[i];
if not BDSNetWorkIsAnalyzed(aDot) then
AnalyzeDot(aDot, True);
end;
finally
aDotList.Free;
end;
{设置所有lsUnknown线路为无电}
for i:=0 to FLines.ItemCount-1 do
begin
if FLines.Items[i].CurState=lsUnknown then
FLines.Items[i].CurState:=lsOff;
end;
end;
procedure TDLControl.GetBDSDots(List: TDotList);
var
i:Integer;
aDot:TDot;
begin
if List.OwnerRec then
raise Exception.Create('无法向列表中增加记录对象,因为该列表只允许自己创建记录对象!');
List.Clear;
for i:=0 to FDots.ItemCount-1 do
begin
aDot:=FDots.Items[i];
if aDot.BDSDot then List.Add(FDots.Items[i]);
end;
end;
function TDLControl.BDSNetWorkIsAnalyzed(aBDSDot:TDot): Boolean;
{如果变电所被分析过,则该变电所连通时,下面所有电路应该有电。}
function CheckLineList:Boolean;
var
i:Integer;
begin
Result:=True;
if aBDSDot.DotState=dsLink then
for i:=0 to aBDSDot.LinkedLines.ItemCount-1 do
if aBDSDot.LinkedLines.Items[i].CurState=lsUnknown then
begin
Result:=False;
Exit;
end;
end;
begin
if not aBDSDot.BDSDot then
raise Exception.Create('该节点不是变电所对象!');
if aBDSDot.LinkedLines.ItemCount=0 then
Result:=True
else
Result:=CheckLineList;
end;
procedure TLineList.Assign(Source: TLineList);
var
i:Integer;
aItem:TLine;
begin
Clear;
for i:=0 to Source.ItemCount-1 do
begin
if OwnerRec then
begin
aItem:=Add;
aItem.Assign(Source.Items[i]);
end
else
Add(Source.Items[i]);
end;
end;
procedure TDotList.Assign(Source: TDotList);
var
i:Integer;
aItem:TDot;
begin
Clear;
for i:=0 to Source.ItemCount-1 do
begin
if OwnerRec then
begin
aItem:=Add;
aItem.Assign(Source.Items[i]);
end
else
Add(Source.Items[i]);
end;
end;
procedure TDotList.Remove(aDot: TDot);
var
Index:Integer;
begin
Index:=IndexOf(aDot.DotId);
Delete(Index);
end;
procedure TDLControl.AnalyzeDot(aDot: TDot; const bInput:Boolean);
var
i, j:Integer;
aLine:TLine;
aDotList:TDotList;
begin
{整个分析过程如下:
1、如果该节点连通,如果上层有输入电流,则该节点下所有线路都有电,
进一步分析每一个线路的所有节点(递归调用该过程),如果上层无输入
电流,则该节点下所有电路状态保持未知,分析流程返回。
2,如果该节点断开,则该节点下所有电路状态保持未知,分析流程返回。}
if aDot.Checked then Exit;
aDot.Checked:=True;
if (bInput) and (aDot.DotState=dsLink) then
begin
for i:=0 to aDot.LinkedLines.ItemCount-1 do
begin
aLine:=aDot.LinkedLines.Items[i];
aLine.CurState:=lsOn;
aDotList:=TDotList.Create(False);
try
aDotList.Assign(aDot.LinkedLines.Items[i].LinkedDots);
aDotList.Remove(aDot);
for j:=0 to aDotList.ItemCount-1 do
AnalyzeDot(aDotList.Items[j], True);
finally
aDotList.Free;
end;
end;
end;
end;
function TLineList.FindLine(const LineId: Integer): TLine;
var
Index:Integer;
begin
Index:=IndexOf(LineId);
Result:=TLine(FList.Items[Index]);
end;
function TLineList.IndexOf(const LineId: Integer): Integer;
var
i:Integer;
begin
Result:=-1;
for i:=0 to FList.Count-1 do
if TLine(FList.Items[i]).LineId=LineId then
begin
Result:=i;
Exit;
end;
end;
procedure TDLControl.SaveState(aDot: TDot; aQuery: TADOQuery);
begin
with aQuery do
begin
Close;
SQL.Clear;
SQL.Add('update t_CtrlDotsLayer');
SQL.Add('set kgState=0');
SQL.Add('where');
SQL.Add('UnitID='+IntToStr(UnitID)+' and DotID='+IntToStr(aDot.DotId));
ExecSQL;
end;
end;
end.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -