프로젝트

일반

사용자정보

통계
| 브랜치(Branch): | 개정판:

hytos / DTI_PID / DTI_PID / XmlGenerator.py @ 16cf1212

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

1
# coding: utf-8
2
""" This is xml generator module """
3

    
4
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree, parse
5
import symbol
6
import SymbolBase
7
import TextInfo as ti
8
import math
9
import os
10
import sys
11
from AppDocData import AppDocData
12

    
13
ROOT_NODE_NAME = "DWG"
14
ROOT_DWGNAME_NODE_NAME = "DWGNAME"
15
ROOT_SIZE_NODE_NAME = "SIZE"
16

    
17
SYMBOL_LIST_NODE_NAME = "SYMBOLS"
18
TEXT_INFO_LIST_NODE_NAME = "TEXTINFOS"
19
IMG_LINE_LIST_NODE_NAME = "IMGLINES"
20
NOTE_TEXT_INFO_LIST_NOTE_NAME = "NOTES"
21

    
22
SCATEGORY_NODE_NAME = "SYMBOL"
23

    
24
SNAME_NODE_NAME = "NAME"
25

    
26
STYPE_NOTE_NAME = "TYPE"
27

    
28
SCLASS_NODE_NAME = "CLASS"
29

    
30
SITEM_NODE_NAME = "ITEM"
31

    
32
SSUB_TEXT = "TEXT"
33
SSUB_ORIGINAL_POINT = "ORIGINALPOINT"
34
SSUB_CONNECTION_POINT = "CONNECTIONPOINT"
35
SSUB_PARENT = "PARENT"
36
SSUB_CHILD = "CHILD"
37
SSUB_ANGLE = "ANGLE"
38
SSUB_START_POINT = "STARTPOINT"
39
SSUB_SIZE = "SIZE"
40

    
41
LINE_NO_LIST_NODE_NAME = "LINE_NOS"
42

    
43
TEXT_INFO_NODE_NAME = "TEXTINFO"
44
TTEXT_NODE_NAME = "TEXT"
45
TTEXT_X_NODE_NAME = "X"
46
TTEXT_Y_NODE_NAME = "Y"
47
TTEXT_WIDTH_NODE_NAME = "WIDTH"
48
TTEXT_HEIGHT_NODE_NAME = "HEIGHT"
49
TTEXT_ANGLE_NODE_NAME = "ANGLE"
50

    
51

    
52
IMG_LINE_NODE_NAME = "IMGLINE"
53
ISP_NODE_NAME = "START"
54
IEP_NODE_NAME = "END"
55

    
56
NOTE_TEXT_INFO_NOTE_NAME = "NOTE"
57
TNOTE_TEXT_NODE_NAME = "TEXT"
58
TNOTE_TEXT_X_NODE_NAME = "X"
59
TNOTE_TEXT_Y_NODE_NAME = "Y"
60
TNOTE_TEXT_WIDTH_NODE_NAME = "WIDTH"
61
TNOTE_TEXT_HEIGHT_NODE_NAME = "HEIGHT"
62
TNOTE_TEXT_ANGLE_NODE_NAME = "ANGLE"
63

    
64
LINE_INFOS_NODE_NAME = "LINEINFOS"
65
LLINE_INFO_NODE_NAME = "LINEINFO"
66
LLINE_UUID = "UUID"
67
LLINE_START_POINT_NODE_NAME = "STARTPOINT"
68
LLINE_END_POINT_NODE_NAME = "ENDPOINT"
69

    
70
LINE_NOS_NODE_NAME = "LINENOS"
71
TRIM_LINE_NOS_NODE_NAME = "TRIMLINENOS"
72

    
73
UNKNOWNS_NODE_NAME = "UNKNOWNS"
74
VENDOR_NODE_NAME = "VENDORS"
75
#END_BREAK = "END_BREAKS"
76

    
77
'''
78
    @brief  
79
    @author 
80
    @date   
81
    @history    2018.05.25  Jeongwoo    Remove parameter 'imgLineList'
82
'''
83
def writeXml(pidName, pidWidth, pidHeight, searchedSymbolList, textInfoList, noteTextInfoList):
84
    path = os.path.join(AppDocData.instance().getCurrentProject().getTempPath(), pidName + '.xml')
85
    try:
86
        xmlData = generateXml(pidName, pidWidth, pidHeight, searchedSymbolList, textInfoList, noteTextInfoList)
87
        ElementTree(xmlData).write(path)
88
    except Exception as ex:
89
        print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
90

    
91
    return path
