WithCoderWithCoderWithCoder

百度地图路书加echarts实现轨迹回放和速度图表仪表盘联动

    在之前的文章中介绍了百度地图路书实现轨迹回放的功能。本文在此基础上,实现路书轨迹回放和echart图表速度仪表盘的联动。

    基本思路:

    1. 实现百度地图路书功能(在轨迹点中随机生成速度speed字段)

    2. 重写路书对象move方法,在此方法中实时通知外部当前速度

    3. 创建echarts速度仪表盘,根据实时速度绘制仪表盘

    实现:

    1. 实现百度地图路书功能

    这一步不再细说,可以参考文章“百度地图路书轨迹回放

    2. 重写路书对象move方法,在此方法中实时通知外部当前速度   

    在重写方法的最后,调用方法,并传递当前点速度(完整代码参考文末)

    curSpeed(arrPois[me.i].speed);

    3. 创建echarts速度仪表盘,根据实时速度绘制仪表盘

    初始化仪表对象speedChart,通过仪表的timeTicket,实时修改仪表的值    

    speedChart.timeTicket = setInterval(function() {
            options.series[0].data[0].value = carspeed;
            speedChart.setOption(options);
        }, 100);

    运行结果:

    1-200414135106104.png

    完整代码:    

<html lang="en">

<head>
    <meta charset="utf-8" />
    <title>路书</title>
    <style type="text/css">
        body,
        html {
            width100%;
            height100%;
            margin0;
            font-family"微软雅黑";
        }

        #map_canvas {
            width100%;
            height500px;
        }

        #result {
            width100%
        }

        #speedbox {
            width200px;
            height200px;
            positionabsolute;
            top50px;
            right50px;
        }
    </style>
    <script src="http://api.map.baidu.com/api?v=2.0&ak=百度地图密钥"></script>
    <script type="text/javascript" src="http://api.map.baidu.com/library/LuShu/1.2/src/LuShu_min.js"></script>
    <script src="https://cdn.bootcss.com/echarts/4.7.0/echarts.js"></script>
</head>

