# CM93 解析与审计设计 v1 ## 1. 原始格式解析 独立 Python 实现依据已公开的 OpenCPN CM93 行为进行互操作核对,但不复制 OpenCPN 的类结构或 GUI/S52 代码。 核心数据顺序: 1. 10-byte prolog 2. 128-byte header 3. vector records 4. 3D point descriptors 5. 2D points 6. feature records 完整性条件: `word0 + table1_length + table2_length == file_size` 且 `word0 == 138`。 进一步核对: - vector point 总数 = header `n_vector_record_points` - 3D point 总数 = header `m_50` - feature 总数 = header `usn_feature_records` - attribute payload bytes = header `m_78` - feature geometry refs = header `m_46 + m_4a` - related object pointers = header `m_nrelated_object_pointers` - 最终 cursor = EOF 任何一项不成立,该 cell 解析失败,不允许“尽量导入”。 ## 2. 属性 按 `CM93ATTR.DIC/ATTRLUT.DIC`: - B: 1-byte integer - W: uint16 / 10.0 - G: int32 - R: float32,标准化后以 Python double/MySQL DOUBLE 保存 - S: NUL-terminated string - C: 3-byte prefix + NUL-terminated string,prefix 与 text 均保留 - L: count byte + count 个 byte values raw value bytes 始终另存。 ## 3. Geometry Feature geotype 低 4 bit: - 1 Point - 2 Line - 4 Area - 8 3D Sounding Line/Area edge index:低 13 bit 是 edge index,高位是 usage;`usage & 4` 表示反向遍历 edge。 Area 按 edge chain 闭合形成 contour/ring。系统不会调用 `make_valid` 或改变原始顶点坐标。 ## 4. 坐标 CM93 raw X/Y:0..65535。 Cell 变换: `easting = raw_x * x_rate + easting_min` `northing = raw_y * y_rate + northing_min` CM93 半长轴:`6378388.0 m`。 若 coverage 给出 `_wgsox/_wgsoy`,标准化母数据采用: `easting -= wgsox` `northing -= wgsoy` 然后执行 CM93 Mercator → lon/lat。 Coverage polygon 自身保留未偏移坐标,用于判断 feature 属于哪个 coverage;offset 元数据独立保存。 ## 5. Sounding CM93 Z: - `z >= 12000` → `depth = z - 12000` - 否则 → `depth = z / 10.0` 每个 sounding point 同时保存 raw_x/raw_y/raw_z、depth 和 WGS84 Point。 ## 6. Raw preservation 每个 cell 保存 decoded: - prolog - header - vector table - point3d table - point2d table - feature table 较大的 table 按 512 KiB 分块写入 `chart_raw_record`,避免 MySQL `max_allowed_packet` 造成单大包问题。 审计要求所有 raw chunk `OCTET_LENGTH` 总和 = 原 cell 文件字节数。 ## 7. 审计分层 ### Source parser audit 重新读取原 CM93,验证所有结构计数和 EOF。 ### Database completeness audit 逐 cell 对比源数据与: - chart_feature - chart_feature_attribute - point/line/area geometry - chart_coverage - chart_sounding_point ### Raw preservation audit 比较 raw chunk 总字节数与原文件长度。 ### Hash audit 比较数据库 `source_sha256` 与当前原文件。 ### Precision audit 从 Z/A~G 分层抽样,重新从 CM93 raw geometry 生成 WKB,然后从 MySQL `ST_AsWKB()` 回读,使用 `equals_exact` 比较。 默认 tolerance:`1e-12 degree`。 该标准比最初讨论的 `1e-9 degree` 更严格。 ## 8. 不做的事情 第一阶段不做: - PBF - zoom selection - simplify - topology repair - scale 去重 - cartographic style 映射 这些都属于第二阶段。