2013-06-03 35 views
4

在mysql中,我使用了haversine公式来查询附近的对象。Firebase查询附近的对象

使用这个公式 式

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地球的半径:指定纬度经度
  • 25:25英里

在Firebase中, 我可以像MySQL中那样存储用户经验吗? 创建一个标记表。 ID,纬度,经度列,然后用公式查询

更新

我要问,什么是查询附近使用这个公式火力的方式。

回答

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

+0

什么他的建议是,你把经度优先级标记列表,并通过纬度优先另一个列表。然后,您查询两个列表,并查看列表相交的位置。 –

3

嘿,我刚刚完成建设用火力和GeoFire实时谷歌地图这篇文章。 GeoFire非常酷且易于使用。它允许你使用lon lat和radius来查询。它返回一个可用于查询您的Firebase数据库的密钥。您可以在创建geoFire对象时设置密钥,以满足您的需求。它通常是一个可以用来获取与该距离相关联的对象的引用。

这里是geoFire链接: https://github.com/firebase/geofire-js

下面是一个例子使用案例:

你有一个经度纬度,你得到了使用导航:

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

如果你正在使用谷歌地图。我建议你使用角度谷歌地图。 它是一个非常酷的谷歌地图指令,需要一系列标记和圆圈。因此,当控制器中的$ scope.markers或$ scope.circles发生变化时,它将自动应用到地图上,而不会有任何杂乱的代码。他们有很好的文档。

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

+0

[您发布了与另一个问题完全相同的答案](https://stackoverflow.com/a/29310763)。请不要在多个问题上发布相同的答案。如果问题重复,请选择最好的答案,然后将其他答案标记为重复。如果它们不重复,则必须[*针对每个问题调整回答*](http://meta.stackexchange.com/q/104227/311792)。我承认我不是这些技术方面的专家,但看起来这不是对被问到的问题的直接回答。他不问如何查询经纬度。 (另外,我知道这是旧的,但它被标记...) –