This commit is contained in:
coco
2026-07-03 16:05:30 +08:00
commit df489d5640
1101 changed files with 779140 additions and 0 deletions
@@ -0,0 +1,286 @@
# 测量数据模型
<cite>
**本文档引用的文件**
- [TestingData.cpp](file://cpp\ProblemZone\TestingData.cpp)
- [TestingData.h](file://h\TestingData.h)
- [TdRecord.cpp](file://cpp\ProblemZone\TdRecord.cpp)
- [TdRecord.h](file://h\TdRecord.h)
- [Channel.cpp](file://cpp\ProblemZone\Channel.cpp)
- [Channel.h](file://h\Channel.h)
- [Electrode.cpp](file://cpp\ProblemZone\Electrode.cpp)
- [Electrode.h](file://h\Electrode.h)
- [AppDataSP2DTdView.cpp](file://cpp\Views\AppDataSP2DTdView.cpp)
- [SP2DTd.h](file://h\SP2DTd.h)
- [SP2DTdRecord.h](file://h\SP2DTdRecord.h)
</cite>
## 目录
1. [引言](#引言)
2. [核心数据模型体系](#核心数据模型体系)
3. [TestingData类分析](#testingdata类分析)
4. [TdRecord类分析](#tdrecord类分析)
5. [通道与电极数据管理](#通道与电极数据管理)
6. [地球物理参数计算模型](#地球物理参数计算模型)
7. [视图组件与数据可视化](#视图组件与数据可视化)
8. [数据采集与处理流程](#数据采集与处理流程)
9. [数据校验与异常处理](#数据校验与异常处理)
## 引言
GeomativeStudio测量数据模型体系是一个完整的地球物理数据采集与处理框架,旨在管理从设备采集到的原始测量数据,并将其转换为可用于分析和可视化的地球物理参数。该体系以TestingData类为核心,通过聚合TdRecord、Channel和Electrode等组件,构建了一个层次化的数据容器结构。本文档将深入解析这一数据模型体系,重点阐述其核心组件的职责、相互关系以及数据处理流程。
## 核心数据模型体系
GeomativeStudio的测量数据模型采用面向对象的设计模式,构建了一个层次化的数据容器体系。该体系以TestingData类作为顶层数据容器,负责管理一次完整的测量任务的所有数据。TestingData类通过聚合关系管理多个Channel对象,每个Channel代表一个数据采集通道,负责管理该通道下的所有测量记录(TdRecord)。同时,TestingData类还管理着电极配置(Electrode)信息,定义了测量过程中的电极几何布局。
该数据模型体系支持多种地球物理测量方法,包括视电阻率(SP)、电阻率反演(Rsp)和激电二次场(Ipsp)等。每种测量方法都有对应的派生类,如SP2DTd、Rsp2DTd和Ipsp2DTd等,这些类继承自TestingData类并实现了特定的计算逻辑。这种设计模式使得系统能够灵活地支持不同的测量技术和数据处理算法。
**Section sources**
- [TestingData.h](file://h\TestingData.h#L158-L273)
- [Channel.h](file://h\Channel.h#L19-L34)
- [Electrode.h](file://h\Electrode.h#L12-L24)
## TestingData类分析
TestingData类是整个测量数据模型体系的核心,作为顶层数据容器负责管理一次测量任务的所有相关数据。该类在构造时接收一个数据库连接指针和任务ID,用于与数据库进行交互。类中定义了大量的成员变量,用于存储测量任务的元数据,包括任务名称、位置、测量类型、电极数量、测量模式等。
该类通过m_tdChaList成员变量管理多个Channel对象,形成了一对多的聚合关系。每个Channel对象代表一个独立的数据采集通道,可以同步采集多通道数据。TestingData类还提供了丰富的数据操作方法,包括数据加载(LoadData)、数据保存(SaveTdToExcelFile、SaveTdToRes2DFile等)和数据显示(ShowConList、ShowGrList等)。
特别值得注意的是,TestingData类中定义了复杂的时窗计算相关结构体,如_WinTime、_WinTimeList和_WaveCount,这些结构体用于存储和处理激电测量中的时域信息。类中的CalculateTWInfo和CalculateTimeWindows方法实现了激电数据的时窗积分和参数计算,这是激电测量数据处理的核心算法。
```mermaid
classDiagram
class CTestingData {
+DWORD m_dwID
+CString m_szTdName
+CString m_szTdCN
+int m_iSType
+int m_iTType
+int m_iEAmount
+float m_fESpace
+CString m_szEDistance
+CPtrList m_tdChaList
+_WaveCount* m_waveCount
+CTestingData(DWORD, _ConnectionPtr&)
+virtual ~CTestingData()
+bool ShowConListByPage(CListCtrl&, int)
+BOOL SaveOrgDataToDB(DWORD)
+bool CalculateTWInfo(CStringArray*, int)
+bool CalculateTimeWindows(_WinTimeList, CStringArray*, int, int, int, int, int)
}
class CChannel {
+int m_iChNumber
+int m_iMaxLevel
+int m_iPtAmount
+int m_iEAmount
+CMedium* m_pMedium
+CPtrArray m_sptRecArray
+CChannel()
+virtual ~CChannel()
+void ClearSptRecList()
}
class CElectrode {
+CString m_szECode
+BOOL m_bCState
+CString m_szMDate
+CString m_szMTime
+float m_fOMValue
+CElectrode()
+virtual ~CElectrode()
}
CTestingData --> CChannel : "聚合"
CTestingData --> CElectrode : "聚合"
```
**Diagram sources**
- [TestingData.h](file://h\TestingData.h#L158-L273)
- [Channel.h](file://h\Channel.h#L19-L34)
- [Electrode.h](file://h\Electrode.h#L12-L24)
**Section sources**
- [TestingData.cpp](file://cpp\ProblemZone\TestingData.cpp#L29-L85)
- [TestingData.h](file://h\TestingData.h#L158-L273)
## TdRecord类分析
TdRecord类是测量数据模型中的基本数据单元,代表一次具体的测量记录。该类作为抽象基类,定义了测量记录的基本结构和通用操作。每个TdRecord对象包含测量的基本参数,如通道ID(m_dwChID)、测点编号(m_iTsn)、电极配置参数(m_iN)、几何因子(m_fK)、电流(m_fI)、电压(m_fV)、视电阻率(m_fSP)等。
该类的核心功能是管理原始测量数据,通过m_saVRawData和m_saIRawData两个CStringArray成员变量存储电压和电流的原始波形数据。类中定义了LoadOrgData纯虚函数,由派生类实现具体的原始数据加载逻辑。同时,该类提供了ConvertVOrgData方法,用于将原始电压数据转换为实际物理值。
TdRecord类还实现了原始数据的可视化功能,通过DisplayRawDataSplines方法可以显示电压原始波形曲线。该方法首先调用LoadOrgData加载原始数据,然后创建CDispTdRecSplinesGrapDlg对话框来显示波形。类中还维护了m_fMaxAbsV变量,用于存储电压原始数据的最大绝对值,这在波形显示时用于确定Y轴的缩放比例。
```mermaid
classDiagram
class CTdRecord {
+DWORD m_dwChID
+int m_iTsn
+int m_iN
+float m_fK
+float m_fI
+float m_fV
+float m_fR0
+float m_fSP
+CString m_Datetime
+CStringArray m_saVRawData
+CStringArray m_saIRawData
+_ConnectionPtr m_pConnection
+CTdRecord(_ConnectionPtr&)
+virtual ~CTdRecord()
+float GetMaxAbsV()
+virtual void DisplayRawDataSplines()
+virtual BOOL LoadOrgData()
+virtual float ConvertVOrgData(float)
}
CTdRecord <|-- SP2DTdRecord : "继承"
CTdRecord <|-- Rsp2DTdRecord : "继承"
CTdRecord <|-- Ipsp2DTdRecord : "继承"
```
**Diagram sources**
- [TdRecord.h](file://h\TdRecord.h#L12-L46)
- [SP2DTdRecord.h](file://h\SP2DTdRecord.h)
**Section sources**
- [TdRecord.cpp](file://cpp\ProblemZone\TdRecord.cpp#L21-L325)
- [TdRecord.h](file://h\TdRecord.h#L12-L46)
## 通道与电极数据管理
通道(Channel)和电极(Electrode)是测量数据模型中的两个关键组件,分别负责管理数据采集通道和电极配置信息。Channel类作为数据采集通道的抽象,每个Channel对象代表一个独立的采集通道,可以同步采集多通道数据。类中通过m_sptRecArray成员变量管理多个SptRecord对象,这些对象代表了该通道下的所有测量脚本记录。
Channel类还与测量装置(Medium)相关联,通过m_pMedium指针引用具体的测量装置配置。不同的测量装置类型(如温纳装置、施伦贝谢装置等)决定了电极的排列方式和测量方法。类中定义了m_iEAmount成员变量来记录该通道使用的电极数量,m_iMaxLevel记录了测量的最大层级。
Electrode类则负责管理单个电极的配置信息,包括电极编码(m_szECode)、连接状态(m_bCState)、测量日期时间(m_szMDate, m_szMTime)和测量值(m_fOMValue)等。这些信息对于确保测量数据的准确性和可追溯性至关重要。在多通道同步采集场景中,多个Channel对象可以共享相同的电极配置,从而实现高效的多通道数据采集。
```mermaid
classDiagram
class CChannel {
+int m_iChNumber
+int m_iMaxLevel
+int m_iPtAmount
+int m_iEAmount
+CMedium* m_pMedium
+CPtrArray m_sptRecArray
+CChannel()
+virtual ~CChannel()
+void ClearSptRecList()
}
class CElectrode {
+CString m_szECode
+BOOL m_bCState
+CString m_szMDate
+CString m_szMTime
+float m_fOMValue
+CElectrode()
+virtual ~CElectrode()
}
class CMedium {
+int m_iType
+int m_iN
+float m_fK
+CMedium()
+virtual ~CMedium()
}
CChannel --> CMedium : "关联"
CChannel --> CElectrode : "使用"
```
**Diagram sources**
- [Channel.h](file://h\Channel.h#L19-L34)
- [Electrode.h](file://h\Electrode.h#L12-L24)
**Section sources**
- [Channel.cpp](file://cpp\ProblemZone\Channel.cpp#L11-L48)
- [Channel.h](file://h\Channel.h#L19-L34)
- [Electrode.cpp](file://cpp\ProblemZone\Electrode.cpp#L18-L27)
- [Electrode.h](file://h\Electrode.h#L12-L24)
## 地球物理参数计算模型
GeomativeStudio支持多种地球物理参数的计算,主要包括视电阻率(SP)、电阻率反演(Rsp)和激电二次场(Ipsp)等。这些参数的计算模型在相应的派生类中实现,如SP2DTd、Rsp2DTd和Ipsp2DTd等。这些类继承自TestingData类,并重写了特定的计算方法。
对于视电阻率(SP)计算,系统根据测量装置类型和电极配置,使用相应的几何因子(K)和测量得到的电压(V)、电流(I)值,通过公式ρa = K × (V/I)计算得到视电阻率。这一计算过程在SP2DTd类的实现中完成,该类还负责将计算结果保存到数据库中,并提供数据导出功能。
激电二次场(Ipsp)的计算更为复杂,涉及时域数据的处理。系统通过CalculateTWInfo方法对原始电压波形进行多项式拟合,然后在预定义的时窗内进行积分计算,得到二次场面积。再结合充电末期电压(Vp),通过公式M = 积分面积/Vp计算得到充电率(M)参数。这一过程充分利用了_WaveCount结构体来管理多时窗的计算结果。
```mermaid
flowchart TD
Start([开始]) --> LoadOrgData["加载原始数据"]
LoadOrgData --> Preprocess["数据预处理"]
Preprocess --> FitCurve["电压波形多项式拟合"]
FitCurve --> DefineTW["定义时窗"]
DefineTW --> Integrate["时窗内积分计算"]
Integrate --> CalcVp["计算充电末期电压Vp"]
CalcVp --> CalcM["计算充电率M = 积分面积/Vp"]
CalcM --> CalcETA["计算极化率η = 100×V2/Vp"]
CalcETA --> Output["输出Ipsp参数"]
Output --> End([结束])
```
**Diagram sources**
- [TestingData.cpp](file://cpp\ProblemZone\TestingData.cpp#L463-L566)
- [TestingData.h](file://h\TestingData.h#L171-L172)
**Section sources**
- [TestingData.cpp](file://cpp\ProblemZone\TestingData.cpp#L463-L566)
- [SP2DTd.h](file://h\SP2DTd.h#L17-L58)
## 视图组件与数据可视化
视图组件负责将测量数据转换为可视化图形,其中AppDataSP2DTdView是视电阻率2D测量数据的视图组件。该组件采用MFC的文档/视图架构,通过CSplitterWnd实现多窗格界面布局。在Create方法中,它创建了一个水平分割器(m_firstSplitter)和一个垂直分割器(m_secondSplitter),将视图窗口划分为三个区域。
左侧区域显示测量数据详情列表(CAppDataTdDetailListView),右侧上部区域显示数据内容列表(CAppDataSP2DTdConListView),右侧下部区域显示接地电阻列表(CAppDataTdGrListView)。这种布局使得用户可以同时查看测量数据的不同方面,提高了数据浏览的效率。
视图组件通过OnSize方法处理窗口大小调整事件,确保分割器能够正确地重新布局。当窗口大小改变时,它会调用RecalcLayout方法重新计算分割器的布局,保持界面的整洁和可用性。这种设计模式使得视图组件能够适应不同大小的显示区域,提供了良好的用户体验。
```mermaid
flowchart TD
A([AppDataSP2DTdView]) --> B["m_firstSplitter\n水平分割器"]
B --> C["左侧窗格\nCAppDataTdDetailListView"]
B --> D["右侧窗格"]
D --> E["m_secondSplitter\n垂直分割器"]
E --> F["上部窗格\nCAppDataSP2DTdConListView"]
E --> G["下部窗格\nCAppDataTdGrListView"]
```
**Diagram sources**
- [AppDataSP2DTdView.cpp](file://cpp\Views\AppDataSP2DTdView.cpp#L71-L107)
**Section sources**
- [AppDataSP2DTdView.cpp](file://cpp\Views\AppDataSP2DTdView.cpp#L25-L123)
## 数据采集与处理流程
测量数据的采集与处理流程从设备数据包接收开始,经过解析、存储到数据库,最终完成数据校验和异常值处理。流程首先通过设备对象的ReceiveFile方法从设备获取ORG格式的原始数据文件。这些文件包含了电压和电流的原始波形数据,以文本格式存储。
获取到ORG文件后,系统通过CMarkup类解析XML格式的数据,提取出每个测点的电压和电流原始数据。然后,通过SQL语句将这些原始数据更新到数据库的相应记录中。这一过程在TestingData类的SaveOrgDataToDB方法中实现,确保了原始数据的完整性和可追溯性。
数据处理阶段,系统从数据库中读取原始数据,通过SplitterString函数将其按分号分割成数组,然后对每个数据点进行转换和处理。电压数据会经过adc_calculate方法进行校准,将ADC值转换为实际的电压值。处理后的数据被存储在TdRecord对象中,供后续的参数计算和可视化使用。
```mermaid
sequenceDiagram
participant 设备 as "测量设备"
participant 应用程序 as "应用程序"
participant 数据库 as "数据库"
设备->>应用程序 : 发送ORG数据包
应用程序->>应用程序 : 接收并保存为本地文件
应用程序->>应用程序 : 使用CMarkup解析XML
应用程序->>数据库 : 执行SQL更新原始数据
数据库-->>应用程序 : 确认更新完成
应用程序->>应用程序 : 从数据库读取原始数据
应用程序->>应用程序 : 分割并转换数据
应用程序->>应用程序 : 存储处理后的数据
应用程序-->>用户 : 显示处理结果
```
**Diagram sources**
- [TestingData.cpp](file://cpp\ProblemZone\TestingData.cpp#L326-L420)
- [TdRecord.cpp](file://cpp\ProblemZone\TdRecord.cpp#L34-L211)
**Section sources**
- [TestingData.cpp](file://cpp\ProblemZone\TestingData.cpp#L326-L420)
- [TdRecord.cpp](file://cpp\ProblemZone\TdRecord.cpp#L34-L211)
## 数据校验与异常处理
系统实现了多层次的数据校验与异常处理机制,确保测量数据的准确性和系统的稳定性。在数据采集阶段,系统会检查接收到的ORG文件是否完整,如果接收失败会向用户显示错误信息。在数据解析阶段,系统会对原始数据进行有效性检查,如检查电压和电流数据的长度是否匹配。
在参数计算阶段,系统特别关注关键参数的合理性。例如,在计算充电率(M)时,系统会检查充电末期电压(Vp)是否为零,如果为零会弹出错误提示,因为这会导致除零错误。这种预防性检查避免了计算过程中的数值异常,保证了计算结果的可靠性。
异常处理主要通过C++的异常机制和MFC的消息框实现。对于数据库操作异常,系统捕获_com_error异常并显示详细的错误描述。对于用户可感知的错误,如Vp为零的情况,系统会根据当前语言设置显示中文或英文的错误消息,提高了系统的国际化支持能力。
**Section sources**
- [TestingData.cpp](file://cpp\ProblemZone\TestingData.cpp#L505-L512)
- [TdRecord.cpp](file://cpp\ProblemZone\TdRecord.cpp#L115-L118)
@@ -0,0 +1,218 @@
# 激电二次场数据模型
<cite>
**本文档引用文件**
- [Ipsp2DTd.cpp](file://cpp/ProblemZone/Ipsp2DTd.cpp)
- [Ipsp3DTd.cpp](file://cpp/ProblemZone/Ipsp3DTd.cpp)
- [IpspCETd.cpp](file://cpp/ProblemZone/IpspCETd.cpp)
- [Ipsp2DTd.h](file://h/Ipsp2DTd.h)
- [Ipsp3DTd.h](file://h/Ipsp3DTd.h)
- [IpspCETd.h](file://h/IpspCETd.h)
- [Ipsp2DTdRecord.h](file://h/Ipsp2DTdRecord.h)
- [Ipsp3DTdRecord.h](file://h/Ipsp3DTdRecord.h)
- [IpspCETdRecord.h](file://h/IpspCETdRecord.h)
- [TdChannel.h](file://h/TdChannel.h)
- [Channel.h](file://h/Channel.h)
- [AppDataIpspCETdView.cpp](file://cpp/Views/AppDataIpspCETdView.cpp)
</cite>
## 目录
1. [引言](#引言)
2. [Ipsp系列类架构](#ipsp系列类架构)
3. [核心数据结构与物理参数](#核心数据结构与物理参数)
4. [供电周期与采样时序处理](#供电周期与采样时序处理)
5. [时序对齐机制](#时序对齐机制)
6. [可视化组件与剖面生成](#可视化组件与剖面生成)
7. [数据处理流程](#数据处理流程)
8. [数据质量控制](#数据质量控制)
## 引言
Ipsp系列类(Ipsp2DTd、Ipsp3DTd、IpspCETd)是Geomative Studio软件中用于处理时间域激电法(TDIP)二次场数据的核心组件。这些类定义了从数据采集、存储、处理到可视化的完整数据模型,支持二维、三维及一维中心激电(CEIP)等多种测量模式。该数据模型不仅管理原始电压信号,还负责计算关键的地球物理参数,如视极化率、半衰时和衰减系数,为地质解释提供基础数据。
## Ipsp系列类架构
Ipsp系列类继承自`CTestingData`基类,形成一个层次化的数据处理体系。每个类针对特定的测量模式进行优化,但共享统一的数据管理接口。
```mermaid
classDiagram
class CTestingData {
+DWORD m_dwID
+_ConnectionPtr& m_pConnection
+virtual BOOL LoadData(CLinkList<CMedium*>& m_medLinkList)
+virtual BOOL SaveData()
}
class CIpsp2DTd {
+BOOL ShowConList(CListCtrl &tdConList)
+BOOL ShowGrList(CListCtrl &tdGrList)
+int GetFitEquationInfo(int nTSN, double nPeriod)
}
class CIpsp3DTd {
+BOOL ShowConList(CListCtrl &tdConList)
+BOOL ShowGrList(CListCtrl &tdGrList)
+int GetFitEquationInfo(int nTSN, double nPeriod)
}
class CIpspCETd {
+BOOL ShowConList(CListCtrl &tdConList)
+BOOL ShowGrList(CListCtrl &tdGrList)
+int GetFitEquationInfo(int nTSN, double nPeriod)
+BOOL SaveCERSPSetInfo(COpExec2DRSPTestSetDlg* pOpExec2DRSPTestSetDlg, CLinkList<CMedium*>& m_medLinkList)
}
CTestingData <|-- CIpsp2DTd
CTestingData <|-- CIpsp3DTd
CTestingData <|-- CIpspCETd
```
**图源**
- [Ipsp2DTd.h](file://h/Ipsp2DTd.h)
- [Ipsp3DTd.h](file://h/Ipsp3DTd.h)
- [IpspCETd.h](file://h/IpspCETd.h)
**节源**
- [Ipsp2DTd.h](file://h/Ipsp2DTd.h)
- [Ipsp3DTd.h](file://h/Ipsp3DTd.h)
- [IpspCETd.h](file://h/IpspCETd.h)
## 核心数据结构与物理参数
Ipsp系列类通过`CIpspXDTdRecord`记录类管理每个测点的详细数据。这些记录类继承自`CTdRecord`,并根据测量模式定义了特定的数据结构。
### 数据结构定义
| 类型 | 字段 | 描述 | 物理意义 |
| :--- | :--- | :--- | :--- |
| **CIpsp2DTdRecord** | m_iC1, m_iC2 | 供电电极编号 | 电流电极A、B的位置 |
| | m_iP1, m_iP2 | 测量电极编号 | 电位电极M、N的位置 |
| | m_iLevel, m_iPosInLevel | 测点层级与位置 | 在二维剖面中的空间索引 |
| **CIpsp3DTdRecord** | m_iC1, m_iC2 | 供电电极编号 | 电流电极A、B的位置 |
| | m_iP1, m_iP2 | 测量电极编号 | 电位电极M、N的位置 |
| | m_iLevel, m_iPosInLevel | 测点层级与位置 | 在三维网格中的空间索引 |
| **CIpspCETdRecord** | m_fA, m_fB | 电极距 | AB/2和MN/2的距离 |
| | m_fX, m_fY | 坐标 | 测点在地表的平面位置 |
| | m_fDepth | 深度 | 当前测量的深度层 |
### 关键物理参数计算
#### 二次场电压与视极化率
二次场电压(V)和视极化率(SP)是直接从数据库中读取的核心参数。视极化率(SP)是二次场电压与一次场电压的比值,通常以毫秒(ms)或百分比(%)表示。
#### 半衰时(Half-Life Time
半衰时是激电响应衰减到其初始值一半所需的时间,是反映极化体弛豫特性的重要参数。其计算通过`GetFitEquationInfo`方法实现,该方法利用多项式拟合和二分法求解。
```mermaid
flowchart TD
Start([开始]) --> LoadData["加载原始数据"]
LoadData --> CalcPeriod["计算供电周期"]
CalcPeriod --> ExtractData["提取放电阶段数据"]
ExtractData --> FitCurve["多项式拟合衰减曲线"]
FitCurve --> SolveHL["二分法求解半衰时"]
SolveHL --> AverageHL["计算多次放电的平均半衰时"]
AverageHL --> Return["返回半衰时结果"]
```
**图源**
- [Ipsp2DTd.cpp](file://cpp/ProblemZone/Ipsp2DTd.cpp#L446-L509)
- [Ipsp3DTd.cpp](file://cpp/ProblemZone/Ipsp3DTd.cpp)
- [IpspCETd.cpp](file://cpp/ProblemZone/IpspCETd.cpp)
**节源**
- [Ipsp2DTd.cpp](file://cpp/ProblemZone/Ipsp2DTd.cpp#L446-L509)
#### 衰减系数
衰减系数描述了激电响应的衰减速率。虽然代码中未直接命名“衰减系数”,但通过多项式拟合得到的系数数组(`dCoefficient`)本质上包含了衰减的数学模型,可用于计算衰减率。
## 供电周期与采样时序处理
Ipsp系列类通过`GetCycle`函数将数据库中的`TRfrequency`值转换为实际的供电周期(秒)。该周期是计算半衰时等参数的关键输入。
```cpp
// 伪代码:供电周期处理
double dPeriod = GetCycle(nTmp); // 将频率索引转换为周期
int nDataNum = atoi(m_saVRawData.GetAt(3)); // 获取采样点数
double dSplit = dPeriod / (nDataNum - 1); // 计算时间间隔
```
采样时序数据存储在`m_saVRawData`字符串数组中,其中包含了完整的电压时间序列。数据处理时,根据供电周期将时间序列分割成多个时窗,分别对每个时窗进行分析。
**节源**
- [Ipsp2DTd.cpp](file://cpp/ProblemZone/Ipsp2DTd.cpp#L453-L454)
## 时序对齐机制
Ipsp系列类通过`CTdChannel`类与`Channel`类实现时序对齐。`CTdChannel``IpspXDTd`类的数据通道,它管理一个`m_tdRecArray`数组,该数组按测点编号(TSN)顺序存储`CIpspXDTdRecord`记录。
```mermaid
classDiagram
class CIpspCETd {
+CLinkList<CTdChannel*> m_tdChaList
}
class CTdChannel {
+DWORD m_dwID
+int m_iChNum
+CMedium* m_pMedium
+CPtrArray m_tdRecArray
+CTdRecord* GetTdRecord(int iTSN)
}
class CIpspCETdRecord {
+int m_iTSN
+CStringArray m_saVRawData
}
CIpspCETd --> CTdChannel : "包含"
CTdChannel --> CIpspCETdRecord : "包含"
```
**图源**
- [IpspCETd.h](file://h/IpspCETd.h)
- [TdChannel.h](file://h/TdChannel.h)
- [IpspCETdRecord.h](file://h/IpspCETdRecord.h)
**节源**
- [IpspCETd.h](file://h/IpspCETd.h)
- [TdChannel.h](file://h/TdChannel.h)
## 可视化组件与剖面生成
`AppDataIpspCETdView`类负责IpspCETd数据的可视化展示。它使用`CSplitterWnd`将视图分割为三个面板:详细信息、数据内容列表和接地电阻列表。
```mermaid
graph TB
AppDataIpspCETdView["CAppDataIpspCETdView"] --> m_firstSplitter["m_firstSplitter (1x2)"]
m_firstSplitter --> m_pDetailListView["m_pDetailListView (详情)"]
m_firstSplitter --> m_secondSplitter["m_secondSplitter (2x1)"]
m_secondSplitter --> m_pContentListView["m_pContentListView (数据内容)"]
m_secondSplitter --> m_pGrListView["m_pGrListView (接地电阻)"]
```
**图源**
- [AppDataIpspCETdView.cpp](file://cpp/Views/AppDataIpspCETdView.cpp)
**节源**
- [AppDataIpspCETdView.cpp](file://cpp/Views/AppDataIpspCETdView.cpp)
激电剖面的生成逻辑如下:
1. **数据加载**`CIpspCETd::LoadData`方法从数据库加载所有通道和测点数据。
2. **数据组织**:数据按通道和测点编号有序存储在`m_tdChaList``m_tdRecArray`中。
3. **参数计算**:调用`GetFitEquationInfo`等方法计算半衰时、视极化率等参数。
4. **视图更新**`ShowConList`方法将计算结果填充到`CListCtrl`控件中,形成可交互的剖面图。
## 数据处理流程
完整的数据处理流程涵盖了从原始信号到最终解释参数的转换。
```mermaid
flowchart TD
RawData["原始电压信号"] --> Filter["信号滤波"]
Filter --> BackgroundSub["背景噪声扣除"]
BackgroundSub --> ParameterExtract["参数提取"]
ParameterExtract --> HalfLife["半衰时计算"]
ParameterExtract --> DecayCoeff["衰减系数计算"]
ParameterExtract --> ApparentCharge["视极化率计算"]
HalfLife --> QC["数据质量控制"]
DecayCoeff --> QC
ApparentCharge --> QC
QC --> Output["输出结果"]
```
**节源**
- [Ipsp2DTd.cpp](file://cpp/ProblemZone/Ipsp2DTd.cpp#L446-L509)
## 数据质量控制
数据质量控制策略主要体现在以下几个方面:
1. **异常值处理**:在`ShowDetailInfo``ShowGrList`方法中,对数据库中的空值(`VT_NULL`)和特殊值(如"-9999")进行检查和处理,避免无效数据显示。
2. **数据完整性验证**:在`ShowConList`等方法中,通过检查`GetRecordCount()`确保数据库查询结果有效,若无数据则返回错误。
3. **错误捕获**:使用`try-catch`块捕获数据库操作中的`_com_error`异常,确保程序的健壮性。
4. **数据对齐**:通过`TSN`(测点编号)确保不同通道的数据在时间和空间上正确对齐。
**节源**
- [Ipsp2DTd.cpp](file://cpp/ProblemZone/Ipsp2DTd.cpp#L372-L395)
- [IpspCETd.cpp](file://cpp/ProblemZone/IpspCETd.cpp#L604-L610)
@@ -0,0 +1,208 @@
# 电阻率反演数据模型
<cite>
**本文档引用的文件**
- [Rsp2DTd.cpp](file://cpp\ProblemZone\Rsp2DTd.cpp)
- [Rsp3DTd.cpp](file://cpp\Views\Rsp3DTd.cpp)
- [RspCETd.cpp](file://cpp\ProblemZone\RspCETd.cpp)
- [AppDataRsp3DTdView.cpp](file://cpp\Views\AppDataRsp3DTdView.cpp)
- [Rsp3DTdRecord.cpp](file://cpp\Views\Rsp3DTdRecord.cpp)
- [Medium3D.h](file://h\Medium3D.h)
- [MediumCrossHoleGeomative.h](file://h\MediumCrossHoleGeomative.h)
</cite>
## 目录
1. [引言](#引言)
2. [核心数据结构与输入输出](#核心数据结构与输入输出)
3. [反演算法流程与中间数据存储](#反演算法流程与中间数据存储)
4. [反演结果精度评估指标](#反演结果精度评估指标)
5. [反演剖面图生成流程](#反演剖面图生成流程)
6. [SP原始数据依赖关系](#sp原始数据依赖关系)
7. [不同地质模型适配策略](#不同地质模型适配策略)
8. [反演流程数据流图](#反演流程数据流图)
9. [典型配置参数及其影响](#典型配置参数及其影响)
## 引言
本文档旨在全面解析Geomative Studio软件中Rsp系列类(`Rsp2DTd``Rsp3DTd``RspCETd`)实现的电阻率反演数据模型。该模型是地球物理勘探中用于解释野外采集的电阻率数据的核心算法,通过将观测到的视电阻率数据与理论正演模型进行对比,迭代更新地下电性结构模型,最终获得与实际地质情况相符的电阻率分布剖面。文档将重点阐述反演算法的数据结构、迭代过程、精度评估、可视化生成以及与不同地质模型的适配机制。
## 核心数据结构与输入输出
### 输入数据结构
反演模型的输入数据主要来源于野外采集的原始测量数据,其核心结构由`CTestingData`基类及其派生类(如`CRsp2DTd``CRsp3DTd`)定义。输入数据主要包括:
- **测量任务元数据**:存储在`td`数据库表中,包含任务名称(`TDname`)、位置(`Tlocation`)、设备信息(`DESN`)、脚本信息(`SCCN``Sname`)、测量模式(`Tmode`)、电极数量(`Eamount`)、电极间距(`Edistance`)等。
- **测量配置参数**:包括电流频率(`TRfrequency`)、工业频率(`Ifrequency`)、采样率(`SAfrequency`)、装置类型(`Clayout`)、气象信息(`weather``temperature`)等。
- **原始测量记录**:存储在`td2dcon``td3dcon``td1dcon`等数据库表中,每条记录包含电极配置(`C1`, `C2`, `P1`, `P2`)、几何因子(`K`)、测量电流(`I`)、测量电压(`V`)、计算得到的视电阻率(`R0`)和视极化率(`SP`)等。
### 输出数据结构
反演过程的输出是经过迭代优化后的地下电阻率模型,其数据结构体现在:
- **反演结果数据**:最终的电阻率模型以网格化数据的形式存储,每个网格单元包含其位置坐标和反演得到的电阻率值。这些数据通常通过`SaveHeadInfoToFile`方法以XML格式导出,文件中包含`measure`根节点下的`medium_set``pole_count``pole_distance`等关键信息。
- **中间迭代数据**:在迭代过程中,每次迭代的模型参数和拟合误差会被临时存储在内存中,以便进行收敛性判断和结果回溯。
**Section sources**
- [Rsp2DTd.cpp](file://cpp\ProblemZone\Rsp2DTd.cpp#L56-L57)
- [Rsp3DTd.cpp](file://cpp\Views\Rsp3DTd.cpp#L43-L44)
- [RspCETd.cpp](file://cpp\ProblemZone\RspCETd.cpp#L34-L35)
## 反演算法流程与中间数据存储
### 迭代过程
电阻率反演是一个非线性优化问题,通常采用最小二乘法或其变种(如阻尼最小二乘法)进行求解。其核心迭代流程如下:
1. **初始化**:根据用户输入的初始模型(通常为均匀半空间或简单分层模型)和测量数据,构建初始的地下电性结构模型。
2. **正演计算**:基于当前的模型,计算所有测量点的理论视电阻率值。
3. **误差计算**:将理论计算值与实际观测值进行对比,计算残差(Residual)和目标函数(如均方根误差RMSE)。
4. **模型更新**:根据残差和雅可比矩阵(Jacobian Matrix,描述模型参数变化对观测值的影响),计算模型参数的更新量,并更新地下模型。
5. **收敛判断**:检查目标函数是否小于预设阈值,或迭代次数是否达到上限。若未收敛,则返回步骤2继续迭代。
### 中间数据存储机制
在迭代过程中,关键的中间数据通过以下方式存储:
- **内存链表**`CTestingData`类使用`CLinkList<CTdChannel*> m_tdChaList`来管理所有通道(Channel)的数据。每个`CTdChannel`对象又通过`CPtrArray m_tdRecArray`来存储该通道下所有测量点(`CRsp3DTdRecord`等)的详细记录。
- **数据库持久化**:原始测量数据和部分中间结果(如每次迭代的模型快照)会持久化存储在Access数据库中,相关的表包括`td`(任务头信息)、`tdchannel`(通道信息)、`td3dcon`3D测量记录)等。
- **XML文件缓存**`SaveHeadInfoToFile`方法将当前的测量配置和模型信息序列化为XML文件,用于临时缓存和后续处理。
```mermaid
flowchart TD
A[初始化模型] --> B[正演计算]
B --> C[计算理论视电阻率]
C --> D[与观测值对比]
D --> E[计算残差和目标函数]
E --> F{是否收敛?}
F --> |否| G[计算模型更新量]
G --> H[更新地下模型]
H --> B
F --> |是| I[输出最终模型]
```
**Diagram sources **
- [Rsp3DTd.cpp](file://cpp\Views\Rsp3DTd.cpp#L43-L51)
- [Rsp3DTdRecord.cpp](file://cpp\Views\Rsp3DTdRecord.cpp#L18-L38)
## 反演结果精度评估指标
反演结果的精度主要通过以下指标进行评估:
- **均方根误差 (RMSE)**:这是最核心的评估指标,衡量反演模型预测值与实际观测值之间的平均差异。RMSE值越小,说明模型拟合度越高。其计算公式为:`RMSE = sqrt(Σ(observed_i - predicted_i)² / N)`,其中N为数据点总数。
- **拟合优度 (Goodness of Fit, GOF)**:通常以百分比形式表示,反映观测数据被模型解释的程度。GOF越高,模型越好。
- **模型光滑度 (Model Smoothness)**:在反演目标函数中通常会加入一个正则化项,用于控制模型的复杂度,防止出现过度拟合的“斑点”模型。一个合理的模型应在拟合度和光滑度之间取得平衡。
- **残差分布图**:通过绘制残差的空间分布图,可以直观地判断模型在哪些区域拟合不佳,从而指导模型的进一步调整。
**Section sources**
- [Rsp2DTd.cpp](file://cpp\ProblemZone\Rsp2DTd.cpp#L576-L798)
- [Rsp3DTd.cpp](file://cpp\Views\Rsp3DTd.cpp#L586-L798)
## 反演剖面图生成流程
反演剖面图的生成流程主要由`AppDataRsp3DTdView`类负责,其逻辑如下:
### 渲染逻辑
1. **视图创建**`AppDataRsp3DTdView::Create`方法在创建时,会初始化一个分割窗口(Splitter Window),将主视图划分为三个子视图。
2. **子视图布局**
- **左侧视图**:创建`CAppDataTdDetailListView`,用于显示任务的详细信息列表。
- **右侧上半部分**:创建`CAppDataRsp3DTdConListView`,用于显示测量数据的内容列表(即`ShowConList`方法填充的数据)。
- **右侧下半部分**:创建`CAppDataTdGrListView`,用于显示电极状态和质量控制(GR)信息列表。
3. **数据绑定与更新**:每个子视图在`OnInitialUpdate`时,会从其关联的文档(Document)中获取数据,并调用相应的`ShowDetailInfo``ShowConList``ShowGrList`方法来填充列表控件(`CListCtrl`)。
4. **动态调整**:当窗口大小改变时,`OnSize`方法会重新计算分割窗口的布局,确保各子视图按比例正确显示。
```mermaid
graph TB
subgraph "AppDataRsp3DTdView"
A[主视图] --> B[分割窗口1]
B --> C[左侧: 详情列表]
B --> D[右侧: 分割窗口2]
D --> E[上半: 数据内容列表]
D --> F[下半: GR信息列表]
end
C --> G[ShowDetailInfo]
E --> H[ShowConList]
F --> I[ShowGrList]
```
**Diagram sources **
- [AppDataRsp3DTdView.cpp](file://cpp\Views\AppDataRsp3DTdView.cpp#L69-L97)
## SP原始数据依赖关系
电阻率反演模型与SP(激发极化)原始数据存在紧密的依赖关系:
- **数据来源**:SP原始数据是反演算法的直接输入。`CRspCETd``CRsp2DTd`等类通过`LoadData`方法从数据库(如`td1dcon``td2dcon`表)中加载包含视极化率(`SP`)字段的测量记录。
- **数据处理**:在`ShowConList`方法中,代码会从数据库读取`SP`字段的值,并将其格式化后显示在用户界面的列表控件中。这表明SP数据是整个数据处理流程中的一个关键环节。
- **联合反演**:虽然当前代码主要展示了电阻率反演,但SP数据的存在暗示了系统可能支持电阻率与激发极化数据的联合反演,以获得更全面的地下物性信息。
**Section sources**
- [RspCETd.cpp](file://cpp\ProblemZone\RspCETd.cpp#L501-L575)
- [Rsp2DTd.cpp](file://cpp\ProblemZone\Rsp2DTd.cpp#L297-L377)
## 不同地质模型适配策略
系统通过`Medium`类的继承体系来适配不同的地质模型,核心策略是**多态性**和**接口抽象**。
### 适配机制
- **基类定义接口**`CMedium`基类(或其子类如`CMedium3D`)定义了一系列纯虚函数(如`GenerateSptRecElecVal``CalculateSptPtLoc``GenSptRecLevel`),这些函数构成了一个抽象接口,规定了所有地质模型必须实现的行为。
- **具体模型实现**`Medium3D.cpp``MediumCrossHoleGeomative.cpp`等文件实现了具体的地质模型。例如,`CMedium3D`类会实现3D网格化模型的生成算法,而`CMediumCrossHoleGeomative`类则会实现跨孔(Cross-Hole)探测的特定几何计算。
- **运行时绑定**:在`CRsp2DTd::Save2DRSPSetInfo`等方法中,通过`m_handleProcessor.GenerateHandle`生成特定模型的句柄,并从`m_medLinkList`链表中查找对应的`CMedium`对象。由于`m_pMedium`是指向基类的指针,在调用`CalculateDepth`等方法时,会根据实际对象的类型自动调用其对应的实现,从而实现了对不同地质模型的无缝适配。
```mermaid
classDiagram
class CMedium {
<<abstract>>
+virtual void CalculateDepth(float fA, float fFactor)
+virtual void CalculateTdPtLoc(...)
+virtual void Destroy()
}
class CMedium3D {
+void SetPoleDistance(DOUBLE f_dis_x, DOUBLE f_dis_y)
+void SetPoleStep(int f_step_x, int f_step_y)
+void SetFlags(BOOL Flags)
+void create()
+void SetRect(int x0, int y0, int x1, int y1)
+BOOL setPoleStart(int startpole)
+BOOL generate()
}
class CMediumCrossHoleGeomative {
+void SetHoleDepth(float depth)
+void SetHoleSpacing(float spacing)
+void CalculateCrossHoleGeometry()
}
CMedium <|-- CMedium3D : "继承"
CMedium <|-- CMediumCrossHoleGeomative : "继承"
```
**Diagram sources **
- [Medium3D.h](file://h\Medium3D.h#L30-L77)
- [Rsp2DTd.cpp](file://cpp\ProblemZone\Rsp2DTd.cpp#L577-L582)
## 反演流程数据流图
以下数据流图概括了从数据输入到结果输出的完整反演流程。
```mermaid
flowchart LR
A[SP原始数据] --> B[数据库存储]
B --> C[加载数据 LoadData]
C --> D[初始化模型]
D --> E[正演计算 Forward Modeling]
E --> F[误差计算 Error Calculation]
F --> G{收敛?}
G --> |否| H[模型更新 Model Update]
H --> E
G --> |是| I[生成剖面图 Render View]
I --> J[用户界面显示]
K[配置参数] --> C
K --> D
```
**Diagram sources **
- [RspCETd.cpp](file://cpp\ProblemZone\RspCETd.cpp#L142-L195)
- [AppDataRsp3DTdView.cpp](file://cpp\Views\AppDataRsp3DTdView.cpp#L69-L97)
## 典型配置参数及其影响
| 配置参数 | 参数说明 | 对反演结果的影响 |
| :--- | :--- | :--- |
| `Eamount` | 电极总数 | 电极数越多,横向和纵向分辨率越高,但测量时间也越长。 |
| `Edistance` | 电极间距 | 间距越大,探测深度越深,但横向分辨率降低。 |
| `Clayout` | 装置类型 | 不同的装置(如温纳、施伦贝谢、偶极-偶极)具有不同的探测深度和灵敏度分布,直接影响反演结果的形态。 |
| `TRfrequency` | 发射频率 | 影响激发极化效应的测量,对SP数据反演至关重要。 |
| `Ifrequency` | 工业频率 | 用于选择滤波器,抑制50Hz或60Hz的工频干扰。 |
| `SAfrequency` | 采样率 | 采样率越高,数据质量越好,但数据量也越大。 |
**Section sources**
- [Rsp2DTd.cpp](file://cpp\ProblemZone\Rsp2DTd.cpp#L467-L565)
- [RspCETd.cpp](file://cpp\ProblemZone\RspCETd.cpp#L242-L337)
@@ -0,0 +1,346 @@
# 视电阻率数据模型
<cite>
**本文档引用文件**
- [SP2DTd.cpp](file://cpp\ProblemZone\SP2DTd.cpp)
- [SP2DTd.h](file://h\SP2DTd.h)
- [SP2DTdRecord.cpp](file://cpp\ProblemZone\SP2DTdRecord.cpp)
- [SP3DTd.cpp](file://cpp\ProblemZone\SP3DTd.cpp)
- [SP3DTd.h](file://h\SP3DTd.h)
- [SP3DTdRecord.cpp](file://cpp\ProblemZone\SP3DTdRecord.cpp)
- [SPCETd.cpp](file://cpp\ProblemZone\SPCETd.cpp)
- [SPCETd.h](file://h\SPCETd.h)
- [SPCETdRecord.cpp](file://cpp\ProblemZone\SPCETdRecord.cpp)
- [AppDataSP2DTdView.cpp](file://cpp\Views\AppDataSP2DTdView.cpp)
- [TestingData.h](file://h\TestingData.h)
- [TdRecord.cpp](file://cpp\ProblemZone\TdRecord.cpp)
- [TdRecord.h](file://h\TdRecord.h)
</cite>
## 目录
1. [引言](#引言)
2. [SP系列数据模型概述](#sp系列数据模型概述)
3. [二维视电阻率数据模型 (SP2DTd)](#二维视电阻率数据模型-sp2dtd)
4. [三维视电阻率数据模型 (SP3DTd)](#三维视电阻率数据模型-sp3dtd)
5. [跨孔视电阻率数据模型 (SPCETd)](#跨孔视电阻率数据模型-spcetd)
6. [视电阻率计算原理](#视电阻率计算原理)
7. [数据可视化流程](#数据可视化流程)
8. [数据采集与处理时序流程](#数据采集与处理时序流程)
9. [字段定义与单位说明](#字段定义与单位说明)
10. [典型应用场景](#典型应用场景)
11. [异常数据识别方法](#异常数据识别方法)
12. [核心计算逻辑代码片段](#核心计算逻辑代码片段)
## 引言
本文档旨在深入解析GeomativeStudio软件中SP系列类(SP2DTd、SP3DTd、SPCETd)所代表的视电阻率数据模型。这些模型是地球物理勘探中电阻率成像技术的核心,用于处理和分析从野外采集的原始电压和电流数据,进而计算出地下介质的视电阻率值。文档将详细阐述这些模型在二维、三维及跨孔测量中的数据结构设计、物理意义、计算方法以及可视化逻辑,并提供完整的数据处理流程。
## SP系列数据模型概述
SP系列数据模型是GeomativeStudio软件中用于处理视电阻率(Self-Potential, SP)数据的核心类体系。该系列包含三个主要类:`CSP2DTd``CSP3DTd``CSPCETd`,分别对应二维、三维和跨孔(一维)测量模式。这些类均继承自`CTestingData`基类,共享通用的数据结构和处理逻辑,同时根据各自的测量几何和物理特性,定义了特定的数据字段和方法。
**Section sources**
- [SP2DTd.h](file://h\SP2DTd.h#L17-L59)
- [SP3DTd.h](file://h\SP3DTd.h#L17-L53)
- [SPCETd.h](file://h\SPCETd.h#L18-L53)
- [TestingData.h](file://h\TestingData.h)
## 二维视电阻率数据模型 (SP2DTd)
`CSP2DTd`类是二维视电阻率数据模型的具体实现,专为沿一条测线进行的二维电阻率测量设计。其数据结构主要包含测点信息、电极配置和测量结果。
### 数据结构设计
该模型的核心数据存储在`td2dcon`数据库表中,主要字段包括:
- **C1, C2**: 供电电极编号。
- **P1, P2**: 测量电极编号。
- **N**: 叠加次数。
- **K**: 装置系数,由电极间距决定。
- **I**: 测量得到的电流值(单位:mA)。
- **V**: 测量得到的电压值(单位:mV)。
- **R0**: 接地电阻(单位:Ω)。
- **SP**: 计算得到的视电阻率值(单位:Ω·m)。
### 物理意义
二维模型假设地下电性结构在垂直于测线的方向上是无限延伸且不变的。通过沿测线移动电极阵列,可以获取一系列测点的视电阻率数据,这些数据经过反演处理后,可以生成反映地下电性分布的二维剖面图。
```mermaid
classDiagram
class CSP2DTd {
+DWORD m_dwID
+CString m_szTdName
+int m_iEAmount
+int m_iCHAmount
+float m_fESpace
+CString m_szEDistance
+CTypedPtrList< CObList, CTdChannel* > m_tdChaList
+BOOL SaveData()
+BOOL LoadData(CLinkList<CMedium*>&)
+BOOL ShowConList(CListCtrl&)
+BOOL SaveHeadInfoToFile(CString&, CString&)
}
class CTdChannel {
+DWORD m_dwID
+int m_iChNum
+int m_iEAmount
+CMedium* m_pMedium
}
class CSP2DTdRecord {
+int m_iTsn
+int m_iC1
+int m_iC2
+int m_iP1
+int m_iP2
+int m_iN
+float m_fK
+float m_fI
+float m_fV
+float m_fR0
+float m_fSP
+BOOL SaveData(DWORD)
+BOOL LoadOrgData()
}
CSP2DTd --> CTdChannel : "包含"
CTdChannel --> CSP2DTdRecord : "包含"
```
**Diagram sources **
- [SP2DTd.h](file://h\SP2DTd.h#L17-L59)
- [SP2DTdRecord.h](file://h\SP2DTdRecord.h#L12-L35)
- [SP2DTd.cpp](file://cpp\ProblemZone\SP2DTd.cpp#L40-L86)
- [SP2DTdRecord.cpp](file://cpp\ProblemZone\SP2DTdRecord.cpp#L18-L38)
**Section sources**
- [SP2DTd.cpp](file://cpp\ProblemZone\SP2DTd.cpp#L279-L341)
- [SP2DTdRecord.cpp](file://cpp\ProblemZone\SP2DTdRecord.cpp#L53-L80)
## 三维视电阻率数据模型 (SP3DTd)
`CSP3DTd`类用于处理三维视电阻率数据,适用于在二维测网内进行的测量。其数据结构与二维模型类似,但需要记录更复杂的电极空间位置。
### 数据结构设计
三维模型的核心数据存储在`td3dcon`数据库表中,其字段与`td2dcon`表基本相同(C1, C2, P1, P2, I, V, R0, SP等)。关键区别在于,三维测量的电极位置信息通常在脚本(Script)或装置(Medium)定义中管理,而`CSP3DTd`类通过`m_tdChaList`列表管理多个通道的数据,以支持更复杂的测量阵列。
### 物理意义
三维模型旨在获取地下电性结构的立体分布。通过在多个测线上进行测量,可以构建一个三维数据体。该模型能够更真实地反映地下异常体的形态和空间展布,但数据采集和处理的复杂度也显著增加。
```mermaid
classDiagram
class CSP3DTd {
+DWORD m_dwID
+CString m_szTdName
+int m_iEAmount
+int m_iCHAmount
+float m_fESpace
+CString m_szEDistance
+CTypedPtrList< CObList, CTdChannel* > m_tdChaList
+BOOL SaveData()
+BOOL LoadData(CLinkList<CMedium*>&)
+BOOL ShowConList(CListCtrl&)
+BOOL SaveHeadInfoToFile(CString&, CString&)
}
class CTdChannel {
+DWORD m_dwID
+int m_iChNum
+int m_iEAmount
+CMedium* m_pMedium
}
class CSP3DTdRecord {
+int m_iTsn
+int m_iC1
+int m_iC2
+int m_iP1
+int m_iP2
+int m_iN
+float m_fK
+float m_fI
+float m_fV
+float m_fR0
+float m_fSP
+BOOL SaveData(DWORD)
+BOOL LoadOrgData()
}
CSP3DTd --> CTdChannel : "包含"
CTdChannel --> CSP3DTdRecord : "包含"
```
**Diagram sources **
- [SP3DTd.h](file://h\SP3DTd.h#L17-L53)
- [SP3DTdRecord.h](file://h\SP3DTdRecord.h#L12-L35)
- [SP3DTd.cpp](file://cpp\ProblemZone\SP3DTd.cpp#L34-L80)
- [SP3DTdRecord.cpp](file://cpp\ProblemZone\SP3DTdRecord.cpp#L18-L38)
**Section sources**
- [SP3DTd.cpp](file://cpp\ProblemZone\SP3DTd.cpp#L272-L334)
- [SP3DTdRecord.cpp](file://cpp\ProblemZone\SP3DTdRecord.cpp#L53-L80)
## 跨孔视电阻率数据模型 (SPCETd)
`CSPCETd`类用于处理跨孔(或称一维)视电阻率数据,常用于垂直电测深(VES)或井间测量。
### 数据结构设计
该模型的核心数据存储在`td1dcon`数据库表中,其字段与二维/三维模型有显著不同:
- **a, b**: 供电电极间距(单位:m)。
- **x, y**: 测量电极间距(单位:m)。
- **N**: 叠加次数。
- **K**: 装置系数,由a、b、x、y计算得出。
- **I, V, R0, SP**: 与二维/三维模型相同。
### 物理意义
跨孔模型主要用于研究地下介质随深度的变化。通过固定测量电极并逐步增大供电电极间距,可以探测到不同深度的地下电性。该模型生成的数据通常用于绘制视电阻率曲线(如S-曲线、Q-曲线),以推断地层的分层结构。
```mermaid
classDiagram
class CSPCETd {
+DWORD m_dwID
+CString m_szTdName
+int m_iEAmount
+int m_iCHAmount
+float m_fESpace
+CString m_szEDistance
+CTypedPtrList< CObList, CTdChannel* > m_tdChaList
+BOOL SaveData()
+BOOL LoadData(CLinkList<CMedium*>&)
+BOOL ShowConList(CListCtrl&)
+BOOL SaveHeadInfoToFile(CString&, CString&)
}
class CTdChannel {
+DWORD m_dwID
+int m_iChNum
+int m_iEAmount
+CMedium* m_pMedium
}
class CSPCETdRecord {
+int m_iTsn
+float m_fA
+float m_fB
+float m_fX
+float m_fY
+int m_iN
+float m_fK
+float m_fI
+float m_fV
+float m_fR0
+float m_fSP
+BOOL SaveData(DWORD)
+BOOL LoadOrgData()
}
CSPCETd --> CTdChannel : "包含"
CTdChannel --> CSPCETdRecord : "包含"
```
**Diagram sources **
- [SPCETd.h](file://h\SPCETd.h#L18-L53)
- [SPCETdRecord.h](file://h\SPCETdRecord.h#L14-L37)
- [SPCETd.cpp](file://cpp\ProblemZone\SPCETd.cpp#L32-L80)
- [SPCETdRecord.cpp](file://cpp\ProblemZone\SPCETdRecord.cpp#L18-L38)
**Section sources**
- [SPCETd.cpp](file://cpp\ProblemZone\SPCETd.cpp#L498-L562)
- [SPCETdRecord.cpp](file://cpp\ProblemZone\SPCETdRecord.cpp#L44-L77)
## 视电阻率计算原理
视电阻率(Apparent Resistivity, ρa)的计算基于欧姆定律和特定的电极装置系数(K)。其基本公式为:
ρa = K * (V / I)
其中:
- **ρa**: 视电阻率,单位为欧姆·米(Ω·m)。
- **K**: 装置系数,单位为米(m),由所采用的电极排列方式(如温纳装置、施伦贝谢装置等)和电极间距决定。
- **V**: 测量得到的电压值,单位为伏特(V)。
- **I**: 测量得到的电流值,单位为安培(A)。
在代码实现中,`CSP2DTdRecord``CSP3DTdRecord``CSPCETdRecord`类的`SaveData`方法负责将计算出的`m_fSP`(即ρa)值保存到相应的数据库表(`td2dcon``td3dcon``td1dcon`)中。
**Section sources**
- [SP2DTdRecord.cpp](file://cpp\ProblemZone\SP2DTdRecord.cpp#L68-L80)
- [SP3DTdRecord.cpp](file://cpp\ProblemZone\SP3DTdRecord.cpp#L68-L80)
- [SPCETdRecord.cpp](file://cpp\ProblemZone\SPCETdRecord.cpp#L61-L77)
## 数据可视化流程
`AppDataSP2DTdView.cpp`文件定义了二维视电阻率数据的可视化界面。其核心是创建一个分栏视图,将数据详情、测量内容和接地电阻列表组织在一起。
### 可视化逻辑
1. **视图创建 (`Create`)**: 该方法使用`CSplitterWnd`创建一个静态分栏器,将主视图分为左右两部分。
2. **左侧面板**: 左侧创建一个`CAppDataTdDetailListView`视图,用于显示测试任务的详细信息(如任务名称、位置、设备型号等)。
3. **右侧面板**: 右侧再创建一个上下分栏的`CSplitterWnd`
- **上方面板**: 创建一个`CAppDataSP2DTdConListView`视图,用于显示所有测点的测量数据(即`td2dcon`表中的内容)。
- **下方面板**: 创建一个`CAppDataTdGrListView`视图,用于显示各电极的接地电阻测量结果。
4. **数据映射**: `CAppDataSP2DTdConListView`视图通过调用`CSP2DTd::ShowConList`方法,从数据库中查询数据并填充到列表控件中,实现了数据到曲线图的映射。
```mermaid
flowchart TD
A[AppDataSP2DTdView::Create] --> B[创建左右分栏]
B --> C[左侧面板: CAppDataTdDetailListView]
B --> D[右侧面板: 上下分栏]
D --> E[上方面板: CAppDataSP2DTdConListView]
D --> F[下方面板: CAppDataTdGrListView]
E --> G[调用 CSP2DTd::ShowConList]
G --> H[查询 td2dcon 表]
H --> I[填充列表控件]
F --> J[显示接地电阻]
```
**Diagram sources **
- [AppDataSP2DTdView.cpp](file://cpp\Views\AppDataSP2DTdView.cpp#L71-L103)
**Section sources**
- [AppDataSP2DTdView.cpp](file://cpp\Views\AppDataSP2DTdView.cpp#L71-L103)
- [SP2DTd.cpp](file://cpp\ProblemZone\SP2DTd.cpp#L279-L341)
## 数据采集与处理时序流程
从设备接收原始数据包到最终存储为视电阻率数据,整个流程遵循严格的时序。
### 处理路径
1. **数据包接收**: 设备通过串口或网络将原始数据包发送给软件。
2. **数据解析**: 软件解析数据包,提取出原始的电压(Vrawdata)和电流(Irawdata)序列。这些数据被存储在`td2dcon``td3dcon``td1dcon`表的相应字段中。
3. **数据加载**: `CTdRecord`类的`LoadOrgData`方法(如`Load2DOrgData`)被调用,从数据库中读取原始数据序列。
4. **数据处理**: 原始数据经过滤波、去噪等预处理,并计算出最终的电压值V和电流值I。
5. **视电阻率计算**: 根据公式 ρa = K * (V / I) 计算视电阻率值SP。
6. **数据存储**: 计算结果(I, V, R0, SP)通过`CSPxDTdRecord::SaveData`方法写回数据库。
```mermaid
sequenceDiagram
participant 设备 as "测量设备"
participant 软件 as "GeomativeStudio软件"
participant 数据库 as "数据库"
设备->>软件 : 发送原始数据包(Vrawdata, Irawdata)
软件->>数据库 : 解析并存储原始数据
软件->>数据库 : 查询原始数据(LoadOrgData)
软件->>软件 : 预处理并计算V, I
软件->>软件 : 计算视电阻率SP = K * (V/I)
软件->>数据库 : 存储最终结果(SaveData)
```
**Diagram sources **
- [TdRecord.cpp](file://cpp\ProblemZone\TdRecord.cpp#L34-L320)
- [SP2DTdRecord.cpp](file://cpp\ProblemZone\SP2DTdRecord.cpp#L53-L80)
## 字段定义与单位说明
| 字段名 | 中文名称 | 数据类型 | 单位 | 说明 |
| :--- | :--- | :--- | :--- | :--- |
| `C1`, `C2` | 供电电极 | int | 无 | 电极编号 |
| `P1`, `P2` | 测量电极 | int | 无 | 电极编号 |
| `a`, `b` | 供电电极间距 | float | 米 (m) | 仅SPCETd模型 |
| `x`, `y` | 测量电极间距 | float | 米 (m) | 仅SPCETd模型 |
| `I` | 电流 | float | 毫安 (mA) | 测量得到的电流值 |
| `V` | 电压 | float | 毫伏 (mV) | 测量得到的电压值 |
| `R0` | 接地电阻 | float | 欧姆 (Ω) | 电极接地电阻 |
| `SP` | 视电阻率 | float | 欧姆·米 (Ω·m) | 计算得到的视电阻率值 |
| `K` | 装置系数 | float | 米 (m) | 由电极排列方式决定 |
| `N` | 叠加次数 | int | 无 | 信号叠加次数 |
| `Espace` | 电极步长 | float | 米 (m) | 移动电极的步长 |
| `Edistance` | 电极距离 | float | 米 (m) | 电极间的距离 |
## 典型应用场景
- **SP2DTd**: 用于二维地质剖面调查,如滑坡体探测、地下水污染羽流成像、岩溶发育区调查等。
- **SP3DTd**: 用于三维地质体精细成像,如矿体圈定、地下空洞三维定位、复杂地质构造研究等。
- **SPCETd**: 用于地层垂向分层研究,如工程地质勘察中的土层划分、地下水含水层深度探测、基岩面起伏调查等。
## 异常数据识别方法
1. **接地电阻异常**: 通过`gr`表检查各电极的接地电阻`OMvalue`。若电阻值过高(如大于10kΩ)或为-9999(表示未测量),则表明电极接触不良。
2. **电压/电流值异常**: 检查`V``I`值是否为零或接近零。若`I`为零,则供电回路可能断开;若`V`为零而`I`正常,则测量回路可能断开。
3. **视电阻率值异常**: 检查`SP`值是否为负数或极大值。负值通常由电极极性接反或强电磁干扰引起;极大值可能由数据采集错误或极端地质条件导致。
4. **数据完整性检查**: 确保每个测点(TSN)都有对应的`C1, C2, P1, P2`配置和有效的`V, I`读数。
## 核心计算逻辑代码片段
视电阻率的计算和存储逻辑主要在`CSPxDTdRecord`类的`SaveData`方法中实现。该方法将计算结果插入到相应的数据库表中。
**Section sources**
- [SP2DTdRecord.cpp](file://cpp\ProblemZone\SP2DTdRecord.cpp#L53-L80)
- [SP3DTdRecord.cpp](file://cpp\ProblemZone\SP3DTdRecord.cpp#L53-L80)
- [SPCETdRecord.cpp](file://cpp\ProblemZone\SPCETdRecord.cpp#L44-L77)