Mongodb - 查找提供的多边形的最近点

时间:2014-04-30 13:41:54

标签: mongodb geospatial

我有一个包含许多文档的mongodb集合。这些文档的属性是一个2D点云集合,我目前正在查询它以查找任何点位于多边形内等的文档。这样可以很好地工作。

我现在要做的是,我不确定它是否真的可以找到每个点云集合中最近的点到提供的多边形。

为了提供可视化,想象一下,文档中包含一个2D点云,代表了对公路隧道的扫描。我希望能够提供一个代表卡车的多边形,并找到最接近它的点。这将是基于文档的,所以在英语中我们会问以下内容:

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...

如果我提供多边形,我想知道的是,Coordinates集合中最近的点是该多边形。注意:这应该是它的任何表面,如。这将允许人们提供表示建议工作站点的多边形,并让Mongo报告哪个嵌套最接近站点参数。

enter image description here

这将首先在文档的基础上请求,因此我们将要求提供文档1234,集合中与此提供的多边形最接近的坐标是什么。

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

2 个答案:

答案 0 :(得分:3)

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

因此,如果位于多边形的边缘,您可以找到最接近的文档。

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

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

enter image description here

答案 1 :(得分: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];
};