10 KiB
NavSea 渲染语义重构报告
1 目标
本报告提出一套更清晰的 NavSea PBF 交付渲染描述体系。
这次重构的目标,不是立刻移除旧的海图渲染体系,而是把下面三件事情拆开:
- 对象本身的语义
- 海图渲染意图
- 最终样式实现
这样 NavSea 才能同时支持:
- 兼容旧海图风格的渲染
- 更清晰、可维护的样式逻辑
- 碰撞检测、检索与语义分析
- 逐步摆脱对原始旧海图编码的强依赖
2 当前问题
当前渲染栈把多种职责混在了一起。
2.1 当前渲染依赖的输入
旧版渲染主要依赖这些字段:
分類番号形状分類番号表示用番号灯色灯略記明弧/分孤表示位置名称- 展开的
at属性
这些字段当然有用,但它们的问题也很明显:它们直接承载的是“海图怎么画”的细节编码,而不是清晰、稳定的渲染语义,因此维护成本高、理解成本高、迁移成本也高。
2.2 当前已经叠加的新语义
新 pbf 已经增加了这些语义字段:
canonical_object_typecanonical_familysemantic_keydetection_keyrender_layer
这些字段已经能很好地服务于检测和分类,但还不足以完整替代海图渲染所需的细粒度表达。
2.3 当前的核心缺口
现在的数据层同时存在两套东西:
- 面向海图绘制细节的旧编码
- 面向系统理解的语义分类
但缺少一层专门回答“应该怎么画”的渲染语义层。也就是目前还没有一套稳定字段,明确回答这些问题:
- 该使用哪一类符号族
- 该按点、线、面还是文字渲染
- 该显示什么文本
- 渲染优先级是什么
- 应该选用哪一种线型、面型或符号变体
3 建议的三层模型
NavSea 的渲染体系建议拆成三层。
3.1 A 层:对象语义层
这一层回答“这是什么对象”。
代表字段:
canonical_object_typecanonical_familydetection_key
示例:
暗岩魚礁港湾灯台港則法による境界
3.2 B 层:渲染语义层
这一层回答“这个对象在海图上应该怎么画”。
这是本报告建议新增的核心层。
代表字段:
chart_render_typechart_symbol_familychart_symbol_codechart_line_stylechart_fill_stylechart_label_textchart_label_subtextchart_label_anchorchart_priority
3.3 C 层:样式层
MapLibre 样式层尽量只消费“渲染语义层”以及少量保留的原始字段。
这样可以让样式规则明显缩短,也更容易维护和演进。
4 建议新增的渲染字段
建议在新的交付 pbf 中补充如下字段。
4.1 核心渲染字段
| 字段 | 类型 | 用途 |
|---|---|---|
chart_render_type |
string | 主渲染类型:symbol、line、fill、label、none |
chart_symbol_family |
string | 符号族,例如 navigation_light、buoy、beacon、hazard、facility、depth_mark |
chart_symbol_code |
string | 稳定的符号编码,例如 lighthouse、rock_awash、anchorage_mark |
chart_line_style |
string | 稳定的线型预设,例如 boundary_dashed、contour_minor、subsea_cable |
chart_fill_style |
string | 稳定的填充预设,例如 depth_zone_0_5、fishery_area、hazard_area |
chart_priority |
integer | 绘制优先级,用于排序和碰撞决策 |
chart_visibility_min |
integer | 最小显示缩放级别 |
chart_visibility_max |
integer | 最大显示缩放级别 |
4.2 标注字段
| 字段 | 类型 | 用途 |
|---|---|---|
chart_label_text |
string | 主标注文本 |
chart_label_subtext |
string | 次级标注,例如辅助说明或灯略记 |
chart_label_anchor |
string | 标准化锚点,例如 top、bottom、left、right、center |
chart_label_dx |
number | 文本 X 方向偏移 |
chart_label_dy |
number | 文本 Y 方向偏移 |
chart_text_style |
string | 文字样式预设,例如 place_name、light_name、depth_text |
4.3 灯标专项字段
| 字段 | 类型 | 用途 |
|---|---|---|
light_color_code |
string | 归一化后的灯色,例如 white、red、green、yellow、mixed |
light_character_code |
string | 归一化后的灯质,例如 Fl、Oc、Iso、F、V-AIS |
light_arc_code |
string | 可选的灯弧编码,用于需要时表达分区差异 |
light_sector_mode |
string | sector、omni、none |
4.4 危险物 / 区域专项字段
| 字段 | 类型 | 用途 |
|---|---|---|
hazard_class |
string | rock、wreck、obstruction、reef、shoal、current 等 |
hazard_severity |
string | critical、major、minor、context |
area_usage_class |
string | anchorage、route、fishery、restricted、facility、land、water |
5 建议的映射策略
新的渲染语义层,应该同时从以下两类输入推导得到:
- 新的语义分类字段
- 为保留海图细节而保留的部分旧字段
5.1 映射原则
对象身份和大类语义,优先使用新的 taxonomy 字段。
只有在确实需要保留海图细节表现时,才继续引用旧字段。
5.2 映射示例
灯标 / 航标
输入字段:
canonical_object_type形状分類番号表示用番号灯色灯略記名称
输出字段:
chart_render_type = symbolchart_symbol_family = navigation_lightchart_symbol_code = lighthouse | light_beacon | buoy | beacon | vaislight_color_code = ...light_character_code = ...chart_label_text = 名称chart_label_subtext = 灯略記
危险点状对象
输入字段:
canonical_object_type分類番号
输出字段:
chart_render_type = symbolchart_symbol_family = hazardchart_symbol_code = rock_awash | isolated_danger | wreck | reef | obstructionhazard_class = rock | reef | wreck | obstructionhazard_severity = critical | major | minor
危险面 / 鱼礁区 / 礁盘区
输入字段:
canonical_object_type分類番号- geometry type
输出字段:
chart_render_type = fillchart_fill_style = hazard_area | reef_area | obstruction_areahazard_class = reef | obstruction | hazard_zone
水深分带
输入字段:
canonical_object_type
输出字段:
chart_render_type = fillchart_fill_style = depth_zone_0_2 | depth_zone_0_5 | depth_zone_5_10 ...area_usage_class = water
边界类对象
输入字段:
canonical_object_type
输出字段:
chart_render_type = linechart_line_style = regulatory_boundary | route_boundary | hazard_boundary
6 建议继续保留的原始字段
即使完成重构,也不建议立刻把所有旧字段从交付 pbf 里删除。
6.1 为渲染保留
分類番号形状分類番号表示用番号灯色灯略記明弧/分孤表示位置名称名称補助日本語地名英文字地名
6.2 为关联 / 检索保留
fidcanonical_object_typecanonical_familydetection_key
6.3 后续可评估移除
这些字段建议在新的渲染语义层稳定之后,再评估是否移除:
semantic_key- 大块原始
at负载,前提是所需信息都已经物化为显式字段 - 不再被样式、检索或检测引用的旧字段
7 样式架构建议
7.1 当前样式模式
当前样式主要是直接对旧编码做分支判断。
例如:
- 如果
分類番号 = 403,就使用某一个图标 - 如果
表示用番号 = 31135504,就切换到另一个图标
这种方式精确,但维护难度很高。
7.2 建议中的新样式模式
未来样式应优先基于“渲染语义字段”分支。
例如:
- 如果
chart_symbol_family = navigation_light,就进入灯标符号体系 - 如果
chart_fill_style = depth_zone_0_5,就使用浅水区填充 - 如果
chart_line_style = regulatory_boundary,就使用监管边界线型
只有少量特殊情形,才继续回退到旧字段。
7.3 预期结果
这样做会带来以下收益:
- 样式文件更短
- 规则归属更清晰
- 后续迁移更容易
- 多产品之间更容易保持一致
8 迁移计划
阶段 1:混合交付
保留:
- 旧渲染关键字段
- 新的语义 taxonomy 字段
新增:
- 新的渲染语义字段
使用方式:
- 旧样式继续承担兼容渲染
- 混合样式用于逐步迁移
阶段 2:迁移到语义样式
构建一套新的样式,优先读取:
chart_render_typechart_symbol_familychart_symbol_codechart_fill_stylechart_line_stylechart_label_text
旧字段只在少量细节场景下兜底。
阶段 3:稳定渲染字段体系
当渲染语义层经过验证后:
- 逐步减少样式对原始旧编码的直接依赖
- 只保留少量用于回退和兼容的旧字段
9 示例输出 Feature 模型
灯台示例:
{
"fid": 12345678,
"canonical_object_type": "港湾灯台",
"canonical_family": "navigation_aid",
"detection_key": "symbol:港湾灯台",
"chart_render_type": "symbol",
"chart_symbol_family": "navigation_light",
"chart_symbol_code": "lighthouse",
"chart_priority": 900,
"chart_visibility_min": 7,
"chart_label_text": "鷹島灯台",
"chart_label_subtext": "Fl W 5s",
"light_color_code": "white",
"light_character_code": "Fl"
}
鱼礁危险区示例:
{
"fid": 23456789,
"canonical_object_type": "魚礁",
"canonical_family": "hazard",
"detection_key": "mixed:魚礁",
"chart_render_type": "fill",
"chart_symbol_family": "hazard",
"chart_fill_style": "reef_area",
"hazard_class": "reef",
"hazard_severity": "major",
"chart_priority": 850
}
10 建议的下一步
建议按下面的顺序推进实现:
- 在出瓦片流程中定义新的渲染语义字段
- 将这些字段物化到交付
pbf - 在过渡期继续保留旧的渲染关键字段
- 构建一套优先读取新渲染语义字段的混合样式
- 优先验证灯标体系、危险物体系、鱼业/鱼礁对象和边界对象,再推进更大范围清理
11 结论
渲染描述体系完全可以重构,而且值得重构。
正确的方向,不是立刻抛弃旧海图字段,而是在“原始海图属性”和“最终样式”之间,增加一层专门的“渲染语义层”。
这层语义应当提供稳定、明确、可维护的海图渲染含义,同时在必要时保留与旧海图表达方式的兼容能力。