12 KiB
NavSea 可追溯映射体系设计 v1
版本:v1 Draft
用途:定义 NavSea “旧版原始数据 -> 新版语义字段 / 渲染字段”的可追溯映射体系,确保后续可以稳定定位分类错误、渲染错误和规则变更影响。
1 目标
这套设计解决的不是“如何分类”本身,而是“分类和渲染映射的过程如何可追溯”。
必须满足:
- 能知道某个 feature 命中了哪条 taxonomy 规则
- 能知道某个 feature 命中了哪条 render 规则
- 能知道规则来自哪个版本
- 能知道规则判断时参考了哪些原始字段
- 能从最终
pbf或fid回查到完整映射过程
一句话概括:
最终结果不是终点,规则命中过程也必须被记录成正式资产。
2 为什么必须做可追溯
如果只保留结果字段,例如:
canonical_familycanonical_object_typedetection_keychart_render_type
那后续虽然能看到“结果是什么”,但看不到:
- 为什么会分成这个结果
- 是哪条规则起了作用
- 如果结果错了,到底该改 taxonomy 还是改 render mapping
- 某次规则调整影响了哪些 feature
而 NavSea 后续一定会反复遇到这些问题:
- 某个对象分错类
- 某类对象在新样式里显示错误
- 某次规则升级导致历史区域表现变化
- 检索命中和渲染表现不一致
这时如果没有 trace,就只能人工猜。
3 设计原则
3.1 文件是规则源头
规则的 source of truth 必须是版本可控文件,而不是代码里的隐式判断,也不是数据库里唯一的一份规则。
建议:
- taxonomy 规则放 YAML/CSV 文件
- render mapping 规则放 YAML/CSV 文件
- 文档文件负责解释,不作为程序执行源
3.2 SQL 是运行时载体
数据库负责:
- 导入规则
- 物化计算结果
- 记录 feature 命中过程
- 支撑查询和审计
但数据库不是唯一规则源头。
3.3 结果和过程都要存
至少要同时存两类数据:
- 规则定义
- feature 命中结果
只存最终结果表不够。
3.4 规则必须有稳定 ID
每条规则必须有稳定 rule_id,不能只靠“第几条规则”或描述文本识别。
3.5 规则必须有版本
每次可影响结果的变更都要有版本号或 bundle 版本。
建议使用:
bundle_versionrule_revision
4 总体架构
建议分成 4 层。
4.1 规则源文件层
建议目录:
tasks/pbf/mappings/navsea_taxonomy_rules_v1.yamltasks/pbf/mappings/navsea_render_rules_v1.yamltasks/pbf/mappings/navsea_rule_bundle_v1.yaml
职责:
- 人可读
- 可进入 git
- 可 code review
- 可回滚
4.2 规则表层
建议导入 MySQL 生成:
navsea_rule_bundlenavsea_taxonomy_rulesnavsea_render_rules
职责:
- 运行时查询
- 规则生效控制
- 按版本执行构建
4.3 结果表层
建议生成:
navsea_feature_taxonomy_resultnavsea_feature_render_resultnavsea_feature_rule_tracenavsea_mapping_run
职责:
- 记录某次构建的命中结果
- 记录 feature 与 rule 的关系
- 记录本次运行使用的规则版本
4.4 交付层
交付层包括:
- delivery pbf
- engineering pbf
其中:
- delivery pbf 只保留必要结果字段
- engineering pbf 或内部查询表保留 trace 回查能力
5 推荐文件结构
建议新增目录:
tasks/pbf/mappings/
navsea_rule_bundle_v1.yaml
navsea_taxonomy_rules_v1.yaml
navsea_render_rules_v1.yaml
建议新增导入脚本:
scripts/pbf/
import_navsea_rules.py
run_navsea_mapping.py
export_navsea_trace_report.py
6 规则文件设计
6.1 bundle 文件
bundle 文件用于声明:
- 当前规则集版本
- taxonomy 规则文件版本
- render 规则文件版本
- 适用范围
- 是否为当前默认版本
示例字段:
bundle_idbundle_versionstatuseffective_datetaxonomy_rulesetrender_rulesetnotes
6.2 taxonomy 规则文件
每条 taxonomy 规则至少包含:
rule_idrule_revisionpriorityenabledmatch_scopematch_exproutput.canonical_familyoutput.canonical_object_typeoutput.detection_key_templatereason
其中:
rule_id是稳定主键,例如TAX-NAV-001rule_revision是规则修订号,例如3priority用于冲突时排序match_expr描述匹配条件reason解释为什么有这条规则
6.3 render 规则文件
每条 render 规则至少包含:
rule_idrule_revisionpriorityenabledmatch_exproutput.chart_render_typeoutput.chart_symbol_familyoutput.chart_symbol_codeoutput.chart_line_styleoutput.chart_fill_styleoutput.chart_text_styleoutput.chart_priorityreason
render 规则的输入通常包括:
canonical_object_typecanonical_family- geometry type
- 必要旧字段
7 match_expr 建议
不建议把匹配逻辑写成自由文本。
建议使用结构化表达,例如:
match_expr:
all:
- field: source_layer
op: in
value: [p航路標識群, P航行危険障害物]
- field: class_name
op: contains_any
value: [港湾灯台, 灯柱, 灯浮標]
- field: geom_type
op: eq
value: Point
支持的运算建议限制在少数几类:
eqneqincontainscontains_anyis_nullnot_nullregex
这样规则可审计、可导入、可执行。
8 SQL 表设计
8.1 navsea_rule_bundle
建议字段:
| 字段 | 类型 | 说明 |
|---|---|---|
bundle_id |
varchar(64) PK | 规则集 ID |
bundle_version |
varchar(32) | 规则集版本 |
status |
varchar(20) | draft / active / retired |
taxonomy_ruleset |
varchar(64) | taxonomy 文件版本 |
render_ruleset |
varchar(64) | render 文件版本 |
effective_date |
datetime | 生效时间 |
created_at |
datetime | 创建时间 |
notes |
text | 备注 |
8.2 navsea_taxonomy_rules
建议字段:
| 字段 | 类型 | 说明 |
|---|---|---|
rule_id |
varchar(64) PK | 稳定规则 ID |
bundle_id |
varchar(64) | 所属 bundle |
rule_revision |
int | 修订号 |
priority |
int | 优先级,值越小越先匹配 |
enabled |
tinyint | 是否启用 |
match_scope |
varchar(32) | feature / layer / object |
match_expr_json |
json | 结构化匹配表达式 |
canonical_family |
varchar(100) | 输出 family |
canonical_object_type |
varchar(191) | 输出 object type |
detection_key_template |
varchar(191) | 输出 detection 模板 |
rule_reason |
text | 规则说明 |
created_at |
datetime | 创建时间 |
updated_at |
datetime | 更新时间 |
8.3 navsea_render_rules
建议字段:
| 字段 | 类型 | 说明 |
|---|---|---|
rule_id |
varchar(64) PK | 稳定规则 ID |
bundle_id |
varchar(64) | 所属 bundle |
rule_revision |
int | 修订号 |
priority |
int | 优先级 |
enabled |
tinyint | 是否启用 |
match_expr_json |
json | 匹配表达式 |
chart_render_type |
varchar(32) | 输出 |
chart_symbol_family |
varchar(64) | 输出 |
chart_symbol_code |
varchar(64) | 输出 |
chart_line_style |
varchar(64) | 输出 |
chart_fill_style |
varchar(64) | 输出 |
chart_text_style |
varchar(64) | 输出 |
chart_priority |
int | 输出 |
chart_visibility_min |
int | 输出 |
chart_visibility_max |
int | 输出 |
rule_reason |
text | 规则说明 |
created_at |
datetime | 创建时间 |
updated_at |
datetime | 更新时间 |
8.4 navsea_mapping_run
记录一次完整构建执行。
建议字段:
| 字段 | 类型 | 说明 |
|---|---|---|
run_id |
bigint PK | 执行 ID |
bundle_id |
varchar(64) | 本次使用的规则集 |
run_type |
varchar(32) | full / aoi / qa |
tile_scope |
text | 范围说明 |
started_at |
datetime | 开始时间 |
finished_at |
datetime | 结束时间 |
status |
varchar(20) | running / success / failed |
source_snapshot |
varchar(128) | 源数据快照标识 |
notes |
text | 备注 |
8.5 navsea_feature_rule_trace
这是最关键的 trace 表。
建议字段:
| 字段 | 类型 | 说明 |
|---|---|---|
run_id |
bigint | 所属执行 |
feature_id |
bigint | 内部 feature 主键 |
fid |
varchar(191) | 原始对象标识 |
z |
int | tile z |
x |
int | tile x |
y |
int | tile y |
source_layer |
varchar(100) | 原始 layer |
geom_type |
varchar(32) | 几何类型 |
taxonomy_rule_id |
varchar(64) | 命中的 taxonomy 规则 |
taxonomy_rule_revision |
int | taxonomy 修订号 |
render_rule_id |
varchar(64) | 命中的 render 规则 |
render_rule_revision |
int | render 修订号 |
bundle_id |
varchar(64) | 规则集版本 |
classification_basis |
varchar(64) | 使用的主要依据 |
source_fields_used_json |
json | 实际参与判定的字段和值摘要 |
canonical_family |
varchar(100) | 产出结果 |
canonical_object_type |
varchar(191) | 产出结果 |
detection_key |
varchar(191) | 产出结果 |
chart_render_type |
varchar(32) | 产出结果 |
chart_symbol_family |
varchar(64) | 产出结果 |
chart_symbol_code |
varchar(64) | 产出结果 |
chart_line_style |
varchar(64) | 产出结果 |
chart_fill_style |
varchar(64) | 产出结果 |
chart_text_style |
varchar(64) | 产出结果 |
trace_status |
varchar(20) | matched / fallback / manual_review |
created_at |
datetime | 记录时间 |
说明:
source_fields_used_json不要求保存整份原始属性- 但必须记录本次命中实际使用的关键字段和值摘要
例如:
{
"fid": "123456",
"分類番号": "403",
"表示用番号": "31135504",
"名称": "鷹島灯台",
"geom_type": "Point"
}
9 交付与追溯分离策略
为了兼顾交付体积和可追溯性,建议分两条线:
9.1 delivery pbf
保留:
- 业务必需字段
- taxonomy 结果字段
- render 结果字段
- 必要旧字段
不强制保留:
- 完整 trace 细节
9.2 engineering trace
通过以下方式保留完整追溯能力:
- SQL trace 表
- engineering pbf
- 按
fid/feature_id回查脚本
建议 engineering pbf 可额外保留:
taxonomy_rule_idrender_rule_idbundle_idtrace_status
10 builder 接入方式
当前 navsea_tile_builder.py 是从 pbf_relayer_candidates 读取结果并写入 pbf。
建议改造成两段式:
阶段 A:规则求值阶段
输入:
- 原始 feature
- 规则表
输出:
navsea_feature_taxonomy_resultnavsea_feature_render_resultnavsea_feature_rule_trace
阶段 B:PBF 输出阶段
输入:
- 已物化结果表
输出:
- delivery pbf
- engineering pbf
这样做的好处是:
- “规则判断”与“PBF 编码”解耦
- 同一份判定结果可重复出图
- QA 和回归检查更容易做
11 问题排查路径
未来排查一个对象时,建议统一走这条链路:
- 先从前端或瓦片里拿到
fid - 用
fid或feature_id查navsea_feature_rule_trace - 看命中的
taxonomy_rule_id和render_rule_id - 回到规则表查看该规则定义
- 必要时回到规则源文件查看变更历史
- 确认问题属于:
- 原始数据异常
- taxonomy 规则错误
- render 规则错误
- 样式解释错误
12 变更管理
建议所有规则变更都遵循:
- 改规则文件
- 提交 git
- 生成新
bundle_version - 导入 SQL
- 执行局部或全量重算
- 输出差异报告
不建议:
- 直接手改结果表
- 直接在 SQL 里无版本地改规则
- 直接在代码里插入一条临时 if 判断后不回写规则文件
13 最小可落地版本
如果要尽快开始,建议第一阶段先做到:
- 新增规则源文件目录
- 给 taxonomy 和 render 规则都定义
rule_id - 新增
navsea_rule_bundle - 新增
navsea_feature_rule_trace - builder 在出 engineering 数据时至少写出:
bundle_idtaxonomy_rule_idrender_rule_idtrace_status
这样即使规则体系还不完整,也已经具备“能追”的能力。
14 结论
NavSea 的“旧版 -> 新版”对应关系,不应只是一套结果字段,也不应只存在于代码里。
它应该被正式建设成一套可追溯资产,包括:
- 可版本化的规则文件
- 可运行的 SQL 规则表
- 可查询的 feature trace 表
- 与 delivery / engineering pbf 配套的回查能力
后续查错、验收、回归、争议复盘,都会依赖这套体系。