zoukankan      html  css  js  c++  java
  • 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;
                }
    
            }
  • 相关阅读:
    LeetCode12: 整数转罗马数字
    LeetCode11:盛最多水的容器
    LeetCode09:判断回文数
    LeetCode08:字符串转换成整数
    LeetCode04:寻找中位数
    LeetCode03:无重复字符的最长子串
    《JAVA编程思想》第四版 PDF 下载 中文版和英文版 高清PDF扫描带书签
    XML
    异常
    委托和匿名方法和Lambda表达式
  • 原文地址:https://www.cnblogs.com/yushuo/p/9304471.html
Copyright © 2011-2022 走看看