• 如何利用百度地图JSAPI画带箭头的线?


       百度地图JSAPI提供两种绘制多折线的方式,一种是已知多折线经纬度坐标串通过AddOverlay接口进行添加;另一种是通过在地图上鼠标单击进行绘制(鼠标绘制工具条库)。目前这两种方式只能绘制多折线,并不能同时绘制线的箭头,以下介绍如何在线的拐点同时绘制箭头,以供参考。最终效果如下:

    1. 绘制箭头方法:

     上图中,线段AB是通过JSAPI画线方式添加的,只要绘制出CBD就可以实现箭头效果。为了灵活绘制箭头,需要用户自定义箭头的长度(r)和角度(angle)。

        实现步骤如下:

         变量定义:pixelStart: 线的一端屏幕坐标,pixelEnd:线的箭头端屏幕坐标;r:选取多长距离绘制箭头(单位像素,并不是CB对应的箭头的长度,而是红色线段对应的距离);angle:箭头线(CB或者DB)与AB的夹角。

         1) 首先要将AB两点的经纬度坐标转换成屏幕坐标。
         2) 然后根据AB两点屏幕坐标以及r长度,计算绿色小绿点的屏幕坐标pixelTem。

         3) 然后根据B点、小绿点的屏幕坐标及angle角度,计算出C,D两点的屏幕坐标。

         4) 利用map的坐标转换方法,将C,D两点的屏幕坐标转成经纬度表示的坐标。

         5) 利用画线方法,绘制CBD多折线。

          备注:思路很简单,主要是计算小绿点、C,D的屏幕坐标麻烦。楼主计算这些点的公式均来自与初中数学公式,就不再赘述直接上代码了。

         完整代码如下:

    <!DOCTYPE html>  
    <html>  
    <head>  
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />  
    <style type="text/css">  
    body, html,#allmap { 100%;height: 100%;overflow: hidden;margin:0;}  
    #l-map{height:100%;78%;float:left;border-right:2px solid #bcbcbc;}  
    #r-result{height:100%;20%;float:left;}  
    </style>  
    <script type="text/javascript" src="http://api.map.baidu.com/api?v=1.4"></script>  
    <title>折线</title>  
    </head>  
    <body>  
    <div id="allmap"></div>  
    </body>  
    </html>  
    <script type="text/javascript">  
    var map = new BMap.Map("allmap");  
    var point = new BMap.Point(116.404, 39.915);  
    map.centerAndZoom(point, 15);  
    map.addControl(new BMap.NavigationControl());  
    map.enableScrollWheelZoom();  
      
      
    var polyline = new BMap.Polyline([  
      //new BMap.Point(116.399, 39.910),  
      new BMap.Point(116.405, 39.920),  
      new BMap.Point(116.425,39.91936),  
      new BMap.Point(116.415,39.93936),  
    // new BMap.Point(116.415,39.92936),  
    ], {strokeColor:"blue", strokeWeight:3, strokeOpacity:0.5});  
    map.addOverlay(polyline);  
    addArrow(polyline,10,Math.PI/7);  
      
    function addArrow(polyline,length,angleValue){ //绘制箭头的函数  
    var linePoint=polyline.getPath();//线的坐标串  
    var arrowCount=linePoint.length;  
    for(var i =1;i<arrowCount;i++){ //在拐点处绘制箭头  
    var pixelStart=map.pointToPixel(linePoint[i-1]);  
    var pixelEnd=map.pointToPixel(linePoint[i]);  
    var angle=angleValue;//箭头和主线的夹角  
    var r=length; // r/Math.sin(angle)代表箭头长度  
    var delta=0; //主线斜率,垂直时无斜率  
    var param=0; //代码简洁考虑  
    var pixelTemX,pixelTemY;//临时点坐标  
    var pixelX,pixelY,pixelX1,pixelY1;//箭头两个点  
    if(pixelEnd.x-pixelStart.x==0){ //斜率不存在是时  
        pixelTemX=pixelEnd.x;  
        if(pixelEnd.y>pixelStart.y)  
        {  
        pixelTemY=pixelEnd.y-r;  
        }  
        else  
        {  
        pixelTemY=pixelEnd.y+r;  
        }     
        //已知直角三角形两个点坐标及其中一个角,求另外一个点坐标算法  
        pixelX=pixelTemX-r*Math.tan(angle);   
        pixelX1=pixelTemX+r*Math.tan(angle);  
        pixelY=pixelY1=pixelTemY;  
    }  
    else  //斜率存在时  
    {  
        delta=(pixelEnd.y-pixelStart.y)/(pixelEnd.x-pixelStart.x);  
        param=Math.sqrt(delta*delta+1);  
      
        if((pixelEnd.x-pixelStart.x)<0) //第二、三象限  
        {  
        pixelTemX=pixelEnd.x+ r/param;  
        pixelTemY=pixelEnd.y+delta*r/param;  
        }  
        else//第一、四象限  
        {  
        pixelTemX=pixelEnd.x- r/param;  
        pixelTemY=pixelEnd.y-delta*r/param;  
        }  
        //已知直角三角形两个点坐标及其中一个角,求另外一个点坐标算法  
        pixelX=pixelTemX+ Math.tan(angle)*r*delta/param;  
        pixelY=pixelTemY-Math.tan(angle)*r/param;  
      
        pixelX1=pixelTemX- Math.tan(angle)*r*delta/param;  
        pixelY1=pixelTemY+Math.tan(angle)*r/param;  
    }  
      
    var pointArrow=map.pixelToPoint(new BMap.Pixel(pixelX,pixelY));  
    var pointArrow1=map.pixelToPoint(new BMap.Pixel(pixelX1,pixelY1));  
    var Arrow = new BMap.Polyline([  
        pointArrow,  
     linePoint[i],  
        pointArrow1  
    ], {strokeColor:"blue", strokeWeight:3, strokeOpacity:0.5});  
    map.addOverlay(Arrow);  
    }  
    }  
    </script>  

    android里的代码 

    /**
         * 添加方向箭头
         * 
         * @param pts 经纬度列表 
         * @param length 箭头长度 
         * @param angleValue 箭头和主线的夹角   度
         */
        private void addArrow(List<LatLng> pts,int length,double angleValue)
        {
            LatLng startLatLng = pts.get(pts.size()-37);
            LatLng endLatLng = pts.get(pts.size()-4);
            Point screenStart = mBaiduMap.getProjection().toScreenLocation(startLatLng);
            Point screenEnd = mBaiduMap.getProjection().toScreenLocation(endLatLng);
            System.out.println("addArrow screenStart.x:"+screenStart.x+" screenEnd.y:"+screenEnd.y);
            if(null == screenStart || null == screenEnd)
            {
                return ;
                
            }
            double angle = angleValue;//angleValue * Math.PI / 180;////箭头和主线的夹角 
            double delta=0; //主线斜率,垂直时无斜率
            double param=0; //代码简洁考虑 , 斜率的平方根
            double screenTemX,screenTemY;//临时点坐标
            double screenX,screenY,screenX1,screenY1;  //箭头两个点 
            
            if((screenEnd.x-screenStart.x) == 0) //线路在屏幕上是垂直,斜率不存在是时
            {
                screenTemX = screenEnd.x;
                if(screenEnd.y>screenStart.y)
                {
                    screenTemY = screenEnd.y-length;
                }else {
                    screenTemY = screenEnd.y+length;
                }
                //已知直角三角形两个点坐标及其中一个角,求另外一个点坐标算法
    //            screenX = screenTemX-Math.round(length*Math.tan(angle));
    //            screenX1 = screenTemX+Math.round(length*Math.tan(angle));
                screenX = screenTemX-length*Math.tan(angle);
                screenX1 = screenTemX+length*Math.tan(angle);
                screenY = screenY1 = screenTemY;
            }
            else //斜率存在时
            {
                delta =  (screenEnd.y-screenStart.y)/(screenEnd.x-screenStart.x);
                param = Math.sqrt(delta*delta+1);
                
                if((screenEnd.x-screenStart.x)<0)//第二,第三象限
                {
                    screenTemX = screenEnd.x+length/param;
                    screenTemY = screenEnd.y+delta*length/param;
                }else //第一,第四象限
                {
                    screenTemX = screenEnd.x-length/param;
                    screenTemY = screenEnd.y-delta*length/param;
                }
                
                //已知直角三角形两个点坐标及其中一个角,求另外一个点坐标算法 
    //            screenX = screenTemX+Math.round(Math.tan(angle)*length*delta/param);
    //            screenY = screenTemY-Math.round(Math.tan(angle)*length/param);
    //            
    //            screenX1 = screenTemX-Math.round(Math.tan(angle)*length*delta/param);
    //            screenY1 = screenTemY+Math.round(Math.tan(angle)*length/param);
                screenX = screenTemX+Math.tan(angle)*length*delta/param;
                screenY = screenTemY-Math.tan(angle)*length/param;
                
                screenX1 = screenTemX-Math.tan(angle)*length*delta/param;
                screenY1 = screenTemY+Math.tan(angle)*length/param;
                
                Point pointArrow = new Point(Math.round((float)screenX),Math.round((float)screenY));
                Point pointArrow1 = new Point(Math.round((float)screenX1),Math.round((float)screenY1));
    //            Math.round((float)screenX1),Math.round((float)screenY1)
                
                LatLng latArrow = mBaiduMap.getProjection().fromScreenLocation(pointArrow);
                LatLng latArrow1 = mBaiduMap.getProjection().fromScreenLocation(pointArrow1);
                
                List<LatLng> arrowList = new ArrayList<LatLng>();
                arrowList.add(latArrow);
                arrowList.add(endLatLng);
                arrowList.add(latArrow1);
                
                OverlayOptions arrowLine = new PolylineOptions()
                .points(arrowList)
                .color(0xAAFF0000)
                .width(5)
                .visible(true);
    
                mBaiduMap.addOverlay(arrowLine);
                
            }
        }

    (出处http://blog.csdn.net/baidulbs/article/details/8571961)

  • 相关阅读:
    无法将类型“XXX”隐式转换为“XXX[]”(Cannot implicitly convert type 'XXX' to 'XXX[]')
    VS2010验证时出错。HRESULT = '8000000A'
    Linux Command Tips
    RealVNC 使用手册
    PL/SQL Developer自动补全SQL技巧
    Install dnsutils(dig, nslookup, host) On iPhone
    asp.net压缩图片
    Discuz论坛密码加密方式详解
    三种SQL分页法效率分析
    Mysql数据库服务器配置文件/etc/my.cnf的详细配置
  • 原文地址:https://www.cnblogs.com/longhs/p/4180524.html
Copyright © 2020-2023  润新知