0

我有一个angularJS绑定到 firebase的模型$scope.items=$firebase(blah),我用它ng-repeat来遍历这些项目。firebase 中的每个项目通过项目的键都有一个对应的 geofire 位置。

如何更新我的控制器以仅包含用户周围自定义半径的项目?我不想按角度的距离进行过滤,只是要求 firebase 只检索更近的项目(比如某个位置周围 0.3 公里)。我环顾了地理查询,但它们有不同的目的,我不知道如何将它们绑定到模型。用户可以更改半径,并且项目列表应该相应更新,因此需要以某种方式绑定它们。

欢迎提出任何建议,但如果我对 angular/firebase/geofire 这三重奏还不熟练,我将不胜感激:P

4

1 回答 1

0

不看代码就很难弄清楚你需要做什么。但一般来说,您需要查询包含Geohash作为子名称或优先级的 Firebase ref。

这种数据结构的一个很好的例子可以在这里找到:https ://publicdata-transit.firebaseio.com/_geofire/i

i
  9mgzcy8ewt:lametro:8637: true
  9mgzgvu3hf:lametro:11027: true
  9mgzuq55cc:lametro:11003: true
  9mue7smpb9:nctd:51117: true
  ...
l
  ...
  lametro:11027
    0: 33.737797
    1: -118.294708
  actransit:1006
  actransit:1011
  actransit:1012
  ...

实际的运输车辆在l节点下。它们中的每一个都有一个数组,其中包含该车辆的位置作为经度和纬度对。

i节点是将每辆车映射到 Geohash 的索引。您可以看到每个节点的名称都构建为<geohash>:<metroarea>:<vehicleid>.

由于 Geohash 位于名称的开头,我们可以使用查询过滤 Geohash:

var ref = new Firebase("https://publicdata-transit.firebaseio.com/_geofire");
var query = ref.child('i').startAt(null, '9mgzgvu3ha').endAt(null, '9mgzgvu3hz');
query.once('child_added', function(snapshot) { console.log(snapshot.name()); });

通过此查询,Firebase 将为我们提供名称在该范围内的所有节点。如果一切正常,这将输出一个节点的名称:

  9mgzgvu3hf:lametro:11027

拥有该节点后,您可以解析名称以提取车辆 ID,然后在l.

根据位置和范围计算 Geohashes

在上面的代码片段中,我硬编码了要使用的 geohash 值。通常,您需要获取围绕中心的特定范围内的所有节点。我建议不要自己计算这些,而是​​使用geohashQueriesGeoFire 中的函数:

var whitehouse = [38.8977, -77.0366];
var rangeInKm = 0.3;
var hashes = geohashQueries(center, radiusInKm*1000);

console.log(JSON.stringify(hashes));

这会输出一些 Geohash 范围:

[["dqcjqch","dqcjqc~"],["dqcjr10","dqcjr1h"],["dqcjqbh","dqcjqb~"],["dqcjr00","dqcjr0h"]]

您可以将这些 Geohash 范围中的每一个传递到 Firebase 查询中:

hashes.forEach(function(hash) {
  var query = geoFireRef.child('i').startAt(null, hash[0]).endAt(null, hash[1]);
  query.once('child_added', function(snapshot) { log(snapshot.name()); });
});

我希望这可以帮助您进行设置。

这是我不久前创建的一个 Fiddle 来试验这些东西:http: //jsfiddle.net/aF9mN/

于 2014-08-05T18:09:17.803 回答