Author SHA1 Message Date
GF3 Pipeline Bot ddf6b64412 Document data management upgrade plan 2026-07-13 16:37:46 +08:00
2 changed files with 275 additions and 0 deletions
+4
View File
@@ -46,6 +46,10 @@ Before processing each scene, the wrapper checks the scene output directory for
More details: [docs/sarscape_go_wrapper.md](docs/sarscape_go_wrapper.md) More details: [docs/sarscape_go_wrapper.md](docs/sarscape_go_wrapper.md)
## Data Management Roadmap
The processing workflow is expected to handle mixed GF3/GF3B/GF3C inputs, both L1A and L2 products, archive-name metadata parsing, and persistent product/task tracking. The proposed upgrade path is documented in [docs/data_management_upgrade_plan.md](docs/data_management_upgrade_plan.md).
## Python Pipeline ## Python Pipeline
Use an environment that already has working GDAL/OSGeo Python bindings. On Windows, Conda/Miniforge is usually the least fragile route. Use an environment that already has working GDAL/OSGeo Python bindings. On Windows, Conda/Miniforge is usually the least fragile route.
+271
View File
@@ -0,0 +1,271 @@
# GF3 数据管理升级方案
本文档记录 GF3 L1A 到 L2 管线升级为数据管理系统的设计方向。当前仓库已经包含两条处理路径:
- SARscape Go wrapper:面向 Windows、ENVI/IDL Runtime 和 SARscape 的生产处理路径。
- Python pipeline:基于 GDAL/Rasterio/NumPy 的纯 Python 处理路径。
后续业务不再只是单批次 L1A 处理。输入可能已经是 L2,也可能是 L1A;卫星平台可能是 GF3、GF3B、GF3C;数据需要被发现、登记、查询、调度、归档和复跑。因此建议把项目从“处理脚本”升级为“产品识别 + 数据库存档 + 处理任务编排 + 执行器”的结构。
## 目标
1. 统一识别 GF3、GF3B、GF3C 产品。
2. 同时管理 L1A 原始产品和 L2 成果产品。
3. 尽量从压缩包名或文件名中解析产品基本信息,包括中心经纬度。
4. 用数据库记录产品、任务、产物和失败原因,避免只依赖目录结构。
5. 保留现有 SARscape Go wrapper 作为生产执行器,避免一次性重写稳定处理链。
6. 为后续 Web 管理界面、地图查询、批处理调度、报表导出预留数据模型。
## 总体架构
```text
输入目录 / NAS / 历史输出
|
v
产品发现与命名解析
|
v
产品库 SQLite
|
+--> L2 产品登记、索引、查询
|
+--> L1A 待处理任务生成
|
v
执行器调度层
|
+--> SARscape Go wrapper
+--> Python pipeline
|
v
L2 产物登记和任务状态更新
```
## 产品识别模型
建议新增统一产品模型,例如 `ProductInfo`
| 字段 | 说明 |
| --- | --- |
| `product_id` | 产品唯一标识,优先使用产品号或完整场景名 |
| `scene_name` | 不含压缩包扩展名的场景名 |
| `satellite` | `GF3``GF3B``GF3C` |
| `level` | `L1A``L2`,必要时扩展到其他级别 |
| `mode` | 成像模式,例如 `FSI``FSII` 等 |
| `polarizations` | 标准化后的极化列表,例如 `HH,HV` |
| `acquisition_date` | 成像日期 |
| `center_lon` | 从文件名或元数据解析的中心经度 |
| `center_lat` | 从文件名或元数据解析的中心纬度 |
| `source_type` | `archive``metadata_xml``directory``sarscape_product` |
| `source_path` | 当前发现的源路径 |
| `metadata_path` | 元数据 XML 路径,未解压时可为空 |
| `archive_path` | 压缩包路径,非压缩产品可为空 |
| `size_bytes` | 文件或目录大小 |
| `mtime` | 源数据最后修改时间 |
| `checksum` | 可选,后续用于完整性校验 |
| `status` | `discovered``registered``processing``processed``failed``archived` |
产品识别应允许“文件名解析先行,元数据补全兜底”。压缩包尚未解压时,系统也应能建立基本索引;等需要处理或做精确校验时,再从 metadata XML 补充字段。
## 文件名解析
现有样例:
```text
GF3_MH1_FSII_051377_E132.3_N48.2_20260514_L1A_HHHV_L10007356478.tar.gz
```
可解析为:
| 字段 | 值 |
| --- | --- |
| `satellite` | `GF3` |
| `mode` | `FSII` |
| `center_lon` | `132.3` |
| `center_lat` | `48.2` |
| `acquisition_date` | `2026-05-14` |
| `level` | `L1A` |
| `polarizations` | `HH,HV` |
| `product_id` | `L10007356478` |
解析规则建议:
1. 卫星字段匹配 `GF3``GF3B``GF3C`
2. 经度匹配 `E132.3``W132.3`,转换为正负浮点数。
3. 纬度匹配 `N48.2``S48.2`,转换为正负浮点数。
4. 日期匹配连续 8 位数字,并转换为 `YYYY-MM-DD`
5. 级别匹配 `L1A``L2`,后续可扩展。
6. 极化字段支持 `HH``HV``VH``VV` 及组合字段,例如 `HHHV`
7. 解析失败不能阻止登记,应记录 `parse_status``parse_message`
GF3B/GF3C 的命名如果与 GF3 不完全一致,应通过多个 parser 版本兼容,而不是把所有规则压进一个不可维护的正则。
## 数据库设计
第一阶段建议使用 SQLite。它部署简单、便于随仓库工具使用,也能支撑批量目录索引和本地管理。未来如果需要多用户并发或 Web 服务,可以迁移到 PostgreSQL/PostGIS。
### `products`
记录发现到的 L1A、L2 和其他可识别产品。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | INTEGER PRIMARY KEY | 内部 ID |
| `product_id` | TEXT | 产品号或业务唯一标识 |
| `scene_name` | TEXT | 场景名 |
| `satellite` | TEXT | GF3/GF3B/GF3C |
| `level` | TEXT | L1A/L2 |
| `mode` | TEXT | 成像模式 |
| `polarizations` | TEXT | 逗号分隔的极化 |
| `acquisition_date` | TEXT | ISO 日期 |
| `center_lon` | REAL | 中心经度 |
| `center_lat` | REAL | 中心纬度 |
| `source_type` | TEXT | archive/metadata_xml/directory/sarscape_product |
| `source_path` | TEXT UNIQUE | 源路径 |
| `metadata_path` | TEXT | 元数据路径 |
| `archive_path` | TEXT | 压缩包路径 |
| `size_bytes` | INTEGER | 大小 |
| `mtime` | TEXT | 修改时间 |
| `checksum` | TEXT | 可选校验 |
| `parse_status` | TEXT | ok/partial/failed |
| `parse_message` | TEXT | 解析说明 |
| `created_at` | TEXT | 入库时间 |
| `updated_at` | TEXT | 更新时间 |
### `processing_tasks`
记录 L1A 到 L2 的处理任务。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | INTEGER PRIMARY KEY | 任务 ID |
| `input_product_id` | INTEGER | 输入产品 |
| `output_product_id` | INTEGER | 输出产品,可为空 |
| `executor` | TEXT | `sarscape_go``python_gdal` |
| `status` | TEXT | pending/running/succeeded/failed/skipped |
| `requested_polarizations` | TEXT | 请求处理的极化 |
| `dem_path` | TEXT | DEM 路径 |
| `output_dir` | TEXT | 输出目录 |
| `attempt_count` | INTEGER | 尝试次数 |
| `started_at` | TEXT | 开始时间 |
| `finished_at` | TEXT | 结束时间 |
| `error_message` | TEXT | 失败原因 |
| `config_json` | TEXT | 处理参数快照 |
### `artifacts`
记录最终成果、中间成果、日志和快视图。
| 字段 | 类型 | 说明 |
| --- | --- | --- |
| `id` | INTEGER PRIMARY KEY | 产物 ID |
| `product_id` | INTEGER | 所属产品 |
| `task_id` | INTEGER | 所属任务 |
| `artifact_type` | TEXT | geo/sml/hdr/quicklook/log/intermediate |
| `polarization` | TEXT | HH/HV/VH/VV |
| `path` | TEXT UNIQUE | 文件路径 |
| `size_bytes` | INTEGER | 文件大小 |
| `mtime` | TEXT | 修改时间 |
| `is_final` | INTEGER | 是否最终交付成果 |
## CLI 演进
建议在现有 `gf3-l1a2l2` CLI 下新增 `inventory``tasks` 子命令:
```powershell
gf3-l1a2l2 inventory init --db .\gf3_inventory.sqlite
gf3-l1a2l2 inventory scan --input D:\GF3 --db .\gf3_inventory.sqlite
gf3-l1a2l2 inventory list --level L1A --satellite GF3B --db .\gf3_inventory.sqlite
gf3-l1a2l2 inventory export --format geojson --output scenes.geojson --db .\gf3_inventory.sqlite
gf3-l1a2l2 tasks create-l2 --input-query "level=L1A,status=registered" --output E:\GF3\L2 --db .\gf3_inventory.sqlite
gf3-l1a2l2 tasks run --executor sarscape_go --db .\gf3_inventory.sqlite
gf3-l1a2l2 tasks retry --failed --db .\gf3_inventory.sqlite
```
Go wrapper 可以保留现在的命令行接口,同时后续增加一种任务配置输入:
```powershell
gf3wrapper.exe -task task_123.json
```
这样数据库调度层负责生成标准任务文件,Go wrapper 只负责稳定执行 SARscape 处理。
## L1A 与 L2 的处理策略
| 输入类型 | 策略 |
| --- | --- |
| L1A 压缩包 | 登记产品;如缺 L2,则生成处理任务 |
| L1A 解压目录 | 登记产品;可直接进入处理任务 |
| L1A metadata XML | 登记产品;以所在目录作为场景目录 |
| L2 SARscape 输出 | 登记最终产物;不再重复处理 |
| L2 压缩包或目录 | 登记为 L2 产品;解析中心点和时间后进入可查询状态 |
| 无法识别数据 | 记录为 `parse_status=failed`,留给人工处理 |
对于已经存在的 L2 数据,系统应优先入库并校验完整性,而不是重新从 L1A 处理。完整性校验可以沿用现有 Go wrapper 的思路:最终 `*_geo.sml` 和匹配主数据文件必须存在且非空。
## 执行器边界
### SARscape Go wrapper
继续作为生产主执行器。后续增强重点:
1. 处理完成后校验请求极化的最终 `*_geo.sml` 和主数据文件。
2. 若 IDL/SARscape 只打印错误但进程返回 0,仍应根据产物校验判定失败。
3. `-keep-extracted` 需要真正控制 `.gf3_extract` 是否保留。
4. 输出任务结果 JSON,便于数据库层读取。
### Python pipeline
继续作为可测试、可扩展的备用执行器。后续增强重点:
1. 增加 inventory 数据模型和扫描命令。
2. 解压失败应进入任务失败状态,而不只是写日志。
3. 明确 HH/HV/VH/VV 支持范围,与 SARscape 路径保持文档一致。
4. 补充发现、解压、命名解析、任务状态的单元测试。
## 分阶段实施计划
### 阶段 1:产品识别和解析
- 新增产品模型。
- 新增文件名 parser。
- 覆盖 GF3、GF3B、GF3C、L1A、L2、E/W/N/S 坐标测试。
- 新增 `inventory scan` 的只读扫描能力,不改变现有处理链。
### 阶段 2SQLite 产品库
- 新增数据库初始化和 upsert。
- 扫描目录后写入 `products`
- 支持按卫星、级别、日期、中心点范围查询。
- 支持 CSV/GeoJSON 导出。
### 阶段 3:任务管理
- 新增 `processing_tasks``artifacts`
- 根据 L1A 产品和缺失 L2 的条件生成任务。
- 记录失败原因、重试次数和处理参数。
- 处理已有 L2 产品的入库和完整性校验。
### 阶段 4:执行器整合
- 数据库层调用 SARscape Go wrapper 或 Python pipeline。
- Go wrapper 输出结构化结果。
- 处理完成后自动登记 L2 产物和日志。
- 支持断点续跑和失败重试。
### 阶段 5:管理界面和报表
- 增加简单 Web UI 或桌面管理工具。
- 支持地图查看中心点。
- 支持按日期、卫星、级别、状态筛选。
- 支持导出批处理报告和归档清单。
## 当前仓库需要优先修正的点
1. Python 测试需要标准化运行方式。当前直接运行 `python -m unittest discover -s tests` 时,`src/` 不在 import path 中。
2. Python 环境文件已有依赖,但当前系统 Python 未安装 `pytest`。应在 README 中强调使用 Conda 环境或 editable install。
3. Go wrapper 的 `-keep-extracted` 当前主要是配置字段,后续应补实际行为。
4. SARscape/IDL 脚本失败是否能反映到进程退出码需要验证,建议增加处理后产物完整性校验。
5. 现有未跟踪的目录报告 `docs/20260514_directory_report.md` 可以作为真实输出组织结构参考,确认后再决定是否纳入版本库。