18 KiB
STEP-065 MapLibreParticleLab V3 通用 Scalar / Vector Field 架构冻结 — Codex 任务 v1
0. 任务定位
本任务是 MapLibreParticleLab V3 的第一步:只读调查当前真实实现,并冻结 V3 通用 Scalar / Vector Field Contract 与迁移方案。
本任务不直接修改 C++、shader、JNI、Kotlin/Java、React Native Runtime 或 Android AAR。
V3 的目标不是“增加 Rain/Wave 两种天气类型”,而是把当前主要围绕 WIND + interleaved U/V 的运行时升级为:
provider-neutral、business-neutral 的二维时序 Scalar / Vector Field Rendering Runtime。
当前已冻结的上游边界:
WeatherV2 -> NSFT -> NavSea JS/TS -> Canonical Field -> MapLibreParticleLab V3
WeatherV2 统一向 NavSea 提供 NSFT;NavSea JS/TS 负责网络、缓存、NSFT 解码、tile 拼接、业务单位与 canonical 化;MapLibreParticleLab 从 canonical field 开始接管。
1. 仓库与执行基线
仓库:
/mnt/sda1/MapLibreParticleLab
分支:particle/main
任务书生成时 HEAD:
2e3ab26275a8d1873d764cf6927783a7b0406836
该 HEAD 已完成并冻结 STEP-064 RN 纯 Field Renderer 13.4.1-particle.2。
执行开始时必须重新确认:
git branch --show-current
git rev-parse HEAD
git rev-parse origin/particle/main
git status --short
若远端已合法推进,先阅读新增提交后再继续;禁止 reset、checkout 覆盖或回退用户工作。 当前工作区已知存在与本任务无关的用户修改和历史未跟踪文件,特别包括 STEP-062 文档、Android/Expo/build 目录、旧任务书和 tgz。
必须遵守:
- 禁止
git add .、git add -A。 - 禁止删除、恢复、格式化、移动无关 modified/untracked 文件。
- 本任务只允许新增/修改 STEP-065 明确列出的文档产物和本任务书自身。
- 本任务不允许以“清理工作区”为理由处理历史文件。
2. 执行前必须阅读
至少完整阅读:
AGENTS.md
PARTICLE_BASELINE.md
docs/00_项目规范/01_Codex协作规范_v1.md
docs/00_项目规范/02_构建与验证规范_v1.md
docs/00_项目规范/03_Step阶段记录规范_v1.md
docs/00_项目规范/05_粒子架构原则_v1.md
docs/40_任务/STEP-064_RN纯FieldRenderer接口V2_Codex任务_v1.md
docs/50_Step记录/STEP-064_RN纯FieldRenderer接口V2_v1.md
docs/报告/STEP-064_RN纯FieldRenderer接口V2_Codex完成报告_v1.md
并重点阅读当前真实实现:
include/mbgl/particle/field/field_data_adapter.hpp
src/mbgl/particle/field/field_data_adapter.cpp
所有 Timeline / Runtime Field Window 实现
WeatherColorLayer 相关 C++ / shader / shader generator
RasterParticleLayer 相关 C++ / particle simulation shader
GPU field texture / upload / reuse / lifecycle 实现
Android Host WeatherRuntime / JNI submission
packages/maplibre-particle-rn/src/index.ts
packages/maplibre-particle-rn/src/types.ts
packages/maplibre-particle-rn/src/FieldRuntime.ts
packages/maplibre-particle-rn/src/NativeWeatherRuntimeBridge.ts
integration/react-native 中当前正式 Consumer/Test Host
必须通过当前源码回答问题,不得根据历史任务书猜实现。
3. WeatherV2 外部输入事实与只读核对
WeatherV2 实际目录:
/root/sourceserver/weatherV2
可只读核对以下文件,不得修改 WeatherV2:
src/dev/core/nsft.py
src/dev/core/field_pmtiles.py
src/dev/layers/wind.py
src/dev/layers/tide.py
src/dev/layers/rain.py
src/dev/layers/waves.py
已调查结论必须作为 V3 设计输入:
- Wind NSFT:物理速度 U/V,单位 m/s,vector-only。
- Tide/Current NSFT:物理速度 U/V,单位 m/s,vector-only。
- Rain NSFT:rain rate scalar + valid mask;当前 NSFT 不保存 precipitation type。
- Wave NSFT:height scalar + period scalar + normalized direction-to U/V;direction U/V 不是 m/s。
- NSFT grid 为
wm_grid_257,NW origin,行 north->south,列 west->east。 - 同 zoom 相邻 257 tile 有共享边界,NavSea 拼接后 canonical grid 可保持
(tiles*256)+1规则,无需 Core 理解 tile。 - Forecast target time 必须按实际 validTime/time_index 使用,Core 不假设固定 1h cadence。
这些事实如与当前 WeatherV2 代码不一致,报告差异并以当前代码为准。
4. V3 冻结边界
V3 Core/Native 不得负责:
- NSFT / PMTiles / WeatherV2 解析;
- HTTP、provider、manifest、time_index、cache、retry、prefetch;
- ECMWF / CMEMS 等业务来源;
- Wind / Rain / Wave / Tide 业务分支;
- kt、mm/h、m、m/s 等宿主业务单位转换;
- NavSea 当前 Layer、Forecast UI 或业务状态。
V3 从 Canonical Field Submission 开始负责:
- descriptor / payload validation;
- Snapshot;
- Timeline / target time / playback;
- T0/T1/MIX;
- Runtime Field Window;
- OLD_T1 -> NEW_T0 reuse;
- GPU channel resource 生命周期;
- Field Renderer;
- Particle Renderer;
- MapLibre style/viewport lifecycle recovery;
- fail-closed。
5. 必须冻结的最小 Canonical 模型
V3.0 只设计:
FieldSnapshot
├─ common descriptor
├─ scalar channel? 0 or 1
├─ vector channel? 0 or 1 (U/V)
└─ shared validity
禁止第一版扩成 N scalar / N vector generic graph。
必须支持三种合法组合:
vector-only
scalar-only
scalar + vector
Neither 必须 invalid / reject。
优先扩展当前 ParticleFieldDescriptor / ParticleFieldSnapshot / ParticleFieldDataAdapter,禁止并行创建 GenericWeatherField、WindFieldV2 等第二套重复模型。
当前 fieldType == "WIND"、displayDomain == "GLOBAL" 等硬编码必须被调查并给出 V3 最小迁移方案;Core 最终不得靠 WIND/WAVE/RAIN/TIDE 决定数据能力。
6. Renderer Contract 必须与数据 Contract 分离
必须调查并冻结以下原则:
FieldSnapshot 只描述“有什么数据”;Renderer config 描述“如何画”。
第一版 Field Renderer 的通用值来源建议为:
SCALAR
VECTOR_MAGNITUDE
即:
SCALAR:色场读取 explicit scalar channel;VECTOR_MAGNITUDE:色场读取sqrt(U^2 + V^2)。
不得让 Renderer 根据 business type 或“有没有 scalar”偷偷猜来源。
必须调查当前 WeatherColorLayer/shader 是否硬依赖 length(U,V),以及将其泛化所需最小接口、uniform/property、GPU resource 与 style property 改动。
FieldColorStop.value 的 RN 公共语义保持 generic;调查 Native/JNI/C++ 内 speedMps 命名实际范围,并给出兼容迁移路径。
7. Vector Semantics 必须业务无关
必须调查当前 Particle Integrator / shader 是否隐含:
U/V = physical velocity (m/s)
V3 需要覆盖至少两类数学语义:
VELOCITY
DIRECTION
目标映射:
- Wind/Tide -> VELOCITY;
- Wave direction-to U/V -> DIRECTION。
不得在 Core 增加 Wind/Wave/Tide enum 来解决。
对于 DIRECTION,设计必须说明:
- T0/T1 vector mix 后是否 normalize;
- 接近零向量/接近反向插值如何 fail-closed;
- particle movement 的独立 advection scale 放在哪一层;
- 如何保证 VELOCITY 当前 Wind 行为不被改变。
本任务只冻结方案,不实现 Wave physics。
8. Binary Submission / Channel Plane 设计
当前 RN 公共入口是:
submitField(metadataJson, payloadFileUri)
当前 Core canonical payload 是:
float32-le / interleaved-uv
必须调查 RN -> Android bridge -> JNI -> Core 的真实 ownership、文件读取、byte[]/buffer、size limit 与 decode 流程。
V3 优先评估独立 plane:
metadata
vectorPayload? // float32-le interleaved U/V
scalarPayload? // float32-le scalar plane
不得使用巨大 JS number[]、JSON Array 或 Base64 作为正式大数据通路。
必须明确:scalar-only、vector-only、scalar+vector 三种提交如何表达;文件引用是一个 container 还是两个 file URI;JNI/Core 最小修改面是什么。
独立 plane 是首选方向,但最终冻结必须依据当前代码,不能为了迎合任务书而忽略更安全的现有接缝。
9. Timeline / Runtime Window 保护项
以下现有能力视为 V3 保护基线,不得在设计中推倒重来:
Core-owned Timeline / Playback
T0 / T1 / MIX
正常连续播放 simulationRebuild=false
正常连续播放 trailCleared=false
Runtime Field Window
OLD_T1 -> NEW_T0 reuse
only NEW_T1 upload
Pause 语义
Invalid / Gap fail-closed
WeatherColorLayer 与 RasterParticleLayer 分离
V3 设计要说明如何把 Snapshot GPU resource 从单 vector texture 扩展成:
SnapshotGpuResources
├─ scalar texture?
├─ vector texture?
└─ validity resource
并保持整个 Snapshot 在 rollover 时一起 reuse,Host 不参与 GPU reuse。
10. Canonical schema 版本决策
必须明确回答:
maplibre-particle-field/v1 additive extension
还是
maplibre-particle-field/v2
当前已知 v1 descriptor 是单 layout/encoding/byteLength/stride,Snapshot 只有 velocity,RN submitField() 只有一个 payload file URI,且 adapter 严格接受 interleaved-uv。
因此本任务的默认判断倾向:如果 Scalar + Vector 会导致字段重载、隐式兼容或 ambiguous payload,则应正式升 v2,而不是污染 v1。
但最终结论必须根据完整 parser/bridge/fixture/consumer 调查给出。
如果选择 v2,设计必须说明:
- v1 Vector-only 是否继续可读;
- compatibility 应放在哪个最薄层;
- 是否允许 v1/v2 同时进入同一个 Runtime;
- 新 RN package 版本至少应升到
13.4.1-particle.3,不得覆盖已发布.2; - Native/AAR version 如何独立推进。
不得为了“兼容”长期维护两套 Runtime。
11. Validity 与业务映射冻结
V3.0 优先保持一个 Snapshot 一个共享 validity,不提前设计 channel-specific mask。
必须给出四类 WeatherV2 -> NavSea canonical -> V3 的映射表,至少明确:
Wind : vector(U/V velocity) -> field=VECTOR_MAGNITUDE, particle=VELOCITY
Tide : vector(U/V velocity) -> field=VECTOR_MAGNITUDE, particle=VELOCITY
Rain : scalar(rainRate) -> field=SCALAR, particle=unavailable
Wave : scalar(height) + vector(direction-to U/V)
-> field=SCALAR, particle=DIRECTION
Wave period 当前保留在 NavSea Weather model/cache,V3.0 不因此增加第二 Scalar Channel。
Rain precipitation_type 当前未进入 NSFT,因此 V3 不推断、不补造该数据。
Field/Particle visibility 必须继续独立:
Field ON / Particle OFF
Field OFF / Particle ON
Field ON / Particle ON
没有 vector 时 Particle unavailable / reject,不允许 scalar 伪装成 U/V。
12. 必须输出的调查结论 A-J
设计文档必须逐项回答:
A. 当前 Field Contract 实际结构与 Wind-only 硬编码点。
B. 当前 GPU Texture / upload / validity / shader 的实际结构。
C. 当前 Particle Integrator 对 vector 数值、单位、dt、scale 的实际假设。
D. 当前 RN -> Android -> JNI -> Core binary submission 路径与 ownership。
E. Scalar Channel 的最小扩展方案与受影响对象。
F. Wave direction-only 的最小、业务无关表达方案。
G. v1 additive extension 还是 canonical v2,并说明理由。
H. 预计受影响文件清单,按 Core / shader / Android / RN / Test Host 分类。
I. 向后兼容、性能、GPU memory、lifecycle、Timeline 风险。
J. 推荐的正式实施批次、验证门槛和 Android 最终一次综合验收范围。
13. 推荐实施路线必须被审查并冻结
设计结果至少应评估以下批次是否合理:
V3-02 Core Contract + Scalar Snapshot/Adapter
V3-03 Scalar GPU Texture + Generic Field Renderer
V3-04 VectorSemantics VELOCITY/DIRECTION + Particle
V3-05 Android/JNI/RN generic binary submission
V3-06 Wind/Rain/Wave 三类 fixture + Tide 回归
V3-07 Linux/Core/OpenGL 精确验证与文档冻结
V3-08 用户一次 Android build/install/device 综合验收
可以根据当前代码合并或调整批次,但必须遵守:
- 尽量减少 Android 重复编译/安装周期;
- 在 Linux/Core 可验证的内容先集中完成;
- 不因单一小按钮/日志单独触发 Android 周期;
- 高风险接口分叉必须在 Android 实现前冻结。
最终路线要给每个批次明确“修改范围 / 不修改范围 / 完成门槛 / 下一批入口”。
14. Validation Fixture 规划
V3 后续至少规划三类数学能力 fixture:
A. Vector-only : 真实 WeatherV2 Wind
B. Scalar-only : 真实 WeatherV2 Rain
C. Scalar+Vector: 真实 WeatherV2 Wave
Tide 作为第二套 VELOCITY vector 做回归,不单独创造业务代码路径。
Wave 必须规划一个独立性 synthetic fixture:
scalar: west low -> east high
vector: 全场 north
预期:
色场只呈东西渐变
粒子只统一向北
该 fixture 用于证明 Field Renderer 不偷读 vector magnitude,Particle Renderer 不偷读 scalar。
同时规划 T0/T1 scalar、T0/T1 vector、共同 MIX、window rollover、style reload、visibility、invalid/gap fail-closed 验证。
15. 本任务禁止事项
本任务不得:
- 修改任何生产代码;
- 修改 shader / generator;
- 修改 Android/JNI/RN API;
- 生成新的 AAR/tgz release;
- 执行 Android Gradle build、APK 安装或 ADB 验收;
- 把 NSFT decoder 放入 ParticleLab;
- 新增 Weather Provider / HTTP / cache;
- 新增 WIND/WAVE/RAIN/TIDE Core 分支;
- 实现 Wave physics;
- 设计 N-channel framework;
- 做 JSI/zero-copy 大重构;
- 加入或执行 Jest;
- 修改 NavSea 或 WeatherV2。
本任务是设计冻结任务,不是实现任务。
16. 必做文档输出
新增:
docs/20_调查/STEP-065_MapLibreParticleLab_V3通用ScalarVectorField现状调查_v1.md
docs/30_设计/MapLibreParticleLab_V3通用ScalarVectorField运行时架构设计_v1.md
docs/50_Step记录/STEP-065_MapLibreParticleLab_V3通用ScalarVectorField架构冻结_v1.md
docs/报告/STEP-065_MapLibreParticleLab_V3通用ScalarVectorField架构冻结_Codex完成报告_v1.md
并追加更新:
粒子开发记录.md
所有文档必须使用中文,代码标识符、路径、schema/property 名保持实际英文。
设计文档必须包含至少:
- 当前真实架构图;
- V3 目标架构图;
- Scalar / Vector / validity 数据模型;
- Renderer config 与 Snapshot data 的边界;
- Binary plane 方案;
- Timeline/GPU reuse 迁移;
- API/schema 版本决策;
- WeatherV2 四层映射;
- 受影响文件矩阵;
- 风险与实施顺序。
17. 必做清单
执行结束前逐项对照,不得静默跳过:
- 读取全部项目规范与 STEP-064 冻结基线。
- 重新确认 branch / HEAD / origin / dirty worktree。
- 调查 Descriptor / Snapshot / Adapter 当前实际结构。
- 找全 WIND / GLOBAL / fieldType 等行为硬编码。
- 调查 Runtime Window / Timeline / MIX / GPU reuse。
- 调查 WeatherColorLayer value 获取和
speedMps链路。 - 调查 Particle Integrator 的 velocity 假设。
- 调查 RN -> Android -> JNI -> Core binary submission。
- 只读核对 WeatherV2 NSFT 四层语义。
- 冻结 0/1 Scalar + 0/1 Vector + shared validity 模型。
- 冻结 FieldValueSource 与 VectorSemantics 方案。
- 冻结 binary payload / file-reference 方案。
- 明确 canonical v1 additive 或 v2。
- 给出 V3 分批实施路线与综合 Android 验收计划。
- 生成调查、设计、Step、完成报告。
- 追加粒子开发记录。
- 确认没有修改生产代码和无关用户文件。
18. Git 收尾要求
本任务会新增/修改项目文档,因此完成后必须 Git 收尾并 push 到公开远端 particle/main。
提交前必须再次执行 git status --short,只暂存本任务明确产物:
docs/40_任务/STEP-065_MapLibreParticleLab_V3通用ScalarVectorField架构冻结_Codex任务_v1.md
docs/20_调查/STEP-065_MapLibreParticleLab_V3通用ScalarVectorField现状调查_v1.md
docs/30_设计/MapLibreParticleLab_V3通用ScalarVectorField运行时架构设计_v1.md
docs/50_Step记录/STEP-065_MapLibreParticleLab_V3通用ScalarVectorField架构冻结_v1.md
docs/报告/STEP-065_MapLibreParticleLab_V3通用ScalarVectorField架构冻结_Codex完成报告_v1.md
粒子开发记录.md
禁止把任何既有 STEP-062 修改、历史 untracked、build/cache/android/tgz 一并提交。
完成后:
- 创建 scoped commit;
- push 到
origin/particle/main; - 确认远端 HEAD;
- 在完成报告记录 commit hash、commit message、push 结果、最终远端分支/HEAD。
push 失败不得声称任务完成,必须明确报告原因。
19. 完成报告格式
完成报告必须按必做项逐项写:
已完成 / 未完成 / 无法验证
并明确:
- 本任务是否修改生产代码:预期“否”;
- WeatherV2 是否被修改:预期“否”;
- Android Gradle / APK / ADB:预期“未执行,按任务边界”;
- Jest:预期“未加入、未执行”;
- 当前最终 V3 schema 推荐;
- 下一实施任务建议名称与范围;
- 所有未解决设计风险。
20. 最终完成标准
只有以下全部满足,STEP-065 才可标记 CLOSED / PASS:
- 当前实际代码调查完整,并有文件/符号级依据;
- V3 Scalar/Vector/validity Contract 已冻结;
- Renderer data source 与 VectorSemantics 已冻结;
- binary submission 与 schema version 路线已冻结;
- Timeline/Runtime Window/GPU reuse 保护方案明确;
- V3 分批实现和最终一次 Android 综合验收路线明确;
- 四份正式文档 + 粒子开发记录完成;
- 无生产代码、WeatherV2、NavSea 和无关工作区文件被修改;
- scoped commit 已成功 push 到
origin/particle/main。