2014-04-30 32 views
1

我有一个包含许多文档的mongodb集合。这些文档的一个属性是一个二维点云集合,我目前正在查询以找到任何点位于多边形内的文档等。这非常出色。Mongodb - 查找提供的多边形的最近点

我现在想要做的是什么,我不确定它实际上是否能够在每个点云集合中找到最接近的点到提供的多边形。

要给出一个可视化文件,想象一下这些文件包含一个代表道路隧道扫描的二维点云。我希望能够提供一个代表卡车的多边形并找到最接近它的点。这将是一个文件基础上,所以在英语中我们会问以下内容:

result = nearest point to <Polygon> in document <Document X>.<CloudPoints> 

奖金 - 如果有可能,以能够与某种方式连接这个结果返回的所有文件,这甚至会更好,虽然我怀疑这远远超出了Mongo设计使用的正常界限。

编辑:

根据要求,这里是一个例子。考虑一下我们收集的文件如下所示。在这个例子中,我有很多文件都有一些坐标集合,这些坐标集合代表了碰巧受到保护的鸟巢的位置,并附有关于公司有多接近地面工程的法律等。

BirdsNests > 
     _id : 1234 
     _Description : North town pipe replacement 2016 
     _NestLocations > 
         [100, 150] 
         [140, 180] 
         [165. 134] 
         etc... 

如果我提供一个多边形,我想知道的是,坐标集合中的最近点是该多边形。注意:这应该是它的任何表面,如。这将允许人们提供代表拟议工作地点的多边形,并让Mongo报告哪个巢位置最接近站点参数。

enter image description here

这将一个文件的基础上要求初步所以我们会要求文件1234,什么是集合中最接近坐标到此提供的多边形。

请注意所有使用的例子都是纯虚构的。

+0

你可以添加一些数据和例子,你想要达到什么? – aks

+0

@aks根据要求更新。 –

+0

鉴于上面的图片,左边的绿点似乎不是最接近我的点......只要确保我正确理解了您的问题,对于给定多边形边上的所有点坐标,您想要找到最接近绿点? (在你的照片中,它似乎是左上角的那个) –

回答

3

我不认为mongo支持将一个多边形传递给$near运算符。所以我的第一个猜测是尝试找到位于多边形边上的每个点的最接近的文档。不幸的是,你将无法比较每个结果之间的距离,因为mongo不会返回这些信息。 (也许你可以自己计算过滤所有由mongo返回的候选人吗?)

因此,给定一个位于多边形边缘的点,可以找到最接近的文档。

但是在你的情况下,从多边形的右边返回最接近的文档而不是从多边形的左边找到最接近的文档?

或者您可以计算多边形的重心并使用该点找到最接近的文档。

enter image description here

+0

谢谢。这也是我自己的结论,通过$ near函数是不可能的,但是想看看那些具有更多mongo经验的人是否知道更好。我们目前有一个应用程序端解决方案来做到这一点,但我正在调查是否有一种“更好”的方式来作为查询。回到我认为的绘图板。 –

0

我还需要找到的最近点到面,但我使用少量的在全球范围内的点,和我的多边形建筑。

由于我点之间的距离比我的多边形的尺寸要大得多,我刚刚发现使用技巧多边形的几何中心这里找到了类似的情况

Center of gravity of a polygon

对于任何人,这里是寻找几何中心的JS代码:

//// 
// Get the geometric center (centroid) of a polygon 
// coordinates: 3d array in the format of a geoJSON Polygon's coordinates 
//  http://geojson.org/geojson-spec.html#polygon 
// only the exterior ring is used 
// the polygon should be closed (last point same as first) 
exports.getPolygonCentroid = function(coordinates) { 
    var secondFactor; 
    var centroidX = 0; 
    var centroidY = 0; 
    var area = 0; 
    var points = coordinates[0]; //only use the exterior ring 

    for(var pt = 0; pt<points.length-1; pt++) { 
     secondFactor = (points[pt][0] * points[pt+1][1]) - (points[pt+1][0] * points[pt][1]); 
     centroidX += (points[pt][0] + points[pt+1][0]) * secondFactor; 
     centroidY += (points[pt][1] + points[pt+1][1]) * secondFactor; 
     area += secondFactor; 
    } 
    area = area/2; 

    centroidX = centroidX/6/area; 
    centroidY = centroidY/6/area; 

    return [centroidX, centroidY]; 
};