프로젝트

일반

사용자정보

통계
| 개정판:

hytos / DTI_PID / ID2PSN / PSN.cs @ 1a379be0

이력 | 보기 | 이력해설 | 다운로드 (42.1 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 (insulAttr != null && !string.IsNullOrEmpty(insulAttr.Value))
104
                            item.PSNPipeLineID = item.TopologyData + "-" + insulAttr.Value;
105
                        else
106
                            item.PSNPipeLineID = item.TopologyData;
107
                    }
108
                    else
109
                    {
110
                        item.TopologyData = "Empty LineNumber";
111
                        item.LineNumber = new LineNumber();
112
                    }
113
                }
114
            }
115

    
116
            int emptyIndex = 1;
117
            foreach (Group group in groups)
118
            {
119
                List<Item> groupItems = group.Items.FindAll(x => x.TopologyData == "Empty LineNumber");
120
                if (groupItems.Count > 0)
121
                {
122
                    foreach (var item in groupItems)
123
                        item.TopologyData += string.Format("-{0}", emptyIndex);
124
                    emptyIndex++;
125
                }
126
            }
127

    
128
        }
129
        private void ConnectByOPC()
130
        {
131
            foreach (Group group in groups.FindAll(x => x.Items.Last().SubItemType == SubItemType.OPC))
132
            {
133
                Item opcItem = group.Items.Last();
134
                DataRow[] fromRows = opcDT.Select(string.Format("FromOPCUID = '{0}'", opcItem.UID));
135
                if (fromRows.Length.Equals(1))
136
                {
137
                    DataRow opcRow = fromRows.First();
138
                    string toDrawing = opcRow["ToDrawing"].ToString();
139
                    string toOPCUID = opcRow["ToOPCUID"].ToString();
140

    
141
                    Document toDocument = Documents.Find(x => x.DrawingName == toDrawing);
142
                    Group toGroup = toDocument.Groups.Find(x => x.Items.Find(y => y.UID == toOPCUID) != null);
143
                    group.EndGroup = toGroup;
144
                    toGroup.StartGroup = group;
145
                }
146
            }
147
        }
148
        private void SetPSNItem()
149
        {
150
            Dictionary<Group, string> groupDic = new Dictionary<Group, string>(); 
151
            foreach (Group group in groups)
152
                groupDic.Add(group, Guid.NewGuid().ToString());
153

    
154
            foreach (Group group in groups)
155
            {
156
                string groupKey = groupDic[group];
157
                if (group.StartGroup != null)
158
                {
159
                    string otherKey = groupDic[group.StartGroup];
160
                    ChangeGroupID(otherKey, groupKey);
161
                }
162
            }
163

    
164
            // PSN 정리
165
            foreach (var item in groupDic)
166
            {
167
                Group group = item.Key;
168
                string uid = item.Value;
169
                PSNItem PSNItem = PSNItems.Find(x => x.UID == uid);
170
                if (PSNItem == null)
171
                {
172
                    PSNItem = new PSNItem(PSNItems.Count, Revision) { UID = uid };
173
                    PSNItems.Add(PSNItem);
174
                }
175
                PSNItem.Groups.Add(group);
176
            }
177

    
178
            // Sort PSN
179
            foreach (PSNItem PSNItem in PSNItems)
180
            {
181
                List<Group> _groups = new List<Group>();
182

    
183
                Stack<Group> stacks = new Stack<Group>();
184
                stacks.Push(PSNItem.Groups.First());
185
                while (stacks.Count > 0)
186
                {
187
                    Group stack = stacks.Pop();
188
                    if (_groups.Contains(stack))
189
                        continue;
190

    
191
                    if (_groups.Count == 0)
192
                        _groups.Add(stack);
193
                    else
194
                    {
195
                        if (stack.StartGroup != null && _groups.Contains(stack.StartGroup))
196
                        {
197
                            int index = _groups.IndexOf(stack.StartGroup);
198
                            _groups.Insert(index + 1, stack);
199
                        }
200
                        else if (stack.EndGroup != null && _groups.Contains(stack.EndGroup))
201
                        {
202
                            int index = _groups.IndexOf(stack.EndGroup);
203
                            _groups.Insert(index, stack);
204
                        }
205
                    }
206

    
207
                    if (stack.StartGroup != null)
208
                        stacks.Push(stack.StartGroup);
209
                    if (stack.EndGroup != null)
210
                        stacks.Push(stack.EndGroup);
211
                }
212

    
213
                PSNItem.Groups.Clear();
214
                PSNItem.Groups.AddRange(_groups);
215
            }
216

    
217

    
218
            void ChangeGroupID(string from, string to)
219
            {
220
                if (from.Equals(to))
221
                    return;
222

    
223
                List<Group> changeItems = new List<Group>();
224
                foreach (var _item in groupDic)
225
                    if (_item.Value.Equals(from))
226
                        changeItems.Add(_item.Key);
227
                foreach (var _item in changeItems)
228
                    groupDic[_item] = to;
229
            }
230
        }
