openlayers 3 实现车辆轨迹回放


先上效果:
这里写图片描述

利用 openlayers 3地图的 postcompose 事件监听地图的重绘

注意:此代码是我在Vue 的methods 里面写的测试方法,并不能直接运行,请在理解的基础上测试。
vm 为vue的this对象 注释已经很丰富了,先做个备份,后期会编辑加入一点详解。

实现代码:
html:

    <div id="menu">
            <label for="speed" style="font-weight: bold;">
                运动速度:&nbsp;
                <input id="speed" type="range" min="1" max="20" step="1" value="10" />
            </label>
            <button id="start-animation">
                开始运动
            </button>
     </div>
     <!-- 注:此代码仅为上面速度条和按钮-->

核心代码:

startMove:function () {
                var vm=this;
                var map=vm.map;
                vm.clearOverlayers("beijing_sq");

                //中间站
                var stops=[
                    [12909554.6597,4933234.84552],   //14
                    [12909824.6852,4931594.7854],    //43
                    [12910026.8837,4930523.89946],   //63
                    [12910870.563,4929357.26511]     //85
                ];

                var stopMakers = new Array();

                for(var i=0;i<4;i++){
                    var s = new ol.Feature({
                        type: 'stop',
                        geometry: new ol.geom.Point(stops[i])
                    });
                    stopMakers.push(s);
                }


                var Coordinates=vm.path;

                //将离散点构建成一条折线
                var route = new ol.geom.LineString(Coordinates);
                //获取直线的坐标
                var routeCoords = route.getCoordinates();
                var routeLength = routeCoords.length;

                var routeFeature = new ol.Feature({
                    type: 'route',
                    geometry: route
                });
                var geoMarker = new ol.Feature({
                    type: 'geoMarker',
                    geometry: new ol.geom.Point(routeCoords[0])
                });
                var startMarker = new ol.Feature({
                    type: 'icon',
                    geometry: new ol.geom.Point(routeCoords[0])
                });
                var endMarker = new ol.Feature({
                    type: 'icon',
                    geometry: new ol.geom.Point(routeCoords[routeLength - 1])
                });

                var styles = {
                    'route': new ol.style.Style({
                        stroke: new ol.style.Stroke({
                            width: 6,
                            color: '#F2C841'
                        }),
                        fill:new ol.style.Fill({
                            color:"#F6E3A3"
                        })
                    }),
                    /*'icon': new ol.style.Style({
                        image: new ol.style.Icon({
                            anchor: [0.5, 1],
                            src: require()
                        })
                    }),*/
                    'geoMarker': new ol.style.Style({
                            /*image: new ol.style.Circle({
                                radius: 7,
                                snapToPixel: false,
                                fill: new ol.style.Fill({ color: 'black' }),
                                stroke: new ol.style.Stroke({
                                    color: 'white',
                                    width: 2
                                })
                            })*/
                            image: new ol.style.Icon({
                                src: require('../../assets/map/left_red_car.png'),
                                rotateWithView: false,
                                rotation: -Math.atan2(routeCoords[0][1]-routeCoords[1][1], routeCoords[0][0]-routeCoords[1][0]),
                                scale:0.3,
                            })
                        }),
                    'stop':new ol.style.Style({
                        image:new ol.style.Circle({
                            radius:10,
                            snapToPixel:false,
                            fill:new ol.style.Fill({ color:'red'}),
                            stroke:new ol.style.Stroke({
                                color:'white',
                                width:2
                            })
                        })
                    })
                };

                var animating = false;
                var speed, now;
                var speedInput = document.getElementById('speed');
                var startButton = document.getElementById('start-animation');

                var vectorLayer = new ol.layer.Vector({
                    id:'carLayer',
                    source: new ol.source.Vector({
                        features: [routeFeature, geoMarker, startMarker, endMarker,stopMakers[0],stopMakers[1],stopMakers[2],stopMakers[3]]
                    }),
                    style: function (feature) {
                        //如果动画是激活的就隐藏geoMarker
                        if (animating && feature.get('type') === 'geoMarker') {
                            return null;
                        }
                        return styles[feature.get('type')];
                    }
                });

                //var center = ol.proj.fromLonLat([115.981,40.451]);

                map.addLayer(vectorLayer);

                // 要素移动
                var moveFeature = function (event) {
                    var vectorContext = event.vectorContext;   //HTML5 Canvas context,ol.render.canvas.Immediate的对象
                    var frameState = event.frameState;        //freme 的状态
                    if (animating) {
                        var elapsedTime = frameState.time - now;    //elapsedTime  已过时间
                        //通过增加速度,来获得lineString坐标
                        var index = Math.round(speed * elapsedTime / 1000);   //已经走了多少个点

                        //console.log("#########",routeCoords[index]);

                        if (index >= routeLength) {
                            stopAnimation(true);
                            return;
                        }

                        //fixme ---------------
                        if( index < 14){
                            flashFeature(0);
                        }
                        if( index == 14){
                            changeStyle(0, 1);
                        }

                        if(index > 14 && index <43){
                            flashFeature(1);
                        }
                        if(index == 43){
                            changeStyle(1, 2);
                        }


                        if(index > 43 && index <63){
                            flashFeature(2);
                        }
                        if(index == 63){
                            changeStyle(2, 3);
                        }

                        if(index > 63 && index <85){
                            flashFeature(3);
                        }
                        if(index == 85){
                            changeStyle(3, 3);
                        }
                        //fixme--------------------

                        var dx,dy,rotation,carStyle;
                        if(routeCoords[index] && routeCoords[index+1]){
                            dx=routeCoords[index][0]-routeCoords[index+1][0];
                            dy=routeCoords[index][1]-routeCoords[index+1][1];
                            rotation = Math.atan2(dy,dx);
                            //console.log("***********",rotation);

                            carStyle= new ol.style.Style({
                                image: new ol.style.Icon({
                                    src: require('../../assets/map/left_red_car.png'),
                                    rotateWithView: false,
                                    rotation: -rotation,
                                    scale:0.3,
                                })
                            });
                            var currentPoint = new ol.geom.Point(routeCoords[index]);  //当前点
                            var feature = new ol.Feature(currentPoint);
                            //Render a feature into the canvas.
                            // Note that any zIndex on the provided style will be ignored - features are rendered immediately in the order that this method is called.
                            // If you need zIndex support, you should be using an ol.layer.Vector instead
                            vectorContext.drawFeature(feature, carStyle);
                        }
                    }
                    //继续动画效果
                    map.render();
                };

                function changeStyle(previous,next) {
                    //console.log(stopMakers[previous]);
                    stopMakers[previous].setStyle(new ol.style.Style({
                        image: new ol.style.Circle({
                            radius: 10,
                            snapToPixel: false,
                            fill: new ol.style.Fill({color: 'green'}),
                            stroke: new ol.style.Stroke({
                                color: 'white',
                                width: 2
                            })
                        })
                    }));
                }

                var colors=['red','green'];
                var colorIndex=0;
                function flashFeature(index) {
                    var color;
                    colorIndex++;
                    colorIndex=colorIndex % 30;

                    if(colorIndex < 15){
                        color=colors[0];
                    }else {
                        color = colors[1];
                    }
                    stopMakers[index].setStyle(new ol.style.Style({
                        image: new ol.style.Circle({
                            radius: 10,
                            snapToPixel: false,
                            fill: new ol.style.Fill({
                                color: color
                            }),
                            stroke: new ol.style.Stroke({
                                color: 'white',
                                width: 2
                            })
                        })
                    }));
                }

                function startAnimation() {
                    if (animating) {
                        stopAnimation(false);
                    } else {
                        animating = true;
                        now = new Date().getTime();           /** 开始时的时间*/
                        speed = speedInput.value;
                        startButton.textContent = '结束运动';
                        //隐藏geoMarker
                        geoMarker.setStyle(null);
                        //设置显示范围
                        //map.getView().setCenter(center);
                        map.on('postcompose', moveFeature);    /** postcompose事件-- 地图渲染时都会触发   */
                        map.render();
                    }
                }

                /**
                 * @param {boolean}结束动画
                 */
                function stopAnimation(ended) {
                    animating = false;
                    startButton.textContent = '开始运动';

                    //如果动画取消就开始动画
                    var coord = ended ? routeCoords[routeLength - 1] : routeCoords[0];
                    /** @type {ol.geom.Point} */
                    (geoMarker.getGeometry()).setCoordinates(coord);
                    //移除监听
                    map.un('postcompose', moveFeature);    /** 解除postcompose 事件  */
                }

                startButton.addEventListener('click', startAnimation, false);
            }

转载自:https://blog.csdn.net/sinat_25295611/article/details/79154182

You may also like...