1 {
2 *****************************************************************************
3 * *
4 * This file is part of the ZCAD *
5 * *
6 * See the file COPYING.modifiedLGPL.txt, included in this distribution, *
7 * for details about the copyright. *
8 * *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
12 * *
13 *****************************************************************************
14 }
15 {
16 @author(Vladimir Bobrov)
17 }
18 {$mode objfpc}
19
20 unit uzvtreedevice;
21 {$INCLUDE def.inc}
22
23 interface
24 uses
25
26 sysutils, math,
27
28 URecordDescriptor,TypeDescriptors,
29
30 Forms, //uzcfblockinsert,
31 uzcfarrayinsert,
32
33 uzeentblockinsert, //unit describes blockinsert entity
34 //модуль описывающий примитив вставка блока
35 uzeentline, //unit describes line entity
36 //модуль описывающий примитив линия
37 uzeentmtext,
38
39 uzeentlwpolyline, //unit describes line entity
40 //модуль описывающий примитив двухмерная ПОЛИлиния
41
42 uzeentpolyline, //unit describes line entity
43 //модуль описывающий примитив трехмерная ПОЛИлиния
44 uzeenttext, //unit describes line entity
45 //модуль описывающий примитив текст
46
47 uzeentdimaligned, //unit describes aligned dimensional entity
48 //модуль описывающий выровненный размерный примитив
49 uzeentdimrotated,
50
51 uzeentdimdiametric,
52
53 uzeentdimradial,
54 uzeentarc,
55 uzeentcircle,
56 uzeentity,
57 uzbgeomtypes,
58
59
60 gvector,garrayutils, // Подключение Generics и модуля для работы с ним
61 uzcstrconsts,
62 uzcentcable,
63 uzeentdevice,
64 UGDBOpenArrayOfPV,
65
66 uzegeometry,
67 uzeentitiesmanager,
68
69 uzcshared,
70 uzeentityfactory, //unit describing a "factory" to create primitives
71 //модуль описывающий "фабрику" для создания примитивов
72 uzcsysvars, //system global variables
73 //системные переменные
74 uzgldrawcontext,
75 uzcinterface,
76 uzbtypesbase,uzbtypes, //base types
77 //описания базовых типов
78 uzeconsts, //base constants
79 //описания базовых констант
80 uzccommandsmanager,
81 uzccommandsabstract,
82 uzccommandsimpl, //Commands manager and related objects
83 //менеджер команд и объекты связанные с ним
84 uzcdrawing,
85 uzedrawingsimple,
86 uzcdrawings, //Drawings manager, all open drawings are processed him
87 //"Менеджер" чертежей
88 uzcutils, //different functions simplify the creation entities, while there are very few
89 //разные функции упрощающие создание примитивов, пока их там очень мало
90 varmandef,
91 Varman,
92 {UGDBOpenArrayOfUCommands,}zcchangeundocommand,
93
94 uzclog, //log system
95 //<**система логирования
96 uzcvariablesutils, // для работы с ртти
97
98 gzctnrvectortypes, //itrec
99
100 //для работы графа
101 ExtType,
102 Pointerv,
103 Graphs,
104 AttrType,
105 AttrSet,
106 //*
107
108 uzcenitiesvariablesextender,
109 UUnitManager,
110 uzbpaths,
111 uzctranslations,
112 uzventsuperline,
113 uzvcom,
114 uzvtmasterdev,
115 uzvvisualgraph,
116 uzvconsts,
117 uzvtestdraw;
118
119
120 type
121 TDummyComparer=class
Comparenull122 function Compare (Edge1, Edge2: Pointer): Integer;
CompareEdgesnull123 function CompareEdges (Edge1, Edge2: Pointer): Integer;
124 end;
125 TSortTreeLengthComparer=class
Comparenull126 function Compare (vertex1, vertex2: Pointer): Integer;
127 end;
128
129
130
131 procedure errorSearchList(ourGraph:TGraphBuilder;Epsilon:double;var listError:TListError;listSLname:TGDBlistSLname);
132 procedure errorList(allGraph:TListAllGraph;Epsilon:double;var listError:TListError;listSLname,listAllSLname:TGDBlistSLname);
133
134 procedure visualMasterGroupLine(listVertexEdge:TGraphBuilder;listMasterDevice:TVectorOfMasterDevice;isMetricNumeric:boolean;heightText:double;numDevice:boolean);
135 procedure visualGraphConnection(GGraph:TGraphBuilder;listMasterDevice:TVectorOfMasterDevice;graphFull,graphEasy:boolean;var fTreeVertex:GDBVertex;var eTreeVertex:GDBVertex);
136
137 procedure cabelingMasterGroupLine(listVertexEdge:TGraphBuilder;listMasterDevice:TVectorOfMasterDevice;isMetricNumeric:boolean);
buildListAllConnectDevicenull138 function buildListAllConnectDevice(listVertexEdge:TGraphBuilder;Epsilon:double; var listError:TListError):TVectorOfMasterDevice;
139
buildListAllConnectDeviceNewnull140 function buildListAllConnectDeviceNew(listVertexEdge:TGraphBuilder;Epsilon:double; var listError:TListError):TVectorOfMasterDevice;
141
142 implementation
143 var
144 DummyComparer:TDummyComparer;
145 SortTreeLengthComparer:TSortTreeLengthComparer;
146
147
148
149 //** Поиск номера по имени устройства из списка из списка устройства
getNumHeadDevicenull150 function getNumHeadDevice(listVertex:TListDeviceLine;name:string;G: TGraph;numDev:integer):integer;
151 var
152 i: Integer;
153 pvd:pvardesk; //для работы со свойствами устройств
154 T: Float;
155 EdgePath, VertexPath: TClassList;
156 begin
157 result:=-1;
158 for i:=0 to listVertex.Size-1 do
159 begin
160 if listVertex[i].deviceEnt<>nil then
161 begin
162 pvd:=FindVariableInEnt(listVertex[i].deviceEnt,'NMO_Name');
163 if pvd <> nil then
164 if pgdbstring(pvd^.data.Instance)^ = name then begin
165 //result:=-1;
166
167 //работа с библиотекой Аграф
168 EdgePath:=TClassList.Create; //Создаем реберный путь
169 VertexPath:=TClassList.Create; //Создаем вершиный путь
170
171 // Получение ребер минимального пути в графи из одной точки в другую
172 T:=G.FindMinWeightPath(G[i], G[numDev], EdgePath);
173 // Получение вершин минимального пути в графи на основе минимального пути в ребер, указывается из какой точки старт
174 G.EdgePathToVertexPath(G[i], EdgePath, VertexPath);
175
176 if VertexPath.Count > 1 then
177 result:= i;
178
179 EdgePath.Free;
180 VertexPath.Free;
181 end;
182 end;
183
184 end;
185 end;
186
187
getListMasterDevnull188 function getListMasterDev(listVertexEdge:TGraphBuilder;globalGraph: TGraph):TVectorOfMasterDevice;
189 type
190 //**список для кабельной прокладки
191 PTCableLaying=^TCableLaying;
192 TCableLaying=record
193 headName:string;
194 GroupNum:string;
195 typeSLine:string;
196
197 end;
198 TVertexofCableLaying=specialize TVector<TCableLaying>;
199
200 TVertexofString=specialize TVector<string>;
201 var
202 /////////////////////////
203
204 listCableLaying:TVertexofCableLaying; //список кабельной прокладки
205
206 masterDevInfo:TMasterDevice;
207 groupInfo:TMasterDevice.TGroupInfo;
208 infoSubDev:TMasterDevice.TGroupInfo.TInfoSubDev;
209 //deviceInfo:TMasterDevice.TGroupInfo.TDeviceInfo;
210 i,j,k,m,counter,tnum: Integer;
211 numHead,numHeadGroup,numHeadDev : integer;
212
213 isHeadnum:boolean;
214 shortNameHead, headDevName, groupName:string;
215 pvd:pvardesk; //для работы со свойствами устройств
216
217 //** Получаем количество кабелей подключения данного устройства к головным устройствам, с последующим разбором
listCollectConnectnull218 function listCollectConnect(nowDev:PGDBObjDevice;var listCableLaying:TVertexofCableLaying;nameSL:string):boolean;
219 var
220 pvd:pvardesk; //для работы со свойствами устройств
221 polyObj:PGDBObjPolyLine;
222 i,counter1,counter2,counter3:integer;
223 tempName,nameParam:gdbstring;
224 infoLay:TCableLaying;
225 listStr1,listStr2,listStr3:TVertexofString;
226
227 begin
228 listStr1:=TVertexofString.Create;
229 listStr2:=TVertexofString.Create;
230 listStr3:=TVertexofString.Create;
231
232 pvd:=FindVariableInEnt(nowDev,'SLCABAGEN_HeadDeviceName');
233 if pvd<>nil then
234 BEGIN
235 tempName:=pgdbstring(pvd^.data.Instance)^;
236 repeat
237 GetPartOfPath(nameParam,tempName,';');
238 listStr1.PushBack(nameParam);
239 // HistoryOutStr(' code2 = ' + nameParam);
240 until tempName='';
241
242 pvd:=FindVariableInEnt(nowDev,'SLCABAGEN_NGHeadDevice');
243 if pvd<>nil then
244 BEGIN
245 tempName:=pgdbstring(pvd^.data.Instance)^;
246 repeat
247 GetPartOfPath(nameParam,tempName,';');
248 listStr2.PushBack(nameParam);
249 until tempName='';
250
251 pvd:=FindVariableInEnt(nowDev,'SLCABAGEN_SLTypeagen');
252 if pvd<>nil then
253 BEGIN
254 tempName:=pgdbstring(pvd^.data.Instance)^;
255 repeat
256 GetPartOfPath(nameParam,tempName,';');
257 listStr3.PushBack(nameParam);
258 until tempName='';
259
260 for i:=0 to listStr1.size-1 do
261 begin
262 infoLay.headName:=listStr1[i];
263 infoLay.GroupNum:=listStr2[i];
264 infoLay.typeSLine:=listStr3[i];
265 if infoLay.typeSLine = nameSL then
266 listCableLaying.PushBack(infoLay);
267 end;
268 end;
269 end;
270
271 end;
272 if listCableLaying.size > 0 then
273 result:=true
274 else
275 result:=false;
276 end;
277
278
279 begin
280 result:=TVectorOfMasterDevice.Create;
281 listCableLaying := TVertexofCableLaying.Create;
282
283 //counter:=0;
284
285 //на базе listVertexEdge заполняем список головных устройств и все что в них входит
286 for i:=0 to listVertexEdge.listVertex.Size-1 do
287 begin
288 //если это устройство и не разрыв
289 if (listVertexEdge.listVertex[i].deviceEnt<>nil) and (listVertexEdge.listVertex[i].break<>true) then
290 begin
291 //Получаем список сколько у устройства хозяев
292 if listCollectConnect(listVertexEdge.listVertex[i].deviceEnt,listCableLaying,listVertexEdge.nameSuperLine) then
293 begin
294 //inc(counter);
295 for m:=0 to listCableLaying.size-1 do begin
296
297 headDevName:=listCableLaying[m].headName;
298 //Поиск хозяина внутри графа полученного из listVertexEdge и возврат номера устройства
299 numHeadDev:=getNumHeadDevice(listVertexEdge.listVertex,headDevName,globalGraph,i); // если минус значит нету хозяина
300
301 if numHeadDev >= 0 then
302 begin
303 //**Проверяем существует ли хоть одно главное устройство с таким именем,
304 //если нет то создаем, если есть то или добавляем к существующему или создаем еще одно устройство
305 numHead := -1;
306 for j:=0 to result.Size-1 do //проверяем существует ли уже такое же головное устройство
307 if result[j].name = headDevName then begin
308 numHead := j;
309
310 //ZCMsgCallBackInterface.TextMessage('NAMENUMmaster = '+inttostr(numHead) + 'namemaster = ' + headDevName + ' = ' + result[j].name,TMWOHistoryOut);
311 isHeadnum:=true;
312 //устройства иногда могут использоватся на разных планах и иметь подчиненных
313 //при обработке всех планов одно и тоже устройство может иметь несколько номеров в глобальном графе
314 for tnum in result[j].LIndex do begin
315 //ZCMsgCallBackInterface.TextMessage('tnum = '+inttostr(tnum) + 'numHeadDev = ' + headDevName + ' = ' + inttostr(numHeadDev),TMWOHistoryOut);
316 if tnum = numHeadDev then
317 isHeadnum:=false;
318 end;
319 if isHeadnum then
320 result.mutable[j]^.LIndex.PushBack(numHeadDev);
321 end;
322
323 if numHead < 0 then // если в списки устройства есть. Но нашего устройства нет, то добавляем его
324 begin
325 masterDevInfo:=TMasterDevice.Create;
326 masterDevInfo.name:=headDevName;
327 masterDevInfo.LIndex.PushBack(numHeadDev);
328 masterDevInfo.shortName:='nil';
329 pvd:=FindVariableInEnt(listVertexEdge.listVertex[numHeadDev].deviceEnt,'NMO_Suffix');
330 if pvd<>nil then
331 masterDevInfo.shortName:=pgdbstring(pvd^.data.Instance)^;
332 result.PushBack(masterDevInfo);
333 numHead:=result.Size-1;
334 masterDevInfo:=nil;
335 end;
336
337 //**работа по поиску и заполнению групп к головному устройству
338 groupName:=listCableLaying[m].GroupNum;
339 numHeadGroup:=-1;
340 for j:=0 to result[numHead].LGroup.Size-1 do // ищем среди существующих групп нашу
341 if result[numHead].LGroup[j].name = groupName then
342 numHeadGroup:=j;
343 if numHeadGroup<0 then //если нет то создаем новую группу в существующий список групп
344 begin
345 groupInfo:=TMasterDevice.TGroupInfo.Create;
346 groupInfo.name:=groupName;
347 infoSubDev.indexMaster:=numHeadDev;
348 infoSubDev.indexSub:=i;
349 infoSubDev.isVertexAdded:=false;
350 //ZCMsgCallBackInterface.TextMessage('master = '+inttostr(infoSubDev.indexMaster)+' sub - ' + inttostr(infoSubDev.indexSub),TMWOHistoryOut);
351
352 groupInfo.LNumSubDevice.PushBack(infoSubDev);
353 //HeadGroupInfo.listVertexTerminalBox:=nil;
354 //HeadGroupInfo.listVertexWayGroup:=nil;
355 //HeadGroupInfo.listVertexWayOnlyVertex:=nil;
356 result.Mutable[numHead]^.LGroup.PushBack(groupInfo);
357 numHeadGroup:=result[numHead].LGroup.Size-1;
358 groupInfo:=nil;
359 end
360 else
361 begin
362 infoSubDev.indexMaster:=numHeadDev;
363 infoSubDev.indexSub:=i;
364 //ZCMsgCallBackInterface.TextMessage('master = '+inttostr(infoSubDev.indexMaster)+' sub - ' + inttostr(infoSubDev.indexSub),TMWOHistoryOut);
365 infoSubDev.isVertexAdded:=false;
366 result.mutable[numHead]^.LGroup.mutable[numHeadGroup]^.LNumSubDevice.PushBack(infoSubDev);
367 end;
368 end;
369
370 end;
371 listCableLaying.Clear;
372 end;
373 end;
374 end;
375 end;
376
Comparenull377 function TSortTreeLengthComparer.Compare (vertex1, vertex2: Pointer): Integer;
378 var
379 e1,e2:TAttrSet;
380 begin
381 result:=0;
382 e1:=TAttrSet(vertex1);
383 e2:=TAttrSet(vertex2);
384
385 //Edge1
386 //ZCMsgCallBackInterface.TextMessage(floattostr(e1.AsFloat64[vGLengthFromEnd]) + ' сравниваем ' + floattostr(e2.AsFloat64[vGLengthFromEnd]),TMWOHistoryOut);
387 // ZCMsgCallBackInterface.TextMessage(floattostr(e2.AsFloat32[vGLength]) + ' ',TMWOHistoryOut);
388
389 //e1.GetAsFloat32
390 if e1.AsFloat64[vGLengthFromEnd] <> e2.AsFloat64[vGLengthFromEnd] then
391 if e1.AsFloat64[vGLengthFromEnd] > e2.AsFloat64[vGLengthFromEnd] then
392 result:=1
393 else
394 result:=-1;
395
396 //тут e1 и e2 надо както сравнить по какомуто критерию и вернуть -1 0 1
397 //в зависимости что чего меньше-больше
398 end;
399
400
401 //** Создание деревьев устройств
402 procedure getEasyTreeDevice(var listMasterDevice:TVectorOfMasterDevice);
403 var
404 i,j,k,l:integer;
405 VertexPath: TClassList;
406 VPath: TClassList;
407 infoGTree:TGraph;
408 tempVertexGraph:TVertex;
409 edgeLen:float;
410 edgeWay:string;
411 nextvert:boolean;
412
413 // получения вершины в графе на основе вершины из другого графа
getLocalVertnull414 function getLocalVert(gTree:TGraph;vt:tvertex):tVertex;
415 var
416 i:integer;
417 begin
418 result:=nil;
419 for i:=0 to gTree.VertexCount-1 do
420 if gTree.Vertices[i].AsInt32[vGGIndex] = vt.AsInt32[vGGIndex] then
421 result:=gTree.Vertices[i];
422 end;
423
424 begin
425 for i:=0 to listMasterDevice.Size-1 do
426 begin
427 for j:=0 to listMasterDevice[i].LGroup.Size -1 do
428 begin
429 for k:=0 to listMasterDevice[i].LGroup[j].LTreeDev.Size -1 do begin
430 infoGTree:=TGraph.Create;
431 infoGTree.Features:=[Tree];
432 infoGTree.CreateVertexAttr(vGGIndex, AttrInt32);
433 infoGTree.CreateEdgeAttr(vGLength, AttrFloat64);
434 infoGTree.CreateVertexAttr(vGIsDevice, AttrBool);
435 infoGTree.CreateEdgeAttr(vGInfoEdge, AttrString);
436 infoGTree.CreateVertexAttr(vGInfoVertex, AttrString);
437
438 //**получаем обход графа
439 VPath:=TClassList.Create;
440 listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.TreeTraversal(tvertex(listMasterDevice[i].LGroup[j].LTreeDev[k].Root), VPath); //получаем путь обхода графа
441
442 //** создаем граф в котором будут только устройства и ответвления
443 tempVertexGraph:=nil;
444
445 infoGTree.AddVertex;
446 infoGTree.Root:=infoGTree.Vertices[infoGTree.VertexCount-1];
447 infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]:=tvertex(VPath[0]).AsInt32[vGGIndex];
448 infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex]:=tvertex(VPath[0]).AsString[vGInfoVertex];
449 infoGTree.Vertices[infoGTree.VertexCount-1].AsBool[vGIsDevice]:=tvertex(VPath[0]).AsBool[vGIsDevice];
450 tempVertexGraph:=infoGTree.Vertices[infoGTree.VertexCount-1];
451 edgeLen:=0;
452 edgeWay:='';
453 nextvert:=false;
454 for l:= 1 to VPath.Count - 1 do
455 begin
456 //**организция изменения родительской вершины tempVertexGraph если обход графа начался после ответвления
457 if nextvert then
458 begin
459 nextvert:=false;
460 tempVertexGraph:=getLocalVert(infoGTree,tvertex(VPath[l]).Parent);
461 end;
462 if (tvertex(VPath[l]).ChildCount < 1) then
463 begin
464 nextvert:=true;
465 end;
466 ///
467
468 if (tvertex(VPath[l]).ChildCount > 1) or tvertex(VPath[l]).AsBool[vGIsDevice] then begin
469 infoGTree.AddVertex;
470 infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]:=tvertex(VPath[l]).AsInt32[vGGIndex];
471 infoGTree.Vertices[infoGTree.VertexCount-1].AsBool[vGIsDevice]:=tvertex(VPath[l]).AsBool[vGIsDevice];
472
473 //**НОВОЕ!!! Добавил ссылку на устройство
474 infoGTree.Vertices[infoGTree.VertexCount-1].AsPointer[vGPGDBObjDevice]:=tvertex(VPath[l]).AsPointer[vGPGDBObjDevice];
475
476 infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex]:=tvertex(VPath[l]).AsString[vGInfoVertex];
477
478 //if infoGTree.Vertices[infoGTree.VertexCount-1].AsPointer[vGPGDBObjDevice] <> nil then
479 //infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex]:= '+' + infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex]
480 //else
481 infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex]:= '-' + infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex];
482
483 edgeLen+=listMasterDevice[i].LGroup[j].LTreeDev[k].GetEdge(tvertex(VPath[l]),tvertex(VPath[l]).Parent).AsFloat64[vGLength];
484
485 edgeLen:=RoundTo(edgeLen,-1);
486 infoGTree.AddEdge(tempVertexGraph,infoGTree.Vertices[infoGTree.VertexCount-1]);
487
488 //**НОВОЕ!!! Добавил ссылку на устройство
489 infoGTree.Edges[infoGTree.EdgeCount-1].AsPointer[vGPGDBObjSuperLine]:=listMasterDevice[i].LGroup[j].LTreeDev[k].GetEdge(tvertex(VPath[l]),tvertex(VPath[l]).Parent).AsPointer[vGPGDBObjSuperLine];
490
491 infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat64[vGLength]:=edgeLen;
492 //if infoGTree.Edges[infoGTree.EdgeCount-1].AsPointer[vGPGDBObjSuperLine] <> nil then
493 //infoGTree.Edges[infoGTree.EdgeCount-1].AsString[vGInfoEdge]:='+way: '+ edgeWay + '\P L=' + floattostr(edgeLen)+'m'
494 //else
495 infoGTree.Edges[infoGTree.EdgeCount-1].AsString[vGInfoEdge]:='-way: '+ edgeWay + '\P L=' + floattostr(edgeLen)+'m';
496
497 edgeLen:=0;
498 edgeWay:='';
499 tempVertexGraph:=infoGTree.Vertices[infoGTree.VertexCount-1];
500 end
501 else
502 begin
503 edgeWay+='-';
504 edgeWay+=inttostr(tvertex(VPath[l]).AsInt32[vGGIndex]);
505 //edgeWay+='-';
506
507 edgeLen+=listMasterDevice[i].LGroup[j].LTreeDev[k].GetEdge(tvertex(VPath[l]),tvertex(VPath[l]).Parent).AsFloat64[vGLength];
508 edgeLen:=RoundTo(edgeLen,-1);
509 end;
510
511 //if
512 // //listMasterDevice[i].LGroup[j].LTreeDev[k].GetEdge(VPath[l]);
513 //ZCMsgCallBackInterface.TextMessage(' vertex = ' + inttostr(tvertex(VPath[l]).AsInt32[vGGIndex]),TMWOHistoryOut);
514 //ZCMsgCallBackInterface.TextMessage(' vertex childercount = ' + inttostr(tvertex(VPath[l]).ChildCount),TMWOHistoryOut);
515 //ZCMsgCallBackInterface.TextMessage(' edge length = ' + floattostr(listMasterDevice[i].LGroup[j].LTreeDev[k].GetEdge(tvertex(VPath[l]),tvertex(VPath[l]).Parent).AsFloat64[vGLength]),TMWOHistoryOut);
516
517 //ZCMsgCallBackInterface.TextMessage(' vertex = ' + inttostr(listMasterDevice[i].LGroup[j].LTreeDev[k].Vertices[tvertex(VPath[l]).Index].AsInt32[vGGIndex]),TMWOHistoryOut);
518 //if listMasterDevice[i].LGroup[j].LTreeDev[k].Vertices[Tvertex(VertexPath[l]).Index].ChildCount<1 then
519
520 end;
521
522 //for l:= 0 to infoGTree.VertexCount - 1 do
523 // begin
524 // ZCMsgCallBackInterface.TextMessage('вершинffffff - ' + inttostr(infoGTree.Vertices[l].Index),TMWOHistoryOut);
525 // end;
526 //for l:= 0 to infoGTree.EdgeCount - 1 do
527 // begin
528 // ZCMsgCallBackInterface.TextMessage('реброооffffff - ' + inttostr(infoGTree.edges[l].V1.Index)+'---'+inttostr(infoGTree.edges[l].V2.Index),TMWOHistoryOut);
529 // end;
530 //ZCMsgCallBackInterface.TextMessage('col vertex = ' + inttostr(listMasterDevice[i].LGroup[j].LTreeDev[k].VertexCount),TMWOHistoryOut);
531 //ZCMsgCallBackInterface.TextMessage(inttostr(listMasterDevice[i].LGroup[j].LTreeDev[k].Root.Index),TMWOHistoryOut);
532 //visualGraph(listMasterDevice[i].LGroup[j].LTreeDev[k],gg,1);
533
534 // ZCMsgCallBackInterface.TextMessage('Количство ребер - ' + inttostr(infoGTree.EdgeCount),TMWOHistoryOut);
535 //ZCMsgCallBackInterface.TextMessage('Количство вершин - ' + inttostr(infoGTree.VertexCount),TMWOHistoryOut);
536
537 infoGTree.CorrectTree;
538
539 listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LEasyTreeDev.PushBack(infoGTree);
540 infoGTree:=nil;
541 tempVertexGraph:=nil;
542 end;
543 end;
544
545 end;
546 end;
547
548 // //** Добавляет пункт к ребрам графа длина с начала (от головного устройства)
549 // procedure addItemLengthFromBegin(var listMasterDevice:TVectorOfMasterDevice);
550 // var
551 // i,j,k,l:integer;
552 //
553 // VPath: TClassList;
554 //
555 // edgeLength,edgeLengthParent:float;
556 //
557 //
558 // begin
559 // for i:=0 to listMasterDevice.Size-1 do
560 // begin
561 // for j:=0 to listMasterDevice[i].LGroup.Size -1 do
562 // begin
563 // for k:=0 to listMasterDevice[i].LGroup[j].LTreeDev.Size -1 do begin
564 //
565 // listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.CreateEdgeAttr('lengthfrombegin', AttrFloat32);
566 //
567 // //**получаем обход графа
568 // VPath:=TClassList.Create;
569 // listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.TreeTraversal(tvertex(listMasterDevice[i].LGroup[j].LTreeDev[k].Root), VPath); //получаем путь обхода графа
570 //
571 //
572 // for l:= 1 to VPath.Count - 1 do
573 // begin
574 //
575 // if tvertex(VPath[l]).Parent.Parent = nil then
576 // edgeLengthParent:=0
577 // else
578 // edgeLengthParent:=listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.GetEdge(tvertex(VPath[l]).Parent,tvertex(VPath[l]).Parent.Parent).AsFloat32['lengthfrombegin'];
579 //
580 // edgeLength:=listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.GetEdge(tvertex(VPath[l]),tvertex(VPath[l]).Parent).AsFloat32[vGLength];
581 // listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.GetEdge(tvertex(VPath[l]),tvertex(VPath[l]).Parent).AsFloat32['lengthfrombegin']:=edgeLength+edgeLengthParent;
582 ////
583 //// listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.GetEdge(tvertex(VPath[l]),tvertex(VPath[l]).Parent).AsString[vGInfoEdge]:='ddd = '+floattostr(listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.GetEdge(tvertex(VPath[l]),tvertex(VPath[l]).Parent).AsFloat32['lengthfrombegin']);
584 // end;
585 // end;
586 // end;
587 //
588 // end;
589 // end;
590
591 procedure visualGraphConnection(GGraph:TGraphBuilder;listMasterDevice:TVectorOfMasterDevice;graphFull,graphEasy:boolean;var fTreeVertex:GDBVertex;var eTreeVertex:GDBVertex);
592 var
593 globalGraph: TGraph;
594 //sumWeightPath: Float;
595 easyListMasterDevice:TVectorOfMasterDevice;
596
597 i,j,k: Integer;
598 //l,m,tnum: Integer;
599 //counter,counter2,counterColor:integer; //счетчики
600
601 //listAllTree:tvectorofGraph;
602 inVertex:GDBVertex;
603
604 begin
605 //визуализация номеров точек на плане для совмещения их с деревом
606 if graphFull or graphEasy then
607 visualPtNameSL(GGraph,0.8);
608 //Построение полного дерева
609 if graphFull then begin
610 for i:=0 to listMasterDevice.Size-1 do
611 begin
612 for j:=0 to listMasterDevice[i].LGroup.Size -1 do
613 begin
614 for k:=0 to listMasterDevice[i].LGroup[j].LTreeDev.Size -1 do begin
615 visualGraph(GGraph,listMasterDevice[i].LGroup[j].LTreeDev[k],fTreeVertex,1);
616 end;
617 end;
618
619 end;
620 end;
621 //Построение полного урезанного дерева, места поворотов кабелей не показаны
622 if graphEasy then begin
623 getEasyTreeDevice(listMasterDevice);
624
625 for i:=0 to listMasterDevice.Size-1 do
626 begin
627 for j:=0 to listMasterDevice[i].LGroup.Size -1 do
628 begin
629 for k:=0 to listMasterDevice[i].LGroup[j].LEasyTreeDev.Size -1 do begin
630 visualGraph(GGraph,listMasterDevice[i].LGroup[j].LEasyTreeDev[k],eTreeVertex,1);
631 end;
632 end;
633 end;
634
635 end;
636
637
638
639 end;
640
641
642 //Визуализация построения шлейфов головных устройств с целью визуального изучения того как будут прокладываться кабельные линии
643 //дабы исключить возмоные программные ошибки
644 procedure visualMasterGroupLine(listVertexEdge:TGraphBuilder;listMasterDevice:TVectorOfMasterDevice;isMetricNumeric:boolean;heightText:double;numDevice:boolean);
645 type
646 counterGroupDevice=record
647 name:string;
648 counter:Integer;
649 end;
650
651 TCounterGroupDevice=specialize TVector<counterGroupDevice>;
652 TVectorofInteger=specialize TVector<integer>;
653 var
654 globalGraph: TGraph;
655 i,j,k,l:integer;
656
657 VPath: TClassList;
658
659 edgeLength,edgeLengthParent:float;
660
661
662 polyObj:PGDBObjPolyLine;
663 //i,j,counter:integer;
664 mtext:string;
665 notVertex:boolean;
666 pvdHeadDevice,pvdHDGroup:pvardesk; //для работы со свойствами устройств
667
668
669 colorNum,numberGDev:integer;
670 listCounterGroupDevice:TCounterGroupDevice;
671 listInteger:TVectorofInteger;
672 needParent:boolean;
673 nowDevCounter:counterGroupDevice;
674
675 // добавляем в список новое устройство из метрики и получаем устройство
addGetCounterGroupDevicenull676 function addGetCounterGroupDevice(num:integer):counterGroupDevice ;
677 var
678 i,counter:integer;
679 name:string;
680 pvd:pvardesk; //для работы со свойствами устройств
681 //devCounter:counterGroupDevice;
682 begin
683 name:='';
684 if isMetricNumeric then
685 begin
686 pvd:=FindVariableInEnt(listVertexEdge.listVertex[num].deviceEnt,'NMO_BaseName');
687 if pvd <> nil then
688 name:=pgdbstring(pvd^.data.Instance)^
689 end;
690 if listCounterGroupDevice.size = 0 then
691 begin
692 result.name:=name;
693 result.counter:=1;
694 listCounterGroupDevice.PushBack(result);
695 end
696 else
697 begin
698 counter:=-1;
699 for i:=0 to listCounterGroupDevice.size-1 do
700 if listCounterGroupDevice[i].name = name then
701 counter:=i;
702 if counter<0 then
703 begin
704 result.name:=name;
705 result.counter:=1;
706 listCounterGroupDevice.PushBack(result);
707 end
708 else
709 begin
710 inc(listCounterGroupDevice.mutable[counter]^.counter);
711 result.name:=listCounterGroupDevice[counter].name;
712 result.counter:=listCounterGroupDevice[counter].counter;
713 end;
714 end;
715 end;
716
717 //Визуализация текста его p1-координата, mText-текст, color-цвет, размер
visualDrawTextnull718 function visualDrawText(p1:GDBVertex;mText:GDBString;color:integer;heightText:double):TCommandResult;
719 var
720 ptext:PGDBObjText;
721 begin
722 ptext := GDBObjText.CreateInstance;
723 zcSetEntPropFromCurrentDrawingProp(ptext); //добавляем дефаултные свойства
724 ptext^.TXTStyleIndex:=drawings.GetCurrentDWG^.GetCurrentTextStyle; //добавляет тип стиля текста, дефаултные свойства его не добавляют
725 ptext^.Local.P_insert:=p1; // координата
726 ptext^.Template:=mText; // сам текст
727 ptext^.vp.LineWeight:=LnWt100;
728 ptext^.vp.Color:=color;
729 ptext^.vp.Layer:=uzvtestdraw.getTestLayer(vTempLayerName);
730 ptext^.textprop.size:=heightText;
731 zcAddEntToCurrentDrawingWithUndo(ptext); //добавляем в чертеж
732 result:=cmd_ok;
733 end;
734
735 //Визуализация круга его p1-координата, rr-радиус, color-цвет
visualDrawCirclenull736 function visualDrawCircle(p1:GDBVertex;rr:GDBDouble;color:integer):TCommandResult;
737 var
738 pcircle:PGDBObjCircle;
739 begin
740 begin
741 pcircle := AllocEnt(GDBCircleID); //выделяем память
742 pcircle^.init(nil,nil,0,p1,rr); //инициализируем и сразу создаем
743
744 zcSetEntPropFromCurrentDrawingProp(pcircle); //присваиваем текущие слой, вес и т.п
745 pcircle^.vp.LineWeight:=LnWt100;
746 pcircle^.vp.Color:=color;
747 pcircle^.vp.Layer:=uzvtestdraw.getTestLayer(vTempLayerName);
748 zcAddEntToCurrentDrawingWithUndo(pcircle); //добавляем в чертеж
749 end;
750 result:=cmd_ok;
751 end;
visualDrawPolyLinenull752 function visualDrawPolyLine(listInteger:TVectorofInteger;color:Integer):TCommandResult;
753 var
754 polyObj:PGDBObjPolyLine;
755 i:integer;
756 begin
757 polyObj:=GDBObjPolyline.CreateInstance;
758 zcSetEntPropFromCurrentDrawingProp(polyObj);
759 polyObj^.Closed:=false;
760 polyObj^.vp.Color:=color;
761 polyObj^.vp.LineWeight:=LnWt200;
762 polyObj^.vp.Layer:=getTestLayer(vTempLayerName);
763
764 for i:=0 to listInteger.size-1 do
765 begin
766 polyObj^.VertexArrayInOCS.PushBackData(listVertexEdge.listVertex[listInteger[i]].centerPoint);
767 end;
768
769 zcAddEntToCurrentDrawingWithUndo(polyObj);
770 result:=cmd_ok;
771 end;
772
773 begin
774
775 //heightText:=2.5;
776
777 //Создаем граф на основе класса TGraphBuilder полученого при обработке устройств и суперлиний
778 globalGraph:=TGraph.Create;
779 globalGraph.Features:=[Weighted];
780 globalGraph.AddVertices(listVertexEdge.listVertex.Size);
781 for i:=0 to listVertexEdge.listEdge.Size-1 do
782 begin
783 globalGraph.AddEdges([listVertexEdge.listEdge[i].VIndex1, listVertexEdge.listEdge[i].VIndex2]);
784 globalGraph.Edges[i].Weight:=listVertexEdge.listEdge[i].edgeLength;
785 end;
786
787 colorNum:=1;
788 for i:=0 to listMasterDevice.Size-1 do
789 for j:=0 to listMasterDevice[i].LGroup.Size -1 do
790 begin
791 if colorNum=6 then
792 colorNum:=1;
793
794 listCounterGroupDevice:=TCounterGroupDevice.Create;
795
796 for k:=0 to listMasterDevice[i].LGroup[j].LTreeDev.Size -1 do
797 begin
798
799 //**получаем обход графа
800 VPath:=TClassList.Create;
801 listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.TreeTraversal(tvertex(listMasterDevice[i].LGroup[j].LTreeDev[k].Root), VPath); //получаем путь обхода графа
802
803 listInteger:=TVectorofInteger.Create;
804
805 needParent:=false;
806 for l:= 0 to VPath.Count - 1 do
807 begin
808
809 if (l <> 0) and tvertex(VPath[l]).AsBool[vGIsDevice] then
810 begin
811 numberGDev:=tvertex(VPath[l]).AsInt32[vGGIndex];
812 if not listVertexEdge.listVertex[numberGDev].break then begin
813 nowDevCounter:= addGetCounterGroupDevice(numberGDev);
814 if numDevice then
815 visualDrawText(listVertexEdge.listVertex[numberGDev].centerPoint,listMasterDevice[i].name+'-'+listMasterDevice[i].LGroup[j].name+'-'+nowDevCounter.name+'-'+inttostr(nowDevCounter.counter),colorNum,heightText);
816 visualDrawCircle(listVertexEdge.listVertex[numberGDev].centerPoint,5,colorNum);
817 end;
818 end;
819
820 if needParent then begin
821 listInteger.PushBack(tvertex(VPath[l]).Parent.AsInt32[vGGIndex]);
822 end;
823
824 listInteger.PushBack(tvertex(VPath[l]).AsInt32[vGGIndex]);
825
826 if listInteger.Size > 1 then
827 if (tvertex(VPath[l]).ChildCount > 1) or (tvertex(VPath[l]).ChildCount = 0) or tvertex(VPath[l]).AsBool[vGIsDevice] then
828 begin
829 visualDrawPolyLine(listInteger,colorNum);
830 listInteger:=TVectorofInteger.Create;
831
832 needParent:=true;
833 //ZCMsgCallBackInterface.TextMessage('numvertex'+inttostr(tvertex(VPath[l]).AsInt32[vGGIndex])+' Количство дтей - ' + inttostr(tvertex(VPath[l]).ChildCount),TMWOHistoryOut);
834 end;
835
836 end;
837 end;
838 inc(colorNum);
839 end;
840 end;
841
842
843
844
845 procedure cabelingMasterGroupLine(listVertexEdge:TGraphBuilder;listMasterDevice:TVectorOfMasterDevice;isMetricNumeric:boolean);
846 type
847 counterGroupDevice=record
848 name:string;
849 counter:Integer;
850 end;
851
852 TCounterGroupDevice=specialize TVector<counterGroupDevice>;
853 TVectorofInteger=specialize TVector<integer>;
854 var
855 globalGraph: TGraph;
856 i,j,k,l,counterSegment:integer;
857
858 VPath: TClassList;
859
860 edgeLength,edgeLengthParent:float;
861
862
863 polyObj:PGDBObjPolyLine;
864 //i,j,counter:integer;
865 mtext:string;
866 notVertex:boolean;
867 pvdHeadDevice,pvdHDGroup:pvardesk; //для работы со свойствами устройств
868 //myVertex,vertexAnalized:TListVertexWayOnlyVertex;
869 //myTerminalBox:TListVertexTerminalBox;
870
871 heightText:double;
872 colorNum,numberGDev:integer;
873 listCounterGroupDevice:TCounterGroupDevice;
874 listInteger:TVectorofInteger;
875 needParent:boolean;
876 nowDevCounter:counterGroupDevice;
877
878
879 //Метрирование датчиков
880 procedure metricNumeric(dev:PGDBObjDevice);
881 var
882 pvd:pvardesk;
883 name:string;
884 begin
885 name:='';
886 if isMetricNumeric then begin
887 pvd:=FindVariableInEnt(dev,'NMO_BaseName');
888 if pvd<>nil then
889 name:=pgdbstring(pvd^.data.Instance)^;
890 end;
891
892 pvd:=FindVariableInEnt(dev,'GC_InGroup_Metric');
893 if pvd<>nil then
894 pgdbstring(pvd^.data.Instance)^:=name ;
895 end;
896
897 procedure drawCableLine(listInteger:TVectorofInteger;numLMaster,numLGroup,counterSegment:Integer);
898 var
899 cableLine:PGDBObjCable;
900 i:integer;
901 pvd:pvardesk; //для работы со свойствами устройств
902 psu:ptunit;
903 pvarext:PTVariablesExtender;
904
905 begin
906 cableLine := AllocEnt(GDBCableID);
907 cableLine^.init(nil,nil,0);
908 zcSetEntPropFromCurrentDrawingProp(cableLine);
909
910 for i:=0 to listInteger.Size-1 do
911 cableLine^.VertexArrayInOCS.PushBackData(listVertexEdge.listVertex[listInteger[i]].centerPoint);
912
913 //**добавление кабельных свойств
914 pvarext:=cableLine^.GetExtension(typeof(TVariablesExtender)); //подклчаемся к инспектору
915 if pvarext<>nil then
916 begin
917 psu:=units.findunit(SupportPath,@InterfaceTranslate,'cable'); //
918 if psu<>nil then
919 pvarext^.entityunit.copyfrom(psu);
920 end;
921 zcSetEntPropFromCurrentDrawingProp(cableLine);
922 //***//
923
924 //** Имя мастера устройства
925 pvd:=FindVariableInEnt(cableLine,'GC_HeadDevice');
926 if pvd<>nil then
927 pgdbstring(pvd^.data.Instance)^:=listMasterDevice[numLMaster].name;
928
929 pvd:=FindVariableInEnt(cableLine,'GC_HDShortName');
930 if pvd<>nil then
931 pgdbstring(pvd^.data.Instance)^:=listMasterDevice[numLMaster].shortName;
932
933 //** обавляем суффикс
934 pvd:=FindVariableInEnt(cableLine,'NMO_Suffix');
935 if pvd<>nil then
936 pgdbstring(pvd^.data.Instance)^:=listMasterDevice[numLMaster].LGroup[numLGroup].name;
937
938 pvd:=FindVariableInEnt(cableLine,'CABLE_AutoGen');
939 if pvd<>nil then
940 pgdbboolean(pvd^.data.Instance)^:=true;
941
942 pvd:=FindVariableInEnt(cableLine,'GC_HDGroup');
943 if pvd<>nil then
944 pgdbstring(pvd^.data.Instance)^:=listMasterDevice[numLMaster].LGroup[numLGroup].name;
945
946
947 pvd:=FindVariableInEnt(cableLine,'NMO_BaseName');
948 if pvd<>nil then
949 pgdbstring(pvd^.data.Instance)^:=listMasterDevice[numLMaster].name + '-';
950
951 pvd:=FindVariableInEnt(cableLine,'CABLE_Segment');
952 if pvd<>nil then
953 begin
954 pgdbinteger(pvd^.data.Instance)^:=counterSegment;
955 end;
956
957
958 zcAddEntToCurrentDrawingWithUndo(cableLine);
959 //result:=cmd_ok;
960 end;
961
962 begin
963
964 //Создаем граф на основе класса TGraphBuilder полученого при обработке устройств и суперлиний
965 globalGraph:=TGraph.Create;
966 globalGraph.Features:=[Weighted];
967 globalGraph.AddVertices(listVertexEdge.listVertex.Size);
968 for i:=0 to listVertexEdge.listEdge.Size-1 do
969 begin
970 globalGraph.AddEdges([listVertexEdge.listEdge[i].VIndex1, listVertexEdge.listEdge[i].VIndex2]);
971 globalGraph.Edges[i].Weight:=listVertexEdge.listEdge[i].edgeLength;
972 end;
973
974
975
976 //colorNum:=1;
977 for i:=0 to listMasterDevice.Size-1 do
978 for j:=0 to listMasterDevice[i].LGroup.Size -1 do
979 begin
980
981 for k:=0 to listMasterDevice[i].LGroup[j].LNumSubDevice.Size -1 do
982 metricNumeric(listVertexEdge.listVertex[listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexSub].deviceEnt);
983
984 counterSegment:=0;
985 for k:=0 to listMasterDevice[i].LGroup[j].LTreeDev.Size -1 do
986 begin
987 //**получаем обход графа
988 VPath:=TClassList.Create;
989 listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.TreeTraversal(tvertex(listMasterDevice[i].LGroup[j].LTreeDev[k].Root), VPath); //получаем путь обхода графа
990
991 listInteger:=TVectorofInteger.Create;
992
993 needParent:=false;
994 for l:= 0 to VPath.Count - 1 do
995 begin
996 //ZCMsgCallBackInterface.TextMessage('вершина - '+inttostr(tvertex(VPath[l]).AsInt32[vGGIndex]),TMWOHistoryOut);
997 //Создаем список точек кабеля который передадим в отрисовку кабельной линии
998 if needParent then begin
999 listInteger.PushBack(tvertex(VPath[l]).Parent.AsInt32[vGGIndex]);
1000 needParent:=false;
1001 end;
1002
1003 listInteger.PushBack(tvertex(VPath[l]).AsInt32[vGGIndex]);
1004
1005 if listVertexEdge.listVertex[tvertex(VPath[l]).AsInt32[vGGIndex]].break and listVertexEdge.listVertex[tvertex(VPath[l]).Parent.AsInt32[vGGIndex]].break then begin
1006 needParent:=true;
1007 listInteger:=TVectorofInteger.Create;
1008 end else
1009
1010 //ZCMsgCallBackInterface.TextMessage('длина списка - '+inttostr(listInteger.Size),TMWOHistoryOut);
1011 if listInteger.Size > 1 then
1012 if (tvertex(VPath[l]).ChildCount > 1) or (tvertex(VPath[l]).ChildCount = 0) or tvertex(VPath[l]).AsBool[vGIsDevice] or (listVertexEdge.listVertex[tvertex(VPath[l]).AsInt32[vGGIndex]].break and listVertexEdge.listVertex[tvertex(VPath[l]).Parent.AsInt32[vGGIndex]].break) then
1013 //if (tvertex(VPath[l]).ChildCount > 1) or (tvertex(VPath[l]).ChildCount = 0) or (listVertexEdge.listVertex[tvertex(VPath[l]).AsInt32[vGGIndex]].break and listVertexEdge.listVertex[tvertex(VPath[l]).Parent.AsInt32[vGGIndex]].break) then
1014 begin
1015 //ZCMsgCallBackInterface.TextMessage('Строем кабель',TMWOHistoryOut);
1016 drawCableLine(listInteger,i,j,counterSegment);
1017 listInteger:=TVectorofInteger.Create;
1018 inc(counterSegment);
1019 needParent:=true;
1020 end;
1021
1022 end;
1023 end;
1024 //inc(colorNum);
1025 end;
1026 end;
1027
1028 //** Добавляет пункт к вершинам графа длина с Конца (от головного устройства)
1029 procedure addItemLengthFromEnd(var listMasterDevice:TVectorOfMasterDevice);
1030 var
1031 i,j,k,l:integer;
1032
1033 VPath: TClassList;
1034
1035 edgeLength,edgeLengthChilds:float;
1036
1037
1038 // получения вершины в графе на основе вершины из другого графа
getLengthChildsnull1039 function getLengthChilds(gTree:TGraph;vt:tvertex):float;
1040 var
1041 i:integer;
1042 begin
1043 result:=0;
1044 for i:=0 to vt.ChildCount-1 do
1045 result+=vt.Childs[i].AsFloat64[vGLengthFromEnd];
1046 end;
1047
1048 begin
1049 for i:=0 to listMasterDevice.Size-1 do
1050 for j:=0 to listMasterDevice[i].LGroup.Size -1 do
1051 for k:=0 to listMasterDevice[i].LGroup[j].LTreeDev.Size -1 do
1052 begin
1053 listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.CreateVertexAttr(vGLengthFromEnd, AttrFloat64);
1054
1055 //**получаем обход графа
1056 VPath:=TClassList.Create;
1057 listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.TreeTraversal(tvertex(listMasterDevice[i].LGroup[j].LTreeDev[k].Root), VPath); //получаем путь обхода графа
1058
1059 for l:= VPath.Count - 1 downto 1 do
1060 begin
1061 edgeLengthChilds:=getLengthChilds(listMasterDevice[i].LGroup[j].LTreeDev[k],tvertex(VPath[l]));
1062 edgeLength:=listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.GetEdge(tvertex(VPath[l]),tvertex(VPath[l]).Parent).AsFloat64[vGLength];
1063 tvertex(VPath[l]).AsFloat64[vGLengthFromEnd]:=edgeLength+edgeLengthChilds;
1064 end;
1065 end;
1066 end;
1067
1068
1069
1070
1071 //** Создание деревьев устройств
1072 procedure addTreeDevice(listVertexEdge:TGraphBuilder;globalGraph:TGraph;var listMasterDevice:TVectorOfMasterDevice);
1073 //type
1074 //tempuseVertex:Tvectorofinteger;
1075 var
1076 pvd:pvardesk; //для работы со свойствами устройств
1077 polyObj:PGDBObjPolyLine;
1078 i,j,k,m,n,counter1,counter2,counter3:integer;
1079 tIndex,tIndexLocal,tIndexGlobal:integer;
1080 EdgePath, VertexPath: TClassList;
1081 infoGTree:TGraph;
1082
1083 tempString:string;
1084 sumWeightPath,tempFloat: Float;
1085 tempLVertex:TvectorOfInteger;
1086 gg:GDBVertex;
1087
isVertexAddednull1088 function isVertexAdded(tempLVertex:tvectorofinteger;index:integer):boolean;
1089 var
1090 i:integer;
1091 begin
1092 result:=true;
1093 for i:=0 to tempLVertex.Size-1 do begin
1094 //ZCMsgCallBackInterface.TextMessage('ищем - ' + inttostr(tempLVertex[i])+' наш - ' + inttostr(index),TMWOHistoryOut);
1095 if tempLVertex[i]=index then begin
1096 result:=false;
1097 //ZCMsgCallBackInterface.TextMessage('совпало: ' + inttostr(tempLVertex[i])+' = ' + inttostr(index),TMWOHistoryOut);
1098 end;
1099 end;
1100 end;
1101
1102
getLengthnull1103 function getLength(listVertexEdge:TGraphBuilder;pt1,pt2:integer):Float;
1104 var
1105 i:integer;
1106 begin
1107 result:=-1;
1108 for i:=0 to listVertexEdge.listEdge.Size-1 do
1109 if ((listVertexEdge.listEdge[i].VIndex1=pt1) and (listVertexEdge.listEdge[i].VIndex2=pt2)) or
1110 ((listVertexEdge.listEdge[i].VIndex1=pt2) and (listVertexEdge.listEdge[i].VIndex2=pt1)) then
1111 result:=listVertexEdge.listEdge[i].edgeLength;
1112 end;
1113
getvGPGDBObjSuperLinenull1114 function getvGPGDBObjSuperLine(listVertexEdge:TGraphBuilder;pt1,pt2:integer):PGDBObjSuperLine;
1115 var
1116 i:integer;
1117 begin
1118 result:=nil;
1119 for i:=0 to listVertexEdge.listEdge.Size-1 do
1120 if ((listVertexEdge.listEdge[i].VIndex1=pt1) and (listVertexEdge.listEdge[i].VIndex2=pt2)) or
1121 ((listVertexEdge.listEdge[i].VIndex1=pt2) and (listVertexEdge.listEdge[i].VIndex2=pt1)) then
1122 result:=listVertexEdge.listEdge[i].cableEnt;
1123 end;
1124
getLocalIndexnull1125 function getLocalIndex(gTree:TGraph;indexGlobal:integer):LongInt;
1126 var
1127 i:integer;
1128 begin
1129 result:=-1;
1130 for i:=0 to gTree.VertexCount-1 do
1131 if gTree.Vertices[i].AsInt32[vGGIndex] = indexGlobal then
1132 result:=i;
1133 end;
1134
1135 //** Есть ли соединение данного устройства с данным номером головного устройства
1136 //** суть в том что одно и тоже устройство может быть на разных планах, это нужно для избежания ошибок связей
isHaveLineMasternull1137 function isHaveLineMaster(isMaster,isSub:integer):boolean;
1138 begin
1139 //ZCMsgCallBackInterface.TextMessage('isMaster : ' + inttostr(isMaster)+' - isSub - ' + inttostr(isSub),TMWOHistoryOut);
1140
1141 result:=true; // нет пути между головным устройством и подключаемым
1142 EdgePath:=TClassList.Create; //Создаем реберный путь
1143 VertexPath:=TClassList.Create; //Создаем вершиный путь
1144 //Получение ребер минимального пути в графе из одной точки в другую
1145 sumWeightPath:=globalGraph.FindMinWeightPath(globalGraph[isMaster], globalGraph[isSub], EdgePath);
1146 //Получение вершин минимального пути в графе на основе минимального пути в ребер, указывается из какой точки старт
1147 globalGraph.EdgePathToVertexPath(globalGraph[isMaster], EdgePath, VertexPath);
1148
1149 //Узнать существует уже граф если нет то создать его и добавляем начальную вершину
1150 if VertexPath.Count > 1 then
1151 result:=false; //путь есть между головным устройством и подключаемым
1152
1153 end;
1154
1155 begin
1156 for i:=0 to listMasterDevice.Size-1 do
1157 begin
1158 for j:=0 to listMasterDevice[i].LGroup.Size -1 do
1159 begin
1160 for n:=0 to listMasterDevice[i].LIndex.Size -1 do
1161 begin
1162
1163 //ZCMsgCallBackInterface.TextMessage('khfskldhfskdhflksdhflksdhflksdflkshd - ' + inttostr(n),TMWOHistoryOut);
1164
1165 infoGTree:=TGraph.Create;
1166 infoGTree.Features:=[Tree];
1167 //infoGTree.Root;
1168 infoGTree.CreateVertexAttr(vGGIndex, AttrInt32);
1169 infoGTree.CreateVertexAttr(vGIsDevice, AttrBool);
1170 infoGTree.CreateVertexAttr(vGInfoVertex, AttrString);
1171
1172 infoGTree.CreateVertexAttr(vGPGDBObjDevice,AttrPointer); // добавили ссылку сразу на само устройство
1173
1174 infoGTree.CreateEdgeAttr(vGLength, AttrFloat64);
1175 infoGTree.CreateEdgeAttr(vGInfoEdge, AttrString);
1176
1177 infoGTree.CreateEdgeAttr(vGPGDBObjSuperLine,AttrPointer); // добавили ссылку сразу на саму линию
1178
1179 //ZCMsgCallBackInterface.TextMessage('yfx Количство ребер - ' + inttostr(infoGTree.EdgeCount),TMWOHistoryOut);
1180 //ZCMsgCallBackInterface.TextMessage('yfx Количство вершин - ' + inttostr(infoGTree.VertexCount),TMWOHistoryOut);
1181
1182
1183 tempLVertex:=tvectorofinteger.create;
1184 //listMasterDevice[i].LGroup[j].LNumSubDevice;
1185 for k:=0 to listMasterDevice[i].LGroup[j].LNumSubDevice.Size-1 do
1186 begin
1187
1188 if isHaveLineMaster(listMasterDevice[i].LIndex[n],listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexSub) then
1189 continue;
1190
1191 EdgePath:=TClassList.Create; //Создаем реберный путь
1192 VertexPath:=TClassList.Create; //Создаем вершиный путь
1193 //Получение ребер минимального пути в графе из одной точки в другую
1194 sumWeightPath:=globalGraph.FindMinWeightPath(globalGraph[listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster], globalGraph[listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexSub], EdgePath);
1195 //Получение вершин минимального пути в графе на основе минимального пути в ребер, указывается из какой точки старт
1196 //ZCMsgCallBackInterface.TextMessage('master = '+inttostr(listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster)+' sub - ' + inttostr(listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexSub),TMWOHistoryOut);
1197
1198 globalGraph.EdgePathToVertexPath(globalGraph[listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster], EdgePath, VertexPath);
1199
1200 tIndexLocal:=-1; //промежуточная вершина для создание ребер графа
1201 tIndexGlobal:=-1; //промежуточная вершина для построения пути глобального графа
1202
1203 //ZCMsgCallBackInterface.TextMessage('количество - ' + inttostr(VertexPath.Count),TMWOHistoryOut);
1204
1205 //Узнать существует уже граф если нет то создать его и добавляем начальную вершину
1206 if infoGTree.VertexCount <= 0 then begin
1207 infoGTree.AddVertex;
1208 infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]:=listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster;
1209
1210 //Добавил ссылку на устройство
1211 infoGTree.Vertices[infoGTree.VertexCount-1].AsPointer[vGPGDBObjDevice]:=listVertexEdge.listVertex[listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster].deviceEnt;
1212
1213 if listVertexEdge.listVertex[listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster].deviceEnt <> nil then
1214 begin
1215 infoGTree.Vertices[infoGTree.VertexCount-1].AsBool[vGIsDevice]:=true;
1216 //tempString:='№';
1217 tempString:=inttostr(infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]);
1218 tempString+='\P';
1219 tempString+='dev';
1220 infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex]:=tempString;
1221 end
1222 else
1223 begin
1224 infoGTree.Vertices[infoGTree.VertexCount-1].AsBool[vGIsDevice]:=false;
1225 //tempString:='№';
1226 tempString:=inttostr(infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]);
1227 tempString+='\P';
1228 tempString+='nul';
1229 infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex]:=tempString;
1230 end;
1231 //infoGTree.Vertices[infoGTree.VertexCount-1].AsBool['isFork']:=false;
1232
1233 //ZCMsgCallBackInterface.TextMessage('РУУТ - ' + inttostr(infoGTree.VertexCount-1),TMWOHistoryOut);
1234
1235 infoGTree.Root:=infoGTree.Vertices[infoGTree.VertexCount-1];
1236 tempLVertex.PushBack(listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster);
1237 end;
1238
1239 if VertexPath.Count > 1 then
1240 for m:=VertexPath.Count - 1 downto 0 do begin
1241 // Добавляет цифрц ы центре каждого устройства
1242 // uzvtestdraw.testTempDrawText(listVertexEdge.listVertex[TVertex(VertexPath[m]).Index].centerPoint,inttostr(TVertex(VertexPath[m]).Index));
1243
1244
1245 //ZCMsgCallBackInterface.TextMessage('way - ' + inttostr(TVertex(VertexPath[m]).Index),TMWOHistoryOut);
1246 if isVertexAdded(tempLVertex,TVertex(VertexPath[m]).Index) then
1247 begin
1248 //ZCMsgCallBackInterface.TextMessage('отработка кода ',TMWOHistoryOut);
1249
1250 infoGTree.AddVertex;
1251 infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]:=TVertex(VertexPath[m]).Index;
1252
1253 //НОВОЕ! Добавил ссылку на устройство
1254 infoGTree.Vertices[infoGTree.VertexCount-1].AsPointer[vGPGDBObjDevice]:=listVertexEdge.listVertex[TVertex(VertexPath[m]).Index].deviceEnt;
1255
1256
1257 if listVertexEdge.listVertex[TVertex(VertexPath[m]).Index].deviceEnt <> nil then
1258 begin
1259 infoGTree.Vertices[infoGTree.VertexCount-1].AsBool[vGIsDevice]:=true;
1260 //tempString:='№';
1261 tempString:=inttostr(infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]);
1262 tempString+='\P';
1263 tempString+='dev';
1264 infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex]:=tempString;
1265 end
1266 else
1267 begin
1268 infoGTree.Vertices[infoGTree.VertexCount-1].AsBool[vGIsDevice]:=false;
1269 //tempString:='№';
1270 tempString:=inttostr(infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]);
1271 tempString+='\P';
1272 tempString+='nul';
1273 infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex]:=tempString;
1274 end;
1275 //infoGTree.Vertices[infoGTree.VertexCount-1].AsBool['isFork']:=false;
1276
1277 tempLVertex.PushBack(TVertex(VertexPath[m]).Index);
1278
1279 if tIndexLocal < 0 then begin
1280 tIndexLocal:=infoGTree.VertexCount-1;
1281 tIndexGlobal:=TVertex(VertexPath[m]).Index;
1282 end
1283 else
1284 begin
1285 //ZCMsgCallBackInterface.TextMessage('edgeGlobal : ' + inttostr(tIndexGlobal)+' - ' + inttostr(TVertex(VertexPath[m]).index),TMWOHistoryOut);
1286 //ZCMsgCallBackInterface.TextMessage('edgelocal : ' + inttostr(tIndexLocal)+' - ' + inttostr(infoGTree.VertexCount-1),TMWOHistoryOut);
1287 infoGTree.AddEdge(infoGTree.Vertices[tIndexLocal],infoGTree.Vertices[infoGTree.VertexCount-1]);
1288
1289 //ZCMsgCallBackInterface.TextMessage('edgelength : ' + floattostr(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index)),TMWOHistoryOut);
1290 //tempFloat:=1*RoundTo(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index),-1);
1291 //tempFloat:=20;
1292 infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat64[vGLength]:=getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index);
1293 infoGTree.Edges[infoGTree.EdgeCount-1].AsString[vGInfoEdge]:='\\P L='+floattostr(RoundTo(infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat64[vGLength],-1))+'m';
1294 //ZCMsgCallBackInterface.TextMessage('edgedddddlength : ' + floattostr(infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat32[vGLength]) + ' - - - ' + floattostr(tempFloat),TMWOHistoryOut);
1295
1296
1297 //infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat32[vGLength]:=RoundTo(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index),-1);
1298 //infoGTree.Edges[infoGTree.EdgeCount-1].AsString[vGInfoEdge]:='\\P L='+floattostr(infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat32[vGLength])+'m';
1299 //ZCMsgCallBackInterface.TextMessage('edgelength : ' + floattostr(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index)) + ' - - - ' + floattostr(RoundTo(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index),-1)),TMWOHistoryOut);
1300 //ZCMsgCallBackInterface.TextMessage('edgelength : ' + floattostr(infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat32[vGLength]) + ' - округ - ' + infoGTree.Edges[infoGTree.EdgeCount-1].AsString[vGInfoEdge],TMWOHistoryOut);
1301
1302 tIndexLocal:=infoGTree.VertexCount-1;
1303 tIndexGlobal:=TVertex(VertexPath[m]).Index;
1304 end;
1305
1306 end
1307 else begin
1308 if tIndexLocal >= 0 then
1309 begin
1310 tIndex:=getLocalIndex(infoGTree,TVertex(VertexPath[m]).index);
1311 //ZCMsgCallBackInterface.TextMessage('edgeGlobal : ' + inttostr(tIndexGlobal)+' - ' + inttostr(TVertex(VertexPath[m]).index),TMWOHistoryOut);
1312 //ZCMsgCallBackInterface.TextMessage('edgelocal : ' + inttostr(tIndexLocal)+' - ' + inttostr(tIndex),TMWOHistoryOut);
1313 infoGTree.AddEdge(infoGTree.Vertices[tIndexLocal],infoGTree.Vertices[tIndex]);
1314
1315 //НОВОЕ!!!! Добавил ссылку на устройство
1316 infoGTree.Edges[infoGTree.EdgeCount-1].AsPointer[vGPGDBObjSuperLine]:=getvGPGDBObjSuperLine(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index);
1317
1318
1319 //ZCMsgCallBackInterface.TextMessage('edgelength : ' + floattostr(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index)),TMWOHistoryOut);
1320 infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat64[vGLength]:=getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index);
1321 infoGTree.Edges[infoGTree.EdgeCount-1].AsString[vGInfoEdge]:='\\P L='+floattostr(RoundTo(infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat64[vGLength],-1))+'m';
1322
1323 //ZCMsgCallBackInterface.TextMessage('edgelength : ' + floattostr(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index)) + ' - - - ' + floattostr(RoundTo(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index),-1)),TMWOHistoryOut);
1324 //ZCMsgCallBackInterface.TextMessage('edgelength : ' + floattostr(infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat32[vGLength]) + ' - округ - ' + infoGTree.Edges[infoGTree.EdgeCount-1].AsString[vGInfoEdge],TMWOHistoryOut);
1325
1326 tIndexLocal:=-1;
1327 tIndexGlobal:=-1;
1328 end;
1329 end;
1330 end;
1331
1332 EdgePath.Destroy;
1333 VertexPath.Destroy;
1334 end;
1335
1336 //ZCMsgCallBackInterface.TextMessage('Количство ребер - ' + inttostr(infoGTree.EdgeCount),TMWOHistoryOut);
1337 //ZCMsgCallBackInterface.TextMessage('Количство вершин - ' + inttostr(infoGTree.VertexCount),TMWOHistoryOut);
1338
1339 // Такая проверку нужна, тогда когда бывает что головное устройство на разных планах установлено
1340 // и может возникнуть ситуация когда на плане разные группы, что вызовит пустой граф
1341 //что бы не было проблем выполнена данная проверка
1342 if infoGTree.VertexCount > 0 then begin
1343 infoGTree.CorrectTree; //Делает дерево корректным, добавляет родителей детей
1344 listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.PushBack(infoGTree);
1345 end;
1346
1347 infoGTree:=nil;
1348 tempLVertex.Destroy;
1349 end;
1350 end;
1351 end;
1352 end;
1353
buildListAllConnectDevicenull1354 function buildListAllConnectDevice(listVertexEdge:TGraphBuilder;Epsilon:double; var listError:TListError):TVectorOfMasterDevice;
1355 var
1356
1357 globalGraph: TGraph;
1358 listMasterDevice:TVectorOfMasterDevice;
1359
1360 i,j,k: Integer;
1361
1362 gg:GDBVertex;
1363
1364
1365 //** Поиск существует ли устройства с нужным именем
isHaveDevicenull1366 function isHaveDevice(listVertex:TListDeviceLine;name:string):boolean;
1367 var
1368 i: Integer;
1369 pvd:pvardesk; //для работы со свойствами устройств
1370 begin
1371 result:=true;
1372 for i:=0 to listVertex.Size-1 do
1373 if listVertex[i].deviceEnt<>nil then
1374 begin
1375 pvd:=FindVariableInEnt(listVertex[i].deviceEnt,'NMO_Name');
1376 if pvd <> nil then
1377 if pgdbstring(pvd^.data.Instance)^ = name then
1378 result:= false;
1379 end;
1380 end;
1381
1382 begin
1383
1384 //Создаем граф на основе класса TGraphBuilder полученого при обработке устройств и суперлиний
1385 globalGraph:=TGraph.Create;
1386 globalGraph.Features:=[Weighted];
1387 globalGraph.AddVertices(listVertexEdge.listVertex.Size);
1388 for i:=0 to listVertexEdge.listEdge.Size-1 do
1389 begin
1390 globalGraph.AddEdges([listVertexEdge.listEdge[i].VIndex1, listVertexEdge.listEdge[i].VIndex2]);
1391 globalGraph.Edges[i].Weight:=listVertexEdge.listEdge[i].edgeLength;
1392 end;
1393
1394 //**получаем список подключенных устройств к головным устройствам
1395 listMasterDevice:=getListMasterDev(listVertexEdge,globalGraph);
1396
1397 //for i:=0 to listMasterDevice.Size-1 do
1398 // begin
1399 // ZCMsgCallBackInterface.TextMessage('мастер = '+ listMasterDevice[i].name,TMWOHistoryOut);
1400 // for j:=0 to listMasterDevice[i].LGroup.Size -1 do
1401 // begin
1402 // ZCMsgCallBackInterface.TextMessage('колво приборы = '+ inttostr(listMasterDevice[i].LGroup[j].LNumSubDevice.size),TMWOHistoryOut);
1403 // for k:=0 to listMasterDevice[i].LGroup[j].LNumSubDevice.Size -1 do
1404 // ZCMsgCallBackInterface.TextMessage('приборы = '+ inttostr(listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexSub),TMWOHistoryOut);
1405 // end;
1406 // end;
1407
1408 //**Переробатываем список устройств подключенный к группам и на основе него создание деревьев усройств
1409 addTreeDevice(listVertexEdge,globalGraph,listMasterDevice);
1410
1411 //**Переробатываем большой граф в упрощенный,для удобной визуализации
1412 //addEasyTreeDevice(globalGraph,listMasterDevice);
1413
1414 //**Добавляем к вершинам длины кабелей с конца, для правильной сортировки дерева по длине
1415 addItemLengthFromEnd(listMasterDevice);
1416
1417 ZCMsgCallBackInterface.TextMessage('*** Суперлиния - ' + listVertexEdge.nameSuperLine + ' - обработка выполнена! ***',TMWOHistoryOut);
1418
1419 //visualGraph(listMasterDevice[0].LGroup[0].LTreeDev[0],gg,1) ;
1420 //gg:=uzegeometry.CreateVertex(0,0,0);
1421
1422 //visualAllTreesLMD(listMasterDevice,gg,1);
1423
1424 for i:=0 to listMasterDevice.Size-1 do
1425 begin
1426 for j:=0 to listMasterDevice[i].LGroup.Size -1 do
1427 begin
1428 for k:=0 to listMasterDevice[i].LGroup[j].LTreeDev.Size -1 do begin
1429 //visualGraph(listMasterDevice[i].LGroup[j].LTreeDev[k],gg,1);
1430
1431 listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.SortTree(listMasterDevice[i].LGroup[j].LTreeDev[k].Root,@SortTreeLengthComparer.Compare);
1432
1433 //visualGraph(listMasterDevice[i].LGroup[j].LTreeDev[k],gg,1);
1434 end;
1435 end;
1436
1437 end;
1438
1439 result:=listMasterDevice;
1440
1441 end;
1442
1443
1444 //** Создает список головных устройств
getListMasterDevNewnull1445 function getListMasterDevNew(listVertexEdge:TGraphBuilder;globalGraph: TGraph):TVectorOfMasterDevice;
1446 type
1447 //**список для кабельной прокладки
1448 PTCableLaying=^TCableLaying;
1449 TCableLaying=record
1450 headName:string;
1451 GroupNum:string;
1452 typeSLine:string;
1453
1454 end;
1455 TVertexofCableLaying=specialize TVector<TCableLaying>;
1456
1457 TVertexofString=specialize TVector<string>;
1458 var
1459 /////////////////////////
1460
1461 listCableLaying:TVertexofCableLaying; //список кабельной прокладки
1462
1463 masterDevInfo:TMasterDevice;
1464 groupInfo:TMasterDevice.TGroupInfo;
1465 infoSubDev:TMasterDevice.TGroupInfo.TInfoSubDev;
1466 //deviceInfo:TMasterDevice.TGroupInfo.TDeviceInfo;
1467 i,j,k,m,counter,tnum: Integer;
1468 numHead,numHeadGroup,numHeadDev : integer;
1469
1470 isHeadnum:boolean;
1471 shortNameHead, headDevName, groupName:string;
1472 pvd:pvardesk; //для работы со свойствами устройств
1473
1474 //** Получаем количество кабелей подключения данного устройства к головным устройствам, с последующим разбором
listCollectConnectnull1475 function listCollectConnect(nowDev:PGDBObjDevice;var listCableLaying:TVertexofCableLaying;nameSL:string):boolean;
1476 var
1477 pvd:pvardesk; //для работы со свойствами устройств
1478 polyObj:PGDBObjPolyLine;
1479 i,counter1,counter2,counter3:integer;
1480 tempName,nameParam:gdbstring;
1481 infoLay:TCableLaying;
1482 listStr1,listStr2,listStr3:TVertexofString;
1483
1484 begin
1485 listStr1:=TVertexofString.Create;
1486 listStr2:=TVertexofString.Create;
1487 listStr3:=TVertexofString.Create;
1488
1489 pvd:=FindVariableInEnt(nowDev,'SLCABAGEN_HeadDeviceName');
1490 if pvd<>nil then
1491 BEGIN
1492 nameParam:=pgdbstring(pvd^.data.Instance)^;
1493 listStr1.PushBack(nameParam);
1494 //repeat
1495 // GetPartOfPath(nameParam,tempName,';');
1496 // listStr1.PushBack(nameParam);
1497 // // HistoryOutStr(' code2 = ' + nameParam);
1498 //until tempName='';
1499
1500 pvd:=FindVariableInEnt(nowDev,'SLCABAGEN_NGHeadDevice');
1501 if pvd<>nil then
1502 BEGIN
1503 nameParam:=pgdbstring(pvd^.data.Instance)^;
1504 //repeat
1505 // GetPartOfPath(nameParam,tempName,';');
1506 listStr2.PushBack(nameParam);
1507 //until tempName='';
1508
1509 pvd:=FindVariableInEnt(nowDev,'SLCABAGEN_SLTypeagen');
1510 if pvd<>nil then
1511 BEGIN
1512 nameParam:=pgdbstring(pvd^.data.Instance)^;
1513 //repeat
1514 // GetPartOfPath(nameParam,tempName,';');
1515 listStr3.PushBack(nameParam);
1516 //until tempName='';
1517
1518 for i:=0 to listStr1.size-1 do
1519 begin
1520 infoLay.headName:=listStr1[i];
1521 infoLay.GroupNum:=listStr2[i];
1522 infoLay.typeSLine:=listStr3[i];
1523 if infoLay.typeSLine = nameSL then
1524 listCableLaying.PushBack(infoLay);
1525 end;
1526 end;
1527 end;
1528
1529 end;
1530 if listCableLaying.size > 0 then
1531 result:=true
1532 else
1533 result:=false;
1534 end;
1535
1536
1537 begin
1538 result:=TVectorOfMasterDevice.Create;
1539 listCableLaying := TVertexofCableLaying.Create;
1540
1541 //counter:=0;
1542
1543 //на базе listVertexEdge заполняем список головных устройств и все что в них входит
1544 for i:=0 to listVertexEdge.listVertex.Size-1 do
1545 begin
1546 //если это устройство и не разрыв
1547 if (listVertexEdge.listVertex[i].deviceEnt<>nil) and (listVertexEdge.listVertex[i].break<>true) then
1548 begin
1549 //Получаем список сколько у устройства хозяев
1550 if listCollectConnect(listVertexEdge.listVertex[i].deviceEnt,listCableLaying,listVertexEdge.nameSuperLine) then
1551 begin
1552 //inc(counter);
1553 for m:=0 to listCableLaying.size-1 do begin
1554
1555 headDevName:=listCableLaying[m].headName;
1556 //Поиск хозяина внутри графа полученного из listVertexEdge и возврат номера устройства
1557 numHeadDev:=getNumHeadDevice(listVertexEdge.listVertex,headDevName,globalGraph,i); // если минус значит нету хозяина
1558
1559 if numHeadDev >= 0 then
1560 begin
1561 //**Проверяем существует ли хоть одно главное устройство с таким именем,
1562 //если нет то создаем, если есть то или добавляем к существующему или создаем еще одно устройство
1563 numHead := -1;
1564 for j:=0 to result.Size-1 do //проверяем существует ли уже такое же головное устройство
1565 if result[j].name = headDevName then begin
1566 numHead := j;
1567
1568 //ZCMsgCallBackInterface.TextMessage('NAMENUMmaster = '+inttostr(numHead) + 'namemaster = ' + headDevName + ' = ' + result[j].name,TMWOHistoryOut);
1569 isHeadnum:=true;
1570 //устройства иногда могут использоватся на разных планах и иметь подчиненных
1571 //при обработке всех планов одно и тоже устройство может иметь несколько номеров в глобальном графе
1572 for tnum in result[j].LIndex do begin
1573 //ZCMsgCallBackInterface.TextMessage('tnum = '+inttostr(tnum) + 'numHeadDev = ' + headDevName + ' = ' + inttostr(numHeadDev),TMWOHistoryOut);
1574 if tnum = numHeadDev then
1575 isHeadnum:=false;
1576 end;
1577 if isHeadnum then
1578 result.mutable[j]^.LIndex.PushBack(numHeadDev);
1579 end;
1580
1581 if numHead < 0 then // если в списки устройства есть. Но нашего устройства нет, то добавляем его
1582 begin
1583 masterDevInfo:=TMasterDevice.Create;
1584 masterDevInfo.name:=headDevName;
1585 masterDevInfo.LIndex.PushBack(numHeadDev);
1586 masterDevInfo.shortName:='nil';
1587 pvd:=FindVariableInEnt(listVertexEdge.listVertex[numHeadDev].deviceEnt,'NMO_Suffix');
1588 if pvd<>nil then
1589 masterDevInfo.shortName:=pgdbstring(pvd^.data.Instance)^;
1590 result.PushBack(masterDevInfo);
1591 numHead:=result.Size-1;
1592 masterDevInfo:=nil;
1593 end;
1594
1595 //**работа по поиску и заполнению групп к головному устройству
1596 groupName:=listCableLaying[m].GroupNum;
1597 numHeadGroup:=-1;
1598 for j:=0 to result[numHead].LGroup.Size-1 do // ищем среди существующих групп нашу
1599 if result[numHead].LGroup[j].name = groupName then
1600 numHeadGroup:=j;
1601 if numHeadGroup<0 then //если нет то создаем новую группу в существующий список групп
1602 begin
1603 groupInfo:=TMasterDevice.TGroupInfo.Create;
1604 groupInfo.name:=groupName;
1605 infoSubDev.indexMaster:=numHeadDev;
1606 infoSubDev.indexSub:=i;
1607 infoSubDev.isVertexAdded:=false;
1608 //ZCMsgCallBackInterface.TextMessage('master = '+inttostr(infoSubDev.indexMaster)+' sub - ' + inttostr(infoSubDev.indexSub),TMWOHistoryOut);
1609
1610 groupInfo.LNumSubDevice.PushBack(infoSubDev);
1611 //HeadGroupInfo.listVertexTerminalBox:=nil;
1612 //HeadGroupInfo.listVertexWayGroup:=nil;
1613 //HeadGroupInfo.listVertexWayOnlyVertex:=nil;
1614 result.Mutable[numHead]^.LGroup.PushBack(groupInfo);
1615 numHeadGroup:=result[numHead].LGroup.Size-1;
1616 groupInfo:=nil;
1617 end
1618 else
1619 begin
1620 infoSubDev.indexMaster:=numHeadDev;
1621 infoSubDev.indexSub:=i;
1622 //ZCMsgCallBackInterface.TextMessage('master = '+inttostr(infoSubDev.indexMaster)+' sub - ' + inttostr(infoSubDev.indexSub),TMWOHistoryOut);
1623 infoSubDev.isVertexAdded:=false;
1624 result.mutable[numHead]^.LGroup.mutable[numHeadGroup]^.LNumSubDevice.PushBack(infoSubDev);
1625 end;
1626 end;
1627
1628 end;
1629 listCableLaying.Clear;
1630 end;
1631 end;
1632 end;
1633 end;
1634
1635
1636
1637
1638 //** Создание деревьев устройств
1639 procedure addNewTreeDevice(listVertexEdge:TGraphBuilder;globalGraph:TGraph;var listMasterDevice:TVectorOfMasterDevice);
1640 //type
1641 //tempuseVertex:Tvectorofinteger;
1642 var
1643 pvd:pvardesk; //для работы со свойствами устройств
1644 polyObj:PGDBObjPolyLine;
1645 i,j,k,m,n,counter1,counter2,counter3:integer;
1646 tIndex,tIndexLocal,tIndexGlobal:integer;
1647 EdgePath, VertexPath: TClassList;
1648 infoGTree:TGraph;
1649
1650 tempString:string;
1651 sumWeightPath,tempFloat: Float;
1652 tempLVertex:TvectorOfInteger;
1653 gg:GDBVertex;
1654
isVertexAddednull1655 function isVertexAdded(tempLVertex:tvectorofinteger;index:integer):boolean;
1656 var
1657 i:integer;
1658 begin
1659 result:=true;
1660 for i:=0 to tempLVertex.Size-1 do begin
1661 //ZCMsgCallBackInterface.TextMessage('ищем - ' + inttostr(tempLVertex[i])+' наш - ' + inttostr(index),TMWOHistoryOut);
1662 if tempLVertex[i]=index then begin
1663 result:=false;
1664 //ZCMsgCallBackInterface.TextMessage('совпало: ' + inttostr(tempLVertex[i])+' = ' + inttostr(index),TMWOHistoryOut);
1665 end;
1666 end;
1667 end;
1668
1669
getLengthnull1670 function getLength(listVertexEdge:TGraphBuilder;pt1,pt2:integer):Float;
1671 var
1672 i:integer;
1673 begin
1674 result:=-1;
1675 for i:=0 to listVertexEdge.listEdge.Size-1 do
1676 if ((listVertexEdge.listEdge[i].VIndex1=pt1) and (listVertexEdge.listEdge[i].VIndex2=pt2)) or
1677 ((listVertexEdge.listEdge[i].VIndex1=pt2) and (listVertexEdge.listEdge[i].VIndex2=pt1)) then
1678 result:=listVertexEdge.listEdge[i].edgeLength;
1679 end;
1680
getvGPGDBObjSuperLinenull1681 function getvGPGDBObjSuperLine(listVertexEdge:TGraphBuilder;pt1,pt2:integer):PGDBObjSuperLine;
1682 var
1683 i:integer;
1684 begin
1685 result:=nil;
1686 for i:=0 to listVertexEdge.listEdge.Size-1 do
1687 if ((listVertexEdge.listEdge[i].VIndex1=pt1) and (listVertexEdge.listEdge[i].VIndex2=pt2)) or
1688 ((listVertexEdge.listEdge[i].VIndex1=pt2) and (listVertexEdge.listEdge[i].VIndex2=pt1)) then
1689 result:=listVertexEdge.listEdge[i].cableEnt;
1690 end;
1691
getLocalIndexnull1692 function getLocalIndex(gTree:TGraph;indexGlobal:integer):LongInt;
1693 var
1694 i:integer;
1695 begin
1696 result:=-1;
1697 for i:=0 to gTree.VertexCount-1 do
1698 if gTree.Vertices[i].AsInt32[vGGIndex] = indexGlobal then
1699 result:=i;
1700 end;
1701
1702 //** Есть ли соединение данного устройства с данным номером головного устройства
1703 //** суть в том что одно и тоже устройство может быть на разных планах, это нужно для избежания ошибок связей
isHaveLineMasternull1704 function isHaveLineMaster(isMaster,isSub:integer):boolean;
1705 begin
1706 //ZCMsgCallBackInterface.TextMessage('isMaster : ' + inttostr(isMaster)+' - isSub - ' + inttostr(isSub),TMWOHistoryOut);
1707
1708 result:=true; // нет пути между головным устройством и подключаемым
1709 EdgePath:=TClassList.Create; //Создаем реберный путь
1710 VertexPath:=TClassList.Create; //Создаем вершиный путь
1711 //Получение ребер минимального пути в графе из одной точки в другую
1712 sumWeightPath:=globalGraph.FindMinWeightPath(globalGraph[isMaster], globalGraph[isSub], EdgePath);
1713 //Получение вершин минимального пути в графе на основе минимального пути в ребер, указывается из какой точки старт
1714 globalGraph.EdgePathToVertexPath(globalGraph[isMaster], EdgePath, VertexPath);
1715
1716 //Узнать существует уже граф если нет то создать его и добавляем начальную вершину
1717 if VertexPath.Count > 1 then
1718 result:=false; //путь есть между головным устройством и подключаемым
1719
1720 end;
1721
1722 begin
1723 for i:=0 to listMasterDevice.Size-1 do
1724 begin
1725 for j:=0 to listMasterDevice[i].LGroup.Size -1 do
1726 begin
1727 for n:=0 to listMasterDevice[i].LIndex.Size -1 do
1728 begin
1729
1730 //ZCMsgCallBackInterface.TextMessage('khfskldhfskdhflksdhflksdhflksdflkshd - ' + inttostr(n),TMWOHistoryOut);
1731 listMasterDevice.Mutable[i]^.LGroup.Mutable[j]^.groupTreeDev:=TGraph.Create;
1732 infoGTree:=listMasterDevice.Mutable[i]^.LGroup.Mutable[j]^.groupTreeDev;
1733 infoGTree.Features:=[Tree];
1734 //infoGTree.Root;
1735 infoGTree.CreateVertexAttr(vGGIndex, AttrInt32);
1736 infoGTree.CreateVertexAttr(vGIsDevice, AttrBool);
1737 infoGTree.CreateVertexAttr(vGInfoVertex, AttrString);
1738 infoGTree.CreateVertexAttr(vGPGDBObjDevice,AttrPointer); // добавили ссылку сразу на само устройство
1739
1740 infoGTree.CreateEdgeAttr(vGLength, AttrFloat64);
1741 infoGTree.CreateEdgeAttr(vGInfoEdge, AttrString);
1742 infoGTree.CreateEdgeAttr(vGPGDBObjSuperLine,AttrPointer); // добавили ссылку сразу на саму линию
1743
1744 //ZCMsgCallBackInterface.TextMessage('yfx Количство ребер - ' + inttostr(infoGTree.EdgeCount),TMWOHistoryOut);
1745 //ZCMsgCallBackInterface.TextMessage('yfx Количство вершин - ' + inttostr(infoGTree.VertexCount),TMWOHistoryOut);
1746
1747
1748 tempLVertex:=tvectorofinteger.create;
1749 //listMasterDevice[i].LGroup[j].LNumSubDevice;
1750 for k:=0 to listMasterDevice[i].LGroup[j].LNumSubDevice.Size-1 do
1751 begin
1752
1753 if isHaveLineMaster(listMasterDevice[i].LIndex[n],listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexSub) then
1754 continue;
1755
1756 EdgePath:=TClassList.Create; //Создаем реберный путь
1757 VertexPath:=TClassList.Create; //Создаем вершиный путь
1758 //Получение ребер минимального пути в графе из одной точки в другую
1759 sumWeightPath:=globalGraph.FindMinWeightPath(globalGraph[listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster], globalGraph[listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexSub], EdgePath);
1760 //Получение вершин минимального пути в графе на основе минимального пути в ребер, указывается из какой точки старт
1761 //ZCMsgCallBackInterface.TextMessage('master = '+inttostr(listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster)+' sub - ' + inttostr(listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexSub),TMWOHistoryOut);
1762
1763 globalGraph.EdgePathToVertexPath(globalGraph[listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster], EdgePath, VertexPath);
1764
1765 tIndexLocal:=-1; //промежуточная вершина для создание ребер графа
1766 tIndexGlobal:=-1; //промежуточная вершина для построения пути глобального графа
1767
1768 //ZCMsgCallBackInterface.TextMessage('количество - ' + inttostr(VertexPath.Count),TMWOHistoryOut);
1769
1770
1771
1772 //Узнать существует уже граф если нет то создать его и добавляем начальную вершину
1773 if infoGTree.VertexCount <= 0 then begin
1774 infoGTree.AddVertex;
1775 infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]:=listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster;
1776
1777 //Добавил ссылку на устройство
1778 infoGTree.Vertices[infoGTree.VertexCount-1].AsPointer[vGPGDBObjDevice]:=listVertexEdge.listVertex[listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster].deviceEnt;
1779
1780 if listVertexEdge.listVertex[listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster].deviceEnt <> nil then
1781 begin
1782 infoGTree.Vertices[infoGTree.VertexCount-1].AsBool[vGIsDevice]:=true;
1783 //tempString:='№';
1784 tempString:=inttostr(infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]);
1785 tempString+='\P';
1786 tempString+='dev';
1787 infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex]:=tempString;
1788 end
1789 else
1790 begin
1791 infoGTree.Vertices[infoGTree.VertexCount-1].AsBool[vGIsDevice]:=false;
1792 //tempString:='№';
1793 tempString:=inttostr(infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]);
1794 tempString+='\P';
1795 tempString+='nul';
1796 infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex]:=tempString;
1797 end;
1798 //infoGTree.Vertices[infoGTree.VertexCount-1].AsBool['isFork']:=false;
1799
1800 //ZCMsgCallBackInterface.TextMessage('РУУТ - ' + inttostr(infoGTree.VertexCount-1),TMWOHistoryOut);
1801
1802 infoGTree.Root:=infoGTree.Vertices[infoGTree.VertexCount-1];
1803 tempLVertex.PushBack(listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexMaster);
1804 end;
1805
1806
1807 //**Если граф уже начал построение
1808 if VertexPath.Count > 1 then
1809 for m:=VertexPath.Count - 1 downto 0 do begin
1810 // Добавляет цифрц ы центре каждого устройства
1811 // uzvtestdraw.testTempDrawText(listVertexEdge.listVertex[TVertex(VertexPath[m]).Index].centerPoint,inttostr(TVertex(VertexPath[m]).Index));
1812
1813
1814 //ZCMsgCallBackInterface.TextMessage('way - ' + inttostr(TVertex(VertexPath[m]).Index),TMWOHistoryOut);
1815
1816
1817 if isVertexAdded(tempLVertex,TVertex(VertexPath[m]).Index) then
1818 begin
1819 //ZCMsgCallBackInterface.TextMessage('отработка кода ',TMWOHistoryOut);
1820
1821 infoGTree.AddVertex;
1822 infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]:=TVertex(VertexPath[m]).Index;
1823
1824 //НОВОЕ! Добавил ссылку на устройство
1825 infoGTree.Vertices[infoGTree.VertexCount-1].AsPointer[vGPGDBObjDevice]:=listVertexEdge.listVertex[TVertex(VertexPath[m]).Index].deviceEnt;
1826
1827
1828 if listVertexEdge.listVertex[TVertex(VertexPath[m]).Index].deviceEnt <> nil then
1829 begin
1830 infoGTree.Vertices[infoGTree.VertexCount-1].AsBool[vGIsDevice]:=true;
1831 //tempString:='№';
1832 tempString:=inttostr(infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]);
1833 tempString+='\P';
1834 tempString+='dev';
1835 infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex]:=tempString;
1836 end
1837 else
1838 begin
1839 infoGTree.Vertices[infoGTree.VertexCount-1].AsBool[vGIsDevice]:=false;
1840 //tempString:='№';
1841 tempString:=inttostr(infoGTree.Vertices[infoGTree.VertexCount-1].AsInt32[vGGIndex]);
1842 tempString+='\P';
1843 tempString+='nul';
1844 infoGTree.Vertices[infoGTree.VertexCount-1].AsString[vGInfoVertex]:=tempString;
1845 end;
1846 //infoGTree.Vertices[infoGTree.VertexCount-1].AsBool['isFork']:=false;
1847
1848 tempLVertex.PushBack(TVertex(VertexPath[m]).Index);
1849
1850 if tIndexLocal < 0 then begin
1851 tIndexLocal:=infoGTree.VertexCount-1;
1852 tIndexGlobal:=TVertex(VertexPath[m]).Index;
1853 end
1854 else
1855 begin
1856 //ZCMsgCallBackInterface.TextMessage('edgeGlobal : ' + inttostr(tIndexGlobal)+' - ' + inttostr(TVertex(VertexPath[m]).index),TMWOHistoryOut);
1857 //ZCMsgCallBackInterface.TextMessage('edgelocal : ' + inttostr(tIndexLocal)+' - ' + inttostr(infoGTree.VertexCount-1),TMWOHistoryOut);
1858 infoGTree.AddEdge(infoGTree.Vertices[tIndexLocal],infoGTree.Vertices[infoGTree.VertexCount-1]);
1859
1860 //ZCMsgCallBackInterface.TextMessage('edgelength : ' + floattostr(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index)),TMWOHistoryOut);
1861 //tempFloat:=1*RoundTo(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index),-1);
1862 //tempFloat:=20;
1863 infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat64[vGLength]:=getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index);
1864 infoGTree.Edges[infoGTree.EdgeCount-1].AsString[vGInfoEdge]:='\\P L='+floattostr(RoundTo(infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat64[vGLength],-1))+'m';
1865 //ZCMsgCallBackInterface.TextMessage('edgedddddlength : ' + floattostr(infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat32[vGLength]) + ' - - - ' + floattostr(tempFloat),TMWOHistoryOut);
1866
1867
1868 //infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat32[vGLength]:=RoundTo(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index),-1);
1869 //infoGTree.Edges[infoGTree.EdgeCount-1].AsString[vGInfoEdge]:='\\P L='+floattostr(infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat32[vGLength])+'m';
1870 //ZCMsgCallBackInterface.TextMessage('edgelength : ' + floattostr(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index)) + ' - - - ' + floattostr(RoundTo(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index),-1)),TMWOHistoryOut);
1871 //ZCMsgCallBackInterface.TextMessage('edgelength : ' + floattostr(infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat32[vGLength]) + ' - округ - ' + infoGTree.Edges[infoGTree.EdgeCount-1].AsString[vGInfoEdge],TMWOHistoryOut);
1872
1873 tIndexLocal:=infoGTree.VertexCount-1;
1874 tIndexGlobal:=TVertex(VertexPath[m]).Index;
1875 end;
1876
1877 end
1878 else begin
1879 if tIndexLocal >= 0 then
1880 begin
1881 tIndex:=getLocalIndex(infoGTree,TVertex(VertexPath[m]).index);
1882 //ZCMsgCallBackInterface.TextMessage('edgeGlobal : ' + inttostr(tIndexGlobal)+' - ' + inttostr(TVertex(VertexPath[m]).index),TMWOHistoryOut);
1883 //ZCMsgCallBackInterface.TextMessage('edgelocal : ' + inttostr(tIndexLocal)+' - ' + inttostr(tIndex),TMWOHistoryOut);
1884 infoGTree.AddEdge(infoGTree.Vertices[tIndexLocal],infoGTree.Vertices[tIndex]);
1885
1886 //НОВОЕ!!!! Добавил ссылку на устройство
1887 infoGTree.Edges[infoGTree.EdgeCount-1].AsPointer[vGPGDBObjSuperLine]:=getvGPGDBObjSuperLine(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index);
1888
1889
1890 //ZCMsgCallBackInterface.TextMessage('edgelength : ' + floattostr(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index)),TMWOHistoryOut);
1891 infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat64[vGLength]:=getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index);
1892 infoGTree.Edges[infoGTree.EdgeCount-1].AsString[vGInfoEdge]:='\\P L='+floattostr(RoundTo(infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat64[vGLength],-1))+'m';
1893
1894 //ZCMsgCallBackInterface.TextMessage('edgelength : ' + floattostr(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index)) + ' - - - ' + floattostr(RoundTo(getlength(listVertexEdge,tIndexGlobal,TVertex(VertexPath[m]).Index),-1)),TMWOHistoryOut);
1895 //ZCMsgCallBackInterface.TextMessage('edgelength : ' + floattostr(infoGTree.Edges[infoGTree.EdgeCount-1].AsFloat32[vGLength]) + ' - округ - ' + infoGTree.Edges[infoGTree.EdgeCount-1].AsString[vGInfoEdge],TMWOHistoryOut);
1896
1897 tIndexLocal:=-1;
1898 tIndexGlobal:=-1;
1899 end;
1900 end;
1901 end;
1902
1903 EdgePath.Destroy;
1904 VertexPath.Destroy;
1905 end;
1906
1907 //ZCMsgCallBackInterface.TextMessage('Количство ребер - ' + inttostr(infoGTree.EdgeCount),TMWOHistoryOut);
1908 //ZCMsgCallBackInterface.TextMessage('Количство вершин - ' + inttostr(infoGTree.VertexCount),TMWOHistoryOut);
1909
1910 // Такая проверку нужна, тогда когда бывает что головное устройство на разных планах установлено
1911 // и может возникнуть ситуация когда на плане разные группы, что вызовит пустой граф
1912 //что бы не было проблем выполнена данная проверка
1913 if infoGTree.VertexCount > 0 then begin
1914 infoGTree.CorrectTree; //Делает дерево корректным, добавляет родителей детей
1915 listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.PushBack(infoGTree);
1916 end;
1917
1918 infoGTree:=nil;
1919 tempLVertex.Destroy;
1920 end;
1921 end;
1922 end;
1923 end;
1924
buildListAllConnectDeviceNewnull1925 function buildListAllConnectDeviceNew(listVertexEdge:TGraphBuilder;Epsilon:double; var listError:TListError):TVectorOfMasterDevice;
1926 var
1927
1928 globalGraph: TGraph;
1929 listMasterDevice:TVectorOfMasterDevice;
1930
1931 i,j,k: Integer;
1932
1933 gg:GDBVertex;
1934
1935
1936 //** Поиск существует ли устройства с нужным именем
isHaveDevicenull1937 function isHaveDevice(listVertex:TListDeviceLine;name:string):boolean;
1938 var
1939 i: Integer;
1940 pvd:pvardesk; //для работы со свойствами устройств
1941 begin
1942 result:=true;
1943 for i:=0 to listVertex.Size-1 do
1944 if listVertex[i].deviceEnt<>nil then
1945 begin
1946 pvd:=FindVariableInEnt(listVertex[i].deviceEnt,'NMO_Name');
1947 if pvd <> nil then
1948 if pgdbstring(pvd^.data.Instance)^ = name then
1949 result:= false;
1950 end;
1951 end;
1952
1953 begin
1954
1955 //Создаем граф на основе класса TGraphBuilder полученого при обработке устройств и суперлиний
1956 globalGraph:=TGraph.Create;
1957 globalGraph.Features:=[Weighted];
1958 globalGraph.AddVertices(listVertexEdge.listVertex.Size);
1959 for i:=0 to listVertexEdge.listEdge.Size-1 do
1960 begin
1961 globalGraph.AddEdges([listVertexEdge.listEdge[i].VIndex1, listVertexEdge.listEdge[i].VIndex2]);
1962 globalGraph.Edges[i].Weight:=listVertexEdge.listEdge[i].edgeLength;
1963 end;
1964
1965
1966 //**получаем список подключенных устройств к головным устройствам
1967 listMasterDevice:=getListMasterDevNew(listVertexEdge,globalGraph);
1968
1969 for i:=0 to listMasterDevice.Size-1 do
1970 begin
1971 ZCMsgCallBackInterface.TextMessage('мастер = '+ listMasterDevice[i].name,TMWOHistoryOut);
1972 ZCMsgCallBackInterface.TextMessage('мастер кол-во = '+ inttostr(listMasterDevice[i].LIndex.Size),TMWOHistoryOut);
1973 for j:=0 to listMasterDevice[i].LGroup.Size -1 do
1974 begin
1975 ZCMsgCallBackInterface.TextMessage('колво приборы = '+ inttostr(listMasterDevice[i].LGroup[j].LNumSubDevice.size),TMWOHistoryOut);
1976 for k:=0 to listMasterDevice[i].LGroup[j].LNumSubDevice.Size -1 do
1977 ZCMsgCallBackInterface.TextMessage('приборы = '+ inttostr(listMasterDevice[i].LGroup[j].LNumSubDevice[k].indexSub),TMWOHistoryOut);
1978 end;
1979 end;
1980
1981 //**Переробатываем список устройств подключенный к группам и на основе него создание сложное дерево усройств
1982 addNewTreeDevice(listVertexEdge,globalGraph,listMasterDevice);
1983
1984
1985 //
1986 // //**Переробатываем список устройств подключенный к группам и на основе него создание деревьев усройств
1987 //
1988 //
1989 // //**Переробатываем большой граф в упрощенный,для удобной визуализации
1990 // //addEasyTreeDevice(globalGraph,listMasterDevice);
1991 //
1992 // //**Добавляем к вершинам длины кабелей с конца, для правильной сортировки дерева по длине
1993 // addItemLengthFromEnd(listMasterDevice);
1994 //
1995 // ZCMsgCallBackInterface.TextMessage('*** Суперлиния - ' + listVertexEdge.nameSuperLine + ' - обработка выполнена! ***',TMWOHistoryOut);
1996 //
1997 // //visualGraph(listMasterDevice[0].LGroup[0].LTreeDev[0],gg,1) ;
1998 // //gg:=uzegeometry.CreateVertex(0,0,0);
1999 //
2000 // //visualAllTreesLMD(listMasterDevice,gg,1);
2001 //
2002 // for i:=0 to listMasterDevice.Size-1 do
2003 // begin
2004 // for j:=0 to listMasterDevice[i].LGroup.Size -1 do
2005 // begin
2006 // for k:=0 to listMasterDevice[i].LGroup[j].LTreeDev.Size -1 do begin
2007 // //visualGraph(listMasterDevice[i].LGroup[j].LTreeDev[k],gg,1);
2008 //
2009 // listMasterDevice.mutable[i]^.LGroup.mutable[j]^.LTreeDev.mutable[k]^.SortTree(listMasterDevice[i].LGroup[j].LTreeDev[k].Root,@SortTreeLengthComparer.Compare);
2010 //
2011 // //visualGraph(listMasterDevice[i].LGroup[j].LTreeDev[k],gg,1);
2012 // end;
2013 // end;
2014 //
2015 // end;
2016 //
2017 result:=listMasterDevice;
2018
2019 end;
2020
2021
2022 //Процедура создания списка ошибок
2023 procedure errorSearchList(ourGraph:TGraphBuilder;Epsilon:double;var listError:TListError;listSLname:TGDBlistSLname);
2024 type
2025 TListString=specialize TVector<string>;
2026 var
2027 EdgePath, VertexPath: TClassList;
2028 G: TGraph;
2029 headNum : integer;
2030
2031 counter,counter2,counter3,counterColor:integer; //счетчики
2032 i,j,k: Integer;
2033 T: Float;
2034
2035 headName,GroupNum,typeSLine,nameSL:string;
2036
2037 listStr1,listStr2,listStr3:TListString;
2038
2039 ///Получить список параметров устройства для подключения
getListParamDevnull2040 function getListParamDev(nowDev:PGDBObjDevice;nameType:string):TListString;
2041 var
2042 pvd:pvardesk; //для работы со свойствами устройств
2043 tempName,nameParam:gdbstring;
2044 begin
2045 result:=TListString.Create;
2046 pvd:=FindVariableInEnt(nowDev,nameType);
2047 if pvd<>nil then
2048 BEGIN
2049 tempName:=pgdbstring(pvd^.data.Instance)^;
2050 repeat
2051 GetPartOfPath(nameParam,tempName,';');
2052 result.PushBack(nameParam);
2053 until tempName='';
2054 end;
2055
2056 end;
2057 procedure addErrorinList(nowDev:PGDBObjDevice;var listError:TListError;textError:string);
2058 var
2059 pvd:pvardesk; //для работы со свойствами устройств
2060 //tempName,nameParam:gdbstring;
2061 errorInfo:TErrorInfo;
2062 //tempstring:string;
2063 isNotDev:boolean;
2064 i:integer;
2065 begin
2066 isNotDev:=true;
2067 for i:=0 to listError.Size-1 do
2068 begin
2069 if listError[i].device = nowDev then
2070 begin
2071 //tempstring := concat(errorInfo.text,textError);
2072 listError.Mutable[i]^.text := listError[i].text + textError;
2073 isNotDev:=false;
2074 end
2075 end;
2076 if isNotDev then
2077 begin
2078 //pvd:=FindVariableInEnt(nowDev,nameType);
2079 errorInfo.device := nowDev;
2080 errorInfo.name:=nowDev^.Name;
2081 errorInfo.text:=textError;
2082 listError.PushBack(errorInfo);
2083 end;
2084 end;
2085
2086 //** Поиск существует ли устройства с нужным именем
isHaveDevicenull2087 function isHaveDevice(listVertex:TListDeviceLine;name:string):boolean;
2088 var
2089 i: Integer;
2090 pvd:pvardesk; //для работы со свойствами устройств
2091 begin
2092 result:=true;
2093 for i:=0 to listVertex.Size-1 do
2094 begin
2095 if listVertex[i].deviceEnt<>nil then
2096 begin
2097 pvd:=FindVariableInEnt(listVertex[i].deviceEnt,'NMO_Name');
2098 if pvd <> nil then
2099 if pgdbstring(pvd^.data.Instance)^ = name then begin
2100 result:= false;
2101 end;
2102 end;
2103
2104 end;
2105 end;
2106
2107 begin
2108
2109 // Подключение созданного граффа к библиотеке Аграф
2110 G:=TGraph.Create;
2111 G.Features:=[Weighted];
2112 G.AddVertices(ourGraph.listVertex.Size);
2113 for k:=0 to ourGraph.listEdge.Size-1 do
2114 begin
2115 G.AddEdges([ourGraph.listEdge[k].VIndex1, ourGraph.listEdge[k].VIndex2]);
2116 G.Edges[k].Weight:=ourGraph.listEdge[k].edgeLength;
2117 end;
2118
2119 //смотрим все вершины
2120 for i:=0 to ourGraph.listVertex.Size-1 do
2121 begin
2122 //если это устройство и не разрыв
2123 if (ourGraph.listVertex[i].deviceEnt<>nil) and (ourGraph.listVertex[i].break<>true) then
2124 begin
2125 listStr1:=getListParamDev(ourGraph.listVertex[i].deviceEnt,'SLCABAGEN_HeadDeviceName');
2126 listStr2:=getListParamDev(ourGraph.listVertex[i].deviceEnt,'SLCABAGEN_NGHeadDevice');
2127 listStr3:=getListParamDev(ourGraph.listVertex[i].deviceEnt,'SLCABAGEN_SLTypeagen');
2128 if (listStr1.size = listStr2.size) and (listStr1.size = listStr3.size) and (listStr2.size = listStr3.size) then
2129 begin
2130 counter:=0;
2131 for j:=0 to listStr1.size-1 do
2132 begin
2133 headName:=listStr1[j]; //имя хозяина
2134 GroupNum:=listStr2[j]; //№ шлейфа
2135 typeSLine:=listStr3[j]; //название трассы
2136 for nameSL in listSLname do
2137 if typeSLine = nameSL then
2138 inc(counter);
2139 end;
2140 if listStr1.size<>counter then
2141 addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Не правильное имя типа трассы *суперлинии* ');
2142
2143 counter:=0;
2144 for j:=0 to listStr1.size-1 do
2145 begin
2146 headName:=listStr1[j]; //имя хозяина
2147 GroupNum:=listStr2[j]; //№ шлейфа
2148 typeSLine:=listStr3[j]; //название трассы
2149 //isHaveDevice
2150 if isHaveDevice(ourGraph.listVertex,headName) then
2151 addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Одно из имен головного устройства не правильное');
2152 end;
2153
2154 for j:=0 to listStr1.size-1 do
2155 begin
2156 headName:=listStr1[j]; //имя хозяина
2157 GroupNum:=listStr2[j]; //№ шлейфа
2158 typeSLine:=listStr3[j]; //название трассы
2159 //for nameSL in listSLname do
2160 // begin
2161 if typeSLine = ourGraph.nameSuperLine then
2162 begin
2163 headNum:=getNumHeadDevice(ourGraph.listVertex,headName,G,i);
2164 if headNum >= 0 then begin
2165
2166 //работа с библиотекой Аграф
2167 EdgePath:=TClassList.Create; //Создаем реберный путь
2168 VertexPath:=TClassList.Create; //Создаем вершиный путь
2169
2170 // Получение ребер минимального пути в графи из одной точки в другую
2171 T:=G.FindMinWeightPath(G[headNum], G[i], EdgePath);
2172 // Получение вершин минимального пути в графи на основе минимального пути в ребер, указывается из какой точки старт
2173 G.EdgePathToVertexPath(G[headNum], EdgePath, VertexPath);
2174
2175 if VertexPath.Count <= 1 then
2176 addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Нет пути до головного устройства');
2177
2178 EdgePath.Free;
2179 VertexPath.Free;
2180 end
2181 else
2182 begin
2183 addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Головное устройство с таким именем отсутствует');
2184 //else
2185 // addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Нет пути до головного устройства');
2186 end;
2187 end;
2188 end;
2189
2190 end
2191 else
2192 addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Не одинаковое количество параметров в настройках');
2193
2194 end;
2195 end;
2196 end;
2197
2198 //Процедура создания списка ошибок
2199 procedure errorList(allGraph:TListAllGraph;Epsilon:double;var listError:TListError;listSLname,listAllSLname:TGDBlistSLname);
2200 type
2201 TListString=specialize TVector<string>;
2202 var
2203 EdgePath, VertexPath: TClassList;
2204 G: TGraph;
2205 headNum : integer;
2206
2207 counter,counter2,counter3,counterColor:integer; //счетчики
2208 i,j,k: Integer;
2209 T: Float;
2210
2211 headName,GroupNum,typeSLine,nameSL:string;
2212
2213 listStr1,listStr2,listStr3:TListString;
2214
2215 ourGraph:TGraphBuilder;
2216 graphBuilderInfo:TListGraphBuilder;
2217 ///Получить список параметров устройства для подключения
getListParamDevnull2218 function getListParamDev(nowDev:PGDBObjDevice;nameType:string):TListString;
2219 var
2220 pvd:pvardesk; //для работы со свойствами устройств
2221 tempName,nameParam:gdbstring;
2222 begin
2223 result:=TListString.Create;
2224 pvd:=FindVariableInEnt(nowDev,nameType);
2225 if pvd<>nil then
2226 BEGIN
2227 tempName:=pgdbstring(pvd^.data.Instance)^;
2228 repeat
2229 GetPartOfPath(nameParam,tempName,';');
2230 result.PushBack(nameParam);
2231 until tempName='';
2232 end;
2233
2234 end;
2235 procedure addErrorinList(nowDev:PGDBObjDevice;var listError:TListError;textError:string);
2236 var
2237 pvd:pvardesk; //для работы со свойствами устройств
2238 //tempName,nameParam:gdbstring;
2239 errorInfo:TErrorInfo;
2240 //tempstring:string;
2241 isNotDev:boolean;
2242 i:integer;
2243 begin
2244 isNotDev:=true;
2245 for i:=0 to listError.Size-1 do
2246 begin
2247 if listError[i].device = nowDev then
2248 begin
2249 //tempstring := concat(errorInfo.text,textError);
2250 listError.Mutable[i]^.text := listError[i].text + textError;
2251 isNotDev:=false;
2252 end
2253 end;
2254 if isNotDev then
2255 begin
2256 //pvd:=FindVariableInEnt(nowDev,nameType);
2257 errorInfo.device := nowDev;
2258 errorInfo.name:=nowDev^.Name;
2259 errorInfo.text:=textError;
2260 listError.PushBack(errorInfo);
2261 end;
2262 end;
2263
2264 //** Поиск существует ли устройства с нужным именем
isHaveDevicenull2265 function isHaveDevice(listVertex:TListDeviceLine;name:string):boolean;
2266 var
2267 i: Integer;
2268 pvd:pvardesk; //для работы со свойствами устройств
2269 begin
2270 result:=true;
2271 for i:=0 to listVertex.Size-1 do
2272 begin
2273 if listVertex[i].deviceEnt<>nil then
2274 begin
2275 pvd:=FindVariableInEnt(listVertex[i].deviceEnt,'NMO_Name');
2276 if pvd <> nil then
2277 if pgdbstring(pvd^.data.Instance)^ = name then begin
2278 result:= false;
2279 end;
2280 end;
2281
2282 end;
2283 end;
getNumHeadDevnull2284 function getNumHeadDev(listVertex:TListDeviceLine;name:string;G:TGraph;numDev:integer):integer;
2285 var
2286 i: Integer;
2287 pvd:pvardesk; //для работы со свойствами устройств
2288 T: Float;
2289 EdgePath, VertexPath: TClassList;
2290 begin
2291 result:=-2;
2292 for i:=0 to listVertex.Size-1 do
2293 begin
2294 if listVertex[i].deviceEnt<>nil then
2295 begin
2296 pvd:=FindVariableInEnt(listVertex[i].deviceEnt,'NMO_Name');
2297 if pvd <> nil then
2298 if pgdbstring(pvd^.data.Instance)^ = name then begin
2299 //result:=-1;
2300
2301 //работа с библиотекой Аграф
2302 EdgePath:=TClassList.Create; //Создаем реберный путь
2303 VertexPath:=TClassList.Create; //Создаем вершиный путь
2304
2305 // Получение ребер минимального пути в графи из одной точки в другую
2306 T:=G.FindMinWeightPath(G[i], G[numDev], EdgePath);
2307 // Получение вершин минимального пути в графи на основе минимального пути в ребер, указывается из какой точки старт
2308 G.EdgePathToVertexPath(G[i], EdgePath, VertexPath);
2309
2310 if VertexPath.Count > 1 then
2311 result:= i;
2312
2313 EdgePath.Free;
2314 VertexPath.Free;
2315 end;
2316 end;
2317
2318 end;
2319 end;
2320
2321 begin
2322 //Проверяем параметры заполненость параметров во Всех устройствах//
2323
2324 ourGraph:=allGraph[0].graph;
2325 for i:=0 to ourGraph.listVertex.Size-1 do
2326 begin
2327 //если это устройство и не разрыв
2328 if (ourGraph.listVertex[i].deviceEnt<>nil) and (ourGraph.listVertex[i].break<>true) then
2329 begin
2330 listStr1:=getListParamDev(ourGraph.listVertex[i].deviceEnt,'SLCABAGEN_HeadDeviceName');
2331 listStr2:=getListParamDev(ourGraph.listVertex[i].deviceEnt,'SLCABAGEN_NGHeadDevice');
2332 listStr3:=getListParamDev(ourGraph.listVertex[i].deviceEnt,'SLCABAGEN_SLTypeagen');
2333 if (listStr1.size = listStr2.size) and (listStr1.size = listStr3.size) and (listStr2.size = listStr3.size) then
2334 begin
2335 counter:=0;
2336 for j:=0 to listStr1.size-1 do
2337 begin
2338 headName:=listStr1[j]; //имя хозяина
2339 GroupNum:=listStr2[j]; //№ шлейфа
2340 typeSLine:=listStr3[j]; //название трассы
2341 for nameSL in listAllSLname do
2342 if typeSLine = nameSL then
2343 inc(counter);
2344 end;
2345 if listStr1.size<>counter then
2346 addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Не правильное имя типа трассы *суперлинии* ');
2347
2348 end
2349 else
2350 addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Не одинаковое количество параметров в настройках');
2351 end;
2352 end;
2353
2354 //** Проверяем подключены устройства к головному устройствам, возможность проложить трассу
2355 for graphBuilderInfo in allGraph do
2356 begin
2357 ourGraph:=graphBuilderInfo.graph;
2358 // Подключение созданного граффа к библиотеке Аграф
2359 G:=TGraph.Create;
2360 G.Features:=[Weighted];
2361 G.AddVertices(ourGraph.listVertex.Size);
2362 for k:=0 to ourGraph.listEdge.Size-1 do
2363 begin
2364 G.AddEdges([ourGraph.listEdge[k].VIndex1, ourGraph.listEdge[k].VIndex2]);
2365 G.Edges[k].Weight:=ourGraph.listEdge[k].edgeLength;
2366 end;
2367
2368 //смотрим все вершины
2369 for i:=0 to ourGraph.listVertex.Size-1 do
2370 begin
2371 //если это устройство и не разрыв
2372 if (ourGraph.listVertex[i].deviceEnt<>nil) and (ourGraph.listVertex[i].break<>true) then
2373 begin
2374 listStr1:=getListParamDev(ourGraph.listVertex[i].deviceEnt,'SLCABAGEN_HeadDeviceName');
2375 listStr2:=getListParamDev(ourGraph.listVertex[i].deviceEnt,'SLCABAGEN_NGHeadDevice');
2376 listStr3:=getListParamDev(ourGraph.listVertex[i].deviceEnt,'SLCABAGEN_SLTypeagen');
2377 if (listStr1.size = listStr2.size) and (listStr1.size = listStr3.size) and (listStr2.size = listStr3.size) then
2378 begin
2379 for j:=0 to listStr1.size-1 do
2380 begin
2381 headName:=listStr1[j]; //имя хозяина
2382 GroupNum:=listStr2[j]; //№ шлейфа
2383 typeSLine:=listStr3[j]; //название трассы
2384 //for nameSL in listSLname do
2385 // begin
2386
2387 if isHaveDevice(ourGraph.listVertex,headName) then begin
2388 addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Одно из имен головного устройства не правильное');
2389 continue;
2390 end;
2391
2392
2393 if typeSLine = ourGraph.nameSuperLine then
2394 begin
2395
2396 headNum:=getNumHeadDev(ourGraph.listVertex,headName,G,i);
2397 //ZCMsgCallBackInterface.TextMessage('*** УРРРРА ***' + inttostr(headNum),TMWOHistoryOut);
2398 //ZCMsgCallBackInterface.TextMessage('*** УРРРРА ***' + inttostr(headNum),TMWOHistoryOut);
2399
2400 if headNum < 0 then begin
2401 addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Нет пути до головного устройства');
2402 // //работа с библиотекой Аграф
2403 // EdgePath:=TClassList.Create; //Создаем реберный путь
2404 // VertexPath:=TClassList.Create; //Создаем вершиный путь
2405 //
2406 // // Получение ребер минимального пути в графи из одной точки в другую
2407 // T:=G.FindMinWeightPath(G[headNum], G[i], EdgePath);
2408 // // Получение вершин минимального пути в графи на основе минимального пути в ребер, указывается из какой точки старт
2409 // G.EdgePathToVertexPath(G[headNum], EdgePath, VertexPath);
2410 //
2411 // if VertexPath.Count <= 1 then
2412 // addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Нет пути до головного устройства');
2413 //
2414 // EdgePath.Free;
2415 // VertexPath.Free;
2416 end;
2417 ////else
2418 ////begin
2419 //// addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Головное устройство с таким именем отсутствует');
2420 //// //else
2421 //// // addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Нет пути до головного устройства');
2422 ////end;
2423 end;
2424 end;
2425
2426 end
2427 else
2428 addErrorinList(ourGraph.listVertex[i].deviceEnt,listError,'Не одинаковое количество параметров в настройках');
2429
2430 end;
2431 end;
2432 end;
2433 end;
2434
2435
TestgraphUses_comnull2436 function TestgraphUses_com(operands:TCommandOperands):TCommandResult;
2437 var
2438 G: TGraph;
2439 EdgePath, VertexPath: TClassList;
2440 I: Integer;
2441 T: Float;
2442 begin
2443 ZCMsgCallBackInterface.TextMessage('*** Min Weight Path ***',TMWOHistoryOut);
2444 // writeln('*** Min Weight Path ***');
2445 G:=TGraph.Create;
2446 G.Features:=[Weighted];
2447 EdgePath:=TClassList.Create;
2448 VertexPath:=TClassList.Create;
2449 try
2450 G.AddVertices(7);
2451 G.AddEdges([0, 2, 0, 3, 0, 4, 0, 5, 1, 2, 1, 3, 1, 5, 2, 4, 3, 4,
2452 5, 6]);
2453 G.Edges[0].Weight:=11;
2454 G.Edges[1].Weight:=7;
2455 G.Edges[2].Weight:=2;
2456 G.Edges[3].Weight:=12;
2457 G.Edges[4].Weight:=2;
2458 G.Edges[5].Weight:=3;
2459 G.Edges[6].Weight:=2;
2460 G.Edges[7].Weight:=1;
2461 G.Edges[8].Weight:=2;
2462 G.Edges[9].Weight:=4;
2463
2464 ZCMsgCallBackInterface.TextMessage(IntToStr(G.VertexCount) + '-вершин до удаления ',TMWOHistoryOut);
2465 ZCMsgCallBackInterface.TextMessage(IntToStr(G.EdgeCount) + '-ребер до удаления ',TMWOHistoryOut);
2466
2467 G.Vertices[4].Destroy;
2468
2469
2470 ZCMsgCallBackInterface.TextMessage(IntToStr(G.VertexCount) + '-вершин после удаления ',TMWOHistoryOut);
2471 ZCMsgCallBackInterface.TextMessage(IntToStr(G.EdgeCount) + '-ребер после удаления ',TMWOHistoryOut);
2472
2473 for I:=0 to G.VertexCount - 1 do
2474 ZCMsgCallBackInterface.TextMessage(IntToStr(I) + '-вершина ',TMWOHistoryOut);
2475
2476 ZCMsgCallBackInterface.TextMessage(' ***Ребра между вершинами*** ',TMWOHistoryOut);
2477 for I:=0 to G.EdgeCount - 1 do begin
2478 ZCMsgCallBackInterface.TextMessage(IntToStr(I) + '- соединение ' + IntToStr(G.Edges[I].V1.Index) + ' - ' + IntToStr(G.Edges[I].V2.Index) + ' = ' + floattostr(G.Edges[I].Weight),TMWOHistoryOut);
2479 end;
2480
2481
2482
2483 T:=G.FindMinWeightPath(G.Vertices[0], G.Vertices[2], EdgePath);
2484
2485 if T <> 11 then begin
2486 ZCMsgCallBackInterface.TextMessage('*** Error! ***',TMWOHistoryOut);
2487 // write('Error!');
2488 // readln;
2489 Exit;
2490 end;
2491 ZCMsgCallBackInterface.TextMessage('Minimal Length: ',TMWOHistoryOut);
2492 //writeln('Minimal Length: ', T :4:2);
2493 G.EdgePathToVertexPath(G[0], EdgePath, VertexPath);
2494 ZCMsgCallBackInterface.TextMessage('Vertices: ',TMWOHistoryOut);
2495 //write('Vertices: ');
2496 for I:=0 to VertexPath.Count - 1 do
2497 ZCMsgCallBackInterface.TextMessage(IntToStr(TVertex(VertexPath[I]).Index) + ' ',TMWOHistoryOut);
2498 //writeln;
2499 finally
2500 G.Free;
2501 EdgePath.Free;
2502 VertexPath.Free;
2503 end;
2504 result:=cmd_ok;
2505 end;
TestTREEUses_comnull2506 function TestTREEUses_com(operands:TCommandOperands):TCommandResult;
2507 var
2508 G: TGraph;
2509 EdgePath, VertexPath: TClassList;
2510 //I: Integer;
2511 //T: Float;
2512 procedure ShowPath(const CorrectPath: array of Integer);
2513 var
2514 I: Integer;
2515 begin
2516 for I:=0 to VertexPath.Count - 1 do
2517 if TVertex(VertexPath[I]).Index <> CorrectPath[I] then begin
2518 ZCMsgCallBackInterface.TextMessage('Error!' + inttostr(TVertex(VertexPath[I]).Index),TMWOHistoryOut);
2519 //write('Error!');
2520 //readln;
2521 //Exit;
2522 end;
2523 for I:=0 to VertexPath.Count - 1 do
2524 ZCMsgCallBackInterface.TextMessage(inttostr(TVertex(VertexPath[I]).Index) + ' ',TMWOHistoryOut);
2525 //write(TVertex(VertexPath[I]).Index, ' ');
2526 //writeln;
2527 end;
2528 begin
2529
2530 ZCMsgCallBackInterface.TextMessage('*** tree Path ***',TMWOHistoryOut);
2531 G:=TGraph.Create;
2532 VertexPath:=TClassList.Create;
2533 try
2534 G.Features:=[Tree];
2535 G.CreateVertexAttr('t', AttrBool);
2536 G.Root:=G.AddVertex;
2537 With G.Root do begin
2538 With AddChild do begin
2539 With AddChild do begin
2540 AddChild.AsBool['t']:=True;
2541 AddChild;
2542 end;
2543 AddChild;
2544 AddChild.AddChild;
2545 end;
2546 AddChild;
2547 end;
2548 if G.IsTree then
2549 ZCMsgCallBackInterface.TextMessage('граф дерево',TMWOHistoryOut)
2550 else
2551 ZCMsgCallBackInterface.TextMessage('граф не дерево',TMWOHistoryOut);
2552 G.CorrectTree;
2553
2554 if G.IsTree then
2555 ZCMsgCallBackInterface.TextMessage('граф дерево',TMWOHistoryOut)
2556 else
2557 ZCMsgCallBackInterface.TextMessage('граф не дерево',TMWOHistoryOut) ;
2558
2559 G.TreeTraversal(G.Root, VertexPath);
2560 ShowPath([0, 1, 3, 2, 4, 5, 6, 7, 8]);
2561 //G.ArrangeTree(G.Root, TAttrSet.CompareUser, TAttrSet.CompareUser);
2562 //G.SortTree(G.Root,@DummyComparer.Compare);
2563 G.TreeTraversal(G.Root, VertexPath);
2564 ShowPath([0, 8, 1, 5, 6, 7, 2, 4, 3]);
2565
2566
2567 //// writeln('*** Min Weight Path ***');
2568 // G:=TGraph.Create;
2569 // G.Features:=[Tree];
2570 // EdgePath:=TClassList.Create;
2571 // VertexPath:=TClassList.Create;
2572 // try
2573 // G.AddVertices(10);
2574 // G.AddEdges([0, 2, 0, 3, 0, 1, 1, 4, 2, 5, 2, 6, 5, 7, 5, 8,
2575 // 6, 9]);
2576 // //G.Edges[0].Weight:=5;
2577 // //G.Edges[1].Weight:=7;
2578 // //G.Edges[2].Weight:=2;
2579 // //G.Edges[3].Weight:=12;
2580 // //G.Edges[4].Weight:=2;
2581 // //G.Edges[5].Weight:=3;
2582 // //G.Edges[6].Weight:=2;
2583 // //G.Edges[7].Weight:=1;
2584 // //G.Edges[8].Weight:=2;
2585 // //G.Edges[9].Weight:=4;
2586 // //T:=G.FindMinWeightPath(G[0], G[6], EdgePath);
2587 //
2588 // //if T <> 11 then begin
2589 // // ZCMsgCallBackInterface.TextMessage('*** Error! ***',TMWOHistoryOut);
2590 // // // write('Error!');
2591 // // // readln;
2592 // // Exit;
2593 // //end;
2594 // //ZCMsgCallBackInterface.TextMessage('Minimal Length: 'G.,TMWOHistoryOut);
2595 // //writeln('Minimal Length: ', T :4:2);
2596 // //G.EdgePathToVertexPath(G[0], EdgePath, VertexPath);
2597 // ZCMsgCallBackInterface.TextMessage('Vertices: ',TMWOHistoryOut);
2598 // //write('Vertices: ');
2599 // for I:=0 to VertexPath.Count - 1 do
2600 // ZCMsgCallBackInterface.TextMessage(IntToStr(TVertex(VertexPath[I]).Index) + ' ',TMWOHistoryOut);
2601 // //writeln;
2602 finally
2603 G.Free;
2604 //EdgePath.Free;
2605 VertexPath.Free;
2606 end;
2607 result:=cmd_ok;
2608 end;
2609
2610
2611
TDummyComparer.Comparenull2612 function TDummyComparer.Compare (Edge1, Edge2: Pointer): Integer;
2613 var
2614 e1,e2:TAttrSet;
2615 begin
2616 result:=0;
2617 e1:=TAttrSet(Edge1);
2618 e2:=TAttrSet(Edge2);
2619
2620 ZCMsgCallBackInterface.TextMessage('sssssssssssssss'+e1.ClassName,TMWOHistoryOut);
2621 //ZCMsgCallBackInterface.TextMessage('xxxxxxssssss'+e1.AsString[vGInfoEdge],TMWOHistoryOut);
2622 //Edge1
2623 //ZCMsgCallBackInterface.TextMessage(floattostr(e1.AsFloat32['tt']) + ' сравниваем ' + floattostr(e2.AsFloat32['tt']),TMWOHistoryOut);
2624 // ZCMsgCallBackInterface.TextMessage(floattostr(e2.AsFloat32[vGLength]) + ' ',TMWOHistoryOut);
2625
2626 //e1.GetAsFloat32
2627
2628 //if e1.ClassName; AsFloat32['lengthfrombegin'] <> nil then
2629 // if e1.AsFloat32['lengthfrombegin'] > e2.AsFloat32['lengthfrombegin'] then
2630 // result:=1
2631 // else
2632 // result:=-1;
2633
2634 {if e1.AsFloat32['tt'] <> e2.AsFloat32['tt'] then
2635 if e1.AsFloat32['tt'] > e2.AsFloat32['tt'] then
2636 result:=1
2637 else
2638 result:=-1;}
2639
2640 //тут e1 и e2 надо както сравнить по какомуто критерию и вернуть -1 0 1
2641 //в зависимости что чего меньше-больше
2642 end;
CompareEdgesnull2643 function TDummyComparer.CompareEdges (Edge1, Edge2: Pointer): Integer;
2644 var
2645 e1,e2:TAttrSet;
2646 begin
2647 ////result:=1;
2648 //e1:=TAttrSet(Edge1);
2649 //e2:=TAttrSet(Edge2);
2650 //
2651 ZCMsgCallBackInterface.TextMessage('hhhhhhhhhhhhhhhhhhhhhhhttttttttttttttttttttt,,,,hj',TMWOHistoryOut);
2652 //ZCMsgCallBackInterface.TextMessage('xxxxxxssssss'+e1.AsString[vGInfoEdge],TMWOHistoryOut);
2653 //Edge1
2654 //ZCMsgCallBackInterface.TextMessage(floattostr(e1.AsFloat32['tt']) + ' сравниваем ' + floattostr(e2.AsFloat32['tt']),TMWOHistoryOut);
2655 // ZCMsgCallBackInterface.TextMessage(floattostr(e2.AsFloat32[vGLength]) + ' ',TMWOHistoryOut);
2656
2657 //e1.GetAsFloat32
2658
2659 //if e1.ClassName; AsFloat32['lengthfrombegin'] <> nil then
2660 // if e1.AsFloat32['lengthfrombegin'] > e2.AsFloat32['lengthfrombegin'] then
2661 // result:=1
2662 // else
2663 // result:=-1;
2664
2665 {if e1.AsFloat32['tt'] <> e2.AsFloat32['tt'] then
2666 if e1.AsFloat32['tt'] > e2.AsFloat32['tt'] then
2667 result:=1
2668 else
2669 result:=-1;}
2670
2671 //тут e1 и e2 надо както сравнить по какомуто критерию и вернуть -1 0 1
2672 //в зависимости что чего меньше-больше
2673 end;
2674
2675
2676 initialization
2677 //CreateCommandFastObjectPlugin(@NumPsIzvAndDlina_com,'test111',CADWG,0);
2678 CreateCommandFastObjectPlugin(@TestgraphUses_com,'test454',CADWG,0);
2679 //CreateCommandFastObjectPlugin(@TestTREEUses_com2,'test333',CADWG,0);
2680 DummyComparer:=TDummyComparer.Create;
2681 finalization
2682 DummyComparer.free;
2683 end.
2684
2685