从 24 位符号转换为纬度/经度?
Convert from 24 bit signed to latitude / longitude?
我有一些 gps 传感器数据,它们分别使用带符号的 24 位来表示纬度和经度。我想将此数据转换为更易读的度、分和秒格式。
我搜索了很多,但没有适合我的算法。我想在 python.
中执行此操作
规范 sheet 说明了以下内容
Byte [8] > Value: MSB of the UP501 received Latitude
Byte [9] > Value: CSB of the UP501 received Latitude
Byte [10] > Value: LSB of the UP501 received Latitude
Byte 8, 9 and 10 represent the latitude. The north-south latitude is
encoded using a signed 24 bit word where -2^23 corresponds to 90°
south (the South Pole) and 2^23- 1 corresponds to 90° north (the North
Pole). The equator corresponds to 0.
Byte [11] > Value: MSB of the UP501 received Longitude
Byte [12] > Value: CSB of the UP501 received Longitude
Byte [13] > Value: LSB of the UP501 received Longitude
Byte 11, 12 and 13 represent the longitude. The east-west longitude is
encoded using a signed 24 bit word where -2^23 corresponds to 180°
west and 2^23 -1 corresponds to 180° east. The Greenwich meridian
corresponds to 0.
示例数据(8-13 字节)
1E 55 9C 1C 69 5A
应该给
北纬 21°19′44″,东经 39°57′13″
编辑:
在第一条评论之后,问题来了
我看到的每个地方都是坐标的 32 位表示。这些方法对我不起作用,因为我没有得到我期望的结果。差一点。
有没有更好的转换方式?
这有点棘手,因为涉及多个尺度。首先,将带符号的值除以 2**23 - 1 以查看它代表的半球 "fraction"。
>>> 0x1e559c / (2.**23 - 1)
0.2369876190409206
那么,90 度的 23.69...% 是多少?
>>> 0x1e559c / (2.**23 - 1) * 90
21.328885713682855
21.something度;我们走在正确的轨道上。相反,请注意赤道和极点之间有 90*3600 秒的纬度。让我们看看我们有多少:
>>> 0x1e559c / (2.**23 - 1) * 90 * 3600
76783.98856925828
所以给定值为赤道以北~76784秒;将其转换为 degrees/minutes/seconds:
# seconds to minutes and seconds
>>> divmod(76784, 60)
(1279, 44)
# minutes to degrees and minutes
>>> divmod(1279, 60)
(21, 19)
还有你的 21 度 19 分 44 秒。现在,我们知道除以 2**23 - 1
因为我们知道该值小于 0x7fffff,所以在北半球也是如此。 (如果该值位于南半球,我们需要除以 2**23
,因为缩放是不对称的。)
对于经度,您将乘以每个半球的 180*3600
秒而不是 90*3600
,然后以相同的方式进行。
一个警告;我没有包含 southern/western 半球的示例,因为我不确定 90S 是 0x800000(补码)还是 0xffffff(有符号星等)。
我有一些 gps 传感器数据,它们分别使用带符号的 24 位来表示纬度和经度。我想将此数据转换为更易读的度、分和秒格式。
我搜索了很多,但没有适合我的算法。我想在 python.
中执行此操作规范 sheet 说明了以下内容
Byte [8] > Value: MSB of the UP501 received Latitude
Byte [9] > Value: CSB of the UP501 received Latitude
Byte [10] > Value: LSB of the UP501 received Latitude
Byte 8, 9 and 10 represent the latitude. The north-south latitude is encoded using a signed 24 bit word where -2^23 corresponds to 90° south (the South Pole) and 2^23- 1 corresponds to 90° north (the North Pole). The equator corresponds to 0.
Byte [11] > Value: MSB of the UP501 received Longitude
Byte [12] > Value: CSB of the UP501 received Longitude
Byte [13] > Value: LSB of the UP501 received Longitude
Byte 11, 12 and 13 represent the longitude. The east-west longitude is encoded using a signed 24 bit word where -2^23 corresponds to 180° west and 2^23 -1 corresponds to 180° east. The Greenwich meridian corresponds to 0.
示例数据(8-13 字节)
1E 55 9C 1C 69 5A
应该给 北纬 21°19′44″,东经 39°57′13″
编辑: 在第一条评论之后,问题来了 我看到的每个地方都是坐标的 32 位表示。这些方法对我不起作用,因为我没有得到我期望的结果。差一点。
有没有更好的转换方式?
这有点棘手,因为涉及多个尺度。首先,将带符号的值除以 2**23 - 1 以查看它代表的半球 "fraction"。
>>> 0x1e559c / (2.**23 - 1)
0.2369876190409206
那么,90 度的 23.69...% 是多少?
>>> 0x1e559c / (2.**23 - 1) * 90
21.328885713682855
21.something度;我们走在正确的轨道上。相反,请注意赤道和极点之间有 90*3600 秒的纬度。让我们看看我们有多少:
>>> 0x1e559c / (2.**23 - 1) * 90 * 3600
76783.98856925828
所以给定值为赤道以北~76784秒;将其转换为 degrees/minutes/seconds:
# seconds to minutes and seconds
>>> divmod(76784, 60)
(1279, 44)
# minutes to degrees and minutes
>>> divmod(1279, 60)
(21, 19)
还有你的 21 度 19 分 44 秒。现在,我们知道除以 2**23 - 1
因为我们知道该值小于 0x7fffff,所以在北半球也是如此。 (如果该值位于南半球,我们需要除以 2**23
,因为缩放是不对称的。)
对于经度,您将乘以每个半球的 180*3600
秒而不是 90*3600
,然后以相同的方式进行。
一个警告;我没有包含 southern/western 半球的示例,因为我不确定 90S 是 0x800000(补码)还是 0xffffff(有符号星等)。