LBS——地理围栏(C#)

LBS GPS围栏计算 点在围栏内 点与围栏的关系 点与多边形的关系

围栏计算(采用最小外包矩形法+暴力数学计算法)

        /// <summary>
        /// 围栏计算(点是否在围栏内)
        /// </summary>
        /// <param name="latlon">单点坐标</param>
        /// <param name="APoints">坐标集合</param>
        /// <returns></returns>
        public static bool MBR(Gps latlon, List<Gps> APoints)
        {
            if (MBR_zerOne(latlon, APoints))
            {
                return IsPtInPoly(latlon, APoints);//内判断
            }
            else
            {
                return false;//外判断
            }
        }
        /// <summary>
        /// 最小外包法
        /// </summary>
        /// <param name="latlon"></param>
        /// <param name="APoints"></param>
        /// <returns></returns>
        private static bool MBR_zerOne(Gps latlon, List<Gps> APoints)
        {
            double max_lon = APoints.Max(x => x.getWgLon());
            double max_lat = APoints.Max(x => x.getWgLat());
            double min_lon = APoints.Min(x => x.getWgLon());
            double min_lat = APoints.Min(x => x.getWgLat());
            double aLon = latlon.getWgLon();
            double aLat = latlon.getWgLat();
            if (aLon >= max_lon || aLon <= min_lon || aLat >= max_lat || aLat <= min_lat)
            {
                return false;
            }
            else
            {
                return true;
            }
        }
        /// <summary>
        /// 点在围栏内(数学计算方法)
        /// </summary>
        /// <param name="latlon">Gps坐标</param>
        /// <param name="APoints">Gps坐标点集合</param>
        /// <returns></returns>
        private static bool IsPtInPoly(Gps latlon, List<Gps> APoints)
        {
            int iSum = 0, iCount;
            double dLon1, dLon2, dLat1, dLat2, dLon;
            double ALat = latlon.getWgLat();
            double ALon = latlon.getWgLon();
            if (APoints.Count < 3)
                return false;
            iCount = APoints.Count;
            for (int i = 0; i < iCount; i++)
            {
                if (i == iCount - 1)
                {
                    dLon1 = APoints[i].getWgLon();
                    dLat1 = APoints[i].getWgLat();
                    dLon2 = APoints[0].getWgLon();
                    dLat2 = APoints[0].getWgLat();
                }
                else
                {
                    dLon1 = APoints[i].getWgLon();
                    dLat1 = APoints[i].getWgLat();
                    dLon2 = APoints[i + 1].getWgLon();
                    dLat2 = APoints[i + 1].getWgLat();
                }
                //以下语句判断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;
        }

GPS坐标模型

    /// <summary>
    /// 坐标模型
    /// </summary>
    public class Gps
    {
        /// <summary>
        /// 纬度
        /// </summary>
        private double wgLat;
        /// <summary>
        /// 经度
        /// </summary>
        private double wgLon;

        public Gps()
        {
            wgLat = 0;
            wgLon = 0;
        }
        public Gps(double wgLat, double wgLon)
        {
            setWgLat(wgLat);
            setWgLon(wgLon);
        }
        public double getWgLat()
        {
            return wgLat;
        }
        public void setWgLat(double wgLat)
        {
            this.wgLat = wgLat;
        }
        public double getWgLon()
        {
            return wgLon;
        }
        public void setWgLon(double wgLon)
        {
            this.wgLon = wgLon;
        }
        public String toString()
        {
            return wgLat + "," + wgLon;
        }
    }

猜你喜欢

转载自blog.csdn.net/qq_35957944/article/details/85051069
LBS