개정판 d58a00de
insert symbol to line test
Change-Id: I9a26b880739b601f22f1e5edc7cda9bc7167c2c0
DTI_PID/DTI_PID/QtImageViewer.py | ||
---|---|---|
631 | 631 |
x.split(',')[0], float(x.split(',')[1]), float(x.split(',')[2])) \ |
632 | 632 |
for x in strConnPts.split('/')] |
633 | 633 |
|
634 |
svg.buildItem(svg_file_name, symbol.getType(), 0, None, None, None, connPts, symbol.getBaseSymbol(),
|
|
634 |
svg.buildItem(svg_file_name, symbol.getType(), 0, None, [symbol.width, symbol.height], None, connPts, symbol.getBaseSymbol(),
|
|
635 | 635 |
symbol.getAdditionalSymbol(), symbol.getHasInstrumentLabel()) |
636 | 636 |
|
637 | 637 |
return svg |
... | ... | |
650 | 650 |
from EngineeringLineItem import QEngineeringLineItem |
651 | 651 |
from SymbolSvgItem import SymbolSvgItem |
652 | 652 |
from EngineeringUnknownItem import QEngineeringUnknownItem |
653 |
from EngineeringAbstractItem import QEngineeringAbstractItem |
|
654 |
|
|
653 | 655 |
import math |
654 | 656 |
from App import App |
655 | 657 |
from AppDocData import AppDocData |
... | ... | |
671 | 673 |
#matches = [item for item in scene.items() if |
672 | 674 |
# (type(item) is QEngineeringLineItem) and (item.distanceTo((scenePos.x(), scenePos.y())) < 20)] |
673 | 675 |
allowed_error = 0.0001 |
674 |
if False: # len(matches) == 1: |
|
675 |
matches[0].insertSymbol(svg, scenePos) |
|
676 |
elif len(connectors) == 1 and len(svg.connectors) >= 2 and len(connectors[0].parentItem().connectors): |
|
677 |
# item assistant with line connection |
|
676 |
if len(connectors) == 1 and len(svg.connectors) >= 2 and len(connectors[0].parentItem().connectors): |
|
677 |
# item assistant with connection |
|
678 | 678 |
xl = connectors[0].parentItem().symbolOrigin[0] - connectors[0].connectPoint[0] |
679 | 679 |
yl = connectors[0].parentItem().symbolOrigin[1] - connectors[0].connectPoint[1] |
680 | 680 |
length = math.sqrt(xl * xl + yl * yl) |
... | ... | |
733 | 733 |
break |
734 | 734 |
connectors[0].connect(svg) |
735 | 735 |
#connectors[0].highlight(False) |
736 |
elif not strict and len(items) == 1 and type(items[0]) is QEngineeringLineItem and items[0].length() > svg.size[0] and items[0].length() > svg.size[1]: |
|
737 |
vec = items[0].perpendicular() |
|
738 |
line = [(scenePos.x() - vec[0] * 20, scenePos.y() - vec[1] * 20), (scenePos.x() + vec[0] * 20, scenePos.y() + vec[1] * 20)] |
|
739 |
origin = items[0].intersection(line) |
|
740 |
configs = AppDocData.instance().getConfigs('Data', 'Grid') |
|
741 |
grid = int(configs[0].value) if 1 == len(configs) else -1 |
|
742 |
if grid == 1: |
|
743 |
svg.origin = [round(origin.x), round(origin.y)] |
|
744 |
svg.loc = [round(origin.x - svg.symbolOrigin[0]), round(origin.y - svg.symbolOrigin[1])] |
|
745 |
else: |
|
746 |
svg.origin = [round(origin.x, 1), round(origin.y, 1)] |
|
747 |
svg.loc = [round(origin.x - svg.symbolOrigin[0], 1), round(origin.y - svg.symbolOrigin[1], 1)] |
|
748 |
svg.angle = items[0].angle() |
|
749 |
|
|
750 |
svg.addSvgItemToScene(scene, True if not auto else False) |
|
751 |
|
|
752 |
if len(svg.connectors) > 1: |
|
753 |
connectors = [svg.connectors[0], svg.connectors[1]] |
|
754 |
connectors.sort(key=lambda x: abs(x.center()[0] - items[0].connectors[0].center()[0]) + abs(x.center()[1] - items[0].connectors[0].center()[1])) |
|
755 |
|
|
756 |
savedConnectors = [] |
|
757 |
for _connector in items[0].connectors: |
|
758 |
if _connector.connectedItem and _connector._connected_at == QEngineeringAbstractItem.CONNECTED_AT_PT: |
|
759 |
_connectors2 = [_connector2 for _connector2 in _connector.connectedItem.connectors if _connector2.connectedItem is items[0] and _connector2._connected_at == QEngineeringAbstractItem.CONNECTED_AT_PT] |
|
760 |
if _connectors2: |
|
761 |
savedConnectors.append(_connectors2[0]) |
|
762 |
continue |
|
763 |
savedConnectors.append(None) |
|
764 |
|
|
765 |
inLine = QEngineeringLineItem(vertices=[items[0].start_point(), connectors[0].center()]) |
|
766 |
inLine.transfer.onRemoved.connect(App.mainWnd().itemRemoved) |
|
767 |
inLine.lineType = items[0].lineType |
|
768 |
|
|
769 |
outLine = QEngineeringLineItem(vertices=[connectors[1].center(), items[0].end_point()]) |
|
770 |
outLine.transfer.onRemoved.connect(App.mainWnd().itemRemoved) |
|
771 |
outLine.lineType = items[0].lineType |
|
772 |
|
|
773 |
inLine.connectors[0].connect(items[0].connectors[0].connectedItem, items[0].connectors[0]._connected_at) |
|
774 |
inLine.connectors[1].connect(svg) |
|
775 |
connectors[0].connect(inLine) |
|
776 |
outLine.connectors[0].connect(svg) |
|
777 |
outLine.connectors[1].connect(items[0].connectors[1].connectedItem, items[0].connectors[1]._connected_at) |
|
778 |
connectors[1].connect(outLine) |
|
779 |
|
|
780 |
if savedConnectors[0]: |
|
781 |
savedConnectors[0].connect(inLine) |
|
782 |
if savedConnectors[1]: |
|
783 |
savedConnectors[1].connect(outLine) |
|
784 |
|
|
785 |
scene.addItem(inLine) |
|
786 |
scene.addItem(outLine) |
|
787 |
items[0].transfer.onRemoved.emit(items[0]) |
|
788 |
|
|
736 | 789 |
elif not strict: |
737 | 790 |
svg.angle = angle if angle else 0.0 |
738 | 791 |
svg.flip = flip if flip else 0 |
739 | 792 |
configs = AppDocData.instance().getConfigs('Data', 'Grid') |
740 | 793 |
grid = int(configs[0].value) if 1 == len(configs) else -1 |
741 |
svg.loc = [round(scenePos.x() - svg.symbolOrigin[0], 1), round(scenePos.y() - svg.symbolOrigin[1], 1)] |
|
742 | 794 |
if grid == 1: |
743 | 795 |
svg.origin = [round(scenePos.x()), round(scenePos.y())] |
744 | 796 |
svg.loc = [round(scenePos.x() - svg.symbolOrigin[0]), round(scenePos.y() - svg.symbolOrigin[1])] |
DTI_PID/DTI_PID/Shapes/EngineeringLineItem.py | ||
---|---|---|
331 | 331 |
dist = line.distance(Point(pt[0], pt[1])) |
332 | 332 |
|
333 | 333 |
return dist |
334 |
|
|
335 |
def insert_symbol(self, symbol, pos: QPointF): |
|
336 |
"""split line and join symbol and line""" |
|
337 |
import math |
|
338 |
from App import App |
|
339 |
from shapely.geometry import Point, LineString |
|
340 |
from shapely import affinity |
|
341 |
|
|
342 |
def perpendicular(pts): |
|
343 |
import math |
|
344 |
|
|
345 |
dx, dy = pts[1][0] - pts[0][0], pts[1][1] - pts[0][1] |
|
346 |
dx, dy = -dy, dx |
|
347 |
length = math.sqrt(dx * dx + dy * dy) |
|
348 |
dx /= length |
|
349 |
dy /= length |
|
350 |
|
|
351 |
return (dx, dy) |
|
352 |
|
|
353 |
def intersection(pts, line): |
|
354 |
import math |
|
355 |
from shapely.geometry import Point, LineString |
|
356 |
|
|
357 |
start_pt, end_pt = pts[0], pts[1] |
|
358 |
dx, dy = end_pt[0] - start_pt[0], end_pt[1] - start_pt[1] |
|
359 |
length = math.sqrt(dx * dx + dy * dy) |
|
360 |
if length == 0: |
|
361 |
return None |
|
362 |
dx /= length |
|
363 |
dy /= length |
|
364 |
lhs = LineString( |
|
365 |
[(start_pt[0] - dx * 20, start_pt[1] - dy * 20), (end_pt[0] + dx * 20, end_pt[1] + dy * 20)]) |
|
366 |
rhs = LineString(line) |
|
367 |
return lhs.intersection(rhs) |
|
368 |
|
|
369 |
def dot_product(lhs, rhs): |
|
370 |
return sum([lhs[i] * rhs[i] for i in range(len(lhs))]) |
|
371 |
|
|
372 |
def angle(pts): |
|
373 |
import math |
|
374 |
|
|
375 |
start_pt, end_pt = pts[0], pts[1] |
|
376 |
dx, dy = end_pt[0] - start_pt[0], end_pt[1] - start_pt[1] |
|
377 |
dot = dot_product((1, 0), (dx, dy)) |
|
378 |
length = math.sqrt(dx * dx + dy * dy) |
|
379 |
return math.acos(dot / length) |
|
380 |
|
|
381 |
try: |
|
382 |
x1, y1, x2, y2 = self.line().x1(), self.line().y1(), self.line().x2(), self.line().y2() |
|
383 |
path = QPainterPath() |
|
384 |
path.moveTo(x1, y1) |
|
385 |
path.lineTo(x2, y2) |
|
386 |
|
|
387 |
pts = [] |
|
388 |
for idx in range(path.elementCount()): |
|
389 |
ele = path.elementAt(idx) |
|
390 |
if ele.isMoveTo(): |
|
391 |
pts.clear() |
|
392 |
pts.append((ele.x, ele.y)) |
|
393 |
elif ele.isLineTo(): |
|
394 |
if len(pts) > 1: |
|
395 |
pts.pop(0) |
|
396 |
|
|
397 |
pts.append((ele.x, ele.y)) |
|
398 |
|
|
399 |
vec = perpendicular(pts) |
|
400 |
line = [(pos.x() - vec[0] * 20, pos.y() - vec[1] * 20), |
|
401 |
(pos.x() + vec[0] * 20, pos.y() + vec[1] * 20)] |
|
402 |
origin = intersection(pts, line) |
|
403 |
if type(origin) is Point: |
|
404 |
dx, dy = origin.x - pos.x(), origin.y - pos.y() |
|
405 |
length = math.sqrt(dx ** 2 + dy ** 2) |
|
406 |
|
|
407 |
symbol.moveBy(origin.x - pos.x(), origin.y - pos.y()) |
|
408 |
symbol.loc = [round(origin.x - symbol.symbolOrigin[0], 1), |
|
409 |
round(origin.y - symbol.symbolOrigin[1], 1)] |
|
410 |
symbol.size = [symbol.boundingRect().width(), symbol.boundingRect().height()] |
|
411 |
symbol.angle = round(angle(pts), 2) |
|
412 |
symbol.setRotation(math.radians(-symbol.angle)) |
|
413 |
|
|
414 |
if 2 == len(symbol.connectors): # 2 way component |
|
415 |
symbol_connectors = symbol.connectors |
|
416 |
|
|
417 |
dx1 = symbol_connectors[0].center()[0] - pts[0][0] |
|
418 |
dy1 = symbol_connectors[0].center()[1] - pts[0][1] |
|
419 |
length1 = math.sqrt(dx1 * dx1 + dy1 * dy1) |
|
420 |
dx2 = symbol_connectors[1].center()[0] - pts[0][0] |
|
421 |
dy2 = symbol_connectors[1].center()[1] - pts[0][1] |
|
422 |
length2 = math.sqrt(dx2 * dx2 + dy2 * dy2) |
|
423 |
|
|
424 |
if length1 < length2: |
|
425 |
_vertices = [] |
|
426 |
"""create a new line""" |
|
427 |
_vertices.append(self.start_point()) |
|
428 |
_vertices.append(symbol_connectors[0].center()) |
|
429 |
new_line = QEngineeringLineItem(_vertices) |
|
430 |
self.scene().addItem(new_line) |
|
431 |
|
|
432 |
if self.connectors[0].connectedItem: |
|
433 |
new_line.connectors[0].connect(self.connectors[0].connectedItem) |
|
434 |
|
|
435 |
new_line.connectors[1].connect(symbol) |
|
436 |
symbol_connectors[0].connect(new_line) |
|
437 |
# |
|
438 |
#"""update stream line""" |
|
439 |
_vertices.clear() |
|
440 |
_vertices.append(symbol_connectors[1].center()) |
|
441 |
_vertices.append(self.end_point()) |
|
442 |
self.setLine(_vertices[0][0], _vertices[0][1], _vertices[1][0], _vertices[1][1]) |
|
443 |
self.connectors[0].connect(symbol) |
|
444 |
symbol_connectors[1].connect(self) |
|
445 |
self.scene().update() |
|
446 |
#"""up to here""" |
|
447 |
return |
|
448 |
else: |
|
449 |
"""create a new line""" |
|
450 |
_vertices = [] |
|
451 |
_vertices.append(self.start_point()) |
|
452 |
_vertices.append(symbol_connectors[1].center()) |
|
453 |
new_line = QEngineeringLineItem(_vertices) |
|
454 |
self.scene().addItem(new_line) |
|
455 |
|
|
456 |
if self.connectors[0].connectedItem: |
|
457 |
new_line.connectors[0].connect(self.connectors[0].connectedItem) |
|
458 |
|
|
459 |
new_line.connectors[1].connect(symbol) |
|
460 |
symbol_connectors[1].connect(new_line) |
|
461 |
|
|
462 |
#"""up to here""" |
|
463 |
|
|
464 |
_vertices.clear() |
|
465 |
connector_center = symbol_connectors[0].center() |
|
466 |
_vertices.append([connector_center[0], connector_center[1]]) |
|
467 |
_vertices.append(self.end_point()) |
|
468 |
self.setLine(_vertices[0][0], _vertices[0][1], _vertices[1][0], _vertices[1][1]) |
|
469 |
self.connectors[0].connect(symbol) |
|
470 |
symbol_connectors[0].connect(self) |
|
471 |
self.scene().update() |
|
472 |
return |
|
473 |
|
|
474 |
|
|
475 |
""" |
|
476 |
symbol.loc = [origin.x - symbol.symbolOrigin[0], origin.y - symbol.symbolOrigin[1]] |
|
477 |
symbol.size = [symbol.boundingRect().width(), symbol.boundingRect().height()] |
|
478 |
self.scene().addItem(symbol) |
|
479 |
""" |
|
480 |
except Exception as ex: |
|
481 |
from App import App |
|
482 |
from AppDocData import MessageType |
|
483 |
|
|
484 |
message = f"error occurred({repr(ex)}) in {sys.exc_info()[-1].tb_frame.f_code.co_filename}:" \ |
|
485 |
f"{sys.exc_info()[-1].tb_lineno}" |
|
486 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
|
487 | 334 |
|
488 | 335 |
''' |
489 | 336 |
@brief return perpendicular vector |
... | ... | |
1208 | 1055 |
sys.exc_info()[-1].tb_lineno) |
1209 | 1056 |
App.mainWnd().addMessage.emit(MessageType.Error, message) |
1210 | 1057 |
|
1211 |
''' |
|
1212 |
@breif insert symbol |
|
1213 |
@author humkyung |
|
1214 |
@date 2018.04.22 |
|
1215 |
@history kyouho 2018.07.24 add symbol angle, transform rotateRadians(-angle -> angle) |
|
1216 |
''' |
|
1217 |
|
|
1218 |
def insertSymbol(self, symbol, pos): |
|
1219 |
import math |
|
1220 |
from shapely.geometry import Point |
|
1221 |
from shapely import affinity |
|
1222 |
|
|
1223 |
vec = self.perpendicular() |
|
1224 |
line = [(pos.x() - vec[0] * 20, pos.y() - vec[1] * 20), (pos.x() + vec[0] * 20, pos.y() + vec[1] * 20)] |
|
1225 |
origin = self.intersection(line) |
|
1226 |
transform = QTransform() |
|
1227 |
transform.translate(origin.x, origin.y) |
|
1228 |
angle = self.angle() |
|
1229 |
transform.rotateRadians(-angle) |
|
1230 |
transform.translate(-symbol.symbolOrigin[0], -symbol.symbolOrigin[1]) |
|
1231 |
symbol.setTransform(transform) |
|
1232 |
# save angle |
|
1233 |
symbol.angle = round(angle, 2) |
|
1234 |
if 2 == len(symbol.connectors): # 2 way component |
|
1235 |
for i in range(len(symbol.connectors)): |
|
1236 |
rotatedPt = affinity.rotate(Point(symbol.connectors[i].connectPoint[0] - symbol.symbolOrigin[0], |
|
1237 |
symbol.connectors[i].connectPoint[1] - symbol.symbolOrigin[1]), |
|
1238 |
-angle, Point(0, 0), use_radians=True) |
|
1239 |
#symbol.connectors[i].sceneConnectPoint = (origin.x + rotatedPt.x, origin.y + rotatedPt.y) |
|
1240 |
|
|
1241 |
dx1 = symbol.connectors[0].center()[0] - self.start_point()[0] |
|
1242 |
dy1 = symbol.connectors[0].center()[1] - self.start_point()[1] |
|
1243 |
length1 = math.sqrt(dx1 * dx1 + dy1 * dy1) |
|
1244 |
dx2 = symbol.connectors[1].center()[0] - self.start_point()[0] |
|
1245 |
dy2 = symbol.connectors[1].center()[1] - self.start_point()[1] |
|
1246 |
length2 = math.sqrt(dx2 * dx2 + dy2 * dy2) |
|
1247 |
|
|
1248 |
if length1 < length2: |
|
1249 |
processLine = QEngineeringLineItem([symbol.connectors[1].center(), self.end_point()]) |
|
1250 |
processLine.connectors[0].connectedItem = symbol |
|
1251 |
processLine.connectors[1].connectedItem = self.connectors[1].connectedItem |
|
1252 |
self.scene().addItem(processLine) |
|
1253 |
|
|
1254 |
line = QLineF(self.line().p1(), QPointF(symbol.connectors[0].center()[0], |
|
1255 |
symbol.connectors[0].center()[1])) |
|
1256 |
self.setLine(line) |
|
1257 |
self.connectors[1].connectedItem = symbol |
|
1258 |
|
|
1259 |
symbol.connectors[0].connectedItem = self |
|
1260 |
symbol.connectors[1].connectedItem = processLine |
|
1261 |
else: |
|
1262 |
processLine = QEngineeringLineItem([symbol.connectors[0].center(), self.end_point()]) |
|
1263 |
processLine.connectors[0].connectedItem = symbol |
|
1264 |
processLine.connectors[1].connectedItem = self.connectors[1].connectedItem |
|
1265 |
self.scene().addItem(processLine) |
|
1266 |
|
|
1267 |
line = QLineF(self.line().p1(), QPointF(symbol.connectors[1].center()[0], |
|
1268 |
symbol.connectors[1].center()[1])) |
|
1269 |
self.setLine(line) |
|
1270 |
self.connectors[1].connectedItem = symbol |
|
1271 |
|
|
1272 |
symbol.connectors[0].connectedItem = processLine |
|
1273 |
symbol.connectors[1].connectedItem = self |
|
1274 |
|
|
1275 |
self.joinTo(symbol) |
|
1276 |
processLine.joinTo(symbol) |
|
1277 |
self.update() |
|
1278 |
|
|
1279 |
symbol.loc = [origin.x - symbol.symbolOrigin[0], origin.y - symbol.symbolOrigin[1]] |
|
1280 |
symbol.size = [symbol.boundingRect().width(), symbol.boundingRect().height()] |
|
1281 |
self.scene().addItem(symbol) |
|
1282 |
|
|
1283 | 1058 |
def update_shape(self, symbol, point): |
1284 | 1059 |
"""update line shape""" |
1285 | 1060 |
for index in range(len(self.connectors)): |
내보내기 Unified diff