将多边形存储在MongoDB中

时间:2019-01-30 18:18:50

标签: java mongodb geojson

我正在用Java构建一个应用程序,必须将GeoJson多边形存储在MongoDB中,然后我必须查询以检查一个Point,该Point与$geoIntersects相交的多边形中有多少。

我有一些关于GeoJson多边形的问题,但我没有在线找到答案。

标准(https://tools.ietf.org/html/rfc7946)说:

  

线性环必须相对于其边界区域遵循右手法则,即外环是逆时针方向,孔是顺时针方向。

但是我进行了一次测试,将两个圆分别保存为多边形,一个顺时针,另一个逆时针,如果查询内部的点,则在两种情况下都可以正常工作。

# 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

谢谢!

1 个答案:

答案 0 :(得分:2)

经过一些搜索和测试,我想我已经找到了答案。我发现this guide带我去了this ticket,最终把我送到了this blog post

  
      
  1. 如何检查给定的多边形是否顺序正确?
  2.   

关于点的顺序的事情是,它定义了多边形的最中间的一侧,即您在内部或外部都感兴趣的多边形。 “除非您使用“大多边形”来定义要使用的顺序,否则“ 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. 是否有一个Java库会检查我的多边形是否有效?
  2.   
  3. 如果我要保存的点列表有交叉点,会发生什么情况?
  4.   

实际上没有必要。

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

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

更多信息

旧的规范和obsolete GeoJson并未讨论坐标的顺序,但是new one却在讨论。

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

我不知道这是否可以使Mongo更改,将线的较小部分视为多边形是默认的,但是直到MongoDB 4.0版,它仍然可以这种方式工作。