# NavSea 物体统一判定、点击查询与审计设计 最后更新:`2026-04-09` 项目根:`/root/sourceserver/pbf` ## 1. 文档目标 本文用于把 `NavSea PBF` 项目的物体模型正式收口为一套可实现、可审计、可交付的设计。 当前项目的核心目标有三项: 1. 点击海图物体时,能够稳定回答“这是什么”,并返回桥高、水深、灯光、净空、名称等关键细节。 2. 能与 `NewPEC` 原体系稳定对应,并通过审计确认“对象没有丢、没有错归、没有错误合并”。 3. 能渲染出与 `NewPEC` 等价的图标、文字、线型、面样式和安全语义。 本文把这三项目标统一到一套模型里,并明确: - 哪些字段服务于点击查询 - 哪些字段服务于对象对回与审计 - 哪些字段服务于样式渲染 - 审计应该如何分层,哪些门禁是硬门禁 ## 2. 设计结论 最重要的结论只有一条: - 不应再试图用单一字段同时承担“身份锚点”“本体分类”“渲染控制”三种职责。 正确做法是把一个 `feature` 拆成 3 个主维度: 1. `identity / trace` 2. `object semantics` 3. `render semantics` 其中: - `identity / trace` 用于和 `NewPEC` 对回、做对象保真审计 - `object semantics` 用于点击查询、业务解释、CPA 相关判断 - `render semantics` 用于让最终渲染表现与 `NewPEC` 等价 `canonical_object_type` 可以保留并继续使用,但它应被定位为: - `NavSea` 统一语义子类名 而不是: - 唯一身份键 - 唯一审计锚点 - 唯一渲染控制字段 ## 3. 现有问题 当前项目里,一个 `feature` 的字段来源混杂了多个维度: - `fid`、`source_layer` 这类追踪字段 - `class_code`、`display_code` 这类 `NewPEC` 原生分类码 - `canonical_object_type` 这类统一语义名 - `chart_icon_image`、`chart_symbol_code` 这类渲染结果字段 - `depth_value_m`、`clearance_height_m`、`light_color_code` 这类业务属性字段 如果不先分层,就会出现三个问题: 1. 点击后不知道“应该信哪个字段来判定物体是什么”。 2. 审计时容易把“画出来了”误当成“对象还在”。 3. 渲染字段容易反过来污染本体分类,导致“画成什么”与“它是什么”混淆。 ## 4. 总体设计原则 ### 4.1 物体本体优先于渲染结果 - 一个对象是什么,必须优先由对象语义决定 - 不能用 `chart_icon_image`、`chart_fill_style` 等渲染字段反推本体 ### 4.2 对象审计优先于视觉相似 正式顺序必须保持为: 1. 对象保真审计 2. 渲染一致性审计 3. AOI / 视觉审计 如果对象已经丢失、错归或被错误合并,则视觉相似不能判定为通过。 ### 4.3 原生码值保留,但不再让它们直接统治上层业务 - `class_code`、`display_code` 必须保留 - 但上层点击查询、业务接口、CPA 判断不应直接依赖 `NewPEC` 原始码值 - 应把这些码值映射进 `NavSea` 自有对象分类体系 ### 4.4 交付版不能只顾渲染,还必须可查询 最终交付版 `PBF` 不能只保留“刚好够 style 用”的字段。 至少对以下查询能力,必须保留足够字段: - 点击知道对象是什么 - 点击读取桥高 / 水深 / 净空 / 灯光属性 - 点击读取危险物或航标的细类信息 - 为 CPA / 安全判断提供必要业务属性 ## 5. 统一物体模型 ### 5.1 三层主模型 建议每个 `feature` 的逻辑模型固定为下面三层。 #### A. identity / trace 回答: - 这是哪个原始对象 - 它来自哪个 `NewPEC` layer - 它能否稳定对回原始对象 建议字段: - `fid` - `source_layer_native` - `source_layer_std` - `geometry_type` - `feature_id` - `native_code_type` - `native_code_value` 其中: - `fid` 是第一锚点 - `source_layer_native + geometry_type` 是第二锚点 - `native_code_type + native_code_value` 是第三锚点 #### B. object semantics 回答: - 这个物体本体是什么 - 它属于哪个业务域、哪一类、哪一个子类 - 它有哪些业务属性 建议字段: - `object_domain` - `object_class` - `object_subclass` - `canonical_object_type` - `object_display_name` - `object_properties` 其中: - `canonical_object_type` 建议保留并作为 `object_subclass` 的稳定值 - `object_display_name` 用于 UI 展示 - `object_properties` 用于承载查询和业务细节 #### C. render semantics 回答: - 这个物体应该如何渲染 - 应该命中什么 icon、text、fill、line 建议字段: - `chart_icon_image` - `chart_symbol_code` - `chart_label_text` - `chart_label_subtext` - `chart_fill_style` - `chart_fill_pattern` - `chart_line_color` - `chart_line_width` - `chart_text_style` - `chart_text_color` ### 5.2 NavSea 自有分类体系 建议正式建立一套 `NavSea` 自有分类体系,不再让上层业务直接依赖旧码值。 建议结构: - `object_domain` - 业务大域 - `object_class` - 业务大类 - `object_subclass` - 业务细类 - `native_code_type` - 原生码种类 - `native_code_value` - 原生码值 建议示例: - `object_domain = navigation_mark` - `object_class = buoy` - `object_subclass = pillar_buoy` - `native_code_type = display_code` - `native_code_value = 31300003` 再例如: - `object_domain = hazard` - `object_class = wreck` - `object_subclass = dangerous_fully_submerged_wreck` - `native_code_type = class_code` - `native_code_value = 404` ### 5.3 object_domain 建议集合 建议首批固定为: - `navigation_mark` - `hazard` - `facility` - `boundary` - `depth` - `clearance` - `toponym` - `seabed` - `route` - `area_usage` - `landform` - `support` - `unclassified` ### 5.4 object_class / object_subclass 的职责 - `object_class` 用于稳定业务分组和 API 过滤 - `object_subclass` 用于更细粒度判定和 UI 展示 例如: - `object_domain = navigation_mark` - `object_class = lighthouse` - `object_subclass = breakwater_lighthouse` 或者: - `object_domain = hazard` - `object_class = rock` - `object_subclass = awash_rock` ### 5.5 原生码与自有体系并存 新的 `NavSea` 体系不是要删除 `NewPEC` 码值,而是要把原生码值纳入可映射、可审计的结构中。 因此应保留: - `native_code_type` - `native_code_value` - `source_layer_native` 并新增: - `object_domain` - `object_class` - `object_subclass` 这样: - 审计仍能稳定回到 `NewPEC` - 业务和 UI 则可以直接消费 `NavSea` 自有语义体系 ## 6. 字段设计建议 ### 6.1 必保留的身份与审计字段 无论工程版还是交付版,建议至少保留: - `fid` - `source_layer_native` - `source_layer_std` - `geometry_type` - `native_code_type` - `native_code_value` - `canonical_object_type` 说明: - 如果交付版完全移除这些字段,将直接削弱点击查询能力和对象审计能力 - 当前项目如果要长期支持“点击解释 + CPA + 安全判断”,这些字段不能被视为纯工程期字段 ### 6.2 必保留的业务查询字段 建议按对象类型保留以下关键字段: - `depth_value_m` - `least_depth_m` - `clearance_height_m` - `light_color_code` - `light_sector_mode` - `bearing_deg` - `name_ja` - `place_name_en` - `shape_class_code` 必要时还应扩展: - 灯质 - 周期 - 射程 - 桥名 - 净空类别 - 航标附注 ### 6.3 必保留的渲染字段 建议保留: - `chart_icon_image` - `chart_symbol_code` - `chart_label_text` - `chart_label_subtext` - `chart_fill_style` - `chart_fill_pattern` - `chart_line_color` - `chart_line_width` - `chart_text_style` - `chart_text_color` ### 6.4 建议新增的统一字段 为降低上层复杂度,建议新增: - `object_domain` - `object_class` - `object_subclass` - `object_display_name` - `source_layer_native` - `native_code_type` - `native_code_value` 其中: - `source_layer_native` 可直接承接现有 `source_layer` - `object_subclass` 可直接复用 `canonical_object_type` ## 7. NewPEC 到 NavSea 的映射设计 ### 7.1 映射目标 映射的目标不是简单改名字,而是建立一套完整、可回查、可审计的自我体系。 映射应回答: 1. 一个 `NewPEC` feature 属于哪个 `NavSea object_domain` 2. 它属于哪个 `object_class` 3. 它属于哪个 `object_subclass` 4. 映射依据是什么 5. 是否仍能回到原始 `class_code / display_code` ### 7.2 建议映射键 建议映射规则至少按以下组合匹配: - `source_layer_native` - `geometry_type` - `native_code_type` - `native_code_value` - 必要时加 `canonical_object_type` 说明: - 航标类通常以 `display_code` 为主 - 危险物 / 设施类通常以 `class_code` 为主 - 地名、深度、净空类则常常以 `source_layer + 业务字段` 判定 ### 7.3 建议规则表 建议新增一张正式映射表,例如: - `navsea_object_taxonomy_rules` 建议字段: - `taxonomy_rule_id` - `bundle_id` - `source_layer_native` - `geometry_type` - `native_code_type` - `native_code_value` - `canonical_object_type_in` - `object_domain` - `object_class` - `object_subclass` - `object_display_name` - `rule_priority` - `rule_reason` - `status` ### 7.4 规则来源要求 每条映射规则都应有明确来源,来源可以是: - 原始 `NewPEC` 码值定义 - 既有 style / sprite 行为 - 现有数据库映射规则 - 既有审计结论 - 专家确认 禁止出现: - 无来源、不可解释的“拍脑袋分类” ## 8. 点击查询模型 ### 8.1 点击查询的目标 点击查询返回结果不应只告诉用户“命中了哪个 style layer”,而应返回: 1. 命中了哪个真实海图对象 2. 这个对象是什么 3. 它有哪些业务细节 4. 当前它如何被渲染 ### 8.2 推荐返回结构 建议 `native MapLibre` 点击拾取最终返回如下结构: ```json { "identity": { "fid": "13025299", "source_layer_native": "p航行危険障害物", "source_layer_std": "navigation_hazard_point", "geometry_type": "Point", "native_code_type": "class_code", "native_code_value": "404" }, "object": { "object_domain": "hazard", "object_class": "wreck", "object_subclass": "dangerous_fully_submerged_wreck", "canonical_object_type": "dangerous_fully_submerged_wreck", "object_display_name": "危险全沉没船" }, "properties": { "least_depth_m": 7.2, "light_color_code": null, "clearance_height_m": null, "name_ja": null }, "render": { "chart_icon_image": "symbol-daytime-404", "chart_symbol_code": "wreck", "chart_label_text": null } } ``` ### 8.3 点击判定逻辑 推荐顺序: 1. 先取点击范围内所有可见候选 feature 2. 先按 `fid` 聚合 3. 再按 `source_layer_native + native_code_type + native_code_value + geometry_type` 兜底聚合 4. 聚合后返回一个“真实物体”而不是多个分裂的 render hit ### 8.4 点击展示逻辑 面板建议固定分为四块: - `物体身份` - `物体分类` - `物体细节` - `当前渲染` 这样可以清楚区分: - 它是谁 - 它是什么 - 它有哪些航行含义 - 它在地图上为何画成现在这样 ## 9. 与 CPA / 安全判断的关系 ### 9.1 设计原则 CPA 或其他安全判断不应直接依赖渲染字段,而应依赖对象语义和业务属性。 也就是说: - `chart_icon_image` 不能作为安全逻辑输入 - `object_domain / object_class / object_subclass` 才是主要业务入口 ### 9.2 对 CPA 重要的对象属性 至少应能稳定读取: - `least_depth_m` - `depth_value_m` - `clearance_height_m` - `light_color_code` - `light_sector_mode` - `bearing_deg` - `object_domain` - `object_class` - `hazard severity` 或等价危险等级字段 ### 9.3 安全对象建议单独分层 建议在 `object_domain` 之上再建立一个轻量级安全标签: - `safety_category` 例如: - `navigation_aid` - `navigation_hazard` - `depth_constraint` - `clearance_constraint` - `facility_reference` 这样上层业务不必每次都回读复杂 `source_layer` 判定。 ## 10. 审计设计 本文最重要的部分是审计。 本设计把审计收口为两条核心硬门禁,外加若干辅助审计。 ### 10.1 两条核心硬门禁 #### A. 物体不丢 必须回答: - 原始对象是否在 NavSea 输出中仍能找到等价对象 - 是否发生: - `missing object` - `wrong relayer` - `identifier lost` - `identifier mismatch` - `over-merged object` 这是第一硬门禁。 只要这一条不过,后面渲染相似也不能判通过。 #### B. 渲染结果一致 必须回答: - 原始版有 icon/text/line/fill 的对象,在 NavSea 输出中是否仍以等价语义渲染 - 是否出现: - icon 丢失 - 文字丢失 - 线型/面样式语义画反 - 危险物 / 航标被画成错误类别 这是第二硬门禁。 ### 10.2 审计总顺序 正式顺序固定为: 1. 对象保真审计 2. 分类映射审计 3. 查询字段完整性审计 4. render-hit 一致性审计 5. style 语义审计 6. AOI / 视觉审计 7. 公开部署一致性审计 其中: - 第 1 层和第 4 层是两条核心硬门禁 - 第 2、3、5、6、7 层是配套强制审计 ## 11. 对象保真审计 ### 11.1 审计目标 确认“对象没有丢”。 ### 11.2 审计对齐键 推荐优先级: 1. `fid` 2. `source_layer_native + geometry_type + native_code_type + native_code_value` 3. `geometry + 稳定业务字段` ### 11.3 必查问题 - `missing object` - `wrong relayer` - `identifier lost` - `identifier mismatch` - `native_code lost` - `semantic collapse` 其中新增重点: - `native_code lost` - 原始 `class_code / display_code` 无法追回 - `semantic collapse` - 多个原始细类被错误压成一个过粗的 NavSea 细类 ### 11.4 通过条件 - 安全关键对象丢失数必须为 `0` - `wrong relayer` 必须为 `0` - `identifier lost` 必须为 `0` - 原始关键码值不可大规模丢失 ## 12. 分类映射审计 ### 12.1 审计目标 确认从 `NewPEC` 原生码值到 `NavSea` 自有体系的映射是完整、稳定、可解释的。 ### 12.2 必查问题 - 是否存在 `source_layer` 无法映射到任何 `object_domain` - 是否存在 `class_code / display_code` 无法映射到任何 `object_class` - 是否存在同一原生码被映射到多个冲突分类 - 是否存在重要对象被映射到 `unclassified` ### 12.3 建议输出 - `feature_count by object_domain` - `feature_count by object_class` - `feature_count by object_subclass` - `unmapped native_code top list` - `conflicting mapping rules` ### 12.4 通过条件 - 正式输出对象必须都有: - `object_domain` - `object_class` - `object_subclass` - 安全关键对象不允许进入: - `unclassified` ## 13. 查询字段完整性审计 ### 13.1 审计目标 确认交付版不仅“能画”,还“能点开查到关键细节”。 ### 13.2 必查对象组 至少包括: - 桥梁 / 净空限制 - 深度数字 / 等深线 - 航标 / 灯标 - 危险物 / 沉船 / 暗岩 / 洗岩 - 锚地 / 航路 / 主要设施 ### 13.3 必查字段 按对象组检查: - 桥高 / 净空: - `clearance_height_m` - 深度: - `depth_value_m` - `least_depth_m` - 灯标: - `light_color_code` - `light_sector_mode` - 危险物: - `object_class` - `object_subclass` - `native_code_value` ### 13.4 通过条件 - 与航行判断直接相关的关键查询字段不能大面积缺失 - 如果对象在地图上可点击,但关键数字或关键语义字段缺失,应判为不通过 ## 14. render-hit 一致性审计 ### 14.1 审计目标 确认“渲染结果一致”。 ### 14.2 审计粒度 保持当前项目正式口径: - 按 `feature instance` 粒度审计 - 保留 tile / zoom 敏感性 ### 14.3 必比内容 - `hit_count_old` - `hit_count_new` - `hit_types_old` - `hit_types_new` - icon 名 - text 值 - fill 语义 - line 语义 - opacity / width / pattern ### 14.4 通过条件 - 不允许关键对象从“有有效渲染”变成“无有效渲染” - 不允许命中层数量相同但语义画反 - 不允许图标 fallback 误导本体判断 ## 15. style 语义审计 ### 15.1 审计目标 确认新版 style 忠于旧版 style 的表现语义,而不是重新设计。 ### 15.2 重点专项 - 陆海主判定一致 - 水上 / 水下 / 露出 / 干出语义一致 - 危险物、潜堤、暗礁、洗岩、浅水区语义一致 - render-support 层没有被错误强化 - 深度数字、净空数字、灯标辅助信息没有被丢掉 ### 15.3 通过条件 - 不允许“画得很像,但安全语义已经反了” ## 16. AOI / 视觉审计 ### 16.1 定位 AOI / 视觉审计是强制层,但它不能替代对象保真审计。 ### 16.2 用途 - 校准 backend 审计盲区 - 复核用户实际看到的问题是否真的被修复 - 核对密集区点击对象和渲染对象是否一致 ### 16.3 当前固定基线 当前仍应固定使用: - `http://192.168.200.184/newpec/navsea-compare-karatsu-20nm.html` 不要用视觉相似去覆盖对象丢失事实。 ## 17. 公开部署一致性审计 必须确认: - 页面加载的是当前候选 style - 页面加载的是当前候选 tile - 版本号已经更新 - compare 页与候选构建产物一致 只要公开页面和候选产物不一致,放行审计就应视为未完成。 ## 18. 工程版与交付版的职责划分 ### 18.1 工程版 工程版应保留更多 trace 与审计字段,用于: - 规则定位 - 审计追踪 - 对象回查 - 映射调试 ### 18.2 交付版 交付版可以做裁剪,但不应裁掉: - 点击查询必要字段 - 安全判断必要字段 - 与原始对象对回必要字段 因此建议未来不要把交付版收缩成“只够 style 渲染”的极小集合,而是收缩成: - “足够渲染” - “足够查询” - “足够审计兜底” ## 19. 实施顺序建议 建议分 4 步落地。 ### 第一步:先固定字段模型 在 builder 中新增并固化: - `source_layer_native` - `native_code_type` - `native_code_value` - `object_domain` - `object_class` - `object_subclass` - `object_display_name` ### 第二步:建立正式映射规则表 为 `class_code / display_code -> NavSea taxonomy` 建规则表与 trace。 ### 第三步:补查询字段清单 按对象组梳理交付版必须保留的查询字段,避免“能画不能查”。 ### 第四步:扩展审计脚本 在现有脚本上补 3 类审计: 1. 分类映射审计 2. 查询字段完整性审计 3. `native_code` 保留审计 ## 20. 最终放行口径 未来正式放行建议固定为以下口径: ### 必须全部通过 - 对象保真审计通过 - 分类映射审计通过 - 查询字段完整性审计通过 - render-hit 一致性审计通过 - style 语义审计通过 - AOI / 视觉审计通过 - 公开部署一致性审计通过 ### 其中两条是核心硬门禁 - 物体不丢 - 渲染结果一致 ### 一句总括 `NavSea PBF` 的交付标准不应再是“图大致像了”,而应是: - 对象能对回 - 语义能解释 - 细节能查询 - 渲染能等价 - 审计能闭环 只有这样,这套 PBF 才既能做图,也能做查询、做安全判断、做长期工程演进。 ## 21. 首版语义定义草案 这一节给出当前 `NavSea` 可以直接采用的首版语义定义。 目的不是一次性把所有历史对象都做成最终完美 taxonomy,而是先建立一套: - 可解释 - 可映射 - 可审计 - 可逐步细化 的统一语义口径。 ### 21.1 定义层级 建议把每个对象的语义定义固定分成三层: 1. `object_domain` 2. `object_class` 3. `object_subclass` 其中: - `object_domain` - 业务大域 - 用于上层筛选、CPA、离线包、风险分组 - `object_class` - 业务大类 - 用于稳定 API 与审计聚合 - `object_subclass` - 细粒度对象子类 - 用于 pickup 解释与精细渲染映射 ### 21.2 首版 object_domain 定义 建议当前正式采用以下 `object_domain`。 - `navigation_mark` - 助航与导航标识对象 - `hazard` - 危险物、障碍物、潜在碍航对象 - `depth` - 深度、等深、深度分带 - `clearance` - 净空、高度、通行限制 - `anchorage` - 锚地、锚泊、抛锚限制 - `route` - 航路、航道、通行边界 - `facility` - 港湾设施、边界设施、结构物 - `landsea` - 陆海主判定对象 - `seabed` - 底质、海底支撑对象 - `toponym` - 地名标注对象 - `fishery` - 渔具、鱼礁、渔业相关对象 - `support` - 仅承担支撑语义、不应直接作为业务主对象的图层 - `pending` - 当前仍未完成语义收口的编码层 ### 21.3 当前标准层语义定义 以下定义基于当前 `Karatsu 20nm final` 实际标准层,以及现有 Domain 原型中的语义口径。 #### A. `navigation_mark` - `navigation_marks` - 语义定义: - 航标、灯标、浮标、灯塔、信标、AIS 航标等导航辅助对象 - `object_class` 建议: - `lighthouse` - `beacon` - `buoy` - `light_buoy` - `leading_light` - `virtual_aid_to_navigation` - `object_subclass` 建议主要来自: - `canonical_object_type` - `display_code` - `shape_class_code` - 说明: - 这是最典型需要“原生码值 + NavSea 统一语义名”并存的对象组 #### B. `hazard` - `navigation_hazard_point` - 语义定义: - 对航行构成直接危险的点状障碍物 - `object_class` 建议: - `wreck` - `rock` - `reef` - `obstruction` - `navigation_hazard_area` - 语义定义: - 对航行构成直接危险的面状障碍区 - `navigation_hazard_outline` - 语义定义: - 航行危险区域的边界线 - `anchor_caution_hazard_point` - 语义定义: - 对抛锚、泊船、近岸操作构成注意/限制的点状障碍物 - `anchor_caution_hazard_area` - 语义定义: - 抛锚注意障碍区 - `anchor_caution_hazard_outline` - 语义定义: - 抛锚注意障碍区边界 - `submerged_reef_area` - 语义定义: - 潜堤、潜礁、浅下危险地形区域 - `hazard_boundary_outline` - 语义定义: - 危险界、危险区域外缘边界 #### C. `depth` - `depth_contour` - 语义定义: - 等深线 - `depth_contour_overview` - 语义定义: - 概略等深线 - `depth_zone_739` - 语义定义: - 当前仍带旧编码痕迹的深度分带层 - 当前域建议: - `pending` - `depth_zone_741` - 语义定义: - 当前仍带旧编码痕迹的深度分带层 - 当前域建议: - `pending` 说明: - `depth_zone_*` 当前不建议直接当最终业务语义层 - 更合理的最终形态应是: - `depth_band` - `shallow_water_band` - `deep_water_band` 等可解释层名 #### D. `clearance` - `clearance_limit_point` - 语义定义: - 高度/净空限制点标注对象 - 关键查询字段: - `clearance_height_m` - `clearance_limit_line` - 语义定义: - 高度/净空限制线或关联约束线 - `bridge_structure` - 语义定义: - 桥梁等与净空判断相关的重要结构物 #### E. `anchorage` - `anchorage_point` - 语义定义: - 锚地符号或锚泊点状标识 - `anchorage_area` - 语义定义: - 锚地、锚泊区域 - `anchorage_outline` - 语义定义: - 锚地边界线 #### F. `route` - `route_outline` - 语义定义: - 航路、航道、通行带边界 说明: - 当前 `20nm final` style 里主要暴露的是 `route_outline` - 未来若要做更完整 route 语义,应进一步引入: - `route_area` - `route_axis_line` - `route_boundary_point` #### G. `facility` - `facility_boundary_point` - 语义定义: - 港湾设施、边界设施、港口辅助设施等点状对象 - 说明: - 当前语义仍偏宽,后续建议继续细分 - `facility_boundary_area` - 语义定义: - 设施/边界相关区域 - 当前域建议: - `detail` - 说明: - 更像容器层,后续需继续拆清 - `facility_boundary_outline` - 语义定义: - 设施/边界边线 - `onshore_structure_area` - 语义定义: - 陆上结构物面 - `onshore_structure_line` - 语义定义: - 陆上结构物线 - `onshore_structure_point` - 语义定义: - 陆上结构物点 - `pilot_station_point` - 语义定义: - 引航站点 - `clip_outline_754` - 语义定义: - 旧编码型边界辅助层 - 当前域建议: - `pending` #### H. `landsea` - `land_area` - 语义定义: - 陆海主判定层中的陆地区域 - 说明: - `land_area` 应继续作为陆海主判定唯一主来源 - `baseline_area` - 语义定义: - 基本线相关面 - 当前域建议: - `safety_extended` - 说明: - 当前仍偏容器/组合语义,后续需继续收口 - `baseline_line` - 语义定义: - 基本线线层 - `baseline_outline` - 语义定义: - 基本线边界 #### I. `seabed` - `seabed_text_point` - 语义定义: - 底质标注点 - `seabed_line` - 语义定义: - 海底线 - `bathymetry_line` - 语义定义: - 海底地形支撑线 - 当前域建议: - `support` - 说明: - 它更像支撑线,不宜直接作为最终业务主对象 - `hole_area` - 语义定义: - 穴/凹地/透明支撑区域 - 当前域建议: - `support` - 说明: - 不应被误解释为陆地或实体设施 #### J. `toponym` - `place_label_sea` - 语义定义: - 海上地名标注 - `place_label_land` - 语义定义: - 陆上地名标注 #### K. `fishery` - `fixed_fishing_gear_area` - 语义定义: - 定置渔具或渔业占用区域 ### 21.4 当前仍属于待收敛或容器语义的层 以下层当前不建议被视为最终稳定的业务语义层,应继续在后续 builder / taxonomy 中细化: - `baseline_area` - `baseline_line` - `baseline_outline` - `facility_boundary_area` - `facility_boundary_outline` - `bathymetry_line` - `hole_area` - `depth_zone_739` - `depth_zone_741` - `clip_outline_754` 这些层的问题不是不能用,而是: - 语义过宽 - 仍带旧编码/制图容器痕迹 - 容易被错误当作业务主对象 ### 21.5 当前可以直接作为稳定业务对象层的部分 以下层已经足够接近稳定业务语义,可直接作为 pickup 和业务查询的首版入口: - `navigation_marks` - `navigation_hazard_point` - `anchor_caution_hazard_point` - `depth_contour` - `depth_contour_overview` - `clearance_limit_point` - `clearance_limit_line` - `anchorage_area` - `anchorage_point` - `route_outline` - `pilot_station_point` - `place_label_sea` - `place_label_land` - `seabed_text_point` - `land_area` ### 21.6 语义定义与审计的关系 语义定义不是写出来就结束,必须进入审计。 至少应新增以下检查: 1. 每个正式输出 `feature` 必须有: - `object_domain` - `object_class` - `object_subclass` 2. 每个标准层必须有明确语义定义,不能长期停留在: - `unknown` - `pending` 3. 所有安全关键层不得退回到纯容器语义或支撑语义 4. 视觉审计时,不允许: - 用 `support` 对象冒充业务主对象 - 用容器层视觉相似掩盖真实对象语义漂移 ## 22. 核心规则记录 本节把当前已经讨论收口、后续不应再反复摇摆的核心规则固定下来。 ### 22.1 唯一对象主键 - 每个原始 `NewPEC` 对象只认一个主键: - `fid` - `NewPEC fid` 与 `NavSea fid` 允许采用不同编码形式 - 但两者必须: - 一对一 - 稳定 - 可逆 这意味着: - 对象 identity 只有一个 - 不再为对象对应额外发明第二套 identity 字段 ### 22.2 主对象一对一 - 当前正式口径坚持: - `1 raw object -> 1 primary NavSea feature` - 不把一个原始对象默认拆成多个业务主 feature - 如后续确需派生辅助 feature,也只能作为: - `helper / support feature` - 不得替代主对象 ### 22.3 统一对象载荷 - 同一个 `feature` 的同一套属性同时服务: - 渲染 - pickup - CPA / 安全判断 - 审计 - 不再设计: - 一套只给渲染的对象模型 - 一套只给查询的对象模型 - 一套只给安全判断的对象模型 ### 22.4 审计全部围绕 fid - 对象保真审计主键: - `fid` - 语义漂移审计: - 看同一 `fid` 的语义属性是否漂移 - 渲染一致性审计: - 看同一 `fid` 的渲染结果是否等价 因此审计结构固定为: 1. `fid` 是否还在 2. 该 `fid` 的语义是否还对 3. 该 `fid` 的渲染是否仍与 `NewPEC` 等价 ### 22.5 不做“查询字段 vs 渲染字段”硬分离 - 当前项目不建议把: - `pickup` 查询字段 - 渲染字段 完全拆成两套数据源 - 原因: - 二者高度重合 - 容易形成双真相源 - 不利于离线、native、本地判断与审计闭环 正确方向是: - 一个统一对象载荷 - 但做“必要最小集”裁剪 - 剔除纯 debug / 纯 trace / 纯中间推导字段 ## 23. 当前 Karatsu 20nm Final 的调整判断 本节回答一个现实问题: - 当前 `Karatsu 20nm final` 是否需要重写 PBF / style 结论: - 当前不建议重写整体架构 - 建议在现有 `20nm final` 基础上做增量调整 ### 23.1 当前 20nm final 已具备的基础 当前这条线已经具备: - 标准层收口 - 对象保真通过 - 视觉 compare 基线稳定 - 关键分类/渲染字段已物化 因此它已经是一条: - 可交付 - 可审计 - 可继续演进 的基础线,而不是需要推倒重来。 ### 23.2 当前不建议做的事 当前不建议: - 改成完全新的分层体系后再重做整套 style - 为 pickup 单独再造第二套 query 数据模型 - 把查询与渲染彻底拆成两套接口 - 仅为了语义理想化而破坏当前 compare 审计基线 ### 23.3 当前建议调整 PBF 的部分 当前更应优先调整的是: #### A. 补统一语义字段 建议在当前 `20nm final` PBF 中增量补入: - `object_domain` - `object_class` - `object_subclass` 说明: - 这三个字段是当前统一对象模型最缺的一层 - 它们直接服务 pickup、CPA 和业务消费 - 加它们不要求推翻现有标准层和 style #### B. 保留现有关键原生码与渲染字段 继续保留: - `class_code` - `display_code` - `shape_class_code` - `canonical_object_type` - 关键 `chart_*` - 关键数值字段 说明: - 这些字段当前已经被 style、解释和审计共同依赖 - 不应为了追求“纯新体系”而过早删掉 #### C. 保持 fid 作为 primary feature id 建议继续坚持: - `feature.id = fid` 或与之等价的稳定主键口径 这样 native 端 pickup、对象保真审计、左右对照都最直接。 ### 23.4 当前建议调整 style 的部分 style 当前不建议大改架构,但建议注意以下原则: #### A. style 继续主要消费标准层 + 物化渲染字段 - 继续使用当前标准层 - 继续优先消费: - `chart_icon_image` - `chart_label_text` - `chart_fill_style` - `chart_line_color` 等物化字段 #### B. style 不承担对象 identity 解释职责 - style 的职责是“画” - 不负责“定义对象身份” - pickup 与审计都应围绕 `fid` 和统一语义字段解释对象 #### C. compare 页不换基线,只升级 pickup 逻辑 - 不切换当前固定 compare URL - 不另建新的主视觉对比页 - 若要改动优先改: - 点击拾取逻辑 - 面板展示结构 - 左右对照方式 ### 23.5 当前最推荐的调整顺序 建议按下面顺序进行: 1. 先给当前 builder 增补统一语义字段 2. 再用同一批字段改 pickup 解释层 3. 再补相关审计 4. 最后才考虑是否需要进一步精简或重构 style ## 24. Pickup 消费方案 本节定义 native 侧如何消费当前及后续增强后的 `NavSea PBF`。 ### 24.1 Pickup 的目标 pickup 的目标不是“点中了哪个 render layer”,而是: 1. 找到点击命中的真实对象 2. 返回这个对象的统一语义 3. 返回该对象的关键查询属性 4. 返回当前命中的渲染层信息 ### 24.2 输入 native 端输入: - 点击屏幕坐标 - 当前地图缩放级 - 当前视图内已加载的 `NavSea` source ### 24.3 查询方式 建议使用: - `queryRenderedFeatures` 但不要只查单像素点,建议用: - 点击点周围 `6px ~ 10px` 小范围 说明: - 海图符号小且密集 - 单点查询容易错过目标 ### 24.4 候选过滤 先过滤到: - 当前 `NavSea` source - 当前业务关注的渲染层 必要时对 support/background 降权。 ### 24.5 候选聚合主键 所有候选 feature 必须先按: - `feature.id` 聚合。 这里的设计前提是: - `feature.id` 与 `fid` 等价或可稳定映射 这一步非常关键,因为: - 同一个对象可能命中 icon/text/outline 多个 render layer - pickup 最终应返回一个对象,不是多个分裂的 render hit ### 24.6 候选排序 同一点击区域内多个 `fid` 候选时,建议排序优先级: 1. `navigation_marks` 2. `navigation_hazard_point` 3. `anchor_caution_hazard_point` 4. `clearance_limit_point` 5. 其他点对象 6. 线对象 7. 面对象 8. support / background 如果同一对象内部有多个 render hit,展示时可保留全部命中层,但只选一个代表对象。 ### 24.7 Pickup 返回结构 建议 native 层最终统一返回: ```json { "fid": 12007897, "source_layer_std": "navigation_marks", "geometry_type": "Point", "object_domain": "navigation_mark", "object_class": "lighthouse", "object_subclass": "harbor_lighthouse", "canonical_object_type": "harbor_lighthouse", "properties": { "display_code": "30100005", "class_code": null, "shape_class_code": null, "depth_value_m": null, "least_depth_m": null, "clearance_height_m": null, "light_color_code": "white", "light_sector_mode": "sector", "name_ja": "平戸牛ケ首灯台" }, "render": { "chart_icon_image": "symbol-daytime-301", "chart_symbol_code": "lighthouse", "render_hit_layers": [ "navigation-mark-icon", "navigation-mark-text" ] } } ``` ### 24.8 Pickup 面板展示建议 建议 pickup UI 固定展示四块: 1. `对象` - `fid` - `source_layer_std` 2. `分类` - `object_domain` - `object_class` - `object_subclass` 3. `细节` - 水深 - 净空 - 灯光 - 名称 4. `渲染` - 当前命中 render layer - icon - text ### 24.9 Pickup 与 CPA 的关系 pickup 不应定义一套独立于安全判断的数据模型。 正确做法是: - pickup 展示的就是对象统一语义模型的一部分 - CPA / 安全判断消费的也是同一对象上的同一组语义字段 也就是说: - `pickup` 是展示层 - `CPA` 是判定层 - 但二者读取同一份对象语义 ### 24.10 当前 compare 页建议改法 当前 compare 页的点击逻辑还是: - `queryRenderedFeatures(event.point)` - 直接取 `features[0]` 这只适合临时 inspect,不适合作为正式 pickup 逻辑。 建议后续改成: 1. 查询点击小范围候选 2. 先按 `feature.id` 聚合 3. 再按对象优先级选代表对象 4. 面板展示统一对象结构 5. 左右页如果命中同一 `fid`,则做并排对照 ## 25. Pickup 规则字典与解释器 当前建议正式采用: - 规则字典: - [navsea-pickup-rules.v1.json](/root/sourceserver/pbf/src/pbf/navsea-pickup-rules.v1.json) - JS 前端解释器: - [navsea-pickup-interpreter.js](/root/sourceserver/pbf/src/pbf/navsea-pickup-interpreter.js) - TS 前端解释器: - [navsea-pickup-interpreter.ts](/root/sourceserver/pbf/src/pbf/navsea-pickup-interpreter.ts) ### 25.1 为什么采用“规则字典 + 薄解释器” 原因: - 前端可以本地判读,不增加 PBF 容量 - 规则可版本化、可审计、可和 builder / style 同步管理 - 不把所有解释逻辑写死在前端 if/else 中 - 后续补 `object_domain / object_class / object_subclass` 后,可以平滑过渡 ### 25.2 当前解释器职责 解释器当前职责固定为: 1. 接收 `queryRenderedFeatures` 返回的候选 feature 2. 按 `feature.id` 聚合 3. 按规则字典匹配 `source_layer_std` 4. 若前端传入 `click_lnglat`,则在同分候选间优先选离点击点最近的对象 5. 结合规则字典中的 `interaction_role` 与 `pickup_priority` 选主对象 6. 生成统一 pickup 结果 解释器不负责: - 再造对象 identity - 替代 style 做渲染判断 - 替代审计脚本做最终放行判定 ### 25.3 当前规则字典职责 规则字典负责声明: - 每个标准层属于哪个 `object_domain` - 当前默认 `object_class` - 当前优先看的原生码字段 - pickup 标题字段优先级 - pickup 细节字段清单 - render 信息回显字段清单 - `semantic_status` - `interaction_role` - `pickup_priority` - `render_layer_groups.primary / area / info / ignore` ### 25.4 更新规则 规则字典不是要求每次纯视觉微调都改。 必须同步更新的情形是: - PBF 标准层发生变化 - 某层的关键分类字段发生变化 - style 对某层的主渲染字段依赖发生变化 - 新增正式支持 pickup 的层 - 可交互 render layer 分组发生变化 ### 25.5 当前消费建议 当前 native / web 端消费建议: 1. 加载 `navsea-pickup-rules.v1.json` 2. 优先读取 `render_layer_groups.primary / area / info / ignore` 3. 先做精确点查: - `area + primary + info` 4. 精确点查未命中时,再做小范围补查: - `primary + info` 5. 把候选数组喂给对应解释器 6. 直接展示返回的: - `primary` - `candidates` 7. 后续如果补入统一语义字段,再逐步把规则字典从“判读主来源”降为“兼容补充层”