Geofire如何为Firebase查询计算边界地理数据?

时间:2017-02-12 18:23:42

标签: javascript firebase firebase-realtime-database geofire geohashing

上下文

我已经将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 */ });

这两个(最小和最大)地理位置是根据给定输入计算的。现在问题是

问题(S)

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

澄清最后一部分:考虑以下图像

Typical geohashing steps

由于通过将区域减半到较小区域进行地理分割,不同大小(最小和最大)的两个哈希如何具有相同的中心点?

假设

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

1 个答案:

答案 0 :(得分:3)

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

然后在客户端代码中检查每个密钥与查询中心的实际距离,并仅针对内的项目触发key_entered / key_moved事件查询。

相关代码为here

// 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);
}