C# 计算地图上某个坐标点的是否在多边形内

Posted lonelyxmas

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C# 计算地图上某个坐标点的是否在多边形内相关的知识,希望对你有一定的参考价值。

原文:C# 计算地图上某个坐标点的是否在多边形内

这个方法引用自群友的博客 https://www.xiaofengyu.com/?p=143

使用百度地图的时候,常常会用到判断一个点是否在一个多边形的范围内,该方法用到的是射线法,

通过修改Javascrpit的代码过来的,射线法的意思就是从点出发和任意的一边的交叉点数为奇数则为在改区域内,

参考文档http://erich.realtimerendering.com/ptinpoly/

 

    public class location
    {
        public double lat;
        public double lng;
    }

    public class GpsPolygonHelper
    {
        /// <summary>
        /// 坐标点是否在多边形内判断
        /// </summary>
        /// <param name="point"></param>
        /// <param name="pts"></param>
        /// <returns></returns>
        public static bool isPointInPolygon(location point, List<location> pts)
        {

            //检查类型
            if (point == null || pts == null)
                return false;

            var N = pts.Count;
            var boundOrVertex = true; //如果点位于多边形的顶点或边上,也算做点在多边形内,直接返回true
            var intersectCount = 0; //cross points count of x 
            var precision = 2e-10; //浮点类型计算时候与0比较时候的容差
            location p1, p2; //neighbour bound vertices
            var p = point; //测试点
            p1 = pts[0]; //left vertex        
            for (var i = 1; i <= N; ++i)
            {
//check all rays            
                if (p.lat.Equals(p1.lat) && p.lng.Equals(p1.lng))
                {
                    return boundOrVertex; //p is an vertex
                }

                p2 = pts[i % N]; //right vertex            
                if (p.lat < Math.Min(p1.lat, p2.lat) || p.lat > Math.Max(p1.lat, p2.lat))
                {
//ray is outside of our interests                
                    p1 = p2;
                    continue; //next ray left point
                }

                if (p.lat > Math.Min(p1.lat, p2.lat) && p.lat < Math.Max(p1.lat, p2.lat))
                {
//ray is crossing over by the algorithm (common part of)
                    if (p.lng <= Math.Max(p1.lng, p2.lng))
                    {
//x is before of ray                    
                        if (p1.lat == p2.lat && p.lng >= Math.Min(p1.lng, p2.lng))
                        {
//overlies on a horizontal ray
                            return boundOrVertex;
                        }

                        if (p1.lng == p2.lng)
                        {
//ray is vertical                        
                            if (p1.lng == p.lng)
                            {
//overlies on a vertical ray
                                return boundOrVertex;
                            }
                            else
                            {
//before ray
                                ++intersectCount;
                            }
                        }
                        else
                        {
//cross point on the left side                        
                            var xinters =
                                (p.lat - p1.lat) * (p2.lng - p1.lng) / (p2.lat - p1.lat) +
                                p1.lng; //cross point of lng                        
                            if (Math.Abs(p.lng - xinters) < precision)
                            {
//overlies on a ray
                                return boundOrVertex;
                            }

                            if (p.lng < xinters)
                            {
//before ray
                                ++intersectCount;
                            }
                        }
                    }
                }
                else
                {
//special case when ray is crossing through the vertex                
                    if (p.lat == p2.lat && p.lng <= p2.lng)
                    {
//p crossing over p2                    
                        var p3 = pts[(i + 1) % N]; //next vertex                    
                        if (p.lat >= Math.Min(p1.lat, p3.lat) && p.lat <= Math.Max(p1.lat, p3.lat))
                        {
//p.lat lies between p1.lat & p3.lat
                            ++intersectCount;
                        }
                        else
                        {
                            intersectCount += 2;
                        }
                    }
                }
                p1 = p2; //next ray left point
            }

            if (intersectCount % 2 == 0)
            {
//偶数在多边形外
                return false;
            }
            else
            {
                //奇数在多边形内
                return true;
            }

        }

 

以上是关于C# 计算地图上某个坐标点的是否在多边形内的主要内容,如果未能解决你的问题,请参考以下文章

C# 计算地图上某个坐标点的到多边形各边的距离

C# 计算地图上某个坐标点的到多边形各边的距离

百度地图选择一个不规则区域,判断某个坐标点是否在这个区域内。该怎么去实现!

百度地图API 地图圈区域并计算坐标点是否在区域内

光线投射算法(如何计算一个坐标点是不是在一个多边形内)

如何判断一个地理坐标点在一个地理坐标多边形中?