# NavSea Chart Domain Model v1 ## 1. 目的 本文件定义 NavSea 在“去掉交付版 `pbf` 对旧日文 layer 体系依赖”之后,面向渲染、离线包、Tile Resolver 和业务消费的 **语义分层模型**。 这不是旧 `source-layer` 的简单改名,而是一次 **按语义重建 layer domain** 的设计。 目标: - 让交付版 `pbf` 的 layer 结构按航海语义组织 - 为离线最小包 / 增强包 / 细节包提供稳定结构 - 为 Tile Resolver 提供明确的优先级 - 为后续“去旧字段依赖”“去日文化技术依赖”提供域模型基础 - 为审计提供明确的验收口径 ## 2. 核心结论 NavSea 不应只分成 `Safety / Detail` 两层,而应分成 **三层语义域**: 1. `safety_core` 2. `safety_extended` 3. `detail` 同时再保留一个过渡状态: 4. `domain_pending` 其中: - `safety_core` - 生存核心层 - 离线最小包必须包含 - Tile Resolver 永远优先返回 - `safety_extended` - 增强安全层 - 对航海有价值,但缺失不会立刻致命 - 建议缓存,可离线降级 - `detail` - 细节层 - 信息丰富,但不是安全底线 - 可延迟加载,甚至可完全缺失 - `domain_pending` - 语义尚未完成重建的过渡层 - 不能直接进入最终交付域模型 ## 3. 设计原则 ### 3.1 这是“语义分层”,不是“旧 layer 改英文名” 域模型的判断依据应是: - 航海风险 - 是否属于安全底线 - 是否必须离线存在 - 是否属于细节补充 不应只依据: - 旧 `source-layer` - 旧编码号 - 当前样式中是否好画 ### 3.2 物体优先,图层其次 最终分层应该优先考虑对象语义,而不是历史制图层名。 例如: - `navigation_marks` - 虽然来自点层,但本质是安全核心对象 - `place_label_sea` - 虽然在视觉上重要,但不属于安全底线 ### 3.3 逻辑层三层,物理分发两包 推荐结构: - 逻辑域模型:三层 - `safety_core` - `safety_extended` - `detail` - 物理分发模型:两包 - `safety` - `detail` 其中: - `safety = safety_core + safety_extended` - `detail = detail` 如果需要极简离线模式,可额外定义: - `base_pack = safety_core` ### 3.4 安全层不得被细节层替代 这是一个硬约束: - 任意 `detail` feature 不得被视为 `safety_core` 的替代来源 即使某个 `detail` 对象在视觉上“看起来像”危险物、边界或航标,也不能因为它恰好被画出来,就把它当作安全底线的一部分。 原因: - `detail` 本来就是允许缺失的 - 离线模式下,`detail` 可能根本不下载 - 如果系统把 `detail` 当作 `safety_core` 的替代,会导致错误安全感 因此: - `safety_core` 必须由明确归入 `safety_core` 的对象独立构成 - 不允许通过 `detail` 的“视觉相似性”补齐安全层 ### 3.5 Resolver 以物理包为最小分发单位 `v1` 阶段必须明确限制客户端复杂度: - Tile Resolver 的最小分发单位是物理包 - 不在客户端做 feature 级或 layer 级重组 也就是说,Resolver 优先返回: - `safety` 包 - `detail` 包 而不是: - 从某个 tile 中抽几个 `safety_core` layer - 再拼几个 `detail` layer - 然后在客户端重新生成一块新 `pbf` 原因: - 客户端复杂度会显著增加 - 缓存模型会被打碎 - 调试、审计、回放都会变复杂 - 第一阶段很容易陷入过度工程 因此 `v1` 原则是: - 逻辑上按 domain 建模 - 物理上按包分发 - 客户端只做“选包”,不做“重组包” ### 3.6 `land_area` 是陆海主判定层 为了支持快速、稳定地将陆地与海洋分开渲染,`v1` 明确规定: - `land_area` 是陆海二分的唯一主来源 - `land_area` 内部视为陆地 - `land_area` 外部默认视为海域/水域背景 同时明确: - `baseline_area` - `baseline_line` - `baseline_outline` - `onshore_structure_*` - 港岸结构、防波堤、码头边线 这些对象可以辅助表达岸线和港湾结构,但**不作为陆海主判定层**。 这条规则的目的,是让显示层和后续 Resolver / 切包逻辑都能用一条简单规则完成陆海分离,而不需要在多个 layer 之间做启发式拼接判断。 ## 4. 域定义 ### 4.1 `safety_core` 定义: - 没有它就不该航行 - 离线底线包必须存在 - 缺失会直接影响最低安全判断 典型特征: - 航行危险 - 航标 - 水深核心 - 危险地形 - 地形基础参考 ### 4.2 `safety_extended` 定义: - 对航行明显重要 - 但缺失不会立刻让系统失去最低安全能力 典型特征: - 锚地 - 净空/限制 - 重要结构物 - 基本边界参考 ### 4.3 `detail` 定义: - 丰富表达、增强理解、提升体验 - 但不影响最低安全底线 典型特征: - 地名 - 底质 - 次级边界 - 支撑线 - 展示性文字 ### 4.4 `domain_pending` 定义: - 当前尚未完成语义重建 - 仍然带旧编码痕迹 - 只能作为过渡层,不得直接当最终域模型交付 典型特征: - 编码型 layer - 仅具“稳定占位名”,不具业务语义 ## 5. 第一轮域归类 以下归类是当前讨论后的 `v1` 基线。 ### 5.1 `safety_core` - `navigation_hazard_area` - `navigation_hazard_outline` - `navigation_hazard_point` - `depth_contour` - `depth_contour_overview` - `navigation_marks` - `fixed_fishing_gear_area` - `land_area` - `submerged_reef_area` ### 5.2 `safety_extended` - `anchor_caution_hazard_area` - `anchor_caution_hazard_outline` - `anchor_caution_hazard_point` - `anchorage_area` - `anchorage_outline` - `anchorage_point` - `clearance_limit_line` - `clearance_limit_point` - `bridge_structure` - `onshore_structure_area` - `onshore_structure_line` - `onshore_structure_point` - `baseline_area` - `baseline_line` - `baseline_outline` - `route_area` - `route_outline` - `route_axis_line` - `route_boundary_point` - `leading_line_outline` - `pilot_station_point` ### 5.3 `detail` - `place_label_sea` - `place_label_land` - `seabed_text_point` - `facility_boundary_area` - `facility_boundary_outline` - `facility_boundary_point` - `hole_area` - `bathymetry_line` - `seabed_line` ### 5.4 `domain_pending` 这几类当前不得直接进入最终 Chart Domain: - `depth_zone_739` - `depth_zone_741` - `clip_outline_754` 原因: - 仍然依赖旧编码 - 语义不够明确 - Resolver 和离线模型无法稳定消费 ## 6. 对当前层命名的解释 本模型中的 layer 名,指的是 **建议标准语义层名**,不是当前交付版实际使用的旧日文 `source-layer`。 也就是说,像: - `P錨泊地等` - `p航路標識群` - `L等深線` 应先标准化为: - `anchorage_area` - `navigation_marks` - `depth_contour` 再进入 Chart Domain 分类。 ## 7. 面向 Tile Resolver 的结构建议 未来 Tile Resolver 不应只拿“某个标准 layer 名”做决策,还应同时读取: - `chart_domain` - `resolver_priority` - `offline_pack` 建议输出字段: - `chart_domain` - `safety_core | safety_extended | detail | domain_pending` - `resolver_priority` - 整数,数值越小优先级越高 - `offline_pack` - `base | safety | detail | pending` - `domain_status` - `active | pending | deprecated` 建议默认优先级: - `safety_core`: `10` - `safety_extended`: `20` - `detail`: `30` - `domain_pending`: `99` ## 8. 面向分包的结构建议 推荐的物理输出结构: ```text tiles/ ├── safety/{z}/{x}/{y}.pbf └── detail/{z}/{x}/{y}.pbf ``` 其中: - `safety` - 包含 `safety_core + safety_extended` - `detail` - 包含 `detail` 如果后续确实需要更细粒度离线控制,可扩展为: ```text tiles/ ├── safety-core/{z}/{x}/{y}.pbf ├── safety-extended/{z}/{x}/{y}.pbf └── detail/{z}/{x}/{y}.pbf ``` 但当前 `v1` 建议先不要切太细,以免: - 分发复杂 - 前端消费复杂 - 缓存策略过碎 ## 9. 审计设计 这部分是本文件最重要的配套要求:**域模型不是写出来就算完成,必须可以审计。** ### 9.1 审计目标 要能回答: 1. 每个标准 layer 是否被正确归入某个 Chart Domain 2. 是否有对象被错分到不合适的域 3. 是否有 `domain_pending` 层被错误放入正式交付 4. 按当前 style 渲染时,域变化是否破坏原始渲染 5. 离线包拆分后,是否仍满足“安全底线” ### 9.2 审计分层 建议分 4 层审计。 #### A. 规则审计 检查内容: - 每个标准 layer 是否有明确域归属 - 每个域归属是否有规则来源 - 是否存在重复归类或冲突归类 建议表结构: - `chart_domain_rules` - `chart_domain_rule_trace` 建议最小字段: - `domain_rule_id` - `bundle_id` - `layer_std` - `chart_domain` - `resolver_priority` - `offline_pack` - `rule_reason` #### B. 数据审计 检查内容: - 当前交付版/工程版 `pbf` 中,每个 feature 属于哪个标准 layer - 是否存在 feature 无法映射到任何域 - 是否存在 `domain_pending` layer 进入了正式输出 建议输出: - `feature_count by chart_domain` - `feature_count by layer_std` - `feature_count by domain_pending` 关键断言: - 每个正式输出 feature 必须有 `chart_domain` - `domain_pending` 不得进入最终交付版 #### C. Resolver 审计 检查内容: - `safety_core` 是否总是优先被 Resolver 选择 - `detail` 是否不会覆盖 `safety_core` - 离线模式下 Base Pack 是否真的包含全部 `safety_core` - Resolver 是否始终按物理包返回,而不是按 layer/feature 临时拼装 关键断言: - `safety_core` 丢失即判定不通过 - `detail` 缺失不影响 `base_pack` 合格 - 不允许 `detail` 被当作 `safety_core` 的替代来源 - 不允许客户端执行 feature 级或 layer 级重组后再返回 tile #### D. 渲染审计 检查内容: - 在 layer domain 切换后,原始样式与新样式是否仍然等价 - 是否有 feature 因域拆分而不再被渲染 - 是否有对象在新样式中出现“语义画反” - 水下对象被画成陆地/露出 - 水上对象被画成水下/危险物 - render-support 层被错误强化成业务语义对象 ##### D-1. Style 语义审计 这是渲染审计中的强制子项,目的不是只看“有没有画出来”,而是看: - 新版 style 是否忠于旧版 style 的表现语义 - 是否把旧版的弱语义/辅助语义误画成强语义 - 是否把航行关键语义画反 重点检查: - 陆海主判定是否与旧版一致 - 水上 / 水下 / 露出 / 干出语义是否与旧版一致 - 危险物、潜堤、暗礁、浅水区等是否被误画成普通背景 - render-support 层是否仍保持旧版的支撑性表现 - 例如 `P穴 -> hole_area` 必须忠于旧版透明/孔洞式表现,不得画成陆地区块 - 文字与符号是否仍表达旧版相同含义 - 有对象、无数字 - 有线、无深度标注 - 有主符号、无关键辅助注记 审计口径: - 旧版 style 是表现基准 - 新版 style 是对旧版 style 的语义转译,不是重新设计 - 只要旧版表现会影响航行判断,该表现就必须被视为“语义表现”,纳入审计 - 交付前执行规范详见 [`NavSea_Delivery_Preflight_Audit_Spec.md`](/root/sourceserver/pbf/NavSea_Delivery_Preflight_Audit_Spec.md) 关键断言: - 不允许把水域对象画成陆地感对象 - 不允许把陆地/露出对象画成水下对象 - 不允许把 render-support 层画成会误导航行判断的实体语义对象 - 不允许因样式转译而丢失关键深度数字、净空数字、灯标说明、危险物标记 审计口径: - 原始 `pbf` + 原始 style - 工程版/交付版 `pbf` + 对应 style - 按 feature instance 级别比较 icon/text/line/fill 关键断言: - 不允许因为域重组导致“原来有渲染、现在完全没渲染” - 不允许 `safety_core` 对象被错误降到 `detail` ## 10. 审计通过条件 本模型建议的最低通过条件如下: ### 10.1 命名通过 - 所有正式输出 layer 必须使用标准层名 - 不再直接暴露旧日文 layer 名 ### 10.2 域归类通过 - 所有正式输出 layer 必须属于: - `safety_core` - `safety_extended` - `detail` - 不允许正式交付 layer 仍停留在 `domain_pending` ### 10.3 渲染通过 - 原始版 vs 新版渲染审计通过 - 不存在 feature 完全失去渲染观察 - Style 语义审计通过 - 不存在会影响航行判断的“语义画反” - render-support 层未被误画为强业务语义对象 ### 10.4 离线通过 - `base_pack` 能独立支撑 `safety_core` - `safety_pack` 能完整支撑安全域 - 缺失 `detail` 时,不得靠 `detail` 外观相似对象替代 `safety_core` - Resolver 返回应保持物理包边界,不做客户端临时重组 ## 11. 当前已知风险 ### 11.1 编码层风险 当前最大的风险仍然是: - `depth_zone_739` - `depth_zone_741` - `clip_outline_754` 如果这些层不先做语义拆解,后续: - Resolver 无法稳定使用 - 离线打包会失真 - Chart Domain 会夹杂“编码占位层” ### 11.2 容器层风险 这几层当前仍偏“容器命名”: - `baseline_area` - `facility_boundary_area` - `bathymetry_line` 它们虽然比旧日文层名好,但还不是最终最清晰的业务层名。 ## 12. 建议的推进顺序 ### Phase 1 - 完成 layer 标准命名 - 不改现有运行系统 - 只形成 Chart Domain 设计与审计要求 ### Phase 2 - 建立 `chart_domain_rules` - 为每个标准 layer 补: - `chart_domain` - `resolver_priority` - `offline_pack` ### Phase 3 - 输出新的语义域 layer 结构 - 仍保留可逆追溯 - 做渲染审计和 Resolver 审计 ### Phase 4 - 正式切换交付版 - 旧日文 layer 退出交付体系 ## 13. 当前结论 NavSea 下一步不是继续停留在“旧 layer 改英文名”,而是要进入: - **按语义重建 layer domain** `v1` 的基础结论是: - 三层域模型是必要的 - 需要额外保留 `domain_pending` - 推荐逻辑三层、物理两包 - 任何后续切换都必须配套审计