如何在Mysql中高效利用经度/纬度值?

3
感谢维基解密,现在我们可以在英国访问每个邮政编码的经纬度坐标。维基解密英国邮政编码 重要提示:不要在公共应用程序中使用此数据-有人担心该数据已被故意损坏,您可能会被认为侵犯版权法。请尝试使用来自开放源代码网站的数据,例如 英国邮政编码网站
现在,可以使用以下计算(最初来自精美的书籍Pro Mysql)计算每个点之间的距离:
两点(x1,y1)和(x2,y2)之间的距离d可以从以下方程式计算得出(只要x值是以弧度表示的纬度,y值是以弧度表示的经度,r是球体的半径,即3956英里): d = acos(sin(x1)* sin(x2)+ cos(x1)* cos(x2)* cos(y2-y1))* r 现在这样是否足够好,还是应该使用新的GIS数据类型和函数?如果需要,如何将我的经度和纬度参考转换为Point数据类型?我意识到由于地球不是完美的球体,所以我上面引用的距离计算并不完美;但对于我的目的来说已经足够好了。使用新的GIS功能会使a)距离计算更快速 b)距离计算更准确吗?
2个回答

2

聚焦于(a):

过去,我已经预先计算了一些部分,存储了经度、纬度、x轴、y轴和z轴,其中x、y和z的定义如下:

xaxis = cos(radians(Lat)) * cos(radians(Lon))
yaxis = cos(radians(Lat)) * sin(radians(Lon))
zaxis = sin(radians(Lat))

距离可以使用SQL计算,类似于(acos( xaxis * $xaxis + yaxis * $yaxis + zaxis * $zaxis ) * 6367.0 / 1.852)(其中以$开头的值是以与上述相同的方式预先计算的起点)。

这种预先计算的方法将比较昂贵的三角函数计算转化为一次性事件,并简化了查询。


太棒了 - 我一直都是非常支持在数据存储中进行反规范化以提高计算时间的。谢谢! - DBMarcos99
有趣的是你使用了6367作为地球半径的公里数。根据不同的来源,这个数字似乎在6356和6378之间变化。无论如何,我将其标记为被接受的答案。 - DBMarcos99
@DBMarcos99 这里所使用的平均半径通常定义为 ((2 * 半长轴) + 半短轴) / 3.0,你可以在你偏好的大地测量系统中找到相应的数值。 - Rowland Shaw
当然,自从这个问题被提出后,军械测绘局已经在其OpenData计划下合法地发布了数据。请访问https://www.ordnancesurvey.co.uk/opendatadownload/products.html。 - Rowland Shaw

1

好的,来回答你的“B”问题,因为你的方程式假定是一个完美的球体,所以你的计算会有些偏差(而且很可能会随着两点之间的距离越远越变得更糟糕)。如果GIS考虑到了这一点,那么你的距离计算就会更加精确。

至于从纬度/经度转换为点,我记得这在Google Maps API中提供了。(参见GLatLng参考文档。)


谢谢。我真的在寻找Mysql内部的选项,但是使用API接口可能是一种有用的替代方案。 - DBMarcos99

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接