프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / ID2PSN / PSN.cs @ 8487ecb2

이력 | 보기 | 이력해설 | 다운로드 (41.4 KB)

1
using System;
2
using System.Collections.Generic;
3
using System.Data;
4
using System.IO;
5
using System.Linq;
6
using System.Text;
7
using System.Threading.Tasks;
8

    
9
namespace ID2PSN
10
{
11
    public enum PSNType
12
    {
13
        None,
14
        Branch,
15
        Equipment,
16
        Header,
17
        Symbol,
18
        OPC,
19
    }
20

    
21
    public class PSN
22
    {
23
        private double[] DrawingSize = null;
24
        private double DrawingWidth = double.NaN;
25
        private double DrawingHeight = double.NaN;
26
        public int Revision;
27
        public DataTable PathItems { get; set; }
28
        public DataTable SequenceData { get; set; }
29
        public DataTable PipeSystemNetwork { get; set; }
30
        public DataTable Equipment { get; set; }
31
        public DataTable Nozzle { get; set; }
32

    
33
        List<Document> Documents;
34
        List<Group> groups = new List<Group>();
35
        List<PSNItem> PSNItems = new List<PSNItem>();
36
        List<Topology> Topologies = new List<Topology>();
37

    
38
        DataTable opcDT = null;
39
        DataTable topologyRuleDT = null;
40

    
41
        const string FluidPriorityType = "FLUIDCODE";
42
        const string PipingMaterialsPriorityType = "PIPINGMATERIALSCLASS";
43

    
44
        public PSN()
45
        {
46
            
47
        }
48

    
49
        public PSN(List<Document> documents, int Revision)
50
        {
51
            Documents = documents;
52
            foreach (Document document in Documents)
53
                groups.AddRange(document.Groups);
54
            opcDT = GetOPCInfo();
55
            topologyRuleDT = GetTopologyRule();
56
            this.Revision = Revision;
57
            DrawingSize = DB.GetDrawingSize();
58
            DrawingWidth = DrawingSize[2] - DrawingSize[0];
59
            DrawingHeight = DrawingSize[3] - DrawingSize[1];
60
        }
61

    
62
        public void SetPSNData()
63
        {
64
            SetTopologyData();
65
            ConnectByOPC();
66
            SetPSNItem();
67
            SetPSNType();
68
            SetBranchInfo();
69
            SetTopology();
70

    
71
            SaveNozzleAndEquipment();
72
            SavePSNData();
73
        }
74
        private void SetTopologyData()
75
        {
76
            foreach (Document document in Documents)
77
            {
78
                foreach (Item item in document.Items)
79
                {
80
                    item.TopologyData = string.Empty;
81
                    item.PSNPipeLineID = string.Empty;
82
                    LineNumber lineNumber = document.LineNumbers.Find(x => x.UID == item.Owner);
83
                    if (lineNumber != null)
84
                    {
85
                        item.LineNumber = lineNumber;
86

    
87
                        foreach (DataRow row in topologyRuleDT.Rows)
88
                        {
89
                            string uid = row["UID"].ToString();
90
                            if (uid == "-")
91
                                item.TopologyData += "-"; 
92
                            else
93
                            {
94
                                Attribute itemAttr = item.Attributes.Find(x => x.Name == uid);
95

    
96
                                Attribute attribute = lineNumber.Attributes.Find(x => x.Name == uid);
97
                                if (attribute != null)
98
                                    item.TopologyData += attribute.Value;
99
                            }
100
                        }
101

    
102
                        Attribute insulAttr = item.LineNumber.Attributes.Find(x => x.Name == "InsulationPurpose");
103
                        if (!string.IsNullOrEmpty(insulAttr.Value))
104
                            item.PSNPipeLineID = item.TopologyData + "-" + insulAttr.Value;
105
                        else
106
                            item.PSNPipeLineID = item.TopologyData;
107
                    }
108
                }
109
            }
110

    
111

    
112
        }
113
        private void ConnectByOPC()
114
        {
115
            foreach (Group group in groups.FindAll(x => x.Items.Last().SubItemType == SubItemType.OPC))
116
            {
117
                Item opcItem = group.Items.Last();
118
                DataRow[] fromRows = opcDT.Select(string.Format("FromOPCUID = '{0}'", opcItem.UID));
119
                if (fromRows.Length.Equals(1))
120
                {
121
                    DataRow opcRow = fromRows.First();
122
                    string toDrawing = opcRow["ToDrawing"].ToString();
123
                    string toOPCUID = opcRow["ToOPCUID"].ToString();
124

    
125
                    Document toDocument = Documents.Find(x => x.DrawingName == toDrawing);
126
                    Group toGroup = toDocument.Groups.Find(x => x.Items.Find(y => y.UID == toOPCUID) != null);
127
                    group.EndGroup = toGroup;
128
                    toGroup.StartGroup = group;
129
                }
130
            }
131
        }
132
        private void SetPSNItem()
133
        {
134
            Dictionary<Group, string> groupDic = new Dictionary<Group, string>(); 
135
            foreach (Group group in groups)
136
                groupDic.Add(group, Guid.NewGuid().ToString());
137

    
138
            foreach (Group group in groups)
139
            {
140
                string groupKey = groupDic[group];
141
                if (group.StartGroup != null)
142
                {
143
                    string otherKey = groupDic[group.StartGroup];
144
                    ChangeGroupID(otherKey, groupKey);
145
                }
146
            }
147

    
148
            // PSN 정리
149
            foreach (var item in groupDic)
150
            {
151
                Group group = item.Key;
152
                string uid = item.Value;
153
                PSNItem PSNItem = PSNItems.Find(x => x.UID == uid);
154
                if (PSNItem == null)
155
                {
156
                    PSNItem = new PSNItem(PSNItems.Count, Revision) { UID = uid };
157
                    PSNItems.Add(PSNItem);
158
                }
159
                PSNItem.Groups.Add(group);
160
            }
161

    
162
            // Sort PSN
163
            foreach (PSNItem PSNItem in PSNItems)
164
            {
165
                List<Group> _groups = new List<Group>();
166

    
167
                Stack<Group> stacks = new Stack<Group>();
168
                stacks.Push(PSNItem.Groups.First());
169
                while (stacks.Count > 0)
170
                {
171
                    Group stack = stacks.Pop();
172
                    if (_groups.Contains(stack))
173
                        continue;
174

    
175
                    if (_groups.Count == 0)
176
                        _groups.Add(stack);
177
                    else
178
                    {
179
                        if (stack.StartGroup != null && _groups.Contains(stack.StartGroup))
180
                        {
181
                            int index = _groups.IndexOf(stack.StartGroup);
182
                            _groups.Insert(index + 1, stack);
183
                        }
184
                        else if (stack.EndGroup != null && _groups.Contains(stack.EndGroup))
185
                        {
186
                            int index = _groups.IndexOf(stack.EndGroup);
187
                            _groups.Insert(index, stack);
188
                        }
189
                    }
190

    
191
                    if (stack.StartGroup != null)
192
                        stacks.Push(stack.StartGroup);
193
                    if (stack.EndGroup != null)
194
                        stacks.Push(stack.EndGroup);
195
                }
196

    
197
                PSNItem.Groups.Clear();
198
                PSNItem.Groups.AddRange(_groups);
199
            }
200

    
201

    
202
            void ChangeGroupID(string from, string to)
203
            {
204
                if (from.Equals(to))
205
                    return;
206

    
207
                List<Group> changeItems = new List<Group>();
208
                foreach (var _item in groupDic)
209
                    if (_item.Value.Equals(from))
210
                        changeItems.Add(_item.Key);
211
                foreach (var _item in changeItems)
212
                    groupDic[_item] = to;
213
            }
214
        }
215
        private void SetPSNType()
216
        {
217
            foreach (PSNItem PSNItem in PSNItems)
218
            {
219
                Group firstGroup = PSNItem.Groups.First();
220
                Group lastGroup = PSNItem.Groups.Last();
221

    
222
                Item firstItem = firstGroup.Items.First();
223
                Item lastItem = lastGroup.Items.Last();
224

    
225
                PSNItem.StartType = GetPSNType(firstItem, true);
226
                PSNItem.EndType = GetPSNType(lastItem, false);
227
            }
228

    
229
            PSNType GetPSNType(Item item, bool bFirst = true)
230
            {
231
                PSNType type = PSNType.None;
232

    
233
                if (item.ItemType == ItemType.Line)
234
                {
235
                    Group group = groups.Find(x => x.Items.Contains(item));
236
                    if (bFirst && item.Relations[0].Item != null && !group.Items.Contains(item.Relations[0].Item))
237
                    {
238
                        Item connItem = item.Relations[0].Item;
239
                        if (connItem.ItemType == ItemType.Line && !IsConnected(item, connItem))
240
                            type = PSNType.Branch;
241
                        else if (connItem.ItemType == ItemType.Symbol)
242
                            type = PSNType.Symbol;
243
                    }
244
                    else if (!bFirst && item.Relations[1].Item != null && !group.Items.Contains(item.Relations[1].Item))
245
                    {
246
                        Item connItem = item.Relations[1].Item;
247
                        if (connItem.ItemType == ItemType.Line && !IsConnected(item, connItem))
248
                            type = PSNType.Branch;
249
                        else if (connItem.ItemType == ItemType.Symbol)
250
                            type = PSNType.Symbol;
251
                    }
252
                }
253
                else if (item.ItemType == ItemType.Symbol)
254
                {
255
                    if (item.SubItemType == SubItemType.Nozzle)
256
                        type = PSNType.Equipment;
257
                    else if (item.SubItemType == SubItemType.Header)
258
                        type = PSNType.Header;
259
                    else if (item.SubItemType == SubItemType.OPC)
260
                        type = PSNType.OPC;
261
                }
262

    
263
                return type;
264
            }
265
        }
266
        private void SetBranchInfo()
267
        {
268
            foreach (Document document in Documents)
269
            {
270
                List<Item> lines = document.Items.FindAll(x => x.ItemType == ItemType.Line).ToList();
271
                foreach (Item line in lines)
272
                {
273
                    double[] point = line.Relations[0].Point;
274
                    List<Item> connLines = lines.FindAll(x => x.Relations.Find(y => y.UID == line.UID) != null && line.Relations.Find(y => y.UID == x.UID) == null);
275
                    connLines.Sort(SortBranchLine);
276
                    line.BranchItems.AddRange(connLines);
277

    
278
                    int SortBranchLine(Item a, Item b)
279
                    {
280
                        double[] pointA = a.Relations[0].UID == line.UID ? a.Relations[0].Point : a.Relations[1].Point;
281
                        double distanceA = CalcPointToPointdDistance(point[0], point[1], pointA[0], pointA[1]);
282

    
283
                        double[] pointB = b.Relations[0].UID == line.UID ? b.Relations[0].Point : b.Relations[1].Point;
284
                        double distanceB = CalcPointToPointdDistance(point[0], point[1], pointB[0], pointB[1]);
285

    
286
                        // 내림차순
287
                        return distanceA.CompareTo(distanceB);
288
                    }
289
                    double CalcPointToPointdDistance(double x1, double y1, double x2, double y2)
290
                    {
291
                        return Math.Pow(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2), 0.5);
292
                    }
293
                }
294
            }
295
        }
296
        private void SetTopology()
297
        {
298
            #region 기본 topology 정리
299
            foreach (PSNItem PSNItem in PSNItems)
300
            {
301
                Topology topology = null;
302
                foreach (Group group in PSNItem.Groups)
303
                {
304
                    foreach (Item item in group.Items)
305
                    {
306
                        if (string.IsNullOrEmpty(item.TopologyData))
307
                            topology = null;
308
                        else
309
                        {
310
                            if (topology == null)
311
                            {
312
                                topology = new Topology()
313
                                {
314
                                    ID = item.TopologyData
315
                                };
316
                                Topologies.Add(topology);
317

    
318
                                if (!PSNItem.Topologies.Contains(topology))
319
                                    PSNItem.Topologies.Add(topology);
320
                            }
321
                            else
322
                            {
323
                                if (topology.ID != item.TopologyData)
324
                                {
325
                                    topology = new Topology()
326
                                    {
327
                                        ID = item.TopologyData
328
                                    };
329
                                    Topologies.Add(topology);
330

    
331
                                    if (!PSNItem.Topologies.Contains(topology))
332
                                        PSNItem.Topologies.Add(topology);
333
                                }
334
                            }
335

    
336
                            item.Topology = topology;
337
                            topology.Items.Add(item);
338
                        }
339
                    }
340
                }
341
            }
342
            #endregion
343

    
344
            #region Type
345

    
346
            //foreach (PSNItem PSNItem in PSNItems)
347
            //{
348
            //    List<Topology> psnTopology = PSNItem.Topologies;
349

    
350
            //    List<string> ids = psnTopology.Select(x => x.ID).Distinct().ToList();
351
            //    foreach (string id in ids)
352
            //    {
353
            //        List<Topology> topologies = psnTopology.FindAll(x => x.ID == id);
354

    
355
            //        // Main
356
            //        List<Topology> mainTopologies = FindMainTopology(topologies);
357
            //        foreach (Topology topology in mainTopologies)
358
            //        {
359
            //            topology.Type = "M";
360
            //            topology.Index = mainTopologies.IndexOf(topology).ToString();
361
            //        }
362

    
363
            //        // Branch
364
            //        List<Topology> branchToplogies = topologies.FindAll(x => string.IsNullOrEmpty(x.Type));
365
            //        foreach (Topology topology in branchToplogies)
366
            //        {
367
            //            topology.Type = "B";
368
            //            topology.Index = (branchToplogies.IndexOf(topology) + 1).ToString();
369
            //        }
370
            //    }
371
            //}
372

    
373
            List<string> ids = Topologies.Select(x => x.ID).Distinct().ToList();
374
            foreach (string id in ids)
375
            {
376
                List<Topology> topologies = Topologies.FindAll(x => x.ID == id);
377

    
378
                // Main
379
                List<Topology> mainTopologies = FindMainTopology(topologies);
380
                foreach (Topology topology in mainTopologies)
381
                {
382
                    topology.Type = "M";
383
                    topology.Index = mainTopologies.IndexOf(topology).ToString();
384
                }
385

    
386
                // Branch
387
                List<Topology> branchToplogies = topologies.FindAll(x => string.IsNullOrEmpty(x.Type));
388
                foreach (Topology topology in branchToplogies)
389
                {
390
                    topology.Type = "B";
391
                    topology.Index = (branchToplogies.IndexOf(topology) + 1).ToString();
392
                }
393
            }
394
            #endregion
395
        }
396
        private List<Topology> FindMainTopology(List<Topology> data)
397
        {
398
            DataTable nominalDiameterDT = DB.SelectNominalDiameter();
399
            DataTable PMCDT = DB.SelectPSNPIPINGMATLCLASS();
400
            DataTable fluidCodeDT = DB.SelectPSNFluidCode();
401

    
402
            List<Topology> main = new List<Topology>();
403
            main.AddRange(data);
404
            //
405
            main = GetNozzleTopology(data);
406
            if (main.Count == 1)
407
                return main;
408
            else
409
            {
410
                if (main.Count > 0)
411
                    main = GetPMCTopology(main);
412
                else
413
                    main = GetPMCTopology(data);
414

    
415
                if (main.Count == 1)
416
                    return main;
417
                else
418
                {
419
                    if (main.Count > 0)
420
                        main = GetDiaTopology(main);
421
                    else
422
                        main = GetDiaTopology(data);
423

    
424

    
425
                    if (main.Count == 1)
426
                        return main;
427
                    else
428
                    {
429
                        if (main.Count > 0)
430
                            main = GetItemTopology(main);
431
                        else
432
                            main = GetItemTopology(data);
433
                    }
434
                }
435
            }
436

    
437
            List<Topology> GetNozzleTopology(List<Topology> topologies)
438
            {
439
                return topologies.FindAll(x => x.Items.Find(y => y.SubItemType == SubItemType.Nozzle) != null);
440
            }
441

    
442
            List<Topology> GetPMCTopology(List<Topology> topologies)
443
            {
444
                List<Topology> result = new List<Topology>();
445
                foreach (DataRow row in PMCDT.Rows)
446
                {
447
                    string value = row["CODE"].ToString();
448
                    foreach (Topology topology in topologies)
449
                    {
450
                        foreach (Item item in topology.Items)
451
                        {
452
                            if (item.LineNumber == null)
453
                                continue;
454
                            string pmcValue = item.LineNumber.Attributes.Find(x => x.Name == "PipingMaterialsClass").Value;
455
                            if (value == pmcValue)
456
                            {
457
                                result.Add(topology);
458
                                break;
459
                            }
460
                        }
461
                    }
462

    
463
                    if (result.Count > 0)
464
                        break;
465
                }
466

    
467
                return result;
468
            }
469

    
470
            List<Topology> GetDiaTopology(List<Topology> topologies)
471
            {
472
                List<Topology> result = new List<Topology>();
473
                foreach (DataRow row in nominalDiameterDT.Rows)
474
                {
475
                    string inchValue = row["InchStr"].ToString();
476
                    string metricValue = row["MetricStr"].ToString();
477
                    foreach (Topology topology in topologies)
478
                    {
479
                        foreach (Item item in topology.Items)
480
                        {
481
                            if (item.LineNumber == null)
482
                                continue;
483
                            string value = item.LineNumber.Attributes.Find(x => x.Name == "NominalDiameter").Value;
484
                            if (inchValue == value || metricValue == value)
485
                            {
486
                                result.Add(topology);
487
                                break;
488
                            }
489
                        }
490
                    }
491

    
492
                    if (result.Count > 0)
493
                        break;
494
                }
495

    
496
                return result;
497
            }
498

    
499
            List<Topology> GetItemTopology(List<Topology> topologies)
500
            {
501
                return new List<Topology>() { topologies.OrderByDescending(x => x.Items.Count).ToList().First() };
502
            }
503

    
504
            return main;
505
        }
506

    
507
        private DataTable GetOPCInfo()
508
        {
509
            DataTable opc = DB.SelectOPCRelations();
510
            DataTable drawing = DB.SelectDrawings();
511

    
512
            DataTable dt = new DataTable();
513
            dt.Columns.Add("FromDrawing", typeof(string));
514
            dt.Columns.Add("FromDrawingUID", typeof(string));
515
            dt.Columns.Add("FromOPCUID", typeof(string));
516
            dt.Columns.Add("ToDrawing", typeof(string));
517
            dt.Columns.Add("ToDrawingUID", typeof(string));
518
            dt.Columns.Add("ToOPCUID", typeof(string));
519
            foreach (DataRow row in opc.Rows)
520
            {
521
                string fromDrawingUID = row["From_Drawings_UID"] == null ? string.Empty : row["From_Drawings_UID"].ToString();
522
                string fromOPCUID = row["From_OPC_UID"] == null ? string.Empty : row["From_OPC_UID"].ToString(); 
523
                string toDrawingUID = row["To_Drawings_UID"] == null ? string.Empty : row["To_Drawings_UID"].ToString(); 
524
                string toOPCUID = row["To_OPC_UID"] == null ? string.Empty : row["To_OPC_UID"].ToString();
525
                if (!string.IsNullOrEmpty(toOPCUID))
526
                {
527
                    DataRow[] fromRows = drawing.Select(string.Format("UID = '{0}'", fromDrawingUID));
528
                    DataRow[] toRows = drawing.Select(string.Format("UID = '{0}'", toDrawingUID));
529
                    if (fromRows.Length.Equals(1) && toRows.Length.Equals(1))
530
                    {
531
                        string fromDrawingName = Path.GetFileNameWithoutExtension(fromRows.First()["NAME"].ToString());
532
                        string toDrawingName = Path.GetFileNameWithoutExtension(toRows.First()["NAME"].ToString());
533

    
534
                        DataRow newRow = dt.NewRow();
535
                        newRow["FromDrawing"] = fromDrawingName;
536
                        newRow["FromDrawingUID"] = fromDrawingUID;
537
                        newRow["FromOPCUID"] = fromOPCUID;
538
                        newRow["ToDrawing"] = toDrawingName;
539
                        newRow["ToDrawingUID"] = toDrawingUID;
540
                        newRow["ToOPCUID"] = toOPCUID;
541

    
542
                        dt.Rows.Add(newRow);
543
                    }
544
                }
545
            }
546

    
547
            return dt;
548
        }
549
        private DataTable GetTopologyRule()
550
        {
551
            DataTable dt = DB.SelectTopologyRule();
552

    
553
            return dt;
554
        }
555
        private bool IsConnected(Item item1, Item item2)
556
        {
557
            if (item1.Relations.Find(x => x.UID.Equals(item2.UID)) != null &&
558
                item2.Relations.Find(x => x.UID.Equals(item1.UID)) != null)
559
                return true;
560
            else
561
                return false;
562
        }
563

    
564
        private void SaveNozzleAndEquipment()
565
        {
566
            List<Item> nozzles = new List<Item>();
567
            List<Equipment> equipments = new List<Equipment>();
568
            foreach (Document document in Documents)
569
            {
570
                nozzles.AddRange(document.Items.FindAll(x => x.SubItemType == SubItemType.Nozzle));
571
                equipments.AddRange(document.Equipments);
572
            }
573
                
574

    
575
            DataTable nozzleDT = new DataTable();
576
            nozzleDT.Columns.Add("OID", typeof(string));
577
            nozzleDT.Columns.Add("ITEMTAG", typeof(string));
578
            nozzleDT.Columns.Add("XCOORDS", typeof(string));
579
            nozzleDT.Columns.Add("YCOORDS", typeof(string));
580
            nozzleDT.Columns.Add("Equipment_OID", typeof(string));
581
            nozzleDT.Columns.Add("FLUID", typeof(string));
582
            nozzleDT.Columns.Add("NPD", typeof(string));
583
            nozzleDT.Columns.Add("ROTATION", typeof(string));
584
            nozzleDT.Columns.Add("FlowDirection", typeof(string));
585

    
586
            foreach (Item item in nozzles)
587
            {
588
                DataRow row = nozzleDT.NewRow();
589
                row["OID"] = item.UID;
590

    
591
                Relation relation = item.Relations.Find(x => equipments.Find(y => y.UID == x.UID) != null);
592
                if (relation != null)
593
                {
594
                    Equipment equipment = equipments.Find(x => x.UID == relation.UID);
595
                    equipment.Nozzles.Add(item);
596
                    row["ITEMTAG"] = string.Format("N-{0}", string.Format("{0:D3}", equipment.Nozzles.Count + 100));
597
                    row["Equipment_OID"] = equipment.UID;
598
                    item.Equipment = equipment;
599
                }
600
                row["XCOORDS"] = (item.POINT[0] / DrawingWidth).ToString();
601
                row["YCOORDS"] = (item.POINT[1] / DrawingHeight).ToString();
602
                Attribute fluidAttr = item.LineNumber.Attributes.Find(x => x.Name == "FluidCode");
603
                row["FLUID"] = fluidAttr != null ? fluidAttr.Value : string.Empty;
604
                Attribute npdAttr = item.LineNumber.Attributes.Find(x => x.Name == "NominalDiameter");
605
                row["NPD"] = npdAttr != null ? npdAttr.Value : string.Empty;
606

    
607
                double angle = Math.PI * 2 - Convert.ToDouble(item.ANGLE);
608
                if (angle >= Math.PI * 2)
609
                    angle = angle - Math.PI * 2;
610
                row["ROTATION"] = angle.ToString();
611

    
612
                if (item.Topology.Items.First().Equals(item))
613
                    row["FlowDirection"] = "Outlet";
614
                else if (item.Topology.Items.Last().Equals(item))
615
                    row["FlowDirection"] = "Inlet";
616
                else
617
                    row["FlowDirection"] = string.Empty;
618

    
619
                nozzleDT.Rows.Add(row);
620
            }
621

    
622
            DataTable equipDT = new DataTable();
623
            equipDT.Columns.Add("OID", typeof(string));
624
            equipDT.Columns.Add("ITEMTAG", typeof(string));
625
            equipDT.Columns.Add("XCOORDS", typeof(string));
626
            equipDT.Columns.Add("YCOORDS", typeof(string));
627

    
628
            foreach (Equipment equipment in equipments)
629
            {
630
                DataRow row = equipDT.NewRow();
631
                row["OID"] = equipment.UID;
632
                row["ITEMTAG"] = equipment.Name;
633

    
634
                List<double> xList = equipment.POINT.Select(x => x[0]).ToList();
635
                row["XCOORDS"] = (xList.Sum() / (double)xList.Count) / DrawingWidth;
636

    
637
                List<double> yList = equipment.POINT.Select(x => x[1]).ToList();
638
                row["YCOORDS"] = (yList.Sum() / (double)yList.Count) / DrawingHeight;
639

    
640
                equipDT.Rows.Add(row);
641
            }
642

    
643
            Equipment = equipDT;
644
            Nozzle = nozzleDT;
645
        }
646
        private void SavePSNData()
647
        {
648
            DataTable pathItemsDT = new DataTable();
649
            pathItemsDT.Columns.Add("OID", typeof(string));
650
            pathItemsDT.Columns.Add("SequenceData_OID", typeof(string));
651
            pathItemsDT.Columns.Add("TopologySet_OID", typeof(string));
652
            pathItemsDT.Columns.Add("BranchTopologySet_OID", typeof(string));
653
            pathItemsDT.Columns.Add("PipeLine_OID", typeof(string));
654
            pathItemsDT.Columns.Add("ITEMNAME", typeof(string));
655
            pathItemsDT.Columns.Add("ITEMTAG", typeof(string));
656
            pathItemsDT.Columns.Add("TYPE", typeof(string));
657
            pathItemsDT.Columns.Add("PIDNAME", typeof(string));
658
            pathItemsDT.Columns.Add("NPD", typeof(string));
659
            pathItemsDT.Columns.Add("PipeSystemNetwork_OID", typeof(string));
660
            pathItemsDT.Columns.Add("PipeRun_OID", typeof(string));
661
            pathItemsDT.Columns.Add("Show", typeof(string));
662

    
663
            DataTable sequenceDataDT = new DataTable();
664
            sequenceDataDT.Columns.Add("OID", typeof(string));
665
            sequenceDataDT.Columns.Add("SERIALNUMBER", typeof(string));
666
            sequenceDataDT.Columns.Add("PathItem_OID", typeof(string));
667
            sequenceDataDT.Columns.Add("TopologySet_OID_Key", typeof(string));
668

    
669
            DataTable pipeSystemNetworkDT = new DataTable();
670
            pipeSystemNetworkDT.Columns.Add("OID", typeof(string));
671
            pipeSystemNetworkDT.Columns.Add("Type", typeof(string));
672
            pipeSystemNetworkDT.Columns.Add("OrderNumber", typeof(string));
673
            pipeSystemNetworkDT.Columns.Add("Pipeline_OID", typeof(string));
674
            pipeSystemNetworkDT.Columns.Add("FROM_DATA", typeof(string));
675
            pipeSystemNetworkDT.Columns.Add("TO_DATA", typeof(string));
676
            pipeSystemNetworkDT.Columns.Add("TopologySet_OID_Key", typeof(string));
677
            pipeSystemNetworkDT.Columns.Add("PSNRevisionNumber", typeof(string));
678
            pipeSystemNetworkDT.Columns.Add("PathOID", typeof(string));
679
            pipeSystemNetworkDT.Columns.Add("PBS", typeof(string));
680
            pipeSystemNetworkDT.Columns.Add("PIDDrawings", typeof(string));
681

    
682
            // key = 미입력 branch
683
            Dictionary<Item, Item> startBranchDic = new Dictionary<Item, Item>();
684
            Dictionary<Item, Item> endBranchDic = new Dictionary<Item, Item>();
685
            foreach (PSNItem PSNItem in PSNItems)
686
            {
687
                int psnOrder = 0;
688
                int index = 0;
689
                bool bPSNStart = true;
690
                string sPSNData = string.Empty;
691
                foreach (Group group in PSNItem.Groups)
692
                {
693
                    foreach (Item item in group.Items)
694
                    {
695
                        if (item.BranchItems.Count == 0)
696
                        {
697
                            CreatePathItemsDataRow(item.UID, item.Type);
698
                            CreateSequenceDataDataRow(item.UID);
699
                            index++;
700
                        }
701
                        else
702
                        {
703
                            CreatePathItemsDataRow(item.UID + "_L1", item.Type);
704
                            CreateSequenceDataDataRow(item.UID + "_L1");
705
                            index++;
706
                            for (int i = 0; i < item.BranchItems.Count; i++)
707
                            {
708
                                CreatePathItemsDataRow(string.Format(item.UID + "_B{0}", i + 1), "Branch", item.BranchItems[i].Topology.FullName);
709
                                CreateSequenceDataDataRow(string.Format(item.UID + "_B{0}", i + 1));
710
                                index++;
711

    
712
                                CreatePathItemsDataRow(string.Format(item.UID + "_L{0}", i + 2), item.Type);
713
                                CreateSequenceDataDataRow(string.Format(item.UID + "_L{0}", i + 2));
714
                                index++;
715

    
716
                                if (item.BranchItems[i].Relations[0].Item != null && item.BranchItems[i].Relations[0].Item == item)
717
                                    startBranchDic.Add(item.BranchItems[i], item);
718
                                else if (item.BranchItems[i].Relations[1].Item != null && item.BranchItems[i].Relations[1].Item == item)
719
                                    endBranchDic.Add(item.BranchItems[i], item);
720
                            }
721
                        }
722

    
723
                        if (bPSNStart)
724
                        {
725
                            CreatePipeSystemNetworkDataRow();
726
                            sPSNData = item.TopologyData;
727
                            psnOrder++;
728
                            bPSNStart = false;
729
                        }
730
                        else
731
                        {
732
                            if (item.TopologyData != sPSNData)
733
                            {
734
                                CreatePipeSystemNetworkDataRow();
735
                                sPSNData = item.TopologyData;
736
                                psnOrder++;
737
                            }
738
                        }
739
                        void CreatePathItemsDataRow(string itemOID, string itemType, string branchTopologyName = "")
740
                        {
741
                            DataRow newRow = pathItemsDT.NewRow();
742
                            newRow["OID"] = itemOID;
743

    
744
                            newRow["SequenceData_OID"] = string.Format(item.Topology.FullName + "_{0}", index);
745

    
746
                            newRow["TopologySet_OID"] = item.Topology.FullName;
747

    
748
                            newRow["BranchTopologySet_OID"] = branchTopologyName;
749
                            newRow["PipeLine_OID"] = item.PSNPipeLineID;
750
                            newRow["ITEMNAME"] = null;
751
                            newRow["ITEMTAG"] = GetItemTag();
752
                            newRow["TYPE"] = item.Name;
753
                            newRow["PIDNAME"] = group.Document.DrawingName;
754

    
755
                            // NPD
756
                            if (item.LineNumber != null)
757
                            {
758
                                Attribute attribute = item.LineNumber.Attributes.Find(x => x.Name == "NominalDiameter");
759
                                if (attribute != null)
760
                                    newRow["NPD"] = attribute.Value;
761
                            }
762
                            else
763
                                newRow["NPD"] = null;
764

    
765
                            newRow["PipeSystemNetwork_OID"] = PSNItem.PSN_OID();
766
                            newRow["PipeRun_OID"] = item.LineNumber != null ? item.LineNumber.Name : string.Empty;
767

    
768
                            pathItemsDT.Rows.Add(newRow);
769
                        }
770
                        void CreateSequenceDataDataRow(string itemOID)
771
                        {
772
                            DataRow newRow = sequenceDataDT.NewRow();
773
                            newRow["OID"] = string.Format(item.Topology.FullName + "_{0}", index);
774
                            newRow["SERIALNUMBER"] = string.Format("{0}", index);
775
                            newRow["PathItem_OID"] = itemOID;
776
                            newRow["TopologySet_OID_Key"] = item.Topology.FullName;
777

    
778
                            sequenceDataDT.Rows.Add(newRow);
779
                        }
780
                        void CreatePipeSystemNetworkDataRow()
781
                        {
782
                            DataRow newRow = pipeSystemNetworkDT.NewRow();
783
                            newRow["OID"] = PSNItem.PSN_OID();
784
                            newRow["Type"] = PSNItem.GetPSNType();
785
                            newRow["OrderNumber"] = psnOrder;
786
                            newRow["Pipeline_OID"] = item.PSNPipeLineID;
787
                            newRow["FROM_DATA"] = PSNItem.GetFromData();
788
                            newRow["TO_DATA"] = PSNItem.GetToData();
789
                            newRow["TopologySet_OID_Key"] = item.Topology.FullName;
790
                            newRow["PSNRevisionNumber"] = string.Format("{0:D3}", Revision);
791
                            newRow["PathOID"] = null;
792
                            newRow["PBS"] = null;
793

    
794

    
795
                            List<string> drawingNames = new List<string>();
796
                            foreach (Group _group in PSNItem.Groups)
797
                            {
798
                                if (newRow["PBS"] == null)
799
                                {
800
                                    List<Item> _items = _group.Items.FindAll(x => x.Attributes.Find(y => y.Name.ToUpper() == "UNITNUMBER" && !string.IsNullOrEmpty(y.Value)) != null);
801
                                    foreach (Item _item in _items)
802
                                    {
803
                                        string _value = _item.Attributes.Find(x => x.Name.ToUpper() == "UNITNUMBER").Value;
804
                                        newRow["PBS"] = _value;
805
                                        break;
806
                                    }
807
                                }
808

    
809
                                if (!drawingNames.Contains(_group.Document.DrawingName))
810
                                {
811
                                    if (drawingNames.Count == 0)
812
                                        newRow["PIDDrawings"] = _group.Document.DrawingName;
813
                                    else
814
                                        newRow["PIDDrawings"] = newRow["PIDDrawings"] + ", " + _group.Document.DrawingName;
815
                                    drawingNames.Add(_group.Document.DrawingName);
816
                                }
817
                            }
818
                            pipeSystemNetworkDT.Rows.Add(newRow);
819
                        }
820

    
821
                        string GetItemTag()
822
                        {
823
                            string result = string.Empty;
824
                            if (item.ItemType == ItemType.Line)
825
                                result = item.LineNumber != null ? item.LineNumber.Name : string.Empty;
826
                            else if (item.ItemType == ItemType.Symbol && item.SubItemType == SubItemType.Nozzle)
827
                                result = Nozzle.Select(string.Format("OID = '{0}'", item.UID)).First()["ITEMTAG"].ToString();
828

    
829

    
830
                            return result;
831
                        }
832
                    }
833
                }
834
            }
835

    
836
            foreach (var item in startBranchDic)
837
            {
838
                string uid = item.Key.UID;
839
                string topologyName = item.Value.Topology.FullName;
840
                DataRow[] rows = pathItemsDT.Select(string.Format("OID LIKE '{0}%'", uid));
841
                if (rows.Length == 1)
842
                    rows.First()["BranchTopologySet_OID"] = topologyName;
843
                else if (rows.Length > 1)
844
                {
845
                    DataRow targetRow = null;
846
                    int index = int.MaxValue;
847
                    foreach (DataRow row in rows)
848
                    {
849
                        string split = row["OID"].ToString().Split(new char[] { '_' })[1];
850
                        if (split.StartsWith("L"))
851
                        {
852
                            int num = Convert.ToInt32(split.Remove(0, 1));
853
                            if (index > num)
854
                            {
855
                                index = num;
856
                                targetRow = row;
857
                            }
858
                        }
859
                    }
860

    
861
                    if (targetRow != null)
862
                        targetRow["BranchTopologySet_OID"] = topologyName;
863
                }
864
            }
865
            foreach (var item in endBranchDic)
866
            {
867
                string uid = item.Key.UID;
868
                string topologyName = item.Value.Topology.FullName;
869
                DataRow[] rows = pathItemsDT.Select(string.Format("OID LIKE '{0}%'", uid));
870
                if (rows.Length == 1)
871
                    rows.First()["BranchTopologySet_OID"] = topologyName;
872
                else if (rows.Length > 1)
873
                {
874
                    DataRow targetRow = null;
875
                    int index = int.MinValue;
876
                    foreach (DataRow row in rows)
877
                    {
878
                        string split = row["OID"].ToString().Split(new char[] { '_' })[1];
879
                        if (split.StartsWith("L"))
880
                        {
881
                            int num = Convert.ToInt32(split.Remove(0, 1));
882
                            if (index < num)
883
                            {
884
                                index = num;
885
                                targetRow = row;
886
                            }
887
                        }
888
                    }
889

    
890
                    if (targetRow != null)
891
                        targetRow["BranchTopologySet_OID"] = topologyName;
892
                }
893
            }
894

    
895
            PathItems = pathItemsDT;
896
            SequenceData = sequenceDataDT;
897
            PipeSystemNetwork = pipeSystemNetworkDT;
898
        }
899
    }
