#include "nmReservoirPropertiesSession.h" #include "nmAttrRegistry.h" #include "nmDataAttribute.h" namespace { /** @brief 比较两个QVariant数值,保留字符串和整数的精确语义。 */ bool sameValue(const QVariant& oLeft, const QVariant& oRight) { return oLeft == oRight; } /** @brief 比较两口井的网格相关参数。 */ bool sameWellGeometry(nmDataWellBase& oLeft, nmDataWellBase& oRight) { return sameValue(oLeft.getX().getValue(), oRight.getX().getValue()) && sameValue(oLeft.getY().getValue(), oRight.getY().getValue()) && sameValue(oLeft.getRadius().getValue(), oRight.getRadius().getValue()); } } nmReservoirPropertiesSession::nmReservoirPropertiesSession( nmIReservoirPropertiesDataSource* pDataSource) : m_pDataSource(pDataSource), m_pAttrRegistry(new nmAttrRegistry), m_bInitialized(false) { } nmReservoirPropertiesSession::~nmReservoirPropertiesSession() { delete m_pAttrRegistry; m_pAttrRegistry = nullptr; m_pDataSource = nullptr; } bool nmReservoirPropertiesSession::initialize(QString& sError) { // 第一步:读取一次真实数据,作为取消和变更检测的基线。 if (m_pDataSource == nullptr || !m_pDataSource->loadSnapshot(m_oOriginalSnapshot, sError)) { m_bInitialized = false; return false; } // 第二步:复制出独立工作副本,后续界面修改只写入此对象。 m_oWorkingSnapshot = m_oOriginalSnapshot; nmReservoirParameterCatalog::registerSnapshot(m_pAttrRegistry, m_oWorkingSnapshot); m_bInitialized = true; sError.clear(); return true; } QList nmReservoirPropertiesSession::objectInfos( nmReservoirPropertiesCategory eCategory) { if (!m_bInitialized) { return QList(); } return nmReservoirParameterCatalog::createObjectInfos(eCategory, m_oWorkingSnapshot); } QVariant nmReservoirPropertiesSession::value(const QString& sParameterId) const { if (!m_bInitialized || m_pAttrRegistry == nullptr) { return QVariant(); } QStringList listIds; listIds << sParameterId; return m_pAttrRegistry->collect(listIds).value(sParameterId, QVariant()); } bool nmReservoirPropertiesSession::setValue(const QString& sParameterId, const QVariant& oValue) { if (!m_bInitialized || m_pAttrRegistry == nullptr || !m_pAttrRegistry->registeredNames().contains(sParameterId)) { return false; } m_pAttrRegistry->setValue(sParameterId, oValue); return true; } void nmReservoirPropertiesSession::setValues( const QMap& mapValues) { QMap::const_iterator oIterator = mapValues.constBegin(); for (; oIterator != mapValues.constEnd(); ++oIterator) { setValue(oIterator.key(), oIterator.value()); } } QString nmReservoirPropertiesSession::enumCode(const QString& sParameterId) const { if (!m_bInitialized) { return QString(); } return nmReservoirParameterCatalog::enumCode(m_oWorkingSnapshot, sParameterId); } bool nmReservoirPropertiesSession::setEnumCode(const QString& sParameterId, const QString& sCode) { if (!m_bInitialized) { return false; } return nmReservoirParameterCatalog::setEnumCode(m_oWorkingSnapshot, sParameterId, sCode); } bool nmReservoirPropertiesSession::commit(QString& sError) { if (!m_bInitialized || m_pDataSource == nullptr) { sError = QObject::tr("The reservoir properties editing session is unavailable."); return false; } // 第一步:在提交前计算几何变更,供数据源决定是否重建网格和刷新画布。 bool bGeometryChanged = isGeometryChanged(); // 第二步:将完整工作副本一次性交给数据源;失败时继续保留当前编辑内容。 if (!m_pDataSource->commitSnapshot(m_oWorkingSnapshot, bGeometryChanged, sError)) { return false; } // 第三步:提交成功后更新基线,防止同一会话重复识别旧变更。 m_oOriginalSnapshot = m_oWorkingSnapshot; sError.clear(); return true; } const nmReservoirPropertiesSnapshot& nmReservoirPropertiesSession::workingSnapshot() const { return m_oWorkingSnapshot; } bool nmReservoirPropertiesSession::isGeometryChanged() const { // 第一步:对象数量变化视为几何变化,虽然当前对话框本身不提供增删操作。 if (m_oOriginalSnapshot.m_vecVerticalWells.size() != m_oWorkingSnapshot.m_vecVerticalWells.size() || m_oOriginalSnapshot.m_vecVerticalFracturedWells.size() != m_oWorkingSnapshot.m_vecVerticalFracturedWells.size() || m_oOriginalSnapshot.m_vecHorizontalFracturedWells.size() != m_oWorkingSnapshot.m_vecHorizontalFracturedWells.size()) { return true; } // 第二步:比较三类井的位置和井径。 for (int nIndex = 0; nIndex < m_oWorkingSnapshot.m_vecVerticalWells.size(); ++nIndex) { nmDataVerticalWell& oOriginal = const_cast(m_oOriginalSnapshot.m_vecVerticalWells[nIndex]); nmDataVerticalWell& oWorking = const_cast(m_oWorkingSnapshot.m_vecVerticalWells[nIndex]); if (!sameWellGeometry(oOriginal, oWorking)) { return true; } } for (int nIndex = 0; nIndex < m_oWorkingSnapshot.m_vecVerticalFracturedWells.size(); ++nIndex) { nmDataVerticalFracturedWell& oOriginal = const_cast( m_oOriginalSnapshot.m_vecVerticalFracturedWells[nIndex]); nmDataVerticalFracturedWell& oWorking = const_cast( m_oWorkingSnapshot.m_vecVerticalFracturedWells[nIndex]); if (!sameWellGeometry(oOriginal, oWorking) || !sameValue(oOriginal.getFractureHalfLength().getValue(), oWorking.getFractureHalfLength().getValue()) || !sameValue(oOriginal.getFractureAngle().getValue(), oWorking.getFractureAngle().getValue())) { return true; } } for (int nIndex = 0; nIndex < m_oWorkingSnapshot.m_vecHorizontalFracturedWells.size(); ++nIndex) { nmDataHorizontalFracturedWell& oOriginal = const_cast( m_oOriginalSnapshot.m_vecHorizontalFracturedWells[nIndex]); nmDataHorizontalFracturedWell& oWorking = const_cast( m_oWorkingSnapshot.m_vecHorizontalFracturedWells[nIndex]); if (!sameWellGeometry(oOriginal, oWorking) || !sameValue(oOriginal.getWellLength().getValue(), oWorking.getWellLength().getValue()) || !sameValue(oOriginal.getDrainAngle().getValue(), oWorking.getDrainAngle().getValue()) || !sameValue(oOriginal.getNumberOfFractures().getValue(), oWorking.getNumberOfFractures().getValue()) || !sameValue(oOriginal.getFractureHalfLength().getValue(), oWorking.getFractureHalfLength().getValue()) || !sameValue(oOriginal.getFractureAngle().getValue(), oWorking.getFractureAngle().getValue())) { return true; } } // 第三步:断层和裂缝端点也直接参与网格,因此比较完整点坐标。 if (m_oOriginalSnapshot.m_vecFaults.size() != m_oWorkingSnapshot.m_vecFaults.size() || m_oOriginalSnapshot.m_vecFractures.size() != m_oWorkingSnapshot.m_vecFractures.size()) { return true; } for (int nIndex = 0; nIndex < m_oWorkingSnapshot.m_vecFaults.size(); ++nIndex) { if (m_oOriginalSnapshot.m_vecFaults[nIndex].getFaultPoints() != m_oWorkingSnapshot.m_vecFaults[nIndex].getFaultPoints()) { return true; } } for (int nIndex = 0; nIndex < m_oWorkingSnapshot.m_vecFractures.size(); ++nIndex) { if (m_oOriginalSnapshot.m_vecFractures[nIndex].getFracturePoints() != m_oWorkingSnapshot.m_vecFractures[nIndex].getFracturePoints()) { return true; } } return false; }