C中的纬度/经度存储和压缩

Jus*_*cle 24 c compression gps floating-accuracy

有没有人知道纬度/经度坐标的最有效表示?消费者GPS设备的准确度应该足够了.

大多数实现似乎都double用于每个单元,但我怀疑一个float或定点格式应该足够了.我很想听到任何试图压缩或存储这些值的大数组的人.

编辑:

换句话说,对于消费级设备来说,表示纬度/经度所需的最低精度是多少?

caf*_*caf 15

就个人而言,我会使用32位十进制定点表示,根据Evan的回答和我的评论除以1,000,000.

但是,如果空间确实非常宝贵,这里有一些额外的想法:

  • 您可以在线上使用26位定点表示.这将需要将纬度和经度编组和解组为大量字节,但是在32位值表示上将为每个位置节省12位 - 几乎节省19%,因此它可能是值得的.

  • 您可以利用以下事实:当您靠近极点时经度值需要更低的精度 - 它们在赤道上只需要26位.因此,您可以编写一个方案,其中用于编码经度的位数取决于纬度的值.

  • 如果您的数据具有其他可压缩属性 - 例如,所有点通常非常接近 - 您可以采用这些特定优势,例如使用增量编码方案(其中除了第一个点之外的每个点都可以编码为最后一个点)点).


Kri*_*fon 10

地球的周长约为.40.000公里或24900英里.

您需要一米精度(3英尺)才能将gps精度提高一个数量级.

因此,您需要精确度来存储40.000.000个不同的值.这至少是26位信息.32位浮点数或int值可以很好地完成.

  • 我倾向于定点表示,因为浮点数对于这种应用没有优势,并且带符号的32位值有足够的位可用于选择方便的比例. (4认同)
  • 实际上,32位IEEE浮点数有24个显式位分数(假设为1),用于24位有效位有效数.这仅能够区分所需的4000万个中的1600万个独特值.从另一个角度看,它可以代表赤道2.4米范围内的位置,这可能仍然足够接近. (2认同)
  • @Ken:民用GPS装置平均精确到5米是绝对不可能的(在任何情况下,精度通常用统计意义上的方差和标准偏差等来衡量 - 单个数字不能反映准确度) .他们的意思是:偶尔设备会测量距离真实位置5米范围内的位置 - 有点像一个破碎的时钟每天两次正确. (2认同)

Eva*_*ran 9

编辑:从评论中添加了一些点,32位值应该能够提供足够的精度.

我会使用32位定点表示法.如果值是:

42.915512,-99.521654我会保存values * 100000int32_t(也可以是负的).

int32_t lat = 42915512;
int32_t lon = -99521654;
Run Code Online (Sandbox Code Playgroud)

这是简单准确之间的良好折衷(5小数点足够平时好,你总是可以碰到它来1000000获得6,如果需要的话).

要向用户显示,请执行caf建议:

...显示给用户 - 使用整数除法和模数,例如 printf("Lat = %d.%06d\n", lat / 1000000, abs(lat) % 1000000)

由于将保留相对排序,因此这些也将以有效的方式进行比较/排序.

编辑:另一个好处是它可以通过网络发送或以便携方式以二进制格式存储到磁盘.

  • 我建议使用2的幂乘数而不是10,000.如果您发现必须对数字进行硬编码,则使用10,000可能是人类可读的,但是否则相当无用.此外,如果您使用此方法,则始终使用宏/内联函数转换为/从double转换为int. (3认同)
  • 也许要小心一点,不要抹去-77.521654和77.521654之间差异的含义 (2认同)
  • 哦,不要转换为双倍和除法显示给用户-使用整数除法和取模,例如printf(“ Lat =%d。%06d \ n”,lat / 1000000,lat%1000000) (2认同)

Mus*_*sis 5

即使消费级GPS设备具有接近其声称准确度的任何地方,浮动对于存储GPS坐标也是足够的.如果您不相信这是真的,请尝试以下两个简单的实验:

  1. 将两个或更多GPS设备带到某个地方的某个地点,然后记下每个设备测量的坐标.回到里面并在地图上绘制每个设备的点数(我认为谷歌有一些能为你做这件事).你会惊讶于这些点有多远(即使它们都应该测量完全相同的点).
  2. 拿你的(据称)最准确的设备,把它放在可以获得卫星定位但不会下雨的地方,并记录几天内进行的一系列测量.绘制所有读数(如#1).再一次,你会惊讶于这些点(应该都是相同或几乎相同)在整个地图上徘徊,有时会长达几百英尺.

多年来我一直在为支持GPS的PDA编写应用程序,我已经一次又一次地为可疑的客户验证了这一点(我甚至以这种方式赢得了赌注).有更高质量的GPS设备确实达到了比这更好的准确性,但是使用更昂贵的芯片组可以获得更好的准确性,并且设备可以在一个地方放置数天甚至数周,读数平均随着时间的推移而变化.

四字节浮点数比设备本身准确得多.只要2X因素不是你的问题,它当然不会伤害你使用双倍.


小智 5

假设地球是一个半径为 3959 英里(或 ×5280 ft/mi = 20903520 ft)的完美球体(它不是,但足够接近),周长为 131340690 英尺(使用 2×PI×R) .

360 度经度覆盖 131340690 英尺。180 度纬度覆盖 65670345 英尺。

如果要将纬度/经度存储到 3 英尺的精度,则需要能够存储 43780230 (131340690/3) 经度值和 21890115 (65670345/3) 纬度值。43780230 需要 25.38 位(log(43780230)/log(2))来存储,21890115 需要 24.38 位(log(21890115)/log(2))来存储 – 或者不到 50 位(或 6.25 字节)。

所以显而易见的问题就变成了,如果你想只用 6 个字节来存储纬度和经度,准确度会是多少?好吧,6 字节是 48 位。这意味着纬度为 23.5 位,经度为 24.5 位(经度的值是两倍,只有一位,24.5-23.5=1 位)。因此,23.5 位允许您表示从 0 到 11863282(11863283 个值)的数字。65670345 英尺除以 11863283 值是 5.53 英尺(经度精度值相同)。

底线:因此,如果纬度和经度的精度都可以达到 5.5 英尺,那么您可以将这两个值都打包到六个字节中。

*旁注:关于纬度和经度对于存储球体周围位置信息很糟糕的评论(因为在极点存储的信息较少)——好吧,这些评论不符合数学要求!让我们弄清楚。假设我们要设计一个新的完美系统,可以记录并在每平方英尺地球中心的地面上放置一个桩。地球的表面积(R 为 3959 英里;球体表面积的公式)是 5490965469267303 SQ FT - 许多赌注需要 52.29 位来表示。现在现有的经纬度系统采用矩形系统。矩形的宽度是地球的周长,矩形的高度是周长的 1/2)——即 131340690 * 65670345(见上文),或 8625188424838050 SQ FT——需要 52。94 位来表示(这个系统在两极周围的地面上放置了“太多”的桩)。因此,令人震惊的答案是,新的完美系统和旧的 lat/lng 系统都需要 53 个实际位来存储地球上的单个位置,精度低至 1 英尺!