231
        private void SetPSNType()
232
        {
233
            foreach (PSNItem PSNItem in PSNItems)
234
            {
235
                Group firstGroup = PSNItem.Groups.First();
236
                Group lastGroup = PSNItem.Groups.Last();
237

    
238
                Item firstItem = firstGroup.Items.First();
239
                Item lastItem = lastGroup.Items.Last();
240

    
241
                PSNItem.StartType = GetPSNType(firstItem, true);
242
                PSNItem.EndType = GetPSNType(lastItem, false);
243
            }
244

    
245
            PSNType GetPSNType(Item item, bool bFirst = true)
246
            {
247
                PSNType type = PSNType.None;
248

    
249
                if (item.ItemType == ItemType.Line)
250
                {
251
                    Group group = groups.Find(x => x.Items.Contains(item));
252
                    if (bFirst && item.Relations[0].Item != null && !group.Items.Contains(item.Relations[0].Item))
253
                    {
254
                        Item connItem = item.Relations[0].Item;
255
                        if (connItem.ItemType == ItemType.Line && !IsConnected(item, connItem))
256
                            type = PSNType.Branch;
257
                        else if (connItem.ItemType == ItemType.Symbol)
258
                            type = PSNType.Symbol;
259
                    }
260
                    else if (!bFirst && item.Relations[1].Item != null && !group.Items.Contains(item.Relations[1].Item))
261
                    {
262
                        Item connItem = item.Relations[1].Item;
263
                        if (connItem.ItemType == ItemType.Line && !IsConnected(item, connItem))
264
                            type = PSNType.Branch;
265
                        else if (connItem.ItemType == ItemType.Symbol)
266
                            type = PSNType.Symbol;
267
                    }
268
                }
269
                else if (item.ItemType == ItemType.Symbol)
270
                {
271
                    if (item.SubItemType == SubItemType.Nozzle)
272
                        type = PSNType.Equipment;
273
                    else if (item.SubItemType == SubItemType.Header)
274
                        type = PSNType.Header;
275
                    else if (item.SubItemType == SubItemType.OPC)
276
                        type = PSNType.OPC;
277
                }
278

    
279
                return type;
280
            }
281
        }
282
        private void SetBranchInfo()
283
        {
284
            foreach (Document document in Documents)
285
            {
286
                List<Item> lines = document.Items.FindAll(x => x.ItemType == ItemType.Line).ToList();
287
                foreach (Item line in lines)
288
                {
289
                    double[] point = line.Relations[0].Point;
290
                    List<Item> connLines = lines.FindAll(x => x.Relations.Find(y => y.UID == line.UID) != null && line.Relations.Find(y => y.UID == x.UID) == null);
291
                    connLines.Sort(SortBranchLine);
292
                    line.BranchItems.AddRange(connLines);
293

    
294
                    int SortBranchLine(Item a, Item b)
295
                    {
296
                        double[] pointA = a.Relations[0].UID == line.UID ? a.Relations[0].Point : a.Relations[1].Point;
297
                        double distanceA = CalcPointToPointdDistance(point[0], point[1], pointA[0], pointA[1]);
298

    
299
                        double[] pointB = b.Relations[0].UID == line.UID ? b.Relations[0].Point : b.Relations[1].Point;
300
                        double distanceB = CalcPointToPointdDistance(point[0], point[1], pointB[0], pointB[1]);
301

    
302
                        // 내림차순
303
                        return distanceA.CompareTo(distanceB);
304
                    }
305
                    double CalcPointToPointdDistance(double x1, double y1, double x2, double y2)
306
                    {
307
                        return Math.Pow(Math.Pow(x1 - x2, 2) + Math.Pow(y1 - y2, 2), 0.5);
308
                    }
309
                }
310
            }
311
        }
312
        private void SetTopology()
