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