a
This commit is contained in:
@@ -0,0 +1,271 @@
|
||||
# 数据采集与存储
|
||||
|
||||
<cite>
|
||||
**本文档引用的文件**
|
||||
- [TdManager.cpp](file://cpp/Managers/TdManager.cpp)
|
||||
- [TdManager.h](file://h/TdManager.h)
|
||||
- [TestingData.h](file://h/TestingData.h)
|
||||
- [TestingData.cpp](file://cpp/ProblemZone/TestingData.cpp)
|
||||
- [DevManager.cpp](file://cpp/Managers/DevManager.cpp)
|
||||
- [DevManager.h](file://h/DevManager.h)
|
||||
- [Device.cpp](file://cpp/ProblemZone/Device.cpp)
|
||||
- [TdRecord.cpp](file://cpp/ProblemZone/TdRecord.cpp)
|
||||
</cite>
|
||||
|
||||
## 目录
|
||||
1. [引言](#引言)
|
||||
2. [数据采集机制](#数据采集机制)
|
||||
3. [数据存储结构](#数据存储结构)
|
||||
4. [时间戳同步与采样控制](#时间戳同步与采样控制)
|
||||
5. [异常数据过滤与完整性校验](#异常数据过滤与完整性校验)
|
||||
6. [缓存机制与内存管理](#缓存机制与内存管理)
|
||||
7. [断点续传与数据库交互](#断点续传与数据库交互)
|
||||
8. [结论](#结论)
|
||||
|
||||
## 引言
|
||||
本文档深入分析Geomative Studio软件中测试数据采集与存储机制的实现细节。系统通过CTdManager类协调设备管理器,实现对地质勘探设备的实时数据采集,包括电阻率、电流、电压、自电位等关键物理量。文档详细阐述了数据存储结构的设计原理、时间同步机制、异常数据处理策略以及与数据库的交互方式,为系统维护和功能扩展提供技术参考。
|
||||
|
||||
## 数据采集机制
|
||||
|
||||
CTdManager类作为数据采集的核心控制器,通过设备管理器获取实时测量数据。该类继承自CObject,负责管理测试数据的生命周期和采集流程。系统通过CTdManager的Upload2DTdFromDev等方法从设备上载2D数据,这些方法接收工程编号、测区编号、测试数据编号和设备指针作为参数,实现数据的远程采集。
|
||||
|
||||
数据采集过程中,CTdManager通过CDevice类与物理设备进行通信。CDevice类封装了设备的所有属性和操作方法,包括设备序列号(m_szDevSN)、设备名称(m_szDevName)、硬件版本(m_szHWV)和软件版本(m_szSWV)等。设备状态通过m_uState成员变量维护,支持离线(PZ_STATE_OFFLINE)、在线(PZ_STATE_ONLINE)等多种状态。
|
||||
|
||||
采集的数据类型由EN_DATA_TYPE枚举定义,包括电阻率测试(EN_RES_TEST_TYPE)、激电测试(EN_IP_TEST_TYPE)和自电位测试(EN_SP_TEST_TYPE)三种。系统通过不同的数据通道(tdchannel)管理不同类型的数据采集任务,确保数据的分类存储和高效处理。
|
||||
|
||||
**Section sources**
|
||||
- [TdManager.cpp](file://cpp/Managers/TdManager.cpp#L57-L6839)
|
||||
- [TdManager.h](file://h/TdManager.h#L16-L21)
|
||||
- [Device.cpp](file://cpp/ProblemZone/Device.cpp#L43-L83)
|
||||
|
||||
## 数据存储结构
|
||||
|
||||
### TestingData类设计
|
||||
TestingData类是数据存储的核心数据结构,采用面向对象的设计模式,封装了测试数据的所有属性和操作方法。该类通过成员变量定义了丰富的数据字段,涵盖了测试任务的各个方面。
|
||||
|
||||
**核心字段定义:**
|
||||
- **标识信息**:m_dwID(数据ID)、m_szTdName(测试名称)、m_szTLocation(测试位置)
|
||||
- **配置参数**:m_iSType(装置类型)、m_iTType(测试类型)、m_iTMode(测试模式)
|
||||
- **电极参数**:m_iEAmount(电极数量)、m_fESpace(电极步长)、m_szEDistance(电极间距)
|
||||
- **环境参数**:m_iWeather(天气)、m_fTemperature(温度)、m_fHumidity(湿度)
|
||||
- **时间信息**:m_szCDate(创建日期)、m_szCTime(创建时间)、m_szTDate(测试日期)、m_szTTime(测试时间)
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CTestingData {
|
||||
+DWORD m_dwID
|
||||
+CString m_szTdName
|
||||
+CString m_szTLocation
|
||||
+int m_iSType
|
||||
+int m_iTType
|
||||
+int m_iEAmount
|
||||
+float m_fESpace
|
||||
+CString m_szEDistance
|
||||
+int m_iWeather
|
||||
+float m_fTemperature
|
||||
+float m_fHumidity
|
||||
+CString m_szCDate
|
||||
+CString m_szCTime
|
||||
+_WaveCount *m_waveCount
|
||||
+bool CalculateTWInfo(CStringArray*, int)
|
||||
+bool CalculateTimeWindows(struct _WinTimeList, CStringArray*, int, int, int, int, int)
|
||||
+double adc_calculate(double, double, double)
|
||||
+double adc_average(int*, int)
|
||||
+double adc_integral(int*, int)
|
||||
}
|
||||
class _WaveCount {
|
||||
+int WaveLength
|
||||
+_WinTimeList windowList[2]
|
||||
}
|
||||
class _WinTimeList {
|
||||
+int ListLength
|
||||
+double wintime_Vp
|
||||
+_WinTime timeWinList[10]
|
||||
}
|
||||
class _WinTime {
|
||||
+int wintime_StartTime
|
||||
+int wintime_width
|
||||
+double wintime_V2
|
||||
+double wintime_Integral
|
||||
+double wintime_ETA
|
||||
+double wintime_M
|
||||
}
|
||||
CTestingData --> _WaveCount : "包含"
|
||||
_WaveCount --> _WinTimeList : "包含"
|
||||
_WinTimeList --> _WinTime : "包含"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [TestingData.h](file://h/TestingData.h#L12-L31)
|
||||
- [TestingData.cpp](file://cpp/ProblemZone/TestingData.cpp#L251-L273)
|
||||
|
||||
### 数据库表结构
|
||||
系统采用关系型数据库存储测试数据,主要表结构包括:
|
||||
- **td表**:存储测试任务基本信息,包含ID、TDname、Tlocation、DESN、SCCN等字段
|
||||
- **tdchannel表**:存储数据通道信息,与td表通过TDID关联
|
||||
- **td2dcon表**:存储2D测试数据,包含TSN、C1、C2、P1、P2、K、I、V、R0、SP等测量值
|
||||
- **td1dcon表**:存储1D测试数据,结构与td2dcon类似
|
||||
- **gr表**:存储接地电阻数据,包含TDID、Ecode、Mdate、Mtime、OMvalue等字段
|
||||
|
||||
数据存储采用分页机制,通过ONE_PAGE_DATA_NUMBER常量定义每页数据量为100条,提高大数据量下的查询效率。
|
||||
|
||||
**Section sources**
|
||||
- [TestingData.h](file://h/TestingData.h#L176-L224)
|
||||
- [TestingData.cpp](file://cpp/ProblemZone/TestingData.cpp#L29-L77)
|
||||
- [TdManager.cpp](file://cpp/Managers/TdManager.cpp#L121-L144)
|
||||
|
||||
## 时间戳同步与采样控制
|
||||
|
||||
### 时间戳同步机制
|
||||
系统通过m_szCDate和m_szCTime字段记录数据创建的时间戳,确保数据的时间一致性。时间戳采用"YYYY-MM-DD"和"HH:MM:SS"格式存储,便于数据库查询和数据分析。在数据采集过程中,系统通过Tm2LocalStr等函数将时间戳转换为本地时间格式,保证跨时区操作的一致性。
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant 设备 as 地质勘探设备
|
||||
participant CTdManager as CTdManager
|
||||
participant 数据库 as 数据库
|
||||
设备->>CTdManager : 发送测量数据包
|
||||
CTdManager->>CTdManager : 解析数据包,提取时间戳
|
||||
CTdManager->>CTdManager : 调用Tm2LocalStr转换为本地时间
|
||||
CTdManager->>数据库 : 插入数据记录,包含时间戳
|
||||
数据库-->>CTdManager : 返回插入结果
|
||||
CTdManager-->>设备 : 确认数据接收
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [TdManager.cpp](file://cpp/Managers/TdManager.cpp#L50-L51)
|
||||
- [TestingData.cpp](file://cpp/ProblemZone/TestingData.cpp#L214-L217)
|
||||
|
||||
### 采样频率控制
|
||||
采样频率由m_iIFrequency和m_iSAFrequency字段控制,分别表示工业频率和采样频率。系统通过GetSample方法根据工业频率和采样类型计算实际采样率:
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
Start([开始]) --> CheckIndustrialFreq["检查工业频率"]
|
||||
CheckIndustrialFreq --> |50Hz| SetSampleRate50["设置采样率: 30/60/120"]
|
||||
CheckIndustrialFreq --> |60Hz| SetSampleRate60["设置采样率: 36/72/144"]
|
||||
SetSampleRate50 --> ApplySampling["应用采样率"]
|
||||
SetSampleRate60 --> ApplySampling
|
||||
ApplySampling --> End([结束])
|
||||
```
|
||||
|
||||
采样控制算法通过波形类型(m_iTRWave)和周期(f_Tcycle)计算每段波形的数据总量,确保采样过程的精确性和一致性。系统支持多种波形类型,通过GetWaveNum方法返回对应的波形段数。
|
||||
|
||||
**Section sources**
|
||||
- [TestingData.cpp](file://cpp/ProblemZone/TestingData.cpp#L697-L724)
|
||||
- [TestingData.h](file://h/TestingData.h#L118-L138)
|
||||
|
||||
## 异常数据过滤与完整性校验
|
||||
|
||||
### 异常数据过滤算法
|
||||
系统采用多层过滤机制处理异常数据。首先在数据采集阶段,通过设备状态检查过滤无效数据;其次在数据存储阶段,通过数据库约束确保数据完整性;最后在数据显示阶段,通过条件判断过滤异常值。
|
||||
|
||||
对于温度和湿度等环境参数,系统采用-9999作为无效值标记。在数据显示时,如果检测到该值,则不显示任何内容:
|
||||
|
||||
```cpp
|
||||
if (szDefault == "-9999")//若为该值则不显示东西
|
||||
{
|
||||
szDefault = "";
|
||||
}
|
||||
```
|
||||
|
||||
### 数据完整性校验
|
||||
数据完整性校验通过以下机制实现:
|
||||
1. **数据库约束**:使用NOT NULL约束确保关键字段不为空
|
||||
2. **事务处理**:使用BeginTrans和CommitTrans确保数据操作的原子性
|
||||
3. **外键关联**:通过ID字段建立表间关联,维护数据一致性
|
||||
4. **日志记录**:通过m_pFile记录数据操作日志,便于问题追踪
|
||||
|
||||
在数据导入过程中,系统使用事务确保数据完整性。如果操作失败,则回滚所有更改,防止数据不一致:
|
||||
|
||||
```cpp
|
||||
try
|
||||
{
|
||||
m_pConnection->BeginTrans();
|
||||
// 执行数据操作
|
||||
m_pConnection->CommitTrans();
|
||||
}
|
||||
catch (_com_error e)
|
||||
{
|
||||
m_pConnection->RollbackTrans();
|
||||
return FALSE;
|
||||
}
|
||||
```
|
||||
|
||||
**Section sources**
|
||||
- [TestingData.cpp](file://cpp/ProblemZone/TestingData.cpp#L305-L308)
|
||||
- [DevManager.cpp](file://cpp/Managers/DevManager.cpp#L224-L277)
|
||||
|
||||
## 缓存机制与内存管理
|
||||
|
||||
### 数据缓存机制
|
||||
系统采用多级缓存机制优化数据访问性能。CTdManager类通过m_tdLinkList链表缓存测试数据对象,避免频繁的数据库查询。链表采用句柄机制管理对象,通过GenerateHandle方法生成唯一句柄:
|
||||
|
||||
```mermaid
|
||||
classDiagram
|
||||
class CLinkList {
|
||||
+Add(DWORD, CTestingData*)
|
||||
+Get(DWORD)
|
||||
+Delete(DWORD)
|
||||
+Find(int)
|
||||
}
|
||||
class CTdManager {
|
||||
+CLinkList<CTestingData*> m_tdLinkList
|
||||
+CHandleProcessor m_handleProcessor
|
||||
}
|
||||
CTdManager --> CLinkList : "包含"
|
||||
```
|
||||
|
||||
**Diagram sources**
|
||||
- [TdManager.h](file://h/TdManager.h#L96-L97)
|
||||
- [TdManager.cpp](file://cpp/Managers/TdManager.cpp#L61-L62)
|
||||
|
||||
### 内存管理策略
|
||||
内存管理采用智能指针和RAII模式,确保资源的正确释放。在CTestingData类的析构函数中,系统释放动态分配的m_waveCount内存:
|
||||
|
||||
```cpp
|
||||
CTestingData::~CTestingData()
|
||||
{
|
||||
delete m_waveCount;
|
||||
m_waveCount = NULL;
|
||||
}
|
||||
```
|
||||
|
||||
系统通过CreateWindowsTime和FreeWindowsTime方法管理时窗数据的内存分配和释放,避免内存泄漏。在长时间连续采集场景下,系统定期清理过期数据,保持内存使用效率。
|
||||
|
||||
**Section sources**
|
||||
- [TestingData.cpp](file://cpp/ProblemZone/TestingData.cpp#L81-L85)
|
||||
- [TestingData.cpp](file://cpp/ProblemZone/TestingData.cpp#L765-L770)
|
||||
|
||||
## 断点续传与数据库交互
|
||||
|
||||
### 断点续传功能
|
||||
断点续传功能通过记录数据采集进度实现。系统使用g_ui32PageCount全局变量跟踪当前页码,在ShowConListByPage方法中根据页码查询数据:
|
||||
|
||||
```cpp
|
||||
szSql.Format(_T("select TSN,a,b,x,y,N,K,I,V,R0,SP,bUse from td1dcon where TCHID in (select ID from tdchannel where TDID = %u and TSN>%u and TSN<=%u order by TCHID) order by TSN"), m_dwID, g_ui32PageCount*ONE_PAGE_DATA_NUMBER, (g_ui32PageCount + 1)*ONE_PAGE_DATA_NUMBER);
|
||||
```
|
||||
|
||||
当数据采集中断后,系统可以从上次的页码继续采集,避免重复工作。
|
||||
|
||||
### 数据库交互方式
|
||||
系统通过ADO技术与数据库交互,使用_RecordsetPtr和_CommandPtr指针执行SQL操作。数据导入采用参数化查询,防止SQL注入:
|
||||
|
||||
```cpp
|
||||
pCmdUpd->Parameters->Append(pCmdUpd->CreateParameter("Vrawdata", adBSTR, adParamInput, szSql.GetLength(), _variant_t(szVRawData.AllocSysString())));
|
||||
```
|
||||
|
||||
数据导出支持多种格式,包括Excel、CSV、Res2D等,通过SaveTdToExcelFile、SaveTdToCsvFile等方法实现:
|
||||
|
||||
```cpp
|
||||
virtual BOOL SaveTdToExcelFile(CString f_szFileName); // 保存数据为Excel文件
|
||||
virtual BOOL SaveTdToCsvFile(CString f_szFileName); // 保存数据为Csv文件
|
||||
virtual BOOL SaveTdToRes2DFile(CString f_szFileName); // 保存数据为Res2D文件
|
||||
```
|
||||
|
||||
**Section sources**
|
||||
- [TestingData.cpp](file://cpp/ProblemZone/TestingData.cpp#L97-L253)
|
||||
- [TestingData.h](file://h/TestingData.h#L230-L234)
|
||||
|
||||
## 结论
|
||||
Geomative Studio的数据采集与存储系统采用模块化设计,通过CTdManager类协调设备管理、数据采集和存储操作。系统具有完善的异常处理机制和数据完整性校验,确保数据的准确性和可靠性。多级缓存和内存管理策略优化了系统性能,特别适合长时间连续采集场景。断点续传功能提高了数据采集的容错能力,而灵活的数据库交互方式支持多种数据格式的导入导出。整体架构设计合理,为地质勘探数据的高效管理和分析提供了坚实基础。
|
||||
Reference in New Issue
Block a user