我传入一些坐标给mongo做地理搜索。如果坐标不相交(例如数字8),它可以正常工作。但是当两条线相交时,就得到了loop is not valid
。有没有办法找到交集,把这些环路分开?
注意可以有很多
EDIT:我添加了示例查询和错误。请注意,我明白为什么会发生这种情况,我只是想知道是否有一些已知的方法将这些循环分割成单独的多边形(一些算法或在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]
]]
}
}
}
});
错误:
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
}
我添加了一个蛮力方法的图像。
多边形切片
- 基本上它是在交叉路口做提前检查。
- 如果它找到一个,它会交换点,以便它保持在循环中。
- 它将在某些队列中添加cut作为"起点"。
- 当向前看并找到它自己的起点时,我们有一个循环。
- 然后继续通过"起始点"队列,直到它为空。
- 新的多边形集应该包含所有单独的循环(理论上)。
这也有一些问题,通过所有这些循环可能会变得相当昂贵。假设最多50个点大约是1275个操作。
同时处理0/180度坐标上的绕身也可能是一个挑战。
无论如何,我不想花一整天的时间在这上面,我甚至可以处理一个不处理环绕条件的解决方案。
希望在某个地方已经有一个很好的算法,我可以直接进入(可能有一些花哨的技术术语)。
如果有比暴力破解更有效的方法就好了。
这是因为你的坐标是相同的,在多边形形状中产生了一个异常:[-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]
]]
正如我在评论中提到的,查询空间数据的更好工具是使用PostGIS。
例如PostGIS有ST_validReason()来查找多边形的问题和st_makevalid来修复,但如果这不是一个选项,那么我会创建一个服务提供给你的PHP脚本与shapely
python库https://github.com/Toblerity/Shapely
shape的第一个前提是Python程序员应该能够在RDBMS之外执行PostGIS类型的几何操作
当然shapely
是一个流行的工具,你应该得到未来的帮助在StackOverflow或gis.stackexchange.com从更有经验的用户
我认为你正在努力解决的问题并不像听起来那么微不足道。
那么我将执行以下步骤:
1查找如何使用shape
相似的问题:分割自相交多边形在Python中只返回一个多边形
2创建一个简单的PHP服务,将查询细节传递给python脚本
3 shape不会阻止无效多边形的创建,但是当它们被操作时将引发异常。所以基本上在这种异常情况下,我会从步骤1调用脚本。
如果这只是一个查询,我会使用QGIS软件(导入点为CSV,创建一个新的shapefile层(多边形类型),并使用数值顶点编辑插件)
我认为多边形应该由创建它的工具固定,所以在这种情况下,它应该是一个用户。也许你可以通过从不同的角度看来解决这个问题如果形状来自用户并且是在你的app的GoogleMap中绘制的也许可以在绘制时强制没有交集。
也找到了这个绘制多边形(排序点和创建多边形没有交集)