#ifndef NMDATAANALYZEMANAGER_H #define NMDATAANALYZEMANAGER_H #include #include "ZxDataObjectBin.h" #include "nmData_global.h" #include "nmDefines.h" #include "nmDataVerticalWell.h" #include "nmDataHorizontalWell.h" #include "nmDataVerticalFracturedWell.h" #include "nmDataHorizontalFracturedWell.h" #include "nmGridDefine.h" #include #include #include #include #include #include #include #include #include // 子类别显示信息结构 struct ChildCategoryDisplayInfo { QString name; // 子项名称 bool isChecked; // 子项是否选中 bool isEnabled; // 子项是否启用 (取决于父项的选中状态) }; // 类别显示信息结构 struct CategoryDisplayInfo { bool isRootChecked; // 根节点是否选中 QVector childItems; // 子节点信息列表 }; // 整体 struct DisplaySetting { QString key; CategoryDisplayInfo value; }; // 油藏地图显示信息结构体 struct BackgroundImageInfo { bool bIsVisible; // 是否显示背景图片到地图 QString sFilePath; // 背景图片的文件路径 QImage objImage; // 具体的QImage对象 }; class nmDataWellBase; class ZxDataWell; class nmDataReservoir; class nmDataRegionMark; class nmDataRegion; class nmDataOutline; class nmDataFracture; class nmDataFault; class nmDataAxis; class nmGuiPlot; class nmDataMeasuringScale; class nmDataMeasure; class nmDataPvtParaForPebi; class nmDataMixedResults; class nmDataLayer; class nmDataGeoRef; class nmDataAutomaticFitting; class nmDataDiagnostic; class nmDataForecast; class ZxDataWell; class iSubWndFitting; class nmDataTimeStepSetting; class nmDataSensitive; class NM_DATA_EXPORT nmDataAnalyzeManager : public ZxDataObjectBin { ZX_DECLARE_DYNAMIC Q_OBJECT public: nmDataAnalyzeManager(); // 分析窗口和数据管理器的映射关系 static QMap s_mapDataAnalManager; // 当前操作的分析窗体 static iSubWndFitting* s_pCurSubWndFitting; // 根据流动段分析窗口的指针作为唯一标识 static nmDataAnalyzeManager* getInstanceByFitting(iSubWndFitting* pSubWndF); /** * @brief 根据流动段分析窗口指针(key)查找对应的分析管理器实例(value) * @param pSubWndF 流动段分析窗口指针(作为key) * @return 返回对应的 nmDataAnalyzeManager 实例指针,如果未找到则返回 nullptr */ static nmDataAnalyzeManager* findManagerByFitting(iSubWndFitting* pSubWndF) { return s_mapDataAnalManager.value(pSubWndF, nullptr); } static iSubWndFitting* getCurrentFitting() { return s_pCurSubWndFitting; } static void setCurrentFitting(iSubWndFitting* pSubWndF) { s_pCurSubWndFitting = pSubWndF; } // 获取当前分析窗体下的指针 static nmDataAnalyzeManager* getCurrentInstance(); // 井的接口 // 添加井 nmDataWellBase* createWell(NM_WELL_MODEL eWellType); nmDataWellBase* changeWellType(nmDataWellBase* pOldWellData, NM_WELL_MODEL eTargetWellType); bool removeWell(nmDataWellBase* pWellData); // 移除井图元以及数据 void removeWellDataAndPlot(nmDataWellBase* pWellData); /** * @brief 清空所有井数据 * @note 会删除所有井对象并清空数组 */ void clearAllWellData(); // 获取井的数据 QVector getWellDataList() const; // 井副本数据 //QVector getWellDataListCopy() const; // TODO:有问题,不会更新不同类型的井数据 //void updateWellData(const QVector& newData); // 添加针对具体井类型的更新方法 void updateVerticalWells(const QVector& wells); void updateVerticalFracturedWells(const QVector& wells); void updateHorizontalFracturedWells(const QVector& wells); // 返回分类后的井数据 // 获取所有直井数据 QVector getVerticalWellData() const; // 获取所有垂直裂缝井数据 QVector getVerticalFracturedWellData() const; // 获取所有多段压裂水平井数据 QVector getHorizontalFracturedWellData() const; // 通过井的名称查找井数据 //nmDataWellBase* findWellByName(const QString& wellName) const; nmDataWellBase* findWellByName(QString wellName) const; // 初始化测试井数据,即点击数值解的时候,将当前井添加到里面 void initCurWellData(); // 添加井数据,包括对应的流量数据和压力数据 void appendWellData(ZxDataWell* pWellData); // 直接添加自定义的井数据 void appendNmWellData(nmDataWellBase* pWellData); // 初始化油藏参数 void createReservoir(); // 获取油藏参数 nmDataReservoir* getReservoirData() const; // 返回油藏副本数据 nmDataReservoir getReservoirDataCopy() const; void updateReservoirData(const nmDataReservoir& newData); // 初始化坐标轴参数 nmDataAxis* getAxisData() const; void setAxisData(nmDataAxis* pAxisData); // 从流动段分析窗口获取对应的PVT相关数据 void initPvtParaFromSubFit(); // 初始化区域标记参数 nmDataRegionMark* createRegionMark(); // 获取区域标记数据 QVector getRegionMarkDataList() const; // 移除区域标记数据 bool removeRegionMarkData(nmDataRegionMark* pData); // 返回区域标记副本数据 QVector getRegionMarkDataListCopy() const; void updateRegionMarkData(const QVector& newData); // 初始化边界数据 nmDataOutline* createOutline(); nmDataOutline* getOutlineData(); // 移除边界数据 bool removeOutlineData(); // 返回边界副本数据 nmDataOutline getOutlineDataCopy() const; void updateOutlineData(const nmDataOutline& newData); // 初始化复合区数据 nmDataRegion* createRegion(); // 获取复合区数据 QVector getRegionDataList() const; // 移除复合区数据 bool removeRegionData(nmDataRegion* pData); // 返回复合区副本数据 QVector getRegionDataListCopy() const; void updateRegionData(const QVector& newData); // 初始化裂缝数据 nmDataFracture* createFracture(); // 获取所有裂缝数据 QVector getFractureDataList() const; // 获取DNF生成的裂缝数据 QVector getDFNFractureDataList() const; // 移除裂缝数据 bool removeFractureData(nmDataFracture* pData); // 返回裂缝副本数据 QVector getFractureDataListCopy() const; void updateFractureData(const QVector& newData); // 初始化断层数据 nmDataFault* createFault(); // 获取断层数据 QVector getFaultDataList() const; // 移除断层数据 bool removeFaultData(nmDataFault* pData); // 返回断层数据副本 QVector getFaultDataListCopy() const; // 更新断层数据 void updateFaultData(const QVector& newData); // 绘图 nmGuiPlot* getPlot() const; void setPlot(nmGuiPlot* plot); // 更新井图元 void updateWellPlotByDataManager(); // 获取所有可连接的点(Value:实际坐标) QVector getValueAllConnectablePoints(); // 获取所有可连接的点(Pos:屏幕坐标) QVector getPosAllConnectablePoints(); // 根据传入的指针,去掉对应的点的坐标 QVector removePosByObject(QObject* obj); // 比例尺数据对象相关 nmDataMeasuringScale* getMeasuringScaleData(); void setMeasuringScaleData(nmDataMeasuringScale *pMeasuringScaleData); // 测量相关 nmDataMeasure* getMeasureData(); void setMeasureData(nmDataMeasure *pMeasureData); bool removeMeasureData(); // 模型参考点相关 nmDataGeoRef* createGeoRefData(); nmDataGeoRef* getGeoRefData() const; nmDataGeoRef getGeoRefDataCopy() const; void updateGeoRefData(const nmDataGeoRef& newData); // 预测相关 nmDataForecast* createForecastData(); nmDataForecast* getForecastData() const; nmDataForecast getForecastDataCopy() const; void updateForecastData(const nmDataForecast& newData); // 敏感性分析相关 nmDataSensitive* createSensitiveData(); nmDataSensitive* getSensitiveData() const; nmDataSensitive getSensitiveDataCopy() const; void updateSensitiveData(const nmDataSensitive& newData); // 自动拟合相关 nmDataAutomaticFitting* createAutomaticFittingData(); nmDataAutomaticFitting* getAutomaticFittingData() const; nmDataAutomaticFitting getAutomaticFittingDataCopy() const; void updateAutomaticFittingData(const nmDataAutomaticFitting& newData); // 诊断参数相关 nmDataDiagnostic* getDiagnosticData() const; // 应用诊断结果 void applyDiagnosticResults(nmDataDiagnostic* diagnostic, nmDataWellBase* wellData, nmDataReservoir* reservoirData); // 重置功能相关方法 bool resetFromDiagnostic(); // 诊断重置业务逻辑 bool resetFromAnalytical(); // 分析重置业务逻辑 // 网格类型 NM_Grid_Type getGridType(); void setGridType(NM_Grid_Type newGridType); // 获取Pebi网格求解数据接口 // 获取压力历史数据 QVector> getPebiSolverHistoryDataByName(const QString& wellName); // 获取压力对数信息 QVector> getPebiSolverLogPreDataByName(const QString& wellName); // 获取压力半对数数据 QVector> getPebiSolverSemiLogPreDataByName(const QString& wellName); // 获取PEBI求解器需要的pvt数据 nmDataPvtParaForPebi* getPebiPvtPara(); // 获取混合结果参数 nmDataMixedResults* getMixedResults(); // 创建混合结果参数对象 nmDataMixedResults* createMixedResult(); // 获取储层数据 nmDataLayer* getLayerData(); // 添加多储层数据 void setLayers(QVector vecLayers); // 获取多储层数据 QVector getLayers(); // 获取储层边界数据 double getMinLayerTop(); double getMaxLayerBottom(); // 在末尾追加一个新的井信息 void appendCalculationWell(const QPair& well); // 在指定位置插入一个新的井信息 void insertCalculationWell(int index, const QPair& well); // 移除指定位置的井信息 bool removeCalculationWell(int index); // 清空容器 void clearCalculationWells(); // 返回井信息的副本 QVector> getCalculationWells() const; // 查询当前计算井中是否有某口井 bool isContainsWellName(const QString& wellName) const; // 设置当前查看井 void setCurWellData(nmDataWellBase* wellData); // 获取当前查看井 nmDataWellBase* getCurWellData(); void notifyDataChanged(); /** * @brief 设置显示设置信息。 * @param displaySettings 包含所有类别显示状态的QVector。 */ void setDisplaySettings(const QVector& displaySettings); /** * @brief 获取当前显示设置信息。 * @return 包含所有类别显示状态的QVector。 */ QVector getDisplaySettings() const; /** * @brief 更新单个类别的显示设置。 * @param categoryName 类别名称。 * @param info 要更新的CategoryDisplayInfo。 * @return 如果找到并更新了指定类别返回true,否则返回false */ bool updateCategoryDisplaySetting(const QString& categoryName, const CategoryDisplayInfo& info); // 初始化默认显示设置 void initDefaultDisplaySettings(); // 用于查找类别 CategoryDisplayInfo* findCategoryDisplayInfo(const QString& categoryName); /** * @brief 向显示设置向量中添加一个子元素。 * @param displaySetting 要添加的DisplaySetting结构。 * @return 添加成功返回true,否则返回false(如已存在相同key) */ bool appendDisplaySetting(const DisplaySetting& displaySetting); /** * @brief 从显示设置向量中删除指定key的子元素。 * @param categoryName 要删除的类别的key。 * @return 删除成功返回true,否则返回false(如未找到) */ bool removeDisplaySetting(const QString& categoryName); /** * @brief 为指定的父类别添加子项 * @param parentCategory 父类别名称(如"Wells", "Faults"等) * @param childNames 要添加的子项名称列表 * @param defaultChecked 子项的默认选中状态 * @return 添加成功返回true,如果父类别不存在则返回false */ bool nmDataAnalyzeManager::addChildItemsToCategory(const QString& parentCategory, const QStringList& childNames, bool defaultChecked); // 刷新当前显示的子节点 void nmDataAnalyzeManager::refreshChildItemsDisplay(); void addWellChildItemsToCategory(const QString& parentCategory); void addFaultChildItemsToCategory(const QString& parentCategory); void addFractureChildItemsToCategory(const QString& parentCategory); void addRegionChildItemsToCategory(const QString& parentCategory); void addRegionMarkChildItemsToCategory(const QString& parentCategory); /** * @brief 设置所有类别的根节点可见性 * @param isVisible true为全部可见,false为全部不可见 */ void setAllCategoriesRootVisibility(bool bIsVisible); // 设置背景图片信息 void setBackgroundImageInfo(const BackgroundImageInfo& info); // 获取背景图片信息 const BackgroundImageInfo& getBackgroundImageInfo() const; // 统一的读写整个项目数据的方法 // @param filePath JSON文件的路径 // @return 读取成功返回 true,否则返回 false bool ReadProjectData(const QString& filePath); // 统一的写整个项目数据的方法 // @param filePath JSON文件的路径 // @return 写入成功返回 true,否则返回 false bool WriteProjectData(const QString& filePath); // 保存数值成果到本地 // @param sRstCode 当前成果ID // @param pSubWndF 当前分析窗体 // @return 保存成功返回 true,否则返回 false bool saveNmResult(QString sRstCode, iSubWndFitting* pSubWndF); // 加载本地成果到内存中 // @param sLoadAnalDir 加载的分析目录 // @return 保存成功返回 true,否则返回 false bool loadNmResult(QString sLoadAnalDir); // 辅助函数:确保目录存在,如果不存在则创建 bool ensureDirectoryExists(const QString& dirPath); /** * @brief 判断指定目录是否存在。 * @param sDirPath 要检查的目录路径。 * @return 如果目录存在且可访问,则返回true,否则返回false。 */ static bool isDirExist(const QString& sDirPath) { QFileInfo dirInfo(sDirPath); bool bExists = dirInfo.exists() && dirInfo.isDir(); return bExists; } // 加载井数组里对应的压力、流量数据,这个是在井里没有这些数据的情况下调用 void loadWellPreAndFlow(); // 设置当前分析下的VTK网格对象 void setUnstructuredGrid(vtkSmartPointer grid); // 获取当前分析下的VTK网格对象 vtkSmartPointer getUnstructuredGrid() const; // 清理当前分析下的VTK网格对象 void clearUnstructuredGrid(); // 获取当前分析下的VTK网格对象的深拷贝对象,一般复制给m_pResultBaseGrid,使用深拷贝,防止场图污染网格 vtkSmartPointer getUnstructuredGridCopy() const; // 设置当前分析下的结果基础网格 void setResultBaseGrid(vtkSmartPointer grid); // 获取当前分析下的结果基础网格 vtkSmartPointer getResultBaseGrid() const; // 获取当前分析下的结果基础网格的深拷贝对象,一般作为场图渲染的基础网格 vtkSmartPointer getResultBaseGridCopy() const; // 将非结构化网格数据写入文件 bool writeUnstructuredGridToFile(vtkSmartPointer grid, const QString& filePath); // 从文件读取非结构化网格数据 bool readUnstructuredGridFromFile(vtkSmartPointer& grid, const QString& filePath); // 添加时间步数据 void addTimeStep(double time, vtkSmartPointer data); // 获取时间步数据 vtkSmartPointer getTimeStepData(double time) const; // 获取时间步数据 QMap 的所有键(时间点) QList getTimeStepKeys(); // 判断当前是否存储了时间步数据 bool isTimeStepDataEmpty(); // 保存整个时间步数据QMap到单个二进制文件 bool writeTimeStepDataMapToBinaryFile(const QString& filePath); // 从单个二进制文件加载整个时间步数据QMap bool readTimeStepDataMapFromBinaryFile(const QString& filePath); // 保存井的历史数据(所有井都要调用) bool saveWellHistoryData(QString sDir, nmDataWellBase* pWellData); // 加载井的历史数据(所有井都要调用) bool loadWellHistoryData(QString sDir, nmDataWellBase* pWellData); // 保存参与计算井的结果到本地,压力、双对数、半对数 bool saveWellCalRstData(QString sDir, nmDataWellBase* pWellData); // 加载井的计算结果到内存 bool loadWellCalRstData(QString sDir, nmDataWellBase* pWellData); // 获取 / 设置 压力标量值的范围 void getScalarRangeP(double range[2]) const; void setScalarRangeP(double min, double max); // 用于获取和设置井位置信息的接口 void addWellLocation(const QString& wellName, const QPointF& location); QPointF getWellLocation(const QString& wellName) const; bool removeWellLocation(const QString& wellName); void clearWellLocations(); QMap getAllWellLocations() const; // 获取所有井位置的副本 // 保存/加载当前场图中的井位置相关信息 bool saveWellLocations(const QString& filePath); bool loadWellLocations(const QString& filePath); // 创建时间步数据 //void createTimeStep(); nmDataTimeStepSetting* createTimeStep(); // 获取时间步数据 nmDataTimeStepSetting* getTimeStep(); void calculationLogData( nmDataWellBase* pWellData, QVector>& vvecHistoryData, QVector>& vvecLogPreData, QVector>& vvecSemiLogPreData); // 获取许可证路径 void setLicensePath(const QString& licensePath); QString getLicensePath() const; signals: void dataChanged(); private: // 存储井的数据 QVector m_vWellData; // 断层数据 QVector m_vFaultData; // 裂缝数据 QVector m_vFractureData; // 复合区数据 QVector m_vRegionData; // 区域标记数据 QVector m_vRegionMarkData; // 边界数据 nmDataOutline* m_outlineData; // 坐标轴范围数据 nmDataAxis* m_axisData; // 自动拟合数据 nmDataAutomaticFitting* m_pAutomaticFittingData; // 油藏数据 nmDataReservoir* m_reservoirData; // 存储nmGuiPlot,绘图 nmGuiPlot* m_pNmGuiPlot; // 比例尺信息 nmDataMeasuringScale* m_pMeasuringScaleData; // 测量信息 nmDataMeasure* m_pMeasureData; // 模型参考点信息 nmDataGeoRef* m_pGeoRefData; // 预测信息 nmDataForecast* m_pForecastData; // 敏感性信息 nmDataSensitive* m_pSensitiveData; // 诊断参数 nmDataDiagnostic* m_pDiagnosticData; // 网格类型 NM_Grid_Type m_eGridType; // Pvt数据(Pebi) nmDataPvtParaForPebi* m_pebiPvtPara; // 混合结果参数 nmDataMixedResults* m_pMixedResults; // 储层数据 nmDataLayer* m_pLayerData; QVector m_vecLayers; // 通过储层对话框后初始化的数组,临时 // 孔射封堵 //nmDataPerforationClosing* m_pPerCloData; // 存储PEBI求解井顺序 QVector> m_vecCalculationWells; // 当前查看的是哪一口井的数据,也是哪一口测试井 nmDataWellBase* m_pCurDataWell; // 显示设置信息 QVector m_vecDisplaySettings; // 背景图片信息 BackgroundImageInfo m_backgroundImageInfo; // VTK非结构化网格对象,用于展示网格划分窗体 vtkSmartPointer m_pVtkUnstructuredGrid; // VTK非结构化网格对象,用于结果场图里的基础网格 vtkSmartPointer m_pResultBaseGrid; // 时间步压力数据 QMap> m_mapTimeStepDataP; // 压力值范围 [min, max] double m_dScalarRangeP[2]; // 存储井名称及其二维位置坐标的映射,这里应该是参与计算求解的井 QMap m_mapWellLocations; // 时间步设置数据 nmDataTimeStepSetting* m_pTimeStep; // 许可证路径 QString m_licensePath; public: // 数据是否是从本地加载进来的 bool m_bIsLoadData; }; #endif // NMDATAANALYZEMANAGER_H