GPX数据在mapboxGL中轨迹动画

概述

喜欢跑步的人都会选择一款APP来自己跑步的,常用的有keep、悦跑圈、华为健康等等,每次跑完步,会根据跑步的轨迹绘制轨迹动画。今天咱们讲讲技术,不扯淡,讲一下在mapboxGL中如何实现类似的效果。

效果

效果

数据

本文中的数据是我跑步的实测数据,数据导出于Garmin运动手表,格式为GPX。

实现

1.解析处理数据

gpx数据解析用到了gpxparse.js,具体请移步GPXParser.js

loadPgxData() {
  $.get('../data/route.gpx', function (res) {
    res = res.firstChild;
    var dom = $('<div/>');
    dom.html(res);
    var gpx = new gpxParser();
    gpx.parse(dom.html());
    that.points = gpx.tracks[0].points;
    var geojson = {
      'type': 'FeatureCollection',
      'features': []
    };
    var points = [[that.points[0].lon, that.points[0].lat]];
    for(var i = 1;i<that.points.length;i++) {
      var p = [that.points[i].lon, that.points[i].lat];
      var _points = points.concat([p]);
      geojson.features.push({
        type: 'Feature',
        geometry: {
          type: 'LineString',
          coordinates: _points
        },
        properties: {
          index: i
        }
      });
      points.push(p);
    }
    // var geojson = gpx.toGeoJSON();
    map.addSource('track-line', {
      type: 'geojson',
      data: geojson
    });
    map.addLayer({
      id: 'track-line',
      type: 'line',
      source: 'track-line',
      paint: {
        'line-color': '#ff0000',
        'line-width': 6
      }
    });

    that.play();

    that.playFlag = setInterval(function () {
      that.index++;
      if(that.index === that.points.length) {
        window.clearInterval(that.playFlag);
      } else {
        that.play();
      }
    }, 30);
  })
}

2.轨迹动画

play() {
  if(that.marker) that.marker.remove();
  switch (that.index) {
    case 0: {
      var img = $('<img>').attr('src', '../css/start.png');
      var dom = $('<div/>').append(img);
      const option = {
        element: dom[0],
        anchor: 'bottom',
        offset: [0, 10]
      };
      new mapboxgl.Marker(option)
              .setLngLat([that.points[0].lon, that.points[0].lat])
              .addTo(map);
      break;
    }
    case that.points.length -1: {
      var img = $('<img>').attr('src', '../css/end.png');
      var dom = $('<div/>').append(img);
      const option = {
        element: dom[0],
        anchor: 'bottom',
        offset: [0, 10]
      };
      new mapboxgl.Marker(option)
              .setLngLat([that.points[that.points.length - 1].lon,
                that.points[that.points.length - 1].lat])
              .addTo(map);
      break;
    }
    default: {
      var img = $('<img>').attr('src', '../css/loc.png');
      var dom = $('<div/>').append(img);
      const option = {
        element: dom[0],
        anchor: 'bottom',
        offset: [0, 10]
      };
      that.marker = new mapboxgl.Marker(option)
              .setLngLat([that.points[that.index].lon,
                that.points[that.index].lat])
              .addTo(map);
      break;
    }
  }
  map.setFilter('track-line', ['==', 'index', that.index]);
  if(that.index === that.points.length - 2) {
    var pt0 = [that.points[that.index].lon,
      that.points[that.index].lat];
    var pt1 = [that.points[that.index + 1].lon,
      that.points[that.index + 1].lat];
    map.flyTo({
      center: pt0,
      zoom: 17.7
    });
    map.setPitch(60);
    var angle = that.getAngle(pt0, pt1);
    map.setBearing(angle);
  }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

牛老师讲GIS

感谢老板支持

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值