在OpenLayers 3中

时间:2015-10-14 07:02:23

标签: animation openlayers-3

我正在创建使用OpenLayers在太平洋上迁移海洋动物的动画。我希望每个“动物”能够随着时间的推移追踪一条轨道。在轨道的头部将是表示该动物的图标/标记/覆盖图。我已经让这个工作用于一个轨道,但是虽然我能够将每个动物的轨迹增长为逐段构建的线串,但是我无法为每个轨道专门分配图标/标记/叠加。相反,我只能在一个轨道上设置一个图标的动画。其余的线串轨迹继续进行,但是在跟踪时,它们在轨道的头部没有图标。这是我的代码。任何帮助表示赞赏。

    // 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);
            };
        };
    };

2 个答案:

答案 0 :(得分:0)

我认为您的叠加层正在重复用于每一行。在任何情况下,使用点特征而不是叠加可能更简单,更高效,如下所示:

  • 为图层添加新样式(圆形,图像等)
  • 添加表示每行头部的点要素
  • 在必要时更新点要素的坐标

换句话说,每只动物都有一个线串和一个点特征。图层上的样式将包括线条的笔触样式和点的图标样式。

您还可以通过为每个点特征赋予其自己的样式或在图层上使用样式函数来独立地设置点的样式。

答案 1 :(得分:0)

我建议使用平滑移动的多个标记的动画,但它需要延迟其他样式:

      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;
      }

参考 http://openlayers.org/en/latest/examples/feature-move-animation.html?q=animation

让这有用。谢谢 将数据作为json传递给函数: push_data_for_multimarker(地图,车辆);