PHP/Mongo geoJSON循环无效

Rob*_*Rob 29 php mongodb geojson

我将一些坐标传给mongo进行地理搜索.如果坐标不相交(例如图8),它可以正常工作.但当两条线相交时,就会给出loop is not valid.有没有办法找到交叉点并将所有这些循环分开?

注意可能有很多.

编辑:我添加了示例查询和错误.请注意,我理解它为什么会发生,我只是想知道是否有一些已知的方法将这些循环分成单独的多边形(某些算法或Mongo内).

查询:

db.items.find({
    "address.location": {
        "$geoWithin": {
            "$geometry": {
                "type": "Polygon",
                "coordinates": [[
                    [-97.209091, 49.905691],
                    [-97.206345, 49.918072],
                    [-97.178879, 49.919399],
                    [-97.165146, 49.907903],
                    [-97.164459, 49.892865],
                    [-97.180939, 49.889326],
                    [-97.197418, 49.895077],
                    [-97.200165, 49.902596],
                    [-97.203598, 49.919399],
                    [-97.216644, 49.928682],
                    [-97.244797, 49.927356],
                    [-97.255096, 49.913209],
                    [-97.209091, 49.905691]
                ]]
            }
        }
    }
});
Run Code Online (Sandbox Code Playgroud)

错误:

Error: error: {
    "waitedMS" : NumberLong(0),
    "ok" : 0,
    "errmsg" : "Loop is not valid: [
            [ -97.209091, 49.905691 ]
            [ -97.206345, 49.918072 ],
            [ -97.17887899999999, 49.919399 ],
            [ -97.16514599999999, 49.907903 ],
            [ -97.16445899999999, 49.892865 ],
            [ -97.180939, 49.889326 ],
            [ -97.197418, 49.895077 ],
            [ -97.200165, 49.902596 ],
            [ -97.203598, 49.919399 ],
            [ -97.216644, 49.928682 ],
            [ -97.24479700000001, 49.927356 ],
            [ -97.25509599999999, 49.913209 ],
            [ -97.209091, 49.905691 ]
        ]
        Edges 1 and 7 cross.
        Edge locations in degrees: [-97.2063450, 49.9180720]-[-97.1788790, 49.9193990]
        and [-97.2001650, 49.9025960]-[-97.2035980, 49.9193990]
    ",
    "code" : 2
}
Run Code Online (Sandbox Code Playgroud)

UPDATE

我添加了一个蛮力方法的图像.

多边形切片

  • 基本上它是在相交上展望未来.
  • 如果找到一个,它会交换点,使其保持在循环内.
  • 它会将切断作为某个队列中的"起点".
  • 当一个向前看并发现它自己的起点时,我们有一个循环.
  • 然后继续通过"起始点"队列,直到它为空.
  • 新的多边形集应包含所有单独的循环(理论上).

但是有一些问题,通过所有这些循环可能会非常昂贵.假设最多50个点将是大约1275次操作.

在0/180度坐标上处理环绕也是一个挑战.

无论如何,我不想花一整天时间,我甚至可以处理一个不涉及环绕条件的解决方案.

希望有一个很好的算法,这个我已经可以弹出(可能有一些花哨的技术术语).

如果有更有效的方法,那么蛮力前瞻也会很棒.

Roh*_*mar 4

这是因为您的坐标相同,导致多边形形状出现异常: [-97.1788790, 49.9193990 ] 和 [-97.2035980, 49.9193990 ]。在您的代码中删除或更改任何重复的坐标,

"coordinates": [[
    [-97.209091, 49.905691],
    [-97.206345, 49.918072],
    [-97.178879, 49.919399], // this line
    [-97.165146, 49.907903],
    [-97.164459, 49.892865],
    [-97.180939, 49.889326],
    [-97.197418, 49.895077],
    [-97.200165, 49.902596],
    [-97.203598, 49.919399], // and this one
    [-97.216644, 49.928682],
    [-97.244797, 49.927356],
    [-97.255096, 49.913209],
    [-97.209091, 49.905691]
]]
Run Code Online (Sandbox Code Playgroud)