diff --git a/Include/nmNum/nmData/nmDataWellBase.h b/Include/nmNum/nmData/nmDataWellBase.h index a3af2db..8136eb5 100644 --- a/Include/nmNum/nmData/nmDataWellBase.h +++ b/Include/nmNum/nmData/nmDataWellBase.h @@ -131,6 +131,20 @@ public: bool getPlotVisible() const; void setPlotVisible(const bool newState); + // 图元外观属性 getter/setter + int getDotStyle() const { return m_nDotStyle; } + void setDotStyle(int style) { m_nDotStyle = style; } + int getDotColorR() const { return m_nDotColorR; } + int getDotColorG() const { return m_nDotColorG; } + int getDotColorB() const { return m_nDotColorB; } + void setDotColor(int r, int g, int b) { m_nDotColorR = r; m_nDotColorG = g; m_nDotColorB = b; } + double getDotRadius() const { return m_dDotRadius; } + void setDotRadius(double r) { m_dDotRadius = r; } + bool getDotFilling() const { return m_bDotFilling; } + void setDotFilling(bool b) { m_bDotFilling = b; } + bool getShowSubObjs() const { return m_bShowSubObjs; } + void setShowSubObjs(bool b) { m_bShowSubObjs = b; } + // 历史数据相关方法 QVector> getHistoryPressure(); void setHistoryPressure(QVector> pressureData); @@ -238,6 +252,15 @@ protected: bool m_bPlotVisible; // 图元是否可见 + // 图元外观属性(用于保存/加载,由 Binder 在 syncWellData 和 _pushWellDataToGraphic 中同步) + int m_nDotStyle; // ZxDotType (int) + int m_nDotColorR; // QColor R + int m_nDotColorG; // QColor G + int m_nDotColorB; // QColor B + double m_dDotRadius; // 点半径 + bool m_bDotFilling; // 是否填充 + bool m_bShowSubObjs; // 是否显示子对象 + // 添加时间变表皮状态字段 bool m_bTimeDependentSkin; diff --git a/Include/nmNum/nmPlot/nmObjPointWell.h b/Include/nmNum/nmPlot/nmObjPointWell.h index 371a31e..ea27ad8 100644 --- a/Include/nmNum/nmPlot/nmObjPointWell.h +++ b/Include/nmNum/nmPlot/nmObjPointWell.h @@ -7,6 +7,7 @@ #include "ZxObjText.h" class nmDataWellBase; +class nmPlotGraphicBinder; // 数值试井绘图对象(点) class NM_PLOT_EXPORT nmObjPointWell : public nmObjPoint { @@ -79,6 +80,9 @@ class NM_PLOT_EXPORT nmObjPointWell : public nmObjPoint { // 获取当前井数据 nmDataWellBase* getNmWellData(); + void setGraphicBinder(nmPlotGraphicBinder* pBinder) { m_pGraphicBinder = pBinder; } + nmPlotGraphicBinder* getGraphicBinder() const { return m_pGraphicBinder; } + public slots: // 图元状态改变 void onObjVisibleChanged(bool bIsVisible); @@ -97,5 +101,7 @@ class NM_PLOT_EXPORT nmObjPointWell : public nmObjPoint { nmDataWellBase* m_pNmWellData; // 自定义井数据 + nmPlotGraphicBinder* m_pGraphicBinder; // 图元-数据绑定协调器 + NM_WELL_MODEL m_enumWellType; // 当前井的类型 }; diff --git a/Include/nmNum/nmPlot/nmPlotGraphicBinder.h b/Include/nmNum/nmPlot/nmPlotGraphicBinder.h index ecbf928..a636c62 100644 --- a/Include/nmNum/nmPlot/nmPlotGraphicBinder.h +++ b/Include/nmNum/nmPlot/nmPlotGraphicBinder.h @@ -5,6 +5,7 @@ #include #include "nmPlot_global.h" +#include "nmDefines.h" class nmDataAnalyzeManager; class nmDataFault; @@ -22,6 +23,8 @@ class nmDataRegionMark; class nmObjRegionMark; class nmDataRegion; class nmObjRegion; +class nmDataWellBase; +class nmObjPointWell; // 图元与数据绑定协调器,由 nmGuiPlot 托管 class NM_PLOT_EXPORT nmPlotGraphicBinder : public QObject @@ -128,6 +131,38 @@ public: // 查找复合区图元对应的数据指针 nmDataRegion* getRegionDataFor(nmObjRegion* pGraphic); + // ==================== 井图元 ==================== + + // 调用:用户创建新井后,创建数据并建立绑定 + nmDataWellBase* createWellForGraphic(nmObjPointWell* pGraphic, NM_WELL_MODEL wellType); + + // 调用:从文件加载,绑定已有井数据到已有图元 + void bindWellToGraphic(nmObjPointWell* pGraphic, nmDataWellBase* pData); + + // 调用:删除井图元前 + void removeWellBinding(nmObjPointWell* pGraphic); + + // 兜底同步:位置、名称,由井图元在 paintBack 中调用 + void syncWellData(nmObjPointWell* pGraphic); + + // 查找井图元对应的数据指针 + nmDataWellBase* getWellDataFor(nmObjPointWell* pGraphic); + + // 更新井图元的数据映射(编辑井后更换数据对象时使用) + void updateWellDataMapping(nmObjPointWell* pGraphic, nmDataWellBase* pNewData) { m_mapWellData[pGraphic] = pNewData; } + + // 井相关数据中心委托方法 + void calculateWellLogData(nmDataWellBase* pWellData, + QVector>& pressure, + QVector>& logLog, + QVector>& semiLog); + bool hasLayers() const; + nmDataWellBase* getCurrentWellData() const; + void setCurrentWellData(nmDataWellBase* pWellData); + void appendWellData(nmDataWellBase* pWellData); + void removeWellData(nmDataWellBase* pWellData); + void notifyDataChanged(); + // 切换分析时更新绑定的 DataManager,并清理旧图元的残留映射 void updateDataMgr(nmDataAnalyzeManager* pDataMgr); @@ -249,4 +284,21 @@ private: // 从复合区数据对象读取值,写入图元本地副本(加载时用) void _pushRegionDataToGraphic(nmObjRegion* pGraphic, nmDataRegion* pData); + + // ==================== 井图元 ==================== + + // 井图元 ↔ 数据 的映射表 + QMap m_mapWellData; + + // 已建立信号连接的井图元集合 + QSet m_setBoundWellGraphics; + + // 井图元 ←→ 数据 信号连接 + void _connectWell(nmObjPointWell* pGraphic, nmDataWellBase* pData); + + // 断开指定井图元与本 Binder 的信号连接 + void _disconnectWell(nmObjPointWell* pGraphic); + + // 从井数据对象读取值,写入图元本地副本(加载时用) + void _pushWellDataToGraphic(nmObjPointWell* pGraphic, nmDataWellBase* pData); }; diff --git a/Src/nmNum/nmData/nmDataAnalyzeManager.cpp b/Src/nmNum/nmData/nmDataAnalyzeManager.cpp index 44b2136..76db932 100644 --- a/Src/nmNum/nmData/nmDataAnalyzeManager.cpp +++ b/Src/nmNum/nmData/nmDataAnalyzeManager.cpp @@ -1056,6 +1056,10 @@ void nmDataAnalyzeManager::calculationLogData( // 准备流量段数据 QVector vecTimeQ = pWellData->getFlowPoints(); int nTimeNumQ = vecTimeQ.size() - 1; + if (nTimeNumQ <= 0) { + // 没有流量段数据,无法计算双对数/半对数曲线 + return; + } std::vector timeQ(nTimeNumQ); std::vector q(nTimeNumQ); diff --git a/Src/nmNum/nmData/nmDataWellBase.cpp b/Src/nmNum/nmData/nmDataWellBase.cpp index daaa6bf..ace4cc4 100644 --- a/Src/nmNum/nmData/nmDataWellBase.cpp +++ b/Src/nmNum/nmData/nmDataWellBase.cpp @@ -46,6 +46,15 @@ nmDataWellBase::nmDataWellBase() // 图元可见性,默认为true m_bPlotVisible = true; + // 图元外观属性默认值(与 nmObjPointWell::init 中的 m_oDot 默认值一致) + m_nDotStyle = 3; // DTS_Circle + m_nDotColorR = 0; // QColor(0, 255, 0) + m_nDotColorG = 255; + m_nDotColorB = 0; + m_dDotRadius = 1.5; + m_bDotFilling = true; + m_bShowSubObjs = true; + m_bTimeDependentSkin = false; // 添加一段射孔,默认与井身长度相同 (现在创建对象并添加指针) @@ -111,6 +120,16 @@ nmDataWellBase& nmDataWellBase::operator=(const nmDataWellBase& other) m_dtChangingStorage = other.m_dtChangingStorage; m_leakSkin = other.m_leakSkin; m_bPlotVisible = other.m_bPlotVisible; + + // 复制图元外观属性 + m_nDotStyle = other.m_nDotStyle; + m_nDotColorR = other.m_nDotColorR; + m_nDotColorG = other.m_nDotColorG; + m_nDotColorB = other.m_nDotColorB; + m_dDotRadius = other.m_dDotRadius; + m_bDotFilling = other.m_bDotFilling; + m_bShowSubObjs = other.m_bShowSubObjs; + m_bTimeDependentSkin = other.m_bTimeDependentSkin; m_eWellType = other.m_eWellType; @@ -183,6 +202,15 @@ rapidjson::Value nmDataWellBase::ToJsonValue(rapidjson::Document::AllocatorType& // 序列化图元可见性 (m_bPlotVisible) wellObject.AddMember("PlotVisible", m_bPlotVisible, allocator); + // 序列化图元外观属性 + wellObject.AddMember("DotStyle", m_nDotStyle, allocator); + wellObject.AddMember("DotColorR", m_nDotColorR, allocator); + wellObject.AddMember("DotColorG", m_nDotColorG, allocator); + wellObject.AddMember("DotColorB", m_nDotColorB, allocator); + wellObject.AddMember("DotRadius", m_dDotRadius, allocator); + wellObject.AddMember("DotFilling", m_bDotFilling, allocator); + wellObject.AddMember("ShowSubObjs", m_bShowSubObjs, allocator); + // 序列化井的流动段索引 (m_nIndexF) wellObject.AddMember("IndexFlow", m_nIndexF, allocator); @@ -302,6 +330,29 @@ void nmDataWellBase::FromJsonValue(const rapidjson::Value& jsonValue) m_bPlotVisible = jsonValue["PlotVisible"].GetBool(); } + // 反序列化图元外观属性 + if(jsonValue.HasMember("DotStyle") && jsonValue["DotStyle"].IsInt()) { + m_nDotStyle = jsonValue["DotStyle"].GetInt(); + } + if(jsonValue.HasMember("DotColorR") && jsonValue["DotColorR"].IsInt()) { + m_nDotColorR = jsonValue["DotColorR"].GetInt(); + } + if(jsonValue.HasMember("DotColorG") && jsonValue["DotColorG"].IsInt()) { + m_nDotColorG = jsonValue["DotColorG"].GetInt(); + } + if(jsonValue.HasMember("DotColorB") && jsonValue["DotColorB"].IsInt()) { + m_nDotColorB = jsonValue["DotColorB"].GetInt(); + } + if(jsonValue.HasMember("DotRadius") && jsonValue["DotRadius"].IsDouble()) { + m_dDotRadius = jsonValue["DotRadius"].GetDouble(); + } + if(jsonValue.HasMember("DotFilling") && jsonValue["DotFilling"].IsBool()) { + m_bDotFilling = jsonValue["DotFilling"].GetBool(); + } + if(jsonValue.HasMember("ShowSubObjs") && jsonValue["ShowSubObjs"].IsBool()) { + m_bShowSubObjs = jsonValue["ShowSubObjs"].GetBool(); + } + // 反序列化井的流动段索引 (m_nIndexF) if(jsonValue.HasMember("IndexFlow") && jsonValue["IndexFlow"].IsInt()) { m_nIndexF = jsonValue["IndexFlow"].GetInt(); diff --git a/Src/nmNum/nmPlot/nmGuiPlot.cpp b/Src/nmNum/nmPlot/nmGuiPlot.cpp index 321f6d0..b543b42 100644 --- a/Src/nmNum/nmPlot/nmGuiPlot.cpp +++ b/Src/nmNum/nmPlot/nmGuiPlot.cpp @@ -576,8 +576,10 @@ void nmGuiPlot::initWellObjsFromData(nmDataAnalyzeManager* pDataManager) // 2.8 移动到正确的位置 pWellPlot->moveToPos(pWellPlot->getPosOf(pWellPlot->getAllPos())); - // 2.9 图元绑定来自数据中心的井数据 - pWellPlot->setNmWellData(pWellData); + // 2.9 通过 Binder 绑定井数据(推值 + 建立信号连接) + if (m_pGraphicBinder) { + m_pGraphicBinder->bindWellToGraphic(pWellPlot, pWellData); + } pWellPlot->afterCreated(); } } diff --git a/Src/nmNum/nmPlot/nmGuiPlotCmdHelper.cpp b/Src/nmNum/nmPlot/nmGuiPlotCmdHelper.cpp index 8bec349..03d6d16 100644 --- a/Src/nmNum/nmPlot/nmGuiPlotCmdHelper.cpp +++ b/Src/nmNum/nmPlot/nmGuiPlotCmdHelper.cpp @@ -18,6 +18,7 @@ #include "nmObjLineFault.h" #include "nmObjLineMeasuringScaleTool.h" #include "nmObjPointWellTool.h" +#include "nmObjPointWell.h" #include "nmObjLineMeasureTool.h" #include "nmObjLineMeasure.h" @@ -408,6 +409,13 @@ void nmGuiPlotCmdHelper::slotObjPtsFinished(QVector& vec) { if (pRegion && pWxPlot->graphicBinder()) { pWxPlot->graphicBinder()->createRegionForGraphic(pRegion); } + } else if (pTool->getNOT() == NMOT_Point_Well) { + // 井图元:先设置 Binder,再执行 afterCreated(内部通过 Binder 创建井数据) + nmObjPointWell* pWell = dynamic_cast(pObj); + if (pWell && pWxPlot->graphicBinder()) { + pWell->setGraphicBinder(pWxPlot->graphicBinder()); + } + pObj->afterCreated(); } else { pObj->afterCreated(); } diff --git a/Src/nmNum/nmPlot/nmObjPointWell.cpp b/Src/nmNum/nmPlot/nmObjPointWell.cpp index ff31794..c8baf3c 100644 --- a/Src/nmNum/nmPlot/nmObjPointWell.cpp +++ b/Src/nmNum/nmPlot/nmObjPointWell.cpp @@ -29,7 +29,7 @@ #include "nmSingalCenter.h" -#include "nmDataAnalyzeManager.h" +#include "nmPlotGraphicBinder.h" #include "ZxDataGaugeP.h" #include "ZxDataGaugeF.h" @@ -49,6 +49,7 @@ nmObjPointWell::nmObjPointWell() , m_bSelectWell(false) , m_pWellData(nullptr) , m_pNmWellData(nullptr) + , m_pGraphicBinder(nullptr) , m_enumWellType(NM_WELL_MODEL::Vertical_Well) { nmObjPointWell::init("", NULL, NULL); @@ -62,6 +63,7 @@ nmObjPointWell::nmObjPointWell(const QString& sName, \ , m_bSelectWell(false) , m_pWellData(nullptr) , m_pNmWellData(nullptr) + , m_pGraphicBinder(nullptr) , m_enumWellType(NM_WELL_MODEL::Vertical_Well) { nmObjPointWell::init(sName, pAxisX, pAxisY); @@ -90,6 +92,7 @@ void nmObjPointWell::init(const QString& sName, \ loadTempl(); m_pNmWellData = nullptr; + m_pGraphicBinder = nullptr; // 连接图元可见性信号和槽 connect(this, SIGNAL(sigObjVisibleChanged(bool)), @@ -107,7 +110,7 @@ bool nmObjPointWell::runMove(const QPointF &pt1, const QPointF &pt2) nmObjPoint::runMove(pt1, pt2); // 更新井的位置信息 - if(m_pWellData) { + if(m_pWellData && m_pNmWellData) { QPointF newLocation = this->getValueOf(pt2); m_pWellData->setLocationX(newLocation.x()); m_pWellData->setLocationY(newLocation.y()); @@ -135,7 +138,9 @@ bool nmObjPointWell::runMove(const QPointF &pt1, const QPointF &pt2) } } - nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged(); + if (m_pGraphicBinder) { + m_pGraphicBinder->notifyDataChanged(); + } return true; } @@ -221,6 +226,7 @@ void nmObjPointWell::afterCreated() if(NULL != pPlot) { QString sName = m_pWellData->getName(); + this->setName(sName); ZxObjBase* p = pPlot->addOneObj(POT_Text, sName, false, \ m_pAxisX, m_pAxisY); appendSubObjs(p); @@ -331,11 +337,12 @@ void nmObjPointWell::afterCreated() return; } - // 初始化默认参数 - m_pNmWellData = nmDataAnalyzeManager::getCurrentInstance()->createWell(m_enumWellType); + // 如果已有井数据(文件加载时通过 bindWellToGraphic 绑定),则跳过创建 if (m_pNmWellData == nullptr) { - return; - } + m_pNmWellData = m_pGraphicBinder->createWellForGraphic(this, m_enumWellType); + if (m_pNmWellData == nullptr) { + return; + } m_pNmWellData->setWellName(m_pWellData->getName()); nmDataAttribute tempAttr = m_pNmWellData->getX(); @@ -373,12 +380,13 @@ void nmObjPointWell::afterCreated() QVector> vvecHistoryLogData; QVector> vvecHistorySemiLogData; - nmDataAnalyzeManager::getCurrentInstance()->calculationLogData(m_pNmWellData, vvecHistoryPressureData, vvecHistoryLogData, vvecHistorySemiLogData); + m_pGraphicBinder->calculateWellLogData(m_pNmWellData, vvecHistoryPressureData, vvecHistoryLogData, vvecHistorySemiLogData); // 存储历史数据到井对象 m_pNmWellData->setHistoryPressure(vvecHistoryPressureData); m_pNmWellData->setHistoryLogLog(vvecHistoryLogData); m_pNmWellData->setHistorySemiLog(vvecHistorySemiLogData); + } return; } @@ -449,7 +457,7 @@ void nmObjPointWell::createWell() void nmObjPointWell::editWell() { // 如果没有层数据,提示用户定义分层信息 - if(nmDataAnalyzeManager::getCurrentInstance()->getLayers().isEmpty()) { + if(m_pGraphicBinder && !m_pGraphicBinder->hasLayers()) { QMessageBox::information(nullptr, tr("error"), tr("please setting layers Data!")); return; } @@ -469,6 +477,7 @@ void nmObjPointWell::editWell() // 更新ZxDataWell的数据 m_pWellData->setName(pReturnWellData->getWellName()); + this->setName(pReturnWellData->getWellName()); m_pWellData->setLocationX(pReturnWellData->getX().getValue().toDouble()); m_pWellData->setLocationY(pReturnWellData->getY().getValue().toDouble()); m_pWellData->setWellRadius(pReturnWellData->getRadius().getValue().toDouble()); @@ -503,25 +512,28 @@ void nmObjPointWell::editWell() moveToPos(this->getPosOf(this->getAllPos())); // 判断是不是当前查看的井 - nmDataWellBase* pCurWellData = nmDataAnalyzeManager::getCurrentInstance()->getCurWellData(); + nmDataWellBase* pCurWellData = m_pGraphicBinder->getCurrentWellData(); if (pCurWellData != nullptr && pCurWellData->getWellName() == m_pNmWellData->getWellName()) { // 设置到当前井 - nmDataAnalyzeManager::getCurrentInstance()->setCurWellData(pReturnWellData); + m_pGraphicBinder->setCurrentWellData(pReturnWellData); } // 更新当前井数据,并添加到数据中心 - nmDataAnalyzeManager::getCurrentInstance()->removeWell(m_pNmWellData); + m_pGraphicBinder->removeWellData(m_pNmWellData); if (m_pNmWellData != nullptr) { m_pNmWellData = nullptr; } m_pNmWellData = pReturnWellData; - nmDataAnalyzeManager::getCurrentInstance()->appendNmWellData(m_pNmWellData); + m_pGraphicBinder->appendWellData(m_pNmWellData); + m_pGraphicBinder->updateWellDataMapping(this, m_pNmWellData); } - nmDataAnalyzeManager::getCurrentInstance()->notifyDataChanged(); + if (m_pGraphicBinder) { + m_pGraphicBinder->notifyDataChanged(); + } this->update(); } @@ -551,6 +563,10 @@ const QString& nmObjPointWell::getWellID() const void nmObjPointWell::paintBack(QPainter* painter, const ZxPaintParam& param) { + if (m_pGraphicBinder) { + m_pGraphicBinder->syncWellData(this); + } + if (m_pWellData == nullptr) { return; } @@ -747,7 +763,9 @@ void nmObjPointWell::paintBack(QPainter* painter, const ZxPaintParam& param) void nmObjPointWell::removeData() { - nmDataAnalyzeManager::getCurrentInstance()->removeWell(m_pNmWellData); + if (m_pGraphicBinder) { + m_pGraphicBinder->removeWellBinding(this); + } m_pNmWellData = nullptr; } @@ -755,16 +773,18 @@ void nmObjPointWell::setNmWellData(nmDataWellBase* wellData) { // 如果是外界设置了当前图元绑定的井数据,则不需要再次在afterCreated()函数中再次设置数据 m_bSelectWell = false; - QString wellClass = m_pWellData->getWellClassEn(); + m_pNmWellData = wellData; - m_pNmWellData = wellData; + if (m_pWellData) { + QString wellClass = m_pWellData->getWellClassEn(); - if(ZxBaseUtil::isSameStr(wellClass, "VerticalWell")) { - m_enumWellType = NM_WELL_MODEL::Vertical_Well; - } else if(ZxBaseUtil::isSameStr(wellClass, "VerticalFracturedWell")) { - m_enumWellType = NM_WELL_MODEL::Vertical_Fractured_Well; - } else if(ZxBaseUtil::isSameStr(wellClass, "HorizontalFracturedWell")) { - m_enumWellType = NM_WELL_MODEL::Horizontal_Fractured_Well; + if(ZxBaseUtil::isSameStr(wellClass, "VerticalWell")) { + m_enumWellType = NM_WELL_MODEL::Vertical_Well; + } else if(ZxBaseUtil::isSameStr(wellClass, "VerticalFracturedWell")) { + m_enumWellType = NM_WELL_MODEL::Vertical_Fractured_Well; + } else if(ZxBaseUtil::isSameStr(wellClass, "HorizontalFracturedWell")) { + m_enumWellType = NM_WELL_MODEL::Horizontal_Fractured_Well; + } } } @@ -775,5 +795,10 @@ nmDataWellBase* nmObjPointWell::getNmWellData() void nmObjPointWell::onObjVisibleChanged(bool bIsVisible) { - m_pNmWellData->setPlotVisible(bIsVisible); + if (m_pGraphicBinder) { + nmDataWellBase* pData = m_pGraphicBinder->getWellDataFor(this); + if (pData) { + pData->setPlotVisible(bIsVisible); + } + } } diff --git a/Src/nmNum/nmPlot/nmPlotGraphicBinder.cpp b/Src/nmNum/nmPlot/nmPlotGraphicBinder.cpp index f6c89d2..20d5f39 100644 --- a/Src/nmNum/nmPlot/nmPlotGraphicBinder.cpp +++ b/Src/nmNum/nmPlot/nmPlotGraphicBinder.cpp @@ -16,6 +16,8 @@ #include "nmDataRegion.h" #include "nmObjBase.h" #include "nmDataAnalyzeManager.h" +#include "nmObjPointWell.h" +#include "nmDataWellBase.h" #include @@ -109,6 +111,8 @@ void nmPlotGraphicBinder::updateDataMgr(nmDataAnalyzeManager* pDataMgr) m_setBoundRegionMarkGraphics.clear(); m_mapRegionData.clear(); m_setBoundRegionGraphics.clear(); + m_mapWellData.clear(); + m_setBoundWellGraphics.clear(); m_pDataMgr = pDataMgr; } @@ -1307,4 +1311,165 @@ void nmPlotGraphicBinder::_pushRegionDataToGraphic(nmObjRegion* pGraphic, nmData pGraphic->setBackgrdColor(pData->getBackgrdColor()); pGraphic->blockSignals(false); -} \ No newline at end of file +} + +// ==================== 井图元 ==================== + +// 用户创建新井后,创建数据并建立绑定 +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); +}