相关文章推荐
气宇轩昂的大象  ·  oracle odp.net ...·  7 月前    · 
温柔的炒粉  ·  javascript - ...·  1 年前    · 
非常酷的熊猫  ·  node.js - ...·  1 年前    · 
首发于 地图说
航线地图上的动画飞行效果怎么实现?只要五步轻松上手

航线地图上的动画飞行效果怎么实现?只要五步轻松上手

Animate a point along a route


最近有 Mapbox 社群里的开发者问 Max:


Hi, Max!我在做航线图,想要做出飞机沿着航线飞过的动画效果, Max 你知道怎么实现吗?


Max 回去苦心研究,查阅了各个教程, 终于研究出了如何实现航线地图上的飞行动画效果!


今天, 我将教大家如何用 Mapbox Gl Js 联合 Turf.js 来实现下面的动画飞行效果!


点击这里在线查看 Codepen 上的代码与作品(最好用电脑哦)


展示效果如下:



如果你对 Mapbox Gl Js 有点陌生, 请查看以下教程熟悉一下:

中文视频教程 | 如何使用 Mapbox GL JS 把标记添加到地图上(含字幕)

35 个你不知道却特好用的 Mapbox GL JS 插件 #GoGlobal Web Week

Mapbox GL JS 又更新了?v1.10.0 四大亮点不可错过!



第1步:确定底图


这次我们直接使用 Mapbox 模板样式 mapbox://styles/mapbox/dark-v10 (当然,你也可以使用属于自己的地图样式), 然后使用你的 accesss token, 创建一个地图页面。


部分代码如下:

  // TO MAKE THE MAP APPEAR YOU MUST
  // ADD YOUR ACCESS TOKEN FROM
  // https://account.mapbox.com
  mapboxgl.accessToken = 'YOUR ACCESS TOKEN';
    var map = new mapboxgl.Map({
        container: 'map',
        style: 'mapbox://styles/mapbox/dark-v10',
        center: [-96, 37.8],
        zoom: 3


更多关于地图样式的请查看:

这幅超可爱的故事地图是怎么做的?Mapbox Studio Classic 地图样式重制思路

如何“偷”来别人好看的 Mapbox Style 地图样式



第2步:添加航线数据


然后你需要添加你的航线数据, 这里我们简单使用单个航线的数据作为示范。这条航线,始于旧金山, 结束于华盛顿特区。

// San Francisco
    var origin = [-122.414, 37.776];
    // Washington DC
    var destination = [-77.032, 38.913];
    // A simple line from origin to destination.
    var route = {
        'type': 'FeatureCollection',
        'features': [
                'type': 'Feature',
                'geometry': {
                    'type': 'LineString',
                    'coordinates': [origin, destination]


如果你的航线数据很多但又不想用数据库, 也可以尝试使用下面这个方案

把 Excel 的内容实时更新到交互地图!Mapbox 推出开源工具 Sheet Mapper




第3步:为你的航线添加飞机飞行的动画效果


这是最关键的一步!

首先,我们要沿着航线添加一个移动的点, 这个点从起始点运动到终点。

    var point = {
        'type': 'FeatureCollection',
        'features': [
                'type': 'Feature',
                'properties': {},
                'geometry': {
                    'type': 'Point',
                    'coordinates': origin
    };


这里我们要借助 Turf.js 来计算路线起点/终点之间的距离,单位为公里。

    // Calculate the distance in kilometers between route start/end point.
    var lineDistance = turf.lineDistance(route.features[0], 'kilometers');
    var arc = [];


接着, 在两点的 "原点 "和 "终点 "之间画一条弧线。并且写明这个点沿着弧线运动的步数 500。步数 (Steps)越多表示越好, 可以显示更平滑的动画效果,但步数太多也会造成低帧率。


    // Number of steps to use in the arc and animation, more steps means
    // a smoother arc and animation, but too many steps will result in a
    // low frame rate
    var steps = 500;
    // Draw an arc between the `origin` & `destination` of the two points
    for (var i = 0; i < lineDistance; i += lineDistance / steps) {
        var segment = turf.along(route.features[0], i, 'kilometers');
        arc.push(segment.geometry.coordinates);
    }


我们还要更新点的移动坐标, 用上面计算出的圆弧坐标。


    // Update the route with calculated arc coordinates
    route.features[0].geometry.coordinates = arc;
    // Used to increment the value of the point measurement against the route.
    var counter = 0;


别忘了最重要的 animate 函数!

        function animate() {
            // Update point geometry to a new position based on counter denoting
            // the index to access the arc.
            point.features[0].geometry.coordinates =
                route.features[0].geometry.coordinates[counter];
            // Calculate the bearing to ensure the icon is rotated to match the route arc
            // The bearing is calculate between the current point and the next point, except
            // at the end of the arc use the previous point and the current point
            point.features[0].properties.bearing = turf.bearing(
                turf.point(
                    route.features[0].geometry.coordinates[
                        counter >= steps ? counter - 1 : counter
                turf.point(
                    route.features[0].geometry.coordinates[
                        counter >= steps ? counter : counter + 1
            );



第5步:把航线,动画效果的图层展示在地图上


在 add Layer 这里,你要做的选择合适的线样式,图标样式, 把航线及飞行动画效果最终呈现在地图上。


一般情况, 你只需要设置线的基础样式,例如 line- width,line-color 即可。但受到的 Jonni Walker 的教程影响,这次我决定把线设置成发光的样式(以配合我的暗黑风格地图样式)



发光的效果



普通的样式


查看 Jonni Walker 的教程: 如何让你的数据发光?“ 萤火虫 ”风格地图制作方法大揭秘!| Mapbox Studio 教程


接着这意味着,我设置了3条重叠的但样式不一样的 Line 来创造发光的航线!

        map.addLayer({
            'id': 'route',
            'source': 'route',
            'type': 'line',
            'paint': {
                'line-width':6,
                'line-blur': 3,
                'line-opacity': 0.4,
                'line-color': '#007cbf'
      map.addLayer({
            'id': 'route2',
            'source': 'route',
            'type': 'line',
            'paint': {
                'line-width':3,
                'line-blur': 3,
                'line-opacity': 0.4,
                'line-color': '#009df2'
      map.addLayer({
            'id': 'route3',
            'source': 'route',
            'type': 'line',
            'paint': {
                'line-width':0.2,
                'line-blur': 1,
                'line-opacity': 1,
                'line-color': '#fafdff'
    



然后我还要在地图上添加飞行动画!我直接用了 Mapbox 自带的 Icon—airport-15。


        map.addLayer({
            'id': 'point',
            'source': 'point',
            'type': 'symbol',
            'layout': {
                'icon-image': 'airport-15',
                'icon-rotate': ['get', 'bearing'],
                'icon-rotation-alignment': 'map',