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;
                }
    
            }
  • 相关阅读:
    vue实现短信验证码登录
    使用vue3.0和element实现后台管理模板
    vue导出excel数据表格功能
    Vue2.0-token权限处理
    vue2.0实现购物车功能
    Vue图片懒加载之lazyload插件使用
    H5 canvas 绘图
    前端常见跨域请求 方法
    Html5 @media + css3 媒体查询
    Java面试之RabbitMQ
  • 原文地址:https://www.cnblogs.com/yushuo/p/9304471.html
Copyright © 2011-2022 走看看