#include "graphicsDataModel/baseModel.h" #include "graphicsItem/itemPort.h" #include "graphicsItem/graphicsBaseItem.h" #include "baseProperty.h" #include "topologyManager.h" #include "powerEntity.h" #include "baseModelItem/electricBaseModelLineItem.h" void BaseModel::createTopoTerminalsByItem(GraphicsBaseItem* pItem,ModelFunctionType funType) { PowerEntity* pEntity = pItem->entity(); if(pEntity) { QMap mapPorts = pItem->getPorts(); //创建实体port对应的拓扑port for(auto &port:mapPorts) { TerminalType terType; HandleType tpe = port->getType(); switch (tpe) { case T_lineIn: terType = TerminalType::PowerInput; break; case T_lineOut: terType = TerminalType::PowerOutput; break; case T_lineInOut: terType = TerminalType::PowerConnect; break; case T_newTral: terType = TerminalType::NewTral; break; default: break; } QPointF f = port->pos(); auto pTer = TopologyManager::instance().createTerminal(pEntity->id(),terType,"",port->pos(),port->getId(),funType); if(pTer) pTer->setPortLocate(port->portPos()); } } } QPointF BaseModel::calculateBusPortPos(GraphicsBaseItem* pBus,GraphicsBaseItem* item) { //return QPointF(item->pos().x(),pBus->pos().y()); QRectF recBus = pBus->sceneBoundingRect(); QLineF busLine = QLineF(recBus.left(),recBus.y(),recBus.right(),recBus.y()); QPointF p1 = busLine.p1(); QPointF p2 = busLine.p2(); // 计算item的中心点在垂直于线段方向上的投影 QPointF itemCenter = item->pos();// + QPointF(item->boundingRect().width()/2, item->boundingRect().height()/2); // 计算投影点在线段上的位置 QPointF projection; if (busLine.length() == 0) { // 如果线段长度为0,直接返回端点 projection = p1; } else { // 计算投影点 QPointF vec = p2 - p1; QPointF relPos = itemCenter - p1; qreal dot = QPointF::dotProduct(relPos, vec) / (busLine.length() * busLine.length()); // 限制投影点在线段范围内 dot = qBound(0.0, dot, 1.0); projection = p1 + dot * vec; } return projection; } ItemPort* BaseModel::getClosestUnusedPort(QMap mapPorts,GraphicsBaseItem* item,ModelFunctionType nType) { QMap mapDistance; // 收集所有端口及其距离 for(auto& port: mapPorts) { double dis = distanceBetweenItems(port, item); mapDistance.insert(dis, port); } for(auto& port:mapDistance){ //从小到大遍历 auto lst = TopologyManager::instance().getConnectionsForTerminal(port->getId(),nType); if(lst.isEmpty()){ //没被占用 return port; } } return nullptr; } template void BaseModel::establishConnection(GraphicsBaseItem* pSrc,GraphicsBaseItem* pDest,TypeLine* pItem,ModelFunctionType nType,int nMode,int nParam) { ItemPort* pSrcPort = nullptr; ItemPort* pDestPort = nullptr; int nTypeSrc = pSrc->getProperty()->type(); int nTypeDest = pDest->getProperty()->type(); //if(pSrc->getItemType() == GIT_baseBus) if((nTypeSrc == 1 || nTypeSrc == 0) && (nTypeDest != 1 && nTypeDest != 0)) //src是母线或节点 { int index = 0; if(nTypeSrc == 1 ) index = pSrc->addPort(p_movable,pSrc->mapFromScene(calculateBusPortPos(pSrc,pDest))); else index = pSrc->addPort(p_movable,QPoint(0,0)); //节点port与自身坐标重合 createTopoTerminalsByItem(pSrc,nType); pSrcPort = pSrc->getPortPtr(index); QMap mapPorts = pDest->getPorts(); if(nMode == 0){ pDestPort = getClosestUnusedPort(mapPorts,pSrc,nType); } else if(nMode == 1){ for(auto& port:mapPorts) //连接中性点 { int nTpe = port->getType(); int nPos = port->portPos(); if(nTpe == T_newTral){ if(nParam == 0){ if(nPos == P_top){ pDestPort = port; } } else if(nParam == 1){ if(nPos == P_left || nPos == P_right){ pDestPort = port; } } else if(nParam == 2){ if(nPos == P_down){ pDestPort = port; } } } } } else if(nMode == 2){ for(auto& port:mapPorts) //连接非中性点 { int nTpe = port->getType(); int nPos = port->portPos(); if(nTpe != T_newTral){ if(nParam == 0){ if(nPos == P_top){ pDestPort = port; } } else if(nParam == 1){ if(nPos == P_left || nPos == P_right){ pDestPort = port; } } else if(nParam == 2){ if(nPos == P_down){ pDestPort = port; } } } } } } else if((nTypeDest == 1 || nTypeDest == 0) && (nTypeSrc != 1 && nTypeSrc != 0)) { int index = 0; if(nTypeDest == 1 ) index = pDest->addPort(p_movable,pDest->mapFromScene(calculateBusPortPos(pDest,pSrc))); else index = pDest->addPort(p_movable,QPoint(0,0)); //节点port与自身坐标重合 createTopoTerminalsByItem(pDest,nType); pDestPort = pDest->getPortPtr(index); QMap mapPorts = pSrc->getPorts(); if(nMode == 0){ pSrcPort = getClosestUnusedPort(mapPorts,pDest,nType); } else if(nMode == 1){ for(auto& port:mapPorts) //连接中性点 { int nTpe = port->getType(); int nPos = port->portPos(); if(nTpe == T_newTral){ if(nParam == 0){ if(nPos == P_top){ pSrcPort = port; } } else if(nParam == 1){ if(nPos == P_left || nPos == P_right){ pSrcPort = port; } } else if(nParam == 2){ if(nPos == P_down){ pSrcPort = port; } } } } } else if(nMode == 2){ for(auto& port:mapPorts) //连接非中性点 { int nTpe = port->getType(); int nPos = port->portPos(); if(nTpe != T_newTral){ if(nParam == 0){ if(nPos == P_top){ pSrcPort = port; } } else if(nParam == 1){ if(nPos == P_left || nPos == P_right){ pSrcPort = port; } } else if(nParam == 2){ if(nPos == P_down){ pSrcPort = port; } } } } } } else if((nTypeSrc == 1 || nTypeSrc == 0) && (nTypeDest == 1 || nTypeDest == 0)){ //两个都是母线或节点 int index = 0; if(nTypeSrc == 1 ) index = pSrc->addPort(p_movable,pSrc->mapFromScene(calculateBusPortPos(pSrc,pDest))); else index = pSrc->addPort(p_movable,QPoint(0,0)); //节点port与自身坐标重合 createTopoTerminalsByItem(pSrc,nType); pSrcPort = pSrc->getPortPtr(index); index = 0; if(nTypeDest == 1 ) index = pDest->addPort(p_movable,pDest->mapFromScene(calculateBusPortPos(pDest,pSrc))); else index = pDest->addPort(p_movable,QPoint(0,0)); //节点port与自身坐标重合 createTopoTerminalsByItem(pDest,nType); pDestPort = pDest->getPortPtr(index); } else { QMap mapSrc = pSrc->getPorts(); QMap mapDest = pDest->getPorts(); pSrcPort = nullptr; pDestPort = nullptr; if(nMode == 1){ //连接中性点 if(nTypeSrc == 15 || nTypeSrc == 16){ //src是变压器中性点 for(auto& port:mapSrc) //连接中性点 { int nTpe = port->getType(); int nPos = port->portPos(); if(nTpe == T_newTral){ if(nParam == 0){ if(nPos == P_top){ pSrcPort = port; } } else if(nParam == 1){ if(nPos == P_left || nPos == P_right){ pSrcPort = port; } } else if(nParam == 2){ if(nPos == P_down){ pSrcPort = port; } } } } for(auto& port:mapDest) { if(port->getType() == T_lineIn) { pDestPort = port; break; } } } else if(nTypeDest == 15 || nTypeDest == 16){ //dest是变压器中性点 for(auto& port:mapSrc) { if(port->getType() == T_lineIn) //始终从中性点出 { pSrcPort = port; break; } } for(auto& port:mapDest) //连接中性点 { int nTpe = port->getType(); int nPos = port->portPos(); if(nTpe == T_newTral){ if(nParam == 0){ if(nPos == P_top){ pDestPort = port; } } else if(nParam == 1){ if(nPos == P_left || nPos == P_right){ pDestPort = port; } } else if(nParam == 2){ if(nPos == P_down){ pDestPort = port; } } } } } } else if(nMode == 2){ //连接变压器 if(nTypeSrc == 15 || nTypeSrc == 16){ //src是变压器 for(auto& port:mapSrc) { int nTpe = port->getType(); int nPos = port->portPos(); if(nTpe != T_newTral){ if(nParam == 0){ if(nPos == P_top){ pSrcPort = port; } } else if(nParam == 1){ if(nPos == P_left || nPos == P_right){ pSrcPort = port; } } else if(nParam == 2){ if(nPos == P_down){ pSrcPort = port; } } } } int transType = 0; if(pSrcPort){ transType = pSrcPort->getType(); } for(auto& port:mapDest) //根据变压器端点选择连接端点类型 { if(transType == T_lineOut) { if(port->getType() == T_lineIn) { pDestPort = port; break; } } else{ if(port->getType() == T_lineOut) { pDestPort = port; break; } } } } else if(nTypeDest == 15 || nTypeDest == 16){ //dest是变压器 for(auto& port:mapDest) { int nTpe = port->getType(); int nPos = port->portPos(); if(nTpe != T_newTral){ if(nParam == 0){ if(nPos == P_top){ pDestPort = port; } } else if(nParam == 1){ if(nPos == P_left || nPos == P_right){ pDestPort = port; } } else if(nParam == 2){ if(nPos == P_down){ pDestPort = port; } } } } int transType = 0; if(pDestPort){ transType = pDestPort->getType(); } for(auto& port:mapSrc) //根据变压器端点选择连接端点类型 { if(transType == T_lineOut) { if(port->getType() == T_lineIn) { pSrcPort = port; break; } } else{ if(port->getType() == T_lineOut) { pSrcPort = port; break; } } } } } else{ for(auto& port:mapSrc) { if(port->getType() == T_lineOut) { pSrcPort = port; break; } } for(auto& port:mapDest) { if(port->getType() == T_lineIn) { pDestPort = port; break; } } } } if(pSrcPort && pDestPort) { QPointF srcPortPos = pSrcPort->scenePos(); QPointF destPortPos = pDestPort->scenePos(); pItem->setStartPoint(srcPortPos); pItem->setEndPoint(destPortPos); pItem->calculatePath(); PowerConnection* pCon = TopologyManager::instance().createConnection(pItem->itemId().toString(),pSrcPort->getId(),pDestPort->getId(),pSrc->itemId().toString(),pDest->itemId().toString(),nType); //创建拓扑连接(逻辑) if(pCon) pCon->setState(DataState::changed); pItem->getProperty()->setConnection(Connection(pSrc->itemId(),QUuid(pSrcPort->getId()),pSrcPort->getType(),pSrcPort->portPos(),pDest->itemId(),QUuid(pDestPort->getId()),pDestPort->getType(),pDestPort->portPos())); } } template void BaseModel::establishConnection(GraphicsBaseItem*,GraphicsBaseItem*,ElectricBaseModelLineItem*,ModelFunctionType,int,int);