百度地图——判断一个点是否在一个区域内?

       由于目前的一个项目涉及离线地图,经过查找资料论证,最终还是决定采用百度地图。在项目过程中,遇到一个比较实际的问题:怎么判断地图上的一个点(经纬坐标下)在一个多边形区域内?

      由于我采用的是百度地图JavaScript API v2.0接口,同时由于要做的是离线地图,百度地图离线版有一些功能函数是不能用的。针对上述问题,在网上查资料发现,百度的BMapLib.GeoUtils里面有一个函数isPointInPolygon可以用于解决这个问题,但是很遗憾,我用的接口函数版本并不能用这个函数,所以我研究了一下,经过修改写了一个满足条件的函数。下面是代码部分:

function isInsidePolygon(point, polygon)
{  
    if(!(point instanceof BMap.Point) || !(polygon instanceof BMap.Polygon))
    {
        return false;
    }
    var polygonBounds = polygon.getBounds();
    if(!polygonBounds.containsPoint(point))
    {
        return false;
    }

    var pts = polygon.getPath();
        
    var N = pts.length;
    var boundOrVertex = true; 
    var intersectCount = 0;
    var precision = 2e-10; 
    var 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.equals(p1))
        {
            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))
        {
            if(p.lng <= Math.max(p1.lng, p2.lng))
            {                  
                if(p1.lat == p2.lat && p.lng >= Math.min(p1.lng, p2.lng))
                {
                    return boundOrVertex;
                }
                   
                if(p1.lng == p2.lng)
                {                      
                    if(p1.lng == p.lng)
                    {
                        return boundOrVertex;
                    }
                    else
                    {
                          ++intersectCount;
                    } 
                }
                else
                {                      
                    var xinters = (p.lat - p1.lat) * (p2.lng - p1.lng) / (p2.lat - p1.lat) + p1.lng;                 
                    if(Math.abs(p.lng - xinters) < precision)
                    {
                        return boundOrVertex;
                    }
                            
                    if(p.lng < xinters)
                    {
                        ++intersectCount;
                    } 
                }
            }
        }
        else
        {             
            if(p.lat == p2.lat && p.lng <= p2.lng)
            {            
                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))
                {
                    ++intersectCount;
                }
                else
                {
                    intersectCount += 2;
                }
            }
        }            
        p1 = p2;//next ray left point
    }
        
    if(intersectCount % 2 == 0)
    {//偶数在多边形外
        return false;
    } 
    else 
    { //奇数在多边形内
            return true;
    }   
}  

参考资料:

http://api.map.baidu.com/library/GeoUtils/1.2/docs/symbols/BMapLib.GeoUtils.html(百度开发平台)

http://lbsyun.baidu.com/cms/jsapi/reference/jsapi_reference.html(百度地图JavaScript API v2.0类参考)

  • 1
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值