2

语境

我已经使用 Geofire 和 Firebase 有一段时间了,我很好奇 Geofire 是如何执行它的查询的。我理解从语义上讲,它是坐标和半径的函数,会产生最小和最大哈希值。所以我认为它与 Firebase 结合使用的方式看起来像这样

ref.child("users").orderByChild("g").startAt(minHash).endAt(maxHash).on('child_added', function(snapshot) { /* retrieved snapshot contains the geohashes in range */ });

这两个(最小和最大)geohashes 是根据给定的输入计算的。现在问题来了

问题)

假设我上面说的是正确的,这两个geohashes是如何计算的?当 geohashes 通常表示边界矩形时,它们如何在某个圆形区域内返回结果?最后,两个不同大小的 geohashes 怎么会有相同的中心呢?

为了澄清最后一部分:考虑下图

典型的地理哈希步骤

由于地理散列通过将区域减半为更小的区域来工作,那么两个不同大小(最小值和最大值)的散列如何具有相同的中心点?

假设

我认为这可能就像增加/减少哈希的原始值一样简单,但这没有多大意义,因为增加/减少应该与哈希的大小相关(可以说是“缩放”级别)和查询半径,如果我没记错的话。

4

1 回答 1

3

GeoFire 实际上对数据库执行矩形区域的范围查询。此范围是包含查询中指示的范围的最小矩形。

然后它在客户端代码中检查每个键到查询中心的实际距离,并且只为查询key_entered的项目触发/key_moved事件。

相关代码在这里

// Determine if the location is within this query
distanceFromCenter = GeoFire.distance(location, _center);
isInQuery = (distanceFromCenter <= _radius);

...

// Fire the "key_entered" event if the provided key has entered this query
if (isInQuery && !wasInQuery) {
  _fireCallbacksForKey("key_entered", key, location, distanceFromCenter);
} else if (isInQuery && oldLocation !== null && (location[0] !== oldLocation[0] || location[1] !== oldLocation[1])) {
  _fireCallbacksForKey("key_moved", key, location, distanceFromCenter);
} else if (!isInQuery && wasInQuery) {
  _fireCallbacksForKey("key_exited", key, location, distanceFromCenter);
}
于 2017-02-14T00:02:55.707 回答