900

    
901
    public class PSNItem
902
    {
903
        public PSNItem(int count, int Revision)
904
        {
905
            Groups = new List<Group>();
906
            Topologies = new List<Topology>();
907

    
908
            Index = count + 1;
909
            this.Revision = Revision;
910
        }
911
        private int Revision;
912
        public string UID { get; set; }
913
        public List<Group> Groups { get; set; }
914
        public List<Topology> Topologies { get; set; }
915
        public PSNType StartType { get; set; }
916
        public PSNType EndType { get; set; }
917
        public int Index { get; set; }
918
        public string PSN_OID()
919
        {
920
            return string.Format("R{0}-PSN-{1}", string.Format("{0:D3}", Revision), string.Format("{0:D5}", Index));
921
        }
922
        public string GetPSNType()
923
        {
924
            string result = string.Empty;
925

    
926
            if (EnableType(StartType) && EnableType(EndType))
927
            {
928
                if (StartType == PSNType.Equipment && EndType == PSNType.Equipment)
929
                    result = "E2E";
930
                else if (StartType == PSNType.Branch && EndType == PSNType.Branch)
931
                    result = "B2B";
932
                else if (StartType == PSNType.Header && EndType == PSNType.Header)
933
                    result = "HD2";
934

    
935
                else if (StartType == PSNType.Equipment && EndType == PSNType.Branch)
936
                    result = "E2B";
937
                else if (StartType == PSNType.Branch && EndType == PSNType.Equipment)
938
                    result = "B2E";
939

    
940
                else if (StartType == PSNType.Header && EndType == PSNType.Branch)
941
                    result = "HDB";
942
                else if (StartType == PSNType.Branch && EndType == PSNType.Header)
943
                    result = "HDB";
944

    
945
                else if (StartType == PSNType.Header && EndType == PSNType.Equipment)
946
                    result = "HDE";
947
                else if (StartType == PSNType.Equipment && EndType == PSNType.Header)
948
                    result = "HDE";
949
                else
950
                    result = "Error";
951
            }
952
            else
953
                result = "Error";
954

    
955
            return result;
956

    
957
            
958
        }
959
        private bool EnableType(PSNType type)
960
        {
961
            bool result = false;
962

    
963
            if (type == PSNType.Branch ||
964
                type == PSNType.Equipment ||
965
                type == PSNType.Header)
966
            {
967
                result = true;
968
            }
969

    
970
            return result;
971
        }
972

    
973
        public string GetFromData()
974
        {
975
            string result = string.Empty;
976
            if (StartType == PSNType.Header)
977
                result = "ENDOFHEADER";
978
            else if (StartType == PSNType.Branch)
979
                result = Groups.First().Items.First().LineNumber.Name;
980
            else if (StartType == PSNType.Equipment)
981
                result = Groups.First().Items.First().Equipment.Name;
982
            else
983
                result = "Unknown";
984

    
985
            return result;
986
        }
987

    
988
        public string GetToData()
989
        {
990
            string result = string.Empty;
991
            if (EndType == PSNType.Header)
992
                result = "ENDOFHEADER";
993
            else if (EndType == PSNType.Branch)
994
                result = Groups.Last().Items.Last().LineNumber.Name;
995
            else if (EndType == PSNType.Equipment)
996
                result = Groups.Last().Items.Last().Equipment.Name;
997
            else 
998
                result = "Unknown";
999
            return result;
1000
        }
1001
    }
1002
}
클립보드 이미지 추가 (최대 크기: 500 MB)