在Spanner中查询给定半径内的地址

问题描述 投票:1回答:1

它在锡上的内容:我如何在我的Spanner数据库中查询在给定long和lat的某个半径范围内的地址?

举个例子,假设我有一个餐馆数据库,我正在寻找距离我公寓十英里的餐馆。我目前将每个餐厅的纬度和长度存储在Address_geolngAddress_geolat字段中作为度数。为了简单的数据,我们会说我不知何故生活在热岛餐厅的中间岛屿(例如0,0)。

许多数据库都有内置的地理类型或某种类型的预建地理坐标功能,但我在Spanner中看不到任何一个。

我一直试图用蛮力实施Haversine formula代替所有其他东西,但老实说,我的眼睛正在穿过这里,要么我无法找到我的用例的相关文档,或者扳手错过了很多有助于更简单地实现这一点的事情。 (例如,看起来它们的三角函数仅以弧度为单位,但我看不到任何参考弧度转换函数的程度或参考PI的能力...有必要比抓住ACOS(-1)更好的东西, 我确定....)

到目前为止,我所付出的最大努力是

    COS(0) * COS(DIV(ACOS(-1),180) * Address_geolat) *
    SIN(DIV(DIV(ACOS(-1),180) * (Address1_geolng - 0)), 2) * SIN(DIV(DIV(ACOS(-1),180) * (Address1_geolng - 0), 2)) AS a FROM restaurants WHERE (3959 * 2 * ATAN2(SQRT(a), SQRT(1 - a)) <= 10)

哪些我是积极的甚至是不对的 - 我的眼睛只是试图整理所有这些。

有人已经为此开发了解决方案吗?你用了什么?

google-cloud-spanner
1个回答
2
投票

所以我正在为此发布文档。您是正确的,Spanner内部没有地理空间支持,但这里有一些提示:

1)不要在顶层选择使用hasrsine进行查询 - 这意味着你必须对所有行进行全表扫描,每个行都有复杂的计算,所以在大表上会非常慢

2)首先计算一个边界为20英里的边界矩形的角坐标,并在中心设置您所需的坐标。

3)使用简单的> / <运算符比较lat-long到角点,查询lat-long在你的边界框内的地址。由于这是一个简单的查询,您可以利用纬度和经度上的二级索引来使您的查询更快...(小心两极,经过180°经度!)

4)你现在有一组有限的地址距离你要求的位置大约20英里(有些距离稍微远一点)你现在可以通过使用余弦或球面余弦定律计算精确距离来过滤这些地址

这种精细的距离计算/过滤可以在SQL中完成,但在您可以使用更多数学函数的应用程序中执行此操作可能更容易,并且可以使用局部变量来简化操作。由于您只有几行可以使用(由于边界框上的粗略过滤),因此这应该很快。

这是一个有用的网页,更容易阅读公式:https://www.movable-type.co.uk/scripts/latlong.html

© www.soinside.com 2019 - 2024. All rights reserved.