2015-10-14 115 views
0

我使用OpenLayers創建跨太平洋遷移海洋動物的動畫。隨着時間的推移,我希望每個「動物」追蹤一條軌跡。在賽道的頭部將是代表該動物的圖標/標記/疊加層。我已經得到了這個工作的一個軌道,但雖然我能夠逐行增長每個動物的軌跡作爲一個線條構建的細分,但我無法爲每個軌道專門分配一個圖標/標記/覆蓋。相反,我只能在一條軌道上爲一個圖標製作動畫。其餘的線串曲目繼續進行,但它們在軌道的頭部沒有圖標,因爲它被追蹤出來。這是我的代碼。任何幫助讚賞。在OpenLayers中動畫多個標記3

// draw tracks 

    function makeLineString(id, species, multipointCoords, tracksTime) { 

     // layer structure and style assignment 

     var trackSource = new ol.source.Vector(); 

     var trackLayer = new ol.layer.Vector({ 
      source: trackSource, 
      style: BWtrackStyle 
     }); 
     map.addLayer(trackLayer); 

     var lineString = new ol.geom.LineString([ 
      ol.proj.fromLonLat(multipointCoords[0][0]) 
     ]); 

     var trackFeature = new ol.Feature({ 
      geometry: lineString 
     }); 

     if (species === "Blue Whale") { 
      trackFeature.setStyle([BWtrackStyle, shadowStyle]); 
     }; 

     trackSource.addFeature(trackFeature); 

     // icon-marker-overlay styling 

     var BW2205005icon = document.getElementById('BW2205005icon'); 
     var BW2205005marker = new ol.Overlay({ 
      positioning: 'center-center', 
      offset: [0, 0], 
      element: BW2205005icon, 
      stopEvent: false 
     }); 
     map.addOverlay(BW2205005marker); 

     var BW2205012icon = document.getElementById('BW2205012icon'); 
     var BW2205012marker = new ol.Overlay({ 
      positioning: 'center-center', 
      offset: [0, 0], 
      element: BW2205012icon, 
      stopEvent: false 
     }); 
     map.addOverlay(BW2205012marker); 

     var coordinate, i = 1, 
      length = multipointCoords[0].length; 

     var currentTime = tracksTime[0][0]; 
     var nextTime = tracksTime[0][1]; 
     speedOption = 100; // the highter this value, the faster the tracks, see next line 
     var transitionTime = (nextTime - currentTime)/speedOption; 
     console.log(transitionTime); 

     var timer; 

     timer = setInterval(function() { 
      segmentConstruction(id, multipointCoords, tracksTime); 
     }, transitionTime); 

     function segmentConstruction(id, multipointCoords, tracksTime) { 
      coordinate = ol.proj.fromLonLat(multipointCoords[0][i]); 
      lineString.appendCoordinate(coordinate); 
      console.log(id); 

      if (id === "BW2205005") { 
       BW2205005marker.setPosition(coordinate); 
      } else { 

       BW2205012marker.setPosition(coordinate); 
      }; 

      if (i >= length - 1) { 
       clearInterval(timer); 
      } else { 
       i++; 
       clearInterval(timer); 
       currentTime = tracksTime[0][i]; 
       nextTime = tracksTime[0][i + 1]; 
       transitionTime = (nextTime - currentTime)/speedOption; 
       timer = setInterval(function() { 
        segmentConstruction(id, multipointCoords, tracksTime); 
       }, transitionTime); 
      }; 
     }; 
    }; 
+0

我應該補充一點,這段代碼的靈感來自於這個例子:http://plnkr.co/edit/2VNqoz?p=preview – interwebjill

回答

0

我認爲你的覆蓋圖正在被重複用於每一行。在任何情況下,它可能會更簡單和更高性能的使用點要素,而不是重疊的,如下:

  • 添加新的樣式,圖層爲點(圓圈,圖像等)
  • 添加表示各線
  • 更新的頭部的點特徵在必要時

換句話說點特徵的座標,每個動物將具有線串和點特徵。圖層上的樣式將包括該線的筆觸樣式和該點的圖標樣式。

您還可以通過爲每個點功能提供自己的樣式或在圖層上使用樣式函數來獨立設置點的樣式。

+0

你是什麼意思:「我認爲你的覆蓋被重複用於每一行」?謝謝。 – interwebjill

+0

大多數示例都使用div覆蓋,並使用.setPosition對其進行動畫處理。要做到這一點的功能,我想可以使用.setGeometry或者也許是實驗性的vectorContext? – interwebjill

+0

我假設你有很多線串,但它看起來像只有兩個疊加層,所以當你改變座標以匹配一個線串的末尾時,它會移動現有的疊加層。這可以解釋爲什麼你沒有看到預期的行爲。 –

