1. 程式人生 > 程式設計 >openlayers 3實現車輛軌跡回放

openlayers 3實現車輛軌跡回放

本文例項為大家分享了openlayers 3實現車輛軌跡回放的具體程式碼,供大家參考,具體內容如下

先上效果:

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'),rotation: -rotation,})
       });
       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,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,fill: new ol.style.Fill({
        color: color
       }),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);
}

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支援我們。