【问题标题】:How can I bind the radius of my Geofire query in AngularFire?如何在 AngularFire 中绑定 Geofire 查询的半径?
【发布时间】:2014-09-27 23:10:36
【问题描述】:

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

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

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

【问题讨论】:

  • 看看 Geofire,它完全符合您的描述。 github.com/firebase/geofire
  • 正如标题所说,我正在使用 Geofire :)。但我不知道如何将它绑定到角度模型。现在我可以拿回我的积分吗? :)
  • 我有一个 AngularGeoFire 库可以帮助你 - github.com/mikepugh/AngularGeoFire。自述文件有一个设置 GeoQuery 的示例以及如何在控制器中获取该数据(通过广播侦听器)。
  • thx @MikePugh,我会试一试,然后回来回答。
  • 糟糕,我错过了您已经在使用 Geofire。虽然我没有投反对票,但可以想象人们会发现你没有包含任何代码的事实是投反对票的理由。请记住“你能告诉我为什么我的代码不起作用吗?”如果问题包含相关代码,则更容易解决问题。

标签: angularjs firebase angularfire geofire


【解决方案1】:

如果不查看您的代码,很难弄清楚您需要做什么。但一般来说,您需要查询包含 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 位于名称的开头,我们可以使用 Query 过滤 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

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

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/

【讨论】:

  • 您为什么要费尽心思从 GeoFire 获取 geohash 范围并设置 child_added 事件,而不仅仅是使用 GeoFire 的查询方法和生成的 GeoQuery 对象?
  • 主要是因为我想了解如何在不查看代码的情况下构建类似的东西。 :-)
  • Geohashes 对我来说听起来有点像独角兽:具有神话属性的魔兽,所以我想更好地了解它们。出于同样的原因,我用 C# 编写了一个 Geohash 解码器:github.com/puf/fietsfiles/blob/master/DecodeGeohash.linq
猜你喜欢
  • 2019-02-01
  • 2019-03-27
  • 1970-01-01
  • 2020-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-29
相关资源
最近更新 更多