92

    
93
'''
94
    @brief  write output xml
95
    @author humkyung
96
    @date   2018.04.23
97
'''
98
def writeOutputXml(pidName, pidWidth, pidHeight):
99
    try:
100
        path = os.path.join(AppDocData.instance().getCurrentProject().getOutputPath(), pidName + '.xml')
101

    
102
        xmlData = generateOutputXml(pidName, pidWidth, pidHeight)
103
        ElementTree(xmlData).write(path)
104
    except Exception as ex:
105
        print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
106

    
107
    return path
108

    
109
'''
110
    @brief      generate output xml for converter
111
    @author     humkyung
112
    @date       2018.04.23
113
    @history    humkyung 2018.05.02 write equipment node
114
                humkyung 2018.05.10 write orphan lines
115
                humkyung 2018.05.16 remove code to write orphan lines and symbols
116
                humkyung 2018.09.06 write text to xml
117
'''
118
def generateOutputXml(pidName, pidWidth, pidHeight):
119
    appDocData = AppDocData.instance()
120

    
121
    try:
122
        xml = Element(ROOT_NODE_NAME) # Root Node
123
        SubElement(xml, ROOT_DWGNAME_NODE_NAME).text = pidName
124
        SubElement(xml, ROOT_SIZE_NODE_NAME).text = str(pidWidth) + "," + str(pidHeight)
125
        SubElement(xml, 'UNIT').text = appDocData.getCurrentProject().unit()
126

    
127
        for equipment in appDocData.equipments:
128
            equipmentNode = Element('EQUIPMENT')
129
            equipmentNode.append(equipment.toXml())
130
            xml.append(equipmentNode)
131

    
132
        sortedList = sorted(appDocData.lineNos, key=lambda param:param.text())
133
        for lineno in sortedList:
134
            xml.append(lineno.toXml())
135

    
136
        for text in appDocData.texts:
137
            xml.append(text.toXml())
138
    except Exception as ex:
139
        print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
140

    
141
    return xml
142

    
143
'''
144
    @history    2018.04.30  Jeongwoo    noteTextInfoList None Check
145
                2018.05.25  Jeongwoo    Remove parameter 'imgLineList' and Check if variable is None or not
146
'''
147
def generateXml(pidName, pidWidth, pidHeight, searchedSymbolList, textInfoList, noteTextInfoList):
148
    xml = Element(ROOT_NODE_NAME) # Root Node
149
    SubElement(xml, ROOT_DWGNAME_NODE_NAME).text = pidName
150
    SubElement(xml, ROOT_SIZE_NODE_NAME).text = str(pidWidth) + "," + str(pidHeight)
151
    try:
152
        if searchedSymbolList is not None:
153
            symbolListNode = Element(SYMBOL_LIST_NODE_NAME) # Symbol List Node
154
            sortedList = sorted(searchedSymbolList, key=lambda sym:sym.getName())
155
            for symbol in sortedList:
156
                node = getSymbolInfoNode(symbol)
157
                symbolListNode.append(node)
158

    
159
            xml.append(symbolListNode)
160

    
161
        if textInfoList is not None:
162
            textInfoListNode = Element(TEXT_INFO_LIST_NODE_NAME) # Text Info List Node
163
            for textInfo in textInfoList:
164
                node = getTextInfoNode(textInfo)
165
                textInfoListNode.append(node)
166

    
167
            xml.append(textInfoListNode)
168

    
169
        noteTextInfoListNode = Element(NOTE_TEXT_INFO_LIST_NOTE_NAME)
170
        if noteTextInfoList is not None:
171
            for noteTextInfo in noteTextInfoList:
172
                node = getNoteTextInfoNode(noteTextInfo)
173
                noteTextInfoListNode.append(node)
174

    
175
        xml.append(noteTextInfoListNode)
176
    except Exception as ex:
177
        print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno))
178

    
179
    return xml
180

    
181
def getSymbolInfoNode(symbol):
182
    sName = symbol.getName()
183
    sSp = symbol.getSp()
184
    sAngle = symbol.getRotatedAngle()
185
    sType = symbol.getType()
186
    sText = symbol.getText()
187
    sOriginalPoint = symbol.getOriginalPoint()
188
    sConnectionPoint = symbol.getConnectionPoint()
189
    sWidth = symbol.getWidth()
190
    sHeight = symbol.getHeight()
191
    sBaseSymbol = symbol.getBaseSymbol()
192
    sAdditionalSymbol = symbol.getAdditionalSymbol()
193

    
194
    sCategoryNode = Element(SCATEGORY_NODE_NAME)
195

    
196
    sNameNode = Element(SNAME_NODE_NAME)
197
    sNameNode.text = sName