313
        {
314
            #region 기본 topology 정리
315
            foreach (PSNItem PSNItem in PSNItems)
316
            {
317
                Topology topology = null;
318
                foreach (Group group in PSNItem.Groups)
319
                {
320
                    foreach (Item item in group.Items)
321
                    {
322
                        if (string.IsNullOrEmpty(item.TopologyData))
323
                            topology = null;
324
                        else
325
                        {
326
                            if (topology == null)
327
                            {
328
                                topology = new Topology()
329
                                {
330
                                    ID = item.TopologyData
331
                                };
332
                                Topologies.Add(topology);
333

    
334
                                if (!PSNItem.Topologies.Contains(topology))
335
                                    PSNItem.Topologies.Add(topology);
336
                            }
337
                            else
338
                            {
339
                                if (topology.ID != item.TopologyData)
340
                                {
341
                                    topology = new Topology()
342
                                    {
343
                                        ID = item.TopologyData
344
                                    };
345
                                    Topologies.Add(topology);
346

    
347
                                    if (!PSNItem.Topologies.Contains(topology))
348
                                        PSNItem.Topologies.Add(topology);
349
                                }
350
                            }
351

    
352
                            item.Topology = topology;
353
                            topology.Items.Add(item);
354
                        }
355
                    }
356
                }
357
            }
358
            #endregion
359

    
360
            #region Type
361

    
362
            //foreach (PSNItem PSNItem in PSNItems)
363
            //{
364
            //    List<Topology> psnTopology = PSNItem.Topologies;
365

    
366
            //    List<string> ids = psnTopology.Select(x => x.ID).Distinct().ToList();
367
            //    foreach (string id in ids)
368
            //    {
369
            //        List<Topology> topologies = psnTopology.FindAll(x => x.ID == id);
370

    
371
            //        // Main
372
            //        List<Topology> mainTopologies = FindMainTopology(topologies);
373
            //        foreach (Topology topology in mainTopologies)
374
            //        {
375
            //            topology.Type = "M";
376
            //            topology.Index = mainTopologies.IndexOf(topology).ToString();
377
            //        }
378

    
379
            //        // Branch
380
            //        List<Topology> branchToplogies = topologies.FindAll(x => string.IsNullOrEmpty(x.Type));
381
            //        foreach (Topology topology in branchToplogies)
382
            //        {
383
            //            topology.Type = "B";
384
            //            topology.Index = (branchToplogies.IndexOf(topology) + 1).ToString();
385
            //        }
386
            //    }
387
            //}
388

    
389
            List<string> ids = Topologies.Select(x => x.ID).Distinct().ToList();
390
            foreach (string id in ids)
391
            {
392
                List<Topology> topologies = Topologies.FindAll(x => x.ID == id);
393

    
394
                // Main
395
                List<Topology> mainTopologies = FindMainTopology(topologies);
396
                foreach (Topology topology in mainTopologies)
397
                {
398
                    topology.Type = "M";
399
                    topology.Index = mainTopologies.IndexOf(topology).ToString();
400
                }
401

    
402
                // Branch
403
                List<Topology> branchToplogies = topologies.FindAll(x => string.IsNullOrEmpty(x.Type));
404
                foreach (Topology topology in branchToplogies)
405
                {
406
                    topology.Type = "B";
407
                    topology.Index = (branchToplogies.IndexOf(topology) + 1).ToString();
408
                }
409
            }
410
            #endregion
411
        }
412
        private List<Topology> FindMainTopology(List<Topology> data)
413
        {
414
            DataTable nominalDiameterDT = DB.SelectNominalDiameter();
415
            DataTable PMCDT = DB.SelectPSNPIPINGMATLCLASS();
416
            DataTable fluidCodeDT = DB.SelectPSNFluidCode();
417

    
418
            List<Topology> main = new List<Topology>();
419
            main.AddRange(data);
420
            //
421
            main = GetNozzleTopology(data);
422
            if (main.Count == 1)
423
                return main;
424
            else
425
            {
426
                if (main.Count > 0)
427
                    main = GetPMCTopology(main);
428
                else
429
                    main = GetPMCTopology(data);
430

    
431
                if (main.Count == 1)
432
                    return main;
433
                else
434
                {
435
                    if (main.Count > 0)
436
                        main = GetDiaTopology(main);
437
                    else
438
                        main = GetDiaTopology(data);
439

    
440

    
441
                    if (main.Count == 1)
442
                        return main;
443
                    else
444
                    {
445
                        if (main.Count > 0)
446
                            main = GetItemTopology(main);
447
                        else
448
                            main = GetItemTopology(data);
449
                    }
450
                }
451
            }
452

    
453
            List<Topology> GetNozzleTopology(List<Topology> topologies)
454
            {
455
                return topologies.FindAll(x => x.Items.Find(y => y.SubItemType == SubItemType.Nozzle) != null);
456
            }
457

    
458
            List<Topology> GetPMCTopology(List<Topology> topologies)
459
            {
460
                List<Topology> result = new List<Topology>();
461
                foreach (DataRow row in PMCDT.Rows)
462
                {
463
                    string value = row["CODE"].ToString();
464
                    foreach (Topology topology in topologies)
465
                    {
466
                        foreach (Item item in topology.Items)
467
                        {
468
                            if (item.LineNumber == null)
469
                                continue;
470
                            Attribute attribute = item.LineNumber.Attributes.Find(x => x.Name == "PipingMaterialsClass");
471
                            if (attribute != null && value == attribute.Value)
472
                            {
473
                                result.Add(topology);
474
                                break;
475
                            }
476
                        }
477
                    }
478

    
479
                    if (result.Count > 0)
480
                        break;
481
                }
482

    
483
                return result;
484
            }
485

    
486
            List<Topology> GetDiaTopology(List<Topology> topologies)
487
            {
488
                List<Topology> result = new List<Topology>();
489
                foreach (DataRow row in nominalDiameterDT.Rows)
490
                {
491
                    string inchValue = row["InchStr"].ToString();
492
                    string metricValue = row["MetricStr"].ToString();
493
                    foreach (Topology topology in topologies)
494
                    {
495
                        foreach (Item item in topology.Items)
496
                        {
497
                            if (item.LineNumber == null)
498
                                continue;
499
                            Attribute attribute = item.LineNumber.Attributes.Find(x => x.Name == "NominalDiameter");
500
                            if (attribute != null && (inchValue == attribute.Value || metricValue == attribute.Value))
501
                            {
502
                                result.Add(topology);
503
                                break;
504
                            }
505
                        }
506
                    }
507

    
508
                    if (result.Count > 0)
509
                        break;
510
                }
511

    
512
                return result;
513
            }
514

    
515
            List<Topology> GetItemTopology(List<Topology> topologies)
516
            {
517
                return new List<Topology>() { topologies.OrderByDescending(x => x.Items.Count).ToList().First() };
518
            }
519

    
520
            return main;
521
        }
