Firebase查询附近的对象

时间:2013-06-03 06:25:11

标签: firebase

在mysql中,我使用的是半字形公式来查询附近的对象。

使用此公式 式

SELECT id, ( 3959 * acos( cos( radians(37) ) * cos( radians( lat ) ) * cos( radians( lng ) - radians(-122) ) + sin( radians(37) ) * sin( radians( lat ) ) ) ) AS distance 
FROM markers HAVING distance < 25 ORDER BY distance LIMIT 0 , 20;

哪些

  • 3959:以英里为单位的地球半径
  • 37,-122:给定lat lng
  • 25:25英里内

在Firebase中 我可以像在mysql中一样存储用户lat lng吗? 创建标记表。 id,lat,lng列然后使用公式查询

更新

我应该问一下,在firebase中使用这个公式查询附近的方法是什么。

2 个答案:

答案 0 :(得分:8)

简短的回答,不像你想要的那样。

  

Firebase本质上有两种查询数据的方法:按路径和按   优先。这比SQL更有限,而且非常好   原因 - 我们的API经过精心设计,仅允许使用   我们可以保证快速的运营。 Firebase是一个实时和   可扩展的后端,我们希望能够让您构建出色的应用程序   可以在不影响响应能力的情况下为数百万用户提供服务。

参见what is firebase and deNormalizing data 此外,这个SO question也是类似的。

对评论的回应: Firebase不会为您计算sin( radians(X) )。这是一个“缓慢”的操作。因此,您需要在保存时将该信息存储到数据中。 我不是100%肯定,但您可以存储标记,并将经度/纬度存储在单独的父级中。

Root
    -> Markers
    -> longitude (Use the value as priority) -> MarkerId
    -> latitude (Use the value as priority) -> MarkerId

然后你应该能够使用边界来找到最大和最小经度和纬度。 用它来按优先级查询经度和纬度路径。如果两者都存在MarkerId,则使用它。

一些研究在Latitude Longitude Bounding Coordinates

上发现了这篇文章

答案 1 :(得分:4)

嘿,我刚刚使用firebase和GeoFire构建了一个实时谷歌地图。 GeoFire非常酷且易于使用。它允许您使用lon lat和radius进行查询。它返回一个可用于查询firebase数据库的密钥。在创建geoFire对象时,将键设置为您想要的任何值。它通常是一个参考,您可以使用它来获取与该距离相关联的对象。

以下是geoFire的链接: https://github.com/firebase/geofire-js

以下是一个用例示例:

你有一个lon lat,你使用了导航器:

var lon = '123.1232';
var lat = '-123.756';
var user = {
    name: 'test user',
    longitude: lon,
    latitude: lat
}
usersRef.push(user).then(function(response) {
    var key = response.key;
    var coords = [lon, lat];
    geoFire.set(key, coords, function(success){
         console.log('User and geofire object has been created');
    });
})

现在您可以使用以下方式查询用户:

// Set your current lon lat and radius
var geoQuery = geoFire.query({
    center: [latitude, longitude],
    radius: radiusKm
});
geoQuery.on('key_entered', function(key, location, distance) {
    // You can now get the user using the key
    var user = firebaseRefUrl + '/' + key;

    // Here you can create an array of users that you can bind to a   scope in the controller
});

如果您使用的是谷歌地图。我建议你使用angular-google-maps。 它是一个非常酷的谷歌地图指令,它接收一系列标记和圆圈。因此,当控制器中的$ scope.markers或$ scope.circles发生变化时,它将自动应用于地图而不会产生任何混乱的代码。他们有很好的文档。

这是一个链接: http://angular-ui.github.io/angular-google-maps/