Files
CM95/docs/CM93解析与审计设计.md
2026-09-02 09:50:12 +08:00

151 lines
3.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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 映射
这些都属于第二阶段。