Algorithm 检查经纬度坐标是否位于嵌入式设备中的复杂多边形内?

Algorithm 检查经纬度坐标是否位于嵌入式设备中的复杂多边形内?,algorithm,math,embedded,geometry,gis,Algorithm,Math,Embedded,Geometry,Gis,我需要用户能够在地图上绘制一个复杂的多边形,然后让应用程序检查给定的经度/纬度是否位于该多边形内 我只能找到使用简单x/y笛卡尔坐标系的算法,该坐标系不能补偿地球的曲率 用户在PC上绘制多边形,通过无线电将点传输到嵌入式设备,然后嵌入式设备需要检查给定多边形是否位于其当前位置(从GPS获取) 由于这是一个嵌入式设备,我不能使用大型库,而是需要算法来执行检查自己或一个非常小的库。但是我似乎找不到任何这样的算法。这是我用C#为包含顶点列表的多边形类编写的一个实现。它不考虑地球的曲率。相反,您应该在运

我需要用户能够在地图上绘制一个复杂的多边形,然后让应用程序检查给定的经度/纬度是否位于该多边形内

我只能找到使用简单x/y笛卡尔坐标系的算法,该坐标系不能补偿地球的曲率

用户在PC上绘制多边形,通过无线电将点传输到嵌入式设备,然后嵌入式设备需要检查给定多边形是否位于其当前位置(从GPS获取)


由于这是一个嵌入式设备,我不能使用大型库,而是需要算法来执行检查自己或一个非常小的库。但是我似乎找不到任何这样的算法。

这是我用C#为包含顶点列表的多边形类编写的一个实现。它不考虑地球的曲率。相反,您应该在运行此操作之前将多边形预处理为更小的段

该算法的性能非常好。即使是有数千条边的多边形,在我的桌面上也只需一到两毫秒就可以完成

这段代码已经优化了很多,所以不像psuedo代码那样可读

public bool Contains(地理位置)
{
如果(!Bounds.Contains(位置))
返回false;
var lastPoint=_顶点[_顶点.Length-1];
var isInside=假;
var x=位置。经度;
foreach(顶点中的变量点)
{
var x1=最后一点经度;
var x2=点经度;
var dx=x2-x1;
如果(数学绝对值(dx)>180.0)
{
//我们很可能只是跳过了日期线(如果需要的话,可以进一步验证这一效果)。将数字正常化。
如果(x>0)
{
而(x1<0)
x1+=360;
而(x2<0)
x2+=360;
}
其他的
{
而(x1>0)
x1-=360;
而(x2>0)
x2-=360;
}
dx=x2-x1;
}
如果((x1 x)| |(x1>=x&&x2位置纬度)
isInside=!isInside;
}
最后一点=点;
}
返回isInside;
}

基本思想是找到多边形的所有边,这些边跨越测试点的“x”位置。然后,您会发现其中有多少与延伸到您的点上方的垂直线相交。如果偶数在该点上方交叉,则您位于多边形外部。如果上面有一个奇数,那么你就在里面了。

很好的解释和简单的C代码,你可以根据自己的需要进行转换


如果您有许多不重叠的多边形,请将多边形检查与RTree结合起来,以便快速剔除搜索树。

您要查看的距离是多少?我做过很多类似的工作,如果你说的是相对较小的多边形,比如说小于1000米的多边形,那么相对于标准GPS的精度来说,这些简单的算法会工作得很好。地球曲率对较小距离没有太大影响。请注意,如果您使用GIS,您可能会喜欢这个姐妹站点:@PeterJ我希望在非常大的范围内(数百公里)使用它,但仍然需要非常接近的精度,因为它也将用于小于1公里的分段区域,但请记住,除非片段相隔很远,否则不会有什么不同。例如,一条200公里长的高速公路,一系列相距几公里的路段不会有太大的区别。只有当你说在一个100公里长的多边形上有一条边时,它才会真正产生影响,这在我的经验中是非常罕见的。大多数现实生活中的事情,比如说城市边界在实践中并不那么笔直,所以如果你真的需要的话,有必要考虑一下可能出现的错误。在高速公路上,如果你真的需要精确的航位推算,你可能也需要一些航位推算。谢谢你的回复!使用此算法,您能够达到什么样的精度?考虑到它不能补偿地球的曲率,它是只在半小距离下工作,还是在更大的多边形(比如50公里左右)上也能正常工作?@ChewToy,精度随距离而变化。如果需要更高的精度,请找到球体上两个相邻顶点的中点,然后插入一个新顶点。重复执行此操作,直到多边形在所需公差范围内。或者,修改算法,以考虑地球曲率的方式执行交点测试。非常感谢该算法,条件边界是什么。包含(位置)做什么?@VladimirGhetau,这是一个可选的优化。如果有一个包含多边形中所有点范围的矩形边界框,则在遍历所有顶点之前对该框进行快速测试可能会更快。如果点不在边界内,则它不能在多边形内。Hi Drew,此算法将告诉您随机顶点是否在多边形内。我试图通过删除任何>=和来排除随机顶点实际上是形成多边形的顶点的情况