docs: add STEP-062 RN weather map task
Some checks failed
validate-scripts / validate-scripts (push) Has been cancelled

This commit is contained in:
OpenAI Codex
2026-09-09 09:03:27 +08:00
parent 729d22169d
commit 364596574a

View File

@@ -0,0 +1,346 @@
# STEP-062 RN Test Host 真实 WeatherV2 底图粒子综合验证 — Codex任务 v1
## 1. 任务定位
当前正式分支:`particle/main`。
开工基线:
- STEP-061 已正式 `CLOSED / PASS`。
- 当前 local / remote HEAD 均为 `729d22169da5cb2d5a4eafbded8dde894739dee6`。
- Native/Core 冻结制品:`org.maplibre.gl:android-sdk-opengl:13.4.1-step061`。
- STEP-062 不进入 NavSea,只在 `MapLibreParticleRNTestHost` 内完成接近最终使用形态的天气地图综合验证。
本阶段目标不是继续扩展 AAR,而是证明:
```text
GSI 底图
+
真实 WeatherV2 canonical T0/T1/T2/T3
+
WeatherColorLayer
+
RasterParticleLayer
+
Timeline / Playback
```
在 React Native Test Host APK 中可以稳定共同工作。
## 2. 最高优先级边界
本任务默认**禁止修改和禁止重新构建 AAR**:
- 不修改 `src/`、`include/` 下 MapLibre Native/Core 粒子实现;
- 不修改 `platform/android/MapLibreAndroid`;
- 不修改 JNI;
- 不修改 `WeatherRuntime.java`;
- 不修改 STEP-061 Binary ingress;
- 不执行 `make apackage`;
- 不执行 Maven Local publish;
- 不生成新的 `13.4.1-step062` AAR;
- 不进入 NavSea。
Test Host 继续固定消费已经通过实机验收的:
```text
org.maplibre.gl:android-sdk-opengl:13.4.1-step061
```
如果实现或 Android 验收证明 `step061` Native/Core 存在真实阻塞缺陷,必须停止扩大 STEP-062,并在报告中明确 `BLOCKED_BY_NATIVE`;不得为了方便顺手改 Core 后重出 AAR。
## 3. 开工前必读与真实基线
必须先读取并遵守:
1. `AGENTS.md`
2. `PARTICLE_BASELINE.md`
3. `docs/00_项目规范/` 当前规范
4. `docs/50_Step记录/STEP-061_Binary_UV_Field_Transport_v2.md`
5. `docs/报告/STEP-061_Android最终验收报告_v1.md`
6. `docs/50_Step记录/STEP-055_Android真实WeatherV2风场综合可视化_v7.md`
7. `docs/20_调查/STEP-056_RN天气渲染桥接现状调查_v1.md`
8. `integration/react-native/MapLibreParticleRNTestHost/` 当前实际源码
9. Android Validation 中当前 GSI / REAL WEATHER 的实际实现,不得凭记忆重写。
当前已确认事实:
- RN Test Host 的底图目前只是 `background-color: #10243a`,没有真实地图瓦片。
- Android Validation 已使用 GSI 标准地图:`https://cyberjapandata.gsi.go.jp/xyz/std/{z}/{x}/{y}.png`,tileSize=256,maxzoom=18。
- 当前真实 WeatherV2 数据为 ECMWF HRES 2026-08-07 四帧:`2026080700/06/12/18`。
- 每帧 grid=`513×769`,payload=`3,155,976 bytes`。
- bounds=`west 112.5 / south 0.0 / east 157.5 / north 55.77657301866769`。
- canonical contract 仍是 `maplibre-particle-field/v1`、`float32-le`、`interleaved-uv`、U eastward、V northward。
- RN bridge 已有 `submitWindField`、forecast time、PLAY/PAUSE、playback speed、WeatherColor stops、particle/trail color、粒子视觉参数、targetFps、getState;本阶段不新增 Native API。
## 4. 真实 WeatherV2 资产
源资产固定来自:
```text
platform/android/MapLibreAndroidTestApp/src/main/assets/integration/particle-weatherv2/
ecmwf-hres-wind-20260807/
```
把本阶段实际需要的 `dataset.json`、四份 `metadata.json`、四份 `field.f32` **原样复制**到 RN Test Host 自己的受控 assets 目录,例如:
```text
integration/react-native/MapLibreParticleRNTestHost/assets/weather/
ecmwf-hres-wind-20260807/...
```
要求:
- 不重新生成、不重采样、不裁剪、不改 metadata;
- 不把 `.f32` 转成 JSON、base64、hex 或 `number[]`;
- 复制后逐文件 SHA-256 与源资产一致;
- `field.f32` 内容必须与已有 Git blob 完全一致;
- 不创建第二套“近似 WeatherV2”测试数据。
## 5. RN 资产加载与 Binary transport
继续使用 STEP-061 的正式 file-reference transport,不新增第二条路径。
建议实现:
1. 将 `expo-asset` 作为 Test Host 的明确直接依赖,版本保持当前 Expo 56 兼容范围,不升级 Expo/RN。
2. 新增 `metro.config.js`,只补充 `.f32` 为 asset extension;不得改动无关 Metro 行为。
3. 新增一个小型 `realWeatherDataset.ts`(或等价文件),用静态 `require()` 注册四帧 `.f32` asset 与 metadata。
4. 通过 `Asset.fromModule(...).downloadAsync()` 获得 app 本地 `file://` URI。
5. metadata 继续以小型 JSON string 传入;payload 只传本地文件引用。
6. 不在 JS 中把 3.01 MiB payload materialize 成数值数组;不做 base64。
必须明确显示并验证:
```text
REAL DATA TRANSPORT = FILE_REF / FLOAT32_LE / INTERLEAVED_UV
```
若 Expo Asset 最终不能稳定给出本地文件 URI,先报告阻塞;不要退回 base64/number[]。
## 6. GSI 底图
将 RN Test Host 的纯色背景升级为真实 GSI 标准底图。
Style 最小结构固定为:
```text
background
GSI raster basemap
WeatherColorLayer
RasterParticleLayer
```
要求:
- raster source 使用 Android Validation 已验证 URL;
- source 写明合适 attribution(至少标明国土地理院 / GSI);
- tileSize=256,maxzoom=18;
- WeatherColor 和 Particle 必须在 GSI 之上;
- 不把 WeatherColor 或粒子烘焙进底图;
- 不增加 provider-specific Weather 逻辑。
使用 MLRN 11.3.6 当前真实 `Camera` API,初始视图应直接覆盖 WeatherV2 bounds 或合理聚焦日本及周边;不得让用户每次启动后手工从世界视图找数据。
页面至少显示:
- `Basemap: GSI READY / ERROR / LOADING`
- map/style loading error(若存在)
- 当前 weather dataset identity。
## 7. T0~T3 提交与 Timeline
新增一个明确的 `LOAD REAL WEATHER T0-T3` 综合入口。
每次执行前必须:
1. `clearWindFields()`;
2. 确认四帧本地 asset 已 materialize 为 file URI;
3. 按 validTime 严格递增提交 T0/T1/T2/T3;
4. 每帧提交后记录结构化结果;
5. 最终重新读取 Native `getState()`。
硬断言:
- T0 = `ACCEPTED_PENDING_INITIAL_WINDOW`
- T1 = `INITIAL_WINDOW_READY`
- T2 = `ACCEPTED_NEXT_SNAPSHOT`
- T3 = `ACCEPTED_NEXT_SNAPSHOT`
- 最终 Native state = `READY`
任一不符都显示 `ERROR`,不得把部分成功显示为 READY。
UI 至少显示:
```text
Dataset: ECMWF HRES 20260807
T0 2026080700: <result>
T1 2026080706: <result>
T2 2026080712: <result>
T3 2026080718: <result>
Runtime: READY / ...
```
RN 只提交 producer timestamp,不保存第二套 T0/T1/MIX Runtime Window;Core Timeline 仍是唯一 owner。
## 8. Playback / Forecast 综合控制
在现有 Bridge API 上补齐 Test Host 可操作 UI,不新增 Native contract:
- PLAY
- PAUSE
- HALF / NORMAL / DOUBLE
- seek T0 / T1 / T2 / T3 对应的 forecast timestamp
- FPS AUTO / 30 / 60
- WeatherColor visible / opacity
- Particle visible
- WeatherColor stops(可使用已冻结的测试色带)
- particleColor / trailColor
- particle count / line width / length / opacity / trail opacity / trail fade
测试 UI 可以紧凑,但必须让真实地图保持主要可视区域;不要把控制面做成遮住地图的大面板。
Forecast seek 必须调用现有 `setForecastTime(timestampMs)`;禁止把 index/T0/T1/MIX 暴露成 JS 业务状态。
## 9. 视觉与地图综合验收准备
代码必须让后续 Android 一次 APK 验收能够观察:
- GSI 海岸线、地名等底图正常;
- WeatherColor 与地图地理位置对齐;
- Particle 与 WeatherColor 使用同一真实 Field;
- pan / zoom / bearing 后粒子与底图保持地理锁定;
- T0/T1/T2/T3 seek 后场景可继续渲染;
- PLAY/PAUSE/速度切换不造成 style reload;
- WeatherColor visible 与 Particle visible 相互独立;
- FPS 切换不改变 forecast/canonical 数据语义。
## 10. 临时文件与稳定性
本阶段要明确 3 MiB 级 asset 的生命周期,但不做 zero-copy 性能工程。
要求:
- `expo-asset` 产生的本地文件由 Expo/系统 cache 生命周期管理;不要额外复制多份 payload;
- 若代码另建临时文件,提交结束后必须有明确清理路径;
- Fast Refresh、重复 LOAD、clear、detach 不得无限累积自建 `.f32` 临时文件;
- 不为了“减少 copy”引入 JSI、direct ByteBuffer、mmap 或新的 Native transport;
- Android 验收阶段观察连续 T0~T3 提交是否出现 OOM、长时间卡死或明显异常 GC;本任务不提前做性能优化。
## 11. 允许修改范围
优先只允许:
- `integration/react-native/MapLibreParticleRNTestHost/App.tsx`
- `integration/react-native/MapLibreParticleRNTestHost/src/**`
- `integration/react-native/MapLibreParticleRNTestHost/assets/**`
- `integration/react-native/MapLibreParticleRNTestHost/metro.config.js`
- `integration/react-native/MapLibreParticleRNTestHost/package.json`
- `integration/react-native/MapLibreParticleRNTestHost/package-lock.json`
- `integration/react-native/MapLibreParticleRNTestHost/README.md`
- 本 Step 的中文记录/报告/开发记录。
如非必要,不修改 `modules/weather-runtime-bridge/**`;当前 Bridge API 已足够完成任务。
明确禁止提交:
- `android/` generated build 目录;
- `node_modules/`;
- `.codex-build-logs/`;
- APK/AAR;
- 与本任务无关的历史 untracked 文件。
## 12. Codex 静态验证
Codex 必须执行并记录:
1. `npm run typecheck`。
2. `metro.config.js` 的 Node 语法/配置检查。
3. 四帧 Test Host asset 与源 WeatherV2 asset 的 SHA-256 一致性检查。
4. 检索正式 transport 不存在 `number[]` / payload JSON / base64 / hex。
5. 检查 style layer 顺序确实为 GSI → WeatherColor → Particle。
6. `git diff --check`。
未经用户明确要求:**不加入 Jest,不运行 Jest**。
Codex 不执行:
- Android Gradle;
- `assembleDebug`;
- ADB;
- APK install;
- Android 设备测试;
- AAR build/publish。
Android APK 编译和设备综合验收仍由后续 CARBON7i 手工周期执行,并尽量一次覆盖全部 STEP-062 验收项。
## 13. 必做输出
至少完成:
1. RN Test Host 的 GSI + Real Weather + WeatherColor + Particle + Playback 代码。
2. 原样复用的四帧 WeatherV2 assets。
3. 更新 Test Host 中文 README,说明 STEP-062 操作方法和冻结的 `step061` AAR。
4. `docs/50_Step记录/STEP-062_RNTestHost真实WeatherV2底图粒子综合验证_v1.md`。
5. `docs/报告/STEP-062_RNTestHost真实WeatherV2底图粒子综合验证_Codex完成报告_v1.md`。
6. 追加 `粒子开发记录.md`。
完成报告必须明确:
- 实际修改文件;
- GSI source/layer 与 camera 实现;
- 四帧 asset 来源、大小和 SHA 对照;
- Expo Asset → local file URI → STEP-061 bridge 的实际调用链;
- T0~T3 的预期 submit result;
- Playback/forecast/visual 控件接线;
- 是否修改任何 Native/Core/WeatherRuntime/JNI(预期:否);
- 是否构建/发布 AAR(必须:否);
- 实际静态验证结果;
- Android APK/设备仍待哪些项目验证。
源码阶段状态只能写:
```text
IMPLEMENTED / WAITING_ANDROID_VALIDATION
```
不得提前写 Android PASS。
## 14. Git 收尾
本任务会生成/修改项目文件,因此完成后必须:
1. 逐项对照本任务必做项;
2. `git diff --check` PASS;
3. 只 `git add` 本任务相关文件;
4. commit 到当前 `particle/main`;
5. `git push origin particle/main`;
6. 完成报告记录 final commit、commit message、push 结果、remote branch;
7. push 失败不得声称任务完成。
不得把现有历史 untracked 文件加入提交。
## 15. 最终必做清单
- [ ] GSI raster basemap 已进入 RN Test Host
- [ ] layer order = GSI → WeatherColor → Particle
- [ ] Camera 初始范围能直接看到 WeatherV2 区域
- [ ] 四帧真实 WeatherV2 asset 原样复制且 SHA 一致
- [ ] `.f32` 走 Expo Asset local file URI
- [ ] 继续使用 STEP-061 file-reference transport
- [ ] T0/T1/T2/T3 结果做严格 hard assertion
- [ ] 最终 Native state 必须要求 READY
- [ ] PLAY/PAUSE/速度/forecast seek 可操作
- [ ] WeatherColor 与 Particle 独立显隐和视觉控制保留
- [ ] FPS AUTO/30/60 可操作
- [ ] 不创建第二套 T0/T1/MIX 状态
- [ ] 不使用 number[]/payload JSON/base64/hex
- [ ] 不修改 Native/Core/JNI/WeatherRuntime
- [ ] 不构建或发布 AAR
- [ ] 不进入 NavSea
- [ ] 不加入或运行 Jest
- [ ] `npm run typecheck` PASS
- [ ] asset SHA 检查 PASS
- [ ] `git diff --check` PASS
- [ ] Step/报告/开发记录完成
- [ ] commit + push `origin/particle/main`