# 数据采集与存储 **本文档引用的文件** - [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) ## 目录 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 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类协调设备管理、数据采集和存储操作。系统具有完善的异常处理机制和数据完整性校验,确保数据的准确性和可靠性。多级缓存和内存管理策略优化了系统性能,特别适合长时间连续采集场景。断点续传功能提高了数据采集的容错能力,而灵活的数据库交互方式支持多种数据格式的导入导出。整体架构设计合理,为地质勘探数据的高效管理和分析提供了坚实基础。