Files
MapLibreParticleLab/docs/报告/STEP-054_真实WeatherV2风数据提取与Canonical测试数据生成_Codex完成报告_v1.md
OpenAI Codex da71c8784e
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled
docs: record STEP-054 canonical data handoff
2026-09-04 21:09:00 +08:00

4.9 KiB
Raw Permalink Blame History

STEP-054 真实 WeatherV2 风数据提取与 Canonical 测试数据生成 Codex 完成报告

完成状态

本任务已完成 WeatherV2 真实风场到 canonical Android 测试 asset 的离线转换。当前状态为:IMPLEMENTED / WAITING_NEXT_ANDROID_INTEGRATION_VALIDATION。

  • Starting HEAD:5fc922785d8ec007127d48cd3ab5dadce270b947
  • 分支:particle/main
  • WeatherV2 源目录(只读):/root/sourceserver/weatherV2/src/dev/_runtime/dev_pipeline_data/datasets/ecmwf-hres/wind/2026080600
  • 实际 validTime:2026080700、2026080706、2026080712、2026080718

已查明的 WeatherV2 格式与语义

以用户提供的《NavSea 天气风数据取数与使用报告》作为 QBIN/NSFT 语义背景,并实际检查 WeatherV2 src/dev/core/bin_export.py、src/dev/layers/wind.py、src/dev/core/qbin_export.py、src/dev/core/qbin.py、src/dev/core/field_pmtiles.py 和 src/dev/core/nsft.py。

wind_vectors.bin 是 weather-v2-particle-bin-v1 的完整拼接 export,不是 QBIN/NSFT:

WVECBIN1 → uint32-le header length → JSON header → U float32-le plane → V float32-le plane → speed float32-le plane → valid uint8 plane。

实际 grid 为 513×769,row-major,bounds 为 west 112.5、south 0.0、east 157.5、north 55.77657301866769,单帧源文件为 5,128,989 bytes。Web Mercator tile y 向南增加,故 row 是 north-to-south、column 是 west-to-east。

decode_wind() 将 decoded R 作为 U、decoded G 作为 V;writer metadata 说明 U=eastward-positive、V=northward-positive。QBIN u_q/v_q 和 NSFT 均从同一 decoded Field 生成;QBIN metadata 明确 m/s、scale=0.01。因此 WVECBIN1 的本次 U/V 单位确认是 m/s,没有猜测或进行 kt 换算。valid/noData 也同源:源 valid plane 为 uint8;canonical 将 invalid/非有限 U/V 转为现有 noData=-9999.0 pair,绝不写作静风。

输出与一致性

新增独立开发工具 tools/weatherv2_wind_canonical/convert_weatherv2_wind.py 和中文 README;工具只读取输入,不依赖 Android Runtime、不引入网络/provider 逻辑。输出位于:

platform/android/MapLibreAndroidTestApp/src/main/assets/integration/particle-weatherv2/ecmwf-hres-wind-20260807/

四帧均保留完整实际范围,不裁剪、不重采样。每个 field.f32 是现有 float32-le interleaved-uv,3,155,976 bytes;metadata 复用 maplibre-particle-field/v1,validTime 为真实 UTC epoch milliseconds,generation/dataVersion 为 producer-owned、严格递增的同值。dataset.json 只是一份开发期 asset 索引,不是 Weather Manifest。

validTime SHA-256 valid / invalid source→canonical max U/V error
2026080700 363e2cd2e77501f6bceecbb4aaa68c4f9ef46998a60319ae5b7aba3548995283 394497 / 0 0 / 0
2026080706 ef7a8e4b1c47f652f8f7012de16a87c16e3b25556a8f4686629f80514426c451 394497 / 0 0 / 0
2026080712 d86a6a51fd5216cf9368756962a5366fd32a627afd40cfde235ba7358c02c5a0 394497 / 0 0 / 0
2026080718 970785b0334a9d1511b8897874a81f681814a32b1e0b90e37cf64b77ca9fa39b 394497 / 0 0 / 0

四个 payload hash 均不同,避免了误复制同一帧;相同输入重复转换 T0 的 SHA-256 相同,确认 deterministic。

验证结果

  • 转换器 Python syntax、四时次成功转换、metadata JSON、binary length、validTime 严格递增、hash 一致性与四帧差异:PASS。
  • 8 个确定性抽样点(中心、角附近、内部)与全量有效数组的无损映射检查:PASS,最大 U/V 误差均为 0。
  • 无效 source directory:明确报错并非零退出:PASS。
  • cmake --build build-linux-opengl --target mbgl-test-runner -j3:PASS(无 C++ 改动,target 已最新)。
  • 既有 ParticleFieldDataAdapter、Local production feed、canonical U/V、Host submission/invalid 定向测试:5/5 PASS。
  • git diff --check:PASS。

范围与未执行项

未修改 WeatherV2 原始数据、MapLibre Core、Descriptor/Snapshot/Adapter、Timeline、Runtime Field Window、Renderer、Android Kotlin/JNI。没有把 Weather Service、HTTP、Provider、QBIN/NSFT download、缓存或目录扫描加入 MapLibre Runtime。

未执行 Android Gradle、APK build/install、ADB、App/设备/模拟器测试或 Jest。真实 asset 的 MapLibre map + WeatherColorLayer + RasterParticleLayer + playback Android 综合验收留给下一独立任务;本任务不进入 React Native Binding 或 UI 改造。

Git 信息

  • 实现 commit:79d4aa6385275662bd892100bf282d6903f9fdc0
  • commit message:feat: add WeatherV2 wind canonical converter
  • remote branch:origin/particle/main
  • push result、Final HEAD:在本报告提交后的 Git 收尾确认。
  • 无关 untracked 文件未修改、未 stage、未提交;包括用户任务书、指定的天气报告与历史 STEP-046-e48fa087-review.diff。

阻塞项:无。下一步只应在单独阶段消费本 canonical asset 完成 Android 综合可视化验证。