七章-83-航班轨迹

2020-03-27  本文已影响0人  彩云飘过

本文基于腾讯课堂老胡的课《跟我学Openlayers--基础实例详解》做的学习笔记,使用的openlayers 5.3.x api。

源码 见 1040.html ,对应的 官网示例 https://openlayers.org/en/latest/examples/flight-animation.html?q=animation

image.png image.png
核心技术点:
map.on('postcompose', animateFlights)
frameState.time控制时间
使用第三方库 arc.js 生成曲线

<!DOCTYPE html>
<html>

<head>
 <title>航班轨迹</title>
 <link rel="stylesheet" href="../include/ol.css" type="text/css" />
 <script src="../include/ol.js"></script>
 <!--第三方库,用来生成航班航线的弧线样式  -->
 <script src="../include/arc.js"></script>
</head>
<style></style>

<body>

 <div id="map" class="map"></div>
 <script>
   var map = new ol.Map({
     layers: [
       new ol.layer.Tile({
         source: new ol.source.Stamen({ //黑白风格的图层,硒鼓样式
           layer: 'toner'
         })
       })
     ],
     target: 'map',
     view: new ol.View({
       center: [0, 0],
       zoom: 2
     })
   });

   var style = new ol.style.Style({
     stroke: new ol.style.Stroke({
       color: '#EAE911',
       width: 2
     })
   });

   var flightsSource = new ol.source.Vector({
     wrapX: false,
     attributions: 'Flight data by ' +
       '<a href="http://openflights.org/data.html">OpenFlights</a>,',
     loader: function () {
     
     var url = 'https://openlayers.org/en/latest/examples/data/openflights/flights.json'; //获取航班出发点 目的地
       //var url = '../data/flights.json'; //获取航班出发点 目的地
       fetch(url).then(function (response) {
         return response.json();
       }).then(function (json) {
         var flightsData = json.flights;
         for (var i = 0; i < flightsData.length; i++) {
           var flight = flightsData[i];
           var from = flight[0];
           var to = flight[1];

           // 使用多线段拟合生成的弧线
           var arcGenerator = new arc.GreatCircle(
             { x: from[1], y: from[0] },
             { x: to[1], y: to[0] });

           //跨越国际日期变更线的航班,会被切割成两半;根据弧线与国际日期变更线之间的偏移量,在10度范围内的,将把线分隔开
           var arcLine = arcGenerator.Arc(100, { offset: 10 }); //用100个直线模拟弧线
           if (arcLine.geometries.length === 1) { //把arcLine 转为 ol中的Line
             var line = new ol.geom.LineString(arcLine.geometries[0].coords);
             line.transform('EPSG:4326', 'EPSG:3857');

             var feature = new ol.Feature({
               geometry: line,
               finished: false // 标记着飞行曲线有没有绘制完成
             });
             // add the feature with a delay so that the animation
             // for all features does not start at the same time
             addLater(feature, i * 50); //为达到航班不是同一时间起飞的效果
           }
         }
         map.on('postcompose', animateFlights);
       });
     }
   });

   var flightsLayer = new ol.layer.Vector({
     source: flightsSource,
     style: function (feature) {
      
       if (feature.get('finished')) {
         return style;
       } else {
         return null;
       }
     }
   });

   map.addLayer(flightsLayer);



   var pointsPerMs = 0.1;

   function animateFlights(event) {
     var vectorContext = event.vectorContext;
     var frameState = event.frameState;
     vectorContext.setStyle(style);//设置矢量数据源的样式

     var features = flightsSource.getFeatures();
     for (var i = 0; i < features.length; i++) {
       var feature = features[i];
       if (!feature.get('finished')) {
       //没有绘制完的话,根据绘制时间,判断该绘制哪些点了
         var coords = feature.getGeometry().getCoordinates();
         var elapsedTime = frameState.time - feature.get('start');
         var elapsedPoints = elapsedTime * pointsPerMs;

         if (elapsedPoints >= coords.length) {
           feature.set('finished', true);
         }

         var maxIndex = Math.min(elapsedPoints, coords.length);
         var currentLine = new ol.geom.LineString(coords.slice(0, maxIndex));

        
         vectorContext.drawGeometry(currentLine);
       }
     }
    
     map.render();
   }

   function addLater(feature, timeout) {
     window.setTimeout(function () {
       feature.set('start', new Date().getTime()); //增加start属性,标记起始时间
       flightsSource.addFeature(feature);
     }, timeout);
   }
 </script>
</body>

</html>
上一篇下一篇

猜你喜欢

热点阅读