21 KiB
Style Visual Object Tool
目标
本工具只做一件事:
从一份 Style JSON 以及它使用的 Sprite / Glyph 中,独立提取和生成 Visual Object。
工具输出的是匿名、可比较、可审计的 Visual Object,不负责给 Visual Object 赋予 NavSea 标准 Layer 名称,也不负责解释 Provider 的业务字段。
最重要原则:先生成 Visual Object,再做语义和 Layer 对齐
本工具必须严格遵守以下顺序:
任意 Provider Style + Sprite / Glyph
↓
Style Visual Object Tool
↓
Anonymous Visual Object Catalog
↓
与 Standard Visual Object Catalog 比较
↓
MATCH / PARTIAL / UNKNOWN
↓
最后才允许赋予标准 Layer 名称或 Semantic
禁止走捷径
在 Visual Object 生成阶段,以下信息即使存在,也只能作为 provenance / audit 信息保存,不得用于决定 Visual Object 属于哪个标准 Layer 或 Semantic:
source-layer名称- Style Layer
id - Provider 名称
canonical_object_type- S-52 / CM95 对象类名称
- S-52 symbol code 的文字含义
- 任何看起来与 NavSea 标准 Layer 同名或相似的字段
- 任何 Provider 私有业务字段名称
例如,某个 Provider 的 Style 中即使存在:
source-layer = navigation_marks
本工具也不得因此把该 Visual Object 定义为 NavSea 的 navigation_marks。
它只能记录:
provenance.source_layer = navigation_marks
真正的 Layer 名称必须在 Visual Object 生成完成后,通过与标准 Visual Object 的比较结果确定。
Provider-neutral
本工具必须完全独立于具体 Provider。
同一套代码应能够处理:
- NavSea Style
- CM95 Style
- 未来 Provider B / C / D
- 任意符合支持范围的 MapLibre Style
主逻辑中禁止出现类似:
if provider == "cm95"
if source_layer == "navigation_marks"
if symbol_code == "BOYCAN63" then ...
这类 Provider-specific Semantic 判断。
Provider-specific 名称可以进入 provenance,但不能进入 Visual Object 分类逻辑。
输入
第一阶段输入仅包括:
Style JSON
Sprite JSON + PNG
Glyph(Style 使用时)
Visual Object 提取本身不要求读取 PBF。
如果 Style 中使用数据驱动表达式,例如:
["get", "chart_icon_image"]
或:
["get", "s52_symbol_code"]
工具必须保留为动态视觉参数,不得为了得到具体值去读取 PBF、猜测字段含义或套用 Provider 规则。
输出
建议至少生成:
catalog.json
catalog.html
previews/
audit.json
其中每个 Visual Object 至少记录:
- 匿名 Visual Object ID
- geometry role
- Style Layer 原始顺序 / z-order
- 参与组成的 Render Components
- icon / line / fill / pattern / circle / text
- Sprite 实际视觉资源
- 动态视觉参数
- 出现条件 / Style filter
- 组件数量与组合关系
- Preview
- provenance
- 无法解析或无法确定的部分
Visual Signature
用于后续跨 Provider 比较的核心是 Visual Signature,而不是 Provider 字段名称。
Visual Signature 应主要表达:
geometry role
+
ordered render components
+
sprite visual
+
fill
+
line
+
pattern
+
text role
+
component multiplicity
+
component composition
+
style order
+
visual conditions / variants
后续 Visual Matcher 应基于这些视觉结构进行比较。
Provider 原始字段只作为辅助审计证据,不作为主要匹配依据。
source-layer 的地位
source-layer 在本工具中只具有两个作用:
- 帮助确定 Style Layer 的数据来源和可组合范围;
- 作为 provenance / debug / audit 信息输出。
它不是 Semantic,也不是最终 Layer 分类结果。
不得执行:
source-layer 名称
→ 直接得到 NavSea 标准 Layer
正确流程必须是:
Style + Sprite
→ Visual Object
→ Visual Match
→ 标准 Layer / Semantic
Standard Visual Object
NavSea 当前 Style 也必须使用同一套 Style Visual Object Tool 生成 Visual Object。
不得在 Tool 内置 NavSea Layer 规则。
NavSea 之所以成为 Standard,不是因为 Tool 对 NavSea 使用特殊逻辑,而是在 Tool 生成 Visual Object 之后,由独立的标准定义/人工确认把这些 Visual Object 与 NavSea 标准 Layer 关联起来。
因此:
NavSea Style
→ Anonymous Visual Object Catalog
→ 标准确认
→ Standard Visual Object Catalog
其他 Provider:
Provider Style
→ Anonymous Visual Object Catalog
→ 与 Standard Visual Object Catalog 比较
→ 标准 Layer
不属于本工具的职责
本工具不负责:
- PBF 数据读取和 Feature 实例化
- Provider 字段翻译
- CM95 专用判断
- NavSea 专用判断
- Semantic 命名
- 标准 Layer 命名
- Feature grouping
- 危险性判断
- 船舶吃水相关 Planning / Danger 判断
- 跨 Provider 的最终匹配决策
这些属于后续独立阶段或独立 Tool。
实现约束
后续实现必须满足:
- 未知 Style expression 必须显式标记 UNKNOWN / UNSUPPORTED,不得静默忽略;
- 必须保留 Style 原始顺序;
- 必须保留组件 multiplicity,不能用 set 去重破坏组合;
- 必须保留动态表达式,不得伪造成确定值;
- Sprite 必须根据 atlas metadata 提取真实视觉资源;
- 不得通过坐标接近、名字相似或 Provider 字段名自动拼接/分类 Visual Object;
- 不得因为某个 source-layer 与 NavSea 标准 Layer 同名就直接判定 MATCH;
- Visual Object 的生成和 Visual Object 的标准匹配必须是两个独立阶段。
一句话验收标准
给工具任意一套 Style + Sprite,即使它完全不知道这是什么 Provider、也没有任何 PBF 数据,仍然能够独立生成匿名 Visual Object Catalog;只有在该 Catalog 生成完成后,才允许进入与 NavSea Standard Visual Object Catalog 的比较和 Layer 命名阶段。
NavSea Standard Visual Object Catalog 冻结规则
NavSea 的 Visual Object 与标准 Layer 名在首次完成生成、确认和命名后,应视为 Standard Visual Object Catalog 的冻结基线。
正常情况下:
NavSea Anonymous Visual Object
↓
人工/标准确认 Layer 名
↓
Standard Visual Object Catalog
↓
冻结
冻结后,后续 CM95、Provider B、Provider C 等只能使用该 Standard Visual Object Catalog 进行 Visual Object 匹配和 Layer 命名。
除非用户明确要求重建、重新生成、修订标准或升级 Standard Catalog 版本,否则禁止:
- 每次处理新 Provider 时重新生成 NavSea Visual Object;
- 自动重新计算或改变 NavSea Visual Object ID;
- 自动改变已经确认的标准 Layer 名;
- 因 CM95 或其他 Provider 的数据特点反向修改 NavSea Standard Catalog;
- 用新的 Provider 匹配结果覆盖现有标准基线。
如果确实需要修改 Standard Visual Object Catalog,必须作为显式的标准升级处理,并保留旧版本,不得静默覆盖。
因此正常跨 Provider 工作流固定为:
已冻结的 NavSea Standard Visual Object Catalog
│
│ 作为只读标准
▼
Provider Anonymous Visual Object
│
▼
Visual Matcher
│
▼
标准 Layer 命名结果
一句话原则:
NavSea Standard Visual Object Catalog 是标准输入,不是每次 Provider 解析时重新生成的临时产物。
Visual Object Layer Assignment 的补充硬规则
1. Sprite 存在不等于 Style 会绘制
Sprite atlas 中存在某个资源,只能说明资源可用,不能说明当前 Style 会实际引用它。
Anonymous Visual Object Catalog 只能从 Style 的正向可达规则生成:
Style 明确允许的资源
→ 进入 Anonymous Visual Object Catalog
仅存在于 Sprite、但当前 Style 没有正向可达路径的资源
→ 不进入 Catalog
尤其不得把 !match、!= 等排除条件中的值误当成候选 Visual Object。
2. 同一视觉类可能对应多个标准 Layer
如果 NavSea Standard Visual Object Catalog 中同一实际视觉图形被多个标准 Layer 复用,则 Visual Matcher 不能仅凭图形强行选一个 Layer。
必须输出:
AMBIGUOUS
candidateStandardLayers:
- layer_a
- layer_b
例如危险物公共符号可以同时被多个标准 Layer 使用;这种歧义是 Standard Catalog 自身的事实,不应由 Matcher 擅自消除。
3. 禁止整个匿名 group 继承单一 Layer
Style 的一个匿名 group 可能允许多个不同视觉家族,尤其是通用 S-52 Style。
因此禁止:
group 命中一个视觉锚点
→ 整个 group 继承该 Layer
Layer Assignment 必须以单个 Visual Object / Visual Resource 为基本单位。
Group 只用于:
- 组合范围审计;
- Style provenance;
- 结果分布检查。
4. Layer Assignment 状态
正式状态固定为:
MATCH
PARTIAL
AMBIGUOUS
COMPONENT
UNKNOWN
含义:
MATCH:实际图形基本一致,可以直接作为标准 Layer 锚点;PARTIAL:不是同一完整图形,但视觉家族或组件关系足以支持唯一标准 Layer;AMBIGUOUS:视觉证据只能得到多个标准 Layer 候选,禁止强行选一个;COMPONENT:明确只是完整 Visual Object 的组成部分,不单独分配 Layer;可选记录组件类型;UNKNOWN:当前证据不足,不命名。
未知和歧义都是合法结果,禁止为了提高覆盖率而静默猜测。
人工确认 UI:CM95 Visual Object Reviewer
最终 Layer Assignment 必须允许人工确认。项目内提供独立 Web Reviewer:
tools/style-visual-object/reviewer/
├── review_server.py
└── web/
├── index.html
├── app.js
└── style.css
默认启动:
python3 tools/style-visual-object/reviewer/review_server.py --host 0.0.0.0 --port 18083
人工确认单位
Reviewer 以 CM95 当前 Style 正向可达的唯一 Visual Resource 为确认单位。
当前基线为 150 个资源。一个人工决定会应用到该视觉资源在 Anonymous Catalog 中的所有 occurrence,但不会修改 Anonymous Catalog 本身。
主审查界面必须隐藏 Provider 语义信息
为了避免人工被字段名或已有 source-layer 名称带偏,主审查界面默认只能看到:
- 匿名 Visual Object ID;
- 实际图形;
- component role;
- geometry role;
- occurrence 数;
- NavSea Standard Visual Object 候选;
- 标准 Layer;
- 当前人工决定。
以下 CM95 原始信息默认隐藏:
- resource key;
- source-layer;
- Style Layer id;
- Provider provenance。
只有用户主动展开“审计信息”后才能读取这些内容。
人工状态
人工决定固定使用:
MATCH
PARTIAL
AMBIGUOUS
COMPONENT
UNKNOWN
规则:
- MATCH / PARTIAL:必须选择且只能选择一个标准 Layer;
- AMBIGUOUS:必须选择至少两个候选标准 Layer;
- COMPONENT:不选择标准 Layer、不绑定 Standard Visual Object;可选记录顶标、浮标主体、立标主体、灯光、附加标记、面填充图案、线型图案、文字或其他组件;
- UNKNOWN:不选择标准 Layer;
- Standard Visual Object 可以选择,也可以不选择;
- 人工确认优先于机器建议;
- 未人工确认的项目在最终人工导出时保持 UNKNOWN,不自动继承机器建议。
人工结果保存
增量人工决定保存到:
tools/style-visual-object/output/cm95-manual-review/manual-review-v1.json
点击“生成当前人工确认结果”后生成:
tools/style-visual-object/output/cm95-manual-review/
├── reviewed-anchors-manual-v1.json
└── assignment/
├── cm95-layer-assignment-v1.json
├── cm95-layer-assignment-v1.csv
└── cm95-layer-assignment-v1.html
人工确认过程不得覆盖:
navsea-standard/standard-catalog.json;cm95-anonymous/anonymous-catalog.json;- 既有自动/辅助建议文件。
NavSea Standard Catalog 继续保持 FROZEN,只作为只读标准库使用。
Reviewer 中文名称显示规则
人工 Reviewer 中,CM95 与 NavSea Standard Visual Object 均应优先显示中文名称,帮助人工理解和确认。
中文名称来源分两类:
-
CM95:
- 优先读取当前 CM95 仓库中的 S-52 symbol / line / area-pattern metadata;
- 保留 S-52 原始英文
description; - 生成独立的中文显示译名;
- 中文译名属于工程 UI enrichment,不冒充 IHO 官方中文译名。
-
NavSea Standard:
- 依据冻结 Standard Visual Object 的语义资源键和标准 Layer 生成中文显示名;
- 标准 Layer 同时显示中文名和原始 Layer ID。
名称补充表:
tools/style-visual-object/output/reference-name-enrichment-v1.json
固定原则:
中文名、英文说明、S-52 code 只用于 UI 显示和人工理解,不得参与 Visual Matcher、自动聚类或 Layer Assignment。
Reviewer 主界面显示优先级:
中文名称
→ 实际图形
→ 中文标准 Layer
→ 原始 code / 英文说明(辅助)
已有机器建议也必须显示:
标准对象中文名
+
标准 Layer 中文名
+
MATCH / PARTIAL / AMBIGUOUS / COMPONENT / UNKNOWN
不得只显示资源 key 或 Layer ID 让用户自行猜测。
Reviewer 宽屏固定确认布局
Reviewer 在宽屏下采用固定三栏工作区:
左:CM95 当前 Visual Object
中:NavSea Standard 候选(竖排、内部滚动)
右:人工判断(固定可见)
固定要求:
- 主页面不得为了点击 MATCH / PARTIAL / AMBIGUOUS / COMPONENT / UNKNOWN 或保存结果而要求纵向滚动;
- NavSea Standard 候选采用竖排列表,并在候选区域内部滚动;
- 标准 Layer 列表在人工判断面板内部滚动;
保存并下一个 / 仅保存 / 撤销始终保持在右侧人工判断区可见;- 左侧 CM95 队列独立滚动;
- 审计信息默认折叠,不抢占主要确认空间;
- 窄屏才允许退回上下布局。
Standard Visual Object 缺失时的 Layer-only 人工命名
外部 Provider(例如 CM95 / S-52)的视觉内容可能多于当前 NavSea Standard Visual Object Catalog。 因此:
找不到对应的 NavSea Standard Visual Object,不等于无法确定标准 Layer。
人工 Reviewer 必须支持两种最终确认路径:
A. 有对应标准图标
Provider Visual Object
→ Standard Visual Object
→ Standard Layer
assignment_mode = VISUAL_OBJECT_MATCH
B. 没有对应标准图标,但所属 Layer 可以人工确定
Provider Visual Object
→ Standard Layer
assignment_mode = LAYER_ONLY
standard_resource_key = null
Layer-only 的要求:
- 必须由人工明确选择标准 Layer;
- 不得伪造一个不存在的 Standard Visual Object;
- 不得因为没有对应图标就强制设为 UNKNOWN;
- 中文名称、S-52 官方英文说明和实际视觉可以作为人工理解证据;
- 这些名称仍不进入自动 Visual Matcher;
- 当前 Reviewer 中,点击“没有对应标准图标,只确认所属 Layer”会清除 Standard Visual Object 绑定,并保留唯一 Layer。
状态建议:
- 有明确对应完整图形时可使用 MATCH;
- 无对应标准图标但 Layer 明确时使用 PARTIAL + LAYER_ONLY;
- 只能确定多个可能 Layer 时使用 AMBIGUOUS;
- 连 Layer 也无法确定时才使用 UNKNOWN。
COMPONENT:只作为完整 Visual Object 的组成部分
当当前显示的 S-52 / CM95 图形只是一个主体、顶标、灯光或其他附加组件时,不应强迫用户给它最终 Layer。 Reviewer 必须允许:
status = COMPONENT
assignment_mode = COMPONENT_ONLY
standard_layer = null
standard_resource_key = null
可选 component_kind:
topmark 顶标
buoy_body 浮标主体
beacon_body 立标主体
light 灯光
auxiliary_mark 附加标记
fill_pattern 面填充图案
line_pattern 线型图案
text 文字
other 其他组件
COMPONENT 与 UNKNOWN 必须区分:
COMPONENT:已经知道它只是完整对象的一部分;UNKNOWN:当前连它的作用/归属关系也无法可靠判断。
后续 Composite Visual Object 阶段再把 COMPONENT 与其他组件组合,最终 Layer 应尽量由完整 Visual Object 确认。
Reviewer 最可能候选提示
Reviewer 的 NavSea Standard 候选可以提供一个 UI-only 的“最可能”提示,帮助人工快速判断。
综合参考只用于界面提示,来源包括:
- Visual Matcher 的实际图形相似度;
- CM95 中文显示名与 NavSea Standard 中文显示名的文字相似度;
- 已有 reviewed visual suggestion 是否支持同一标准对象或同一 Layer。
界面规则:
- 综合排序第一的候选中文名称标红;
- 显示“最可能”标签;
- 同时显示“视觉 xx% / 综合 xx%”;
- 即使是第一名,综合分较低时也必须保留低分,不能隐藏不确定性;
- 红色提示不得自动选择 Standard Visual Object;
- 不得自动写入人工决定;
- 不参与最终 Layer Assignment。
一句话:
红色“最可能”只是人工审查提示,不是系统确认结果。
宽屏布局同时调整为:当前 CM95 对象区域更窄,NavSea Standard 视觉候选区域更宽,右侧人工判断继续固定显示。
Provider Layer Classifier:当前工作的最终目标
当前多源 PBF 对应工作的目标不是寻找“外部 Provider 图标等于 NavSea 哪个图标”,而是:
把外部 Provider 的对象正确分类到现有 NavSea Standard Layer。
因此正式流程分成两层:
第一层:Provider-neutral Style Visual Object Tool
Style + Sprite
→ Anonymous Visual Object
第二层:Provider Layer Classifier
Anonymous Visual Object
+ Provider 官方语义资料
+ 实际视觉证据
+ 可选 Standard Visual Object 参考
→ NavSea Standard Layer
→ 人工确认
关键规则:
Style Visual Object Tool仍然不知道 NavSea Layer、CM95 语义或 Provider 私有分类,继续保持 Provider-neutral。Provider Layer Classifier可以使用 Provider 自己的官方语义资料。CM95 当前使用 S-52 metadata 的官方英文description,再提供中文显示译名。- Provider 的
source-layer仍不得作为分类依据,只保留 provenance/audit。 - Standard Visual Object 一一对应不是最终目标,也不是 Layer 命名的强制前提。
- 没有对应 NavSea 图标,但 Provider 语义足以确定 Layer 时,允许直接
LAYER_ONLY。 - 当前图形只是顶标、灯光、主体、pattern 等组件时使用
COMPONENT,不单独分配最终 Layer。 - 只有连 Layer 都无法可靠判断时才使用
UNKNOWN。
CM95 语义 Layer 规则
当前 CM95 分类规则独立保存:
tools/style-visual-object/cm95_semantic_layer_rules_v1.json
规则使用 S-52 官方 description 和资源类型进行声明式分类,例如:
tower, black/white, full-chart and simplified
→ 对象大类:陆上塔状构筑物
→ onshore_structure_point
beacon tower, red, full-chart
→ 对象大类:航标塔体
→ navigation_marks
topmark for buoys ...
→ COMPONENT / topmark
这些规则属于 Provider Layer Classifier,不得回写进通用 Style Visual Object extraction。
Reviewer 中间区域
Reviewer 中间主要区域现在显示 NavSea Layer 建议,综合参考:
- S-52 官方语义;
- 实际视觉相似度;
- 已有 reviewed visual suggestion。
语义证据优先于“长得像”。例如普通 tower 即使视觉上很像 beacon,也应优先按 S-52 的 tower 语义归到 onshore_structure_point。
Standard Visual Object 图标被降为折叠的辅助参考区,不再作为主要任务。
Git 冻结基线与固定校验命令
CM95 v1 人工分类完成后,以下内容属于应进入 Git 的冻结基线:
- 工具实现:
style_vo_tool.py、visual_anchor_matcher.py、build_reference_names.py、apply_reviewed_layer_assignment.py; - Provider 分类规则:
cm95_semantic_layer_rules_v1.json; - 人工 Reviewer:
reviewer/; - 固定校验逻辑:
validate_cm95_classification.py; - NavSea Frozen Standard Catalog 与 CM95 Anonymous Catalog;
- S-52 中文名称 enrichment、视觉辅助结果;
- 150 项人工确认;
- 最终 occurrence 级 Layer Assignment;
- 固定校验报告和最终中文报告。
固定校验命令:
python3 tools/style-visual-object/validate_cm95_classification.py
提交前必须满足:
RESULT: PASS
WARN 允许存在,但只能表示“人工结果与后续语义建议不同,需要时复核”;不得自动覆盖人工结果。
当前权威结果路径:
tools/style-visual-object/output/cm95-manual-review/manual-review-v1.json
tools/style-visual-object/output/cm95-manual-review/reviewed-anchors-manual-v1.json
tools/style-visual-object/output/cm95-manual-review/assignment/cm95-layer-assignment-v1.json
tools/style-visual-object/output/cm95-manual-review/validation-report-v1.json
当前最终报告:
tools/style-visual-object/output/CM95_Visual_Object_Layer命名报告_v2.md