# NavSea 渲染语义重构报告

## 1 目标

本报告提出一套更清晰的 NavSea PBF 交付渲染描述体系。

这次重构的目标，不是立刻移除旧的海图渲染体系，而是把下面三件事情拆开：

- 对象本身的语义
- 海图渲染意图
- 最终样式实现

这样 NavSea 才能同时支持：

- 兼容旧海图风格的渲染
- 更清晰、可维护的样式逻辑
- 碰撞检测、检索与语义分析
- 逐步摆脱对原始旧海图编码的强依赖

## 2 当前问题

当前渲染栈把多种职责混在了一起。

### 2.1 当前渲染依赖的输入

旧版渲染主要依赖这些字段：

- `分類番号`
- `形状分類番号`
- `表示用番号`
- `灯色`
- `灯略記`
- `明弧/分孤`
- `表示位置`
- `名称`
- 展开的 `at` 属性

这些字段当然有用，但它们的问题也很明显：它们直接承载的是“海图怎么画”的细节编码，而不是清晰、稳定的渲染语义，因此维护成本高、理解成本高、迁移成本也高。

### 2.2 当前已经叠加的新语义

新 `pbf` 已经增加了这些语义字段：

- `canonical_object_type`
- `canonical_family`
- `semantic_key`
- `detection_key`
- `render_layer`

这些字段已经能很好地服务于检测和分类，但还不足以完整替代海图渲染所需的细粒度表达。

### 2.3 当前的核心缺口

现在的数据层同时存在两套东西：

- 面向海图绘制细节的旧编码
- 面向系统理解的语义分类

但缺少一层专门回答“应该怎么画”的渲染语义层。也就是目前还没有一套稳定字段，明确回答这些问题：

- 该使用哪一类符号族
- 该按点、线、面还是文字渲染
- 该显示什么文本
- 渲染优先级是什么
- 应该选用哪一种线型、面型或符号变体

## 3 建议的三层模型

NavSea 的渲染体系建议拆成三层。

### 3.1 A 层：对象语义层

这一层回答“这是什么对象”。

代表字段：

- `canonical_object_type`
- `canonical_family`
- `detection_key`

示例：

- `暗岩`
- `魚礁`
- `港湾灯台`
- `港則法による境界`

### 3.2 B 层：渲染语义层

这一层回答“这个对象在海图上应该怎么画”。

这是本报告建议新增的核心层。

代表字段：

- `chart_render_type`
- `chart_symbol_family`
- `chart_symbol_code`
- `chart_line_style`
- `chart_fill_style`
- `chart_label_text`
- `chart_label_subtext`
- `chart_label_anchor`
- `chart_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 = symbol`
- `chart_symbol_family = navigation_light`
- `chart_symbol_code = lighthouse | light_beacon | buoy | beacon | vais`
- `light_color_code = ...`
- `light_character_code = ...`
- `chart_label_text = 名称`
- `chart_label_subtext = 灯略記`

#### 危险点状对象

输入字段：

- `canonical_object_type`
- `分類番号`

输出字段：

- `chart_render_type = symbol`
- `chart_symbol_family = hazard`
- `chart_symbol_code = rock_awash | isolated_danger | wreck | reef | obstruction`
- `hazard_class = rock | reef | wreck | obstruction`
- `hazard_severity = critical | major | minor`

#### 危险面 / 鱼礁区 / 礁盘区

输入字段：

- `canonical_object_type`
- `分類番号`
- geometry type

输出字段：

- `chart_render_type = fill`
- `chart_fill_style = hazard_area | reef_area | obstruction_area`
- `hazard_class = reef | obstruction | hazard_zone`

#### 水深分带

输入字段：

- `canonical_object_type`

输出字段：

- `chart_render_type = fill`
- `chart_fill_style = depth_zone_0_2 | depth_zone_0_5 | depth_zone_5_10 ...`
- `area_usage_class = water`

#### 边界类对象

输入字段：

- `canonical_object_type`

输出字段：

- `chart_render_type = line`
- `chart_line_style = regulatory_boundary | route_boundary | hazard_boundary`

## 6 建议继续保留的原始字段

即使完成重构，也不建议立刻把所有旧字段从交付 `pbf` 里删除。

### 6.1 为渲染保留

- `分類番号`
- `形状分類番号`
- `表示用番号`
- `灯色`
- `灯略記`
- `明弧/分孤`
- `表示位置`
- `名称`
- `名称補助`
- `日本語地名`
- `英文字地名`

### 6.2 为关联 / 检索保留

- `fid`
- `canonical_object_type`
- `canonical_family`
- `detection_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_type`
- `chart_symbol_family`
- `chart_symbol_code`
- `chart_fill_style`
- `chart_line_style`
- `chart_label_text`

旧字段只在少量细节场景下兜底。

### 阶段 3：稳定渲染字段体系

当渲染语义层经过验证后：

- 逐步减少样式对原始旧编码的直接依赖
- 只保留少量用于回退和兼容的旧字段

## 9 示例输出 Feature 模型

灯台示例：

```json
{
  "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"
}
```

鱼礁危险区示例：

```json
{
  "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 建议的下一步

建议按下面的顺序推进实现：

1. 在出瓦片流程中定义新的渲染语义字段
2. 将这些字段物化到交付 `pbf`
3. 在过渡期继续保留旧的渲染关键字段
4. 构建一套优先读取新渲染语义字段的混合样式
5. 优先验证灯标体系、危险物体系、鱼业/鱼礁对象和边界对象，再推进更大范围清理

## 11 结论

渲染描述体系完全可以重构，而且值得重构。

正确的方向，不是立刻抛弃旧海图字段，而是在“原始海图属性”和“最终样式”之间，增加一层专门的“渲染语义层”。

这层语义应当提供稳定、明确、可维护的海图渲染含义，同时在必要时保留与旧海图表达方式的兼容能力。
