Ruby 如何从中心圆的半径找到所有重叠圆?

Ruby 如何从中心圆的半径找到所有重叠圆?,ruby,mongodb,mongodb-query,mongoid3,Ruby,Mongodb,Mongodb Query,Mongoid3,如何在mongo shell中执行相交或重叠查询-哪些圆与我的搜索区域重叠在中仅与中心位置相关,但不包括搜索范围内其他圆的半径 蒙戈: # My bad conception: var search = [[30, 30], 10] db.places.find({circle : {"$within" : {"$center" : [search]}}}) 现在我只能得到中心点内的圆位于圆的搜索区域内: 红宝石: 我创建了带有附加位置(特殊索引)和半径的示例数据,而不是圆,因为mongodb

如何在mongo shell中执行相交或重叠查询-哪些圆与我的搜索区域重叠<代码>在中仅与中心位置相关,但不包括搜索范围内其他圆的半径

蒙戈:

# My bad conception:
var search = [[30, 30], 10]
db.places.find({circle : {"$within" : {"$center" : [search]}}})
现在我只能得到中心点内的圆位于圆的搜索区域内:

红宝石:

我创建了带有附加位置(特殊索引)和半径的示例数据,而不是圆,因为mongodb地理索引不支持圆:

{ "_id" : 1, "name" : "a", "circle" : [ [ 5, 5 ], 40 ], "latlng" : [ 5, 5 ], "radius" : 40 }
{ "_id" : 2, "name" : "b", "circle" : [ [ 10, 10 ], 5 ], "latlng" : [ 10, 10 ], "radius" : 5 }
{ "_id" : 3, "name" : "c", "circle" : [ [ 20, 20 ], 5 ], "latlng" : [ 20, 20 ], "radius" : 5 }
{ "_id" : 4, "name" : "d", "circle" : [ [ 30, 30 ], 50 ], "latlng" : [ 30, 30 ], "radius" : 50}
{ "_id" : 5, "name" : "e", "circle" : [ [ 80, 80 ], 30 ], "latlng" : [ 80, 80 ], "radius" : 30}
{ "_id" : 6, "name" : "f", "circle" : [ [ 80, 80 ], 20 ], "latlng" : [ 80, 80 ], "radius" : 20}
所需的查询结果:

{ "_id" : 1, "name" : "a", "circle" : [ [ 5, 5 ], 40 ], "latlng" : [ 5, 5 ], "radius" : 40 }
{ "_id" : 3, "name" : "c", "circle" : [ [ 20, 20 ], 5 ], "latlng" : [ 20, 20 ], "radius" : 5 }
{ "_id" : 4, "name" : "d", "circle" : [ [ 30, 30 ], 50 ], "latlng" : [ 30, 30 ], "radius" : 50}
{ "_id" : 5, "name" : "e", "circle" : [ [ 80, 80 ], 30 ], "latlng" : [ 80, 80 ], "radius" : 30}
下面的解决方案假设我获取所有行,然后在ruby端过滤半径,但它只返回:

{ "_id" : 4, "name" : "d", "circle" : [ [ 30, 30 ], 50 ], "latlng" : [ 30, 30 ], "radius" : 50}

我不熟悉mongodb,但我假设在[[x,y]中,r]值意味着

x:轴x上的中心值。 y:轴y上的中心值。 r:圆半径

假设你有一个圆S,这是你的搜索和一个随机圆a。然后你可以计算两个圆的中心(S.center和a.center)之间的距离,看看它是否低于两个圆半径加起来的距离(S.r+a.r)

def(a、b)之间的距离
((b.first-a.first)**2+(b.last-a.last)**2)**0.5
结束
元素=[{u id:1,名称:“a”,圆圈:[[5,5],40]},
{{u id:2,名字:“b”,圆圈:[[10,10],5]},
{{u id:3,名字:“c”,圆圈:[[20,20],5]},
{{u id:4,名字:“d”,圆圈:[[30,30],50]},
{u id:5,名字:“e”,圆圈:[[80,80],30]},
{{u id:6,名字:“f”,圆圈:[[80,80,20]}]
搜索=[[30,30],10]
elements.select do | elem | circle=elem[:circle]
(circle.first,search.first)1,:name=>a,:circle=>[[5,5],40]之间的距离
#{:_id=>3,:name=>c,:circle=>[[20,20],5]}
#{:_id=>4,:name=>d,:circle=>[[30,30,50]}

不幸的是,mongo目前没有直接查询重叠对象的功能,只能查询对象内的点

@oldergod的回答描述了计算两个圆是否重叠的算法

以下是基于该计算在外壳中的解决方法:

function distance(a, b) {
    return Math.pow(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2), 0.5);
}
在插入到集合“圆圈”中的样本数据上:

> db.circle.find().forEach(
    function(c) {  
        if ( (distance(c.latlng, search.latlng) < c.radius + search.radius) ) 
          {   
               print(c.name); 
          } 
    } )
a
c
d
> 
>db.circle.find().forEach(
函数(c){
if((距离(c.latlng,search.latlng) 

我想你想要回“a”、“c”和“d”。“e”与您的圆圈不重叠。我无法在第一次回答时检查我的代码。检查过了,现在修好了。你可以自己看。正如Asya Kamsky所说,你只期望a、c和d。否则你给我们的信息是错误的。事实上我在“e”上犯了一个错误。这两种解决方案都很好,但现在我看到,在目前的情况下,我们将使用ruby。我担心在较大的记录上,我的程序可能不会运行得太快,所以我也询问了mongo的方法。非常感谢。请注意,截至2.4(2013年3月)$geoIntersects运算符可用于为GeoJSON和2dSphere索引提供此功能。请注意,截至2.4(2013年3月)$geoIntersects运算符可用于为GeoJSON和2dSphere索引提供此功能。
function distance(a, b) {
    return Math.pow(Math.pow(a[0] - b[0], 2) + Math.pow(a[1] - b[1], 2), 0.5);
}
> db.circle.find().forEach(
    function(c) {  
        if ( (distance(c.latlng, search.latlng) < c.radius + search.radius) ) 
          {   
               print(c.name); 
          } 
    } )
a
c
d
>