#include "nmWellParameterCatalog.h" #include "nmDataHorizontalFracturedWell.h" #include "nmDataPerforation.h" #include "nmDataVerticalFracturedWell.h" #include "nmDataWellBase.h" #include namespace { /* Qt 4.8的lupdate需要显式标记间接翻译字符串。 */ static const char* const s_pCatalogTranslationMarkers[] = { QT_TRANSLATE_NOOP("nmWxWellEditor", "Basic parameters"), QT_TRANSLATE_NOOP("nmWxWellEditor", "Perforation parameters"), QT_TRANSLATE_NOOP("nmWxWellEditor", "Fracture parameters"), QT_TRANSLATE_NOOP("nmWxWellEditor", "Perforation name") }; QString editorText(const char* pText) { Q_UNUSED(s_pCatalogTranslationMarkers); return QCoreApplication::translate("nmWxWellEditor", pText); } nmParameterFieldInfo numericField(nmWellParameterId eParameterId, const QString& sBaseParameterId, nmParameterEditorType eEditorType = NM_PARAMETER_EDITOR_NUMBER) { // 数值字段显示名称、精度、范围和单位均由基础参数XML提供。 nmParameterFieldInfo oFieldInfo; oFieldInfo.m_sParameterId = nmWellParameterCatalog::parameterId(eParameterId); oFieldInfo.m_sBaseParameterId = sBaseParameterId; oFieldInfo.m_eEditorType = eEditorType; oFieldInfo.m_bUnitEnabled = true; return oFieldInfo; } nmParameterFieldInfo textField(nmWellParameterId eParameterId, const char* pLabel) { // 文本字段没有XML数值定义,目录直接提供可翻译名称。 nmParameterFieldInfo oFieldInfo; oFieldInfo.m_sParameterId = nmWellParameterCatalog::parameterId(eParameterId); oFieldInfo.m_sLabel = editorText(pLabel); oFieldInfo.m_eEditorType = NM_PARAMETER_EDITOR_TEXT; oFieldInfo.m_bUnitEnabled = false; return oFieldInfo; } nmWellParameterGroupInfo parameterGroup(const char* pTitle) { nmWellParameterGroupInfo oGroupInfo; oGroupInfo.m_sTitle = editorText(pTitle); return oGroupInfo; } } nmWellParameterGroupInfo::nmWellParameterGroupInfo() : m_bPerforationGroup(false) { } QList nmWellParameterCatalog::createGroups( NM_WELL_MODEL eWellType) { QList listGroups; // 第一步:所有支持井型都显示通用井筒参数。 nmWellParameterGroupInfo oBasic = parameterGroup("Basic parameters"); oBasic.m_listFields << numericField(NM_WELL_PARAMETER_X, "W_X") << numericField(NM_WELL_PARAMETER_Y, "W_Y") << numericField(NM_WELL_PARAMETER_RADIUS, "W_Rw") << numericField(NM_WELL_PARAMETER_STORAGE, "W_C") << numericField(NM_WELL_PARAMETER_BOTTOMHOLE_MD, "W_BottomholeMD") << numericField(NM_WELL_PARAMETER_LENGTH, "W_WellLength"); listGroups.append(oBasic); // 第二步:射孔字段由选择器定位到当前射孔段,字段定义保持不变。 nmWellParameterGroupInfo oPerforation = parameterGroup("Perforation parameters"); oPerforation.m_bPerforationGroup = true; oPerforation.m_listFields << textField(NM_WELL_PARAMETER_PERFORATION_NAME, "Perforation name") << numericField(NM_WELL_PARAMETER_PERFORATION_MD_START, "W_PerforationMdStart") << numericField(NM_WELL_PARAMETER_PERFORATION_MD_END, "W_PerforationMdEnd") << numericField(NM_WELL_PARAMETER_PERFORATION_SKIN, "W_Skin"); listGroups.append(oPerforation); // 第三步:裂缝分组按井型追加字段,水平井额外显示排水角度和裂缝数。 if (eWellType == Vertical_Fractured_Well || eWellType == Horizontal_Fractured_Well) { nmWellParameterGroupInfo oFracture = parameterGroup("Fracture parameters"); if (eWellType == Horizontal_Fractured_Well) { oFracture.m_listFields << numericField(NM_WELL_PARAMETER_DRAIN_ANGLE, "W_DrainAngle") << numericField(NM_WELL_PARAMETER_FRACTURE_COUNT, "W_NumberOfFractures", NM_PARAMETER_EDITOR_INTEGER); } oFracture.m_listFields << numericField(NM_WELL_PARAMETER_FRACTURE_HALF_LENGTH, "W_FractureHalfLength") << numericField(NM_WELL_PARAMETER_FRACTURE_ANGLE, "W_FractureAngle") << numericField(NM_WELL_PARAMETER_FRACTURE_HEIGHT, "W_FractureHeight") << numericField(NM_WELL_PARAMETER_FRACTURE_MIDPOINT_HEIGHT, "W_FractureMidPointHeight") << numericField(NM_WELL_PARAMETER_FRACTURE_WIDTH, "W_FractureWidth") << numericField(NM_WELL_PARAMETER_FRACTURE_CONDUCTIVITY, "W_Dfc"); listGroups.append(oFracture); } return listGroups; } QString nmWellParameterCatalog::parameterId( nmWellParameterId eParameterId) { // 稳定ID不参与翻译,也不依赖XML名称,供字段映射和校验规则长期使用。 static const char* const s_pParameterIds[] = { "well.x", "well.y", "well.radius", "well.storage", "well.bottomhole_md", "well.length", "perforation.name", "perforation.md_start", "perforation.md_end", "perforation.skin", "fracture.drain_angle", "fracture.count", "fracture.half_length", "fracture.angle", "fracture.height", "fracture.midpoint_height", "fracture.width", "fracture.conductivity" }; int nIndex = static_cast(eParameterId); int nCount = static_cast(sizeof(s_pParameterIds) / sizeof(s_pParameterIds[0])); return nIndex >= 0 && nIndex < nCount ? QString::fromLatin1(s_pParameterIds[nIndex]) : QString(); } nmDataAttribute* nmWellParameterCatalog::attribute( nmDataWellBase* pWell, const QString& sParameterId, int nPerforationIndex) { if (pWell == nullptr) { return nullptr; } // 第一步:解析所有井型共有的基础属性。 if (sParameterId == parameterId(NM_WELL_PARAMETER_X)) { return &pWell->getX(); } if (sParameterId == parameterId(NM_WELL_PARAMETER_Y)) { return &pWell->getY(); } if (sParameterId == parameterId(NM_WELL_PARAMETER_RADIUS)) { return &pWell->getRadius(); } if (sParameterId == parameterId(NM_WELL_PARAMETER_STORAGE)) { return &pWell->getWellboreStorage(); } if (sParameterId == parameterId(NM_WELL_PARAMETER_BOTTOMHOLE_MD)) { return &pWell->getBottomholeMD(); } if (sParameterId == parameterId(NM_WELL_PARAMETER_LENGTH)) { return &pWell->getWellLength(); } // 第二步:射孔字段绑定到面板当前选择的射孔对象。 if (isPerforationParameter(sParameterId)) { nmDataPerforation* pPerforation = pWell->getPerforation(nPerforationIndex); if (pPerforation == nullptr) { return nullptr; } if (sParameterId == parameterId( NM_WELL_PARAMETER_PERFORATION_NAME)) { return &pPerforation->getName(); } if (sParameterId == parameterId( NM_WELL_PARAMETER_PERFORATION_MD_START)) { return &pPerforation->getMdStart(); } if (sParameterId == parameterId( NM_WELL_PARAMETER_PERFORATION_MD_END)) { return &pPerforation->getMdEnd(); } return &pPerforation->getSkin(); } // 第三步:优先解析水平压裂井专属及共享裂缝属性。 nmDataHorizontalFracturedWell* pHorizontal = dynamic_cast(pWell); if (pHorizontal != nullptr) { if (sParameterId == parameterId(NM_WELL_PARAMETER_DRAIN_ANGLE)) { return &pHorizontal->getDrainAngle(); } if (sParameterId == parameterId(NM_WELL_PARAMETER_FRACTURE_COUNT)) { return &pHorizontal->getNumberOfFractures(); } if (sParameterId == parameterId( NM_WELL_PARAMETER_FRACTURE_HALF_LENGTH)) { return &pHorizontal->getFractureHalfLength(); } if (sParameterId == parameterId(NM_WELL_PARAMETER_FRACTURE_ANGLE)) { return &pHorizontal->getFractureAngle(); } if (sParameterId == parameterId(NM_WELL_PARAMETER_FRACTURE_HEIGHT)) { return &pHorizontal->getFractureHeight(); } if (sParameterId == parameterId( NM_WELL_PARAMETER_FRACTURE_MIDPOINT_HEIGHT)) { return &pHorizontal->getFractureMidPointHeight(); } if (sParameterId == parameterId(NM_WELL_PARAMETER_FRACTURE_WIDTH)) { return &pHorizontal->getWidth(); } if (sParameterId == parameterId( NM_WELL_PARAMETER_FRACTURE_CONDUCTIVITY)) { return &pHorizontal->getDfc(); } } // 第四步:解析垂直压裂井的裂缝属性;普通直井在此返回空。 nmDataVerticalFracturedWell* pVertical = dynamic_cast(pWell); if (pVertical != nullptr) { if (sParameterId == parameterId( NM_WELL_PARAMETER_FRACTURE_HALF_LENGTH)) { return &pVertical->getFractureHalfLength(); } if (sParameterId == parameterId(NM_WELL_PARAMETER_FRACTURE_ANGLE)) { return &pVertical->getFractureAngle(); } if (sParameterId == parameterId(NM_WELL_PARAMETER_FRACTURE_HEIGHT)) { return &pVertical->getFractureHeight(); } if (sParameterId == parameterId( NM_WELL_PARAMETER_FRACTURE_MIDPOINT_HEIGHT)) { return &pVertical->getFractureMidPointHeight(); } if (sParameterId == parameterId(NM_WELL_PARAMETER_FRACTURE_WIDTH)) { return &pVertical->getWidth(); } if (sParameterId == parameterId( NM_WELL_PARAMETER_FRACTURE_CONDUCTIVITY)) { return &pVertical->getDfc(); } } return nullptr; } bool nmWellParameterCatalog::isPerforationParameter( const QString& sParameterId) { return sParameterId.startsWith("perforation."); }