tommasopasini/igpsport-binavi-poi
GitHub: tommasopasini/igpsport-binavi-poi
通过逆向工程 iGPSPORT BiNavi 码表的 .cnx 原生格式,将 GPX 轨迹和路书 CSV 转换为带自定义 POI 的导航路线文件。
Stars: 0 | Forks: 0
# igpsport-binavi-poi
将您自己的兴趣点(POI)——如水、食物、危险、备注——放入
**iGPSPORT BiNavi** 码表中,以便在导航时显示。
官方 iGPSPORT 应用做这件事很别扭(没有“饮水点”或“食物”分类,
按距离放置点位很困难,且导出的 FIT 路线点会被设备
忽略)。这个仓库包含一个小型生成器,直接写入设备
**原生的 `.cnx` 路线格式**,并按公里数沿轨迹放置您的 POI。
在导航期间,当您靠近时,BiNavi 会将每个点显示为
**带有倒数距离的接近提醒**。
逆向工程的格式(轨迹编解码器 + POI `` 枚举)已记录
在 **[BINAVI_NOTES.md](BINAVI_NOTES.md)** 中。
## 工作原理
BiNavi 路线是设备 `Courses/` 文件夹中的一个 `.cnx` XML 文件。它包含
轨迹(增量编码)和一个由 POI 组成的 `` 列表。`generate_cnx.py` 接收一个普通的
**GPX 轨迹**加上一个**路书 CSV**(您的点位,按公里),并写入一个您可以复制
到设备的 `.cnx` 文件。在写入任何内容之前,一个往返自检会检查解码后的轨迹是否在 0.5 厘米误差范围内还原为 GPX。
### 为什么不用 GPX 或 FIT?
两者最初都尝试过;都没有成功将 POI 传到设备上:
- **GPX** 仅作为*轨迹*源。BiNavi 自己的路线格式是 `.cnx`;当导入 GPX 时
(通过 App),轨迹会被转换为 `.cnx`,而其 `` **路径点会被
丢弃** —— 它们永远不会变成设备上的 POI。因此,GPX 在这里仅用于
在桌面地图应用中预览点位,而不适用于设备。
- **FIT** 路线文件可以*加载*(轨迹可用),但固件**忽略了
`course_point` 消息** —— 没有图标,也没有警报。已在设备上验证:一个带有类型化
饮水/食物/危险路线点的 FIT 文件什么也没显示。详情见
[BINAVI_NOTES.md §4](BINAVI_NOTES.md);相关脚本保留在 `experiments/` 中作为记录。
原生的 `.cnx` `` 列表是设备实际渲染的唯一通道 —— 这正是
`generate_cnx.py` 所写入的内容。
## 环境要求
- Python 3(仅限标准库 —— 无需 `pip install`)
- `gpsbabel` —— 仅用于 `experiments/` 中的 FIT 脚本,主工具不需要
## 用法
您实际操作的所有内容都保留在**本地**:`inputs/` 和 `outputs/` 文件夹
已被 gitignore 忽略,因此您的轨迹和生成的路线永远不会被提交。
```
# 1. 将你的 track 和 roadbook 放入 inputs/
cp my_ride.gpx inputs/
cp roadbook.example.csv inputs/roadbook.csv # then edit it
# 2. 生成 native route
python generate_cnx.py
# -> outputs/my_ride.cnx (+ 打印 self-test 结果)
# 3. 将其复制到设备中(BiNavi 作为 USB mass storage 挂载,处于关机状态)
cp outputs/my_ride.cnx /mnt/d/iGPSPORT/Courses/
```
选项:`--gpx`、`--roadbook`、`--out` 会覆盖默认值。如果 `inputs/` 中有一个 `.gpx` 文件
并且有一个 `inputs/roadbook.csv`,则无需任何参数。
### 路书 CSV
参见 **[roadbook.example.csv](roadbook.example.csv)**。各列:
| 列名 | 含义 |
|---|---|
| `km` | 点位在 GPX 轨迹上的距离位置(十进制公里) |
| `type` | 分类 —— 名称(例如 `supply point`)或其整数代码 `0`–`22` |
| `description` | 设备上显示的简短文本(开头的 `!` 会读取为警告) |
设备上没有“饮水点”或“食物”分类;`supply point` 是
最接近水/补给点的选项,`shop` 适合作为食物停靠站。
**POI 类型图例**(内部的 `` 枚举 —— *不是*应用屏幕菜单上的顺序):
| 代码 | 名称 | 代码 | 名称 |
|---|---|---|---|
| 0 | waypoint | 12 | equipment area |
| 1 | sprint point | 13 | shop |
| 2 | hc climb | 14 | meeting point |
| 3 | level 1 climb | 15 | viewing platform |
| 4 | level 2 climb | 16 | instagram-worthy location |
| 5 | level 3 climb | 17 | tunnel |
| 6 | level 4 climb | 18 | valley |
| 7 | supply point | 19 | dangerous road |
| 8 | garbage recycle area | 20 | sharp turn |
| 9 | restroom | 21 | steep slope |
| 10 | service point | 22 | intersection |
| 11 | medical aid station | | |
您可以在 `type` 列中写入名称或数字。(它们各自渲染成什么图标是
设备自己的事;关于该枚举是如何恢复的,请参见 [BINAVI_NOTES.md §3](BINAVI_NOTES.md)。)
### 在地图应用中预览(可选)
`build_roadbook_gpx.py` 会将相同的点写入为 GPX 路径点(到 `outputs/`),以便您
可以在 Komoot/GPXSee 中直观地检查它们。这仅用于预览 —— 它**不会**在 BiNavi 上
放置任何内容。
## 在设备上测试(无需骑行)
POI **不是**地图图标 —— 在 BiNavi 上,它们仅**在活动导航期间**出现,表现为
一个随着您接近而倒计时距离的接近提醒(无声音)。为了在实际骑行前确认
这一点,请在您附近创建一条带有 2-3 个相隔几百米的点的短测试路线,
对其进行导航,然后走向第一个点直到提醒出现。
有两种方法可以获取该测试路线 —— 可用作 A/B 测试检查:
- **使用 iGPSPORT App(参考 / 已知良好):**在 App 中创建一条短路线,在上面
添加几个 *Navigation Pro Points*,并同步到设备。这是官方途径;
如果您生成的文件表现相同,您就知道文件是对的。
- **不使用 App(使用本工具):**在您附近制作一个微型 GPX 和一个 2-3 行的路书 CSV,运行
`python generate_cnx.py --gpx inputs/test.gpx --roadbook inputs/test_roadbook.csv`,然后将
`.cnx` 复制到 `Courses/`。
两者都应以相同的方式显示点位。(相比之下,基于 FIT 的测试路线什么也
不显示 —— 这就是上面记录的死胡同;如果您想看看它失败的样子,
`experiments/generate_test_course.py` 可以构建一个。)
## 布局
```
generate_cnx.py main tool: GPX + roadbook CSV -> native .cnx
build_roadbook_gpx.py preview helper: -> GPX waypoints
roadbook.example.csv template for your roadbook
BINAVI_NOTES.md reverse-engineered .cnx format + POI enum
experiments/ FIT attempts (dead end: device ignores FIT course points)
inputs/ YOUR tracks / roadbooks / PDFs (gitignored)
outputs/ generated .cnx / .gpx / .fit (gitignored)
```
## 许可证
MIT —— 见 [LICENSE](LICENSE)。
标签:GPX, iGPSPORT, 数据生成, 文件格式, 自行车码表, 运动导航