198

    
199
    sTypeNode = Element(STYPE_NOTE_NAME)
200
    sTypeNode.text = sType
201
    
202
    sOriginalPointNode = Element(SSUB_ORIGINAL_POINT)
203
    sOpX = sSp[0] + int(sOriginalPoint.split(',')[0])
204
    sOpY = sSp[1] + int(sOriginalPoint.split(',')[1])
205
    sOriginalPointNode.text = str(sOpX) + "," + str(sOpY)
206

    
207
    sConnectionPointNode = Element(SSUB_CONNECTION_POINT)
208
    convertedConnectionPoint = ""
209
    if sConnectionPoint:
210
        splitConnectionPoint = sConnectionPoint.split("/")
211
        for index in range(len(splitConnectionPoint)):
212
            if index != 0:
213
                convertedConnectionPoint = convertedConnectionPoint + "/"
214
            item = splitConnectionPoint[index]
215
            sCpX = sSp[0] + int(item.split(',')[0])
216
            sCpY = sSp[1] + int(item.split(',')[1])
217
            tempStr = str(sCpX) + "," + str(sCpY)
218
            convertedConnectionPoint = convertedConnectionPoint + tempStr
219
    sConnectionPointNode.text = convertedConnectionPoint
220

    
221
    sBaseSymbolNode = Element(SSUB_PARENT)
222
    sBaseSymbolNode.text = sBaseSymbol
223

    
224
    if sAdditionalSymbol is not None:
225
        sAdditionalSymbolNode = Element(SSUB_CHILD)
226
        sAdditionalSymbolNode.text = sAdditionalSymbol
227
        sCategoryNode.append(sAdditionalSymbolNode)
228

    
229
    sAngleNode = Element(SSUB_ANGLE)
230
    sAngleNode.text = str(round(math.radians(sAngle), 2))
231

    
232
    sTextNode = Element(SSUB_TEXT)
233
    sTextNode.text = sText
234

    
235
    sStartPointNode = Element(SSUB_START_POINT)
236
    sStartPointNode.text = str(sSp[0]) + "," + str(sSp[1])
237

    
238
    sSizeNode = Element(SSUB_SIZE)
239
    sSizeNode.text = str(sWidth) + "," + str(sHeight)
240

    
241
    sCategoryNode.append(sNameNode)
242
    sCategoryNode.append(sTypeNode)
243
    sCategoryNode.append(sOriginalPointNode)
244
    sCategoryNode.append(sConnectionPointNode)
245
    sCategoryNode.append(sBaseSymbolNode)
246
    sCategoryNode.append(sAngleNode)
247
    sCategoryNode.append(sTextNode)
248
    sCategoryNode.append(sStartPointNode)
249
    sCategoryNode.append(sSizeNode)
250

    
251
    return sCategoryNode
252

    
253
def getTextInfoNode(textInfo):
254
    text = textInfo.getText()
255
    x = textInfo.getX()
256
    y = textInfo.getY()
257
    w = textInfo.getW()
258
    h = textInfo.getH()
259
    angle = textInfo.getAngle()
260

    
261
    tInfoNode = Element(TEXT_INFO_NODE_NAME)
262

    
263
    textNode = Element(TTEXT_NODE_NAME)
264
    textNode.text = text
265

    
266
    xNode = Element(TTEXT_X_NODE_NAME)
267
    xNode.text = str(x)
268

    
269
    yNode = Element(TTEXT_Y_NODE_NAME)
270
    yNode.text = str(y)
271

    
272
    widthNode = Element(TTEXT_WIDTH_NODE_NAME)
273
    widthNode.text = str(w)
274

    
275
    heightNode = Element(TTEXT_HEIGHT_NODE_NAME)
276
    heightNode.text = str(h)
277

    
278
    angleNode = Element(TTEXT_ANGLE_NODE_NAME)
279
    angleNode.text = str(round(math.radians(angle), 2))
280
    
281
    tInfoNode.append(textNode)
282
    tInfoNode.append(xNode)
283
    tInfoNode.append(yNode)
284
    tInfoNode.append(widthNode)
285
    tInfoNode.append(heightNode)
286
    tInfoNode.append(angleNode)
287

    
288
    return tInfoNode
289

    
290
def getNoteTextInfoNode(noteTextInfo):
291
    text = noteTextInfo.getText()
292
    x = noteTextInfo.getX()
293
    y = noteTextInfo.getY()
294
    w = noteTextInfo.getW()
295
    h = noteTextInfo.getH()
296
    angle = noteTextInfo.getAngle()
297

    
298
    ntInfoNode = Element(NOTE_TEXT_INFO_NOTE_NAME)
