将多边形存储在 MongoDB

Store Polygons in MongoDB

我正在 Java 中构建一个应用程序,我必须在 MongoDB 中存储 GeoJson 多边形,然后我必须查询以检查一个点与它相交的多边形数量$geoIntersects.

我有几个关于 GeoJson 多边形的问题,但我没有在网上找到答案。

标准 (https://www.rfc-editor.org/rfc/rfc7946) 说:

A linear ring MUST follow the right-hand rule with respect to the area it bounds, i.e., exterior rings are counterclockwise, and holes are clockwise.

但我做了一个测试,我将 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. 如果我保存的点列表有交叉点会怎样?我做了一个测试,我保存了一个像图片中的多边形,但看起来查询不与任何点相交。如果多边形有交点,我应该在保存之前检查吗?我该怎么做?

谢谢!

经过一番搜索和测试,我想我找到了答案。我找到 this guide that took me to this ticket that eventualy sent me to this blog post.

  1. How do I check if a given polygon is in the right order?

关于点的顺序的事情是它定义了多边形的哪一侧是您感兴趣的一侧,内部还是外部。 “MongoDB 确定性地选择“两者中最小的”区域。”,除非您使用“大多边形”,在其中定义您使用的顺序。

如果你真的想检查顺序,我发现这个函数是从这个 validator:

中获取的
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. Is there a java library that will check if my polygon is valid?
  2. What happens if the list of points that I'm saving has intersecctions?

其实不需要这个

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

如果该字段没有索引,那些错误的多边形(自相交或开放)将不会与任何点相交。

更多信息

旧的和 obsolete GeoJson specifications didn't talk about order of coordinates, but the new one 一样。

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

我不知道这是否可以使 Mongo 改变将线的较小部分视为多边形的默认设置,但直到 MongoDB 的 4.0 版,它仍然有效这样。