522

    
523
        private DataTable GetOPCInfo()
524
        {
525
            DataTable opc = DB.SelectOPCRelations();
526
            DataTable drawing = DB.SelectDrawings();
527

    
528
            DataTable dt = new DataTable();
529
            dt.Columns.Add("FromDrawing", typeof(string));
530
            dt.Columns.Add("FromDrawingUID", typeof(string));
531
            dt.Columns.Add("FromOPCUID", typeof(string));
532
            dt.Columns.Add("ToDrawing", typeof(string));
533
            dt.Columns.Add("ToDrawingUID", typeof(string));
534
            dt.Columns.Add("ToOPCUID", typeof(string));
535
            foreach (DataRow row in opc.Rows)
536
            {
537
                string fromDrawingUID = row["From_Drawings_UID"] == null ? string.Empty : row["From_Drawings_UID"].ToString();
538
                string fromOPCUID = row["From_OPC_UID"] == null ? string.Empty : row["From_OPC_UID"].ToString(); 
539
                string toDrawingUID = row["To_Drawings_UID"] == null ? string.Empty : row["To_Drawings_UID"].ToString(); 
540
                string toOPCUID = row["To_OPC_UID"] == null ? string.Empty : row["To_OPC_UID"].ToString();
541
                if (!string.IsNullOrEmpty(toOPCUID))
542
                {
543
                    DataRow[] fromRows = drawing.Select(string.Format("UID = '{0}'", fromDrawingUID));
544
                    DataRow[] toRows = drawing.Select(string.Format("UID = '{0}'", toDrawingUID));
545
                    if (fromRows.Length.Equals(1) && toRows.Length.Equals(1))
546
                    {
547
                        string fromDrawingName = Path.GetFileNameWithoutExtension(fromRows.First()["NAME"].ToString());
548
                        string toDrawingName = Path.GetFileNameWithoutExtension(toRows.First()["NAME"].ToString());
549

    
550
                        DataRow newRow = dt.NewRow();
551
                        newRow["FromDrawing"] = fromDrawingName;
552
                        newRow["FromDrawingUID"] = fromDrawingUID;
553
                        newRow["FromOPCUID"] = fromOPCUID;
554
                        newRow["ToDrawing"] = toDrawingName;
555
                        newRow["ToDrawingUID"] = toDrawingUID;
556
                        newRow["ToOPCUID"] = toOPCUID;
557

    
558
                        dt.Rows.Add(newRow);
559
                    }
560
                }
561
            }
562

    
563
            return dt;
564
        }
565
        private DataTable GetTopologyRule()
566
        {
567
            DataTable dt = DB.SelectTopologyRule();
568

    
569
            return dt;
570
        }
571
        private bool IsConnected(Item item1, Item item2)
572
        {
573
            if (item1.Relations.Find(x => x.UID.Equals(item2.UID)) != null &&
574
                item2.Relations.Find(x => x.UID.Equals(item1.UID)) != null)
575
                return true;
576
            else
577
                return false;
578
        }
579

    
580
        private void SaveNozzleAndEquipment()
