3.2 KiB
CM93 解析与审计设计 v1
1. 原始格式解析
独立 Python 实现依据已公开的 OpenCPN CM93 行为进行互操作核对,但不复制 OpenCPN 的类结构或 GUI/S52 代码。
核心数据顺序:
- 10-byte prolog
- 128-byte header
- vector records
- 3D point descriptors
- 2D points
- 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 映射
这些都属于第二阶段。