10 KiB
STEP-070 MapLibreParticleLab V3-06 四类场 Fixture 与 RN 通用回归 — Codex 任务 v1
1. 目标
基于 particle/main 当前 HEAD 3b012759838f1e1ecc44559faffe061d396b6cce,完成 V3 通用 Scalar/Vector Field 的离线业务语义映射与回归资产:Wind、Rain、Wave、Tide/Current 四类场,外加固定 synthetic Wave independence fixture。
本 Step 的重点不是增加新的 Runtime 架构,而是证明 STEP-065~069 冻结的通用契约能够由真实/可追溯数据映射并通过 .3 RN 公共 API 驱动。Android 编译/安装/ADB/设备视觉验证继续留到后续统一周期,不在本任务执行。
开始前完整阅读 AGENTS.md、PARTICLE_BASELINE.md、docs/00_项目规范/、STEP-065~069 Step/报告,以及当前实际源码。不得按记忆重建。
2. 必须保持的架构边界
- Core/Renderer 不得出现 Wind/Wave/Rain/Tide/provider/network/vendor 业务分支。
- Host/RN 负责业务字段到 canonical scalar/vector/validity 的映射。
- canonical schema 继续使用
maplibre-particle-field/v2。 - 一个 Snapshot:0/1 scalar + 0/1 vector + shared validity;neither 非法。
- Wind / Tide(Current):vector
VELOCITY,Field=VECTOR_MAGNITUDE,Particle 使用 VELOCITY。 - Rain:scalar rain rate,Field=
SCALAR,不启用 Particle。 - Wave:scalar=wave height;vector=direction-to unit vector;semantics=
DIRECTION;Field=SCALAR;Particle=DIRECTION,推进视觉速度只来自advectionScale。 - Wave period 不进入第二 scalar,不参与推进,不从 height/period 推导速度。
- Rain precipitation_type 暂不进入 canonical V3.0。
- T0/T1/MIX、Timeline、Playback、OLD_T1→NEW_T0 reuse 等 Core 逻辑不得修改。
3. 当前基线事实
- RN package 已是
@navsea/maplibre-particle-rn@13.4.1-particle.3。 - 正式 v2 API:
FieldRuntime.submitField(reactTag, metadataJson, payloadRefs)。 payloadRefs为必填 validity + optional scalar/vector local file URI,scalar/vector 至少一个。.3已提供setFieldValueSource()与setParticleAdvectionScale()。- Android/JNI/Core multi-plane ingress 已实现,但 Android 编译留待 V3-08。
- 现有 RN Test Host 的 REAL WEATHER 仍直接调用旧
WeatherRuntimeBridge.submitWindField();本 Step 必须迁移验证入口到 package.3的FieldRuntime,不能继续用旧 bridge 证明新 API。 - 仓库已有真实 WeatherV2 Wind canonical 资产:
platform/android/MapLibreAndroidTestApp/src/main/assets/integration/particle-weatherv2/ecmwf-hres-wind-20260807/。 - WeatherV2 源树只读位于
/root/sourceserver/weatherV2;其 NSFT v1 语义以src/dev/core/nsft.py和当前生产 pipeline 为准。不要修改 WeatherV2。
4. 数据来源与可追溯性
先调查 /root/sourceserver/weatherV2 当前实际输出,优先从已存在的 NSFT v1 field_pmtiles//fields 等本地数值产物生成 fixture,不联网、不重新跑完整生产 pipeline。
至少为以下四类场确认一个可用 source/refTime/validTime/区域:
- Wind
- Rain
- Wave
- Tide/Current
优先选日本及周边、相邻两个实际 validTime,便于 T0/T1/MIX。若某层当前本地没有可用正式 NSFT 数值产物,不得伪称“真实 WeatherV2”;应在报告明确说明并使用最小可追溯 synthetic/decoder-derived fallback,同时保留该层的业务语义。Wind 已有真实 canonical 基线可直接复用/升级。
不得把旧 QBIN 当作正式未来 transport。若为数据核验读取旧 BIN,只能作为来源调查/对照,最终 fixture 必须输出 v2 canonical planes。
5. 新建通用 fixture/converter 工具
在 tools/ 下新增 provider-neutral 或 WeatherV2-to-canonical 的离线工具,具体目录名由实际实现确定,但不得只为 Wind 特化。
工具至少应支持把已解码/NSFT 数值场规范化为:
metadata.jsonvalidity.u8- optional
scalar.f32 - optional
vector.f32(interleaved U/V) conversion_summary.json
约束:
- float32-le;validity uint8;NW-origin row-major;rows north→south;cols west→east。
- U eastward,V northward。
- 每个输出文件记录 byteLength、SHA-256、grid、bounds、validTime、generation、source provenance。
- vector DIRECTION 必须在 valid cell 上接近 unit length;允许原始量化误差,转换后可规范化,但近零/非 finite 必须 invalid/fail-closed,不得任造方向。
- shared validity 必须由源有效性与所有存在 channel 的有限性共同约束;invalid cell 的具体 payload 值可为 0,但 validity=0 才是权威。
- metadata 中不允许 Wind/Wave/Rain/Tide capability enum;
fieldId可包含可读 fixture 名称但 Core 不依赖它。
6. 四类 fixture 目录
新增仓库内固定测试资产,建议:
integration/particle-v3-fields/
至少:
wind-real/:两个相邻 validTime,vector-only VELOCITY。rain-real/:两个相邻 validTime,scalar-only。wave-real/:两个相邻 validTime,scalar+vector DIRECTION。tide-real/:两个相邻 validTime,vector-only VELOCITY。wave-synthetic-independence/:两个兼容时次或至少足以验证 T0/T1 的 fixture。
若某 *-real 因本机数据缺失只能 fallback,目录名不得误用 real;改用 *-decoder-fixture 或等价明确命名,并在 dataset manifest/报告写明来源。
每组 fixture 提供 dataset.json,列出 frame 顺序、metadata/plane 路径、expected FieldValueSource、particle expected on/off、vector semantics、建议 advectionScale(Wave synthetic 可指定非 1 值用于验证 scale 独立性)。
7. Synthetic Wave Independence 固定语义
必须实现并静态验证:
- scalar(wave height)西侧低、东侧高,形成明显 E→W 或 W→E 的横向数值梯度;
- vector 在所有 valid cell 固定向北
(u=0, v=1); vectorSemantics=DIRECTION;- Field source=
SCALAR; - Particle 方向应只由 vector 决定为北向;scalar 改变不得改变粒子方向/推进 magnitude;
- 改
advectionScale只改变 DIRECTION visual movement magnitude,不改变 field scalar。
增加无 Android 的数据 oracle/脚本验证该 fixture:scalar 的东西梯度与 vector 的北向独立,不允许只靠人工阅读 JSON。
8. RN Test Host 升级到 .3 正式 API
只修改 Test Host 的 JS/TS 与离线 assets/config,不执行 Gradle。
要求:
- REAL WEATHER/V3 验证入口从内部
WeatherRuntimeBridge.submitWindField迁移到@navsea/maplibre-particle-rn的FieldRuntime。 - 不从 package 内部路径 import bridge。
- 通过 app cache/local file URI 提交 metadata + plane refs;不得 JS number[] / base64 / giant JSON。
- 提供四类场选择/加载能力,至少能在 UI/fixture runner 中选择 Wind/Rain/Wave/Tide 和 synthetic Wave。
- 每次切换 dataset 前
clearFields(),设置正确的setFieldValueSource()、Particle visibility、setParticleAdvectionScale(),再顺序提交 T0/T1。 - 对每个 dataset 明确断言:T0=
ACCEPTED_PENDING_INITIAL_WINDOW,T1=INITIAL_WINDOW_READY,runtime state=READY。 - Rain 必须 Particle OFF;Wind/Tide Particle ON;Wave Particle ON 且 DIRECTION 数据不被改成 VELOCITY。
- Field/Particle visibility 仍独立。
- 不在 JS 保存 T0/T1/MIX 第二份 Runtime 状态;JS 只保存 fixture/选择 UI 与调用结果。
- 现有 GSI/base map 与已验证 UI 可保留,不做无关重构。
9. Core/Linux 回归
新增最小 C++/数据 contract 测试,重点不是复制完整 Android bridge,而是验证:
- 四类 canonical shape 能被
LocalParticleFieldFeed/RasterArraySource接受。 - Wind/Tide vector-only VELOCITY compatible T0/T1。
- Rain scalar-only compatible T0/T1。
- Wave scalar+vector DIRECTION compatible T0/T1。
- channel presence/semantics mismatch 继续 fail-closed。
- synthetic Wave 的 scalar/vector independence oracle。
- normal T0→T1 / next snapshot 不修改 Runtime 算法。
如果现有 test 已覆盖底层形状,不重复堆测试;新增 fixture-specific contract test 即可。
10. 本 Step 不做
- 不执行 Android Gradle/AAR/APK/ADB/设备测试。
- 不执行 Jest。
- 不修改 NavSea。
- 不修改 WeatherV2 源项目。
- 不联网下载天气数据。
- 不引入 provider/network/cache/manifest runtime 到 C++ Core。
- 不改 v2 schema、Timeline/Playback、shader 数学、DIRECTION 算法。
- 不发布 npm/tgz/tag;
.3仅保持源码版本。 - 不修改 STEP-062 两处现有用户 dirty 文档,不清理历史 untracked/build/cache。
11. 必须验证
至少执行并记录:
- fixture converter/validator 自检 PASS,含 plane byteLength/SHA/grid/bounds/time/finite/validity。
- synthetic Wave independence oracle PASS。
- package
.3TypeScripttsc --noEmitPASS。 - RN Test Host TypeScript/typecheck PASS(使用项目现有命令,不跑 Jest)。
- RN TurboModule codegen schema 检查 PASS,确保 STEP-069 ABI 未被破坏。
- 受影响 Core 精确对象编译 PASS。
- 相关 C++ fixture/Source 过滤测试 PASS。
git diff --checkPASS。
所有 noisy build 使用 $build-output-throttle。若完整 mbgl-test/runner 已经最新可直接使用;若因改 C++ test 触发重链,允许 Linux 重链。
12. 文档输出
必须生成/更新:
- 本任务书。
docs/50_Step记录/STEP-070_MapLibreParticleLab_V3-06_四类场Fixture与RN通用回归_v1.mddocs/报告/STEP-070_MapLibreParticleLab_V3-06_四类场Fixture与RN通用回归_Codex完成报告_v1.md- 追加
粒子开发记录.md - 新工具 README / fixture dataset manifest 必须中文说明为主。
状态上限:IMPLEMENTED / WAITING_ANDROID_VALIDATION。不得标记 Android CLOSED/PASS。
13. Git 收尾
所有本任务实际修改必须 scoped commit 并 push origin/particle/main。
- 开始/结束都核对 branch、HEAD、origin。
- 严禁
git add ./git add -A。 - 不提交 STEP-062 两处用户 dirty、历史任务 MD、build/cache/tgz。
- 可使用 1 个实现 commit + 1 个文档 handoff commit;必要时再用一个纯 Git 元数据收尾 commit。
- 完成报告记录 implementation/handoff commit、push result、remote branch、Final HEAD、
HEAD == origin/particle/main。 - push 失败不得声称完成。