是否在多边形内找到位置c#

时间:2018-08-28 11:03:52

标签: javascript c# jquery google-maps

我正在寻找一种完美的C#算法,该算法确定是否在多边形内找到位置(经/纬度)。

在Google地图上,我创建了多边形的不同区域。每个区域可以由一组坐标表示。例如,以下是牙买加蒙特哥湾(A区)的坐标(经度,纬度组合):

-77.9531479,18.4565699,-77.9482339,18.4579542,-77.9443393,18.4615874,-77.9399726,18.4627373,-77.933943,18.4653526,-77.931272,18.4652763,-77.9282138,18.46578,-77.9267121,18.4645891,-77.924619,18.4625118,-77.923131,18.4689837,-77.924646,18.4727285,-77.924112,18.4763919,-77.9255882,18.4793735,-77.927573,18.4833522,-77.9234638,18.4888979,-77.92363,18.492311,-77.914973,18.4951459,-77.918355,18.4971759,-77.972733,18.4985953,-77.916291,18.527569,-77.8997725,18.56178,-77.8962851,18.58578,-77.873843,18.517512,-77.8772736,18.5228297,-77.9253387,18.521568,-77.9531479,18.4565699

现在让我们说,我们需要确定坐标为(长/纬):-95.030710、29.148650的牙买加蒙特哥湾日落海滩酒店是否属于A区?

我已经测试了很多可用的算法,但是没有一个能完美地工作。它适用于某些酒店,但不适用于所有酒店。

将寻求任何帮助。

1 个答案:

答案 0 :(得分:1)

我使用绕组编号http://geomalgorithms.com/a03-_inclusion.html

获得成功

第1步:定义多边形的绘制方向。

从根本上讲,多边形是静态的,没有方向。但是,请考虑在一张纸上绘制多边形时执行的移动。您从一个位置开始,然后移动笔为多边形的每一侧画一条线。如果不将笔从纸上移开,则多边形的每一边将全部沿顺时针方向绘制,或者全部沿逆时针方向绘制。

我们可以使用此“方向”来确定多边形的边如何围绕点(顺时针缠绕或逆时针缠绕)缠绕。

对于所讨论的真实多边形(尚未在一个方向上绘制),您认为已绘制哪个方向并不重要,但重要的是将每一边都视为在同一方向上绘制

第2步:将多边形的每一边视为具有两个顶点的单个对象。

如果我们知道多边形的顶点,就可以确定多边形各边的端点。

第3步:确定每边与该点相交的方向(如果两边确实与该点相交)。

使用顺时针缠绕查找多边形是否围绕point的示例:

定义一个counter来跟踪绕组编号。

对于多边形的每一边,取第一顶点vertex1和第二顶点vertex2(这些点定义了每一边的末端)。 如果vertex1.x <point.x,则边开始于point.x的左侧。 如果vertex2.x> point.x,则边在point.x的右侧结束。 如果该边开始于左侧,而结束于右侧,则该线穿过该点。

如果侧面越过point,我们需要确定其越过的方向。 使用顺时针方向作为正方向,该边必须在point上方交叉才能视为正。如果在point的x位置的线的y值大于point的y值,则该线越过point。否则,它会越过该点。

如果从上方穿过,请增加counter。如果在下方穿过,请减小counter

注意:请注意,如果直线从左向右穿过,则正方向会看到该线在该点上方通过,但是如果直线从右向左(绕回该点下方),则正方向会看到该线通过以下的点。正方向是顺时针方向。

现在对多边形的下一面执行相同的操作,其中vertex1将是多边形的下一面vertex2,而新的vertex2是多边形在行驶时的下一角顺时针方向。

对多边形的所有面执行此操作。

最后,您将获得一个带有正,负或0值的计数器。

如果计数器的值为0,则多边形不包含点,否则包含点。

这是因为包含点的多边形始终具有偶数个通过该点的边。无论是2面,还是4面,等等。在这些面中,一半将在该点上方从左到右,而另一半将在该点下方从右到左。

结果为0表示没有边通过该点(因此多边形永远不会穿过该点的轴),或者该多边形在两个方向上(例如,从左到右的点上方)通过该点的一侧,然后从右到左指向上方)。因此,绕组号相互抵消。