我应该如何准确地储存经纬度?

我在这里读到一个问题:

在 SQL 数据库中存储经纬度数据时使用什么数据类型?

似乎大多数人都认为应该使用 Decimal (9,6)。我的问题是,我到底需要这个有多精确?

例如,Google 的 API 返回的结果如下:

"lat": 37.4219720,
"lng": -122.0841430

在 -122.0841430中,我需要多少位数字?我已经读了几本指南,但是我不能从中理解出足够的意义来解决这个问题。

更准确地说,在我的问题中: 如果我想要精确到50英尺以内的确切位置,我需要存储多少个小数点?

也许一个更好的问题实际上应该是一个非编程问题,但它应该是: 每个小数点给你的精度有多高?

就这么简单吗?

  1. 列表项目
  2. x00 = 6000 miles
  3. Xx0 = 600英里
  4. xxx = 60 miles
  5. X = 6英里
  6. Xxx.xx = .6英里
  7. etc?
74585 次浏览

每个纬度之间的距离随着地球形状的变化而变化,而且随着你越来越接近两极,每个纬度之间的距离也越来越小。让我们来谈谈赤道,在赤道上,纬度是110.574公里,经度是111.320公里。

50英尺是0.01524公里,所以:

  • 0.01524/110.574 = 1/7255纬度
  • 经度0.01524/111.320 = 1/7304

你需要四位数的刻度,足够精确到千分之一度,总共需要七位数的精度。

DECIMAL(7,4)应该足够满足你的需要。

+----------------+-------------+
|    Decimals    |  Precision  |
+----------------+-------------+
|    5           |  1m         |
|    4           |  11m        |
|    3           |  111m       |
+----------------+-------------+

If you want 50ft (15m) precision go for 4 digits. 所以 decimal(9,6)

赤道的精确度与小数点后的位数

decimal  degrees    distance
places
-------------------------------
0        1.0        111 km
1        0.1        11.1 km
2        0.01       1.11 km
3        0.001      111 m
4        0.0001     11.1 m
5        0.00001    1.11 m
6        0.000001   0.111 m
7        0.0000001  1.11 cm
8        0.00000001 1.11 mm

ref : https://en.wikipedia.org/wiki/Decimal_degrees#Precision

我设计数据库并且已经研究这个问题有一段时间了。我们使用一个带有 Oracle 后端的现成应用程序,其中数据字段定义为允许17位小数。太荒谬了!也就是千分之一英寸。世界上没有任何 GPS 仪器能如此精确。所以让我们把小数点后17位放到一边,来处理一些实际的问题。政府保证他们的系统在95% 的置信水平下可以达到7.8米的“最坏情况”伪距精度,但是接着又说实际的联邦航空局(使用他们的高质量仪器)已经显示 GPS 读数通常在一米之内。

所以你必须问自己两个问题: 1)你的价值观的来源是什么? 2)这些资料会用作甚么用途?

手机并不是特别准确,Google/MapQuest 的读数可能只有4或5个小数点。一个高质量的 GPS 仪器可能会让你6(在美国)。但是捕获更多的内容是对打字和存储空间的浪费。此外,如果对这些值进行任何搜索,用户最好知道6是他/她应该查找的最大值(显然任何输入的搜索值都应该首先四舍五入到与被搜索的数据值相同的准确度)。

此外,如果你要做的只是在谷歌地图上查看一个位置,或者把它放在一个 GPS 里去那里,四个或五个就足够了。

我不得不嘲笑这里的人输入这些数字。他们到底在哪里测量的?前门把手?前面的信箱?大楼中心?信号塔顶?每个人都在同一个地方服用吗?

As a good database design, I would accept values from a user for maybe a few more than five decimal digits, then round and capture only five for consistency [maybe six if your instruments are good and your end use warrants it].

不要存储浮点值。尽管你可能认为它们是准确的,但事实并非如此。它们是近似值。结果表明,不同的语言有不同的“解析”浮点信息的方法。不同的数据库有不同的实现值近似的方法。

相反,使用 吉欧哈希。Geohash 是以一致的方式对经度/纬度信息进行编码/解码的最佳方式。通过从不将经度/纬度的近似浮点值“序列化”到数据库列中,而是使用 Geohash,您将获得与 String 值相同的往返一致性保证。这个网站非常适合帮助你玩 Geohash。

考虑到球体的各个部分和对角线距离,下表列出了可用的精度:

   Datatype           Bytes       resolution
------------------ -----  --------------------------------
Deg*100 (SMALLINT)     4  1570 m    1.0 mi  Cities
DECIMAL(4,2)/(5,2)     5  1570 m    1.0 mi  Cities
SMALLINT scaled        4   682 m    0.4 mi  Cities
Deg*10000 (MEDIUMINT)  6    16 m     52 ft  Houses/Businesses
DECIMAL(6,4)/(7,4)     7    16 m     52 ft  Houses/Businesses
MEDIUMINT scaled       6   2.7 m    8.8 ft
FLOAT                  8   1.7 m    5.6 ft
DECIMAL(8,6)/(9,6)     9    16cm    1/2 ft  Friends in a mall
Deg*10000000 (INT)     8    16mm    5/8 in  Marbles
DOUBLE                16   3.5nm     ...    Fleas on a dog

-- http://mysql.rjweb.org/doc.php/latlng#representation_choices

If you click locations on Google Maps, you get latitude and longitude with 7 decimal places