581
        {
582
            List<Item> nozzles = new List<Item>();
583
            List<Equipment> equipments = new List<Equipment>();
584
            foreach (Document document in Documents)
585
            {
586
                nozzles.AddRange(document.Items.FindAll(x => x.SubItemType == SubItemType.Nozzle));
587
                equipments.AddRange(document.Equipments);
588
            }
589
                
590

    
591
            DataTable nozzleDT = new DataTable();
592
            nozzleDT.Columns.Add("OID", typeof(string));
593
            nozzleDT.Columns.Add("ITEMTAG", typeof(string));
594
            nozzleDT.Columns.Add("XCOORDS", typeof(string));
595
            nozzleDT.Columns.Add("YCOORDS", typeof(string));
596
            nozzleDT.Columns.Add("Equipment_OID", typeof(string));
597
            nozzleDT.Columns.Add("FLUID", typeof(string));
598
            nozzleDT.Columns.Add("NPD", typeof(string));
599
            nozzleDT.Columns.Add("ROTATION", typeof(string));
600
            nozzleDT.Columns.Add("FlowDirection", typeof(string));
601

    
602
            foreach (Item item in nozzles)
603
            {
604
                DataRow row = nozzleDT.NewRow();
605
                row["OID"] = item.UID;
606

    
607
                Relation relation = item.Relations.Find(x => equipments.Find(y => y.UID == x.UID) != null);
608
                if (relation != null)
609
                {
610
                    Equipment equipment = equipments.Find(x => x.UID == relation.UID);
611
                    equipment.Nozzles.Add(item);
612
                    row["ITEMTAG"] = string.Format("N-{0}", string.Format("{0:D3}", equipment.Nozzles.Count + 100));
613
                    row["Equipment_OID"] = equipment.UID;
614
                    item.Equipment = equipment;
615
                }
616
                row["XCOORDS"] = (item.POINT[0] / DrawingWidth).ToString();
617
                row["YCOORDS"] = (item.POINT[1] / DrawingHeight).ToString();
618
                Attribute fluidAttr = item.LineNumber.Attributes.Find(x => x.Name == "FluidCode");
619
                row["FLUID"] = fluidAttr != null ? fluidAttr.Value : string.Empty;
620
                Attribute npdAttr = item.LineNumber.Attributes.Find(x => x.Name == "NominalDiameter");
621
                row["NPD"] = npdAttr != null ? npdAttr.Value : string.Empty;
622

    
623
                double angle = Math.PI * 2 - Convert.ToDouble(item.ANGLE);
624
                if (angle >= Math.PI * 2)
625
                    angle = angle - Math.PI * 2;
626
                row["ROTATION"] = angle.ToString();
627

    
628
                if (item.Topology.Items.First().Equals(item))
629
                    row["FlowDirection"] = "Outlet";
630
                else if (item.Topology.Items.Last().Equals(item))
631
                    row["FlowDirection"] = "Inlet";
632
                else
633
                    row["FlowDirection"] = string.Empty;
634

    
635
                nozzleDT.Rows.Add(row);
636
            }
637

    
638
            DataTable equipDT = new DataTable();
639
            equipDT.Columns.Add("OID", typeof(string));
640
            equipDT.Columns.Add("ITEMTAG", typeof(string));
641
            equipDT.Columns.Add("XCOORDS", typeof(string));
642
            equipDT.Columns.Add("YCOORDS", typeof(string));
643

    
644
            foreach (Equipment equipment in equipments)
645
            {
646
                DataRow row = equipDT.NewRow();
647
                row["OID"] = equipment.UID;
648
                row["ITEMTAG"] = equipment.Name;
649

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

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

    
656
                equipDT.Rows.Add(row);
657
            }
658

    
659
            Equipment = equipDT;
660
            Nozzle = nozzleDT;
661
        }
662
        private void SavePSNData()
