zoukankan      html  css  js  c++  java
  • 判断点在不在多边形范围内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;
                }
    

     }

    再三须慎意,第一莫欺心
  • 相关阅读:
    RxJava开发精要3-向响应式世界问好
    RxJava开发精要2-为什么是Observables?
    RxJava开发精要1-从.NET到RxJava
    为你的应用加速
    Android最佳性能实践(二)——分析内存的使用情况
    Android最佳性能实践(一)——合理管理内存
    Android 性能优化之使用MAT分析内存泄露问题
    给 Android 开发者的 RxJava 详解
    优化 Android 线程和后台任务开发
    资深谷歌安卓工程师对安卓应用开发的建议
  • 原文地址:https://www.cnblogs.com/otsf/p/10161011.html
Copyright © 2011-2022 走看看