docs: 初始提交 Geopro3.0 桌面客户端材料与 M1 架构设计
- 技术选型与架构规约、Excel 功能菜单、business/admin OpenAPI - 三维数据样本(剖面/网格/色阶/异常/雷达/DEM)与数据格式说明 - M1 架构设计 v2(双专家评审+数据核验修订)与 Windows 环境搭建指引
This commit is contained in:
commit
667e97ed1b
|
|
@ -0,0 +1,43 @@
|
|||
# ---- Build output ----
|
||||
/build/
|
||||
/out/
|
||||
/cmake-build-*/
|
||||
CMakeUserPresets.json
|
||||
|
||||
# ---- vcpkg ----
|
||||
/vcpkg_installed/
|
||||
/vcpkg/
|
||||
|
||||
# ---- Visual Studio / IDE ----
|
||||
.vs/
|
||||
.vscode/
|
||||
*.user
|
||||
*.suo
|
||||
*.VC.db
|
||||
*.opendb
|
||||
|
||||
# ---- Compiled / artifacts ----
|
||||
*.obj
|
||||
*.o
|
||||
*.exe
|
||||
*.dll
|
||||
*.lib
|
||||
*.pdb
|
||||
compile_commands.json
|
||||
|
||||
# ---- OS / temp ----
|
||||
Thumbs.db
|
||||
.DS_Store
|
||||
~$*
|
||||
|
||||
# ---- Working artifacts (this session) ----
|
||||
.playwright-mcp/
|
||||
proto*.jpeg
|
||||
tenant_login*.jpeg
|
||||
docs/proto*.jpeg
|
||||
docs/tenant_login*.jpeg
|
||||
docs/docx_media/
|
||||
docs/_docx_media/
|
||||
|
||||
# ---- Large redundant archive (sample data kept unpacked in folder) ----
|
||||
docs/剖面网格数据的色阶数据2等文件.tar
|
||||
|
|
@ -0,0 +1,231 @@
|
|||
# Geopro 3.0 桌面客户端 — Windows 开发环境从零搭建指引
|
||||
|
||||
适用:Windows 10 22H2 / Windows 11,64 位,MSVC 2022 工具链。
|
||||
目标:从一台干净的机器,搭到能 `cmake --build` 出可运行的 Qt6 + VTK9 桌面程序。
|
||||
|
||||
> 配套设计文档:`docs/superpowers/specs/2026-06-07-geopro-desktop-m1-design.md`
|
||||
|
||||
---
|
||||
|
||||
## 0. 总览
|
||||
|
||||
四块:① 编译器(VS2022 / MSVC)② Git ③ 依赖管理(vcpkg + CMake)④ 全量依赖(含 Qt/VTK,走 vcpkg)。
|
||||
|
||||
> **构建方案已定:全 vcpkg(方案 B)。** 原因(已核 vcpkg `ports/vtk/vcpkg.json`):嵌 VTK 进 Qt 必须用 `QVTKOpenGLNativeWidget`/`QVTKOpenGLStereoWidget`(在 VTK 的 `GUISupportQt` 模块),该模块要求 `vtk[qt]`,而 `vtk[qt]` 依赖 vcpkg 的 `qtbase`+`qtdeclarative`。若再叠加 Qt 官方安装器,会出现**两份 Qt(官方 + vcpkg)DLL/ABI 冲突**(典型表现:运行期 plugin 加载失败或崩溃)。故全家共用同一份 vcpkg Qt。
|
||||
>
|
||||
> 代价:首次编译 Qt+VTK 较久(数小时级),用二进制缓存(`VCPKG_BINARY_SOURCES`)缓解;CI 同此方案保证可复现。
|
||||
>
|
||||
> (若确有理由保留官方 Qt,须为 vcpkg 的 vtk/qtkeychain 配 overlay-port 指向官方 Qt、禁止 vcpkg 重复构建 Qt——复杂易错,不推荐。)
|
||||
|
||||
---
|
||||
|
||||
## 1. Visual Studio 2022(MSVC + CMake + Ninja)
|
||||
|
||||
1. 安装 **Visual Studio 2022 Community**(或更高)。
|
||||
2. 勾选工作负载 **「使用 C++ 的桌面开发」(Desktop development with C++)**,确保包含:
|
||||
- MSVC v143 - VS 2022 C++ x64/x86 生成工具
|
||||
- Windows 11 SDK(或 Windows 10 SDK)
|
||||
- C++ CMake tools for Windows(自带 CMake + Ninja)
|
||||
- C++ AddressSanitizer(用于 Debug Sanitizer,规约 §10.2)
|
||||
3. 验证:开「x64 Native Tools Command Prompt for VS 2022」,运行:
|
||||
```
|
||||
cl
|
||||
cmake --version # 应 ≥ 3.21
|
||||
ninja --version
|
||||
```
|
||||
|
||||
> 之后所有 cmake/vcpkg 命令都在 **x64 Native Tools 命令行** 里跑(已设好 MSVC 环境变量)。
|
||||
|
||||
---
|
||||
|
||||
## 2. Git
|
||||
|
||||
1. 安装 [Git for Windows](https://git-scm.com/download/win)。
|
||||
2. 验证:`git --version`。
|
||||
3. 本项目当前**尚未初始化 git 仓库**——首次提交前需 `git init`(见 §7)。
|
||||
|
||||
---
|
||||
|
||||
## 3. vcpkg(依赖管理)
|
||||
|
||||
```powershell
|
||||
# 选一个不含空格/中文的路径,例如 C:\dev
|
||||
git clone https://github.com/microsoft/vcpkg C:\dev\vcpkg
|
||||
C:\dev\vcpkg\bootstrap-vcpkg.bat
|
||||
```
|
||||
|
||||
设环境变量(系统环境变量或当前会话):
|
||||
```powershell
|
||||
$env:VCPKG_ROOT = "C:\dev\vcpkg"
|
||||
setx VCPKG_ROOT "C:\dev\vcpkg" # 永久(新开终端生效)
|
||||
```
|
||||
|
||||
> 本项目用 **vcpkg manifest 模式**(`vcpkg.json`),不需要手动 `vcpkg install`;CMake 配置时按清单自动拉取。
|
||||
|
||||
---
|
||||
|
||||
## 4. Qt(不单独装——随 vcpkg 全量构建)
|
||||
|
||||
方案 B 下 **Qt 不用官方安装器**,由 vcpkg 的 `qtbase`/`qttools` 以及 `vtk[qt]` 共同复用同一份 Qt(见 §5)。这样 VTK、QtKeychain、ADS、应用本体全部链接同一 Qt,杜绝双份 Qt 冲突。
|
||||
|
||||
---
|
||||
|
||||
## 5. 全量依赖:`vcpkg.json`(项目根,M1 清单)
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "geopro-desktop",
|
||||
"version": "0.1.0",
|
||||
"dependencies": [
|
||||
{ "name": "qtbase", "default-features": false, "features": ["gui", "widgets", "network", "sql", "sql-sqlite", "concurrent", "opengl"] },
|
||||
"qttools",
|
||||
{ "name": "vtk", "default-features": false, "features": ["qt", "opengl", "gdal", "proj"] },
|
||||
"gdal",
|
||||
"proj",
|
||||
"eigen3",
|
||||
"spdlog",
|
||||
"fmt",
|
||||
"nlohmann-json",
|
||||
"openssl",
|
||||
"qtkeychain",
|
||||
"gtest"
|
||||
],
|
||||
"builtin-baseline": "<运行 vcpkg x-update-baseline 自动填入>",
|
||||
"overrides": []
|
||||
}
|
||||
```
|
||||
|
||||
说明:
|
||||
- **`vtk[qt]`** 拉入 vcpkg `qtbase`+`qtdeclarative`(已核 vcpkg `ports/vtk/vcpkg.json`);与上面显式声明的 `qtbase` 复用同一份 Qt——这是方案 B 的关键。
|
||||
- **`vtk` 用 `default-features:false` 只选 `qt/opengl/gdal/proj`**,避免默认拉入 netcdf/seacas/libharu/cgns 等重特性,缩短编译。
|
||||
- **ADS(Qt-Advanced-Docking-System)**:vcpkg 端口 `qt-advanced-docking-system`——**端口可用性/对 Qt6 支持需在 spike 阶段先验证**;不可用则改 FetchContent 锁 tag(见 §6 备注)。验证通过后加进 dependencies。
|
||||
- **PCL 不引入**(M1 点规模无需 KD-tree)。
|
||||
- `builtin-baseline`:`vcpkg x-update-baseline --add-initial-baseline` 自动写入,锁版本(规约 §5.4)。
|
||||
- 首次编译 Qt+VTK 久,配 `VCPKG_BINARY_SOURCES`(如本地/网络二进制缓存)显著提速。
|
||||
|
||||
---
|
||||
|
||||
## 6. CMake 接线
|
||||
|
||||
### 6.1 `CMakePresets.json`(项目根)
|
||||
|
||||
```json
|
||||
{
|
||||
"version": 3,
|
||||
"configurePresets": [
|
||||
{
|
||||
"name": "msvc-debug",
|
||||
"generator": "Ninja",
|
||||
"binaryDir": "${sourceDir}/build/debug",
|
||||
"cacheVariables": {
|
||||
"CMAKE_BUILD_TYPE": "Debug",
|
||||
"CMAKE_TOOLCHAIN_FILE": "$env{VCPKG_ROOT}/scripts/buildsystems/vcpkg.cmake",
|
||||
"CMAKE_EXPORT_COMPILE_COMMANDS": "ON"
|
||||
}
|
||||
},
|
||||
{
|
||||
"name": "msvc-release",
|
||||
"inherits": "msvc-debug",
|
||||
"binaryDir": "${sourceDir}/build/release",
|
||||
"cacheVariables": { "CMAKE_BUILD_TYPE": "Release" }
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
> 全 vcpkg 方案下**不设 `CMAKE_PREFIX_PATH` 指向官方 Qt**——vcpkg 工具链接管 Qt 查找(避免双 Qt)。
|
||||
|
||||
### 6.2 顶层 `CMakeLists.txt`(骨架)
|
||||
|
||||
```cmake
|
||||
cmake_minimum_required(VERSION 3.21)
|
||||
project(geopro_desktop LANGUAGES CXX)
|
||||
set(CMAKE_CXX_STANDARD 17)
|
||||
set(CMAKE_CXX_STANDARD_REQUIRED ON)
|
||||
set(CMAKE_AUTOMOC ON)
|
||||
set(CMAKE_AUTORCC ON)
|
||||
set(CMAKE_AUTOUIC ON)
|
||||
|
||||
find_package(Qt6 REQUIRED COMPONENTS Core Gui Widgets Network Sql Concurrent)
|
||||
find_package(VTK REQUIRED) # 含 GUISupportQt(vtk[qt])→ QVTKOpenGLStereoWidget
|
||||
find_package(GDAL CONFIG REQUIRED)
|
||||
find_package(PROJ CONFIG REQUIRED)
|
||||
find_package(Eigen3 CONFIG REQUIRED)
|
||||
find_package(spdlog CONFIG REQUIRED)
|
||||
find_package(nlohmann_json CONFIG REQUIRED)
|
||||
find_package(OpenSSL REQUIRED)
|
||||
# find_package(Qt6Keychain CONFIG REQUIRED) # qtkeychain
|
||||
# ADS:vcpkg 端口验证通过后 find_package;否则用下方 FetchContent
|
||||
|
||||
add_subdirectory(src)
|
||||
enable_testing()
|
||||
add_subdirectory(tests)
|
||||
```
|
||||
|
||||
> VTK 链接用 `vtk_module_autoinit`;视图层用 **`QVTKOpenGLStereoWidget`**(QOpenGLWidget 系,ADS reparent 友好,见设计 §K-9),不用 native 版。
|
||||
|
||||
> **ADS 备选引入**(若 vcpkg 端口不可用,spike 阶段确定):
|
||||
> ```cmake
|
||||
> include(FetchContent)
|
||||
> FetchContent_Declare(ads GIT_REPOSITORY https://github.com/githubuser0xFFFF/Qt-Advanced-Docking-System.git GIT_TAG <tag>)
|
||||
> FetchContent_MakeAvailable(ads)
|
||||
> ```
|
||||
|
||||
---
|
||||
|
||||
## 7. 首次配置、编译、运行
|
||||
|
||||
```powershell
|
||||
# 在 x64 Native Tools 命令行、项目根目录
|
||||
git init # 首次:初始化仓库
|
||||
vcpkg x-update-baseline --add-initial-baseline
|
||||
|
||||
cmake --preset msvc-debug # 首次会编译 VTK 等,耗时较长
|
||||
cmake --build build/debug
|
||||
|
||||
# 运行(VTK/Qt 的 dll 需在 PATH 或同目录)
|
||||
.\build\debug\src\app\geopro_desktop.exe
|
||||
```
|
||||
|
||||
**运行期 DLL 部署(单一 vcpkg 链路)**:
|
||||
- 全部 dll(含 Qt)来自 vcpkg:`build/vcpkg_installed/x64-windows/(debug/)bin`。
|
||||
- 用 CMake `TARGET_RUNTIME_DLLS` + `add_custom_command(POST_BUILD)` 自动拷贝到 exe 目录(实现阶段加)。
|
||||
- **不混用官方 Qt 的 `windeployqt`**——本方案 Qt 来自 vcpkg,混用会拷错版本造成双 Qt 冲突。
|
||||
- Qt plugins(platforms/imageformats/sqldrivers 等)由 vcpkg 部署脚本处理;如缺再用 vcpkg 安装树里的 `windeployqt` 对齐同一份 Qt。
|
||||
|
||||
---
|
||||
|
||||
## 8. AI 编码上下文基础设施(规约 §10.1,强烈建议先建)
|
||||
|
||||
项目根放:
|
||||
|
||||
- `.clang-format`:统一风格(基于 LLVM/Google + 团队微调)。
|
||||
- `.clangd`:
|
||||
```yaml
|
||||
CompileFlags:
|
||||
CompilationDatabase: build/debug
|
||||
```
|
||||
使 clangd 读取 `compile_commands.json`,给 AI/IDE 精确类型上下文。
|
||||
- VS Code 装 **clangd** 扩展(禁用微软 C++ IntelliSense 避免冲突),或 CLion 直接用 CMake。
|
||||
|
||||
---
|
||||
|
||||
## 9. 验证清单
|
||||
|
||||
- [ ] `cl` / `cmake` / `ninja` / `git` 命令可用
|
||||
- [ ] `VCPKG_ROOT` 已设
|
||||
- [ ] `vcpkg.json` 含 qtbase + vtk[qt](共用一份 Qt),preset **未**指向官方 Qt
|
||||
- [ ] `cmake --preset msvc-debug` 成功(Qt+VTK 已拉取编译,首次较久)
|
||||
- [ ] `cmake --build` 出 exe
|
||||
- [ ] exe 能起一个空 Qt 窗 + 一个 `QVTKOpenGLStereoWidget` 渲染窗(冒烟测试)
|
||||
- [ ] 部署后 exe 目录只有一份 Qt6*.dll(无双 Qt)
|
||||
- [ ] `compile_commands.json` 生成,clangd 正常索引
|
||||
|
||||
---
|
||||
|
||||
## 10. 与设计文档对应的 spike 门槛
|
||||
|
||||
本指引服务于设计 §15 的第一周 spike:① 全 vcpkg 构建/部署打通(本文);② ADS + `QVTKOpenGLStereoWidget` 浮动/重停靠不黑屏;③ 真实样本跑通 banded contour。三者通过再进入完整实现计划。
|
||||
|
||||
---
|
||||
|
||||
*遇到具体报错(VTK/Qt/GDAL 链接、ADS 端口、双 Qt)按规约 §10.4 由工程师复核;AI 协助按 build-error-resolver 流程逐条解决。*
|
||||
Binary file not shown.
|
|
@ -0,0 +1,443 @@
|
|||
# Geopro 3.0 桌面客户端技术选型与架构规约
|
||||
|
||||
**版本 v1.1** · 适用范围:Geopro 3.0 桌面版「项目分析视图」首版及后续演进
|
||||
|
||||
---
|
||||
|
||||
## 1. 文档概述
|
||||
|
||||
### 1.1 目的
|
||||
|
||||
本文档为 Geopro 3.0 桌面客户端的技术选型结论、技术栈与依赖库规约、界面组件规约、配置与缓存规约、动态升级规约、许可证合规要求,以及面向 AI 辅助编码的工程实践规约。文档作为开发团队的技术基线,后续编码、依赖引入、架构设计均应以本文档为准。
|
||||
|
||||
### 1.2 适用范围
|
||||
|
||||
首版(v1)聚焦于「项目分析视图」这一核心页面,即包含对象列表、二维/三维地图、数据集列表、数据集详情等板块的多面板工作台。启动登录、项目管理、设备连接、平台后台、Web 端等模块不在首版范围内,但本文档的技术选型已为其后续演进预留了架构空间。
|
||||
|
||||
### 1.3 读者对象
|
||||
|
||||
项目技术负责人、架构师、开发团队,以及负责许可证与商务合规审查的相关人员。
|
||||
|
||||
### 1.4 重要约定
|
||||
|
||||
> **关于编码方式的前提**
|
||||
> 本项目开发团队 100% 依赖 AI 辅助编码(Claude Code)完成实现。这一前提显著影响了选型逻辑:传统意义上「某语言开发更快」的人力效率差异在 AI 编码下被大幅抹平,因此选型回归到软件本身的长期质量属性——性能上限、部署形态、可维护性、生态契合度、代码资产保护。
|
||||
> 本文档不包含任何代码实现,仅规定技术方向、依赖边界与工程约束。
|
||||
|
||||
---
|
||||
|
||||
## 2. 功能范围概要
|
||||
|
||||
本章为桌面客户端功能的概要清单,仅作范围界定,每项一句话;详细需求以需求文档与原型为准。
|
||||
|
||||
### 2.1 客户端基础能力
|
||||
|
||||
| 功能 | 概要 |
|
||||
|---|---|
|
||||
| 启动 / 登录 | 用户登录与启动画面展示。 |
|
||||
| 工作空间切换 | 在企业空间与个人空间之间切换。 |
|
||||
| 项目列表 / 选择 | 浏览并进入当前空间下的项目。 |
|
||||
| 平台通知 | 接收平台推送的消息。 |
|
||||
| 个人资料 / 登录状态 | 查看个人信息与登录状态管理。 |
|
||||
| 偏好设置 | 配置客户端的本地偏好。 |
|
||||
| 在线更新 | 检测并升级客户端版本。 |
|
||||
|
||||
### 2.2 项目分析视图(核心工作台)
|
||||
|
||||
| 功能 | 概要 |
|
||||
|---|---|
|
||||
| 对象列表 | 展示并管理项目下的对象。 |
|
||||
| 数据集列表 | 展示当前对象下的数据集。 |
|
||||
| 二维视图 | 在地图底图上展示对象与数据集的平面视图。 |
|
||||
| 三维视图 | 以三维形式展示剖面、切片、模型等数据。 |
|
||||
| 对象属性 / 异常 | 查看对象属性,管理异常与异常体。 |
|
||||
| 数据集属性 / 任务 | 查看数据集属性及其处理任务。 |
|
||||
| 数据集详情 | 集中展示数据集的详情内容。 |
|
||||
|
||||
> **范围说明**:首版(v1)交付范围为「项目分析视图」及其依赖的客户端基础能力。数据集在二维/三维视图中能否显示及显示方式,均由其 dd 类型定义;各板块间的联动(对象勾选驱动视图刷新、列表与详情定位)构成该视图的主要复杂度。
|
||||
|
||||
---
|
||||
|
||||
## 3. 目标平台与最低版本
|
||||
|
||||
### 3.1 最低系统版本
|
||||
|
||||
| 平台 | 最低版本 | 说明 |
|
||||
|---|---|---|
|
||||
| **Windows** | **Windows 10 64 位(22H2)** | 仅支持 64 位;仅限 Win10 最终功能版本 22H2,不兼容更早版本。 |
|
||||
| **macOS** | **macOS 12 Monterey** | Apple 用户升级积极,支持过老版本收益极低;如目标用户机器较新可提至 macOS 13。 |
|
||||
|
||||
### 3.2 版本约束链条
|
||||
|
||||
- **Qt 锁定 6.8 LTS**:该版本同时覆盖上述两端最低版本,并提供五年长期支持,与产品生命周期匹配。
|
||||
- **Windows 10 与 Qt 版本上界绑定**:Qt 6.12 为最后一个支持 Windows 10 的版本;在仍需支持 Win10 的周期内,Qt 不得升级越过 6.12。
|
||||
- **Windows 10 现状**:微软已于 2025 年 10 月终止 Win10 支持(消费者 ESU 延至 2026 年 10 月),但行业现场作业机器存量大,首版保留支持;路线图中应明确未来某大版本起转向 Windows 11-only,届时方可解锁 Qt 6.12 以上版本。
|
||||
- **编译器**:Windows 侧 MSVC 2022,macOS 侧对应较新 Xcode/Clang;语言标准 C++17(可渐进使用 C++20 特性)。
|
||||
|
||||
### 3.3 macOS 专项约束与风险
|
||||
|
||||
- **构建为 Universal Binary(arm64 + x86_64),优先保证 arm64 原生**:Mac 已全面转向 Apple Silicon 且 Intel 支持临近终止;VTK 重渲染负载经 Rosetta 转译损失可观,所有依赖须具备 arm64 构建。
|
||||
- **OpenGL 废弃风险(挂入风险清单)**:Apple 已废弃 OpenGL(停留 4.1)并主推 Metal,而 VTK 默认渲染后端为 OpenGL;短期可用,长期须持续跟踪 VTK 的 Metal/WebGPU 后端成熟度。
|
||||
|
||||
---
|
||||
|
||||
## 4. 技术选型决策
|
||||
|
||||
### 4.1 选型结论
|
||||
|
||||
桌面客户端采用 **Qt(C++)+ VTK(C++)** 作为核心技术栈。
|
||||
|
||||
核心依据:Geopro 3.0 桌面客户端在本质上是一款科学可视化软件,其数据类型(电法、地质雷达、地震、磁法、电磁、钻探等)与可视化范式(剖面、切片、点云、三维属性模型、三维结构模型、地图叠加)与 ParaView、QGIS、3D Slicer、地质/油气勘探软件属于同一谱系。这一谱系的行业标准技术栈即为 Qt + VTK 的 C++ 实现。
|
||||
|
||||
### 4.2 关键质量属性与选型对应
|
||||
|
||||
| 质量属性 | 说明 | Qt C++ + VTK 的契合度 |
|
||||
|---|---|---|
|
||||
| 大数据渲染上限 | 三维地震体、亿级 LiDAR 点云、电法全波形等大体量数据的流畅交互 | **最高,可直接调用 OpenGL/并行,无 WebGL 天花板** |
|
||||
| 专业可视化表达 | 色阶、图例、切片、等值面、glyph、标注的精细控制 | VTK 原生能力最完整 |
|
||||
| 设备集成深度 | 厂商设备 SDK 多为 C/C++ 动态库,需直接链接 | 同语言直链,无桥接层 |
|
||||
| 桌面工作流 | 多窗口、停靠面板、拖拽、快捷键、文件关联、打印 | Qt 提供原生桌面体验 |
|
||||
| 代码资产保护 | 反演算法、设备协议等核心资产的反编译防护 | 编译产物逆向门槛高 |
|
||||
| 部署形态 | 安装包体积、运行时依赖、跨平台一致性 | 单一原生可执行,依赖可控 |
|
||||
|
||||
### 4.3 备选方案及其适用条件
|
||||
|
||||
| 备选方案 | 唯一应当选用的条件 | 当前是否命中 |
|
||||
|---|---|---|
|
||||
| PySide6 + VTK(Python) | 团队重度依赖 Python 地球物理算法生态(如 SimPEG、ResIPy、ObsPy 等),且不希望承担跨语言桥接成本 | 取决于算法语言,见 4.4 |
|
||||
| Electron + vtk.js | 数据规模长期稳定在中等水平、不触及 WebGL 上限,且对跨平台 UI 一致性与启动体验有极高要求 | **未命中** |
|
||||
|
||||
> **关于 PySide6 的补充说明**:PySide6 与 Qt C++ 共享同一套底层 Qt 引擎,UI 渲染与 VTK 渲染性能几乎无差异,API 亦近乎一一对应。两者的真实差异在于:算法生态(Python 占优)、部署体积(C++ 占优)、代码保护(C++ 占优)。若后续确有强 Python 算法依赖,推荐的折中路径是:主框架保持 Qt C++,将 Python 算法以「进程隔离」方式接入(见第 8 章动态升级中的插件架构),而非整体改用 PySide6。
|
||||
|
||||
### 4.4 待确认的关键前提
|
||||
|
||||
本选型结论成立的关键前提是反演与数据处理算法的语言归属,需在开发启动前确认:
|
||||
|
||||
- **若算法为自研 C++ 或计划用 C++ 实现** —— Qt C++ + VTK C++ 形成完美闭环,无需跨语言。
|
||||
- **若算法重度依赖 Python 生态**(注:ResIPy 反演框架本身即为 Python 包)—— 应采用进程隔离架构接入 Python 算法,主框架仍为 Qt C++。
|
||||
- **两者并存** —— 主框架 Qt C++,C++ 算法内嵌,Python 算法经进程隔离接入。
|
||||
|
||||
---
|
||||
|
||||
## 5. 技术栈与依赖库规约
|
||||
|
||||
「必选」为项目基线,「推荐」依据实际需求引入。所有第三方依赖须经第 9 章许可证矩阵审查后方可正式引入。
|
||||
|
||||
### 5.1 框架内核
|
||||
|
||||
| 项 | 选用 | 说明 |
|
||||
|---|---|---|
|
||||
| **框架** | **Qt 6.5/6.8 LTS** | 采用 Qt 6 LTS;不使用 Qt 5。UI 主框架采用 QtWidgets,不采用 QML 作为主框架。 |
|
||||
| 核心模块 | QtCore/Gui/Widgets | 对象系统、信号槽、控件体系。 |
|
||||
| 网络模块 | QtNetwork/WebSockets | REST 通信与设备实时数据流、平台通知推送。 |
|
||||
| 数据库模块 | QtSql | SQLite 访问抽象层。 |
|
||||
| 并发模块 | QtConcurrent | 耗时任务线程池。 |
|
||||
| Web 嵌入 | QtWebEngine | 后续嵌入 Web 端页面(设备管理、企业大屏、报告预览等)。 |
|
||||
| 设备串口 | QtSerialPort | 串口设备通信。 |
|
||||
| 国际化 | Qt Linguist(内置) | 中英文双语。 |
|
||||
|
||||
> **Qt 许可证须优先决策**:Qt 提供 LGPLv3 / GPLv3 / 商业授权。闭源商用若走 LGPLv3,须严格动态链接并允许用户替换 Qt 库;部分模块(QtWebEngine、QtCharts)限制不同。此为商务与法务问题,优先级高于技术实现。
|
||||
|
||||
### 5.2 三维可视化
|
||||
|
||||
| 项 | 选用 | 说明 |
|
||||
|---|---|---|
|
||||
| **渲染核心** | **VTK 9.3+** | 经 QVTKOpenGLNativeWidget 集成进 Qt;需协调 VTK 交互器与 Qt 事件循环。 |
|
||||
| 体绘制 | VTK Volume 模块 | 三维属性模型(dd_Property3D)所需。 |
|
||||
| 切片/等值面 | VTK Filters 模块 | 水平切片、任意角度切片、isosurface。 |
|
||||
| 点云高级处理 | PCL(推荐) | 如需 KD-tree 加速、配准、分割;仅显示则 VTK 自带即可。 |
|
||||
|
||||
### 5.3 二维地图
|
||||
|
||||
| 方案 | 定位 | 说明 |
|
||||
|---|---|---|
|
||||
| **VTK 一统(首选)** | **首版采用** | 二维视图为相机俯视锁定的 VTK 渲染;底图作地面纹理,矢量对象用 VTK actor 渲染。二维/三维共享对象、色阶与坐标系。底图瓦片经 GDAL/网络层下载缓存。 |
|
||||
| MapLibre Native | 备选 | BSD 许可,矢量瓦片支持完整。若 VTK 二维地图交互体验达不到预期,作为独立二维引擎并列。 |
|
||||
| QGIS Core 嵌入 | 谨慎 | GIS 能力最强,但依赖复杂且 GPL 许可,闭源商用须高度谨慎。 |
|
||||
|
||||
### 5.4 构建与依赖管理
|
||||
|
||||
| 项 | 选用 | 说明 |
|
||||
|---|---|---|
|
||||
| **构建系统** | **CMake 3.21+** | Qt 6 官方推荐;不采用 qmake。 |
|
||||
| 包管理 | vcpkg(推荐) | 统一管理依赖,严禁手动管理(手动依赖降低 AI 编码上下文准确度)。Conan 备选。 |
|
||||
| 编译数据库 | compile_commands.json | 供 clangd、静态分析与 AI 工具获取完整上下文。 |
|
||||
|
||||
### 5.5 网络与通信
|
||||
|
||||
| 项 | 选用 | 说明 |
|
||||
|---|---|---|
|
||||
| **HTTP/REST** | QtNetwork | 与 Qt 事件循环原生集成。 |
|
||||
| 实时通信 | QtWebSockets | 在线监测数据流、设备状态、平台推送。 |
|
||||
| JSON | nlohmann/json(推荐) | 现代 C++ JSON 库,header-only。 |
|
||||
| 大数据传输 | FlatBuffers / Protobuf(推荐) | 三维数据、点云等大体量下载远优于 JSON。 |
|
||||
| 客户端代码生成 | openapi-generator(推荐) | 若 Web 端有 OpenAPI 文档,生成 C++ DTO。 |
|
||||
|
||||
### 5.6 数据存储
|
||||
|
||||
| 项 | 选用 | 说明 |
|
||||
|---|---|---|
|
||||
| **结构化数据库** | **SQLite(QtSql)** | 项目本地缓存、对象/数据集元数据、关系索引、操作历史。 |
|
||||
| 大文件存储 | HDF5 / VTK 原生格式 | 严禁大二进制以 BLOB 入 SQLite;「元数据进库、大文件进文件系统」。 |
|
||||
| 轻量封装 | SQLiteCpp(可选) | 简化访问。 |
|
||||
|
||||
配置与缓存的存储归属另见第 7 章,与 SQLite 职责严格区分。
|
||||
|
||||
### 5.7 数学与算法库
|
||||
|
||||
| 项 | 选用 | 说明 |
|
||||
|---|---|---|
|
||||
| **线性代数** | **Eigen** | C++ 数值计算事实标准。 |
|
||||
| 坐标系/投影 | PROJ(推荐) | WGS84/UTM/本地坐标系转换,必备。 |
|
||||
| 地理数据 I/O | GDAL/OGR(推荐) | 支撑 dd_KML/dd_GeoJson/dd_shp/dd_dem 导入。 |
|
||||
| 几何运算 | GEOS | 多边形相交、缓冲、空间关系。 |
|
||||
| 点云 I/O | PDAL(推荐) | LAS/LAZ 等;LiDAR 必备。 |
|
||||
| 通用工具 | fmt | 字符串格式化。 |
|
||||
| 按需子库 | Boost(按需) | 不默认全量引入。 |
|
||||
|
||||
### 5.8 文件格式与导入导出
|
||||
|
||||
| 需求 | 选用 | 说明 |
|
||||
|---|---|---|
|
||||
| GIS 矢量/栅格/DEM | GDAL/OGR | KML、GeoJSON、Shapefile、GeoTIFF、DEM。 |
|
||||
| BIM(IFC) | IfcOpenShell | dd_bim 解析。 |
|
||||
| 地震 SEG-Y | libsegyio(按需) | 直接读 SEG-Y。 |
|
||||
| Excel 报告 | OpenXLSX / libxlsxwriter | 读写 Excel。 |
|
||||
| Word/PPT 报告 | 模板填充方案待定 | 无理想 C++ 库;LibreOffice headless 或外部服务。 |
|
||||
| DWG/DXF 报告 | libDXFrw(DXF) | DWG 完整支持需商业库或 GPL 的 LibreDWG,须审查许可证。 |
|
||||
| PDF 报告 | QPdfWriter / PoDoFo | 简单用 Qt 自带,复杂版面用 PoDoFo。 |
|
||||
| 报表引擎 | LimeReport(可选) | 复杂模板可选用。 |
|
||||
|
||||
### 5.9 设备通信
|
||||
|
||||
| 类型 | 选用 | 说明 |
|
||||
|---|---|---|
|
||||
| 串口 | QtSerialPort | Qt 官方串口模块。 |
|
||||
| USB / HID | libusb / hidapi | USB 与 HID 设备。 |
|
||||
| 工业总线 | libmodbus(按需) | Modbus 设备。 |
|
||||
| 厂商 SDK | C++ 直接链接 | 厂商动态库直链,无桥接层。 |
|
||||
|
||||
### 5.10 日志、监控与测试
|
||||
|
||||
| 项 | 选用 | 说明 |
|
||||
|---|---|---|
|
||||
| **日志** | **spdlog** | 结构化、分级、滚动文件;禁止 qDebug 作生产日志。 |
|
||||
| 崩溃监控 | Sentry C++ / Crashpad | 自动采集崩溃栈;数据安全要求高则自有服务器上报。 |
|
||||
| 单元测试 | Qt Test + Google Test | Qt Test 测 UI/Qt 相关,gtest 测纯业务。 |
|
||||
| Mock | Google Mock / trompeloeil | 配合测试框架。 |
|
||||
| 静态分析 | clang-tidy + cppcheck | 强制纳入 CI。 |
|
||||
| Sanitizers | ASan/UBSan/TSan | Debug 构建启用。 |
|
||||
|
||||
### 5.11 安全
|
||||
|
||||
| 项 | 选用 | 说明 |
|
||||
|---|---|---|
|
||||
| **传输/加密** | **OpenSSL** | HTTPS、JWT、签名校验;Windows 须随包分发。 |
|
||||
| 现代加密 | libsodium(可选) | X25519/ChaCha20-Poly1305/Argon2。 |
|
||||
| 凭证存储 | QtKeychain(推荐) | 对接三平台密钥库;凭证严禁明文存储。 |
|
||||
|
||||
---
|
||||
|
||||
## 6. 界面组件规约
|
||||
|
||||
Qt C++ 的 UI 组件生态不如前端繁荣,因 QtWidgets 本身已是完整组件库,第三方库多为「补充特定缺失」。
|
||||
|
||||
### 6.1 UI 技术路线
|
||||
|
||||
主框架采用 **QtWidgets**,不采用 QML 作为主框架。IDE 风格「窗口 + 菜单 + 停靠面板」工作台正是 QtWidgets 的设计本位;QML 可局部用于色阶编辑器等视觉化小组件。
|
||||
|
||||
### 6.2 停靠布局框架(核心)
|
||||
|
||||
| 框架 | 定位 | 说明 |
|
||||
|---|---|---|
|
||||
| **Qt-Advanced-Docking-System (ADS)** | **首选** | 体验接近 Visual Studio;LGPL v2.1,商用友好。 |
|
||||
| KDDockWidgets | 备选 | KDAB 出品,质量顶级;GPL/商业双授权,闭源商用须购买。 |
|
||||
|
||||
布局/透视图状态序列化后与 QSettings 配合持久化。该框架须早期确定并据此设计窗口架构。
|
||||
|
||||
### 6.3 主题与外观
|
||||
|
||||
| 项 | 选用 | 说明 |
|
||||
|---|---|---|
|
||||
| **皮肤机制** | **QSS(内置)** | Qt 样式表,零依赖。 |
|
||||
| 现成主题打底 | QDarkStyleSheet / BreezeStyleSheets | 成熟深色主题,套用后按品牌定制。科学软件主流为深色主题。 |
|
||||
| 终极定制 | 自定义 QStyle | 一般不必。 |
|
||||
|
||||
### 6.4 专业控件与图标
|
||||
|
||||
| 需求 | 选用 | 说明 |
|
||||
|---|---|---|
|
||||
| **图标** | **QtAwesome** | 图标字体,矢量、可染色、随主题变色。 |
|
||||
| 科学曲线 | QCustomPlot / QWT | 测井曲线、时序监测曲线。QWT 商用友好;QCustomPlot 有商业版。 |
|
||||
| 脚本编辑器 | QScintilla(按需) | 「电法脚本与装置」编辑;注意许可证。 |
|
||||
| 节点管线编辑 | QtNodes(按需) | 「数据→模型→输出」可视化连线。 |
|
||||
| 属性表单 / 色阶编辑器 | 自研 | 「按对象类型动态生成表单」「多模态显示」「色阶命名保存」需高度定制;色阶可基于 VTK 颜色传递函数构建。 |
|
||||
|
||||
---
|
||||
|
||||
## 7. 配置与缓存管理规约
|
||||
|
||||
核心原则:**按「数据的生命周期与归属」分类存储**。Qt 原生能力基本覆盖,无需第三方库(QtKeychain 除外)。
|
||||
|
||||
### 7.1 路径定位基础
|
||||
|
||||
所有本地落盘路径一律经 **QStandardPaths** 获取平台规范目录,严禁手动拼接。须严格区分 AppConfigLocation(配置)、CacheLocation(可丢弃缓存)、AppDataLocation(持久数据)、DocumentsLocation(用户导出)、TempLocation(临时)。缓存目录被清空时应用必须能正常重建。
|
||||
|
||||
### 7.2 配置管理
|
||||
|
||||
- 用户偏好(主题、字体、启动停留时间、默认大屏等)→ **QSettings**。
|
||||
- 窗口几何与停靠布局状态 → 序列化后存入 QSettings,与 ADS 配合。
|
||||
- 为支持绿色部署,Windows 可强制 QSettings 使用 INI 格式而非注册表。
|
||||
- **项目级业务设置(坐标系、底图、异常类型、自动任务、告警级别等)严禁使用 QSettings**,因其属「项目数据」,须跟随项目存储(SQLite 或项目目录文件)以便整体导出、迁移与共享;复杂嵌套配置采用 JSON(nlohmann/json)。
|
||||
|
||||
### 7.3 缓存管理
|
||||
|
||||
| 缓存类型 | 选用 | 说明 |
|
||||
|---|---|---|
|
||||
| 内存缓存 | QCache / QPixmapCache | 容量上限 + LRU 淘汰;解析后对象、缩略图。 |
|
||||
| 网络/瓦片缓存 | QNetworkDiskCache | 按 HTTP 缓存语义自动缓存 REST 响应与地图瓦片。 |
|
||||
| 大文件缓存 | 文件系统 + SQLite 索引 | 大二进制存文件系统,元数据与淘汰索引存 SQLite;自行实现按大小/LRU 淘汰。 |
|
||||
|
||||
### 7.4 安全凭证
|
||||
|
||||
需持久化的 token/凭证严禁明文存入 QSettings 或 SQLite,一律经 **QtKeychain** 存入平台密钥库。
|
||||
|
||||
### 7.5 存储归属总表
|
||||
|
||||
| 数据类型 | 存储位置 | 理由 |
|
||||
|---|---|---|
|
||||
| 用户偏好 | QSettings | 少量键值,跟随用户/机器 |
|
||||
| 窗口几何、停靠布局 | QSettings(字节数组) | Qt 序列化直接支持 |
|
||||
| 项目业务设置 | SQLite / 项目文件 | 属项目数据,须随项目导出 |
|
||||
| 对象/数据集元数据、关系、索引 | SQLite | 需查询、关联、事务 |
|
||||
| 操作历史、任务记录 | SQLite | 结构化、需查询 |
|
||||
| 内存中间数据、缩略图 | QCache / QPixmapCache | 临时、带淘汰 |
|
||||
| REST 响应、地图瓦片 | QNetworkDiskCache | HTTP 缓存语义、可丢弃 |
|
||||
| 大文件(地震/点云/原始数据) | 文件系统 + SQLite 索引 | 大二进制不入库 |
|
||||
| token / 凭证 | QtKeychain(密钥库) | 安全要求 |
|
||||
|
||||
---
|
||||
|
||||
## 8. 动态升级规约
|
||||
|
||||
结合业务特征(算法模型、设备驱动、报告模板需独立更新),采用三通道更新架构。
|
||||
|
||||
### 8.1 三通道更新架构
|
||||
|
||||
| 通道 | 对象 | 更新频率 / 生效方式 |
|
||||
|---|---|---|
|
||||
| **通道一:应用本体** | 主程序、核心库 | 低频 / 重启生效。差分整包更新。 |
|
||||
| **通道二:算法插件** | 反演、处理等算法模型 | 中高频 / 进程隔离,替换插件文件后下次调用生效,不影响主程序。 |
|
||||
| **通道三:资源数据** | 报告模板、设备驱动、配置 | 高频 / 从平台 API 按需同步,无需重启。 |
|
||||
|
||||
### 8.2 通道一:应用本体更新
|
||||
|
||||
自实现差分更新流程,统一三平台逻辑并自主控制下载源:
|
||||
|
||||
1. 客户端定期向更新服务器请求版本清单(manifest)。
|
||||
2. 比对版本,下载差分包或整包至临时目录。
|
||||
3. 校验数字签名与哈希,全部通过后方可替换。
|
||||
4. 由独立的 updater 进程在主程序退出后完成文件替换,再重启主程序。
|
||||
|
||||
差分库推荐 HDiffPatch 或 zstd patch-from。
|
||||
|
||||
**必须守住的工程约束:**
|
||||
|
||||
- **文件占用**:运行中的可执行文件无法被覆盖(Windows 尤甚),须由独立 updater 进程在主程序退出后替换。
|
||||
- **原子性**:校验全部通过后一次性替换;失败可回滚(旧版本重命名或双目录指向切换)。
|
||||
- **签名验证**:更新包以离线私钥签名,客户端内置公钥验证;私钥严禁进入代码库。
|
||||
- **灰度与回滚**:manifest 支持灰度比例;客户端记录上一可用版本,升级后启动失败可自动回滚。
|
||||
- **强制更新**:manifest 标记最低支持版本,低于此版本强制升级。
|
||||
|
||||
### 8.3 通道二:算法插件架构
|
||||
|
||||
算法插件采用**进程隔离架构**:每个算法为独立子程序,主程序经本地 socket / 共享内存与之通信。理由:
|
||||
|
||||
- 崩溃隔离:科学计算易因数值问题崩溃,隔离后不拖垮主程序。
|
||||
- 语言无关:插件可用 C++、Python、Rust 等任意语言实现,不受 C++ ABI 约束(直接支撑 ResIPy 等 Python 算法接入)。
|
||||
- 更新简单:替换子程序文件即完成更新,不影响主程序。
|
||||
- 可并行、可做资源限制。
|
||||
|
||||
> **ABI 兼容性提示**:若未来确有同进程 C++ 插件需求(Qt Plugin 机制),主程序与插件必须使用兼容编译器、相同 C++ 运行时与相同 Qt 版本编译,且插件接口仅暴露 C ABI 兼容类型。进程隔离架构从根本上规避了这一整类问题,故为首选。
|
||||
|
||||
### 8.4 统一版本清单
|
||||
|
||||
三通道由统一 manifest 描述,至少包含:应用本体的版本号、最低支持版本、下载地址、差分基线、签名;各算法插件的版本与哈希;各设备驱动与模板的版本与地址。
|
||||
|
||||
---
|
||||
|
||||
## 9. 许可证合规矩阵
|
||||
|
||||
> **强制要求**:C++ 依赖的许可证直接决定能否闭源商用。AI 编码工具不会主动提示许可证风险,须由人工管理。所有依赖正式引入前须经法务复核,并随项目维护更新。
|
||||
|
||||
| 依赖 | 许可证 | 闭源商用 | 备注 |
|
||||
|---|---|---|---|
|
||||
| Qt 6 | LGPLv3 / 商业 | ⚠️ 需决策 | LGPL 须动态链接;或购商业授权 |
|
||||
| VTK | BSD | ✅ 友好 | 宽松许可 |
|
||||
| Eigen | MPL2 | ✅ 友好 | |
|
||||
| GDAL / PROJ / GEOS | MIT / X11 类 | ✅ 友好 | |
|
||||
| PDAL | BSD | ✅ 友好 | |
|
||||
| PCL | BSD | ✅ 友好 | |
|
||||
| nlohmann/json | MIT | ✅ 友好 | |
|
||||
| spdlog / fmt | MIT | ✅ 友好 | |
|
||||
| OpenSSL | Apache 2.0 | ✅ 友好 | 1.1.1 起为 Apache 2.0 |
|
||||
| QtKeychain | BSD | ✅ 友好 | |
|
||||
| ADS(停靠框架) | LGPL v2.1 | ✅ 友好 | 动态链接 |
|
||||
| KDDockWidgets | GPL / 商业 | ⚠️ 需购授权 | 闭源商用须购买 |
|
||||
| QWT | QWT License(LGPL 变体) | ✅ 友好 | |
|
||||
| QCustomPlot | GPL / 商业 | ⚠️ 需购授权 | 有商业版 |
|
||||
| QScintilla | GPL / 商业 | ⚠️ 需购授权 | 须审查 |
|
||||
| QGIS Core | GPL | ❌ 高风险 | 嵌入可能要求开源,慎用 |
|
||||
| LibreDWG | GPL | ❌ 高风险 | DWG 需求建议另寻方案 |
|
||||
| HDiffPatch | MIT 类 | ✅ 友好 | 差分更新 |
|
||||
|
||||
---
|
||||
|
||||
## 10. 面向 AI 编码的工程实践规约
|
||||
|
||||
团队 100% 依赖 Claude Code 编码,以下为强制规约。
|
||||
|
||||
### 10.1 代码与上下文基础设施
|
||||
|
||||
- **clang-format**:强制统一代码风格,约束 AI 输出风格漂移。
|
||||
- **clangd LSP + .clangd 配置**:为 AI 工具提供精确类型信息。
|
||||
- **compile_commands.json**:由 CMake 生成,提供完整依赖上下文。
|
||||
- **cmake-format**:CMake 文件亦统一格式。
|
||||
|
||||
### 10.2 质量兜底
|
||||
|
||||
- **clang-tidy + cppcheck 纳入 CI**:捕获 AI 易产生的冗余拷贝、生命周期与反模式问题。
|
||||
- **Debug 构建启用 Sanitizers(ASan/UBSan/TSan)**:兜底未定义行为与数据竞争。
|
||||
- **跨平台 CI(Windows/macOS)**:平台相关逻辑(文件占用、.app bundle、权限)须显式封装并提醒 AI 处理差异。
|
||||
- **失败路径测试**:AI 易只写正常路径;更新中断、签名错误、替换失败等失败分支须明确要求覆盖。
|
||||
|
||||
### 10.3 架构与规范约束
|
||||
|
||||
- **清晰分层目录**:core(纯业务,不依赖 Qt)/ data(数据访问)/ view(视图)/ controller(控制)/ app(入口装配)。
|
||||
- **架构规约文档供 AI 读取**:明确诸如「VTK actor 统一由视图模型管理,禁止 Widget 直接持有」「信号槽连接集中于初始化方法」等约束。
|
||||
- **强类型与文档注释**:public API 强制 Doxygen 注释。
|
||||
- **严格锁定依赖版本**:经 vcpkg/Conan 锁版本,避免 AI 在不同版本 API 间混用。
|
||||
- **私钥与密钥不入库**:明确禁止 AI 将示例密钥写入代码;签名私钥离线保管。
|
||||
|
||||
### 10.4 须保留的人工角色
|
||||
|
||||
> AI 编码降低了「编写业务代码」的成本,但「构建、部署、工程化」的成本几乎不变。须保留至少一名具备 C++ 工程化能力的工程师,负责构建系统、依赖管理、跨平台打包,以及对 CMake、打包脚本等 AI 输出不稳定产物的复核。
|
||||
|
||||
---
|
||||
|
||||
## 11. 待决策事项汇总
|
||||
|
||||
| 编号 | 事项 | 影响 |
|
||||
|---|---|---|
|
||||
| D-1 | **反演/处理算法的语言归属** | 决定是否需进程隔离接入 Python 算法,以及是否动摇 Qt C++ 主框架的最终成立(见 4.4)。 |
|
||||
| D-2 | **Qt 许可证:LGPL 严格动态链接 vs 购买商业授权** | 商务与合规前提,优先级高于技术实现(见 5.1)。 |
|
||||
| D-3 | 首版是否即建立完整插件架构,或先硬编码少数算法、后续再抽象 | 影响 v1 工作量与架构投入(见 8.3)。 |
|
||||
| D-4 | 算法插件是否需支持第三方/客户自行开发 | 进一步强化进程隔离的必要性。 |
|
||||
| D-5 | 二维地图首版采用 VTK 一统是否满足交互体验预期 | 若不满足则引入 MapLibre Native(见 5.3)。 |
|
||||
| D-6 | 全部第三方依赖的许可证法务复核 | 决定可否闭源商用(见第 9 章)。 |
|
||||
| D-7 | Word/PPT 报告的生成方案 | 目前无理想 C++ 库,须确定模板填充路径(见 5.8)。 |
|
||||
| D-8 | 目标客户中 Windows 10 机器的实际占比 | 决定首版是否保留 Win10 支持,或直接 Windows 11-only 以解除 Qt 版本上界束缚(见第 3 章)。 |
|
||||
|
||||
---
|
||||
|
||||
*本文档由技术选型讨论整理而成,作为开发基线;随项目推进应持续维护版本。*
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 101 KiB |
|
|
@ -0,0 +1,359 @@
|
|||
# Geopro 3.0 桌面客户端 — M1 架构设计
|
||||
|
||||
**日期**:2026-06-07
|
||||
**版本**:v2(已按双专家评审 + 数据核验修订;修订点见 §16)
|
||||
**状态**:待用户复核 v2
|
||||
**范围**:M1 里程碑 = 完整工作台外壳 + 登录功能 + 三维视图(基础渲染 / dd_voxel 体绘制与切片 / DEM 地形)
|
||||
**上位文档**:`docs/Geopro3.0_技术选型与架构规约.md`(技术基线,本文遵从其全部约束)
|
||||
|
||||
---
|
||||
|
||||
## 1. 目标与范围
|
||||
|
||||
### 1.1 M1 交付目标
|
||||
|
||||
复刻 Geopro 3.0 最核心的「项目分析视图」桌面版,并把登录做实:
|
||||
|
||||
1. **登录功能完全可用**:真实连接生产后端(`pop-api`),走验证码 + RSA 加密密码流程,token 安全存储。登录页样式参考现有 web 系统。
|
||||
2. **完整工作台外壳**:ADS 三区停靠布局,还原原型(左:对象树 + 数据集列表;中:2D/3D 视图 + 数据详情;右:异常列表/对象属性 + 属性)。
|
||||
3. **三维视图**(M1 核心难点):
|
||||
- ① 基础渲染:剖面散点、网格等值面/等值线/标注、异常圈定(直接渲染)
|
||||
- ② dd_voxel 体绘制 + 鼠标交互切片(dd_slice)——C++ 进程内三维插值;**追求可信体**(非演示性),故对输入数据有要求(见 §10、§13 分阶段)
|
||||
- ④ DEM 地形起伏 + 影像贴图
|
||||
- 二维俯视相机预设(验证「单一场景」架构)
|
||||
4. **业务数据来源**:登录联网;工作台业务数据 M1 用本地样本文件,经 Repository 抽象注入,未来无缝切 API。
|
||||
|
||||
### 1.2 不在 M1 范围
|
||||
|
||||
- ③ 雷达单/多通道渲染、⑤ 在线底图瓦片 → M1.5
|
||||
- 反演/数据处理算法本体(M1 只做「展示期插值」,不做反演)
|
||||
- 项目管理、设备连接、在线监测、报告、平台后台、Web 端
|
||||
- 完整算法插件架构(进程隔离 + manifest)→ 规约 D-3 推迟;M1 仅以 `IInterpolator` 接口预留
|
||||
- 在线更新三通道(规约 §8)
|
||||
- macOS 构建(M1 先 Windows / MSVC 2022,架构保持跨平台可移植)
|
||||
|
||||
---
|
||||
|
||||
## 2. 关键决策记录
|
||||
|
||||
| 编号 | 决策 | 结论 |
|
||||
|---|---|---|
|
||||
| K-1 | 2D/3D 视图架构 | **单一 VTK 三维场景 + 相机预设切换**;底图做可插拔 GroundLayer(规约 §5.3、D-5)。被现有 web「Cesium 单 3D 引擎」实践印证。 |
|
||||
| K-2 | 启动节奏 | 先出设计文档 → **spike 预研门槛** → 再写完整实现计划 |
|
||||
| K-3 | M1 外壳范围 | 完整工作台(A 方案) |
|
||||
| K-4 | 业务数据来源 | 登录走真实 API;业务数据本地样本 + Repository 抽象(B 方案) |
|
||||
| K-5 | M1 三维内容 | ① 基础 + ② dd_voxel(可信体,图分阶段)+ ④ DEM;③ 雷达、⑤ 底图瓦片留 M1.5 |
|
||||
| K-6 | 三维插值实现 | C++ 进程内(IDW 起步),`IInterpolator` 接口隔离、**返回 core 中立类型**;推迟完整插件架构(D-1/D-3) |
|
||||
| K-7 | 坐标系 | **每数据源各记源 CRS + 各自 LocalFrame** → 统一 rebase 到唯一「项目世界系(局部米,含 Z 基准)」;GIS/经纬/底图用 PROJ 实时换算(见 §5) |
|
||||
| K-8 | 构建/部署 | **全 vcpkg(方案 B)**:Qt 与 VTK[qt] 共用同一份 vcpkg Qt,规避双份 Qt DLL/ABI 冲突 |
|
||||
| K-9 | 视图 widget | 评估 **`QVTKOpenGLStereoWidget`(QOpenGLWidget 系)** 优先于 native,缓解 ADS reparent 上下文丢失(spike 验证) |
|
||||
| K-10 | dd_voxel 可信度 | 维持可信体目标;可信度取决于输入数据充分性(≥3 非共线剖面或 3D 网格),列为数据依赖(见 §10、§14) |
|
||||
|
||||
---
|
||||
|
||||
## 3. 分层架构与目录结构
|
||||
|
||||
遵循规约 §10.3 清晰分层(core / data / view / controller / app),细分 net、render。
|
||||
|
||||
```
|
||||
geopro/
|
||||
├─ CMakeLists.txt / CMakePresets.json / vcpkg.json
|
||||
├─ .clang-format / .clangd # AI 编码上下文基础设施(规约 §10.1)
|
||||
├─ cmake/ # Find 模块、打包、dll 部署
|
||||
├─ src/
|
||||
│ ├─ core/ # 纯业务,零 Qt / 零 VTK 依赖(可独立单测)
|
||||
│ │ ├─ model/ # Project, GsObject, TmObject, DsObject, Anomaly, ColorScale, Grid, ScatterField, ScalarVolume
|
||||
│ │ ├─ geo/ # LocalFrame(原点+Z基准+轴向)、CrsTransform(PROJ 封装,多 CRS)
|
||||
│ │ └─ algo/ # IInterpolator 接口 + IdwInterpolator(返回 core 的 ScalarVolume,绝不含 VTK)
|
||||
│ ├─ data/ # 数据访问层(异步契约)
|
||||
│ │ ├─ repo/ # IProjectRepository, IDatasetRepository(QFuture/回调 + 取消 + 分页)
|
||||
│ │ ├─ local/ # LocalSampleRepository(QtConcurrent 线程池跑解析)+ 各格式解析器
|
||||
│ │ ├─ api/ # ApiRepository(M1 骨架,签名对齐)
|
||||
│ │ └─ dto/ # 后端 JSON DTO + → model 映射
|
||||
│ ├─ net/ # ApiClient(QtNetwork)/ AuthService(验证码+RSA+login2)/ Credential(QtKeychain)
|
||||
│ ├─ render/ # VTK 渲染层(独占 vtkRenderWindow,统一管理所有 actor)
|
||||
│ │ ├─ Scene # 场景图、世界坐标空间、可见性;持有 RenderWindow
|
||||
│ │ ├─ actors/ # ScatterActor, GridContourActor, VoxelVolumeActor, AnomalyActor, TerrainActor
|
||||
│ │ ├─ color/ # ColorLutBuilder(colorBar → vtkLookupTable 离散阶梯), ScalarBar
|
||||
│ │ ├─ camera/ # CameraPreset(Top2D / Free3D)
|
||||
│ │ ├─ interact/ # InteractionManager + InteractionTool(MeasureTool/SliceTool/PickSelectTool)
|
||||
│ │ └─ ground/ # IGroundLayer + DemImageGroundLayer(M1);TileGroundLayer(M1.5 预留)
|
||||
│ ├─ view/ # QtWidgets 视图(被动;持有 VTK widget 外壳,不 new actor)
|
||||
│ │ ├─ login/ # LoginWindow(样式参考 web)
|
||||
│ │ ├─ panels/ # ObjectTreePanel, DatasetListPanel, MapViewPanel(QVTKOpenGLStereoWidget),
|
||||
│ │ │ # DataDetailPanel, AnomalyPanel, ObjectPropertyPanel, PropertyPanel
|
||||
│ │ └─ widgets/ # ColorScaleEditor, ToolbarBits
|
||||
│ ├─ controller/ # 联动编排(按交互闭环拆分,避免 God Object)
|
||||
│ │ ├─ SelectionController # 勾选/选中状态
|
||||
│ │ ├─ RenderSyncController # 状态→Scene 渲染同步
|
||||
│ │ └─ DetailSyncController # 列表↔详情↔视图定位三向联动
|
||||
│ └─ app/ # main / MainWindow(ADS 布局、主题)/ AppContext(DI 根)
|
||||
├─ resources/ # QSS 主题、QtAwesome、登录页素材
|
||||
├─ tests/ # gtest(core/data/algo)+ Qt Test(view/controller)
|
||||
└─ docs/
|
||||
```
|
||||
|
||||
**架构铁律(写入 .clangd 供 AI 读取)**:
|
||||
|
||||
- `core` 绝不 `#include` 任何 Qt / VTK 头(含 `IInterpolator`,返回 `core::ScalarVolume`)。
|
||||
- VTK actor / RenderWindow 一律由 `render` 层创建与持有;`view` 只持有 `QVTKOpenGLStereoWidget` 外壳,把其 interactor 注入 render,并将**拾取/交互事件回流**给 controller(见 §4.4),禁止直接 new actor。
|
||||
- 数据流双向已显式化:`view → render`(交互注入)与 `render → controller`(拾取/选择出站信号)。
|
||||
- 信号槽连接集中在各 `*Controller` / `MainWindow` 的 `wireUp()`。
|
||||
- 所有落盘路径经 `QStandardPaths`(规约 §7.1)。
|
||||
|
||||
---
|
||||
|
||||
## 4. 渲染核心:单一 VTK 场景(K-1)
|
||||
|
||||
### 4.1 Scene 与 RenderWindow 所有权
|
||||
|
||||
- `render::Scene` 持有**唯一** `vtkRenderWindow` + `vtkRenderer` + 项目世界坐标空间里的全部 actor,维护当前色阶与坐标系。
|
||||
- **单一 `QVTKOpenGLStereoWidget`**(K-9,QOpenGLWidget 系,FBO 合成、reparent 友好)承载渲染窗口,**不放进 Tab**;中央面板的「二维/三维」是工具栏上的模式切换,不是两个 widget。
|
||||
- view 仅持有该 widget 外壳;RenderWindow/Interactor 所有权归 render。
|
||||
|
||||
### 4.2 2D / 3D = 三要素组合
|
||||
|
||||
| 模式 | CameraPreset | InteractorStyle | 典型可见性 |
|
||||
|---|---|---|---|
|
||||
| 二维 | Top2D:正交投影、俯视、Z 锁定 | Locked2D:禁旋转,平移/缩放/正南正北 | 地面 + 平面要素 + 俯视散点/网格 |
|
||||
| 三维 | Free3D:透视、自由轨道 | Orbit3D:自由旋转/缩放/平移 | 全部 actor(体素、剖面、地形起伏) |
|
||||
|
||||
切换 = 切相机预设 + 交互器样式 + 工具集 + actor 可见性,**零数据重建**。
|
||||
|
||||
### 4.3 数据 → VTK 管线映射(已按评审修正)
|
||||
|
||||
| 数据类型 | 来源 | VTK 管线(修正后) | 备注 |
|
||||
|---|---|---|---|
|
||||
| 剖面散点 | 剖面原数据(2597 点) | `vtkPolyData`(verts) + `vtkLookupTable` 着色 | 图 #17 |
|
||||
| 网格等值面/线/标注 | 网格数据(规则栅格 x[100]×y[22],v[22][100],z 抬升) | **`vtkImageData`(origin+spacing)→(z 抬升用 `vtkWarpScalar`)→ `vtkDataSetSurfaceFilter`/`vtkGeometryFilter` → `vtkBandedPolyDataContourFilter`(开 `GenerateContourEdgesOn()` 一次产 banded 面+等值线,共用阈值)→ `vtkLabeledDataMapper` 标注** | 图 #18;**不可让 structured/image 直连 banded filter**(B-1) |
|
||||
| dd_voxel 体绘制 | 多剖面散点 → `IInterpolator` → `core::ScalarVolume` | `ScalarVolume` →(render 转)`vtkImageData` → `vtkGPUVolumeRayCastMapper` + 颜色/不透明度传递函数 | 图 #09;插值域受限(§10) |
|
||||
| dd_slice 切片 | voxel + 受控切面 | **`vtkResliceCursorWidget` / `vtkImageReslice`**(受控正交/任意切片),随相机模式启停 | 替代 `vtkImagePlaneWidget`(避免与交互器抢事件,M-2) |
|
||||
| 异常圈定 | 异常数据(markType 1点/2线/3面 + legend + z/elevation) | **按 markType 三条子管线**:点 `vtkGlyph3D`(pointShape)、线 polydata+dashed、面 `vtkPolygon`/`vtkTriangleFilter` 填充+边框;标注屏幕空间 billboard | legend 的 `*NoOpacity` 0–100 → 归一 [0,1];z 取值同剖面 Z 基准(§5) |
|
||||
| DEM 地形 + 影像 | dem.tif + image.tif + tfw(**可能异源 CRS**) | GDAL 读 → **PROJ/GDAL 重投影到项目世界 CRS** → `vtkImageData` → `vtkWarpScalar` 抬升 + 影像纹理 | 图 #05;影像实测为 EPSG:3857,须重投影(§5、M-1) |
|
||||
| 色阶 | colorBar:[值, 颜色] 阶梯 | `vtkLookupTable`(离散阶梯,取下界)+ `vtkScalarBarActor` | 见 §7 |
|
||||
|
||||
### 4.4 模态交互与拾取回流(M-2、B-3)
|
||||
|
||||
- `InteractionManager` 管理**模态工具**激活互斥与 VTK observer 优先级:`MeasureTool`、`SliceTool`、`PickSelectTool`。工具激活/退出负责其临时 actor 生命周期。
|
||||
- 3D Widget(切片)与自定义 InteractorStyle 共享同一 interactor,须显式管理 `SetEnabled()` 与事件优先级,避免抢事件。
|
||||
- **拾取回流通道**:`render` 拾取到对象 → 经 view 中转发出出站信号 → `DetailSyncController` → 列表/详情定位。此箭头在分层图中显式存在(§3)。
|
||||
|
||||
### 4.5 GroundLayer 可插拔
|
||||
|
||||
`IGroundLayer { build(Scene&); setVisible(bool); }`:M1 `DemImageGroundLayer`;M1.5 `TileGroundLayer`。若 VTK 贴瓦片体验差(D-5),可仅替换二维为 MapLibre 而不动 data/render 的 actor 体系。
|
||||
|
||||
---
|
||||
|
||||
## 5. 坐标系设计(K-7,评审最大短板,已重写)
|
||||
|
||||
数据现实(已核验真实样本):
|
||||
|
||||
- 剖面/网格/异常:GIS 投影 **EPSG:32649(UTM 49N)**,`projectX`≈516868=**Easting**,`projectY`≈2494259=**Northing**;另带局部米 `xlist/ylist`(各数据集自原点起算)。
|
||||
- 影像 `image.tfw`:原点 (12708343, 2577685) = **EPSG:3857(Web 墨卡托)**,与剖面**不同投影**。
|
||||
- 网格另带 `elevation[100]` / `lat/lon`(经纬度,EPSG:4326)。
|
||||
- API 几何 `tm/geometry/get` 返回 **EPSG:4326**。
|
||||
|
||||
**设计**:
|
||||
|
||||
1. **唯一权威系 = 项目世界系**:局部米,含明确 Z 基准;选定一个工作平面 CRS(默认项目 UTM,如 EPSG:32649)+ 双精度原点偏移。
|
||||
2. **每数据源各记源 CRS + 源 LocalFrame**:领域模型为每个数据集保存其源 CRS 与(如有)自身局部原点。**不假设全项目单一 CRS**。
|
||||
3. **统一 rebase 管线**(显式步骤,非一句话):任何几何进入 Scene 前,`CrsTransform`(PROJ)把 `源局部米 →(源原点)→ 源 CRS GIS → 项目世界 CRS →(减项目原点)→ 项目世界米`。多数据集因此对齐到同一世界系(解决 B-1 多原点冲突)。
|
||||
4. **轴向约定钉死**:world.x = Easting = `projectX`,world.y = Northing = `projectY`,world.z 向上为正、单位米。**解析器不信 `eastCoord/northCoord` 字段名**(实测与值颠倒),按 projectX/Y 取值,单测对照(B-2)。
|
||||
5. **垂向(Z)基准统一**(M-3):`LocalFrame` 定义高程基准面、向上为正、单位米、可选垂向夸张 z-scale。网格 z(剖面深度/构造面)、DEM `elevation`(地表高程)、体素 Z 在进入 Scene 前统一归算到该基准,避免地形与剖面垂直穿插。
|
||||
6. **影像/DEM 重投影**:装载时经 GDAL/PROJ 重投影到项目世界 CRS 再贴地,**不能简单减原点**(M-1)。
|
||||
7. **float 精度**:世界=局部米(小数值)从根本规避 VTK float 大坐标抖动。
|
||||
|
||||
---
|
||||
|
||||
## 6. 数据层:Repository(K-4,异步契约)
|
||||
|
||||
接口即按 **API 现实形态**定义(异步 + 分页 + 取消),本地实现用 QtConcurrent 满足同一签名(M-1):
|
||||
|
||||
```
|
||||
IProjectRepository {
|
||||
QFuture<Project> loadProject(id);
|
||||
QFuture<vector<GsObject>> loadStructure(projectId); // GS/TM 树
|
||||
}
|
||||
IDatasetRepository {
|
||||
QFuture<Page<DsObject>> listDatasets(tmObjectId, PageReq); // 分页
|
||||
QFuture<ScatterField> loadScatter(dsId);
|
||||
QFuture<Grid> loadGrid(dsId);
|
||||
QFuture<ColorScale> loadColorScale(dsId);
|
||||
QFuture<vector<Anomaly>> loadAnomalies(dsId);
|
||||
QFuture<TerrainTile> loadTerrain(...);
|
||||
// 大数据(体素/雷达):返回带取消句柄 + 进度回调;M1.5 走 FlatBuffers/Protobuf 流
|
||||
RequestHandle loadVolumeStream(dsId, sink, onProgress); // 可 cancel
|
||||
}
|
||||
```
|
||||
|
||||
- 切换 ds 时取消上一个未完成请求;列表类带游标/分页;大数据流式 + 进度 + 取消。
|
||||
- **M1**:`LocalSampleRepository` 读样本目录,解析器映射成领域模型(DTO ↔ model 在 `data/dto` 隔离)。
|
||||
- **未来**:`ApiRepository` 同签名对接 `pop-api`。
|
||||
|
||||
### 6.1 样本文件 → 模型解析约定(已核对真实样本)
|
||||
|
||||
| 文件 | 结构 | 解析要点 |
|
||||
|---|---|---|
|
||||
| 剖面原数据N.txt | `{data:{min,max,projectXList,projectYList,vlist,xlist,ylist,hlist}}` | 2597 点;local(x,y)+gis(projX=East,projY=North)+value |
|
||||
| 剖面网格数据N.txt | `{data:{x[100],y[22],v[22][100],z[22][100],elevation[100],lat[100],lon[100],vmin,vmax,overlayCoordinate,overlayElevation}}` | **规则栅格**(dx≈0.709,dy≈0.704 恒定)→ vtkImageData;**v/z 为 [j=y][i=x],灌点序 i 最快**;无顶层 min/max;对未知字段宽容 |
|
||||
| 剖面网格数据的色阶数据N.txt | `{data:{properties:{colorBar:[[值,rgba]],lineConfig,labelConfig,lvlMinMax}}}` | 17 段阶梯;`lineType` 实测 "solid"(以配置为准,勿硬编码 dashed) |
|
||||
| 剖面网格数据N——对应的异常圈定数据.txt | `{data:[{exceptionName,exceptionMarkType(1点/2线/3面),legend{point*/polyline*/polygon*},location:{coordinate[{x,y}]},zlist?,elevationList?,geographicalCoordinates{projectX,projectY,...}}]}` | 字段比早期列举多;`eastCoord/northCoord` 名值颠倒,按 projectX/Y 取 |
|
||||
| dem.tif / image.tif / image.tfw | GeoTIFF + world file | **影像 tfw 为 EPSG:3857**;GDAL 读 + PROJ 重投影到世界 CRS |
|
||||
| test_001_A*.head/.data/.cor | GPR 原始(462×4100×int16,多通道分文件) | **属 M1.5 雷达,LocalSampleRepository 不解析** |
|
||||
|
||||
---
|
||||
|
||||
## 7. 色阶(ColorScale)
|
||||
|
||||
`colorBar` 为 `[值, 颜色]` 阶梯数组(颜色支持 `#RRGGBB` 与 `rgba(r,g,b,a)`)。映射:值落相邻两 stop 间取**下界 stop** 颜色(阶梯,非线性插值)。
|
||||
|
||||
- **实现统一为离散 `vtkLookupTable`**(贴合「取下界阶梯」语义,2D/3D 共用同一可信源),显式定义 under(低于首 stop)/ over(高于末 stop)/ NaN 颜色。
|
||||
- **alpha 量纲按色阶来源文件类型判定**(网格色阶 0–255、LVL 色阶 0–1),解析器入口带 source 标记,**不按数值范围猜**(m-2)。
|
||||
- `lineConfig`:等值线显隐/颜色/`lineType`(以配置为准)/zmin/zmax;`labelConfig`:标注显隐/颜色;`equalAreaLayerCount`/`logLinesCount`。
|
||||
- 视图层 `ColorScaleEditor`:M1 读取与基本调整;命名保存对接后续色阶模板 API。
|
||||
|
||||
---
|
||||
|
||||
## 8. 登录与网络层(M1 必做,真实流程已抓取)
|
||||
|
||||
### 8.1 已确认的生产实现细节
|
||||
|
||||
- **API 基址** `http://tenant.geomative.cn/pop-api`(openresty 反代;OpenAPI 的 `/admin/*`、`/business/*` 加 `/pop-api` 前缀)。
|
||||
- **认证头** `geomativeauthorization: Geomative <token>`(不透明会话令牌,非 JWT)。
|
||||
- **登录三步**:① `GET /business/system/personalUser/getImageCode`→验证码图+`codeId` → ② `POST /business/system/personalUser/verifyCodeCheck {code,codeId}` → ③ `POST /admin/tenant/auth/login2 {username, password=RSA加密, checkCode}`→token。
|
||||
- 登录后:`getInfo` / `list-menus` / `enterprise/info` / `enterprise/joined/list`。
|
||||
|
||||
### 8.2 实现要点
|
||||
|
||||
- `AuthService`:取验证码→展示→校验→**OpenSSL RSA** 加密密码→login2→持有 token。
|
||||
- `Credential`(**QtKeychain**):token 存平台密钥库,严禁明文(规约 §7.4)。
|
||||
- `ApiClient`:注入 `geomativeauthorization`、基址、超时、错误码、401 处理;QtNetwork 原生。
|
||||
- **登录窗 UI**:样式参考现有 web 登录页(实现阶段截图复刻)。
|
||||
|
||||
### 8.3 ⚠️ 前置确认项(与 RSA 同级,M-5)
|
||||
|
||||
抓取的真实流程里**未见 refresh-token 实际使用,login2 只返不透明会话 token**。因此:
|
||||
|
||||
- **RSA 公钥来源**待确认(内置 vs 接口取)。
|
||||
- **token 生命周期 / 是否有 refresh 机制**待确认。据此二选一设计:
|
||||
- (a) 有 refresh token → 标准静默刷新、401 静默续期。
|
||||
- (b) 仅会话 token → 「免登录」= 持久化会话 token 至其有效期;**到期/401 引导用户重新登录(含验证码),不声称静默重登**。
|
||||
- 本项在 spike/实现前向后端确认;spec 不把「静默刷新」当既定能力。
|
||||
|
||||
---
|
||||
|
||||
## 9. UI 外壳:完整工作台(K-3)
|
||||
|
||||
- **停靠框架**:ADS(LGPL,规约 §6.2)。**VTK 面板默认不可浮动**(或浮动时占位、停靠回重建),缓解 reparent 上下文问题(spike 验证,M-4)。
|
||||
- **三区布局**(还原原型):左(对象树 + 数据集列表)/ 中(2D-3D 视图 + 数据详情)/ 右(异常-对象属性 + 属性)。
|
||||
- **主题**:QSS + QDarkStyleSheet 打底 + QtAwesome 图标。
|
||||
- **布局持久化**:ADS 透视图 + 窗口几何存 QSettings(Windows 强制 INI,规约 §7.2)。
|
||||
- **联动**(controller 按闭环拆分,§3):勾选 GS/TM→按 dd 类型筛选 ds→勾选 ds→渲染;列表↔详情↔视图定位三向;色阶调整两视角实时更新。
|
||||
|
||||
---
|
||||
|
||||
## 10. 算法:展示期三维插值(K-6、K-10)
|
||||
|
||||
- `core/algo/IInterpolator`:`core::ScalarVolume interpolate(const PointSet& pts, const GridSpec& spec)`——**返回 core 中立类型**(dims/spacing/origin/double 数组),绝不含 VTK(M-2)。render 层 `VoxelVolumeActor` 把 `ScalarVolume`→`vtkImageData`。
|
||||
- M1 实现 `IdwInterpolator`(反距离加权,Eigen 辅助;2597 点规模**不需要 PCL/KD-tree**,m-1)。
|
||||
- **可信度与数据依赖(K-10、B-3)**:可信体素需 **≥3 条非共线剖面或真实 3D 网格(dd_Property3D)/ 反演网格** 输入。仅两条近平行剖面 IDW 会得到「夹层片状」幻影。故:
|
||||
- 插值**限定在输入包络内 + 最大距离 clamp**,包络外置 blank/透明,避免 ray cast 渲染整盒幻影。
|
||||
- M1 体绘制按 §13 分阶段:先在**充分输入**数据上出可信体;输入不足的复杂体后置。
|
||||
- **数据依赖**:需客户提供达到可信度的体素级输入数据(≥3 剖面 / 3D 网格)——列入 §14 待办。
|
||||
- **不做反演**(上游、Python 生态 ResIPy 等),未来按规约 §8.3 进程隔离接入,M1 仅接口预留。
|
||||
|
||||
---
|
||||
|
||||
## 11. 构建与依赖(K-8,全 vcpkg)
|
||||
|
||||
- **构建**:CMake 3.21+ + **vcpkg manifest(全量,含 Qt)**;生成 `compile_commands.json`。MSVC 2022,C++17。
|
||||
- **关键依赖事实**(已核 vcpkg `ports/vtk/vcpkg.json`):`qt` 非 vtk 默认特性;`vtk[qt]` 依赖 `qtbase(gui/opengl/widgets/sql-sqlite)` + `qtdeclarative`。→ 用 `vtk` 时显式开 `qt`,**全家共用同一份 vcpkg Qt**(K-8)。用 `default-features:false` 仅选 `qt/opengl/gdal/proj`,避免拉入 netcdf/seacas/libharu 等重特性。
|
||||
- **M1 依赖矩阵**:
|
||||
|
||||
| 依赖(vcpkg 名) | 用途 | 许可证 |
|
||||
|---|---|---|
|
||||
| qtbase / qttools / qtdeclarative | UI/网络/SQL/并发(VTK[qt] 亦复用) | LGPLv3(动态)⚠️ 商务 D-2 |
|
||||
| vtk[qt,opengl,gdal,proj] | 三维渲染 + QVTK widget | BSD ✅ |
|
||||
| gdal / proj | DEM/影像/坐标重投影 | MIT 类 ✅ |
|
||||
| qt-advanced-docking-system(端口可用性 spike 验证;不可用则 FetchContent 锁 tag) | 停靠布局 | LGPL v2.1 ✅ |
|
||||
| qtkeychain(共用同一 Qt) | 凭证存储 | BSD ✅ |
|
||||
| openssl | RSA/HTTPS | Apache 2.0 ✅ |
|
||||
| eigen3 | 数值/插值 | MPL2 ✅ |
|
||||
| spdlog / fmt | 日志 | MIT ✅ |
|
||||
| nlohmann-json | JSON | MIT ✅ |
|
||||
| gtest | 单测 | BSD ✅ |
|
||||
|
||||
- ~~PCL~~:**M1 移除**(点规模不需要)。
|
||||
- 部署:单一 vcpkg 链路(`TARGET_RUNTIME_DLLS` + vcpkg deploy),**不混用 windeploypt 与官方 Qt**(规避双 Qt,M-5)。
|
||||
- 环境从零搭建:见 `docs/ENV_SETUP_Windows.md`(已改为方案 B 为主)。
|
||||
|
||||
---
|
||||
|
||||
## 12. 测试策略(规约 §10.2)
|
||||
|
||||
- `core`/`data`/`algo`:gtest(坐标 rebase/轴向、Z 基准归算、colorBar LUT 映射、v[j][i] 灌点序、样本解析、IDW 正确性)。
|
||||
- `view`/`controller`:Qt Test(联动、模态工具互斥)。
|
||||
- 失败路径必测:登录失败/验证码错/token 失效、样本缺失/损坏、空数据集、异源 CRS 重投影。
|
||||
- 渲染以小基准截图人工核对(对照图 #17/#18/#09)。
|
||||
- clang-tidy + cppcheck 入 CI;Debug 启用 ASan/UBSan。
|
||||
|
||||
---
|
||||
|
||||
## 13. M1 验收标准(图分阶段,K-5/K-10)
|
||||
|
||||
**M1-a(先达成)**
|
||||
1. 启动→登录窗(近 web)→真连 `pop-api` 登录成功。
|
||||
2. 完整工作台 ADS 三区停靠;对象树/数据集来自本地样本。
|
||||
3. ① 渲染剖面散点(图 #17 样)、网格 banded 等值面+等值线+标注(图 #18 样)、异常按 markType 圈定。
|
||||
4. ④ DEM 地形起伏 + 影像(经重投影对齐)。
|
||||
5. 色阶离散 LUT 可调,两视角实时联动;二维俯视相机预设可切。
|
||||
|
||||
**M1-b(在充分输入数据上达成可信体)**
|
||||
6. 由 ≥3 剖面/3D 网格经 IDW 生成**可信** dd_voxel 体绘制,插值域受限;`vtkResliceCursorWidget` 交互切片得 dd_slice。
|
||||
|
||||
**通用**:core 单测通过;clang-tidy 无新增告警;布局/偏好持久化生效;2D/3D 切换零数据重建、坐标对齐正确。
|
||||
|
||||
---
|
||||
|
||||
## 14. 风险与待决(承接规约 §11)
|
||||
|
||||
| 风险/待决 | 说明 | 处理 |
|
||||
|---|---|---|
|
||||
| D-2 Qt 许可证 | LGPL 动态 vs 商业 | M1 按 LGPL 动态链接;商务并行 |
|
||||
| RSA 公钥来源 + token 生命周期 | 登录加密公钥、是否有 refresh | spike 前向后端确认(§8.3) |
|
||||
| 可信体输入数据 | 2 平行剖面不足以出可信体(K-10) | 需客户提供 ≥3 剖面/3D 网格;M1-b 验收依赖此 |
|
||||
| ADS 端口 + QVTK reparent | vcpkg 端口可用性、浮动黑屏 | spike 门槛验证(§15) |
|
||||
| 全 vcpkg 首编译耗时 | VTK+Qt 编译久 | 二进制缓存 `VCPKG_BINARY_SOURCES` |
|
||||
| 异源 CRS 配准 | 影像 3857 vs 剖面 32649 | GDAL/PROJ 重投影(§5) |
|
||||
| macOS / OpenGL 废弃 | 规约 §3.3 | M1 仅 Windows;保持可移植 |
|
||||
|
||||
---
|
||||
|
||||
## 15. Spike 预研门槛(K-2,进入完整实现计划前必过)
|
||||
|
||||
第一周先跑通三个高风险点,任一不过则调整方案后再展开计划:
|
||||
|
||||
1. **构建/部署 spike**:全 vcpkg(qtbase + vtk[qt] 共用一份 Qt)配置、编译、出 exe、单一链路部署、无双 Qt 冲突。
|
||||
2. **UI 上下文 spike**:ADS(vcpkg 或 FetchContent)+ `QVTKOpenGLStereoWidget`,验证停靠/浮动/重停靠不黑屏、相机预设切换稳定。
|
||||
3. **渲染管线 spike**:用真实样本跑通 `vtkImageData(+warp) → geometry filter → vtkBandedPolyDataContourFilter(GenerateContourEdges) → 标注`,目视对照图 #18;散点 + 离散 LUT 色阶对照图 #17。
|
||||
|
||||
---
|
||||
|
||||
## 16. v2 修订记录(对应评审)
|
||||
|
||||
- 网格管线改 `vtkImageData(+warp)→geometry filter→banded contour(GenerateContourEdges)`(B-1/B-2 code)。
|
||||
- 坐标系重写:多源 CRS + 各自 LocalFrame + 统一 rebase + 轴向钉死 + Z 基准 + 影像重投影(B-1/B-2 arch、M-1/M-3 code、M-3 arch)。
|
||||
- dd_voxel 维持可信体但列数据依赖、插值域受限、验收分阶段(B-3 code、K-10)。
|
||||
- Repository 改异步契约(分页/取消/流)(M-1 arch)。
|
||||
- `IInterpolator` 返回 core `ScalarVolume`,去 VTK(M-2 arch)。
|
||||
- 交互:模态工具抽象 + 拾取回流 + 切片改 `vtkResliceCursorWidget`(B-3 arch、M-2 code)。
|
||||
- widget 改 `QVTKOpenGLStereoWidget` + VTK 面板不可浮动 + spike(M-4 code)。
|
||||
- 构建改全 vcpkg(已核 vtk[qt]→qtbase 依赖)、删 PCL(M-5 code、m-1)。
|
||||
- 登录 refresh/token 生命周期降为前置确认(M-5 arch)。
|
||||
- 色阶离散 LUT + under/over/NaN + alpha 按来源 + lineType 以配置为准(m-1/m-2/m-4 各)。
|
||||
- controller 拆 Selection/RenderSync/DetailSync(m-5 arch)。
|
||||
- 新增 §15 spike 门槛(K-2)。
|
||||
|
||||
---
|
||||
|
||||
*v2 经双专家评审 + 数据核验修订。下一步:spike 预研 → writing-plans。*
|
||||
Binary file not shown.
|
|
@ -0,0 +1,6 @@
|
|||
0.298582141739
|
||||
0.000000000000
|
||||
0.000000000000
|
||||
-0.298582141739
|
||||
12708343.885664964100
|
||||
2577685.904860967300
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
|
@ -0,0 +1,40 @@
|
|||
HEADER VERSION: 10
|
||||
DATA VERSION: 16
|
||||
DATE: 2024-02-26
|
||||
START TIME: 01:16:07
|
||||
STOP TIME: 01:17:41
|
||||
ANTENNA: 450 MHz
|
||||
ANTENNA SEPARATION: 0.250
|
||||
SAMPLES: 462
|
||||
SIGNAL POSITION: 14
|
||||
CLIPPED SAMPLES: 0
|
||||
RUNS: 32
|
||||
MAX STACKS: 512
|
||||
AUTOSTACKS: 1
|
||||
FREQUENCY: 5120.000
|
||||
TIMEWINDOW: 100.000
|
||||
LAST TRACE: 4100
|
||||
TRIG SOURCE: wheel
|
||||
TIME INTERVAL: 0.100000
|
||||
DISTANCE INTERVAL: 0.099150
|
||||
USER DISTANCE INTERVAL: 0.100000
|
||||
STOP POSITION: 406.515581
|
||||
WHEEL NAME: 20240224
|
||||
WHEEL CALIBRATION: 423.6000000000
|
||||
ZERO LEVEL: 40
|
||||
SOIL VELOCITY: 100.000000
|
||||
PREPROCESSING: 0
|
||||
OPERATOR COMMENT: _
|
||||
ANTENNA F/W: 48001271
|
||||
ANTENNA H/W: 0
|
||||
ANTENNA FPGA: CA75
|
||||
ANTENNA SERIAL: 2066
|
||||
SOFTWARE VERSION: T 1.3.03
|
||||
POSITIONING: 2
|
||||
CHANNELS: 14
|
||||
CHANNEL CONFIGURATION: T1 - R1
|
||||
CH_X_OFFSET: -0.686000
|
||||
CH_Y_OFFSET: -1.000000
|
||||
POSITION POLE HEIGHT: 1.500000
|
||||
RTK_X_OFFSET: 0.0
|
||||
RTK_Y_OFFSET: -1.0
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
|
@ -0,0 +1,40 @@
|
|||
HEADER VERSION: 10
|
||||
DATA VERSION: 16
|
||||
DATE: 2024-02-26
|
||||
START TIME: 01:16:07
|
||||
STOP TIME: 01:17:41
|
||||
ANTENNA: 450 MHz
|
||||
ANTENNA SEPARATION: 0.250
|
||||
SAMPLES: 462
|
||||
SIGNAL POSITION: 14
|
||||
CLIPPED SAMPLES: 0
|
||||
RUNS: 32
|
||||
MAX STACKS: 512
|
||||
AUTOSTACKS: 1
|
||||
FREQUENCY: 5120.000
|
||||
TIMEWINDOW: 100.000
|
||||
LAST TRACE: 4100
|
||||
TRIG SOURCE: wheel
|
||||
TIME INTERVAL: 0.100000
|
||||
DISTANCE INTERVAL: 0.099150
|
||||
USER DISTANCE INTERVAL: 0.100000
|
||||
STOP POSITION: 406.515581
|
||||
WHEEL NAME: 20240224
|
||||
WHEEL CALIBRATION: 423.6000000000
|
||||
ZERO LEVEL: 40
|
||||
SOIL VELOCITY: 100.000000
|
||||
PREPROCESSING: 0
|
||||
OPERATOR COMMENT: _
|
||||
ANTENNA F/W: 48001271
|
||||
ANTENNA H/W: 0
|
||||
ANTENNA FPGA: CA75
|
||||
ANTENNA SERIAL: 2066
|
||||
SOFTWARE VERSION: T 1.3.03
|
||||
POSITIONING: 2
|
||||
CHANNELS: 14
|
||||
CHANNEL CONFIGURATION: T1 - R1
|
||||
CH_X_OFFSET: -0.686000
|
||||
CH_Y_OFFSET: -1.000000
|
||||
POSITION POLE HEIGHT: 1.500000
|
||||
RTK_X_OFFSET: 0.0
|
||||
RTK_Y_OFFSET: -1.0
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
|
@ -0,0 +1,40 @@
|
|||
HEADER VERSION: 10
|
||||
DATA VERSION: 16
|
||||
DATE: 2024-02-26
|
||||
START TIME: 01:16:07
|
||||
STOP TIME: 01:17:41
|
||||
ANTENNA: 450 MHz
|
||||
ANTENNA SEPARATION: 0.250
|
||||
SAMPLES: 462
|
||||
SIGNAL POSITION: 14
|
||||
CLIPPED SAMPLES: 0
|
||||
RUNS: 32
|
||||
MAX STACKS: 512
|
||||
AUTOSTACKS: 1
|
||||
FREQUENCY: 5120.000
|
||||
TIMEWINDOW: 100.000
|
||||
LAST TRACE: 4100
|
||||
TRIG SOURCE: wheel
|
||||
TIME INTERVAL: 0.100000
|
||||
DISTANCE INTERVAL: 0.099150
|
||||
USER DISTANCE INTERVAL: 0.100000
|
||||
STOP POSITION: 406.515581
|
||||
WHEEL NAME: 20240224
|
||||
WHEEL CALIBRATION: 423.6000000000
|
||||
ZERO LEVEL: 40
|
||||
SOIL VELOCITY: 100.000000
|
||||
PREPROCESSING: 0
|
||||
OPERATOR COMMENT: _
|
||||
ANTENNA F/W: 48001271
|
||||
ANTENNA H/W: 0
|
||||
ANTENNA FPGA: CA75
|
||||
ANTENNA SERIAL: 2066
|
||||
SOFTWARE VERSION: T 1.3.03
|
||||
POSITIONING: 2
|
||||
CHANNELS: 14
|
||||
CHANNEL CONFIGURATION: T1 - R1
|
||||
CH_X_OFFSET: -0.686000
|
||||
CH_Y_OFFSET: -1.000000
|
||||
POSITION POLE HEIGHT: 1.500000
|
||||
RTK_X_OFFSET: 0.0
|
||||
RTK_Y_OFFSET: -1.0
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,102 @@
|
|||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"id": "1437832397873152",
|
||||
"projectId": "1434842515398656",
|
||||
"templateId": null,
|
||||
"dsObjectId": "1434990453727232",
|
||||
"tmObjectId": "1434842536083456",
|
||||
"graphicArea": 1038.5564990593678,
|
||||
"properties": {
|
||||
"lvlSchemeType": "normal",
|
||||
"colorBar": [
|
||||
[
|
||||
"0.00",
|
||||
"#00008B"
|
||||
],
|
||||
[
|
||||
"1.51",
|
||||
"rgba(0, 0, 170, 1)"
|
||||
],
|
||||
[
|
||||
"2.27",
|
||||
"rgba(0, 0, 211, 1)"
|
||||
],
|
||||
[
|
||||
"3.43",
|
||||
"#0000FF"
|
||||
],
|
||||
[
|
||||
"5.17",
|
||||
"rgba(0, 128, 255, 1)"
|
||||
],
|
||||
[
|
||||
"7.79",
|
||||
"#00FFFF"
|
||||
],
|
||||
[
|
||||
"11.75",
|
||||
"rgba(0, 192, 128, 1)"
|
||||
],
|
||||
[
|
||||
"17.72",
|
||||
"#00FF00"
|
||||
],
|
||||
[
|
||||
"26.73",
|
||||
"rgba(0, 128, 0, 1)"
|
||||
],
|
||||
[
|
||||
"40.30",
|
||||
"rgba(128, 192, 0, 1)"
|
||||
],
|
||||
[
|
||||
"60.77",
|
||||
"#FFFF00"
|
||||
],
|
||||
[
|
||||
"91.64",
|
||||
"rgba(191, 128, 0, 1)"
|
||||
],
|
||||
[
|
||||
"138.20",
|
||||
"rgba(255, 128, 0, 1)"
|
||||
],
|
||||
[
|
||||
"208.40",
|
||||
"#FF0000"
|
||||
],
|
||||
[
|
||||
"314.20",
|
||||
"rgba(211, 0, 0, 1)"
|
||||
],
|
||||
[
|
||||
"473.80",
|
||||
"rgba(132, 0, 64, 1)"
|
||||
],
|
||||
[
|
||||
"714.50",
|
||||
"rgba(96, 0, 96, 1)"
|
||||
],
|
||||
[
|
||||
"1323.20",
|
||||
"rgba(48, 0, 48, 1)"
|
||||
]
|
||||
],
|
||||
"equalAreaLayerCount": 10,
|
||||
"labelConfig": {
|
||||
"showLabels": true,
|
||||
"color": "#000000"
|
||||
},
|
||||
"logLinesCount": 8,
|
||||
"lineConfig": {
|
||||
"showLines": true,
|
||||
"color": "#000000",
|
||||
"lineType": "dashed",
|
||||
"zmin": 0,
|
||||
"zmax": 1323.2
|
||||
}
|
||||
}
|
||||
},
|
||||
"msg": "成功"
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"id": "1437832432312320",
|
||||
"projectId": "1434842515398656",
|
||||
"templateId": null,
|
||||
"dsObjectId": "1434990492565504",
|
||||
"tmObjectId": "1434857871704064",
|
||||
"graphicArea": 153.93909725108225,
|
||||
"properties": {
|
||||
"lvlSchemeType": "normal",
|
||||
"colorBar": [
|
||||
[
|
||||
"0.00",
|
||||
"#00008B"
|
||||
],
|
||||
[
|
||||
"1.51",
|
||||
"rgba(0, 0, 170, 1)"
|
||||
],
|
||||
[
|
||||
"2.27",
|
||||
"rgba(0, 0, 211, 1)"
|
||||
],
|
||||
[
|
||||
"3.43",
|
||||
"#0000FF"
|
||||
],
|
||||
[
|
||||
"5.17",
|
||||
"rgba(0, 128, 255, 1)"
|
||||
],
|
||||
[
|
||||
"7.79",
|
||||
"#00FFFF"
|
||||
],
|
||||
[
|
||||
"11.75",
|
||||
"rgba(0, 192, 128, 1)"
|
||||
],
|
||||
[
|
||||
"17.72",
|
||||
"#00FF00"
|
||||
],
|
||||
[
|
||||
"26.73",
|
||||
"rgba(0, 128, 0, 1)"
|
||||
],
|
||||
[
|
||||
"40.30",
|
||||
"rgba(128, 192, 0, 1)"
|
||||
],
|
||||
[
|
||||
"60.77",
|
||||
"#FFFF00"
|
||||
],
|
||||
[
|
||||
"91.64",
|
||||
"rgba(191, 128, 0, 1)"
|
||||
],
|
||||
[
|
||||
"138.20",
|
||||
"rgba(255, 128, 0, 1)"
|
||||
],
|
||||
[
|
||||
"208.40",
|
||||
"#FF0000"
|
||||
],
|
||||
[
|
||||
"314.20",
|
||||
"rgba(211, 0, 0, 1)"
|
||||
],
|
||||
[
|
||||
"473.80",
|
||||
"rgba(132, 0, 64, 1)"
|
||||
],
|
||||
[
|
||||
"714.50",
|
||||
"rgba(96, 0, 96, 1)"
|
||||
],
|
||||
[
|
||||
"1323.20",
|
||||
"rgba(48, 0, 48, 1)"
|
||||
]
|
||||
],
|
||||
"equalAreaLayerCount": 10,
|
||||
"labelConfig": {
|
||||
"showLabels": true,
|
||||
"color": "#000000"
|
||||
},
|
||||
"logLinesCount": 8,
|
||||
"lineConfig": {
|
||||
"showLines": true,
|
||||
"color": "#000000",
|
||||
"lineType": "dashed",
|
||||
"zmin": 0,
|
||||
"zmax": 1323.2
|
||||
}
|
||||
}
|
||||
},
|
||||
"msg": "成功"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,398 @@
|
|||
{
|
||||
"code": 200,
|
||||
"data": [
|
||||
{
|
||||
"id": "1436605284917248",
|
||||
"tenantId": "1434713686794240",
|
||||
"projectId": "1434842515398656",
|
||||
"remarkSourceId": "1434990453727232",
|
||||
"parentConfType": 2,
|
||||
"parentId": "1434842536083456",
|
||||
"exceptionName": "ERT1-54",
|
||||
"exceptionTypeId": "1434990928879616",
|
||||
"exceptionTypeName": "推断异常区",
|
||||
"exceptionMarkTypeName": "多段线",
|
||||
"exceptionMarkType": 2,
|
||||
"legend": {
|
||||
"textNoOpacity": 100,
|
||||
"polylineWidth": 5,
|
||||
"polygonFillColor": "#000000",
|
||||
"textSize": 12,
|
||||
"textColor": "#000000",
|
||||
"polylineNoOpacity": 100,
|
||||
"polylineShape": "dash",
|
||||
"pointSize": 1,
|
||||
"polylineColor": "#000000",
|
||||
"polygonFill": "",
|
||||
"polygonFillNoOpacity": 100,
|
||||
"pointNoOpacity": 0,
|
||||
"pointShape": "circle",
|
||||
"textFont": "微软雅黑",
|
||||
"pointColor": "#000000"
|
||||
},
|
||||
"location": {
|
||||
"coordinate": [
|
||||
{
|
||||
"x": 26.297797699395506,
|
||||
"y": 22.87809573580929
|
||||
},
|
||||
{
|
||||
"x": 25.889741886260932,
|
||||
"y": 18.752198069670822
|
||||
},
|
||||
{
|
||||
"x": 21.854523289707924,
|
||||
"y": 19.250932952390855
|
||||
},
|
||||
{
|
||||
"x": 23.169369798697105,
|
||||
"y": 22.696737596638368
|
||||
},
|
||||
{
|
||||
"x": 25.57236514271182,
|
||||
"y": 22.651398061845637
|
||||
}
|
||||
]
|
||||
},
|
||||
"geographicalCoordinates": {
|
||||
"coordinates": [
|
||||
{
|
||||
"projectX": 516863.6350992983,
|
||||
"projectY": 2494259.56246985,
|
||||
"eastCoord": 2494259.56246985,
|
||||
"northCoord": 516863.6350992983
|
||||
},
|
||||
{
|
||||
"projectX": 516863.29736813204,
|
||||
"projectY": 2494259.3334537474,
|
||||
"eastCoord": 2494259.3334537474,
|
||||
"northCoord": 516863.29736813204
|
||||
},
|
||||
{
|
||||
"projectX": 516859.84188118874,
|
||||
"projectY": 2494257.252264521,
|
||||
"eastCoord": 2494257.252264521,
|
||||
"northCoord": 516859.84188118874
|
||||
},
|
||||
{
|
||||
"projectX": 516860.9722501914,
|
||||
"projectY": 2494257.923903857,
|
||||
"eastCoord": 2494257.923903857,
|
||||
"northCoord": 516860.9722501914
|
||||
},
|
||||
{
|
||||
"projectX": 516863.0346883361,
|
||||
"projectY": 2494259.155330112,
|
||||
"eastCoord": 2494259.155330112,
|
||||
"northCoord": 516863.0346883361
|
||||
}
|
||||
]
|
||||
},
|
||||
"latitudeLongitude": {
|
||||
"latLon": [
|
||||
{
|
||||
"latitude": 22.545901392177885,
|
||||
"longitude": 114.16394368149074
|
||||
},
|
||||
{
|
||||
"latitude": 22.54589932743741,
|
||||
"longitude": 114.16394039572776
|
||||
},
|
||||
{
|
||||
"latitude": 22.545880567883383,
|
||||
"longitude": 114.16390678033547
|
||||
},
|
||||
{
|
||||
"latitude": 22.545886621798203,
|
||||
"longitude": 114.16391777660226
|
||||
},
|
||||
{
|
||||
"latitude": 22.5458977215281,
|
||||
"longitude": 114.16393784013441
|
||||
}
|
||||
]
|
||||
},
|
||||
"remark": "",
|
||||
"createTime": "2025-07-28 10:09:20",
|
||||
"updateTime": "2025-07-28 10:09:20",
|
||||
"elevationList": [],
|
||||
"elevationMinMaxList": null,
|
||||
"latMinMaxList": null,
|
||||
"lonMinMaxList": null,
|
||||
"type": null,
|
||||
"fileId": null,
|
||||
"zlist": null,
|
||||
"xminMaxList": null,
|
||||
"yminMaxList": null
|
||||
},
|
||||
{
|
||||
"id": "1444610089246720",
|
||||
"tenantId": "1434713686794240",
|
||||
"projectId": "1434842515398656",
|
||||
"remarkSourceId": "1434990453727232",
|
||||
"parentConfType": 2,
|
||||
"parentId": "1434842536083456",
|
||||
"exceptionName": "ERT1-55",
|
||||
"exceptionTypeId": "1434990928879616",
|
||||
"exceptionTypeName": "推断异常区",
|
||||
"exceptionMarkTypeName": "多段线",
|
||||
"exceptionMarkType": 2,
|
||||
"legend": {
|
||||
"textNoOpacity": 100,
|
||||
"polylineWidth": 5,
|
||||
"polygonFillColor": "#000000",
|
||||
"textSize": 12,
|
||||
"textColor": "#000000",
|
||||
"polylineNoOpacity": 100,
|
||||
"polylineShape": "dash",
|
||||
"pointSize": 1,
|
||||
"polylineColor": "#000000",
|
||||
"polygonFill": "",
|
||||
"polygonFillNoOpacity": 100,
|
||||
"pointNoOpacity": 0,
|
||||
"pointShape": "circle",
|
||||
"textFont": "微软雅黑",
|
||||
"pointColor": "#000000"
|
||||
},
|
||||
"location": {
|
||||
"coordinate": [
|
||||
{
|
||||
"x": 28.416731752440885,
|
||||
"y": 17.638235918367346
|
||||
},
|
||||
{
|
||||
"x": 42.2186174667266,
|
||||
"y": 19.65922632653061
|
||||
},
|
||||
{
|
||||
"x": 42.514372160604154,
|
||||
"y": 16.258047346938774
|
||||
},
|
||||
{
|
||||
"x": 25.262015017747007,
|
||||
"y": 15.469368163265303
|
||||
},
|
||||
{
|
||||
"x": 22.45234542591027,
|
||||
"y": 18.969132040816326
|
||||
}
|
||||
]
|
||||
},
|
||||
"geographicalCoordinates": {
|
||||
"coordinates": [
|
||||
{
|
||||
"x": 28.416731752440885,
|
||||
"y": 17.638235918367346
|
||||
},
|
||||
{
|
||||
"x": 42.2186174667266,
|
||||
"y": 19.65922632653061
|
||||
},
|
||||
{
|
||||
"x": 42.514372160604154,
|
||||
"y": 16.258047346938774
|
||||
},
|
||||
{
|
||||
"x": 25.262015017747007,
|
||||
"y": 15.469368163265303
|
||||
},
|
||||
{
|
||||
"x": 22.45234542591027,
|
||||
"y": 18.969132040816326
|
||||
}
|
||||
]
|
||||
},
|
||||
"latitudeLongitude": {
|
||||
"latLon": [
|
||||
{
|
||||
"latitude": 22.545913289483373,
|
||||
"longitude": 114.16395865260866
|
||||
},
|
||||
{
|
||||
"latitude": 22.546014362176127,
|
||||
"longitude": 114.16403620696535
|
||||
},
|
||||
{
|
||||
"latitude": 22.546016974294574,
|
||||
"longitude": 114.16403686975868
|
||||
},
|
||||
{
|
||||
"latitude": 22.545896055134875,
|
||||
"longitude": 114.16393496549607
|
||||
},
|
||||
{
|
||||
"latitude": 22.545883197297574,
|
||||
"longitude": 114.16391155204525
|
||||
}
|
||||
]
|
||||
},
|
||||
"remark": "",
|
||||
"createTime": "2025-11-18 12:27:30",
|
||||
"updateTime": "2025-11-18 12:27:30",
|
||||
"elevationList": [
|
||||
18.130960102239015,
|
||||
19.868592604577906,
|
||||
16.657547764384148,
|
||||
15.775206774222223,
|
||||
19.25697116487228
|
||||
],
|
||||
"elevationMinMaxList": [
|
||||
24.62915893717389,
|
||||
25.919367346938778
|
||||
],
|
||||
"latMinMaxList": [
|
||||
22.545840344401373,
|
||||
22.546289821121675
|
||||
],
|
||||
"lonMinMaxList": [
|
||||
114.16374305442663,
|
||||
114.16410535150006
|
||||
],
|
||||
"type": null,
|
||||
"fileId": null,
|
||||
"zlist": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"xminMaxList": [
|
||||
3.628030303030303,
|
||||
73.8589696969697
|
||||
],
|
||||
"yminMaxList": [
|
||||
11.131632653061224,
|
||||
25.919367346938778
|
||||
]
|
||||
},
|
||||
{
|
||||
"id": "1444618494304256",
|
||||
"tenantId": "1434713686794240",
|
||||
"projectId": "1434842515398656",
|
||||
"remarkSourceId": "1434990453727232",
|
||||
"parentConfType": 2,
|
||||
"parentId": "1434842536083456",
|
||||
"exceptionName": "ERT1-56",
|
||||
"exceptionTypeId": "1434990928879616",
|
||||
"exceptionTypeName": "推断异常区",
|
||||
"exceptionMarkTypeName": "多段线",
|
||||
"exceptionMarkType": 2,
|
||||
"legend": {
|
||||
"textNoOpacity": 100,
|
||||
"polylineWidth": 5,
|
||||
"polygonFillColor": "#000000",
|
||||
"textSize": 12,
|
||||
"textColor": "#000000",
|
||||
"polylineNoOpacity": 100,
|
||||
"polylineShape": "dash",
|
||||
"pointSize": 1,
|
||||
"polylineColor": "#000000",
|
||||
"polygonFill": "",
|
||||
"polygonFillNoOpacity": 100,
|
||||
"pointNoOpacity": 0,
|
||||
"pointShape": "circle",
|
||||
"textFont": "微软雅黑",
|
||||
"pointColor": "#000000"
|
||||
},
|
||||
"location": {
|
||||
"coordinate": [
|
||||
{
|
||||
"x": 49.5366106964761,
|
||||
"y": 23.621811382619335
|
||||
},
|
||||
{
|
||||
"x": 60.65868511350889,
|
||||
"y": 22.89078301718056
|
||||
},
|
||||
{
|
||||
"x": 50.58093693281721,
|
||||
"y": 18.609045448182027
|
||||
},
|
||||
{
|
||||
"x": 49.641043320110214,
|
||||
"y": 23.621811382619335
|
||||
}
|
||||
]
|
||||
},
|
||||
"geographicalCoordinates": {
|
||||
"coordinates": [
|
||||
{
|
||||
"x": 49.5366106964761,
|
||||
"y": 23.621811382619335
|
||||
},
|
||||
{
|
||||
"x": 60.65868511350889,
|
||||
"y": 22.89078301718056
|
||||
},
|
||||
{
|
||||
"x": 50.58093693281721,
|
||||
"y": 18.609045448182027
|
||||
},
|
||||
{
|
||||
"x": 49.641043320110214,
|
||||
"y": 23.621811382619335
|
||||
}
|
||||
]
|
||||
},
|
||||
"latitudeLongitude": {
|
||||
"latLon": [
|
||||
{
|
||||
"latitude": 22.546078917267046,
|
||||
"longitude": 114.16404625003365
|
||||
},
|
||||
{
|
||||
"latitude": 22.54617433413568,
|
||||
"longitude": 114.1640743917907
|
||||
},
|
||||
{
|
||||
"latitude": 22.54608770512832,
|
||||
"longitude": 114.16404974715866
|
||||
},
|
||||
{
|
||||
"latitude": 22.54607977590409,
|
||||
"longitude": 114.16404661260026
|
||||
}
|
||||
]
|
||||
},
|
||||
"remark": "",
|
||||
"createTime": "2025-11-18 15:18:30",
|
||||
"updateTime": "2025-11-18 15:18:30",
|
||||
"elevationList": [
|
||||
23.608570241971698,
|
||||
22.678127539499208,
|
||||
18.304733365315005,
|
||||
23.713879720905936
|
||||
],
|
||||
"elevationMinMaxList": [
|
||||
24.62915893717389,
|
||||
25.919367346938778
|
||||
],
|
||||
"latMinMaxList": [
|
||||
22.545840344401373,
|
||||
22.546289821121675
|
||||
],
|
||||
"lonMinMaxList": [
|
||||
114.16374305442663,
|
||||
114.16410535150006
|
||||
],
|
||||
"type": null,
|
||||
"fileId": null,
|
||||
"zlist": [
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
],
|
||||
"xminMaxList": [
|
||||
3.628030303030303,
|
||||
73.8589696969697
|
||||
],
|
||||
"yminMaxList": [
|
||||
11.131632653061224,
|
||||
25.919367346938778
|
||||
]
|
||||
}
|
||||
],
|
||||
"msg": "成功"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,97 @@
|
|||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"id": null,
|
||||
"projectId": null,
|
||||
"templateId": null,
|
||||
"dsObjectId": "1434990453727232",
|
||||
"tmObjectId": null,
|
||||
"graphicArea": 1038.5564990593678,
|
||||
"properties": {
|
||||
"colorBar": [
|
||||
[
|
||||
"-57.09136148261278",
|
||||
"rgba(0,0,170,255)"
|
||||
],
|
||||
[
|
||||
"5.801828325646119",
|
||||
"rgba(0,0,211,255)"
|
||||
],
|
||||
[
|
||||
"37.02556849526284",
|
||||
"rgba(0,0,255,255)"
|
||||
],
|
||||
[
|
||||
"60.4096686077103",
|
||||
"rgba(0,128,255,255)"
|
||||
],
|
||||
[
|
||||
"67.58134117549344",
|
||||
"rgba(0,255,255,255)"
|
||||
],
|
||||
[
|
||||
"71.9360844638518",
|
||||
"rgba(0,192,128,255)"
|
||||
],
|
||||
[
|
||||
"89.01788560187286",
|
||||
"rgba(0,255,0,255)"
|
||||
],
|
||||
[
|
||||
"102.55327343637795",
|
||||
"rgba(0,128,0,255)"
|
||||
],
|
||||
[
|
||||
"116.75693614290593",
|
||||
"rgba(128,192,0,255)"
|
||||
],
|
||||
[
|
||||
"141.06719439867751",
|
||||
"rgba(255,255,0,255)"
|
||||
],
|
||||
[
|
||||
"174.17771819359507",
|
||||
"rgba(191,128,0,255)"
|
||||
],
|
||||
[
|
||||
"212.85100047878993",
|
||||
"rgba(255,128,0,255)"
|
||||
],
|
||||
[
|
||||
"255.55193963149196",
|
||||
"rgba(255,255,0,255)"
|
||||
],
|
||||
[
|
||||
"301.4870703097707",
|
||||
"rgba(211,0,0,255)"
|
||||
],
|
||||
[
|
||||
"388.51836985966247",
|
||||
"rgba(132,0,64,255)"
|
||||
],
|
||||
[
|
||||
"484.14613609848493",
|
||||
"rgba(96,0,96,255)"
|
||||
],
|
||||
[
|
||||
"828.0750235961099",
|
||||
"rgba(48,0,48,255)"
|
||||
]
|
||||
],
|
||||
"labelConfig": {
|
||||
"showLabels": true,
|
||||
"color": "#000000"
|
||||
},
|
||||
"lvlMinMax": [
|
||||
-57.09136148261278,
|
||||
828.0750235961099
|
||||
],
|
||||
"lineConfig": {
|
||||
"showLines": true,
|
||||
"color": "#000000",
|
||||
"lineType": "solid"
|
||||
}
|
||||
}
|
||||
},
|
||||
"msg": "成功"
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
{
|
||||
"code": 200,
|
||||
"data": {
|
||||
"id": "1437832432312320",
|
||||
"projectId": "1434842515398656",
|
||||
"templateId": null,
|
||||
"dsObjectId": "1434990492565504",
|
||||
"tmObjectId": "1434857871704064",
|
||||
"graphicArea": 153.93909725108225,
|
||||
"properties": {
|
||||
"lvlSchemeType": "normal",
|
||||
"colorBar": [
|
||||
[
|
||||
"0.00",
|
||||
"#00008B"
|
||||
],
|
||||
[
|
||||
"1.51",
|
||||
"rgba(0, 0, 170, 1)"
|
||||
],
|
||||
[
|
||||
"2.27",
|
||||
"rgba(0, 0, 211, 1)"
|
||||
],
|
||||
[
|
||||
"3.43",
|
||||
"#0000FF"
|
||||
],
|
||||
[
|
||||
"5.17",
|
||||
"rgba(0, 128, 255, 1)"
|
||||
],
|
||||
[
|
||||
"7.79",
|
||||
"#00FFFF"
|
||||
],
|
||||
[
|
||||
"11.75",
|
||||
"rgba(0, 192, 128, 1)"
|
||||
],
|
||||
[
|
||||
"17.72",
|
||||
"#00FF00"
|
||||
],
|
||||
[
|
||||
"26.73",
|
||||
"rgba(0, 128, 0, 1)"
|
||||
],
|
||||
[
|
||||
"40.30",
|
||||
"rgba(128, 192, 0, 1)"
|
||||
],
|
||||
[
|
||||
"60.77",
|
||||
"#FFFF00"
|
||||
],
|
||||
[
|
||||
"91.64",
|
||||
"rgba(191, 128, 0, 1)"
|
||||
],
|
||||
[
|
||||
"138.20",
|
||||
"rgba(255, 128, 0, 1)"
|
||||
],
|
||||
[
|
||||
"208.40",
|
||||
"#FF0000"
|
||||
],
|
||||
[
|
||||
"314.20",
|
||||
"rgba(211, 0, 0, 1)"
|
||||
],
|
||||
[
|
||||
"473.80",
|
||||
"rgba(132, 0, 64, 1)"
|
||||
],
|
||||
[
|
||||
"714.50",
|
||||
"rgba(96, 0, 96, 1)"
|
||||
],
|
||||
[
|
||||
"1323.20",
|
||||
"rgba(48, 0, 48, 1)"
|
||||
]
|
||||
],
|
||||
"equalAreaLayerCount": 10,
|
||||
"labelConfig": {
|
||||
"showLabels": true,
|
||||
"color": "#000000"
|
||||
},
|
||||
"logLinesCount": 8,
|
||||
"lineConfig": {
|
||||
"showLines": true,
|
||||
"color": "#000000",
|
||||
"lineType": "dashed",
|
||||
"zmin": 0,
|
||||
"zmax": 1323.2
|
||||
}
|
||||
}
|
||||
},
|
||||
"msg": "成功"
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Loading…
Reference in New Issue