# 2D脚本生成 **本文档引用文件** - [SptManager.cpp](file://cpp/Managers/SptManager.cpp) - [Script.cpp](file://cpp/ProblemZone/Script.cpp) - [Script2D.cpp](file://cpp/ProblemZone/Script2D.cpp) - [MediumA.cpp](file://cpp/ProblemZone/MediumA.cpp) - [MediumW.cpp](file://cpp/ProblemZone/MediumW.cpp) - [MediumBasicWenAndSch.cpp](file://cpp/ProblemZone/MediumBasicWenAndSch.cpp) - [MediumStrongWenAndSch.cpp](file://cpp/ProblemZone/MediumStrongWenAndSch.cpp) - [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp) - [DialCustomSptInput.cpp](file://cpp/Operator/DialCustomSptInput.cpp) - [Script.h](file://h/Script.h) - [Script2D.h](file://h/Script2D.h) ## 目录 1. [引言](#引言) 2. [项目结构](#项目结构) 3. [核心组件](#核心组件) 4. [架构概述](#架构概述) 5. [详细组件分析](#详细组件分析) 6. [依赖关系分析](#依赖关系分析) 7. [性能考虑](#性能考虑) 8. [故障排除指南](#故障排除指南) 9. [结论](#结论) ## 引言 本文档详细阐述了Geomative Studio软件中2D测量脚本的生成机制。重点分析了`CSptManager::Create2DSConInDB`和`CScript`类在脚本创建过程中的协作,描述了从MediumA到MediumW等2D介质模型的电极排列算法和测量序列生成逻辑。文档还说明了脚本参数配置界面(如DialNew2DTask和OpCreateSptDlg)如何收集用户输入并生成XML格式的脚本结构,提供了从项目创建到脚本导出的完整流程,并分析了2D脚本与测试数据管理器的集成方式。 ## 项目结构 Geomative Studio项目是一个用于地球物理测量的软件系统,其核心功能围绕测量脚本的创建、管理和执行。项目结构清晰地分离了管理层、操作层和问题区域(ProblemZone)的代码。 ```mermaid graph TD subgraph "管理层" SptManager["SptManager.cpp
脚本管理"] ProManager["ProManager.cpp
项目管理"] TdManager["TdManager.cpp
测试数据管理"] end subgraph "操作层" DialNew2DTask["DialNew2DTask.cpp
2D任务创建对话框"] DialCustomSptInput["DialCustomSptInput.cpp
自定义脚本输入"] end subgraph "问题区域" Script["Script.cpp
脚本基类"] Script2D["Script2D.cpp
2D脚本实现"] MediumA["MediumA.cpp
温纳装置模型"] MediumW["MediumW.cpp
偶极-偶极装置模型"] MediumBasicWenAndSch["MediumBasicWenAndSch.cpp
施伦贝谢基础模型"] MediumStrongWenAndSch["MediumStrongWenAndSch.cpp
施伦贝谢强模型"] end SptManager --> Script2D SptManager --> MediumA SptManager --> MediumW DialNew2DTask --> SptManager DialCustomSptInput --> SptManager ``` **图源** - [SptManager.cpp](file://cpp/Managers/SptManager.cpp) - [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp) - [Script2D.cpp](file://cpp/ProblemZone/Script2D.cpp) - [MediumA.cpp](file://cpp/ProblemZone/MediumA.cpp) - [MediumW.cpp](file://cpp/ProblemZone/MediumW.cpp) **本节源** - [SptManager.cpp](file://cpp/Managers/SptManager.cpp) - [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp) ## 核心组件 2D脚本生成的核心组件包括`CSptManager`、`CScript2D`和各种`CMedium`派生类。`CSptManager`负责协调脚本的创建流程,`CScript2D`作为2D脚本的数据容器,而`CMedium`系列类则封装了不同测量装置的电极排列算法。 **本节源** - [SptManager.cpp](file://cpp/Managers/SptManager.cpp) - [Script2D.cpp](file://cpp/ProblemZone/Script2D.cpp) - [MediumA.cpp](file://cpp/ProblemZone/MediumA.cpp) ## 架构概述 2D脚本生成的架构遵循典型的MVC(模型-视图-控制器)模式。用户通过视图(如`DialNew2DTask`)输入参数,控制器(`CSptManager`)接收请求并协调模型(`CScript2D`和`CMedium`)进行处理,最终将结果持久化到数据库。 ```mermaid sequenceDiagram participant User as "用户" participant View as "DialNew2DTask" participant Controller as "CSptManager" participant Model as "CScript2D / CMedium" participant DB as "数据库" User->>View : 输入参数电极数、测量类型等 View->>Controller : 调用Create2DSConInDB Controller->>Model : 创建CScript2D实例 Controller->>Model : 调用介质模型的GenerateSptRecElecVal Model-->>Controller : 返回生成的测量序列 Controller->>DB : 将脚本数据写入scon、channel、script2d表 DB-->>Controller : 确认写入成功 Controller-->>View : 返回成功状态 View-->>User : 显示创建成功消息 ``` **图源** - [SptManager.cpp](file://cpp/Managers/SptManager.cpp#L257-L486) - [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp#L414-L664) - [Script2D.cpp](file://cpp/ProblemZone/Script2D.cpp) ## 详细组件分析 ### CSptManager与CScript的协作机制 `CSptManager::Create2DSConInDB`是创建2D脚本的核心方法。它首先创建一个`COpCreateSptDlg`对话框来收集用户输入,然后根据输入创建一个`CScript2D`对象。该方法与`CScript`类的协作体现在`CScript2D`作为`CScript`的派生类,继承了基本的脚本属性和方法。 ```mermaid classDiagram class CScript { +DWORD m_dwID +int m_iEAmount +int m_iSType +int m_iAR +_ConnectionPtr m_pConnection +CScript(DWORD dwID, _ConnectionPtr& pConnection) +virtual ~CScript() } class CScript2D { +CPtrList m_chaList +bool ShowSptConInfo(CListCtrl& sptConList) +bool ShowSptDetailInfo(CListCtrl& sptDetailList) +bool ShowChannelList(CListCtrl& sptChannelList) +void AdjustRecListColumn(int iAR, CListCtrl& sptConListInfo) +CScript2D(DWORD dwID, _ConnectionPtr& pConnection) +virtual ~CScript2D() } class CSptManager { +UINT Create2DSConInDB(DWORD& dwSConID) +void Delete2DSConInDB(DWORD dwSConID) +CScript* GetScript(DWORD dwHandle) +void DeleteObjInMem(DWORD dwHandle) } CScript2D --|> CScript : 继承 CSptManager --> CScript2D : 创建实例 CSptManager --> COpCreateSptDlg : 显示对话框 ``` **图源** - [SptManager.cpp](file://cpp/Managers/SptManager.cpp#L257-L486) - [Script.cpp](file://cpp/ProblemZone/Script.cpp) - [Script2D.cpp](file://cpp/ProblemZone/Script2D.cpp) - [Script.h](file://h/Script.h) - [Script2D.h](file://h/Script2D.h) **本节源** - [SptManager.cpp](file://cpp/Managers/SptManager.cpp#L257-L486) - [Script.cpp](file://cpp/ProblemZone/Script.cpp) - [Script2D.cpp](file://cpp/ProblemZone/Script2D.cpp) ### 2D介质模型的电极排列算法 不同的2D介质模型(如MediumA、MediumW)实现了各自的`GenerateSptRecElecVal`方法来生成特定的测量序列。 #### MediumA(温纳装置)算法 `CMediumA`类实现了温纳装置的电极排列算法。其核心逻辑是根据电极总数计算最大层数,并生成相应的测量序列。 ```mermaid flowchart TD Start([开始]) --> CheckInput["验证输入参数"] CheckInput --> CalcMaxSpace["计算最大间距 iMaxSpace = (iEAmount-1)/3"] CalcMaxSpace --> LoopLayer["循环每一层 iMMVal"] LoopLayer --> CalcPositions["计算A, B, M, N电极位置"] CalcPositions --> CreateRecord["创建CSptRecord并设置参数"] CreateRecord --> AddToArray["将记录添加到pSptRecArray"] AddToArray --> CalcK["计算K值: fK = 2*π*(iN-iM)"] CalcK --> CalcLevel["计算层数: iN-iM"] CalcLevel --> InnerLoop["内部循环: 电极向右平移"] InnerLoop --> UpdatePositions["更新A, B, M, N位置"] UpdatePositions --> CreateInnerRecord["创建新的CSptRecord"] CreateInnerRecord --> AddInnerRecord["添加到pSptRecArray"] AddInnerRecord --> CheckEnd["检查是否到达电极末端"] CheckEnd --> |否| UpdatePositions CheckEnd --> |是| NextLayer["进入下一层"] NextLayer --> LoopLayer LoopLayer --> |完成| SetOutput["设置输出参数 *pMaxLevel 和 *pPtAmount"] SetOutput --> End([结束]) ``` **图源** - [MediumA.cpp](file://cpp/ProblemZone/MediumA.cpp#L30-L167) **本节源** - [MediumA.cpp](file://cpp/ProblemZone/MediumA.cpp#L30-L167) #### MediumW(偶极-偶极装置)算法 `CMediumW`类使用了一个外部的脚本生成库(scr_)来处理复杂的偶极-偶极装置的测量序列生成。 ```mermaid flowchart TD Start([开始]) --> Init["初始化scr对象"] Init --> SetRect["设置测量区域矩形"] SetRect --> SetPoleStart["设置起始电极号"] SetPoleStart --> SetZone["设置测量区域"] SetZone --> Generate["调用scr_generate生成序列"] Generate --> GetPoints["获取生成的测量点列表"] GetPoints --> LoopPoints["循环每个测量点"] LoopPoints --> CreateRecord["创建CSptRecord并填充A,B,M,N,K值"] CreateRecord --> AddToArray["添加到pSptRecArray"] AddToArray --> NextPoint["下一个点"] NextPoint --> LoopPoints LoopPoints --> |完成| Return["返回成功"] Return --> End([结束]) ``` **图源** - [MediumW.cpp](file://cpp/ProblemZone/MediumW.cpp#L27-L62) **本节源** - [MediumW.cpp](file://cpp/ProblemZone/MediumW.cpp#L27-L62) #### MediumBasicWenAndSch(施伦贝谢基础模型)算法 该模型实现了施伦贝谢装置的测量序列,其特点是AM间距和MN间距按特定规则递增。 ```mermaid flowchart TD Start([开始]) --> LoopLayer["循环每一层 iLayer"] LoopLayer --> CalcTailor["计算调整层数 iTailorLayer = (iLayer-1)/5"] CalcTailor --> CalcAM["计算AM间距: iLayer - iTailorLayer"] CalcAM --> CalcMN["计算MN间距: 1 + iTailorLayer*2"] CalcMN --> SetInitialPos["设置初始电极位置"] SetInitialPos --> CheckEnd["检查B电极是否超出范围"] CheckEnd --> |是| Break["跳出循环"] CheckEnd --> |否| LoopMeasure["循环测量"] LoopMeasure --> CreateRecord["创建CSptRecord"] CreateRecord --> CalcK["计算K值"] CalcK --> AddToArray["添加到pSptRecArray"] AddToArray --> MoveRight["电极向右平移1"] MoveRight --> CheckEnd LoopLayer --> |完成| SetOutput["设置输出参数"] SetOutput --> End([结束]) ``` **图源** - [MediumBasicWenAndSch.cpp](file://cpp/ProblemZone/MediumBasicWenAndSch.cpp#L43-L118) **本节源** - [MediumBasicWenAndSch.cpp](file://cpp/ProblemZone/MediumBasicWenAndSch.cpp#L43-L118) ### 脚本参数配置界面 `DialNew2DTask`对话框是用户创建2D测量任务的主要界面,它收集了任务名称、测试地点、测量类型、电极间距等关键参数。 ```mermaid flowchart TD A[任务名称] --> B[测试地点] B --> C[测量类型] C --> D[装置类型] D --> E[脚本选择] E --> F[电缆布线方式] F --> G[发射周期] G --> H[电极间距] H --> I[采样间隔] I --> J[起始/结束电极] J --> K[验证输入] K --> L[创建任务] ``` **本节源** - [DialNew2DTask.cpp](file://cpp/Views/DialNew2DTask.cpp) ### 自定义脚本输入 `DialCustomSptInput`对话框允许用户手动输入或从Excel导入自定义的测量序列。 ```mermaid flowchart TD A[手动输入] --> B[验证A,B,M,N,K值] B --> C[计算K值(可选)] C --> D[添加到列表] D --> E[修改/删除列表项] E --> F[从Excel导入] F --> G[选择追加或替换] G --> H[解析Excel数据] H --> I[添加到列表] I --> J[完成] ``` **本节源** - [DialCustomSptInput.cpp](file://cpp/Operator/DialCustomSptInput.cpp) ## 依赖关系分析 2D脚本生成模块依赖于数据库连接、对话框界面和各种介质模型。 ```mermaid graph TD SptManager --> Script2D SptManager --> MediumA SptManager --> MediumB SptManager --> MediumC SptManager --> MediumD SptManager --> MediumE SptManager --> MediumK SptManager --> MediumQ SptManager --> MediumR SptManager --> MediumS SptManager --> MediumT SptManager --> MediumU SptManager --> MediumV SptManager --> MediumW SptManager --> MediumX SptManager --> MediumY SptManager --> MediumZ SptManager --> MediumZA SptManager --> MediumZB SptManager --> MediumZC SptManager --> MediumLogging SptManager --> MediumStrongWenAndSch SptManager --> MediumBasicWenAndSch SptManager --> MediumAM SptManager --> MediumAMN SptManager --> MediumCustom2D SptManager --> MediumUnityProfile SptManager --> MediumEdgeGradient SptManager --> MeidumBipoleUpHole SptManager --> MediumTwoSideAMN SptManager --> MediumMidGardientScan SptManager --> MediumStrongGradient SptManager --> MediumCrossHoleGeomative SptManager --> MediumCrossHoleGeomativeAM SptManager --> MediumLandfillAdjacent SptManager --> MediumLandfillDiagonally SptManager --> MediumS3P SptManager --> opcreatesptdlg.h SptManager --> opcreatecesptdlg.h SptManager --> OpCreate3DSptDlg.h SptManager --> GD10OperCmd.h SptManager --> MediumCustom2D.h SptManager --> DialCreateNew3DSpt.h DialNew2DTask --> SptManager DialCustomSptInput --> SptManager ``` **图源** - [SptManager.cpp](file://cpp/Managers/SptManager.cpp#L10-L51) **本节源** - [SptManager.cpp](file://cpp/Managers/SptManager.cpp#L10-L51) ## 性能考虑 在生成大型2D测量脚本时,性能主要受电极总数和层数的影响。`CMediumA`和`CMediumBasicWenAndSch`的算法复杂度为O(n²),其中n为电极数量。对于非常大的测量区域,建议分段创建脚本。 ## 故障排除指南 常见问题及解决方案: 1. **电极冲突检测**:在`CMediumA::GenerateSptRecElecVal`中,通过检查`iAM`, `iAN`, `iBM`, `iBN`是否为零来避免电极位置重叠。 2. **测量序列优化**:`CMediumBasicWenAndSch::ReSortPoint`方法实现了优化的跑极顺序,以减少电极移动距离。 3. **K值计算错误**:在`CalculateK`方法中,当分母为零时会弹出错误提示,防止生成无效的K值。 4. **脚本名称重复**:在`CSptManager::Create2DSConInDB`中,通过查询数据库检查是否存在同名脚本,避免重复创建。 **本节源** - [MediumA.cpp](file://cpp/ProblemZone/MediumA.cpp#L531-L538) - [MediumBasicWenAndSch.cpp](file://cpp/ProblemZone/MediumBasicWenAndSch.cpp#L309-L384) - [DialCustomSptInput.cpp](file://cpp/Operator/DialCustomSptInput.cpp#L505-L517) - [SptManager.cpp](file://cpp/Managers/SptManager.cpp#L334-L351) ## 结论 Geomative Studio的2D脚本生成系统是一个功能强大且灵活的框架。通过`CSptManager`统一管理,结合多种`CMedium`模型实现不同的测量装置,为用户提供了一个从参数配置到脚本生成的完整解决方案。该系统设计良好,易于扩展,能够满足各种复杂的地球物理测量需求。