개정판 baf331db
fixed issue #622:
- save item's area
DTI_PID/DTI_PID/AppDocData.py | ||
---|---|---|
48 | 48 |
image = ImageQt(self.getPyImageOnRect(rect)) |
49 | 49 |
return image.convertToFormat(QImage.Format_RGBA8888) |
50 | 50 |
|
51 |
class Area: |
|
52 |
def __init__(self): |
|
53 |
self.name = None |
|
54 |
self.x = None |
|
55 |
self.y = None |
|
56 |
self.width = None |
|
57 |
self.height = None |
|
58 |
|
|
59 |
''' |
|
60 |
@brief parse area |
|
61 |
@author humkyung |
|
62 |
@date 2018.06.29 |
|
63 |
''' |
|
64 |
def parse(self, strArea): |
|
65 |
import re |
|
66 |
|
|
67 |
found = re.findall('\d+', strArea) |
|
68 |
if len(found) == 4: |
|
69 |
self.x = int(found[0]) |
|
70 |
self.y = int(found[1]) |
|
71 |
self.width = int(found[2]) |
|
72 |
self.height = int(found[3]) |
|
73 |
|
|
74 |
''' |
|
75 |
@brief to string |
|
76 |
@author humkyung |
|
77 |
@date 2018.06.30 |
|
78 |
''' |
|
79 |
def toString(self): |
|
80 |
return '({},{}),({},{})'.format(self.x, self.y, self.width, self.height) |
|
81 |
|
|
82 |
''' |
|
83 |
@brief clone an object |
|
84 |
''' |
|
85 |
def clone(self): |
|
86 |
clone = Area() |
|
87 |
clone.x = self.x |
|
88 |
clone.y = self.y |
|
89 |
clone.width = self.width |
|
90 |
clone.height = self.height |
|
91 |
|
|
92 | 51 |
class Config: |
93 | 52 |
def __init__(self, section, key, value): |
94 | 53 |
self.section = section |
... | ... | |
141 | 100 |
|
142 | 101 |
self._areas = [] |
143 | 102 |
self.equipments = [] |
144 |
#self.equipmentDataList = [] |
|
145 | 103 |
self.lineNos = [] |
146 | 104 |
self.lines = [] |
105 |
self.texts = [] |
|
147 | 106 |
self.symbols = [] |
148 | 107 |
self._colors = None |
149 | 108 |
self._lineTypes = None |
... | ... | |
152 | 111 |
self._hmbTable = None |
153 | 112 |
|
154 | 113 |
''' |
114 |
@brief clear |
|
115 |
@author humkyung |
|
116 |
@date 2018.09.06 |
|
117 |
''' |
|
118 |
def clear(self): |
|
119 |
self._imgFilePath = None |
|
120 |
self.imgName = None |
|
121 |
self.imgWidth = 0 |
|
122 |
self.imgHeight = 0 |
|
123 |
self._imgSrc = None |
|
124 |
|
|
125 |
self._areas.clear() |
|
126 |
self.equipments.clear() |
|
127 |
self.lineNos.clear() |
|
128 |
self.lines.clear() |
|
129 |
self.texts.clear() |
|
130 |
self.symbols.clear() |
|
131 |
self._colors = None |
|
132 |
self._lineTypes = None |
|
133 |
self._lineTypeConfigs = None |
|
134 |
self._activeDrawing = None |
|
135 |
self._hmbTable = None |
|
136 |
|
|
137 |
''' |
|
155 | 138 |
@brief Get DB file path in ProgramData |
156 | 139 |
@author Jeongwoo |
157 | 140 |
@date 2018.06.27 |
... | ... | |
931 | 914 |
@author humkyung |
932 | 915 |
''' |
933 | 916 |
def getAreaList(self): |
917 |
from Area import Area |
|
918 |
|
|
934 | 919 |
if len(self._areas) == 0: |
935 | 920 |
try: |
936 | 921 |
# Creates or opens a file called mydb with a SQLite3 DB |
937 |
dbPath = self.getCurrentProject().getDbFilePath() + "/ITI_PID.db"
|
|
922 |
dbPath = os.path.join(self.getCurrentProject().getDbFilePath(), 'ITI_PID.db')
|
|
938 | 923 |
conn = sqlite3.connect(dbPath) |
939 | 924 |
# Get a cursor object |
940 | 925 |
cursor = conn.cursor() |
... | ... | |
943 | 928 |
cursor.execute(sql) |
944 | 929 |
rows = cursor.fetchall() |
945 | 930 |
for row in rows: |
946 |
area = Area()
|
|
947 |
area.name = row[1]
|
|
931 |
name = row[1]
|
|
932 |
area = Area(name)
|
|
948 | 933 |
area.parse(row[2]) |
949 | 934 |
self._areas.append(area) |
950 | 935 |
# Catch the exception |
DTI_PID/DTI_PID/Area.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
|
|
3 |
import sys |
|
4 |
import os |
|
5 |
|
|
6 |
class Area: |
|
7 |
def __init__(self, name): |
|
8 |
self._name = name |
|
9 |
self.x = None |
|
10 |
self.y = None |
|
11 |
self.width = None |
|
12 |
self.height = None |
|
13 |
|
|
14 |
''' |
|
15 |
@brief getter of name |
|
16 |
@author humkyung |
|
17 |
@date 2018.09.06 |
|
18 |
''' |
|
19 |
@property |
|
20 |
def name(self): |
|
21 |
return self._name |
|
22 |
|
|
23 |
''' |
|
24 |
@brief setter of name |
|
25 |
@author humkyung |
|
26 |
@date 2018.09.06 |
|
27 |
''' |
|
28 |
@name.setter |
|
29 |
def name(self, value): |
|
30 |
self._name = value |
|
31 |
|
|
32 |
''' |
|
33 |
@brief parse area |
|
34 |
@author humkyung |
|
35 |
@date 2018.06.29 |
|
36 |
''' |
|
37 |
def parse(self, strArea): |
|
38 |
import re |
|
39 |
|
|
40 |
found = re.findall('\d+', strArea) |
|
41 |
if len(found) == 4: |
|
42 |
self.x = int(found[0]) |
|
43 |
self.y = int(found[1]) |
|
44 |
self.width = int(found[2]) |
|
45 |
self.height = int(found[3]) |
|
46 |
|
|
47 |
''' |
|
48 |
@brief check if given point exists in area |
|
49 |
@author humkyung |
|
50 |
@date 2018.09.06 |
|
51 |
''' |
|
52 |
def contains(self, pt): |
|
53 |
if len(pt) == 2: |
|
54 |
if pt[0] < self.x: return False |
|
55 |
if pt[0] > self.x + self.width: return False |
|
56 |
if pt[1] < self.y: return False |
|
57 |
if pt[1] > self.y + self.height: return False |
|
58 |
elif len(pt) == 4: |
|
59 |
minx = pt[0] |
|
60 |
miny = pt[1] |
|
61 |
maxx = pt[2] |
|
62 |
maxy = pt[3] |
|
63 |
|
|
64 |
if minx < self.x: return False |
|
65 |
if maxx > self.x + self.width: return False |
|
66 |
if miny < self.y: return False |
|
67 |
if maxy > self.y + self.height: return False |
|
68 |
|
|
69 |
return True |
|
70 |
|
|
71 |
''' |
|
72 |
@brief to string |
|
73 |
@author humkyung |
|
74 |
@date 2018.06.30 |
|
75 |
''' |
|
76 |
def toString(self): |
|
77 |
return '({},{}),({},{})'.format(self.x, self.y, self.width, self.height) |
|
78 |
|
|
79 |
''' |
|
80 |
@brief clone an object |
|
81 |
''' |
|
82 |
def clone(self): |
|
83 |
clone = Area(self._name) |
|
84 |
clone.x = self.x |
|
85 |
clone.y = self.y |
|
86 |
clone.width = self.width |
|
87 |
clone.height = self.height |
DTI_PID/DTI_PID/Commands/AreaOcrCommand.py | ||
---|---|---|
14 | 14 |
import sys |
15 | 15 |
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + '\\Shapes') |
16 | 16 |
from EngineeringTextItem import QEngineeringTextItem |
17 |
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
|
|
17 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
18 | 18 |
from QEngineeringNoteItem import QEngineeringNoteItem |
19 | 19 |
from TextItemFactory import TextItemFactory |
20 | 20 |
from AppDocData import AppDocData |
DTI_PID/DTI_PID/Commands/DefaultCommand.py | ||
---|---|---|
46 | 46 |
''' |
47 | 47 |
def execute(self, param): |
48 | 48 |
from SymbolSvgItem import SymbolSvgItem |
49 |
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
|
|
49 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
50 | 50 |
|
51 | 51 |
event = param[1] |
52 | 52 |
scenePos = param[2] |
DTI_PID/DTI_PID/ConfigurationAreaDialog.py | ||
---|---|---|
7 | 7 |
import sqlite3 |
8 | 8 |
|
9 | 9 |
from AppDocData import AppDocData, Config |
10 |
from AppDocData import Area
|
|
10 |
from Area import Area
|
|
11 | 11 |
|
12 | 12 |
sys.path.insert(0, os.path.dirname(os.path.realpath(__file__)) + '\\Commands') |
13 | 13 |
import CreateCommand |
... | ... | |
103 | 103 |
self.ui.tableWidgetEquipmentDescArea.setRowCount(len(configs)) |
104 | 104 |
row = 0 |
105 | 105 |
for config in configs: |
106 |
area = Area() |
|
106 |
area = Area('')
|
|
107 | 107 |
area.parse(config.value) |
108 | 108 |
|
109 | 109 |
boundingBox = QGraphicsBoundingBoxItem(area.x, area.y, area.width, area.height) |
DTI_PID/DTI_PID/ConnectAttrDialog.py | ||
---|---|---|
10 | 10 |
from AppDocData import * |
11 | 11 |
from LineDetector import LineDetector |
12 | 12 |
from EngineeringLineItem import QEngineeringLineItem |
13 |
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
|
|
13 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
14 | 14 |
from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem |
15 | 15 |
from SymbolSvgItem import SymbolSvgItem |
16 | 16 |
from EngineeringTextItem import QEngineeringTextItem |
DTI_PID/DTI_PID/DTI_PID.py | ||
---|---|---|
822 | 822 |
from shapely.geometry import Point, LineString |
823 | 823 |
from SymbolSvgItem import SymbolSvgItem |
824 | 824 |
from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem |
825 |
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
|
|
825 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
826 | 826 |
from EngineeringTextItem import QEngineeringTextItem |
827 | 827 |
from EngineeringLineItem import QEngineeringLineItem |
828 | 828 |
from LineDetector import LineDetector |
DTI_PID/DTI_PID/ItemDataExportDialog.py | ||
---|---|---|
419 | 419 |
if not self.parent.graphicsView.hasImage(): |
420 | 420 |
return |
421 | 421 |
|
422 |
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
|
|
422 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
423 | 423 |
items = [item for item in self.parent.graphicsView.scene.items() if type(item) is QEngineeringLineNoTextItem] |
424 | 424 |
for item in items: |
425 | 425 |
text = item.text() |
DTI_PID/DTI_PID/ItemPropertyTableWidget.py | ||
---|---|---|
16 | 16 |
import math |
17 | 17 |
import re |
18 | 18 |
from SymbolSvgItem import SymbolSvgItem |
19 |
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
|
|
19 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
20 | 20 |
from EngineeringLineItem import QEngineeringLineItem |
21 | 21 |
from QEngineeringNoteItem import QEngineeringNoteItem |
22 | 22 |
from EngineeringTextItem import QEngineeringTextItem |
DTI_PID/DTI_PID/ItemTreeWidget.py | ||
---|---|---|
17 | 17 |
from SymbolSvgItem import SymbolSvgItem |
18 | 18 |
from EngineeringTextItem import QEngineeringTextItem |
19 | 19 |
from QEngineeringNoteItem import QEngineeringNoteItem |
20 |
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
|
|
20 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
21 | 21 |
from QEngineeringEquipmentItem import QEngineeringEquipmentItem |
22 | 22 |
from QEngineeringInstrumentItem import QEngineeringInstrumentItem |
23 | 23 |
from QEngineeringTrimLineNoTextItem import QEngineeringTrimLineNoTextItem |
DTI_PID/DTI_PID/LineNoTracer.py | ||
---|---|---|
12 | 12 |
import shapely |
13 | 13 |
from AppDocData import AppDocData |
14 | 14 |
from EngineeringLineItem import QEngineeringLineItem |
15 |
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
|
|
15 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
16 | 16 |
from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem |
17 | 17 |
from SymbolSvgItem import SymbolSvgItem |
18 | 18 |
from EngineeringTextItem import QEngineeringTextItem |
DTI_PID/DTI_PID/MainWindow.py | ||
---|---|---|
32 | 32 |
from SymbolSvgItem import SymbolSvgItem |
33 | 33 |
from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem |
34 | 34 |
from EngineeringTextItem import QEngineeringTextItem |
35 |
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
|
|
35 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
36 | 36 |
from QEngineeringNoteItem import QEngineeringNoteItem |
37 | 37 |
from QEngineeringSizeTextItem import QEngineeringSizeTextItem |
38 | 38 |
from EngineeringUnknownItem import QEngineeringUnknownItem |
... | ... | |
273 | 273 |
|
274 | 274 |
QMessageBox.about(self.graphicsView, "알림", resultStr) |
275 | 275 |
|
276 |
|
|
277 | 276 |
''' |
278 | 277 |
@brief refresh resultPropertyTableWidget |
279 | 278 |
@author kyouho |
... | ... | |
1034 | 1033 |
humkyung 2018.06.11 display difference between original and recognized image |
1035 | 1034 |
Jeongwoo 2018.06.18 Update Scene after all item added |
1036 | 1035 |
''' |
1037 |
def drawDetectedItems(self, symbolList, textInfoList, noteTextInfoList):
|
|
1036 |
def drawDetectedItems(self, symbolList, textInfoList, otherTextInfoList):
|
|
1038 | 1037 |
QApplication.processEvents() |
1039 | 1038 |
self.drawDetectedSymbolItem(symbolList) |
1040 | 1039 |
QApplication.processEvents() |
1041 | 1040 |
self.drawDetectedTextItem(textInfoList) |
1042 | 1041 |
QApplication.processEvents() |
1043 |
self.drawDetectedNoteItem(noteTextInfoList)
|
|
1042 |
self.drawDetectedOtherTextItem(otherTextInfoList)
|
|
1044 | 1043 |
|
1045 | 1044 |
# Update Scene |
1046 | 1045 |
self.graphicsView.scene.update(self.graphicsView.sceneRect()) |
... | ... | |
1056 | 1055 |
lines = [] |
1057 | 1056 |
for pts in lineList: |
1058 | 1057 |
processLine = QEngineeringLineItem(vertices=[(area.x + param[0], area.y + param[1]) for param in pts]) |
1058 |
processLine.area = 'Drawing' |
|
1059 | 1059 |
self.graphicsView.scene.addItem(processLine) |
1060 | 1060 |
lines.append(processLine) |
1061 | 1061 |
|
... | ... | |
1100 | 1100 |
svg = SymbolSvgItem.createItem(_type, svgFilePath) |
1101 | 1101 |
svg.buildItem(name, _type, angle, pt, size, origin, connPts, parentSymbol, childSymbol, hasInstrumentLabel) |
1102 | 1102 |
svg.reCalculationRotatedItem() |
1103 |
svg.area = 'Drawing' |
|
1103 | 1104 |
|
1104 | 1105 |
# set owner - 2018.07.20 added by humkyung |
1105 | 1106 |
matches = [searched for searched in searchedMap if searched[0] == symbol.owner] |
... | ... | |
1118 | 1119 |
# Equipment Item 경우 저장 |
1119 | 1120 |
if type(svg) is QEngineeringInstrumentItem: |
1120 | 1121 |
svg.saveInstData() |
1121 |
|
|
1122 | 1122 |
else: |
1123 | 1123 |
item = QGraphicsBoundingBoxItem(pt[0], pt[1], size[0], size[1]) |
1124 | 1124 |
item.isSymbol = True |
... | ... | |
1136 | 1136 |
def drawDetectedTextItem(self, textInfoList): |
1137 | 1137 |
from TextItemFactory import TextItemFactory |
1138 | 1138 |
import math |
1139 |
|
|
1139 | 1140 |
try: |
1141 |
appDocData = AppDocData.instance() |
|
1142 |
|
|
1140 | 1143 |
# parse texts |
1141 | 1144 |
for textInfo in textInfoList: |
1142 | 1145 |
x = textInfo.getX() |
... | ... | |
1152 | 1155 |
item.size = (width, height) |
1153 | 1156 |
item.angle = angle |
1154 | 1157 |
item.setPlainText(text) |
1158 |
item.area = 'Drawing' |
|
1155 | 1159 |
item.transfer.onRemoved.connect(self.itemRemoved) |
1156 | 1160 |
self.addTextItemToScene(item) |
1161 |
appDocData.texts.append(item) |
|
1157 | 1162 |
|
1158 | 1163 |
# Line No Text Item 경우 저장 |
1159 | 1164 |
if type(item) is QEngineeringLineNoTextItem: |
1160 | 1165 |
item.saveLineData() |
1161 |
|
|
1162 | 1166 |
except Exception as ex: |
1163 | 1167 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
1164 | 1168 |
self.addMessage.emit(MessageType.Error, message) |
1165 | 1169 |
|
1166 |
def drawDetectedNoteItem(self, noteTextInfoList): |
|
1170 |
''' |
|
1171 |
@brief draw detected texts except which in drawing area |
|
1172 |
''' |
|
1173 |
def drawDetectedOtherTextItem(self, otherTextInfoList): |
|
1167 | 1174 |
from TextItemFactory import TextItemFactory |
1168 | 1175 |
import math |
1176 |
|
|
1169 | 1177 |
try: |
1178 |
appDocData = AppDocData.instance() |
|
1179 |
|
|
1170 | 1180 |
# parse notes |
1171 |
for note in noteTextInfoList: |
|
1172 |
x = note.getX() |
|
1173 |
y = note.getY() |
|
1174 |
width = note.getW() |
|
1175 |
height = note.getH() |
|
1176 |
angle = round(math.radians(note.getAngle())) |
|
1177 |
text = note.getText() |
|
1178 |
item = TextItemFactory.instance().createTextItem(text) |
|
1179 |
item.loc = (x, y) |
|
1180 |
item.size = (width, height) |
|
1181 |
item.angle = angle |
|
1182 |
item.setPlainText(text) |
|
1183 |
self.addTextItemToScene(item) |
|
1181 |
for textInfoMap in otherTextInfoList: |
|
1182 |
for textInfo in textInfoMap[1]: |
|
1183 |
x = textInfo.getX() |
|
1184 |
y = textInfo.getY() |
|
1185 |
width = textInfo.getW() |
|
1186 |
height = textInfo.getH() |
|
1187 |
angle = round(math.radians(textInfo.getAngle())) |
|
1188 |
text = textInfo.getText() |
|
1189 |
item = TextItemFactory.instance().createTextItem(text) |
|
1190 |
item.loc = (x, y) |
|
1191 |
item.size = (width, height) |
|
1192 |
item.angle = angle |
|
1193 |
item.setPlainText(text) |
|
1194 |
item.area = textInfoMap[0] |
|
1195 |
self.addTextItemToScene(item) |
|
1196 |
appDocData.texts.append(item) |
|
1184 | 1197 |
except Exception as ex: |
1185 | 1198 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
1186 | 1199 |
self.addMessage.emit(MessageType.Error, message) |
... | ... | |
1243 | 1256 |
approx = cv2.approxPolyDP(contour, epsilon, True) |
1244 | 1257 |
approx = [pt[0] for pt in approx] |
1245 | 1258 |
item = QEngineeringUnknownItem(approx) |
1259 |
item.ara = 'Drawing' |
|
1246 | 1260 |
diffItems.append(item) |
1247 | 1261 |
# up to here |
1248 | 1262 |
|
... | ... | |
1332 | 1346 |
|
1333 | 1347 |
# parse texts |
1334 | 1348 |
for text in root.iter('ATTRIBUTE'): |
1335 |
location = text.find('LOCATION').text if text.find('LOCATION') is not None else '0,0' |
|
1336 |
x = float(location.split(',')[0]) |
|
1337 |
y = float(location.split(',')[1]) |
|
1338 |
width = float(text.find('WIDTH').text) if text.find('WIDTH') is not None else 0 |
|
1339 |
height = float(text.find('HEIGHT').text) if text.find('HEIGHT') is not None else 0 |
|
1340 |
angle = float(text.find('ANGLE').text) if text.find('ANGLE') is not None else 0 |
|
1341 |
value = text.find('VALUE').text |
|
1342 |
uid = text.find('UID') |
|
1343 |
attributeValue = text.find('ATTRIBUTEVALUE') |
|
1344 |
name = text.find('NAME').text |
|
1345 |
if name == 'TEXT': |
|
1346 |
item = TextItemFactory.instance().createTextItem(value) |
|
1347 |
if item is not None: |
|
1348 |
item.loc = (x, y) |
|
1349 |
item.size = (width, height) |
|
1350 |
item.angle = angle |
|
1351 |
item.setPlainText(value) |
|
1352 |
item.transfer.onRemoved.connect(self.itemRemoved) |
|
1353 |
self.addTextItemToScene(item) |
|
1349 |
item = QEngineeringTextItem.fromXml(text) |
|
1350 |
if item is not None: |
|
1351 |
uid = text.find('UID') |
|
1352 |
attributeValue = text.find('ATTRIBUTEVALUE') |
|
1353 |
name = text.find('NAME').text |
|
1354 |
item.transfer.onRemoved.connect(self.itemRemoved) |
|
1355 |
self.addTextItemToScene(item) |
|
1356 |
|
|
1357 |
if name == 'TEXT': |
|
1354 | 1358 |
if uid is not None and attributeValue is not None: |
1355 | 1359 |
item.uid = uid.text |
1356 | 1360 |
item.attribute = attributeValue.text |
1357 |
elif name == 'NOTE': |
|
1358 |
item = TextItemFactory.instance().createTextItem(value) |
|
1359 |
if item is not None: |
|
1360 |
item.loc = (x, y) |
|
1361 |
item.size = (width, height) |
|
1362 |
item.angle = angle |
|
1363 |
item.setPlainText(value) |
|
1364 |
self.addTextItemToScene(item) |
|
1361 |
elif name == 'NOTE': |
|
1365 | 1362 |
if uid is not None: |
1366 | 1363 |
item.uid = uid.text |
1367 | 1364 |
|
... | ... | |
1452 | 1449 |
for connectedItem in lineRunItem.items: |
1453 | 1450 |
if issubclass(type(connectedItem), SymbolSvgItem): self.resultTreeWidget.addTreeItem(treeItem, connectedItem) |
1454 | 1451 |
docData.lineNos.append(item) |
1455 |
|
|
1456 |
|
|
1457 |
|
|
1458 | 1452 |
# up to here |
1459 | 1453 |
|
1460 | 1454 |
# set symbol's connectItem |
... | ... | |
1534 | 1528 |
return |
1535 | 1529 |
|
1536 | 1530 |
try: |
1537 |
docData = AppDocData.instance()
|
|
1531 |
appDocData = AppDocData.instance()
|
|
1538 | 1532 |
|
1539 |
docData.lines.clear() |
|
1540 |
docData.lines = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineItem and item.owner is None] |
|
1533 |
## collect items |
|
1534 |
appDocData.lines.clear() |
|
1535 |
appDocData.lines = [item for item in self.graphicsView.scene.items() if type(item) is QEngineeringLineItem and item.owner is None] |
|
1541 | 1536 |
|
1542 |
docData.symbols.clear()
|
|
1543 |
docData.symbols = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem) and item.owner is None]
|
|
1537 |
appDocData.symbols.clear()
|
|
1538 |
appDocData.symbols = [item for item in self.graphicsView.scene.items() if issubclass(type(item), SymbolSvgItem) and item.owner is None]
|
|
1544 | 1539 |
|
1545 |
docData.equipments.clear()
|
|
1540 |
appDocData.equipments.clear()
|
|
1546 | 1541 |
for item in self.graphicsView.scene.items(): |
1547 | 1542 |
if type(item) is QEngineeringEquipmentItem: |
1548 |
docData.equipments.append(item) |
|
1543 |
appDocData.equipments.append(item) |
|
1544 |
|
|
1545 |
appDocData.texts.clear() |
|
1546 |
appDocData.texts = [item for item in self.graphicsView.scene.items() if issubclass(type(item), QEngineeringTextItem) and type(item) is not QEngineeringLineNoItem] |
|
1547 |
## up to here |
|
1549 | 1548 |
|
1550 |
docData.imgOutput = np.ones((docData.imgHeight, docData.imgWidth), np.uint8)*255
|
|
1549 |
appDocData.imgOutput = np.ones((docData.imgHeight, docData.imgWidth), np.uint8)*255
|
|
1551 | 1550 |
xg.writeOutputXml(docData.imgName, docData.imgWidth, docData.imgHeight) # TODO: check |
1552 | 1551 |
project = docData.getCurrentProject() |
1553 |
cv2.imwrite(os.path.join(project.getTempPath() , 'OUTPUT.png') , docData.imgOutput)
|
|
1552 |
cv2.imwrite(os.path.join(project.getTempPath() , 'OUTPUT.png') , appDocData.imgOutput)
|
|
1554 | 1553 |
except Exception as ex: |
1555 | 1554 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
1556 | 1555 |
self.addMessage.emit(MessageType.Error, message) |
DTI_PID/DTI_PID/RecognitionDialog.py | ||
---|---|---|
13 | 13 |
from AppDocData import * |
14 | 14 |
from LineDetector import LineDetector |
15 | 15 |
from EngineeringLineItem import QEngineeringLineItem |
16 |
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
|
|
16 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
17 | 17 |
from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem |
18 | 18 |
from SymbolSvgItem import SymbolSvgItem |
19 | 19 |
from EngineeringTextItem import QEngineeringTextItem |
... | ... | |
29 | 29 |
#region Global variables |
30 | 30 |
searchedSymbolList = [] |
31 | 31 |
textInfoList = [] |
32 |
noteTextInfoList = [] |
|
33 | 32 |
|
34 | 33 |
src = [] |
35 | 34 |
|
... | ... | |
196 | 195 |
global threadLock |
197 | 196 |
global searchedSymbolList |
198 | 197 |
global textInfoList |
199 |
global noteTextInfoList |
|
200 | 198 |
global maxProgressValue |
201 | 199 |
|
202 | 200 |
try: |
... | ... | |
210 | 208 |
type(item) is QEngineeringUnknownItem] |
211 | 209 |
for item in items: |
212 | 210 |
worker.graphicsView.scene.removeItem(item) |
211 |
|
|
212 |
appDocData.equipments.clear() |
|
213 |
appDocData.symbols.clear() |
|
214 |
appDocData.lineNos.clear() |
|
215 |
appDocData.texts.clear() |
|
213 | 216 |
#up to here |
214 | 217 |
|
215 | 218 |
srcList = [] |
... | ... | |
287 | 290 |
worker.displayTitle.emit('텍스트 인식 중...') |
288 | 291 |
textDetector.recognizeText(appDocData.imgSrc, offset, textAreas, searchedSymbolList, worker, listWidget, maxProgressValue) |
289 | 292 |
textInfoList = textDetector.textInfoList.copy() if textDetector.textInfoList is not None else None |
290 |
noteTextInfoList = textDetector.noteTextInfoList.copy() if textDetector.noteTextInfoList is not None else None
|
|
293 |
otherTextInfoList = textDetector.otherTextInfoList.copy() if textDetector.otherTextInfoList is not None else None
|
|
291 | 294 |
|
292 | 295 |
appDocData.imgWidth, appDocData.imgHeight = appDocData.imgSrc.shape[::-1] |
293 | 296 |
Worker.drawFoundSymbolsOnCanvas(mainRes, textInfoList, listWidget) |
... | ... | |
327 | 330 |
loop = QEventLoop() |
328 | 331 |
listWidget.addItem('인식 정보 생성 중...') |
329 | 332 |
worker.displayTitle.emit('인식 정보 생성 중...') |
330 |
drawDetectedItems.emit(searchedSymbolList, textInfoList, noteTextInfoList if noteTextInfoList is not None else [], loop)
|
|
333 |
drawDetectedItems.emit(searchedSymbolList, textInfoList, otherTextInfoList if otherTextInfoList is not None else [], loop)
|
|
331 | 334 |
loop.exec_() |
332 | 335 |
## up to here |
333 | 336 |
except Exception as ex: |
... | ... | |
349 | 352 |
from shapely.geometry import Point, LineString |
350 | 353 |
from SymbolSvgItem import SymbolSvgItem |
351 | 354 |
from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem |
352 |
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
|
|
355 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
353 | 356 |
from EngineeringTextItem import QEngineeringTextItem |
354 | 357 |
from EngineeringLineItem import QEngineeringLineItem |
355 | 358 |
from LineDetector import LineDetector |
... | ... | |
357 | 360 |
try: |
358 | 361 |
listWidget.addItem('Starting line recognization') |
359 | 362 |
worker.displayTitle.emit('라인 인식 중...') |
360 |
|
|
363 |
|
|
364 |
appDocData = AppDocData.instance() |
|
361 | 365 |
#remove already existing line and flow arrow item |
362 | 366 |
items = [item for item in worker.graphicsView.scene.items() if (type(item) is QEngineeringLineItem) or (type(item) is QEngineeringFlowArrowItem)] |
363 | 367 |
for item in items: |
364 | 368 |
worker.graphicsView.scene.removeItem(item) |
369 |
|
|
370 |
appDocData.lines.clear() |
|
365 | 371 |
#up to here |
366 | 372 |
|
367 | 373 |
# detect line |
368 | 374 |
connectedLines = [] |
369 | 375 |
|
370 |
area = AppDocData.instance().getArea('Drawing')
|
|
376 |
area = appDocData.getArea('Drawing')
|
|
371 | 377 |
area.img = worker.removeSmallObjects(area.img) |
372 | 378 |
detector = LineDetector(area.img) |
373 | 379 |
|
... | ... | |
1187 | 1193 |
|
1188 | 1194 |
global ocrCompletedSrc |
1189 | 1195 |
global textInfoList |
1190 |
global noteTextInfoList |
|
1191 | 1196 |
|
1192 | 1197 |
try: |
1193 | 1198 |
appDocData = AppDocData.instance() |
... | ... | |
1380 | 1385 |
2018.05.30 Jeongwoo Change method name |
1381 | 1386 |
humkyung 2018.06.09 set progressbar value to maximum |
1382 | 1387 |
''' |
1383 |
def drawDetectedItems(self, symbolList, textInfoList, noteTextInfoList, loop):
|
|
1388 |
def drawDetectedItems(self, symbolList, textInfoList, otherTextInfoList, loop):
|
|
1384 | 1389 |
try: |
1385 | 1390 |
self.ui.progressBar.setValue(self.ui.progressBar.maximum()) |
1386 |
self.parent.drawDetectedItems(symbolList, textInfoList, noteTextInfoList)
|
|
1391 |
self.parent.drawDetectedItems(symbolList, textInfoList, otherTextInfoList)
|
|
1387 | 1392 |
finally: |
1388 | 1393 |
loop.quit() |
1389 | 1394 |
|
... | ... | |
1410 | 1415 |
from shapely.geometry import Point, LineString |
1411 | 1416 |
from SymbolSvgItem import SymbolSvgItem |
1412 | 1417 |
from QEngineeringFlowArrowItem import QEngineeringFlowArrowItem |
1413 |
from QEngineeringLineNoTextItem import QEngineeringLineNoTextItem
|
|
1418 |
from EngineeringLineNoTextItem import QEngineeringLineNoTextItem |
|
1414 | 1419 |
from EngineeringTextItem import QEngineeringTextItem |
1415 | 1420 |
from EngineeringLineItem import QEngineeringLineItem |
1416 | 1421 |
from LineDetector import LineDetector |
DTI_PID/DTI_PID/Shapes/EngineeringAbstractItem.py | ||
---|---|---|
12 | 12 |
def __init__(self, parent=None): |
13 | 13 |
self._color = self.DEFAULT_COLOR # default color |
14 | 14 |
self._owner = None |
15 |
self._area = None |
|
15 | 16 |
self.connectors = [] |
16 | 17 |
|
17 | 18 |
''' |
... | ... | |
49 | 50 |
self._owner = value |
50 | 51 |
|
51 | 52 |
''' |
53 |
@brief getter of area |
|
54 |
@author humkyung |
|
55 |
@date 2018.09.06 |
|
56 |
''' |
|
57 |
@property |
|
58 |
def area(self): |
|
59 |
return self._area if self._area is not None else 'None' |
|
60 |
|
|
61 |
''' |
|
62 |
@brief setter of area |
|
63 |
@author humkyung |
|
64 |
@date 2018.09.06 |
|
65 |
''' |
|
66 |
@area.setter |
|
67 |
def area(self, value): |
|
68 |
self._area = value |
|
69 |
|
|
70 |
''' |
|
52 | 71 |
@brief write to xml |
53 | 72 |
@author humkyung |
54 | 73 |
@date 2018.05.16 |
DTI_PID/DTI_PID/Shapes/EngineeringLineItem.py | ||
---|---|---|
965 | 965 |
@staticmethod |
966 | 966 |
def fromXml(node): |
967 | 967 |
import uuid |
968 |
from AppDocData import AppDocData |
|
968 | 969 |
|
969 | 970 |
item = None |
970 | 971 |
try: |
... | ... | |
976 | 977 |
|
977 | 978 |
item = QEngineeringLineItem(vertices=[startPoint, endPoint]) |
978 | 979 |
item.lineType = node.find('TYPE').text if node.find('TYPE') is not None else 'Primary' |
980 |
## assign area |
|
981 |
if node.find('AREA') is None: |
|
982 |
appDocData = AppDocData.instance() |
|
983 |
for area in appDocData.getAreaList(): |
|
984 |
if area.contains(startPoint) and area.contains(endPoint): |
|
985 |
item.area = area.name |
|
986 |
break |
|
987 |
else: |
|
988 |
item.area = node.find('AREA').text |
|
989 |
## up to here |
|
990 |
|
|
979 | 991 |
item.uid = uid |
980 | 992 |
|
981 | 993 |
connectors = node.find('CONNECTORS') |
... | ... | |
1027 | 1039 |
typeNode.text = self.lineType |
1028 | 1040 |
node.append(typeNode) |
1029 | 1041 |
|
1042 |
areaNode = Element('AREA') |
|
1043 |
areaNode.text = self.area |
|
1044 |
node.append(areaNode) |
|
1045 |
|
|
1030 | 1046 |
connectorsNode = Element('CONNECTORS') |
1031 | 1047 |
for connector in self.connectors: |
1032 | 1048 |
connectorNode = Element('CONNECTOR') |
... | ... | |
1045 | 1061 |
|
1046 | 1062 |
# up to here |
1047 | 1063 |
except Exception as ex: |
1048 |
return str(self.uid) |
|
1049 | 1064 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
1065 |
return str(self.uid) |
|
1050 | 1066 |
|
1051 | 1067 |
return node |
1052 | 1068 |
|
... | ... | |
1057 | 1073 |
@history 2018.05.29 Add parameter 'self' / Make comments emit() |
1058 | 1074 |
''' |
1059 | 1075 |
def deleteLineItemFromScene(self): |
1060 |
#self.removed.emit(self) |
|
1061 | 1076 |
self.scene().removeItem(self) |
1062 | 1077 |
|
1063 | 1078 |
''' |
DTI_PID/DTI_PID/Shapes/EngineeringLineNoTextItem.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
import os.path |
|
3 |
import sys |
|
4 |
import copy |
|
5 |
try: |
|
6 |
from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
7 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform, QFont |
|
8 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, QGraphicsTextItem |
|
9 |
except ImportError: |
|
10 |
try: |
|
11 |
from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
12 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont |
|
13 |
except ImportError: |
|
14 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
|
15 |
|
|
16 |
from EngineeringPolylineItem import QEngineeringPolylineItem |
|
17 |
from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem |
|
18 |
from UserInputAttribute import UserInputAttribute |
|
19 |
from OcrResultDialog import QOcrResultDialog |
|
20 |
from AppDocData import AppDocData |
|
21 |
from EngineeringTextItem import QEngineeringTextItem |
|
22 |
|
|
23 |
lineColumnList = ['UID', 'LINE_SIZE', 'LINE_SYMBOL', 'LINE_NO', 'LINE_CLASS', 'LINE_ROUTING_FROM', 'LINE_ROUTING_TO', 'SERVICE_FLUID', 'SERVICE_DENSITY', 'SERVICE_STATE', 'OPERATION_CONDITION_TEMP', 'OPERATION_CONDITION_PRESS', 'DESIGN_CONDITION_TEMP', 'DESIGN_CONDITION_PRESS', 'TEST_CONDITION_TEMP', 'TEST_CONDITION_PRESS', 'INSUL_CODE', 'PAINT_CODE', 'NDE_CODE', 'PWHT', 'PNID_NO'] |
|
24 |
|
|
25 |
class QEngineeringLineNoTextItem(QEngineeringTextItem): |
|
26 |
|
|
27 |
''' |
|
28 |
@history 18.05.14 Jeongwoo Add variable self.runs |
|
29 |
humkyung 2018.07.09 add stream no |
|
30 |
''' |
|
31 |
def __init__(self, parent=None): |
|
32 |
QEngineeringTextItem.__init__(self, parent) |
|
33 |
|
|
34 |
self._runs = [] |
|
35 |
|
|
36 |
appDocData = AppDocData.instance() |
|
37 |
attributes = appDocData.getSymbolAttribute('Line No Label') |
|
38 |
self._attrs = [[attr, None] for attr in attributes] |
|
39 |
|
|
40 |
''' |
|
41 |
@brief getter of runs |
|
42 |
@author humkyung |
|
43 |
@date 2018.05.11 |
|
44 |
''' |
|
45 |
@property |
|
46 |
def runs(self): |
|
47 |
return self._runs |
|
48 |
|
|
49 |
''' |
|
50 |
@brief setter of runs |
|
51 |
@author humkyung |
|
52 |
@date 2018.05.11 |
|
53 |
''' |
|
54 |
@runs.setter |
|
55 |
def runs(self, value): |
|
56 |
self._runs = value |
|
57 |
|
|
58 |
def getLongestTwoPoints(self, pts): |
|
59 |
import math |
|
60 |
res = [None, None] |
|
61 |
|
|
62 |
maxDistance = None |
|
63 |
for i in range(len(pts)): |
|
64 |
for j in range(i+1, len(pts)): |
|
65 |
dx = pts[i][0] - pts[j][0] |
|
66 |
dy = pts[i][1] - pts[j][1] |
|
67 |
dist = math.sqrt(dx*dx + dy*dy) |
|
68 |
if (maxDistance is None) or (maxDistance < dist): |
|
69 |
maxDistance = dist |
|
70 |
res[0] = pts[i] |
|
71 |
res[1] = pts[j] |
|
72 |
|
|
73 |
return res |
|
74 |
|
|
75 |
''' |
|
76 |
@brief set attribute |
|
77 |
@author humkyung |
|
78 |
@date 2018.07.20 |
|
79 |
''' |
|
80 |
def setAttribute(self, name, value): |
|
81 |
matches = [attr for attr in self._attrs if attr[0] == name] |
|
82 |
if len(matches) == 1: |
|
83 |
matches[0][1] = value |
|
84 |
|
|
85 |
''' |
|
86 |
@brief get line no attributes |
|
87 |
@author humkyung |
|
88 |
@date 2018.04.24 |
|
89 |
@history humkyung 2018.05.09 evaluate string for Tag Seq No |
|
90 |
kyouho 2018.07.06 add using TextItemFactory.isLineNo method |
|
91 |
''' |
|
92 |
def getLineNoAttributes(self, getLineNo = False): |
|
93 |
res = [] |
|
94 |
|
|
95 |
try: |
|
96 |
docData = AppDocData.instance() |
|
97 |
lineNoconfigs = docData.getConfigs('Line No', 'Configuration') |
|
98 |
|
|
99 |
from TextItemFactory import TextItemFactory |
|
100 |
item = TextItemFactory.instance().isLineNo(self.text()) |
|
101 |
# Line No 부분 |
|
102 |
if item[0]: |
|
103 |
result = item[1] |
|
104 |
configs = lineNoconfigs[0].value.split(self.delimiter) |
|
105 |
lineAttrs = docData.getLineProperties() |
|
106 |
for lineAttr in lineAttrs: |
|
107 |
if lineAttr[3] == 'String': |
|
108 |
find = False |
|
109 |
for attr in self._attrs: |
|
110 |
if type(attr) is UserInputAttribute and attr.attribute == lineAttr[0]: |
|
111 |
find = True |
|
112 |
res.append(attr) |
|
113 |
break; |
|
114 |
if not find: |
|
115 |
newAttr = UserInputAttribute(lineAttr[0], '') |
|
116 |
self._attrs.append(newAttr) |
|
117 |
res.append(newAttr) |
|
118 |
else: |
|
119 |
for i in range(len(configs)): |
|
120 |
if lineAttr[0] == configs[i]: |
|
121 |
res.append((lineAttr[0], result[i])) |
|
122 |
break |
|
123 |
|
|
124 |
if getLineNo: |
|
125 |
res.append(('Line No', self.uid)) |
|
126 |
except Exception as ex: |
|
127 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
128 |
|
|
129 |
return res |
|
130 |
|
|
131 |
''' |
|
132 |
@brief generate xml code |
|
133 |
@author humkyung |
|
134 |
@date 2018.04.23 |
|
135 |
@history humkyung 2018.05.02 write symbol's attribute |
|
136 |
humkyung 2018.05.16 write run information to xml |
|
137 |
''' |
|
138 |
def toXml(self): |
|
139 |
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree |
|
140 |
from EngineeringLineItem import QEngineeringLineItem |
|
141 |
from SymbolSvgItem import SymbolSvgItem |
|
142 |
|
|
143 |
try: |
|
144 |
docData = AppDocData.instance() |
|
145 |
configs = docData.getConfigs('Line No', 'Delimiter') |
|
146 |
delimiter = configs[0].value if 1 == len(configs) else '-' |
|
147 |
lineNoconfigs = docData.getConfigs('Line No', 'Configuration') |
|
148 |
|
|
149 |
node = Element('LINE_NO') |
|
150 |
uidNode = Element('UID') |
|
151 |
uidNode.text = str(self.uid) |
|
152 |
node.append(uidNode) |
|
153 |
|
|
154 |
textNode = Element('TEXT') |
|
155 |
textNode.text = self.text() |
|
156 |
node.append(textNode) |
|
157 |
|
|
158 |
rect = self.sceneBoundingRect() |
|
159 |
locNode = Element('LOCATION') |
|
160 |
locNode.text = '{},{}'.format(rect.left(), rect.top()) |
|
161 |
node.append(locNode) |
|
162 |
|
|
163 |
widthNode = Element('WIDTH') |
|
164 |
widthNode.text = str(rect.width()) |
|
165 |
node.append(widthNode) |
|
166 |
|
|
167 |
heightNode = Element('HEIGHT') |
|
168 |
heightNode.text = str(rect.height()) |
|
169 |
node.append(heightNode) |
|
170 |
|
|
171 |
angleNode = Element('ANGLE') |
|
172 |
angleNode.text = str(self.angle) |
|
173 |
node.append(angleNode) |
|
174 |
|
|
175 |
areaNode = Element('AREA') |
|
176 |
areaNode.text = self.area |
|
177 |
node.append(areaNode) |
|
178 |
|
|
179 |
for run in self.runs: |
|
180 |
node.append(run.toXml()) |
|
181 |
|
|
182 |
attrs = self.getLineNoAttributes() |
|
183 |
for attr in attrs: |
|
184 |
if type(attr) is not UserInputAttribute: |
|
185 |
attrNode = Element('ATTRIBUTE') |
|
186 |
|
|
187 |
uidNode = Element('UID') |
|
188 |
uidNode.text = str(self.uid) |
|
189 |
attrNode.append(uidNode) |
|
190 |
|
|
191 |
nameNode = Element('NAME') |
|
192 |
nameNode.text = str(attr[0]) |
|
193 |
attrNode.append(nameNode) |
|
194 |
|
|
195 |
valueNode = Element('VALUE') |
|
196 |
valueNode.text = str(attr[1]) |
|
197 |
attrNode.append(valueNode) |
|
198 |
|
|
199 |
node.append(attrNode) |
|
200 |
else: |
|
201 |
node.append(attr.toXml()) |
|
202 |
except Exception as ex: |
|
203 |
return str(self.uid) |
|
204 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
205 |
|
|
206 |
return node |
|
207 |
|
|
208 |
''' |
|
209 |
@Override (QEngineeringTextItem) |
|
210 |
@brief get connected items |
|
211 |
@author Jeongwoo |
|
212 |
@date 2018.05.15 |
|
213 |
''' |
|
214 |
def getConnectedItems(self): |
|
215 |
visited = [] |
|
216 |
|
|
217 |
try: |
|
218 |
if self.runs is not None: |
|
219 |
for run in self.runs: |
|
220 |
items = run.items |
|
221 |
if items is not None: |
|
222 |
for item in items: |
|
223 |
pool = [] |
|
224 |
pool.append(item) |
|
225 |
while len(pool) > 0: |
|
226 |
it = pool.pop() |
|
227 |
visited.append(it) |
|
228 |
for connector in it.connectors: |
|
229 |
if (connector.connectedItem is not None) and (connector.connectedItem not in visited): pool.append(connector.connectedItem) |
|
230 |
except Exception as ex: |
|
231 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
232 |
|
|
233 |
return visited |
|
234 |
|
|
235 |
''' |
|
236 |
@brief save Line Data |
|
237 |
@author kyouho |
|
238 |
@date 2018.08.14 |
|
239 |
''' |
|
240 |
def saveLineData(self): |
|
241 |
try: |
|
242 |
docData = AppDocData.instance() |
|
243 |
docData.setLineDataList([self.getLineDataList()]) |
|
244 |
except Exception as ex: |
|
245 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
246 |
return str(self.uid) |
|
247 |
|
|
248 |
''' |
|
249 |
@brief return Line Data List |
|
250 |
@author kyouho |
|
251 |
@date 2018.08.14 |
|
252 |
''' |
|
253 |
def getLineDataList(self): |
|
254 |
dataList = [] |
|
255 |
try: |
|
256 |
import uuid |
|
257 |
global lineColumnList |
|
258 |
|
|
259 |
docData = AppDocData.instance() |
|
260 |
attrs = self.getLineNoAttributes(True) |
|
261 |
|
|
262 |
for index in range(len(lineColumnList)): |
|
263 |
dataList.append('') |
|
264 |
|
|
265 |
dataList[20] = docData.imgName |
|
266 |
|
|
267 |
for attr in attrs: |
|
268 |
if type(attr) is not UserInputAttribute: |
|
269 |
lineProp = docData.getLinePropertiesByUID(attr[0]) |
|
270 |
if lineProp: |
|
271 |
attrName = lineProp[0][1].upper().replace(' ','') |
|
272 |
else: |
|
273 |
attrName = attr[0].upper().replace(' ','') |
|
274 |
data = attr[1] if attr[1] is not None else '' |
|
275 |
if attrName == 'NOMINALDIAMETER': |
|
276 |
dataList[1] = data |
|
277 |
elif attrName == 'FLUIDCODE': |
|
278 |
dataList[2] = data |
|
279 |
dataList[7] = data |
|
280 |
elif attrName == 'TAGSEQNO': |
|
281 |
pass |
|
282 |
elif attrName == 'INSULATIONPURPOSE': |
|
283 |
dataList[16] = data |
|
284 |
elif attrName == 'STREAMNO': |
|
285 |
pass |
|
286 |
elif attrName == 'LINENO': |
|
287 |
dataList[3] = data |
|
288 |
elif attrName == 'PNIDNUMBER': |
|
289 |
pass |
|
290 |
elif attrName == 'PIPINGMATERIALSCLASS': |
|
291 |
dataList[4] = data |
|
292 |
elif attrName == '': |
|
293 |
pass |
|
294 |
else: |
|
295 |
typeUID = attr.attribute |
|
296 |
value = attr.text |
|
297 |
lineAttr = docData.getLinePropertiesByUID(typeUID) |
|
298 |
|
|
299 |
for index in range(len(lineColumnList)): |
|
300 |
if lineColumnList[index] == lineAttr[0][1]: |
|
301 |
dataList[index] = value |
|
302 |
except Exception as ex: |
|
303 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
304 |
|
|
305 |
return dataList |
DTI_PID/DTI_PID/Shapes/EngineeringTextItem.py | ||
---|---|---|
349 | 349 |
return visited |
350 | 350 |
|
351 | 351 |
''' |
352 |
@brief parse xml code |
|
353 |
@author humkyung |
|
354 |
@date 2018.09.15 |
|
355 |
''' |
|
356 |
@staticmethod |
|
357 |
def fromXml(node): |
|
358 |
from TextItemFactory import TextItemFactory |
|
359 |
from AppDocData import AppDocData |
|
360 |
|
|
361 |
item = None |
|
362 |
|
|
363 |
try: |
|
364 |
location = node.find('LOCATION').text if node.find('LOCATION') is not None else '0,0' |
|
365 |
x = float(location.split(',')[0]) |
|
366 |
y = float(location.split(',')[1]) |
|
367 |
width = float(node.find('WIDTH').text) if node.find('WIDTH') is not None else 0 |
|
368 |
height = float(node.find('HEIGHT').text) if node.find('HEIGHT') is not None else 0 |
|
369 |
angle = float(node.find('ANGLE').text) if node.find('ANGLE') is not None else 0 |
|
370 |
value = node.find('VALUE').text |
|
371 |
uid = node.find('UID') |
|
372 |
attributeValue = node.find('ATTRIBUTEVALUE') |
|
373 |
name = node.find('NAME').text |
|
374 |
if name == 'TEXT': |
|
375 |
item = TextItemFactory.instance().createTextItem(value) |
|
376 |
if item is not None: |
|
377 |
item.loc = (x, y) |
|
378 |
item.size = (width, height) |
|
379 |
item.angle = angle |
|
380 |
item.setPlainText(value) |
|
381 |
elif name == 'NOTE': |
|
382 |
item = TextItemFactory.instance().createTextItem(value) |
|
383 |
if item is not None: |
|
384 |
item.loc = (x, y) |
|
385 |
item.size = (width, height) |
|
386 |
item.angle = angle |
|
387 |
item.setPlainText(value) |
|
388 |
|
|
389 |
## assign area |
|
390 |
if item is not None: |
|
391 |
if node.find('AREA') is None: |
|
392 |
appDocData = AppDocData.instance() |
|
393 |
for area in appDocData.getAreaList(): |
|
394 |
if area.contains([x, y]): |
|
395 |
item.area = area.name |
|
396 |
break |
|
397 |
else: |
|
398 |
item.area = node.find('AREA').text |
|
399 |
## up to here |
|
400 |
except Exception as ex: |
|
401 |
from App import App |
|
402 |
from AppDocData import MessageType |
|
403 |
|
|
404 |
message = 'error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno) |
|
405 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
406 |
|
|
407 |
return item |
|
408 |
|
|
409 |
''' |
|
352 | 410 |
@brief generate xml code |
353 | 411 |
@author humkyung |
354 | 412 |
@date 2018.04.23 |
... | ... | |
388 | 446 |
angleNode.text = str(self.angle) |
389 | 447 |
node.append(angleNode) |
390 | 448 |
|
391 |
#rect = self.sceneBoundingRect() |
|
392 | 449 |
widthNode = Element('WIDTH') |
393 |
#widthNode.text = str(rect.width()) |
|
394 | 450 |
widthNode.text = str(self.size[0]) |
395 | 451 |
node.append(widthNode) |
396 | 452 |
|
397 | 453 |
heightNode = Element('HEIGHT') |
398 |
#heightNode.text = str(rect.height()) |
|
399 | 454 |
heightNode.text = str(self.size[1]) |
400 | 455 |
node.append(heightNode) |
456 |
|
|
457 |
areaNode = Element('AREA') |
|
458 |
areaNode.text = self.area |
|
459 |
node.append(areaNode) |
|
401 | 460 |
except Exception as ex: |
402 |
return str(self.uid) |
|
403 | 461 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
462 |
return str(self.uid) |
|
404 | 463 |
|
405 | 464 |
return node |
406 | 465 |
|
DTI_PID/DTI_PID/Shapes/EngineeringUnknownItem.py | ||
---|---|---|
170 | 170 |
''' |
171 | 171 |
@staticmethod |
172 | 172 |
def fromXml(node): |
173 |
from AppDocData import AppDocData |
|
174 |
|
|
173 | 175 |
item = None |
174 | 176 |
try: |
175 | 177 |
location = [float(x) for x in node.find('LOCATION').text.split(',')] |
... | ... | |
177 | 179 |
points = [[int(float(coord)) for coord in pt.split(',')] for pt in node.find('POINTS').text.split('\n')] |
178 | 180 |
|
179 | 181 |
item = QEngineeringUnknownItem(points) |
182 |
if node.find('AREA') is None: |
|
183 |
appDocData = AppDocData.instance() |
|
184 |
|
|
185 |
minx = min([coord[0] for coord in points]) |
|
186 |
maxx = max([coord[0] for coord in points]) |
|
187 |
miny = min([coord[1] for coord in points]) |
|
188 |
maxy = max([coord[1] for coord in points]) |
|
189 |
for area in appDocData.getAreaList(): |
|
190 |
if area.contains([minx, miny, maxx, maxy]): |
|
191 |
item.area = area.name |
|
192 |
break |
|
193 |
else: |
|
194 |
item.area = node.find('AREA').text |
|
180 | 195 |
except Exception as ex: |
181 | 196 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
182 | 197 |
|
... | ... | |
205 | 220 |
sizeNode.text = '{},{}'.format(rect.width(), rect.height()) |
206 | 221 |
node.append(sizeNode) |
207 | 222 |
|
223 |
areaNode = Element('AREA') |
|
224 |
areaNode.text = self.area |
|
225 |
node.append(areaNode) |
|
226 |
|
|
208 | 227 |
ptNode = Element('POINTS') |
209 | 228 |
points = None |
210 | 229 |
for pt in self._pol: |
DTI_PID/DTI_PID/Shapes/QEngineeringLineNoTextItem.py | ||
---|---|---|
1 |
# coding: utf-8 |
|
2 |
import os.path |
|
3 |
import sys |
|
4 |
import copy |
|
5 |
try: |
|
6 |
from PyQt5.QtCore import Qt, QPointF, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
7 |
from PyQt5.QtGui import QImage, QPixmap, QPainterPath, QBrush, QPen, QTransform, QFont |
|
8 |
from PyQt5.QtWidgets import QGraphicsView, QGraphicsScene, QFileDialog, QGraphicsItem, QAbstractGraphicsShapeItem, QGraphicsTextItem |
|
9 |
except ImportError: |
|
10 |
try: |
|
11 |
from PyQt4.QtCore import Qt, QRectF, pyqtSignal, QT_VERSION_STR, QRect |
|
12 |
from PyQt4.QtGui import QGraphicsView, QGraphicsScene, QImage, QPixmap, QPainterPath, QFileDialog, QFont |
|
13 |
except ImportError: |
|
14 |
raise ImportError("ImageViewerQt: Requires PyQt5 or PyQt4.") |
|
15 |
|
|
16 |
from EngineeringPolylineItem import QEngineeringPolylineItem |
|
17 |
from GraphicsBoundingBoxItem import QGraphicsBoundingBoxItem |
|
18 |
from UserInputAttribute import UserInputAttribute |
|
19 |
from OcrResultDialog import QOcrResultDialog |
|
20 |
from AppDocData import AppDocData |
|
21 |
from EngineeringTextItem import QEngineeringTextItem |
|
22 |
|
|
23 |
lineColumnList = ['UID', 'LINE_SIZE', 'LINE_SYMBOL', 'LINE_NO', 'LINE_CLASS', 'LINE_ROUTING_FROM', 'LINE_ROUTING_TO', 'SERVICE_FLUID', 'SERVICE_DENSITY', 'SERVICE_STATE', 'OPERATION_CONDITION_TEMP', 'OPERATION_CONDITION_PRESS', 'DESIGN_CONDITION_TEMP', 'DESIGN_CONDITION_PRESS', 'TEST_CONDITION_TEMP', 'TEST_CONDITION_PRESS', 'INSUL_CODE', 'PAINT_CODE', 'NDE_CODE', 'PWHT', 'PNID_NO'] |
|
24 |
|
|
25 |
class QEngineeringLineNoTextItem(QEngineeringTextItem): |
|
26 |
|
|
27 |
''' |
|
28 |
@history 18.05.14 Jeongwoo Add variable self.runs |
|
29 |
humkyung 2018.07.09 add stream no |
|
30 |
''' |
|
31 |
def __init__(self, parent=None): |
|
32 |
QEngineeringTextItem.__init__(self, parent) |
|
33 |
|
|
34 |
self._runs = [] |
|
35 |
|
|
36 |
appDocData = AppDocData.instance() |
|
37 |
attributes = appDocData.getSymbolAttribute('Line No Label') |
|
38 |
self._attrs = [[attr, None] for attr in attributes] |
|
39 |
|
|
40 |
''' |
|
41 |
@brief getter of runs |
|
42 |
@author humkyung |
|
43 |
@date 2018.05.11 |
|
44 |
''' |
|
45 |
@property |
|
46 |
def runs(self): |
|
47 |
return self._runs |
|
48 |
|
|
49 |
''' |
|
50 |
@brief setter of runs |
|
51 |
@author humkyung |
|
52 |
@date 2018.05.11 |
|
53 |
''' |
|
54 |
@runs.setter |
|
55 |
def runs(self, value): |
|
56 |
self._runs = value |
|
57 |
|
|
58 |
def getLongestTwoPoints(self, pts): |
|
59 |
import math |
|
60 |
res = [None, None] |
|
61 |
|
|
62 |
maxDistance = None |
|
63 |
for i in range(len(pts)): |
|
64 |
for j in range(i+1, len(pts)): |
|
65 |
dx = pts[i][0] - pts[j][0] |
|
66 |
dy = pts[i][1] - pts[j][1] |
|
67 |
dist = math.sqrt(dx*dx + dy*dy) |
|
68 |
if (maxDistance is None) or (maxDistance < dist): |
|
69 |
maxDistance = dist |
|
70 |
res[0] = pts[i] |
|
71 |
res[1] = pts[j] |
|
72 |
|
|
73 |
return res |
|
74 |
|
|
75 |
''' |
|
76 |
@brief set attribute |
|
77 |
@author humkyung |
|
78 |
@date 2018.07.20 |
|
79 |
''' |
|
80 |
def setAttribute(self, name, value): |
|
81 |
matches = [attr for attr in self._attrs if attr[0] == name] |
|
82 |
if len(matches) == 1: |
|
83 |
matches[0][1] = value |
|
84 |
|
|
85 |
''' |
|
86 |
@brief get line no attributes |
|
87 |
@author humkyung |
|
88 |
@date 2018.04.24 |
|
89 |
@history humkyung 2018.05.09 evaluate string for Tag Seq No |
|
90 |
kyouho 2018.07.06 add using TextItemFactory.isLineNo method |
|
91 |
''' |
|
92 |
def getLineNoAttributes(self, getLineNo = False): |
|
93 |
res = [] |
|
94 |
|
|
95 |
try: |
|
96 |
docData = AppDocData.instance() |
|
97 |
lineNoconfigs = docData.getConfigs('Line No', 'Configuration') |
|
98 |
|
|
99 |
from TextItemFactory import TextItemFactory |
|
100 |
item = TextItemFactory.instance().isLineNo(self.text()) |
|
101 |
# Line No 부분 |
|
102 |
if item[0]: |
|
103 |
result = item[1] |
|
104 |
configs = lineNoconfigs[0].value.split(self.delimiter) |
|
105 |
lineAttrs = docData.getLineProperties() |
|
106 |
for lineAttr in lineAttrs: |
|
107 |
if lineAttr[3] == 'String': |
|
108 |
find = False |
|
109 |
for attr in self._attrs: |
|
110 |
if type(attr) is UserInputAttribute and attr.attribute == lineAttr[0]: |
|
111 |
find = True |
|
112 |
res.append(attr) |
|
113 |
break; |
|
114 |
if not find: |
|
115 |
newAttr = UserInputAttribute(lineAttr[0], '') |
|
116 |
self._attrs.append(newAttr) |
|
117 |
res.append(newAttr) |
|
118 |
else: |
|
119 |
for i in range(len(configs)): |
|
120 |
if lineAttr[0] == configs[i]: |
|
121 |
res.append((lineAttr[0], result[i])) |
|
122 |
break |
|
123 |
|
|
124 |
if getLineNo: |
|
125 |
res.append(('Line No', self.uid)) |
|
126 |
except Exception as ex: |
|
127 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
128 |
|
|
129 |
return res |
|
130 |
|
|
131 |
''' |
|
132 |
@brief generate xml code |
|
133 |
@author humkyung |
|
134 |
@date 2018.04.23 |
|
135 |
@history humkyung 2018.05.02 write symbol's attribute |
|
136 |
humkyung 2018.05.16 write run information to xml |
|
137 |
''' |
|
138 |
def toXml(self): |
|
139 |
from xml.etree.ElementTree import Element, SubElement, dump, ElementTree |
|
140 |
from EngineeringLineItem import QEngineeringLineItem |
|
141 |
from SymbolSvgItem import SymbolSvgItem |
|
142 |
|
|
143 |
try: |
|
144 |
docData = AppDocData.instance() |
|
145 |
configs = docData.getConfigs('Line No', 'Delimiter') |
|
146 |
delimiter = configs[0].value if 1 == len(configs) else '-' |
|
147 |
lineNoconfigs = docData.getConfigs('Line No', 'Configuration') |
|
148 |
|
|
149 |
node = Element('LINE_NO') |
|
150 |
uidNode = Element('UID') |
|
151 |
uidNode.text = str(self.uid) |
|
152 |
node.append(uidNode) |
|
153 |
|
|
154 |
textNode = Element('TEXT') |
|
155 |
textNode.text = self.text() |
|
156 |
node.append(textNode) |
|
157 |
|
|
158 |
rect = self.sceneBoundingRect() |
|
159 |
locNode = Element('LOCATION') |
|
160 |
locNode.text = '{},{}'.format(rect.left(), rect.top()) |
|
161 |
node.append(locNode) |
|
162 |
|
|
163 |
widthNode = Element('WIDTH') |
|
164 |
widthNode.text = str(rect.width()) |
|
165 |
node.append(widthNode) |
|
166 |
|
|
167 |
heightNode = Element('HEIGHT') |
|
168 |
heightNode.text = str(rect.height()) |
|
169 |
node.append(heightNode) |
|
170 |
|
|
171 |
angleNode = Element('ANGLE') |
|
172 |
angleNode.text = str(self.angle) |
|
173 |
node.append(angleNode) |
|
174 |
|
|
175 |
for run in self.runs: |
|
176 |
node.append(run.toXml()) |
|
177 |
|
|
178 |
attrs = self.getLineNoAttributes() |
|
179 |
for attr in attrs: |
|
180 |
if type(attr) is not UserInputAttribute: |
|
181 |
attrNode = Element('ATTRIBUTE') |
|
182 |
|
|
183 |
uidNode = Element('UID') |
|
184 |
uidNode.text = str(self.uid) |
|
185 |
attrNode.append(uidNode) |
|
186 |
|
|
187 |
nameNode = Element('NAME') |
|
188 |
nameNode.text = str(attr[0]) |
|
189 |
attrNode.append(nameNode) |
|
190 |
|
|
191 |
valueNode = Element('VALUE') |
|
192 |
valueNode.text = str(attr[1]) |
|
193 |
attrNode.append(valueNode) |
|
194 |
|
|
195 |
node.append(attrNode) |
|
196 |
else: |
|
197 |
node.append(attr.toXml()) |
|
198 |
except Exception as ex: |
|
199 |
return str(self.uid) |
|
200 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
201 |
|
|
202 |
return node |
|
203 |
|
|
204 |
''' |
|
205 |
@Override (QEngineeringTextItem) |
|
206 |
@brief get connected items |
|
207 |
@author Jeongwoo |
|
208 |
@date 2018.05.15 |
|
209 |
''' |
|
210 |
def getConnectedItems(self): |
|
211 |
visited = [] |
|
212 |
|
|
213 |
try: |
|
214 |
if self.runs is not None: |
|
215 |
for run in self.runs: |
|
216 |
items = run.items |
|
217 |
if items is not None: |
|
218 |
for item in items: |
|
219 |
pool = [] |
|
220 |
pool.append(item) |
|
221 |
while len(pool) > 0: |
|
222 |
it = pool.pop() |
|
223 |
visited.append(it) |
|
224 |
for connector in it.connectors: |
|
225 |
if (connector.connectedItem is not None) and (connector.connectedItem not in visited): pool.append(connector.connectedItem) |
|
226 |
except Exception as ex: |
|
227 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
228 |
|
|
229 |
return visited |
|
230 |
|
|
231 |
''' |
|
232 |
@brief save Line Data |
|
233 |
@author kyouho |
|
234 |
@date 2018.08.14 |
|
235 |
''' |
|
236 |
def saveLineData(self): |
|
237 |
try: |
|
238 |
docData = AppDocData.instance() |
|
239 |
docData.setLineDataList([self.getLineDataList()]) |
|
240 |
except Exception as ex: |
|
241 |
return str(self.uid) |
|
242 |
print('error occured({}) in {}:{}'.format(ex, sys.exc_info()[-1].tb_frame.f_code.co_filename, sys.exc_info()[-1].tb_lineno)) |
|
243 |
|
|
244 |
''' |
|
245 |
@brief return Line Data List |
|
246 |
@author kyouho |
내보내기 Unified diff