# NavSea 语义分包与叠加渲染设计 ## 目标 本设计说明 NavSea 如何将某一坐标区域内的海图数据按语义拆分成多个 `pbf` 包,并在客户端或 Resolver 侧叠加恢复出与当前整包渲染近似等价的最终视觉结果。 这份设计服务于三个目标: 1. 在不损失海图细节的前提下重构 `pbf` 数据结构。 2. 让安全相关数据与细节相关数据可以分开交付、缓存、下载和审计。 3. 为后续离线包、Tile Resolver、按需加载和流量控制提供基础。 ## 核心结论 可以将一个区域的 `pbf` 按语义拆分成多个包。 这些包在渲染时叠加后,可以恢复出与当前整包 `pbf` 基本一致的视觉结果。 但前提是: 1. 各包的语义边界稳定。 2. 样式明确知道每一层来自哪个包。 3. 叠加顺序固定。 4. 有专门的分包叠加一致性审计。 ## 逻辑分层模型 当前建议的逻辑层仍采用 `NavSea_Chart_Domain_Model_v1.md` 中定义的三层模型: 1. `safety_core` 2. `safety_extended` 3. `detail` 并保留: 4. `domain_pending` 说明: - `safety_core` 是最低安全底线。 - `safety_extended` 是重要但允许降级的数据层。 - `detail` 是信息丰富但不构成最低安全底线的层。 - `domain_pending` 是尚未完成业务语义重建的过渡层,不应直接成为正式 Chart Domain 的长期成员。 ## 物理分包模型 建议 `v1` 采用“逻辑三层,物理两包”的结构: 1. `safety.pbf` 包含: - `safety_core` - `safety_extended` 2. `detail.pbf` 包含: - `detail` 在兼容阶段可允许: 3. `compat_pending.pbf` 仅用于兼容迁移期承载少量 `domain_pending` 层。 如果不单独出第三包,也可以在迁移期临时将少量 `domain_pending` 兼容层放入 `safety` 包,但必须有审计记录。 ## 为什么不建议一开始拆成很多小包 虽然理论上可以拆成: - `hazard.pbf` - `contour.pbf` - `marks.pbf` - `labels.pbf` - `seabed.pbf` 但 `v1` 不建议这样做。 原因: 1. 客户端 source 数量会快速膨胀。 2. 样式复杂度显著增加。 3. Tile Resolver 逻辑会变重。 4. 网络请求会被切碎。 5. 审计维度会显著复杂化。 因此 `v1` 先采用两包结构最稳。 ## 叠加渲染原则 语义分包后,最终渲染必须遵守以下原则。 ### 原则 1:安全层不能被细节层替代 任意 `detail` feature 不得被视为 `safety_core` 的替代来源。 即使 `detail` 中恰好存在一个对象在视觉上看起来能表达某种危险,也不能把它作为安全底线的替代依据。 ### 原则 2:Resolver 按包返回,不按 layer/feature 拼装 `v1` Resolver 必须按物理包分发,不在客户端做 feature 级或 layer 级重组。 也就是说: - 返回 `safety` 包 - 返回 `detail` 包 而不是: - 从多个包中抽若干 layer - 再动态重新打成新 tile ### 原则 3:样式叠加顺序固定 客户端的样式层顺序必须固定,不能由请求时动态推断。 最基础的顺序建议是: 1. 背景与底图 2. `safety` 面层 3. `detail` 面层 4. `safety` 线层 5. `detail` 线层 6. `safety` 符号层 7. `detail` 符号层 8. `safety` 文字层 9. `detail` 文字层 ### 原则 4:分包后必须还能恢复旧视觉 当前阶段的首要目标不是做新视觉,而是: - 新结构 - 旧视觉 所以“分包叠加结果”和“原始整包结果”必须可做等价审计。 ## 推荐消费模式 ### 模式 A:单 Style,多 Source 叠加 这是当前最推荐的模式。 样式中声明: - `domain_safety` - `domain_detail` 然后不同 layer 从不同 source 取数据。 优点: 1. 最符合 MapLibre / Mapbox Style 常规工作方式。 2. 不需要客户端自行拼瓦片。 3. 便于渐进迁移旧样式。 4. 最适合当前阶段的视觉等价验证。 ### 模式 B:Resolver 选择性返回包 Resolver 按场景返回: - 只返回 `safety` - 返回 `safety + detail` 客户端仍按固定 source/固定 style 消费。 优点: 1. 更适合离线/带宽优化。 2. 可以基于业务场景做包级裁剪。 要求: - 样式必须在缺少 `detail` 时仍可安全退化。 - 不允许缺少 `safety_core` 时依赖 `detail` 伪装补齐。 ## 推荐目录结构 ### 局部测试目录 ```text /home/wwwroot/pbf-domain-karatsu-10nm/ ├── safety/{z}/{x}/{y}.pbf ├── detail/{z}/{x}/{y}.pbf ├── chart_domain_build_audit.json └── chart_domain_build_audit.md ``` ### 全国目录建议 ```text /home/wwwroot/pbf-domain-full/ ├── safety/{z}/{x}/{y}.pbf ├── detail/{z}/{x}/{y}.pbf ├── build_audit.json ├── build_audit.md ├── overlay_audit.json └── overlay_audit.md ``` ## 样式组织建议 ### 兼容阶段 优先使用: - 旧样式规则 - 新 Domain 包 source 也就是当前已经验证过的路径: - 保留旧 `paint` - 保留旧 `layout` - 保留旧 `filter` - 仅替换 `source` 与 `source-layer` ### 清理阶段 在视觉对齐后,再逐步: 1. 去掉旧日文 `layer id` 2. 去掉旧字段依赖 3. 收敛到纯标准语义 layer 4. 最终形成新的可读样式层命名 ## 审计设计 分包以后,必须增加一套新的“叠加一致性审计”。 建议至少做三类审计。 ### 1. 构建审计 检查: - 每个 feature 被分到了哪个包 - 是否有 feature 被错误丢弃 - `domain_pending` 数量和明细 - 包内实际 layer 集合 当前已有样例: - `chart_domain_build_audit.json` - `chart_domain_build_audit.md` ### 2. 渲染等价审计 比较: - 原始版:原始样式 + 原始 `pbf` - 分包版:兼容样式 + `safety/detail` 叠加结果 审计单位: - `fid` 优先 - 无 `fid` 用 `geometry + 稳定旧属性` - 保留 tile instance 粒度 注意: - 分包版不能按新标准 layer 名直接对比 - 必须按 `source_layer_jp` 或 trace 回溯后的旧身份对齐 当前已经为此新建了 Domain 专用脚本方向: - `src/Domain/navsea_domain_render_audit.py` ### 3. 包级可用性审计 验证以下两种消费结果: 1. `safety` 单独加载 2. `safety + detail` 叠加加载 目标: - `safety` 单独时,满足最低安全表达 - `safety + detail` 时,尽可能恢复原始整包视觉 ## 推荐审计结论口径 建议把审计结论分成三档: 1. `safe_minimum_pass` `safety` 单独可用于最低安全判断 2. `overlay_equivalent_pass` `safety + detail` 叠加结果与原始版视觉等价 3. `pending_semantic_gap` 存在尚未完成业务语义重建的层,仅靠兼容模式暂时保留 ## 当前阶段的正确顺序 推荐按以下顺序推进,不要反过来: 1. 重构 `pbf` 内部结构 2. 用新结构恢复旧视觉 3. 用 Domain 专用审计确认“叠加等价” 4. 再做分包消费策略和 Resolver 策略 5. 最后才做新的 UI/新视觉/新风格 ## 当前阶段的可接受实现 就当前工程而言,以下做法是合理的: 1. 区域级生成 例如先做唐津 10 海里 2. 输出两包 - `safety` - `detail` 3. 提供一个兼容样式 目标是“看起来和旧版一样” 4. 提供 Domain 专用审计 不修改原有工程版审计体系 这意味着: - 旧体系继续可用 - Domain 体系独立演进 - 两条线彼此不污染 ## 后续实施建议 建议下一阶段按以下顺序执行: 1. 固化唐津 10 海里 Domain 审计结论 2. 将唐津流程推广到九州区域 3. 补齐 `domain_pending` 的正式业务语义 4. 在全国范围生成 `safety/detail` 双包 5. 增加 `safety-only` 与 `safety+detail` 双场景验收 ## 总结 某个坐标区域的 `pbf` 完全可以按语义拆成多个包。 这些包叠加后,可以恢复到与当前整包渲染近似等价的状态。 这不是额外能力,而是 NavSea Domain 设计成立的核心验证点之一。 真正需要控制的,不是“能不能拆”,而是: 1. 语义边界是否稳定 2. 样式是否固定知道从哪个包取哪种对象 3. `detail` 是否错误替代 `safety` 4. 是否存在分包叠加的一致性审计