299

    
300
    textNode = Element(TNOTE_TEXT_NODE_NAME)
301
    textNode.text = text
302

    
303
    xNode = Element(TNOTE_TEXT_X_NODE_NAME)
304
    xNode.text = str(x)
305

    
306
    yNode = Element(TNOTE_TEXT_Y_NODE_NAME)
307
    yNode.text = str(y)
308

    
309
    widthNode = Element(TNOTE_TEXT_WIDTH_NODE_NAME)
310
    widthNode.text = str(w)
311

    
312
    heightNode = Element(TNOTE_TEXT_HEIGHT_NODE_NAME)
313
    heightNode.text = str(h)
314

    
315
    angleNode = Element(TNOTE_TEXT_ANGLE_NODE_NAME)
316
    angleNode.text = str(round(math.radians(angle), 2))
317
    
318
    ntInfoNode.append(textNode)
319
    ntInfoNode.append(xNode)
320
    ntInfoNode.append(yNode)
321
    ntInfoNode.append(widthNode)
322
    ntInfoNode.append(heightNode)
323
    ntInfoNode.append(angleNode)
324

    
325
    return ntInfoNode
326

    
327
'''
328
    @brief      Append LineInfo Data
329
    @author     Jeongwoo
330
    @date       2018.05.28
331
'''
332
def appendLineInfo(xmlPath, lineInfo):
333
    tree = parse(xmlPath)
334
    root = tree.getroot()
335
    lineInfosNode = root.find(LINE_INFOS_NODE_NAME)
336
    if lineInfosNode is not None:
337
        lineInfosNode.clear()
338
    else:
339
        lineInfosNode = Element(LINE_INFOS_NODE_NAME)
340
        root.append(lineInfosNode)
341
    for line in lineInfo:
342
        lineInfoNode = Element(LLINE_INFO_NODE_NAME)
343
        #uuidNode = Element(LLINE_UUID)
344
        #uuidNode.text = line.uid
345
        startPointNode = Element(LLINE_START_POINT_NODE_NAME)
346
        startPointNode.text = str(line.startPoint()[0])+","+str(line.startPoint()[1])
347
        endPointNode = Element(LLINE_END_POINT_NODE_NAME)
348
        endPointNode.text = str(line.endPoint()[0])+","+str(line.endPoint()[1])
349
        #lineInfoNode.append(uuidNode)
350
        lineInfoNode.append(startPointNode)
351
        lineInfoNode.append(endPointNode)
352
        lineInfosNode.append(lineInfoNode)
353
        
354

    
355
    ElementTree(root).write(xmlPath)
356
    
357
'''
358
    @brief      Write xml data by scene
359
    @author     Jeongwoo
360
    @date       2018.05.30
361
    @history    2018.05.30  Jeongwoo    Create node by item object
362
                2018.06.12  Jeongwoo    Add if-statement for QEngineeringLineNoTextItem data node
363
                2018.06.14  Jeongwoo    Add if-statement for QEngineeringUnknownItem data node
364
                2018.11.26  euisung     remove scene dependency
365
'''
366
def writeXmlOnScene(pidName, pidWidth, pidHeight):
367
    from EngineeringAbstractItem import QEngineeringAbstractItem
368
    from EngineeringNoteItem import QEngineeringNoteItem
369
    from EngineeringTextItem import QEngineeringTextItem
370
    from EngineeringLineItem import QEngineeringLineItem
371
    from EngineeringLineNoTextItem import QEngineeringLineNoTextItem
372
    from EngineeringUnknownItem import QEngineeringUnknownItem
373
    from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem
374
    from QEngineeringSizeTextItem import QEngineeringSizeTextItem
375
    from QEngineeringTagNoTextItem import QEngineeringTagNoTextItem
376
    from EngineeringValveOperCodeTextItem import QEngineeringValveOperCodeTextItem
377
    from SymbolSvgItem import SymbolSvgItem
378
    from EngineeringVendorItem import QEngineeringVendorItem
379
    from EngineeringErrorItem import QEngineeringErrorItem
380
    from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem
381
    from EngineeringEndBreakItem import QEngineeringEndBreakItem
382

    
383
    appDocData = AppDocData.instance()
384
    items = []
385
    items = appDocData.allItems
386
    path = os.path.join(AppDocData.instance().getCurrentProject().getTempPath(), pidName + '.xml')
387

    
388
    xml = Element(ROOT_NODE_NAME) # Root Node
389
    SubElement(xml, ROOT_DWGNAME_NODE_NAME).text = pidName
