首页  >  问答  >  正文

baidu-地图 - 请教一个问题, 百度地图的javascript api 能否用触摸方式动态画一个圆或者矩形?

如题,请教下解决思路。

阿神阿神2771 天前554

全部回复(3)我来回复

  • 怪我咯

    怪我咯2017-04-10 15:35:56

    我自己实现了一下,可以自己在百度地图上随便画图形,基本原理就是,监听touch事件,touchMove,保存当前的经纬度,转化为pixel坐标,重复绘制线段,当touchEnd时,绘制矩形图形。最后会连接首位2点,并判断矩形是否有效,同时如果在画得过程中已经有闭合图形,则终止画图。

    演示地址,需要使用手机浏览测试:

    JS 实现代码:

    var app = app || {};
    
    app.BM = {
        map: false,
        init: function() {
            // 百度地图API功能
            this.map = new BMap.Map("allmap");    // 创建Map实例
            this.map.centerAndZoom(new BMap.Point(116.404, 39.915), 11);  // 初始化地图,设置中心点坐标和地图级别
            this.map.addControl(new BMap.MapTypeControl());   //添加地图类型控件
            this.map.setCurrentCity("北京");          // 设置地图显示的城市 此项是必须设置的
    
            this.map.enableScrollWheelZoom();     //开启鼠标滚轮缩放
            this.map.enableDragging();
        }
    };
    
    // 电子围栏
    // @todo 数据交互部分
    app.Fence = {
        cache_points: [], // 缓存折线数据,取消操作时,重新画图。
    
        polyline:false, // 百度折线覆盖物
        points: [], // 折线数据 [H,H,H,...] H{lat:"",lng:""}
        coordinate: [], // 像素数据 [P,P,...] P{x:"",y:""}
        cur_point: false, 
        cur_pixel: false,
        isOver: false, // 围栏是否已经完成
        cross_at: false, // 相交的点索引  
        state: 0, // 界面状态 0 待设定状态, 1 开始设定, 2 设定完成
    
        polygon: false, // 完成后的栏栅覆盖物
    
        polylineOption: {strokeColor:"blue", strokeWeight:4, strokeOpacity:0.5},
    
        init: function() {
            app.BM.init();      
            this.initClickEvent();
        },
    
        initClickEvent: function() {
            // 设定或取消
            document.getElementById('action').addEventListener('click', this.clickSettingHandler, false);       
            // 确定或重新设定事件监听
            document.getElementById('setok').addEventListener('click', this.setOKHandler, false);
            document.getElementById('reset').addEventListener('click', this.resetHandler, false);
        },
    
        clickSettingHandler: function(){        
            if (app.Fence.state == 0)
            {
                app.Fence.initTouchEvent();
    
                if (app.Fence.polygon){
                    app.BM.map.removeOverlay(app.Fence.polygon);                
                }
    
                app.Fence.resetData();
                app.Fence.state = 1;                                        
    
                app.Fence.setElementHidden('fence_show');           
                app.Fence.setElementDisplay('fence_begin_draw');                    
                document.getElementById('action').innerHTML = "取消"; 
    
            } else {                                                                    
                app.Fence.removeTouchEvent();           
    
                if (app.Fence.polyline) {
                    app.BM.map.removeOverlay(app.Fence.polyline);
                }
    
                app.Fence.resetData();          
                app.Fence.state = 0;                    
    
                if (app.Fence.cache_points) {
                    app.Fence.polygon = new BMap.Polygon(app.Fence.cache_points, app.Fence.polylineOption);
                    app.BM.map.addOverlay(app.Fence.polygon);
                }                                                       
    
                app.Fence.setElementDisplay('fence_show');          
                app.Fence.setElementHidden('fence_begin_draw');
                document.getElementById('action').innerHTML = "设定";                 
            } 
        },
    
        finishDrawing: function(){
            app.Fence.state = 2;
            // 画图完成后立即清除移动
            app.Fence.removeTouchEvent();
    
            app.Fence.setElementHidden('fence_begin_draw');
            app.Fence.setElementDisplay('fence_end_draw');                  
        },
    
        drawPolygon: function(){
            app.BM.map.removeOverlay(app.Fence.polyline);       
            app.Fence.polygon = new BMap.Polygon(app.Fence.points, app.Fence.polylineOption);
            app.BM.map.addOverlay(app.Fence.polygon);
        },
        removeClickEvent: function(){           
            document.getElementById('setok').removeEventListener('click', app.Fence.setOKHandler, false);
            document.getElementById('reset').removeEventListener('click', app.Fence.resetHandler, false);
        },
        setOKHandler: function(){
            app.Fence.state = 0;                
            // 最后画一个多边形polygon                  
            app.Fence.drawPolygon();
    
            app.Fence.setElementDisplay('fence_show');          
            app.Fence.setElementHidden('fence_end_draw');
            document.getElementById('action').innerHTML = "设定";
    
            document.getElementById('setting_state').innerHTML = "电子栏栅设定成功";                
            // 缓存数据
            app.Fence.cache_points = app.Fence.points;  
    
            // @todo 同步数据到服务器
        },  
        // 不满意,重新画图
        resetHandler: function(){           
            app.Fence.state = 1;        
    
            app.BM.map.removeOverlay(app.Fence.polyline);       
            app.Fence.resetData();              
            app.Fence.initTouchEvent();
    
            app.Fence.setElementHidden('fence_end_draw');
            app.Fence.setElementDisplay('fence_begin_draw');            
        },
        // 触摸事件 @important 开始画图时init 画完图后remove
        initTouchEvent: function(){
            app.BM.map.addEventListener("touchstart", app.Fence.touchStartHandler, false);
            app.BM.map.addEventListener("touchend", app.Fence.touchEndHandler, false);        
            app.BM.map.addEventListener("touchmove", app.Fence.touchMoveHandler, false);
        },
        removeTouchEvent: function(){
            app.BM.map.removeEventListener("touchstart", app.Fence.touchStartHandler, false);
            app.BM.map.removeEventListener("touchend", app.Fence.touchEndHandler, false);        
            app.BM.map.removeEventListener("touchmove", app.Fence.touchMoveHandler, false);
        },
        touchStartHandler: function(){
            app.BM.map.disableDragging(); 
            app.Bm.map.disableScrollWheelZoom(); 
        },
        touchEndHandler: function(){        
            // 正确的画完图形  
            if (app.Fence.isOver){
                app.Fence.finishDrawing();          
            } else {
                if (!app.Fence.finalCheckIsCrossed())
                {            
                    var last = app.Fence.points.length - 1;
                    app.Fence.polyline = new BMap.Polyline([app.Fence.points[0], app.Fence.points[last]], app.Fence.polylineOption);  //创建多边形
                    app.BM.map.addOverlay(app.Fence.polyline);
                    app.Fence.finishDrawing();
                }
                else
                {
                    alert("电子栏栅设定错误,请重新设定!");
                    app.BM.map.removeOverlay(app.Fence.polyline);
                    app.Fence.resetData(); 
                    app.Fence.state = 1;
                    app.Fence.setElementHidden('fence_end_draw');
                    app.Fence.setElementDisplay('fence_begin_draw');                
                }   
            }           
            app.BM.map.enableDragging();
            app.BM.map.enableScrollWheelZoom();
        },
        touchMoveHandler: function(e){
            app.Fence.cur_point = e.point;
            app.Fence.cur_pixel = e.pixel;
            app.Fence.points.push(e.point);
            app.Fence.coordinate.push(e.pixel);
    
            if (app.Fence.checkIsCrossed()) 
            {           
                app.Fence.redrawPolyline();
                app.Fence.isOver = true;  
            }           
            else
            {
                if (!app.Fence.isOver) app.Fence.redraw();  
            }   
        },
        checkIsCrossed: function(){
            var last = app.Fence.coordinate.length - 1;
            for (var i = 1; i < last - 2; i++)
            {
                if (last > 5 && app.Fence.intersect(app.Fence.coordinate[last-1], app.Fence.coordinate[last], app.Fence.coordinate[i-1], app.Fence.coordinate[i]))
                {      
                    app.Fence.cross_at = i;
                    return true;                
                }                       
            }       
            return false;
        },
        finalCheckIsCrossed: function(){
            var last = app.Fence.coordinate.length - 1;
            for (var i = 2; i < last - 2; i++)
            {
                if (app.Fence.intersect(app.Fence.coordinate[i-1], app.Fence.coordinate[i], app.Fence.coordinate[0], app.Fence.coordinate[last]))
                {                                                            
                    return true;                
                }                       
            }  
            return false;
        },
        redrawPolyline: function(){                     
            app.Fence.points.splice(0, app.Fence.cross_at);         
            // 重画图形
            if (app.Fence.polyline) {
                app.BM.map.removeOverlay(app.Fence.polyline);           
            }                   
            if (app.Fence.points)
            {
                app.Fence.polyline = new BMap.Polyline(app.Fence.points, app.Fence.polylineOption);  //创建多边形
                app.BM.map.addOverlay(app.Fence.polyline);   //增加多边形    
    
                var last = app.Fence.points.length -1 ;
                app.Fence.polyline = new BMap.Polyline([app.Fence.points[0], app.Fence.points[last]], app.Fence.polylineOption);  //创建多边形
                app.BM.map.addOverlay(app.Fence.polyline);              
            }           
        },
        redraw: function(){
            if (app.Fence.polyline) {           
                app.BM.map.removeOverlay(app.Fence.polyline);           
            }                   
            if (app.Fence.points)
            {
                app.Fence.polyline = new BMap.Polyline(app.Fence.points, app.Fence.polylineOption);  //创建多边形
                app.BM.map.addOverlay(app.Fence.polyline);   //增加多边形        
            }  
        },
        /* 叉积 判断2条线段是否相交 */
        mult: function(a, b, c) {
            return (a.x-c.x)*(b.y-c.y)-(b.x-c.x)*(a.y-c.y);
        },
        /* pa, pb为一条线段两端点 pc, pd为另一条线段的两端点 相交返回true, 不相交返回false*/
        intersect: function(pa, pb, pc, pd) {
            if ( Math.max(pa.x, pb.x)<Math.min(pc.x, pd.x) )
            {
                return false;
            }
            if ( Math.max(pa.y, pb.y)<Math.min(pc.y, pd.y) )
            {
                return false;
            }
            if ( Math.max(pc.x, pd.x)<Math.min(pa.x, pb.x) )
            {
                return false;
            }
            if ( Math.max(pc.y, pd.y)<Math.min(pa.y, pb.y) )
            {
                return false;
            }
            if ( app.Fence.mult(pc, pb, pa)*app.Fence.mult(pb, pd, pa)<0 )
            {
                return false;
            }
            if ( app.Fence.mult(pa, pd, pc)*app.Fence.mult(pd, pb, pc)<0 )
            {
                return false;
            }
            return true;
        },
        resetData: function(){       
            app.Fence.polyline = false;
            app.Fence.points = [];
            app.Fence.coordinate = [];              
    
            app.Fence.isOver = false;
            app.Fence.cur_point = false;
            app.Fence.cur_pixel = false; 
            app.Fence.polygon = false; 
        },
        setElementDisplay:function(id){
            document.getElementById(id).style.display = "block";
        },
        setElementHidden: function(id){
            document.getElementById(id).style.display = "none";
        }
    };
    

    回复
    0
  • 迷茫

    迷茫2017-04-10 15:35:56

    触摸时获取触摸点的经纬度,然后调用api里画圆的方法画圆

    回复
    0
  • ringa_lee

    ringa_lee2017-04-10 15:35:56

    http://developer.baidu.com/map/reference/index.phptitle=Class:%E8%A6%8...百度地图API的Circle类画圆

    回复
    0
  • 取消回复