【问题标题】:How to draw linestring from consecutive points of array in openlayers如何从openlayers中的数组的连续点绘制线串
【发布时间】:2019-04-09 19:15:50
【问题描述】:

我正在尝试用连续的Points 在 openlayers 中绘制 LineString,以赋予它从头到尾绘制的动画感觉。

我试图通过关注this example 来实现它。 OL2 的所有引用都转换为 OpenLayers 5,但对于整个数组,仍然应该绘制一个点,然后是下一个,而不是一次。

在此处找到具有当前输出的我的代码 - my code

[供参考]这是我正在努力实现的Snake animation for leaflet

【问题讨论】:

    标签: javascript openlayers openlayers-3 openlayers-5


    【解决方案1】:

    仅使用线串的顶点不会产生流畅的动画。您可以在 OpenLayers 示例 https://openlayers.org/en/v4.6.5/examples/feature-move-animation.html 中看到标记在直线部分上移动得更快。如果您需要像 OpenLayers 2 示例中那样沿着直线平滑移动,您需要使用 .getCoordinateAt() 来计算您应该在任何时候在线上的位置。这是一个基于标记动画示例的演示,但也计算顶点之间的位置,显示蛇示例中的线串。您还可以绘制自己的直线并观看流畅的动画效果。

    var style = new ol.style.Style({
      stroke: new ol.style.Stroke({
    width: 4,
    color: 'red'
      })
    });
    
    var raster = new ol.layer.Tile({
      source:  new ol.source.OSM()
    });
    
    var vector = new ol.layer.Vector({
      source: new ol.source.Vector(),
      style: style
    });
    
    var map = new ol.Map({
      layers: [raster, vector],
      target: 'map',
      view: new ol.View()
    });
    
    var xhr = new XMLHttpRequest();
    xhr.open('GET', 'https://raw.githubusercontent.com/IvanSanchez/Leaflet.Polyline.SnakeAnim/master/route.js');
    xhr.onload = function() {
      // read the route coordinates
      eval(xhr.responseText);
      // reverse the route
      var geom = new ol.geom.LineString(route.reverse());
      // change Lat/Lon to Lon/Lat
      geom.applyTransform(function(c){ return c.reverse(); });
      geom.transform('EPSG:4326', map.getView().getProjection());
      map.getView().fit(geom.getExtent(), { size: map.getSize() });
      var snake = new ol.Feature();
      vector.getSource().addFeature(snake);
      animate_line(snake, geom, 30000);
    }
    xhr.send();
    
    function animate_line(feature, linestring, duration) {
    
      var length = linestring.getLength();
      var length_shown = 0;
    
      var coords = linestring.getCoordinates();
      var coords_shown = [coords[0], coords[0]];
      var geom_shown = new ol.geom.LineString(coords_shown);
      feature.setGeometry(geom_shown);
    
      var coordcount = 1;
      var start = new Date().getTime();
      var listenerKey = map.on('postcompose', animate);
    
      function animate() {
    
    var elapsed = new Date().getTime() - start;
    var toAdd = length*elapsed/duration - length_shown;
    var point = linestring.getCoordinateAt(Math.min(elapsed/duration, 1));
    
    // restart from last intermediate point and remove it
    var newPart = new ol.geom.LineString(coords_shown.slice(-1));
    coords_shown.pop();
    
    // add vertices until required length exceeded
    while (coordcount < coords.length && newPart.getLength() <= toAdd) {
      newPart.appendCoordinate(coords[coordcount]);
      coords_shown.push(coords[coordcount]);
      coordcount++;
    }
    
    // replace overrun vertex with intermediate point
    coords_shown.pop();
    coordcount--;
    coords_shown.push(point);
    
    geom_shown.setCoordinates(coords_shown);
    length_shown += toAdd;
    
    if (elapsed > duration) {
      ol.Observable.unByKey(listenerKey);
    }
    map.render();
    
      }
    
    }
    
    draw = new ol.interaction.Draw({
      source: vector.getSource(),
      type: 'LineString'
    });
    
    draw.on('drawend',function(evt){
      geom = evt.feature.getGeometry();
      evt.feature.setGeometry(undefined);
      animate_line(evt.feature, geom, 6000);
    });
    map.addInteraction(draw);
    html, body, .map {
        margin: 0;
        padding: 0;
        width: 100%;
        height: 100%;
    }
    <link href="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/css/ol.css" rel="stylesheet" />
    <script src="https://cdn.rawgit.com/openlayers/openlayers.github.io/master/en/v5.3.0/build/ol.js"></script>
    <div id="map" class="map"></div>

    【讨论】:

    • xhr 请求只返回路由,那么如果我提供我的几何图形和特征同时保持 xhr 请求注释,为什么动画不起作用。注释掉 xhr 请求并在此处查看输出 - [jsbin.com/tozenav/edit?js,output]
    • 您需要在调用animate_line之前初始化视图map.getView().fit(g);(或者在创建地图时设置中心和缩放)
    【解决方案2】:

    你的 for 循环

    for(i=0;i<path.length;) {
        drawAnimatedLine(/*snip*/);
    }
    

    基本同时开始所有点的动画,无需等待。您需要等到第一行的动画完成后才能开始下一段。您的drawAnimation 函数有第 6 个参数 fn 为它提供绘制完成时要调用的函数的函数指针。

    这是一个快速的肮脏版本,我重写了你的 for 循环来演示我的意思。 https://jsbin.com/lanoxojugi/edit?js,output

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-09-09
      • 1970-01-01
      • 2018-11-18
      • 1970-01-01
      • 2021-05-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多