【注意】以下都是为了能在我的 HD2 WM6.5 Garmin Mobile XT 5.86 上实现某些 Garmin 手持机功能而折腾的
1、为什么要转换 GPX 和 NVM ? 为什么要 DIY 转换?
GPX(GPS eXchange Format, GPS交換格式)是一個XML格式,為應用軟件設計的通用GPS數據格式。
NVM 格式是 Garmin Mobile XT 保存航迹、兴趣点等数据的格式。
为了能把其他的航迹文件(GPX格式)导入到 Garmin Mobile XT 里面使用,所以要转换。
因为 Garmin Mobile XT 5.86 的和谐版并不完美,无法实现航迹的导入和导出,而且使用 MapSource 连接的时候也无法将 GPX 文件传送到 5.86 里面去(如果能通过 MapSource 搞,只是我没搞对,那我就白痴了)。好吧,至少我找了很多帖子(中外的),没找到方法。
2、什么样的设备需要这个功能?
正如我说的那样,那些折腾 WM6.5 Garmin Mobile XT 5.86 的同学。为什么是 5.86 ? 不是 5.52 ? 因为只有 5.86 才能在 <2km 比例下显示 DEM 地形图,所以才能实现上面我提到的某些功能。
3、如何转换?
我分析了两天的 GARMIN_STRK.NVM 数据文件(已保存的航迹),很遗憾,我只分析出了一些头信息,对其数据结构仍无法破解。
于是,我把目标转向了 GARMIN_ATRK.NVM 数据文件(当前航迹),这个文件结构简单多了。
a - 从 NVM 到 GPX,这个过程很简单,参考了国外网站的一些数据后,我写了一个小程序,用来转换,将我自己手机里面 GARMIN_ATRK.NVM 转成了 GPX 并拖到 MapSource 里面去了。看上去很不错,工作良好。
b - 从 GPX 到 NVM,这个是我们的目的,但是有点麻烦。因为从NVM到GPX时,有些数据我们可以不用管,只抓取航点信息就可以了。但是要生产 NVM 文件,并被 5.86 正确读取,就必须正确构建数据文件的每一个 bit。下面我贴出对 GARMIN_ATRK.NVM 数据文件的格式分析
原解说图有误,已经删除了 实际文件结构为 12bytes 头部,2 bytes航点数量,2 bytes 空白。接下来每 15 bytes 一个记录。15 bytes中, 2 byte 记录头, 3bytes Lat,3bytes Lon,2bytes Ele, 4bytes Time, 1bytes 尾部未知数据。
4、问题在哪?
第一张图中所示的 数据结构中 那些未知的部分数据,不知是何内容,有什么影响?
另外,我发现数据记录的 1 Bytes 结束部分,是有变化的,变化量不大,但是规律仍然未知。
OK,尽管如此,我还是参考了 NVM 到 GPX 的逆向过程,写了另外一个程序,并实现了 GPX 到 NVM 的转换。但是,无论我怎么试,5.86 都只显示航迹上最后 498 个航点。我这个郁闷啊。。。下面我贴出这坑爹的 498 点航迹,经常广州户外拉练的朋友应该能看出这是在哪里(为了测试,我将数据进行了截取,并且没有叠加等高线图)。
右边那条浅蓝色的线,就是我从 GPX 转到 NVM 后显示的 498 点航迹。。。
我尝试过 修改第一张图中所示的 数据结构中 那些未知的部分数据,发现并没有什么影响,我搜索了 WM 6.5 的注册表,里面有个 Garmin_Flash_NVM 的二进制片段,但是没分析出是什么结构和内容。看了 GARMIN.NVM 和 GARMIN_MDB.NVM 也没有收获。
有兴趣的同学们,不妨一起来分析一下。如果这个问题能解决的话,我保证写一个 exe 程序并放出来大家一起用
(好吧,iMac 或 iOS 的也可以
,linux 的。。。我考虑一下。。。
)
jamesljl
·
2012-03-20 14:43
网上的GMXT2GPX有点问题,不过还是能用,导出的 GPX 也能在 Mapsource 里面显示。尽管如此,我还是自己写了一个 NVM2GPX 的程序,为了做 GPX2NVM 的参考。
嗯,我也怀疑这个 500 点的限制是从哪里来的。对于机器本身记录的航迹,貌似是没有这个 500 点的限制的,我曾测试记录过超过800多点的航迹。
另外,目前在写 geoTiff 的拼合程序,暂时没有再继续研究 GPX2NVM 了。
jamesljl
·
2012-03-21 16:20
测试了一下,相同的 GARMIN_ATRK.NVM 文件 在 5.52 上能完整显示, 在 5.86 上只能显示最后的 500 个航点。
另外 active track 里面没有 track 的数量, saved track 里面才有,对应的文件是 GARMIN_STRK.NVM 这个文件比较复杂,分析起来很麻烦,不过可以分析出航迹数量和分段的边界。
jamesljl
·
2012-03-22 15:02
GPSBabel 试用了一下,发现无法从 5.86 读取数据也无法向 5.86 发送数据。而且,连本地 NVM 文件转 GPX 都不成功。
另外,看了 GPSBabel 的源码,估计 STRK 格式里面的数据是加密和重构了的,源码里面有解密和解构的函数,但是移植过来后,发现解出的结果不正确。移植的过程应该没有问题,函数的代码都没改,只是把灌入数据的前期工作改了一下,所以算法还是源码原本的。
折腾了一天,没有突破性进展,郁闷。。。
jamesljl
·
2012-04-08 15:55
已研究完成,请见以下链接
http://www.sosaw.com/forum.php?mod=viewthread&tid=279059&mobile=yes

从NVM到GPX相对简单,网上搜程式GMXT2GPX即可实现
从GPX到NVM,我以前弄常常只弄到前面半截,,,我估计是只能输500个点,可以通过精简航迹到500点内测试看是否可行
60系列的gpx必须500点分段,多了就显示不全,activelog可以几千点
你可能需要找到NVM分段的记录方式
我看了一眼gpsbabel的代码,开头那个16bits应该是track的数量,每个track开头的后16bits才是这条track中路点的数量
建议把分割成多个500点以下track
这个思路看来是对的,既然 60 系列本身有 500 点分段,那 5.52 和 5.86 可能也是 500 点分段的。我等下回去的时候再录一段 activelog 的看看,开慢点,尽量保证航点超过 1000 点,看能不能找到分段规律。
分段的文件数据结构你直接看gpsbable源代码就知道了,activelog有略为不同的格式
楼主可否发个NVM 格式文件上来给我们玩玩,MS不需要折腾吧。
发两个上来吧,一共是 GARMIN_ATRK 一个是 GARMIN_STRK
另外,你说的 MS 是指啥? MapSource? MapSource 能认我的 HD2,也能读数据,就是发送 GPX 的时候,只是在机器对应的目录里简单的生成了个 temp.gpx 。而 5.52 和 5.86 是不会去自动导入的,5.03 会。
附件:NVM2GPX.rar
Garmin Mobile XT 5.03 将gpx 文件 改名 current.gpx 更换原有的,打开garmin 查看 已保存 轨迹,ok
5.03 是可以导入 gpx ,但是 5.86 不行。而且,经过测试, 5.03 的 NVM 文件和 5.86 的 NVM 文件不通用。