将多边形存储在MongoDB中

3
我正在使用Java构建一个应用程序,需要将GeoJson多边形存储到MongoDB中,然后查询以检查一个点与多少个多边形相交$geoIntersects。我有几个关于GeoJson多边形的问题,在网上没有找到答案。标准(https://www.rfc-editor.org/rfc/rfc7946)指出:线性环必须遵循右手规则,即外部环逆时针,内部环顺时针。但是我进行了一个测试,将2个圆保存为多边形,一个顺时针,另一个逆时针,如果我查询一个在内部的点,两种情况都可以正常工作。
# Clockwise:
"polygon": {
    "type": "Polygon",
    "coordinates": [
      [
        [-58.3816, -34.51386847158805 ], [-58.317506306149276, -34.531008005363724 ], [-58.27783822235179, -34.57589660852675 ], [-58.27776882904558, -34.631415496391675 ], [-58.317394025120045, -34.6763584216405 ], [-58.3816, -34.69353152841195 ], [-58.445805974879946, -34.6763584216405 ], [-58.48543117095441, -34.631415496391675 ], [-58.4853617776482, -34.57589660852675 ], [-58.44569369385072, -34.531008005363724 ], [-58.3816, -34.51386847158805 ] ]
    ]
  }
# Counterclockwise
  "polygon": {
    "type": "Polygon",
    "coordinates": [
      [
        [-58.3816, -34.51386847158805 ], [-58.44569369385072, -34.531008005363724 ], [-58.4853617776482, -34.57589660852675 ], [-58.48543117095441, -34.631415496391675 ], [-58.445805974879946, -34.6763584216405 ], [-58.3816, -34.69353152841195 ], [-58.317394025120045, -34.6763584216405 ], [-58.27776882904558, -34.631415496391675 ], [-58.27783822235179, -34.57589660852675 ], [-58.317506306149276, -34.531008005363724 ], [-58.3816, -34.51386847158805 ] ]
    ]
  }
  1. 如何检查给定的多边形是否按正确顺序排列?
  2. 有没有Java库可以检查我的多边形是否有效?例如,检查第一个和最后一个点是否匹配以及逆时针方向等。类似于http://geojsonlint.com/,但是使用Java库。
  3. 如果我保存的点列表存在交叉点会发生什么?我进行了一个测试,保存了一个像图片中那样的多边形,但似乎查询与任何点都不相交。我应该在保存之前检查多边形是否具有交叉点吗?如何做到这一点?

enter image description here

谢谢!


https://dev59.com/eJTfa4cB1Zd3GeqPWdcy - oriash
1个回答

3
经过一番搜索和测试,我认为我找到了答案。我发现了这篇指南,它带我去了这个票,最终带我去了这篇博客文章
  1. 如何检查给定的多边形是否按正确顺序排列?

关于点的顺序,它定义了您感兴趣的多边形的哪一侧是内部或外部。除非您使用“Big Polygon”并定义所使用的顺序,“MongoDB确定性地选择面积“两者中最小的那个”。

如果您真的想检查顺序,我找到了这个函数,它来自于这个验证器

function isRingClockwise (coords) {
    var area = 0;
    if (coords.length > 2) {
        var p1, p2;
        for (var i = 0; i < coords.length - 1; i++) {
            p1 = coords[i];
            p2 = coords[i + 1];
            area += rad(p2[0] - p1[0]) * (2 + Math.sin(rad(p1[1])) + Math.sin(rad(p2[1])));
        }
    }
    return area >= 0;
}
  1. 有没有一个Java库可以检查我的多边形是否有效?
  2. 如果我保存的点列表有交叉会发生什么?

其实并不需要。

如果该字段具有2d索引,则Mongo不会让您保存自相交或未封闭的多边形。它将抛出异常:WriteConcernException:Write failed with error code 16755 and error message' Can't extract geo keys:,然后是像Edges 1 and 3 cross之类的内容。

如果该字段没有索引,则这些错误的多边形(自相交或未封闭)将与任何点都不相交。

更多信息

旧版和已过时的GeoJson规范没有提到坐标顺序,但新版有所不同。这里是旧版,这里是新版。

我找到的链接日期早于新规范。

我不知道这是否会使Mongo更改其默认设置,以便将线的较小部分视为多边形,但在MongoDB 4.0版本之前,它仍然是这样工作的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接