# 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` 的只读扫描能力,不改变现有处理链。 ### 阶段 2:SQLite 产品库 - 新增数据库初始化和 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` 可以作为真实输出组织结构参考,确认后再决定是否纳入版本库。