348 lines
8.0 KiB
Markdown
348 lines
8.0 KiB
Markdown
# 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. 是否存在分包叠加的一致性审计
|