# CM95 — CM93 → MySQL Importer CM95 当前仓库的已验证基线,是一个将 CM93 数据解析、标准化并保存到 MySQL 5.7 的 importer。 当前基线: ```text commit: 9d56592cadf7e047fb059e5a8746188595a08b43 tag: cm93-mysql-importer-baseline-v1 date: 2026-09-02 ``` 本阶段只覆盖: ```text CM93 source → binary parse → dictionary decode → geometry build / normalization → MySQL 5.7 → audit / traceability ``` 本文 importer 冻结基线本身不因下游 PBF 工作而改变;PBF 已在后续独立阶段单独启动,见本文末尾。 --- ## 1. 当前状态 CM93JAPAN / Dataset ID=1 已完成两套独立全库验收: ```text Geometry Audit: OVERALL: PASS Non-Geometry Audit: OVERALL: PASS ``` 最终基线: | 项目 | 数量 / 结果 | |---|---:| | Cells | 784 | | Features | 322465 | | Attributes | 405153 | | Sounding points | 275700 | | Coverages | 1156 | | Area | 81080 | | Area valid | 81080 / 81080 | | Coverage valid | 1156 / 1156 | | Feature repaired | 55 | | Coverage repaired | 3 | | Feature geometry issues | 0 | | Coverage geometry issues | 0 | | raw_geotype=16 | 4406 | | raw_geotype=16 issues | 0 | | Area bbox mismatch | 0 | | Source files checked | 784 | | Source files missing | 0 | | Source size mismatch | 0 | | Source SHA-256 mismatch | 0 | --- ## 2. 主要能力 Importer 当前处理并保存: - CM93 Cell 扫描; - CM93OBJ / CM93ATTR 字典; - Cell header; - vector / edge; - 2D point; - 3D sounding; - Feature; - Attribute; - Point / Line / Area; - Coverage; - WGS offset; - Sounding point; - Feature bbox; - raw feature / raw attribute; - Cell 原始 table 分块; - source SHA-256; - import job / event; - geometry issue / repaired 状态。 每个 Feature 必须保持: ```text dataset_id cell_id source_record_index ``` 从数据库记录可追溯回原始 CM93 Cell 和 source record。 --- ## 3. 生产代码 核心生产文件: ```text src/cm93db/cm93_binary.py src/cm93db/cell_parser.py src/cm93db/geometry.py src/cm93db/importer.py src/cm93db/audit.py sql/001_schema_mysql57.sql ``` Geometry 和 importer 的当前行为已经通过全量数据验收。后续没有明确任务时,不应重写其主流程。 --- ## 4. 数据库 目标数据库: ```text MySQL 5.7 ``` Schema: ```text sql/001_schema_mysql57.sql ``` Importer 的 normalized SRID 为: ```text EPSG:4326 ``` MySQL geometry 通过 WKB 写入,坐标使用 double precision。 不要假设 MySQL 8 的 Spatial / SRID 行为适用于本项目。 数据库连接配置以项目现有 `.env.example` / 配置模块为准。 --- ## 5. 导入 Windows 项目环境示例: ```powershell cd D:\React\cm93-mysql-importer-starter & ".\.venv\Scripts\cm93db.exe" import D:\Ship\CM93V2\CM93JAPAN ``` 普通导入会根据: ```text chart_cell.import_status source_size source_sha256 ``` 跳过已经成功导入且源文件 SHA-256 未变化的 Cell。 典型输出: ```text SKIP ... (SHA-256 unchanged) ``` 需要强制重新解析并写入所有选中 Cell 时: ```powershell & ".\.venv\Scripts\cm93db.exe" import D:\Ship\CM93V2\CM93JAPAN --reimport ``` `--reimport` 会清理每个 Cell 已有 payload 后重新生成,因此只应在明确需要全量重导时使用。 如果单个 Cell 因临时数据库连接错误等原因处于 `FAILED`,普通 import 默认会重试失败 Cell,同时跳过其余未变化的 DONE Cell。 --- ## 6. Geometry 语义 ### 6.1 坐标 CM93 raw coordinate 按 Cell header 参数转换到 Mercator 坐标,再转换为经纬度。 Coverage 的 `_wgsox / _wgsoy` 用于最终 geometry 的 WGS offset 修正。 最终数据库 geometry 使用 SRID 4326。 ### 6.2 Line Line 必须保留断开的多个 line parts,不得为了得到单条 LineString 而跨 discontinuity 人为连接。 ### 6.3 Area / Coverage 当前冻结规则: #### 已经 OGC-valid ```text PASS-THROUGH ``` 已经 valid 的 Polygon / MultiPolygon 不重新 normalization,不为了统一 ring 顺序而重建。 #### OGC-invalid 只有 invalid Area / Coverage 才执行: ```text boundary noding → polygonize_full → odd-even face selection → union selected faces → GEOS normalize → valid Polygon / MultiPolygon ``` 该规则来自 CM93 实际 topology / fill semantics 的完整审计。 生产规则明确禁止直接使用: ```text make_valid() ST_MakeValid() buffer(0) ``` 来覆盖原始 CM93 Polygon 语义。 Normalization 不允许创造原始 CM93 boundary linework 之外的新边界。 open ring、断裂 contour 等真实结构异常不能静默“修好”;无法安全 normalization 的 Coverage 必须阻止错误 Cell 落库。 ### 6.4 raw_geotype=16 `raw_geotype=16` 是 CM93 正常的 parent/no-geometry 对象。 当前正确语义: ```text geometry_type = META geometry = NULL geometry_issue = NULL geometry_repaired = 0 ``` 它不是 `"geometry missing"` 错误,也不进入 `geometry_invalid_count`。 当前 Dataset ID=1 共验证: ```text 4406 / 4406 ``` 全部为正常 parent/no-geometry。 ### 6.5 bbox Area 发生 normalization 后: ```text feature bbox = final normalized geometry.bounds ``` 不能继续使用 normalization 前可能包含 retraced connector 的 bounds。 --- ## 7. geometry_repaired / geometry_issue `geometry_repaired=1` 表示 importer 对原 OGC-invalid CM93 polygon 执行冻结 normalization,并得到了最终 valid Polygon/MultiPolygon。 `geometry_issue` 只用于: - geometry 真正缺失但该 primitive 应存在 geometry; - geometry empty; - open ring / 结构异常; - normalization 无法安全完成; - 其他真实 geometry 异常。 正常 META parent/no-geometry 不属于 issue。 当前已验证: ```text Feature repaired = 55 Coverage repaired = 3 Feature issues = 0 Coverage issues = 0 ``` Coverage 同时也是 `_m_sor` Feature,所以不要简单把 `55 + 3` 当作 58 个独立 CM93 source Feature。 --- ## 8. Raw source 保留 标准化 geometry 不得破坏原始输入证据。 必须长期保留: ```text chart_feature.raw_feature_blob chart_feature.raw_attribute_blob chart_raw_record source_record_index ``` `chart_raw_record` 使用分块保存原始 Cell table,并在 metadata 中记录: ```text chunk_index chunk_count total_bytes ``` 这保证后续仍可重新核对 parser 与 CM93 原始二进制。 --- ## 9. 长期回归验收 正式长期验收工具: ```text tools/cm93_mysql_final_geometry_audit.py tools/cm93_mysql_non_geometry_final_audit.py ``` ### Geometry 全库验收 ```powershell & ".\.venv\Scripts\python.exe" .\tools\cm93_mysql_final_geometry_audit.py ` --host 127.0.0.1 ` --port 3306 ` --user root ` --database cm93_chart ` --dataset-id 1 ``` 当前 CM93JAPAN 基线应得到: ```text Cells : 784 Features : 322465 Feature repaired : 55 Coverage repaired : 3 Feature issues : 0 Coverage issues : 0 Geotype16 total : 4406 Geotype16 issues : 0 Area total : 81080 Area valid : 81080 Area bbox mismatch : 0 Coverage total : 1156 Coverage valid : 1156 Failure count : 0 OVERALL: PASS ``` ### 非 Geometry 全库验收 ```powershell & ".\.venv\Scripts\python.exe" .\tools\cm93_mysql_non_geometry_final_audit.py ` --host 127.0.0.1 ` --port 3306 ` --user root ` --database cm93_chart ` --dataset-id 1 ` --source-root "D:\Ship\CM93V2\CM93JAPAN" ``` 当前 CM93JAPAN 基线应得到: ```text Cells : 784 Features : 322465 Attributes : 405153 Soundings : 275700 Coverages : 1156 Cell count mismatch : 0 Feature check failures : 0 Dictionary failures : 0 Attribute failures : 0 Coverage failures : 0 Sounding failures : 0 JSON/relation failures : 0 Raw failures : 0 Source files checked : 784 Source files missing : 0 Source size mismatch : 0 Source SHA256 mismatch : 0 Failure count : 0 OVERALL: PASS ``` 任何实质性修改以下部分后,都应重新执行对应验收: - binary parser; - dictionary decode; - geometry build; - Area/Coverage normalization; - WGS offset; - importer DB mapping; - raw preservation; - Feature / Attribute / Sounding / Coverage 关系; - bbox; - schema。 --- ## 10. 历史调查脚本 仓库中保留了本次 importer 调查过程中产生的 V 系列审计脚本。 它们用于记录问题定位过程,不再作为日常回归入口。 日常回归只使用: ```text tools/cm93_mysql_final_geometry_audit.py tools/cm93_mysql_non_geometry_final_audit.py ``` 历史调查脚本不要被新的生产代码 import,也不要把历史审计结果作为运行时依赖。 --- ## 11. Git 冻结基线 当前正式可回退点: ```text commit 9d56592cadf7e047fb059e5a8746188595a08b43 tag cm93-mysql-importer-baseline-v1 ``` 该 tag 表示: ```text CM93 → MySQL importer validated baseline ``` tag 应保持不可变。 后续改动在 `main` 上正常提交;需要对比时,以此 tag 作为 importer normalization 前后已验证基线。 --- ## 12. 当前不做的事情 当前 importer 阶段不包括: - PBF 生成; - PBF schema; - PBF renderer; - PBF API; - 为 PBF 改写 MySQL importer; - 为了下游显示而损失 raw CM93 数据; - 对原始 CM93 文件进行写回。 该限制针对 importer 冻结阶段;后续 PBF 阶段已由用户明确启动,但 PBF 实现不得反向破坏已冻结的 importer / MySQL / raw 数据模型。 --- ## 13. 后续独立 PBF 阶段 CM95 → NavSea 的 PBF 下游阶段已经单独启动;importer 冻结基线继续保持不变。 2026-10-01 新增独立 bathymetry PBF 首批 build: ```text config/bathymetry/cm95_bathymetry_north_kyushu_v1.yaml tools/cm95_bathymetry_build_v1.py web/bathymetry_test.html web/bathymetry_test_server.py docs/CM95_Bathymetry独立PBF_v1.md ``` 该 bathymetry PBF 是第二个独立 vector source,等深线由 SOUNDG 测深点派生,标记为 `reliability=reference_low`,不与基础 PBF 合并。