<body>
    <div id="map_canvas"></div>
    <div id="speedbox"></div>
    <div id="result"></div>
    <button id="run">开始</button>
    <button id="stop">停止</button>
    <button id="pause">暂停</button>
    <button id="hide">隐藏信息窗口</button>
    <button id="show">展示信息窗口</button>
    <script>
        var map = new BMap.Map('map_canvas');
        map.enableScrollWheelZoom();
        map.centerAndZoom(new BMap.Point(116.40439.915), 13);
        var lushu;
        // 实例化一个驾车导航用来生成路线
        var drv = new BMap.DrivingRoute('北京', {
            onSearchComplete: function(res) {
                if (drv.getStatus() == BMAP_STATUS_SUCCESS) {
                    var plan = res.getPlan(0);
                    // 根据搜索结果,生成路径轨迹点
                    var arrPois = [];
                    for (var j = 0j < plan.getNumRoutes(); j++) {
                        var route = plan.getRoute(j);
                        arrPois = arrPois.concat(route.getPath());
                    }
                    // 给每个点加上随机速度
                    arrPois.forEach(function(p) {
                        Object.assign(p, {
                            speed: Math.round(Math.random() * 120 * 10) / 10
                        });
                    });

                    // 画轨迹
                    map.addOverlay(new BMap.Polyline(arrPois, { strokeColor: '#111' }));
                    map.setViewport(arrPois);

                    BMapLib.LuShu.prototype._move = function(initPostargetPoseffect) {
                        var pointsArr = [initPostargetPos]; //点数组
                        var me = this,
                            //当前的帧数
                            currentCount = 0,
                            //步长,米/秒
                            timer = 10,
                            step = this._opts.speed / (1000 / timer),
                            //初始坐标
                            init_pos = this._projection.lngLatToPoint(initPos),
                            //获取结束点的(x,y)坐标
                            target_pos = this._projection.lngLatToPoint(targetPos),
                            //总的步长
                            count = Math.round(me._getDistance(init_postarget_pos) / step);
                        //显示折线
                        //如果想显示小车走过的痕迹,放开这段代码就行
                        // this._map.addOverlay(
                        //     new BMap.Polyline(pointsArr, {
                        //         strokeColor: "#bfa",
                        //         strokeWeight: 5,
                        //         strokeOpacity: 0.5
                        //     })
                        // ); // 画线
                        //如果小于1直接移动到下一点
                        if (count < 1) {
                            me._moveNext(++me.i);
                            return;
                        }
                        me._intervalFlag = setInterval(function() {
                            //两点之间当前帧数大于总帧数的时候,则说明已经完成移动
                            if (currentCount >= count) {
                                clearInterval(me._intervalFlag);
                                //移动的点已经超过总的长度
                                if (me.i > me._path.length) {
                                    return;
                                }
                                //运行下一个点
                                me._moveNext(++me.i);
                            } else {
                                currentCount++;
                                var x = effect(init_pos.xtarget_pos.xcurrentCountcount),
                                    y = effect(init_pos.ytarget_pos.ycurrentCountcount),
                                    pos = me._projection.pointToLngLat(new BMap.Pixel(xy));
                                //设置marker
                                if (currentCount == 1) {
                                    var proPos = null;
                                    if (me.i - 1 >= 0) {
                                        proPos = me._path[me.i - 1];
                                    }
                                    if (me._opts.enableRotation == true) {
                                        me.setRotation(proPosinitPostargetPos);
                                    }
                                    if (me._opts.autoView) {
                                        if (!me._map.getBounds().containsPoint(pos)) {
                                            me._map.setCenter(pos);
                                        }
                                    }
                                }
                                //正在移动
                                me._marker.setPosition(pos);
                                //设置自定义overlay的位置
                                me._setInfoWin(pos);

                                // 实时通知外部当前速度
                                curSpeed(arrPois[me.i].speed);
                            }
                        }, timer);
                    };

                    // 创建路书
                    lushu = new BMapLib.LuShu(maparrPois, {
                        defaultContent: "",//"从天安门到百度大厦"
                        autoView: true,//是否开启自动视野调整,如果开启那么路书在运动过程中会根据视野自动调整
                        icon: new BMap.Icon('./images/car.png'new BMap.Size(5226), { anchor: new BMap.Size(2713) }),
                        speed: 4500,
                        enableRotation: true,//是否设置marker随着道路的走向进行旋转
                        landmarkPois: [
                            { lng: 116.314782lat: 39.913508html: '加油站'pauseTime: 2 },
                            { lng: 116.315391lat: 39.964429html: '高速公路收费<div><img src="//map.baidu.com/img/logo-map.gif"/></div>'pauseTime: 3 },
                            { lng: 116.381476lat: 39.974073html: '肯德基早餐'pauseTime: 2 }
                        ]
                    });
                }
            }
        });
        var start = new BMap.Point(116.40484439.911836);
        var end = new BMap.Point(116.30810240.056057);
        drv.search(startend);
        //绑定事件
        $("run").onclick = function() {
            lushu.start();
        }
        $("stop").onclick = function() {
            lushu.stop();
        }
        $("pause").onclick = function() {
            lushu.pause();
        }
        $("hide").onclick = function() {
            lushu.hideInfoWindow();
        }
        $("show").onclick = function() {
            lushu.showInfoWindow();
        }

        function $(element) {
            return document.getElementById(element);
        }

        // 实时速度
        var carspeed = 0;
        function curSpeed(car_speed) {
            carspeed = car_speed;
        }

        // 速度表
        var speedChart = echarts.init(document.getElementById("speedbox"));
        options = {
            tooltip: {
                formatter: "{a} <br/>{b} : {c}"
            },
            series: [{
                title: {
                    // 其余属性默认使用全局文本样式,详见TEXTSTYLE
                    fontWeight: 'bolder',
                    fontSize: 14,
                    color: '#222',
                    fontStyle: 'normal',
                    offsetCenter: [0'70%']
                },
                splitLine: {            // 分隔线
                    length: 20,         // 属性length控制线长
                    lineStyle: {        // 属性lineStyle(详见lineStyle)控制线条样式
                        color: 'auto'
                    }
                },
                itemStyle: {
                    normal: {
                        color: '#333'
                    }
                },
                name: '行驶速度',
                type: 'gauge',
                min: 0,
                max: 120,
                radius: '80%',
                axisLine: {            // 坐标轴线
                    lineStyle: {
                        color: [[1 / 1.5'green'], [1 / 1.5'red'], [1'red']],
                        width: 15,
                        shadowColor: '#666'//默认透明
                        shadowBlur: 20
                    }
                },
                detail: {
                    color: '#222',
                },
                data: [{
                    value: 0,
                    name: '超速上限:' + 120 + 'Km/h',
                }]
            }
            ]
        };
        // 根据实时速度,修改图表的值
        speedChart.timeTicket = setInterval(function() {
            options.series[0].data[0].value = carspeed;
            speedChart.setOption(options);
        }, 100);
    </script>
</body>

</html>

欢迎分享交流,转载请注明出处:WithCoder » 百度地图路书加echarts实现轨迹回放和速度图表仪表盘联动