您的位置:首页 > 编程语言 > C#

如何判断一个指定的经纬度点是否落在一个多边形内

2012-05-04 21:08 351 查看
1、理论支持:如果从需要判断的点出发的一条射线与该多边形的焦点个数为奇数,则该点在此多边形内,否则该点在此多边形外。(射线不能与多边形顶点相交)

2、编程思路:

该程序的思路是从A点出发向左做一条水平射线(平行于x轴,向X轴的反方向),判断与各边是否有焦点。

dLon1, dLon2, dLat1, dLat2分别表示边的起点和终点的经度和纬度(x轴和y轴)。

先判断A点是否在边的两端点d1和d2的水平平行线之间,不在则不可能有交点,继续判断下一条边。

在之间则说明可能与A点向左的射线有交点,接下来利用几何方法得到A点的水平直线与该边交点的x坐标。

然后判断交点的x坐标在A点的左侧还是右侧,左侧则总交点数加一,右侧则不在A点左射线上,继续判断下一条边。

3、原文代码如下(Dephi):
Type

  TMyPoint =
packed
record

    X : double;

    Y : double;

  end;

{*------------------------------------------------------------------------------

  判 断指定的经纬度坐标点是否落在指定的多边形区域内

  @param ALon   指定点的经度

  @param ALat   指定点的纬度

  @param APoints   指定多边形区域各个节点坐标

  @return True 落在范围内 False 不在范围内

------------------------------------------------------------------------------*}
function IsPtInPoly(ALon, ALat: double; APoints:
array
of TMyPoint): Boolean;
var

  iSum, iCount, iIndex: Integer;

  dLon1, dLon2, dLat1, dLat2, dLon: double;
begin

  Result := False;

  if (Length(APoints)
< 3)
then

  begin

    Result := False;

    Exit;

  end;

  iSum :=
0;

  iCount := Length(APoints);

  for iIndex :=0
to iCount
- 1
do

  begin

    if (iIndex
= iCount
- 1)
then

    begin

      dLon1 := APoints[iIndex].X;

      dLat1 := APoints[iIndex].Y;

      dLon2 := APoints[0].X;

      dLat2 := APoints[0].Y;

    end

    else

    begin

      dLon1 := APoints[iIndex].X;

      dLat1 := APoints[iIndex].Y;

      dLon2 := APoints[iIndex
+ 1].X;

      dLat2 := APoints[iIndex
+ 1].Y;

    end;

   //以下语句判断A点是否在边的两端点的水平平行线之间,在则可能有交点,开始判断交点是否在左射线上

    if ((ALat
>= dLat1)
and (ALat < dLat2))
or ((ALat>=dLat2)
and (ALat
< dLat1)) then

    begin

      if (abs(dLat1
- dLat2)
> 0)
then

      begin

       //得到 A点向左射线与边的交点的x坐标:

        dLon := dLon1
- ((dLon1
-dLon2) * (dLat1
-ALat))
/ (dLat1 - dLat2);

       // 如果交点在A点左侧(说明是做射线与 边的交点),则射线与边的全部交点数加一:
        if (dLon
< ALon)
then

          Inc(iSum);

      end;

    end;

  end;

  if (iSum
mod 2
<> 0)
then

    Result := True;
end;

(C#)

public bool IsPtInPoly(double ALon, double ALat, List<Point> APoints)

        {

            int iSum = 0, iCount;

            double dLon1, dLon2, dLat1, dLat2, dLon;

            if (APoints.Count < 3)

                return false;

            iCount = APoints.Count;

            for (int i = 0; i < iCount - 1; i++)

            {

                if (i == iCount - 1)

                {

                    dLon1 = APoints[i].X;

                    dLat1 = APoints[i].Y;

                    dLon2 = APoints[0].X;

                    dLat2 = APoints[0].Y;

                }

                else

                {

                    dLon1 = APoints[i].X;

                    dLat1 = APoints[i].Y;

                    dLon2 = APoints[i + 1].X;

                    dLat2 = APoints[i + 1].Y;

                }

                //以下语句判断A点是否在边的两端点的水平平行线之间,在则可能有交点,开始判断交点是否在左射线上

                if (((ALat >= dLat1) && (ALat < dLat2)) || ((ALat >= dLat2) && (ALat < dLat1)))

                {

                    if (Math.Abs(dLat1 - dLat2) > 0)

                    {

                        //得到 A点向左射线与边的交点的x坐标:

                        dLon = dLon1 - ((dLon1 - dLon2) * (dLat1 - ALat)) / (dLat1 - dLat2);

                        // 如果交点在A点左侧(说明是做射线与 边的交点),则射线与边的全部交点数加一:

                        if (dLon < ALon)

                            iSum++;

                    }

                }

            }

            if (iSum % 2 != 0)

                return true;

            return false;

        }
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  integer function 编程 c#