663
        {
664
            DataTable pathItemsDT = new DataTable();
665
            pathItemsDT.Columns.Add("OID", typeof(string));
666
            pathItemsDT.Columns.Add("SequenceData_OID", typeof(string));
667
            pathItemsDT.Columns.Add("TopologySet_OID", typeof(string));
668
            pathItemsDT.Columns.Add("BranchTopologySet_OID", typeof(string));
669
            pathItemsDT.Columns.Add("PipeLine_OID", typeof(string));
670
            pathItemsDT.Columns.Add("ITEMNAME", typeof(string));
671
            pathItemsDT.Columns.Add("ITEMTAG", typeof(string));
672
            pathItemsDT.Columns.Add("TYPE", typeof(string));
673
            pathItemsDT.Columns.Add("PIDNAME", typeof(string));
674
            pathItemsDT.Columns.Add("NPD", typeof(string));
675
            pathItemsDT.Columns.Add("PipeSystemNetwork_OID", typeof(string));
676
            pathItemsDT.Columns.Add("PipeRun_OID", typeof(string));
677

    
678
            DataTable sequenceDataDT = new DataTable();
679
            sequenceDataDT.Columns.Add("OID", typeof(string));
680
            sequenceDataDT.Columns.Add("SERIALNUMBER", typeof(string));
681
            sequenceDataDT.Columns.Add("PathItem_OID", typeof(string));
682
            sequenceDataDT.Columns.Add("TopologySet_OID_Key", typeof(string));
683

    
684
            DataTable pipeSystemNetworkDT = new DataTable();
685
            pipeSystemNetworkDT.Columns.Add("OID", typeof(string));
686
            pipeSystemNetworkDT.Columns.Add("Type", typeof(string));
687
            pipeSystemNetworkDT.Columns.Add("OrderNumber", typeof(string));
688
            pipeSystemNetworkDT.Columns.Add("Pipeline_OID", typeof(string));
689
            pipeSystemNetworkDT.Columns.Add("FROM_DATA", typeof(string));
690
            pipeSystemNetworkDT.Columns.Add("TO_DATA", typeof(string));
691
            pipeSystemNetworkDT.Columns.Add("TopologySet_OID_Key", typeof(string));
692
            pipeSystemNetworkDT.Columns.Add("PSNRevisionNumber", typeof(string));
693
            pipeSystemNetworkDT.Columns.Add("PathOID", typeof(string));
694
            pipeSystemNetworkDT.Columns.Add("PBS", typeof(string));
695
            pipeSystemNetworkDT.Columns.Add("PIDDrawings", typeof(string));
696

    
697
            // key = 미입력 branch
698
            Dictionary<Item, Item> startBranchDic = new Dictionary<Item, Item>();
699
            Dictionary<Item, Item> endBranchDic = new Dictionary<Item, Item>();
700
            foreach (PSNItem PSNItem in PSNItems)
701
            {
702
                int psnOrder = 0;
703
                int index = 0;
704
                bool bPSNStart = true;
705
                string sPSNData = string.Empty;
706
                foreach (Group group in PSNItem.Groups)
707
                {
708
                    foreach (Item item in group.Items)
709
                    {
710
                        if (item.BranchItems.Count == 0)
711
                        {
712
                            CreatePathItemsDataRow(item.UID, item.Type);
713
                            CreateSequenceDataDataRow(item.UID);
714
                            index++;
715
                        }
716
                        else
717
                        {
718
                            CreatePathItemsDataRow(item.UID + "_L1", item.Type);
719
                            CreateSequenceDataDataRow(item.UID + "_L1");
720
                            index++;
721
                            for (int i = 0; i < item.BranchItems.Count; i++)
722
                            {
723
                                CreatePathItemsDataRow(string.Format(item.UID + "_B{0}", i + 1), "Branch", item.BranchItems[i].Topology.FullName);
724
                                CreateSequenceDataDataRow(string.Format(item.UID + "_B{0}", i + 1));
725
                                index++;
726

    
727
                                CreatePathItemsDataRow(string.Format(item.UID + "_L{0}", i + 2), item.Type);
728
                                CreateSequenceDataDataRow(string.Format(item.UID + "_L{0}", i + 2));
729
                                index++;
730

    
731
                                if (item.BranchItems[i].Relations[0].Item != null && item.BranchItems[i].Relations[0].Item == item)
732
                                    startBranchDic.Add(item.BranchItems[i], item);
733
                                else if (item.BranchItems[i].Relations[1].Item != null && item.BranchItems[i].Relations[1].Item == item)
734
                                    endBranchDic.Add(item.BranchItems[i], item);
735
                            }
736
                        }
737

    
738
                        if (bPSNStart)
739
                        {
740
                            CreatePipeSystemNetworkDataRow();
741
                            sPSNData = item.TopologyData;
742
                            psnOrder++;
743
                            bPSNStart = false;
744
                        }
745
                        else
746
                        {
747
                            if (item.TopologyData != sPSNData)
748
                            {
749
                                CreatePipeSystemNetworkDataRow();
750
                                sPSNData = item.TopologyData;
751
                                psnOrder++;
752
                            }
753
                        }
754
                        void CreatePathItemsDataRow(string itemOID, string itemType, string branchTopologyName = "")
755
                        {
756
                            DataRow newRow = pathItemsDT.NewRow();
757
                            newRow["OID"] = itemOID;
758

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

    
761
                            newRow["TopologySet_OID"] = item.Topology.FullName;
762

    
763
                            newRow["BranchTopologySet_OID"] = branchTopologyName;
764
                            newRow["PipeLine_OID"] = item.PSNPipeLineID;
765
                            newRow["ITEMNAME"] = null;
766
                            newRow["ITEMTAG"] = GetItemTag();
767
                            newRow["TYPE"] = item.Name;
768
                            newRow["PIDNAME"] = group.Document.DrawingName;
769

    
770
                            // NPD
771
                            if (item.LineNumber != null)
772
                            {
773
                                Attribute attribute = item.LineNumber.Attributes.Find(x => x.Name == "NominalDiameter");
774
                                if (attribute != null)
775
                                    newRow["NPD"] = attribute.Value;
776
                            }
777
                            else
778
                                newRow["NPD"] = null;
779

    
780
                            newRow["PipeSystemNetwork_OID"] = PSNItem.PSN_OID();
781
                            newRow["PipeRun_OID"] = item.LineNumber != null ? item.LineNumber.Name : string.Empty;
782

    
783
                            pathItemsDT.Rows.Add(newRow);
784
                        }
785
                        void CreateSequenceDataDataRow(string itemOID)
786
                        {
787
                            DataRow newRow = sequenceDataDT.NewRow();
788
                            newRow["OID"] = string.Format(item.Topology.FullName + "_{0}", index);
789
                            newRow["SERIALNUMBER"] = string.Format("{0}", index);
790
                            newRow["PathItem_OID"] = itemOID;
791
                            newRow["TopologySet_OID_Key"] = item.Topology.FullName;
792

    
793
                            sequenceDataDT.Rows.Add(newRow);
794
                        }
795
                        void CreatePipeSystemNetworkDataRow()
796
                        {
797
                            DataRow newRow = pipeSystemNetworkDT.NewRow();
798
                            newRow["OID"] = PSNItem.PSN_OID();
799
                            newRow["Type"] = PSNItem.GetPSNType();
800
                            newRow["OrderNumber"] = psnOrder;
801
                            newRow["Pipeline_OID"] = item.PSNPipeLineID;
802
                            newRow["FROM_DATA"] = PSNItem.GetFromData();
803
                            newRow["TO_DATA"] = PSNItem.GetToData();
804
                            newRow["TopologySet_OID_Key"] = item.Topology.FullName;
805
                            newRow["PSNRevisionNumber"] = string.Format("{0:D3}", Revision);
806
                            newRow["PathOID"] = null;
807
                            newRow["PBS"] = null;
808

    
809

    
810
                            List<string> drawingNames = new List<string>();
811
                            foreach (Group _group in PSNItem.Groups)
812
                            {
813
                                if (newRow["PBS"] == null)
814
                                {
815
                                    List<Item> _items = _group.Items.FindAll(x => x.Attributes.Find(y => y.Name.ToUpper() == "UNITNUMBER" && !string.IsNullOrEmpty(y.Value)) != null);
816
                                    foreach (Item _item in _items)
817
                                    {
818
                                        string _value = _item.Attributes.Find(x => x.Name.ToUpper() == "UNITNUMBER").Value;
819
                                        newRow["PBS"] = _value;
820
                                        break;
821
                                    }
822
                                }
823

    
824
                                if (!drawingNames.Contains(_group.Document.DrawingName))
825
                                {
826
                                    if (drawingNames.Count == 0)
827
                                        newRow["PIDDrawings"] = _group.Document.DrawingName;
828
                                    else
829
                                        newRow["PIDDrawings"] = newRow["PIDDrawings"] + ", " + _group.Document.DrawingName;
830
                                    drawingNames.Add(_group.Document.DrawingName);
831
                                }
832
                            }
833
                            pipeSystemNetworkDT.Rows.Add(newRow);
834
                        }
835

    
836
                        string GetItemTag()
837
                        {
838
                            string result = string.Empty;
839
                            if (item.ItemType == ItemType.Line)
840
                                result = item.LineNumber != null ? item.LineNumber.Name : string.Empty;
841
                            else if (item.ItemType == ItemType.Symbol && item.SubItemType == SubItemType.Nozzle)
842
                                result = Nozzle.Select(string.Format("OID = '{0}'", item.UID)).First()["ITEMTAG"].ToString();
843

    
844

    
845
                            return result;
846
                        }
847
                    }
848
                }
849
            }
850

    
851
            foreach (var item in startBranchDic)
852
            {
853
                string uid = item.Key.UID;
854
                string topologyName = item.Value.Topology.FullName;
855
                DataRow[] rows = pathItemsDT.Select(string.Format("OID LIKE '{0}%'", uid));
856
                if (rows.Length == 1)
857
                    rows.First()["BranchTopologySet_OID"] = topologyName;
858
                else if (rows.Length > 1)
859
                {
860
                    DataRow targetRow = null;
861
                    int index = int.MaxValue;
862
                    foreach (DataRow row in rows)
863
                    {
864
                        string split = row["OID"].ToString().Split(new char[] { '_' })[1];
865
                        if (split.StartsWith("L"))
866
                        {
867
                            int num = Convert.ToInt32(split.Remove(0, 1));
868
                            if (index > num)
869
                            {
870
                                index = num;
871
                                targetRow = row;
872
                            }
873
                        }
874
                    }
875

    
876
                    if (targetRow != null)
877
                        targetRow["BranchTopologySet_OID"] = topologyName;
878
                }
879
            }
880
            foreach (var item in endBranchDic)
881
            {
882
                string uid = item.Key.UID;
883
                string topologyName = item.Value.Topology.FullName;
884
                DataRow[] rows = pathItemsDT.Select(string.Format("OID LIKE '{0}%'", uid));
885
                if (rows.Length == 1)
886
                    rows.First()["BranchTopologySet_OID"] = topologyName;
887
                else if (rows.Length > 1)
888
                {
889
                    DataRow targetRow = null;
890
                    int index = int.MinValue;
891
                    foreach (DataRow row in rows)
892
                    {
893
                        string split = row["OID"].ToString().Split(new char[] { '_' })[1];
894
                        if (split.StartsWith("L"))
895
                        {
896
                            int num = Convert.ToInt32(split.Remove(0, 1));
897
                            if (index < num)
898
                            {
899
                                index = num;
900
                                targetRow = row;
901
                            }
902
                        }
903
                    }
904

    
905
                    if (targetRow != null)
906
                        targetRow["BranchTopologySet_OID"] = topologyName;
907
                }
908
            }
909

    
910
            PathItems = pathItemsDT;
911
            SequenceData = sequenceDataDT;
912
            PipeSystemNetwork = pipeSystemNetworkDT;
913
        }
