DiagramDesigner/diagramCavas/source/graphicsDataModel/baseModel.cpp

455 lines
16 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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<QString,ItemPort*> 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<QString,ItemPort*> mapPorts,GraphicsBaseItem* item,ModelFunctionType nType)
{
QMap<double,ItemPort*> 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<typename TypeLine> 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<QString,ItemPort*> 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<QString,ItemPort*> 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<QString,ItemPort*> mapSrc = pSrc->getPorts();
QMap<QString,ItemPort*> 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<ElectricBaseModelLineItem>(GraphicsBaseItem*,GraphicsBaseItem*,ElectricBaseModelLineItem*,ModelFunctionType,int,int);