#include "nmPlotGraphicBinder.h" #include "nmObjLineFault.h" #include "nmDataFault.h" #include "nmObjLineCrack.h" #include "nmDataFracture.h" #include "nmObjRoundOutline.h" #include "nmObjRectOutline.h" #include "nmObjPolygonOutline.h" #include "nmDataOutline.h" #include "nmObjLineMeasure.h" #include "nmDataMeasure.h" #include "nmObjRegionMark.h" #include "nmDataRegionMark.h" #include "nmObjRegion.h" #include "nmDataRegion.h" #include "nmObjBase.h" #include "nmDataAnalyzeManager.h" #include "nmObjPointWell.h" #include "nmDataWellBase.h" #include nmPlotGraphicBinder::nmPlotGraphicBinder(nmDataAnalyzeManager* pDataMgr, QObject* parent) : QObject(parent) , m_pDataMgr(pDataMgr) { } // 用户画完断层后:创建数据对象并建立绑定 void nmPlotGraphicBinder::createFaultForGraphic(nmObjLineFault* pGraphic) { if (!pGraphic || !m_pDataMgr) { return; } // 创建数据对象 nmDataFault* pData = m_pDataMgr->createFault(); // 将图元值推入数据 pData->setFaultName(pGraphic->getName()); pData->setFaultPoints(pGraphic->getAllValues()); // 建立信号连接 _connectFault(pGraphic, pData); m_pDataMgr->notifyDataChanged(); } // 从文件加载:绑定已有数据到已有图元 void nmPlotGraphicBinder::bindFaultToGraphic(nmObjLineFault* pGraphic, nmDataFault* pData) { if (!pGraphic || !pData) { return; } // 将数据值推到图元 _pushFaultDataToGraphic(pGraphic, pData); // 建立信号连接 _connectFault(pGraphic, pData); } // 删除图元:断开连接并移除数据 void nmPlotGraphicBinder::removeFaultBinding(nmObjLineFault* pGraphic) { if (!pGraphic) { return; } // 断开信号 _disconnectFault(pGraphic); // 从数据中心移除 if (m_mapFaultData.contains(pGraphic)) { nmDataFault* pData = m_mapFaultData.value(pGraphic); if (pData && m_pDataMgr) { m_pDataMgr->removeFaultData(pData); } m_mapFaultData.remove(pGraphic); } } nmDataFault* nmPlotGraphicBinder::getFaultDataFor(nmObjLineFault* pGraphic) { return m_mapFaultData.value(pGraphic, nullptr); } // 名称同步:检测图元名称与数据名称是否一致,不一致则同步 void nmPlotGraphicBinder::syncFaultName(nmObjLineFault* pGraphic) { if (!pGraphic) return; nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr); if (pData && pData->getFaultName() != pGraphic->getName()) { pData->setFaultName(pGraphic->getName()); } } // 切换分析时更新绑定的 DataManager // 旧图元已由 deleteAllPlotObjs 清除,清理残留映射避免悬空指针 void nmPlotGraphicBinder::updateDataMgr(nmDataAnalyzeManager* pDataMgr) { m_mapFaultData.clear(); m_setBoundGraphics.clear(); m_mapCrackData.clear(); m_setBoundCrackGraphics.clear(); m_mapOutlineData.clear(); m_setBoundOutlineGraphics.clear(); m_mapMeasureData.clear(); m_mapRegionMarkData.clear(); m_setBoundRegionMarkGraphics.clear(); m_mapRegionData.clear(); m_setBoundRegionGraphics.clear(); m_mapWellData.clear(); m_setBoundWellGraphics.clear(); m_pDataMgr = pDataMgr; } // 将数据值推到图元本地副本 void nmPlotGraphicBinder::_pushFaultDataToGraphic(nmObjLineFault* pGraphic, nmDataFault* pData) { // 阻断信号,防止推送中触发反向同步 pGraphic->blockSignals(true); pGraphic->setName(pData->getFaultName()); int flowModel = (pData->getFaultFlowModel().getValue() == tr("Leaky")) ? 0 : 1; pGraphic->setFaultFlowModel(flowModel); pGraphic->setFaultLeakage(pData->getFaultLeakage().getValue().toDouble()); pGraphic->blockSignals(false); } // 建立图元与数据的双向信号连接 void nmPlotGraphicBinder::_connectFault(nmObjLineFault* pGraphic, nmDataFault* pData) { QObject::connect(pGraphic, SIGNAL(sigFlowModelChanged(int)), this, SLOT(onGraphicFlowModelChanged(int))); QObject::connect(pGraphic, SIGNAL(sigLeakageChanged(double)), this, SLOT(onGraphicLeakageChanged(double))); QObject::connect(pGraphic, SIGNAL(sigPointsChanged()), this, SLOT(onGraphicPointsChanged())); QObject::connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)), this, SLOT(onGraphicVisibleChanged(bool))); m_mapFaultData[pGraphic] = pData; m_setBoundGraphics.insert(pGraphic); pGraphic->setGraphicBinder(this); } // 断开图元与本 Binder 的所有信号连接 void nmPlotGraphicBinder::_disconnectFault(nmObjLineFault* pGraphic) { QObject::disconnect(pGraphic, SIGNAL(sigFlowModelChanged(int)), this, SLOT(onGraphicFlowModelChanged(int))); QObject::disconnect(pGraphic, SIGNAL(sigLeakageChanged(double)), this, SLOT(onGraphicLeakageChanged(double))); QObject::disconnect(pGraphic, SIGNAL(sigPointsChanged()), this, SLOT(onGraphicPointsChanged())); QObject::disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)), this, SLOT(onGraphicVisibleChanged(bool))); m_setBoundGraphics.remove(pGraphic); } // 图元属性变更 → 同步到数据 // 流动模型变更 void nmPlotGraphicBinder::onGraphicFlowModelChanged(int model) { nmObjLineFault* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr); if (!pData) return; nmDataAttribute attr = pData->getFaultFlowModel(); attr.setValue(model == 0 ? tr("Leaky") : tr("Composite Limit")); pData->setFaultFlowModel(attr); } // 渗漏率变更 void nmPlotGraphicBinder::onGraphicLeakageChanged(double leakage) { nmObjLineFault* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr); if (!pData) return; nmDataAttribute attr = pData->getFaultLeakage(); attr.setValue(leakage); pData->setFaultLeakage(attr); } // 点坐标变更 void nmPlotGraphicBinder::onGraphicPointsChanged() { nmObjLineFault* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr); if (!pData) return; pData->setFaultPoints(pGraphic->getAllValues()); pData->setFaultName(pGraphic->getName()); if (m_pDataMgr) { m_pDataMgr->notifyDataChanged(); } } // 可见性变更 void nmPlotGraphicBinder::onGraphicVisibleChanged(bool bVisible) { nmObjLineFault* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataFault* pData = m_mapFaultData.value(pGraphic, nullptr); if (!pData) return; pData->setPlotVisible(bVisible); } // 数据变更(预留) void nmPlotGraphicBinder::onDataChanged() { } // ============ 裂缝绑定 ============ // 用户画完裂缝后:创建数据对象并建立绑定 void nmPlotGraphicBinder::createCrackForGraphic(nmObjLineCrack* pGraphic) { if (!pGraphic || !m_pDataMgr) { return; } // 创建数据对象 nmDataFracture* pData = m_pDataMgr->createFracture(); // 将图元值推入数据 pData->setFractureName(pGraphic->getName()); pData->setFracturePoints(pGraphic->getAllValues()); // 建立信号连接 _connectCrack(pGraphic, pData); m_pDataMgr->notifyDataChanged(); } // 从文件加载:绑定已有裂缝数据到已有图元 void nmPlotGraphicBinder::bindCrackToGraphic(nmObjLineCrack* pGraphic, nmDataFracture* pData) { if (!pGraphic || !pData) { return; } // 将数据值推到图元 _pushCrackDataToGraphic(pGraphic, pData); // 建立信号连接 _connectCrack(pGraphic, pData); } // 删除裂缝图元:断开连接并移除数据 void nmPlotGraphicBinder::removeCrackBinding(nmObjLineCrack* pGraphic) { if (!pGraphic) { return; } // 断开信号 _disconnectCrack(pGraphic); // 从数据中心移除 if (m_mapCrackData.contains(pGraphic)) { nmDataFracture* pData = m_mapCrackData.value(pGraphic); if (pData && m_pDataMgr) { m_pDataMgr->removeFractureData(pData); } m_mapCrackData.remove(pGraphic); } } nmDataFracture* nmPlotGraphicBinder::getCrackDataFor(nmObjLineCrack* pGraphic) { return m_mapCrackData.value(pGraphic, nullptr); } // 名称同步:检测图元名称与数据名称是否一致,不一致则同步 void nmPlotGraphicBinder::syncCrackName(nmObjLineCrack* pGraphic) { if (!pGraphic) return; nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr); if (pData && pData->getFractureName() != pGraphic->getName()) { pData->setFractureName(pGraphic->getName()); } } // 将裂缝数据值推到图元本地副本 void nmPlotGraphicBinder::_pushCrackDataToGraphic(nmObjLineCrack* pGraphic, nmDataFracture* pData) { // 阻断信号,防止推送中触发反向同步 pGraphic->blockSignals(true); pGraphic->setName(pData->getFractureName()); int flowModel = (pData->getFractureFlowModel().getValue() == tr("Infinite Conductivity")) ? 0 : 1; pGraphic->setCrackFlowModel(flowModel); pGraphic->setCrackDfc(pData->getFractureDfc().getValue().toDouble()); pGraphic->setCrackDw(pData->getFractureDw().getValue().toDouble()); pGraphic->blockSignals(false); } // 建立裂缝图元与数据的双向信号连接 void nmPlotGraphicBinder::_connectCrack(nmObjLineCrack* pGraphic, nmDataFracture* pData) { QObject::connect(pGraphic, SIGNAL(sigFlowModelChanged(int)), this, SLOT(onGraphicCrackFlowModelChanged(int))); QObject::connect(pGraphic, SIGNAL(sigDfcChanged(double)), this, SLOT(onGraphicCrackDfcChanged(double))); QObject::connect(pGraphic, SIGNAL(sigDwChanged(double)), this, SLOT(onGraphicCrackDwChanged(double))); QObject::connect(pGraphic, SIGNAL(sigPointsChanged()), this, SLOT(onGraphicCrackPointsChanged())); QObject::connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)), this, SLOT(onGraphicCrackVisibleChanged(bool))); m_mapCrackData[pGraphic] = pData; m_setBoundCrackGraphics.insert(pGraphic); pGraphic->setGraphicBinder(this); } // 断开裂缝图元与本 Binder 的所有信号连接 void nmPlotGraphicBinder::_disconnectCrack(nmObjLineCrack* pGraphic) { QObject::disconnect(pGraphic, SIGNAL(sigFlowModelChanged(int)), this, SLOT(onGraphicCrackFlowModelChanged(int))); QObject::disconnect(pGraphic, SIGNAL(sigDfcChanged(double)), this, SLOT(onGraphicCrackDfcChanged(double))); QObject::disconnect(pGraphic, SIGNAL(sigDwChanged(double)), this, SLOT(onGraphicCrackDwChanged(double))); QObject::disconnect(pGraphic, SIGNAL(sigPointsChanged()), this, SLOT(onGraphicCrackPointsChanged())); QObject::disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)), this, SLOT(onGraphicCrackVisibleChanged(bool))); m_setBoundCrackGraphics.remove(pGraphic); } // 裂缝流动模型变更 void nmPlotGraphicBinder::onGraphicCrackFlowModelChanged(int model) { nmObjLineCrack* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr); if (!pData) return; nmDataAttribute attr = pData->getFractureFlowModel(); attr.setValue(model == 0 ? tr("Infinite Conductivity") : tr("Finite Conductivity")); pData->setFractureFlowModel(attr); } // 裂缝导流能力变更 void nmPlotGraphicBinder::onGraphicCrackDfcChanged(double dfc) { nmObjLineCrack* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr); if (!pData) return; nmDataAttribute attr = pData->getFractureDfc(); attr.setValue(dfc); pData->setFractureDfc(attr); } // 裂缝储能比变更 void nmPlotGraphicBinder::onGraphicCrackDwChanged(double dw) { nmObjLineCrack* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr); if (!pData) return; nmDataAttribute attr = pData->getFractureDw(); attr.setValue(dw); pData->setFractureDw(attr); } // 裂缝点坐标变更 void nmPlotGraphicBinder::onGraphicCrackPointsChanged() { nmObjLineCrack* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr); if (!pData) return; pData->setFracturePoints(pGraphic->getAllValues()); pData->setFractureName(pGraphic->getName()); if (m_pDataMgr) { m_pDataMgr->notifyDataChanged(); } } // 裂缝可见性变更 void nmPlotGraphicBinder::onGraphicCrackVisibleChanged(bool bVisible) { nmObjLineCrack* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataFracture* pData = m_mapCrackData.value(pGraphic, nullptr); if (!pData) return; pData->setPlotVisible(bVisible); } // ==================== 边界图元绑定 ==================== // 圆形边界:用户画完后创建数据并绑定 void nmPlotGraphicBinder::createOutlineForGraphic(nmObjRoundOutline* pGraphic) { if (!pGraphic || !m_pDataMgr) return; // 清理旧边界图元的绑定(数据中心同一时间只持有一个边界数据) QList oldGraphics = m_mapOutlineData.keys(); foreach (nmObjBase* pOld, oldGraphics) { if (pOld != pGraphic) { _disconnectOutline(pOld); m_mapOutlineData.remove(pOld); } } nmDataOutline* pData = m_pDataMgr->createOutline(); pData->setName(pGraphic->getName()); pData->setOutlinePoints(pGraphic->getAllValues()); pData->setFlowTypeList(pGraphic->m_vFlowTypeList); pData->setOutlineType(NM_Data_Outline_Type::NM_Round_Outline_Type); // 视觉属性同步到数据 pData->setPenWidth(pGraphic->getPen().widthF()); QColor roundClr = pGraphic->getBackgrdColor(); pData->setBackgrdColor(roundClr); pData->setBackgrdAlpha(roundClr.alpha()); pData->setVisualPropsValid(true); double qradius = pGraphic->getAllValues()[2].y() - pGraphic->getAllValues()[0].y(); pData->setRadius(qradius); pData->setCenter(pGraphic->getAllValues()[0]); m_mapOutlineData[pGraphic] = pData; m_setBoundOutlineGraphics.insert(pGraphic); _connectOutline(pGraphic, pData); if (m_pDataMgr) { m_pDataMgr->notifyDataChanged(); } } // 矩形边界:用户画完后创建数据并绑定 void nmPlotGraphicBinder::createOutlineForGraphic(nmObjRectOutline* pGraphic) { if (!pGraphic || !m_pDataMgr) return; // 清理旧边界图元的绑定(数据中心同一时间只持有一个边界数据) QList oldGraphics = m_mapOutlineData.keys(); foreach (nmObjBase* pOld, oldGraphics) { if (pOld != pGraphic) { _disconnectOutline(pOld); m_mapOutlineData.remove(pOld); } } nmDataOutline* pData = m_pDataMgr->createOutline(); pData->setName(pGraphic->getName()); pData->setOutlinePoints(pGraphic->getAllValues()); pData->setFlowTypeList(pGraphic->m_vFlowTypeList); pData->setOutlineType(NM_Data_Outline_Type::NM_Rect_Outline_Type); pData->setPenWidth(pGraphic->getPen().widthF()); pData->setBackgrdColor(pGraphic->getBackgrdColor()); pData->setBackgrdAlpha(pGraphic->getBackgrdAlpha()); pData->setVisualPropsValid(true); m_mapOutlineData[pGraphic] = pData; m_setBoundOutlineGraphics.insert(pGraphic); _connectOutline(pGraphic, pData); if (m_pDataMgr) { m_pDataMgr->notifyDataChanged(); } } // 多边形边界:用户画完后创建数据并绑定 void nmPlotGraphicBinder::createOutlineForGraphic(nmObjPolygonOutline* pGraphic) { if (!pGraphic || !m_pDataMgr) return; // 清理旧边界图元的绑定(数据中心同一时间只持有一个边界数据) QList oldGraphics = m_mapOutlineData.keys(); foreach (nmObjBase* pOld, oldGraphics) { if (pOld != pGraphic) { _disconnectOutline(pOld); m_mapOutlineData.remove(pOld); } } nmDataOutline* pData = m_pDataMgr->createOutline(); pData->setName(pGraphic->getName()); pData->setOutlinePoints(pGraphic->getAllValues()); pData->setFlowTypeList(pGraphic->m_vFlowTypeList); pData->setOutlineType(NM_Data_Outline_Type::NM_Polygon_Outline_Type); pData->setPenWidth(pGraphic->getPen().widthF()); pData->setBackgrdColor(pGraphic->getBackgrdColor()); pData->setBackgrdAlpha(pGraphic->getBackgrdAlpha()); pData->setVisualPropsValid(true); m_mapOutlineData[pGraphic] = pData; m_setBoundOutlineGraphics.insert(pGraphic); _connectOutline(pGraphic, pData); if (m_pDataMgr) { m_pDataMgr->notifyDataChanged(); } } // 从文件加载,绑定已有边界数据到已有图元 void nmPlotGraphicBinder::bindOutlineToGraphic(nmObjBase* pGraphic, nmDataOutline* pData) { if (!pGraphic || !pData) return; m_mapOutlineData[pGraphic] = pData; m_setBoundOutlineGraphics.insert(pGraphic); _pushOutlineDataToGraphic(pGraphic, pData); _connectOutline(pGraphic, pData); } // 删除边界图元前,断开绑定并从数据中心移除 void nmPlotGraphicBinder::removeOutlineBinding(nmObjBase* pGraphic) { if (!pGraphic) return; _disconnectOutline(pGraphic); m_mapOutlineData.remove(pGraphic); if (m_pDataMgr) { m_pDataMgr->removeOutlineData(); m_pDataMgr->notifyDataChanged(); } } // 查找边界图元对应的数据指针 nmDataOutline* nmPlotGraphicBinder::getOutlineDataFor(nmObjBase* pGraphic) { return m_mapOutlineData.value(pGraphic, nullptr); } // 名称同步:setName 不发信号,由图元在 paintBack 中调用 void nmPlotGraphicBinder::syncOutlineName(nmObjBase* pGraphic) { if (!pGraphic) return; nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr); if (pData && pData->getName() != pGraphic->getName()) { pData->setName(pGraphic->getName()); } } // 视觉属性兜底同步:paintBack 中调用,确保画笔宽度、填充色、透明度始终同步到数据中心 void nmPlotGraphicBinder::syncOutlineVisual(nmObjBase* pGraphic) { if (!pGraphic) return; nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr); if (!pData) return; // 画笔宽度 QPen pen = pGraphic->getPen(); double penWidth = pen.widthF(); if (pData->getPenWidth() != penWidth) { pData->setPenWidth(penWidth); } // 填充背景色和透明度 QColor backgrdColor; int backgrdAlpha = 0; if (nmObjRectOutline* pRect = dynamic_cast(pGraphic)) { backgrdColor = pRect->getBackgrdColor(); backgrdAlpha = pRect->getBackgrdAlpha(); } else if (nmObjRoundOutline* pRound = dynamic_cast(pGraphic)) { backgrdColor = pRound->getBackgrdColor(); backgrdAlpha = backgrdColor.alpha(); // 圆形透明度嵌入在 QColor 中 } else if (nmObjPolygonOutline* pPolygon = dynamic_cast(pGraphic)) { backgrdColor = pPolygon->getBackgrdColor(); backgrdAlpha = pPolygon->getBackgrdAlpha(); } if (pData->getBackgrdColor().rgb() != backgrdColor.rgb()) { pData->setBackgrdColor(backgrdColor); } if (pData->getBackgrdAlpha() != backgrdAlpha) { pData->setBackgrdAlpha(backgrdAlpha); } pData->setVisualPropsValid(true); } // 建立边界图元与数据的信号连接(三条信号) void nmPlotGraphicBinder::_connectOutline(nmObjBase* pGraphic, nmDataOutline* pData) { QObject::connect(pGraphic, SIGNAL(sigOutlinePointsChanged()), this, SLOT(onGraphicOutlinePointsChanged())); QObject::connect(pGraphic, SIGNAL(sigOutlineFlowTypeChanged()), this, SLOT(onGraphicOutlineFlowTypeChanged())); QObject::connect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)), this, SLOT(onGraphicOutlineVisibleChanged(bool))); m_setBoundOutlineGraphics.insert(pGraphic); // 注入 Binder 指针到图元 if (nmObjRoundOutline* pRound = dynamic_cast(pGraphic)) { pRound->setGraphicBinder(this); } else if (nmObjRectOutline* pRect = dynamic_cast(pGraphic)) { pRect->setGraphicBinder(this); } else if (nmObjPolygonOutline* pPolygon = dynamic_cast(pGraphic)) { pPolygon->setGraphicBinder(this); } } // 断开边界图元与本 Binder 的信号连接 void nmPlotGraphicBinder::_disconnectOutline(nmObjBase* pGraphic) { QObject::disconnect(pGraphic, SIGNAL(sigOutlinePointsChanged()), this, SLOT(onGraphicOutlinePointsChanged())); QObject::disconnect(pGraphic, SIGNAL(sigOutlineFlowTypeChanged()), this, SLOT(onGraphicOutlineFlowTypeChanged())); QObject::disconnect(pGraphic, SIGNAL(sigObjVisibleChanged(bool)), this, SLOT(onGraphicOutlineVisibleChanged(bool))); m_setBoundOutlineGraphics.remove(pGraphic); } // 从边界数据对象读取值,写入图元本地副本(加载时用) void nmPlotGraphicBinder::_pushOutlineDataToGraphic(nmObjBase* pGraphic, nmDataOutline* pData) { pGraphic->blockSignals(true); pGraphic->setName(pData->getName()); QVector flowTypes = pData->getFlowTypeList(); bool bPushVisual = pData->hasVisualProps(); if (nmObjRoundOutline* pRound = dynamic_cast(pGraphic)) { pRound->m_vFlowTypeList = flowTypes; if (bPushVisual) { QPen pen = pRound->getPen(); pen.setWidthF(pData->getPenWidth()); pRound->setPen(pen); QColor clr = pData->getBackgrdColor(); clr.setAlpha(pData->getBackgrdAlpha()); pRound->setBackgrdColor(clr); } } else if (nmObjRectOutline* pRect = dynamic_cast(pGraphic)) { pRect->m_vFlowTypeList = flowTypes; if (bPushVisual) { QPen pen = pRect->getPen(); pen.setWidthF(pData->getPenWidth()); pRect->setPen(pen); pRect->setBackgrdColor(pData->getBackgrdColor()); pRect->setBackgrdAlpha(pData->getBackgrdAlpha()); } } else if (nmObjPolygonOutline* pPolygon = dynamic_cast(pGraphic)) { pPolygon->m_vFlowTypeList = flowTypes; if (bPushVisual) { QPen pen = pPolygon->getPen(); pen.setWidthF(pData->getPenWidth()); pPolygon->setPen(pen); pPolygon->setBackgrdColor(pData->getBackgrdColor()); pPolygon->setBackgrdAlpha(pData->getBackgrdAlpha()); } } pGraphic->blockSignals(false); } // ==================== 边界图元信号 → 数据同步 ==================== // 边界点坐标变更 void nmPlotGraphicBinder::onGraphicOutlinePointsChanged() { nmObjBase* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr); if (!pData) return; pData->setOutlinePoints(pGraphic->getAllValues()); // 圆形边界额外同步 radius 和 center if (nmObjRoundOutline* pRound = dynamic_cast(pGraphic)) { QVector pts = pRound->getAllValues(); if (pts.count() >= 3) { double radius = pts[2].y() - pts[0].y(); pData->setRadius(radius); pData->setCenter(pts[0]); } } if (m_pDataMgr) { m_pDataMgr->notifyDataChanged(); } } // 边界流动类型变更 void nmPlotGraphicBinder::onGraphicOutlineFlowTypeChanged() { nmObjBase* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr); if (!pData) return; QVector flowTypes; if (nmObjRoundOutline* pRound = dynamic_cast(pGraphic)) { flowTypes = pRound->m_vFlowTypeList; } else if (nmObjRectOutline* pRect = dynamic_cast(pGraphic)) { flowTypes = pRect->m_vFlowTypeList; } else if (nmObjPolygonOutline* pPolygon = dynamic_cast(pGraphic)) { flowTypes = pPolygon->m_vFlowTypeList; } pData->setFlowTypeList(flowTypes); if (m_pDataMgr) { m_pDataMgr->notifyDataChanged(); } } // 边界可见性变更 void nmPlotGraphicBinder::onGraphicOutlineVisibleChanged(bool bVisible) { nmObjBase* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataOutline* pData = m_mapOutlineData.value(pGraphic, nullptr); if (!pData) return; pData->setPlotVisible(bVisible); if (m_pDataMgr) { m_pDataMgr->notifyDataChanged(); } } // ==================== 测量线图元 ==================== // 用户画完测量线后:获取数据对象并建立绑定 void nmPlotGraphicBinder::createMeasureForGraphic(nmObjLineMeasure* pGraphic) { if (!pGraphic || !m_pDataMgr) { return; } // 获取测量数据单例 nmDataMeasure* pData = m_pDataMgr->getMeasureData(); // 将图元坐标推入数据 QVector pts = pGraphic->getAllValues(); if (pts.count() >= 2) { QPointF pStart = pts[0]; QPointF pEnd = pts[1]; double dLength = QLineF(pStart, pEnd).length(); if (pEnd != pStart) { pData->setStartPoint(pStart); pData->setEndPoint(pEnd); } else { pData->setCurrentPoint(pStart); } nmDataAttribute lenAttr = pData->getLength(); lenAttr.setValue(dLength); pData->setLength(lenAttr); } // 建立映射 m_mapMeasureData[pGraphic] = pData; pGraphic->setGraphicBinder(this); m_pDataMgr->notifyDataChanged(); } // 删除测量线图元:移除映射(不删除数据对象,由 DataManager 管理) void nmPlotGraphicBinder::removeMeasureBinding(nmObjLineMeasure* pGraphic) { if (!pGraphic) { return; } m_mapMeasureData.remove(pGraphic); } // 坐标同步:从数据对象读取起点终点,写回图元(拟合功能修改数据后由 paintBack 调用) void nmPlotGraphicBinder::syncMeasurePoints(nmObjLineMeasure* pGraphic) { if (!pGraphic || !m_pDataMgr) return; nmDataMeasure* pData = m_mapMeasureData.value(pGraphic, nullptr); if (!pData) return; QPointF startPt = pData->getStartPoint(); QPointF endPt = pData->getEndPoint(); // 仅在坐标确实变化时才更新,避免每次绘制都无谓写入 QVector currentPts = pGraphic->getAllValues(); if (currentPts.count() >= 2 && currentPts[0] == startPt && currentPts[1] == endPt) { return; } pGraphic->blockSignals(true); QVector pts; pts << startPt << endPt; pGraphic->setAllValues(pts); pGraphic->blockSignals(false); } // ==================== 区域标记图元 ==================== // 用户画完区域标记后:创建数据对象并建立绑定 void nmPlotGraphicBinder::createRegionMarkForGraphic(nmObjRegionMark* pGraphic) { if (!pGraphic || !m_pDataMgr) { return; } // 创建数据对象 nmDataRegionMark* pData = m_pDataMgr->createRegionMark(); // 将图元值推入数据 pData->setRegionMarkName(pGraphic->getName()); QVector pts = pGraphic->getAllValues(); if (pts.count() >= 1) { pData->setPtPos(pts[0]); } // 储层类型:int → 字符串 nmDataAttribute attr = pData->getReservoirType(); if (pGraphic->getResevoirType() == 0) { attr.setValue("Homogeneous"); } else { attr.setValue("Dual porosity pseudo steady state"); } pData->setReservoirType(attr); // 综合压缩系数、净毛比 nmDataAttribute comKrAttr = pData->getComKr(); comKrAttr.setValue(pGraphic->getComKr()); pData->setComKr(comKrAttr); nmDataAttribute comWAttr = pData->getComW(); comWAttr.setValue(pGraphic->getComW()); pData->setComW(comWAttr); nmDataAttribute ntgAttr = pData->getNetToGross(); ntgAttr.setValue(pGraphic->getNetToGross()); pData->setNetToGross(ntgAttr); // 建立信号连接 _connectRegionMark(pGraphic, pData); m_pDataMgr->notifyDataChanged(); } // 从文件加载:绑定已有区域标记数据到已有图元 void nmPlotGraphicBinder::bindRegionMarkToGraphic(nmObjRegionMark* pGraphic, nmDataRegionMark* pData) { if (!pGraphic || !pData) { return; } // 将数据值推到图元本地副本 _pushRegionMarkDataToGraphic(pGraphic, pData); // 建立信号连接 _connectRegionMark(pGraphic, pData); } // 删除区域标记图元:从数据中心移除数据并断开信号 void nmPlotGraphicBinder::removeRegionMarkBinding(nmObjRegionMark* pGraphic) { if (!pGraphic) { return; } _disconnectRegionMark(pGraphic); nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr); if (pData && m_pDataMgr) { m_pDataMgr->removeRegionMarkData(pData); } m_mapRegionMarkData.remove(pGraphic); } // 兜底同步:名称、位置(由 paintBack 调用) void nmPlotGraphicBinder::syncRegionMarkData(nmObjRegionMark* pGraphic) { if (!pGraphic) return; nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr); if (!pData) return; pData->setRegionMarkName(pGraphic->getName()); QVector pts = pGraphic->getAllValues(); if (pts.count() >= 1) { pData->setPtPos(pts[0]); } } // 查找区域标记图元对应的数据指针 nmDataRegionMark* nmPlotGraphicBinder::getRegionMarkDataFor(nmObjRegionMark* pGraphic) { return m_mapRegionMarkData.value(pGraphic, nullptr); } // 图元信号 → 数据同步 void nmPlotGraphicBinder::onGraphicRegionMarkReservoirTypeChanged(int type) { nmObjRegionMark* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr); if (!pData) return; nmDataAttribute attr = pData->getReservoirType(); if (type == 0) { attr.setValue("Homogeneous"); } else { attr.setValue("Dual porosity pseudo steady state"); } pData->setReservoirType(attr); if (m_pDataMgr) { m_pDataMgr->notifyDataChanged(); } } void nmPlotGraphicBinder::onGraphicRegionMarkComKrChanged(double comKr) { nmObjRegionMark* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr); if (!pData) return; nmDataAttribute attr = pData->getComKr(); attr.setValue(comKr); pData->setComKr(attr); if (m_pDataMgr) { m_pDataMgr->notifyDataChanged(); } } void nmPlotGraphicBinder::onGraphicRegionMarkComWChanged(double comW) { nmObjRegionMark* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr); if (!pData) return; nmDataAttribute attr = pData->getComW(); attr.setValue(comW); pData->setComW(attr); if (m_pDataMgr) { m_pDataMgr->notifyDataChanged(); } } void nmPlotGraphicBinder::onGraphicRegionMarkNetToGrossChanged(double netToGross) { nmObjRegionMark* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr); if (!pData) return; nmDataAttribute attr = pData->getNetToGross(); attr.setValue(netToGross); pData->setNetToGross(attr); if (m_pDataMgr) { m_pDataMgr->notifyDataChanged(); } } void nmPlotGraphicBinder::onGraphicRegionMarkVisibleChanged(bool bVisible) { nmObjRegionMark* pGraphic = qobject_cast(sender()); if (!pGraphic) return; nmDataRegionMark* pData = m_mapRegionMarkData.value(pGraphic, nullptr); if (!pData) return; pData->setPlotVisible(bVisible); if (m_pDataMgr) { m_pDataMgr->notifyDataChanged(); } } // 建立信号连接 void nmPlotGraphicBinder::_connectRegionMark(nmObjRegionMark* pGraphic, nmDataRegionMark* pData) { if (!pGraphic || !pData) return; m_mapRegionMarkData[pGraphic] = pData; pGraphic->setGraphicBinder(this); if (m_setBoundRegionMarkGraphics.contains(pGraphic)) { return; } connect(pGraphic, SIGNAL(sigResevoirTypeChanged(int)), this, SLOT(onGraphicRegionMarkReservoirTypeChanged(int))); connect(pGraphic, SIGNAL(sigComKrChanged(double)), this, SLOT(onGraphicRegionMarkComKrChanged(double))); connect(pGraphic, SIGNAL(sigComWChanged(double)), this, SLOT(onGraphicRegionMarkComWChanged(double))); connect(pGraphic, SIGNAL(sigNetToGrossChanged(double)), this, SLOT(onGraphicRegionMarkNetToGrossChanged(double))); connect(pGraphic, SIGNAL(sigRegionMarkVisibleChanged(bool)), this, SLOT(onGraphicRegionMarkVisibleChanged(bool))); m_setBoundRegionMarkGraphics.insert(pGraphic); } // 断开信号连接 void nmPlotGraphicBinder::_disconnectRegionMark(nmObjRegionMark* pGraphic) { if (!pGraphic) return; if (!m_setBoundRegionMarkGraphics.contains(pGraphic)) { return; } disconnect(pGraphic, SIGNAL(sigResevoirTypeChanged(int)), this, SLOT(onGraphicRegionMarkReservoirTypeChanged(int))); disconnect(pGraphic, SIGNAL(sigComKrChanged(double)), this, SLOT(onGraphicRegionMarkComKrChanged(double))); disconnect(pGraphic, SIGNAL(sigComWChanged(double)), this, SLOT(onGraphicRegionMarkComWChanged(double))); disconnect(pGraphic, SIGNAL(sigNetToGrossChanged(double)), this, SLOT(onGraphicRegionMarkNetToGrossChanged(double))); disconnect(pGraphic, SIGNAL(sigRegionMarkVisibleChanged(bool)), this, SLOT(onGraphicRegionMarkVisibleChanged(bool))); m_setBoundRegionMarkGraphics.remove(pGraphic); } // 从数据对象读取值,写入图元本地副本(加载时用) void nmPlotGraphicBinder::_pushRegionMarkDataToGraphic(nmObjRegionMark* pGraphic, nmDataRegionMark* pData) { pGraphic->blockSignals(true); // 储层类型:字符串 → int if (pData->getReservoirType().getValue() == "Homogeneous") { pGraphic->setResevoirType(0); } else { pGraphic->setResevoirType(1); } pGraphic->setComKr(pData->getComKr().getValue().toDouble()); pGraphic->setComW(pData->getComW().getValue().toDouble()); pGraphic->setNetToGross(pData->getNetToGross().getValue().toDouble()); // 位置 QVector pts; pts << pData->getPtPos(); pGraphic->setAllValues(pts); pGraphic->blockSignals(false); } // ==================== 复合区图元 ==================== // 用户画完复合区后,创建数据并建立绑定 void nmPlotGraphicBinder::createRegionForGraphic(nmObjRegion* pGraphic) { if (!pGraphic || !m_pDataMgr) { return; } // 创建数据对象 nmDataRegion* pData = m_pDataMgr->createRegion(); // 将图元值推入数据 pData->setRegionName(pGraphic->getName()); pData->setVecPts(pGraphic->getAllValues()); // 流动模型 nmDataAttribute flowModelAttr = pData->getRegionFlowModel(); flowModelAttr.setValue(pGraphic->getRegionFlowModel() == 0 ? "Leaky" : "Composite limit"); pData->setRegionFlowModel(flowModelAttr); // 泄漏系数 nmDataAttribute leakageAttr = pData->getRegionLeakage(); leakageAttr.setValue(pGraphic->getRegionLeakage()); pData->setRegionLeakage(leakageAttr); // 建立映射 m_mapRegionData[pGraphic] = pData; pGraphic->setGraphicBinder(this); // 建立信号连接 _connectRegion(pGraphic, pData); m_pDataMgr->notifyDataChanged(); } // 从文件加载:绑定已有数据到已有图元 void nmPlotGraphicBinder::bindRegionToGraphic(nmObjRegion* pGraphic, nmDataRegion* pData) { if (!pGraphic || !pData) { return; } m_mapRegionData[pGraphic] = pData; pGraphic->setGraphicBinder(this); _pushRegionDataToGraphic(pGraphic, pData); _connectRegion(pGraphic, pData); } // 删除复合区图元前,断开信号并清理映射 void nmPlotGraphicBinder::removeRegionBinding(nmObjRegion* pGraphic) { if (!pGraphic) { return; } _disconnectRegion(pGraphic); nmDataRegion* pData = m_mapRegionData.value(pGraphic, nullptr); if (pData && m_pDataMgr) { m_pDataMgr->removeRegionData(pData); } m_mapRegionData.remove(pGraphic); } // 兜底同步:名称、位置、区域标记关联(由 paintBack 调用) void nmPlotGraphicBinder::syncRegionData(nmObjRegion* pGraphic) { if (!pGraphic) return; nmDataRegion* pData = m_mapRegionData.value(pGraphic, nullptr); if (!pData) return; // 兜底同步:名称、位置 pData->setRegionName(pGraphic->getName()); pData->setVecPts(pGraphic->getAllValues()); // 视觉属性兜底同步:画笔宽度、填充背景色 QPen pen = pGraphic->getPen(); if (pData->getPenWidth() != pen.widthF()) { pData->setPenWidth(pen.widthF()); } QColor clr = pGraphic->getBackgrdColor(); if (pData->getBackgrdColor() != clr) { pData->setBackgrdColor(clr); } // 区域标记关联 nmObjRegionMark* pRegionMark = pGraphic->getRegionMark(); if (pRegionMark) { nmDataRegionMark* pMarkData = pRegionMark->getRegionMarkData(); if (pMarkData) { pData->setRegionMarkData(pMarkData); } else { // 区域标记图元存在但数据为空,清除关联 pGraphic->setRegionMark(nullptr); pData->setRegionMarkData(nullptr); pGraphic->setBackgrdColor(QColor(0, 0, 0, 0)); } } else { // 没有区域标记图元,清除数据关联 if (pData->getRegionMarkData() != nullptr) { pData->setRegionMarkData(nullptr); } } } // 查找复合区图元对应的数据指针 nmDataRegion* nmPlotGraphicBinder::getRegionDataFor(nmObjRegion* pGraphic) { return m_mapRegionData.value(pGraphic, nullptr); } // 复合区图元信号 → 数据同步 void nmPlotGraphicBinder::onGraphicRegionFlowModelChanged(int model) { nmObjRegion* pGraphic = dynamic_cast(sender()); if (!pGraphic) return; nmDataRegion* pData = m_mapRegionData.value(pGraphic, nullptr); if (!pData) return; nmDataAttribute attr = pData->getRegionFlowModel(); if (model == 0) attr.setValue("Leaky"); else attr.setValue("Composite limit"); pData->setRegionFlowModel(attr); } void nmPlotGraphicBinder::onGraphicRegionLeakageChanged(double leakage) { nmObjRegion* pGraphic = dynamic_cast(sender()); if (!pGraphic) return; nmDataRegion* pData = m_mapRegionData.value(pGraphic, nullptr); if (!pData) return; nmDataAttribute attr = pData->getRegionLeakage(); attr.setValue(leakage); pData->setRegionLeakage(attr); } // 建立信号连接 void nmPlotGraphicBinder::_connectRegion(nmObjRegion* pGraphic, nmDataRegion* pData) { if (!pGraphic || !pData) return; if (m_setBoundRegionGraphics.contains(pGraphic)) return; connect(pGraphic, SIGNAL(sigRegionFlowModelChanged(int)), this, SLOT(onGraphicRegionFlowModelChanged(int))); connect(pGraphic, SIGNAL(sigRegionLeakageChanged(double)), this, SLOT(onGraphicRegionLeakageChanged(double))); m_setBoundRegionGraphics.insert(pGraphic); } // 断开信号连接 void nmPlotGraphicBinder::_disconnectRegion(nmObjRegion* pGraphic) { if (!pGraphic) return; if (!m_setBoundRegionGraphics.contains(pGraphic)) return; disconnect(pGraphic, SIGNAL(sigRegionFlowModelChanged(int)), this, SLOT(onGraphicRegionFlowModelChanged(int))); disconnect(pGraphic, SIGNAL(sigRegionLeakageChanged(double)), this, SLOT(onGraphicRegionLeakageChanged(double))); m_setBoundRegionGraphics.remove(pGraphic); } // 从数据对象读取值,写入图元本地副本(加载时用) void nmPlotGraphicBinder::_pushRegionDataToGraphic(nmObjRegion* pGraphic, nmDataRegion* pData) { if (!pGraphic || !pData) return; pGraphic->blockSignals(true); // 流动模型:字符串 → int if (pData->getRegionFlowModel().getValue() == "Leaky") { pGraphic->setRegionFlowModel(0); } else { pGraphic->setRegionFlowModel(1); } pGraphic->setRegionLeakage(pData->getRegionLeakage().getValue().toDouble()); // 视觉属性:画笔宽度、填充背景色 QPen pen = pGraphic->getPen(); pen.setWidthF(pData->getPenWidth()); pGraphic->setPen(pen); pGraphic->setBackgrdColor(pData->getBackgrdColor()); pGraphic->blockSignals(false); } // ==================== 井图元 ==================== // 用户创建新井后,创建数据并建立绑定 nmDataWellBase* nmPlotGraphicBinder::createWellForGraphic(nmObjPointWell* pGraphic, NM_WELL_MODEL wellType) { if (!pGraphic || !m_pDataMgr) { return nullptr; } nmDataWellBase* pData = m_pDataMgr->createWell(wellType); m_mapWellData[pGraphic] = pData; pGraphic->setGraphicBinder(this); _connectWell(pGraphic, pData); return pData; } // 从文件加载,绑定已有井数据到已有图元 void nmPlotGraphicBinder::bindWellToGraphic(nmObjPointWell* pGraphic, nmDataWellBase* pData) { if (!pGraphic || !pData) { return; } m_mapWellData[pGraphic] = pData; pGraphic->setGraphicBinder(this); _pushWellDataToGraphic(pGraphic, pData); _connectWell(pGraphic, pData); } // 删除井图元前,断开信号并清理映射 void nmPlotGraphicBinder::removeWellBinding(nmObjPointWell* pGraphic) { if (!pGraphic) { return; } _disconnectWell(pGraphic); nmDataWellBase* pData = m_mapWellData.value(pGraphic, nullptr); if (pData && m_pDataMgr) { m_pDataMgr->removeWell(pData); } m_mapWellData.remove(pGraphic); } // 兜底同步:由井图元在 paintBack 中调用 // 注意:不同步名称。图元 getName() 返回自动生成的对象名,用它会覆盖数据中心井名, // 导致重新加载时名称匹配失败。井名通过 afterCreated() 正确设置。 // 位置/半径等同步已在 paintBack() 主体中完成。此处仅同步图元外观属性用于持久化。 void nmPlotGraphicBinder::syncWellData(nmObjPointWell* pGraphic) { if (!pGraphic) return; nmDataWellBase* pData = m_mapWellData.value(pGraphic, nullptr); if (!pData) return; // 同步图元外观属性到井数据(用于保存到 JSON) ZxDot dot = pGraphic->getDot(); pData->setDotStyle(static_cast(dot.style())); QColor clr = dot.color(); pData->setDotColor(clr.red(), clr.green(), clr.blue()); pData->setDotRadius(dot.radius()); pData->setDotFilling(dot.isFilling()); pData->setShowSubObjs(pGraphic->isShowSubObjs()); } // 查找井图元对应的数据指针 nmDataWellBase* nmPlotGraphicBinder::getWellDataFor(nmObjPointWell* pGraphic) { return m_mapWellData.value(pGraphic, nullptr); } void nmPlotGraphicBinder::calculateWellLogData(nmDataWellBase* pWellData, QVector>& pressure, QVector>& logLog, QVector>& semiLog) { if (!m_pDataMgr || !pWellData) return; m_pDataMgr->calculationLogData(pWellData, pressure, logLog, semiLog); } bool nmPlotGraphicBinder::hasLayers() const { if (!m_pDataMgr) return false; return !m_pDataMgr->getLayers().isEmpty(); } nmDataWellBase* nmPlotGraphicBinder::getCurrentWellData() const { if (!m_pDataMgr) return nullptr; return m_pDataMgr->getCurWellData(); } void nmPlotGraphicBinder::setCurrentWellData(nmDataWellBase* pWellData) { if (!m_pDataMgr) return; m_pDataMgr->setCurWellData(pWellData); } void nmPlotGraphicBinder::appendWellData(nmDataWellBase* pWellData) { if (!m_pDataMgr) return; m_pDataMgr->appendNmWellData(pWellData); } void nmPlotGraphicBinder::removeWellData(nmDataWellBase* pWellData) { if (!m_pDataMgr || !pWellData) return; m_pDataMgr->removeWell(pWellData); } void nmPlotGraphicBinder::notifyDataChanged() { if (!m_pDataMgr) return; m_pDataMgr->notifyDataChanged(); } // 建立信号连接 void nmPlotGraphicBinder::_connectWell(nmObjPointWell* pGraphic, nmDataWellBase* pData) { if (!pGraphic || !pData) return; if (m_setBoundWellGraphics.contains(pGraphic)) return; m_setBoundWellGraphics.insert(pGraphic); } // 断开信号连接 void nmPlotGraphicBinder::_disconnectWell(nmObjPointWell* pGraphic) { if (!pGraphic) return; if (!m_setBoundWellGraphics.contains(pGraphic)) return; m_setBoundWellGraphics.remove(pGraphic); } // 从井数据对象读取值,写入图元本地副本(加载时用) void nmPlotGraphicBinder::_pushWellDataToGraphic(nmObjPointWell* pGraphic, nmDataWellBase* pData) { if (!pGraphic || !pData) return; pGraphic->blockSignals(true); pGraphic->setNmWellData(pData); // 从井数据恢复图元外观属性(加载时从 JSON 恢复的属性设置到图元) ZxDot dot = pGraphic->getDot(); dot.setStyle(static_cast(pData->getDotStyle())); dot.setColor(QColor(pData->getDotColorR(), pData->getDotColorG(), pData->getDotColorB())); dot.setRadius(pData->getDotRadius()); dot.setFilling(pData->getDotFilling()); pGraphic->setDot(dot); pGraphic->showSubObjs(pData->getShowSubObjs()); pGraphic->blockSignals(false); }