914
    }
915

    
916
    public class PSNItem
917
    {
918
        public PSNItem(int count, int Revision)
919
        {
920
            Groups = new List<Group>();
921
            Topologies = new List<Topology>();
922

    
923
            Index = count + 1;
924
            this.Revision = Revision;
925
        }
926
        private int Revision;
927
        public string UID { get; set; }
928
        public List<Group> Groups { get; set; }
929
        public List<Topology> Topologies { get; set; }
930
        public PSNType StartType { get; set; }
931
        public PSNType EndType { get; set; }
932
        public int Index { get; set; }
933
        public string PSN_OID()
934
        {
935
            return string.Format("R{0}-PSN-{1}", string.Format("{0:D3}", Revision), string.Format("{0:D5}", Index));
936
        }
937
        public string GetPSNType()
938
        {
939
            string result = string.Empty;
940

    
941
            if (EnableType(StartType) && EnableType(EndType))
942
            {
943
                if (StartType == PSNType.Equipment && EndType == PSNType.Equipment)
944
                    result = "E2E";
945
                else if (StartType == PSNType.Branch && EndType == PSNType.Branch)
946
                    result = "B2B";
947
                else if (StartType == PSNType.Header && EndType == PSNType.Header)
948
                    result = "HD2";
949

    
950
                else if (StartType == PSNType.Equipment && EndType == PSNType.Branch)
951
                    result = "E2B";
952
                else if (StartType == PSNType.Branch && EndType == PSNType.Equipment)
953
                    result = "B2E";
954

    
955
                else if (StartType == PSNType.Header && EndType == PSNType.Branch)
956
                    result = "HDB";
957
                else if (StartType == PSNType.Branch && EndType == PSNType.Header)
958
                    result = "HDB";
959

    
960
                else if (StartType == PSNType.Header && EndType == PSNType.Equipment)
961
                    result = "HDE";
962
                else if (StartType == PSNType.Equipment && EndType == PSNType.Header)
963
                    result = "HDE";
964
                else
965
                    result = "Error";
966
            }
967
            else
968
                result = "Error";
969

    
970
            return result;
971

    
972
            
973
        }
974
        private bool EnableType(PSNType type)
975
        {
976
            bool result = false;
977

    
978
            if (type == PSNType.Branch ||
979
                type == PSNType.Equipment ||
980
                type == PSNType.Header)
981
            {
982
                result = true;
983
            }
984

    
985
            return result;
986
        }
987

    
988
        public string GetFromData()
989
        {
990
            string result = string.Empty;
991
            if (StartType == PSNType.Header)
992
                result = "ENDOFHEADER";
993
            else if (StartType == PSNType.Branch)
994
                result = Groups.First().Items.First().LineNumber.Name;
995
            else if (StartType == PSNType.Equipment)
996
                result = Groups.First().Items.First().Equipment.Name;
997
            else
998
                result = "Unknown";
999

    
1000
            return result;
1001
        }
1002

    
1003
        public string GetToData()
1004
        {
1005
            string result = string.Empty;
1006
            if (EndType == PSNType.Header)
1007
                result = "ENDOFHEADER";
1008
            else if (EndType == PSNType.Branch)
1009
                result = Groups.Last().Items.Last().LineNumber.Name;
1010
            else if (EndType == PSNType.Equipment)
1011
                result = Groups.Last().Items.Last().Equipment.Name;
1012
            else 
1013
                result = "Unknown";
1014
            return result;
1015
        }
1016
    }
1017
}
클립보드 이미지 추가 (최대 크기: 500 MB)