You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
nmWTAI-Platform/Src/nmNum/nmSubWxs/nmReservoirPropertiesSessio...

243 lines
8.6 KiB
C++

#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<nmReservoirPropertyObjectInfo> nmReservoirPropertiesSession::objectInfos(
nmReservoirPropertiesCategory eCategory)
{
if (!m_bInitialized)
{
return QList<nmReservoirPropertyObjectInfo>();
}
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<QString, QVariant>& mapValues)
{
QMap<QString, QVariant>::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<nmDataVerticalWell&>(m_oOriginalSnapshot.m_vecVerticalWells[nIndex]);
nmDataVerticalWell& oWorking =
const_cast<nmDataVerticalWell&>(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<nmDataVerticalFracturedWell&>(
m_oOriginalSnapshot.m_vecVerticalFracturedWells[nIndex]);
nmDataVerticalFracturedWell& oWorking = const_cast<nmDataVerticalFracturedWell&>(
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<nmDataHorizontalFracturedWell&>(
m_oOriginalSnapshot.m_vecHorizontalFracturedWells[nIndex]);
nmDataHorizontalFracturedWell& oWorking =
const_cast<nmDataHorizontalFracturedWell&>(
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;
}