如何判断一个指定的经纬度点是否落在一个多边形内
2011-10-25 14:29
1151 查看
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; } //解题思想用射线法 //该题思想是向由点P向x正方向发射一个射线,穿过多边形线段上的个数为奇数则在多边形内,偶数则在多边形外 //具体方法是:点的Y值大于等于多边形上某个线段的最小值且小于该线段上的最大值,在该线段上取一个y值为点P.y的点P1。如果P.x<P1.x ,则计数器加1,若计数器为奇数则在多边形内,若为偶数则在多边形外 private bool PointInFences(point pnt1, point[] fencePnts) { int j=0, cnt = 0; for (int i = 0; i < fencePnts.Length; i++) { j = (i == fencePnts.Length - 1) ? 0 : j + 1; if ((fencePnts[i].y!=fencePnts[j].y)&&(((pnt1.y >= fencePnts[i].y) && (pnt1.y < fencePnts[j].y)) || ((pnt1.y >= fencePnts[j].y) && (pnt1.y < fencePnts[i].y))) && (pnt1.x < (fencePnts[j].x - fencePnts[i].x) * (pnt1.y - fencePnts[i].y) / (fencePnts[j].y - fencePnts[i].y) + fencePnts[i].x)) cnt++; } return (cnt%2>0)?true:false; } 我的一哥们写的比较精炼的一个小程序。原程序没有考虑到点P与多边形上的某个平行x轴的线段的两个端点三点共线问题。我加了一个先决判断条件就是到线段不平行于x轴。 该方法构思巧妙: 1、向X轴正方向发射射线,先判断是否与多边形的线段相交,若相交点的X值大于P的x值,则计数器加1. 2、通过大于等于线段两个端点的最小Y值,小于线段两个端点的最大Y值,判断出射线与线段是否相交。——避免了P在线段的延长线上的情况对计算结果的困扰。 |
相关文章推荐
- 如何判断一个指定的经纬度点是否落在一个多边形区域内?
- 如何判断一个指定的经纬度点是否落在一个多边形内
- 在Android里如何判断一个指定的经纬度点是否落在一个多边形区域内
- 如何判断一个指定的经纬度点是否落在一个多边形区域内?
- opencv中如何判断一个点是否在一个多边形中
- 如何判断一个点是否在一个多边形内部
- 如何判断一个点是否在一个多边形内部(转)
- 如何判断一个点是否在多边形内部还是外部
- java实现判断一个经纬度坐标是否在一个多边形内(经自己亲测)
- 如何判断一个点是否在一个多边形内部(有向面积)
- Java中如何判断一个日期字符串是否是指定的格式
- 如何判断一个点是否在一个多边形内部+三角形有向面积公式
- 如何判断一个点是否在多边形内?
- [转]如何判断一个点是否在一个多边形内部
- SQL查询如何判断要查找的字符是否在一个指定集合中
- 如何判断一个点是否在多边形内部ne?
- 如何判断一个指定的目录是否为空
- 利用百度api判断已知经纬度的一个点是否在多边形内
- 如何判断一个点是否在多边形内部?
- indexOf() 如何判断一个元素在指定数组中是否存在? 找出指定元素出现的所有位置? indexOf()方法 是正序查找,lastIndexOf()是倒叙查找