我将一些坐标传递给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]
]]
}
}
}
});
错误:
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
}
更新
我添加了一个蛮力方法的图像。
但是这有一些问题,通过所有这些循环可能会非常昂贵。假设最多50个点将是大约1275次操作。
同样处理0/180度坐标的环绕可能是一个挑战。
无论如何,我不想花一整天的时间,我甚至可以处理一个不涉及环绕条件的解决方案。
希望这个地方有一个很好的算法,我可以直播(可能有一些奇特的技术术语)。
如果有更有效的方法,那么蛮力前瞻也会很棒。
答案 0 :(得分: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]
]]
答案 1 :(得分:2)
正如我在评论中提到的,查询空间数据的更好工具是使用PostGIS。
例如,PostGIS有ST_validReason()来查找polygon的问题和要修复的st_makevalid,但如果这不是一个选项,那么我将使用shapely
python库{{shapely
创建一个可用于PHP脚本的服务3}}
https://github.com/Toblerity/Shapely
Shapely的第一个前提是Python程序员应该能够 在RDBMS之外执行PostGIS类型几何操作
当然{{1}}是一种流行的工具,您应该从更有经验的用户那里获得有关StackOverflow或gis.stackexchange.com的未来帮助
我认为你试图解决的问题并不像听起来那么简单。
所以我会执行以下步骤:
1找到如何使用匀称
类似的问题: http://toblerity.org/shapely/manual.html
2创建一个简单的php服务,将查询详细信息传递给python脚本
3 Shapely不会阻止创建无效多边形,但在操作时会引发异常。所以基本上在这样的例外情况下,我会从第1步调用脚本。
如果这只是一个查询,我只会使用QGIS软件(导入点为CSV,创建一个新的shapefile图层(类型为多边形),并使用数字顶点编辑插件)
<强>更新强>
我认为多边形应该由创建它的工具修复,因此在这种情况下,应该是用户。也许您可以通过从不同角度查看来解决该问题,如果形状来自用户并且在应用程序中的GoogleMap中绘制,则可能在绘图期间不强制执行交叉。
还找到了这个Splitting self-intersecting polygon only returned one polygon in shapely in Python(排序点和创建没有交叉点的多边形)