390
    SubElement(xml, ROOT_SIZE_NODE_NAME).text = str(pidWidth) + "," + str(pidHeight)
391
    symbolListNode = Element(SYMBOL_LIST_NODE_NAME) # Symbol List Node
392
    textInfoListNode = Element(TEXT_INFO_LIST_NODE_NAME) # Text Info List Node
393
    noteTextInfoListNode = Element(NOTE_TEXT_INFO_LIST_NOTE_NAME)
394
    lineListNode = Element(LINE_INFOS_NODE_NAME)
395
    lineNoListNode = Element(LINE_NOS_NODE_NAME)
396
    unknownListNode = Element(UNKNOWNS_NODE_NAME)
397
    vendorListNode = Element(VENDOR_NODE_NAME)
398

    
399
    node_dictionary = {SymbolSvgItem:symbolListNode, QEngineeringTextItem:textInfoListNode, QEngineeringNoteItem:noteTextInfoListNode, 
400
        QEngineeringLineItem:lineListNode, QEngineeringLineNoTextItem:lineNoListNode, QEngineeringUnknownItem:unknownListNode,
401
        QEngineeringSizeTextItem:textInfoListNode, QEngineeringValveOperCodeTextItem:textInfoListNode, QEngineeringTagNoTextItem:textInfoListNode,
402
        QEngineeringVendorItem:vendorListNode}
403

    
404
    # trim line 추가
405
    trimLineNoListNode = Element(TRIM_LINE_NOS_NODE_NAME)
406
    
407
    try:
408
        resultDic = {}
409

    
410
        for item in items:
411
            key = str(type(item))
412
            if not key in resultDic:
413
                resultDic[key] = [0, []]
414

    
415
            node = None
416
            try:
417
                if type(item) is QEngineeringNoteItem:
418
                    node = item.toXml(name = 'NOTE')
419
                elif type(item) is QEngineeringSizeTextItem:
420
                    node = item.toXml(name='SIZE')
421
                elif type(item) is QEngineeringValveOperCodeTextItem:
422
                    node = item.toXml(name='VALVE OPER CODE')
423
                elif type(item) is QEngineeringTagNoTextItem:
424
                    node = item.toXml(name='TAG NO')
425
                elif issubclass(type(item), QEngineeringAbstractItem) and type(item) is not QGraphicsBoundingBoxItem and type(item) is not QEngineeringErrorItem:
426
                    node = item.toXml()
427
                else:
428
                    continue
429
            except Exception as ex:
430
                from App import App
431
                from AppDocData import MessageType
432

    
433
                message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
434
                App.mainWnd().addMessage.emit(MessageType.Error, message)
435
            finally:
436
                pass
437

    
438
            if node:
439
                resultDic[key][0] += 1
440
                _type = type(item)
441
                if issubclass(type(item), SymbolSvgItem) : _type = SymbolSvgItem
442
                if _type in node_dictionary: node_dictionary[_type].append(node)
443
            else:
444
                resultDic[key][1].append(str(item.uid))
445

    
446
        for line in appDocData.tracerLineNos:
447
            if type(line) is QEngineeringTrimLineNoTextItem:
448
                trimNode = line.toXml()
449
                if trimNode:
450
                    resultDic[str(type(item))][0] += 1
451
                    trimLineNoListNode.append(trimNode)
452
                else:
453
                    resultDic[str(type(item))][1].append(str(line.uid))
454

    
455
        xml.append(symbolListNode)
456
        xml.append(textInfoListNode)
457
        xml.append(noteTextInfoListNode)
458
        xml.append(lineListNode)
459
        xml.append(lineNoListNode)
460
        xml.append(unknownListNode)
461
        xml.append(trimLineNoListNode)
462
        xml.append(vendorListNode)
463
        ElementTree(xml).write(path)
464
    except Exception as ex:
465
        from App import App
466
        from AppDocData import MessageType
467

    
468
        message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)
469
        App.mainWnd().addMessage.emit(MessageType.Error, message)
470

    
471
    return resultDic
472

    
473
def indent(elem, level=0):
474
    i = "\n" + level*"  "
475
    if len(elem):
476
        if not elem.text or not elem.text.strip():
477
            elem.text = i + "  "
478
        if not elem.tail or not elem.tail.strip():
479
            elem.tail = i
480
        for elem in elem:
481
            indent(elem, level+1)
482
        if not elem.tail or not elem.tail.strip():
483
            elem.tail = i
484
    else:
485
        if level and (not elem.tail or not elem.tail.strip()):
486
            elem.tail = i
487

    
488
    return elem
클립보드 이미지 추가 (최대 크기: 500 MB)