feat: finalize Kyushu S-52 production release

This commit is contained in:
OpenAI Codex
2026-09-19 15:09:11 +08:00
parent 9dd6282817
commit 472acd6938
4 changed files with 498 additions and 15 deletions

View File

@@ -0,0 +1,171 @@
# CM95 S-52 Production Pipeline v2 与九州运行报告 v3
日期:2026-09-19
## 1. 本阶段结论
本阶段已完成九州工程 AOI 的 S-52 资源契约补全、MySQL 8 空间查询修复、全量 PBF 重新生产、Release finalize、release-scoped S-52 style 编译和 Web 对比页切换。
最终 Release 状态为 **PASS**。本次 PASS 表示 Production Pipeline、AOI footprint、S-52 resource/runtime contract、PBF/report/decoded feature 对账和当前 release gate 均通过;不表示所有 ENC 语义待审项目已经清零。
## 2. 权威输入与版本
- OpenCPN S-52 参考 commit:`f7211b4e1874c453e37a7f190aa191c55a25c32e`
- Builder contract:`cm95pbf-builder/0.4.10-s52-resource-contract`
- Production pipeline:`cm95pbf-production/2.2-s52-resource-contract`
- Lookup IR SHA-256:`f63cbc0d3c9317b1873c0b0c470a5e7371d1b6d8d58393da660f70b837a52eb7`
- Resource contract SHA-256:`ebdce70cf8f67dff3ecdeecc8e8f161d9626153a860c69972d41612ed803ef1e`
## 3. S-52 资源契约
按当前 OpenCPN 定义统计,完整资源宇宙为:
- SY:1018
- AP:30
- LC:59
- Defined total:1107
- Active reachable:SY 902 / AP 27 / LC 48 / total 977
`build/s52_resources_v2/resource_contract.json` 最终为 **PASS**,defined missing=0,active missing=0。
资源编译同时处理了 OpenCPN 重名 symbol 的 bitmap/vector 选择、真正 vector-only symbol、全部 vector AP、全部 LC,以及 OpenCPN 自身未定义资源引用的官方 fallback 语义;未人为伪造上游不存在的资源。
## 4. AOI 与生产计划
工程 AOI:`kyushu-main-nearby-v1`
bbox:`128.0,29.5,132.5,34.8`
Zoom 5–12 的完整计划数:
- z5=2,z6=4,z7=12,z8=24
- z9=70,z10=247,z11=962,z12=3744
- total=5065
Plan ID:`2b2e7d976a43df64da3d031c3863ab596469c7331fc990a4025238e6b9b0d0c9`
Release ID:`cm95-d1-62a85bd40d3a-2b2e7d976a43`
旧 incomplete release `cm95-d1-62a85bd40d3a-7cb5890160d2` 已在本次生产前整目录删除。新 release 从零建立,不做 migrate / hardlink / copy,也不复用旧 PBF。历史已 finalize 的 sparse release `cm95-d1-62a85bd40d3a-bbaaeafee1b4` 仅作为历史参考保留。
## 5. MySQL 8 空间索引问题与修复
实际生产数据库位于 NAS `192.168.200.230` 的 MySQL 8.0.45 Docker 实例,数据库为 `cm95_japan`;X220 本地 MySQL 不是本次生产数据源。
原 geometry 列虽然数据实际为 SRID 4326,但列定义没有声明固定 SRID。MySQL 8 因此不把现有 SPATIAL index 作为查询候选,即使 SQL 使用 `FORCE INDEX(spx_*)`,执行计划仍为 `type=ALL / possible_keys=None`,每个 tile 会反复扫描几十万 geometry。
隔离实验确认:将列声明改为 `... NOT NULL SRID 4326` 后,执行计划变为 `type=range` 并实际使用 `spx_*`。
已修复:
- `chart_area_geometry` + `spx_area_geom`
- `chart_line_geometry` + `spx_line_geom`
- `chart_point_geometry` + `spx_point_geom`
- `chart_sounding_point` + `spx_sounding_geom`
代表性查询修复后实测:AREA 约 0.31s、LINE 热缓存约 0.09s、POINT 约 0.02s、SOUNDING 约 0.03–0.07s。生产恢复后吞吐显著提升。
仓库仍保留 MySQL 5.7 历史兼容 schema,本次没有把 `sql/001_schema_mysql57.sql` 强行改成 MySQL 8 专用列语法。后续若新建 MySQL 8 production 数据库,必须在投入 PBF 生产前同样确认四张空间表的列级 `SRID 4326` 与 `spx_*` 实际可用,避免回退到全表扫描。
## 6. 九州 Production 最终结果
生产任务最终为:
- PASS:5065 / 5065
- FAILED:0
- Report:5065
- 实体 PBF:5064
- 合法显式空 tile:1
- planned output features:476121
- report output features:476121
- decoded PBF features:476121
唯一没有实体 PBF 的 tile 是 `12/3530/1648`。其 report 明确记录 `planned_output_feature_count=0`、`output_feature_count=0`,且无 hard gate、无 encoder drop,因此属于合法空瓦片,不应伪造空 PBF。
Release gate 已调整为:AOI complete 要求每个计划 tile 都有 PASS report;非空 tile 必须有 PBF;经过明确验证的空 tile 可以不产生实体 PBF。
最终 `tile_footprint_contract.status=PASS`,`materialized_or_empty_tile_count=5065`,missing non-empty PBF=[],unexpected PBF=[]。
## 7. S-52 Runtime Contract
本 release 使用:
- point table:Paper
- boundary table:Plain
- mariner mode:runtime
Final manifest:
- `s52_resource_contract.status=PASS`
- `s52_runtime_contract.status=PASS`
- mariner-dependent features:286975
- dynamic final leaks:`{}`
- runtime failure count:0
Runtime CSP 数量:
- DEPARE01:47516
- DEPCNT02:46189
- OBSTRN04:45633
- SOUNDG02:146728
- WRECKS02:909
因此 PBF 保存水深、危险物、sounding 等事实字段,而不会永久写死当前用户的 safety contour / safety depth / isolated danger 等动态最终结果。
## 8. Release-scoped S-52 Style
对新 release 的 5064 个实体 PBF 做 aggregate usage 编译后生成:
`build/s52_style_compiler_release_2b2e7d976a43/style.s52.json`
结果:
- compiled layers:142
- 使用范围:5064 PBF / 28 source layers / 476121 features
- resource contract:PASS
- hard gate failures:[]
关键 FSHFAC、FSHHAV、SOUNDG 和 LOWACC/fallback 资源均可在生成 style 中找到。
完整 sprite 使用 `build/s52_resources_v2/final/s52-sprite-full`,并补齐浏览器需要的 1x / 2x sprite JSON/PNG。
## 9. Web 对比与实际 WebGL 验证
比较服务已切换到新 Release,端口 `18888`。
`/health` 当前返回新 release、release status PASS、PBF=5064、decoded features=476121、S-52 runtime contract PASS。
浏览器实际加载验证已完成,而不是只检查 DOM:
- release-scoped style:HTTP 200
- sprite 1x/2x JSON/PNG:HTTP 200
- 普通 PBF:HTTP 200
- 合法空 tile:HTTP 204
- 左右 MapLibre style 状态均为 OK
- 左侧实际 `querySourceFeatures` / `queryRenderedFeatures` 有数据
- 静态 LANDA fill 在截图中实际出现;其 0.92 opacity 混合色 `#CABD83` 有大量像素
为验证 runtime PBF,本地比较页增加了可关闭的 runtime 默认阈值预览。默认值来自现有 `S52MarinerSettings`:shallow=2m、safety contour=3m、safety depth=3m、deep=6m。
z11 近岸样本实测:
- effective safety contour:5m
- runtime DEPARE rendered:24
- runtime DEPCNT rendered:35
- runtime SOUNDG rendered:61
- source SOUNDG facts:202
实际截图已生成并检查。runtime preview 只读取 PBF facts,不修改 PBF;Hazard exact isolated-danger / symbol composition 仍明确留给正式 NavSea Runtime Adapter,不在 Web 调试页中伪造。
## 10. 仍然保留的语义待审项
Final manifest 的 `semantic_completeness` 仍为 **PENDING_REVIEW**:
- observed gap variants:141
- pending semantic review:112
- pending semantic review feature rows:52828
这部分是既有语义映射 backlog,与本次资源契约、PBF 技术生产和 runtime contract PASS 是不同维度。
因此本阶段可以确认“技术生产链与 S-52 资源/runtime 契约闭环”,但不能描述为“全部 ENC/S-52 业务语义已经 100% 完成”。
## 11. 最终结论
九州完整 AOI 的新 S-52 runtime Release 已完成从零生产并 finalize PASS。MySQL 8 空间查询根因已确认并在当前 NAS 数据库修复,生产查询已真正使用 SPATIAL index。
新 Release、完整 S-52 资源、release-scoped style、Web 对比服务和 runtime facts 预览已连通。后续工作可以基于该 Release 继续做语义 backlog 审查和正式 NavSea Runtime Adapter,而不需要重新设计本次 Production/Resource Contract 基线。