0

我建議這對多個標記平穩運動的動畫,但它需要其他風格的延遲:參照 http://openlayers.org/en/latest/examples/feature-move-animation.html?q=animation

 var vehicles= [{ "curlon":77.654397, "curlat":12.959898, "prevlon":77.651951, "prevlat":12.951074 },{ "curlon":77.672936, "curlat":12.958100, "prevlon":77.649290, "prevlat":12.960024 }]; 

      function push_data_for_multimarker(map,gps_obj) 
      { 
      destruct=false; 
       var getz = gps_obj; 
       var data_arry = []; 
       for (var i = 0, length = getz.length; i < length; i++) 
       { 
       gps_smooth_coordinates_generator(parseFloat(getz[i].prevlon),parseFloat(getz[i].prevlat),parseFloat(getz[i].curlon),parseFloat(getz[i].curlat)); 
       } 
      } 


      function gps_smooth_coordinates_generator(map,sourcelon,sourcelat,destinationlon,destinationlat) 
      { 
       var vehicle_data=[]; 

       var beginz=ol.proj.transform([sourcelon,sourcelat], 'EPSG:4326', 'EPSG:3857'); 

       var endz=ol.proj.transform([destinationlon,destinationlat], 'EPSG:4326', 'EPSG:3857'); 


       vehicle_data.push(beginz); 
       vehicle_data.push(endz); 
       var path= vehicle_data; 
       var genrated_positions = []; 
          for(var k = 1;k<path.length;k++) 
           { 
            var pointsNo = 1000; 
            var startPos = {}; 
            startPos.lat = path[k-1][1]; 
            startPos.lng = path[k-1][0]; 
            var endPos = {}; 
            endPos.lat = path[k][1]; 
            endPos.lng = path[k][0]; 
            var latDelta = (endPos.lat - startPos.lat)/pointsNo; 
            var lngDelta = (endPos.lng - startPos.lng)/pointsNo; 

            for (var i = 0; i < pointsNo; i++) 
            { 
             var curLat = startPos.lat + i * latDelta; 
             var curLng = startPos.lng + i * lngDelta; 
             var arr = []; 
             arr.push(curLng); 
             arr.push(curLat); 
             genrated_positions.push(arr); 
            } 
           } 

          animate_multiple_marker(genrated_positions); 
      } 

    function animate_multiple_marker(map,veh_croods) 
     { 
     var routeCoords = veh_croods; 
     var routeLength = routeCoords.length; 
     console.log("routeCoords"+routeCoords); 
     console.log("routeLength"+routeLength); 
     var geoMarker = new ol.Feature({ 
     type: 'geoMarker', 
     geometry: new ol.geom.Point(routeCoords[0]) 
     }); 


     var off_style =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 
      }) 
      }) 
     }); 

      var now; 
      var animating = false; 
      var speed=20; 

      var moveFeature = function(event) { 
      var vectorContext = event.vectorContext; 
      var frameState = event.frameState; 

      if (animating) { 
       var elapsedTime = frameState.time - now; 
       var index = Math.round(speed * elapsedTime/1000); 
       if (index >= routeLength) { 
       console.log("index>>"+index); 
       stopAnimation(); 
       animating = false; 
       console.log("animation ends"); 
       } 
       if(animating) 
        { 
          var currentPoint = new ol.geom.Point(routeCoords[index]); 
          var feature = new ol.Feature(currentPoint); 
          vectorContext.drawFeature(feature,off_style); 

        } 
       else 
       {} 

       if(destruct) 
       { 
        console.log("termination initiated"); 
        stopAnimation();    
        //destruct=false; 
       } 
       else 
       { } 
      } 
      else 
      { 
       console.log("Not amnimating!!"); 
      } 
      // tell OL3 to continue the postcompose animation 
      map.render(); 
      }; 

      triggerz_animation(); 


     function stopAnimation() { 
     animating = false; 
     caller=false; 
     //remove listener 
      map.un('postcompose', moveFeature); 
     } 

      function start_vehicles() 
      { 
      animating = true; 
      now = new Date().getTime(); 
      map.on('postcompose', moveFeature); 
      map.render(); 
      } 


      if(caller) 
      { 

       start_vehicles(); 

      } 
      else 
      { 


      } 
     } 

     var caller=false; 
     var drive_vehicle; 

     function triggerz_animation() 
     { 
     caller=true; 
     } 
     var destruct=false; 
     function collapse_animation() 
     { 
     destruct=true; 
     } 

讓這成爲helpfull..Thank你 將數據作爲json傳遞給函數: push_data_for_multimarker(map,vehicles);