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,121 @@
# 数据格式处理
<cite>
**本文档引用的文件**
- [Markup.cpp](file://cpp/Tools/Markup.cpp)
- [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp)
- [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp)
- [Res3DDatFile.cpp](file://cpp/Tools/Res3DDatFile.cpp)
- [Res3DDatFileRecord.cpp](file://cpp/Tools/Res3DDatFileRecord.cpp)
</cite>
## 目录
1. [引言](#引言)
2. [XML配置文件解析与生成](#xml配置文件解析与生成)
3. [文本测量数据读写](#文本测量数据读写)
4. [URF专有数据格式解析](#urf专有数据格式解析)
5. [三维测量结果数据存储](#三维测量结果数据存储)
6. [应用实例](#应用实例)
7. [性能优化与错误容忍](#性能优化与错误容忍)
8. [结论](#结论)
## 引言
Geomative Studio项目涉及多种数据格式的处理,包括用于配置的XML文件、用于测量数据交换的文本文件、专有的URF数据格式以及用于存储三维测量结果的二进制DAT文件。本文件详细阐述了`Markup.cpp``OperTxtFile.cpp``OperUrfFile.cpp``Res3DDatFile.cpp`四个核心模块的实现逻辑,分析其在项目缓存、任务脚本导出和结果文件生成中的应用,并讨论其性能优化与错误处理策略。
## XML配置文件解析与生成
`Markup.cpp`模块提供了一个功能完整的XML文档解析与生成器,其核心是`CMarkup`类。该模块实现了对XML配置文件的节点遍历、属性读取、嵌套结构处理和内存管理。
### 节点遍历与属性读取
该模块通过维护一个`ElemPos`(元素位置)结构数组来高效地表示XML文档的树形结构。每个`ElemPos`结构记录了节点在文档字符串中的起始位置、长度、标签长度、层级深度以及与其他节点的父子、兄弟关系。这种设计避免了在解析时进行昂贵的字符串分割操作,而是通过索引直接定位节点内容。
对于属性读取,模块提供了`SetAttrib``GetAttrib`等方法。当需要设置属性时,它会计算属性在标签字符串中的精确位置,并使用`x_StrInsertReplace`函数进行原地插入或替换,从而最小化内存拷贝开销。
### 嵌套结构处理
模块通过`iElemParent``iElemChild``iElemNext`等指针在`ElemPos`结构中构建了完整的树形关系。这使得`FindElem``IntoElem``OutOfElem`等方法能够高效地在嵌套的XML结构中进行导航。例如,`IntoElem`会将当前上下文移动到当前元素的第一个子元素,而`OutOfElem`则会返回到父元素。
### 内存管理策略
内存管理是该模块的核心优势。它采用了一种“分段数组”(Segmented Array)的策略来管理`ElemPos`结构。`ElemPosTree`类将`ElemPos`对象存储在多个连续的内存块(段)中,而不是一个巨大的连续数组。这避免了在文档变大时重新分配和复制整个数组的性能瓶颈。`GrowElemPosTree`方法在需要时动态增加新的内存段,确保了在处理大型XML文件时的内存效率和性能稳定性。
**节段来源**
- [Markup.cpp](file://cpp/Tools/Markup.cpp#L917-L998)
## 文本测量数据读写
`OperTxtFile.cpp`模块负责处理以文本格式存储的测量数据,支持多种编码和分隔符,主要用于任务脚本和配置的导出。
### 读写实现
该模块通过标准C库的`fopen``fwrite``fclose`函数进行文件操作。`OpenFileforWrite`方法以写入模式打开文件,`WriteFileContent`方法则负责将`CStringArray`中的内容写入文件。
### 编码与分隔符支持
虽然代码中未显式处理编码转换,但通过使用`CString`类,模块天然支持Unicode(UTF-16)和多字节字符集(MBCS)。文件的最终编码取决于系统区域设置和`fopen`函数的内部行为。对于分隔符,该模块采用了一种独特的“固定宽度”格式。`SetParamWidth`方法设置每个字段的固定宽度(默认18个字符),`WriteFileContent`方法会用空格填充不足的字段,从而形成类似表格的对齐效果。这虽然不是传统的逗号或制表符分隔,但提供了一种简单、可读性强的数据格式。
**节段来源**
- [OperTxtFile.cpp](file://cpp/Tools/OperTxtFile.cpp)
## URF专有数据格式解析
`OperUrfFile.cpp`模块专门用于解析和生成URFUniversal Resistivity File)专有数据格式,这是一种用于地球物理电阻率测量的行业标准文本格式。
### 解析规则
URF文件采用纯文本格式,包含注释行、元数据行和数据行。该模块的解析规则主要体现在`WriteUrfPoleInfo``WriteUrfPoleInfo_3D`等方法中:
1. **头部信息**:通过`WriteUrfHeadInfo``Write3DUrfHeadInfo`写入文件描述和单位信息。
2. **几何信息**:以`:Geometry`为分隔符,后跟`ID,X,Y,Z`的列标题,然后是电极的坐标数据。电极坐标的生成逻辑(如温纳装置、偶极装置等)由`WriteElecByAR`系列方法根据不同的测量阵列(AR)类型实现。
3. **测量信息**:以`:Measurements`为分隔符,后跟`A, B, M, N, V/I(ohm), I(mA), Error(%), Chargeability(mV/V)`的列标题,然后是实际的测量数据。
该模块通过`WriteElecByCrossHoleGeomative`等方法从数据库(如`TTaskBindElecInfo`表)中查询电极坐标,实现了URF文件与项目数据的动态绑定。
**节段来源**
- [OperUrfFile.cpp](file://cpp/Tools/OperUrfFile.cpp)
## 三维测量结果数据存储
`Res3DDatFile.cpp`模块负责将三维测量结果以结构化的二进制布局存储到`.dat`文件中,该文件用于后续的数据处理和成像。
### 结构化存储机制
#### 二进制布局
该模块使用Windows API的`CreateFile``WriteFile`函数直接写入二进制数据。文件布局分为三个部分:
1. **头部**:包含标题、网格列数、行数、列间距、行间距、介质类型和记录点总数。所有数据均以ASCII文本形式写入,每项后跟换行符。
2. **记录数据**:包含多个测量记录。每个记录由A、B、M、N四个电极的坐标(X, Y)和电阻率值`R0`组成。坐标和`R0`均以固定格式的文本写入。
3. **尾部**:写入5个零值,作为文件结束的标记。
#### 元数据嵌入
元数据(如标题、网格尺寸、间距、介质类型)在文件头部以明文形式嵌入。`SetTitle``SetGriding``SetSpacing``SetMedium`等方法用于设置这些元数据。
#### 版本兼容性处理
代码中通过`VAL_ZERO``VAL_MINUS_ONE`等常量定义了默认值和无效值,这有助于在不同版本的软件之间保持一定的兼容性。例如,当电极ID为-1时,表示该电极未使用。然而,代码中未发现显式的版本号字段或复杂的向后/向前兼容性逻辑,其兼容性主要依赖于固定的文件结构和数据类型。
**节段来源**
- [Res3DDatFile.cpp](file://cpp/Tools/Res3DDatFile.cpp)
- [Res3DDatFileRecord.cpp](file://cpp/Tools/Res3DDatFileRecord.cpp)
## 应用实例
上述数据格式处理模块在Geomative Studio中有着广泛的应用:
- **项目缓存**`Markup.cpp`用于读写`CACHE`目录下的`project.xml``testzone.xml`文件,保存和恢复项目状态。
- **任务脚本导出**`OperTxtFile.cpp`用于生成`.map``.rul`等脚本文件,`OperUrfFile.cpp`用于将任务导出为标准的URF格式,便于与其他软件交换数据。
- **结果文件生成**`Res3DDatFile.cpp`用于将三维测量结果生成`.dat`文件,供后续的反演和成像模块使用。
## 性能优化与错误容忍策略
### 性能优化
- **内存效率**`Markup.cpp`的分段数组设计避免了大文件解析时的内存抖动。
- **I/O效率**`Res3DDatFile.cpp``OperUrfFile.cpp`都使用了`fflush`来控制缓冲区刷新,平衡了性能和数据安全性。
- **算法优化**`Markup.cpp`中的`x_Hash`函数使用了简单的加法哈希,确保了在编码查找时的快速响应。
### 错误容忍策略
- **输入验证**:所有模块在关键操作前都进行了严格的输入验证,例如检查文件指针是否为空、参数是否在有效范围内。
- **异常处理**:通过`GetLastError()`获取系统错误码,并使用`AfxMessageBox``MessageBoxEx`向用户报告详细的错误信息(支持中英文)。
- **资源清理**:在析构函数和`CloseFile`方法中确保文件句柄被正确关闭,防止资源泄漏。
## 结论
Geomative Studio的数据格式处理体系结构清晰,各模块职责分明。`Markup.cpp`提供了一个高效、内存友好的XML处理方案;`OperTxtFile.cpp``OperUrfFile.cpp`分别处理通用文本和行业标准格式;`Res3DDatFile.cpp`则实现了专有的二进制结果存储。这些模块共同支撑了项目的配置管理、数据交换和结果保存功能。尽管在编码转换和版本兼容性方面有进一步提升的空间,但其整体设计稳健,错误处理完善,为地球物理测量软件的可靠运行提供了坚实的基础。