如何将二进制(十六进制)数据转换为纬度和经度?

时间:2011-02-25 20:42:52

标签: binary hex coordinates

我有一些二进制数据流传递地理位置坐标 - 纬度和经度。我需要找到它们编码的方法。

4adac812 = 74°26.2851' = 74.438085
2b6059f9 = 43°0.2763'  = 43.004605

4adaee12 = 74°26.3003' = 74.438338
2a3c8df9 = 42°56.3177' = 42.938628

4ae86d11 = 74°40.1463' = 74.669105
2afd0efb = 42°59.6263' = 42.993772

第一个值是十六进制值。第二&第三个是我在输出中得到的值(不确定在转换中使用哪一个)。

我发现第一个字节表示值的整数部分(0x4a = 74)。但我找不到小数部分的编码方式。

我真的很感激任何帮助!

感谢。

-

Upd:这个流来自一些“中国”gps服务器软件,通过tcp协议。我没有关于clent软件的资料或文档。我想它是用VC ++ 6编写的,并使用了一些标准实现。

-

更新:这是我收到的数据包:

Hex data:
41 00 00 00  13 bd b2 2c
4a e8 6d 11  2a 3c 8d f9
f6 0c ee 13

Log data in client soft:
[Lng] 74°40.1463', direction:1
[Lat] 42°56.3177', direction:1
[Head] direction:1006, speed:3318, AVA:1
[Time] 2011-02-25 19:52:19

Result data in client (UI):
74.669105
42.938628
Head 100 // floor(1006/10)
Speed 61.1 // floor(3318/54.3)


41 00 00 00  b1 bc b2 2c
4a da ee 12  2b 60 59 f9
00 00 bc 11
[Lng] 74°26.3003', direction:1
[Lat] 43°0.2763', direction:1
[Head] direction:444, speed:0, AVA:1
[Time] 2011-02-25 19:50:49
74.438338
43.004605


00 00 00 00  21 bd b2 2c
4a da c8 12  aa fd 0e fb
0d 0b e1 1d
[Lng] 74°26.2851', direction:1
[Lat] 42°59.6263', direction:1
[Head] direction:3553, speed:2829, AVA:1
[Time] 2011-02-25 19:52:33
74.438085
42.993772

我不知道前4个字节是什么意思。

我发现第5个字节的低7位代表秒数。 (也许5-8位是时间?) 字节9表示Lat的整数。

字节13是Lng的整数。

字节17-18反转(字节字节)是速度。

字节19-20反转是ava(?)&方向(4 + 12位)。 (顺便说一句,有人知道ava是什么?)

还有一个说明。在第3个数据包第13个字节中,您只能看到使用低7位。我猜第一位并不意味着smth(我在开始时删除了它,抱歉,如果我错了)。

3 个答案:

答案 0 :(得分:3)

我已重新排序您的数据,以便我们首先拥有3个长支,然后是3个纬度:

74.438085,74.438338,74.669105,43.004605,42.938628,42.993772

这是我能想到的最合适的十六进制:

74.437368,74.439881,74.668392,42.993224,42.961388,42.982391

差异为:-0.000717,0.001543,-0.000713,-0.011381,0.022760,-0.011381

从完整的Hex'es(4个而不是3个字节)生成这些值的程序是:

int main(int argc, char** argv) {
    int a[] = { 0x4adac812, 0x4adaee12, 0x4ae86d11, 0x2b6059f9, 0x2a3c8df9, 0x2afd0efb };
    int i = 0;
    while(i<3) {
        double b = (double)a[i] / (2<<(3*8)) * 8.668993 -250.0197;
        printf("%f\n",b);
        i++;
    }
    while(i<6) {
        double b = (double)a[i] / (2<<(3*8)) *  0.05586007 +41.78172;
        printf("%f\n",b);
    i++;
    }
    printf("press key");
    getch();
}

答案 1 :(得分:0)

在这里集思广益。

如果我们查看第二个字节的低6位(data [1]&amp; 0x3f),我们会得到大多数示例的“分钟”值。

0xda & 0x3f = 0x1a = 26; // ok
0x60 & 0x3f = 0; // ok
0xe8 & 0x3f = 0x28 = 40; // ok
0x3c & 0x3f = 0x3c = 60; // should be 56
0xfd & 0x3f = 0x3d = 61; // should be 59

也许这是正确的方向?

答案 2 :(得分:0)

我已经尝试过你的新数据包了:

74 + 40.1463 / 60 74 + 26.3003 / 60 74 + 26.2851 / 60 42 + 56.3177 / 60 43 + 0.2763 / 60 42 + 59.6263 / 60

74.66910, 74.43834, 74.43809, 42.93863, 43.00460, 42.99377

我的节目给出了:

74.668392, 74.439881, 74.437368, 42.961388, 42.993224, 39.407346

区别在于:

-0.000708,  0.001541,  -0.000722,  0.022758, -0.011376, -3.586424

我重新使用了从你的第一个数据包派生的4个常量,因为它们可能存储在你的客户端的某个地方。稍有差异可能是客户端为防止您获得准确值或对其协议进行逆向工程而进行的一些随机化的结果。