vue+mapboxgl 运行轨迹循环

   最终的样子

+

mapboxgl 官网的例子 :https://docs.mapbox.com/mapbox-gl-js/example/animate-a-line/ 

turf.js  官网:http://turfjs.org/

requestAnimationFrame  详解   我觉得写的很好:https://www.jianshu.com/p/fa5512dfb4f5

一、实现思路

1、绘制线

2、绘制一个点,将线的第一个点赋值给点

3、将geometry中线的每个节点值 赋值给点

<template>
  <div class="hello">
    <div id="map" style="width: 100%; height: 100%"></div>
  </div>
</template>
 
<script>
export default {
  name: "Map",
  data() {
    return {};
  },
  methods: {
    initmap() {
      mapboxgl.accessToken =
        "pk.eyJ1IjoiMTU5MzU3MyIsImEiOiJjamw3bW85dHkwbXlvM3ZzMm5iZnZ6bWJpIn0.W6_MGVjNaImIybFdMJBMpg";
      let initMap = new mapboxgl.Map({
        container: "map",
        style: "mapbox://styles/mapbox/streets-v11",
        zoom: 3, //缩放层级
        center: [108.420679, 36.772537], //进入后展现的中心点
      });
      return initMap;
    },
  },
  mounted() {
    window.map = this.initmap();
    let coor = [
      [74.91932166254529, 43.34799143293915],
      [78.82968043376917, 35.32100587068976],
      [82.20680846345789, 43.283329636323145],
      [84.60634680034286, 35.46590128939705],
      [88.60557736181482, 42.82877118912947],
      [92.07157718176103, 34.07894110138169],
      [100.86988441701243, 42.95898883351077],
      [109.31270449123406, 31.766651099437112],
      [127.53142149351078, 41.17789211364973],
      [135.8853697774751, 33.33965831774536],
      [142.3730104660895, 43.283329636323145],
      [148.94952294496136, 37.39631064993182],
      [152.94875350643326, 44.753129575870986],
    ];
    let origin = coor[0];
    var route = {
      type: "FeatureCollection",
      features: [
        {
          type: "Feature",
          geometry: {
            type: "LineString",
            coordinates: coor,
          },
        },
      ],
    };
    var point = {
      type: "FeatureCollection",
      features: [
        {
          type: "Feature",
          properties: {},
          geometry: {
            type: "Point",
            coordinates: origin,
          },
        },
      ],
    };

    map.on("load", function () {
      map.addSource("route", {
        type: "geojson",
        data: route,
      });

      map.addSource("point", {
        type: "geojson",
        data: point,
      });

      map.addLayer({
        id: "route",
        source: "route",
        type: "line",
        paint: {
          "line-width": 2,
          "line-color": "#007cbf",
        },
      });

      map.addLayer({
        id: "point",
        source: "point",
        type: "symbol",
        layout: {
          "icon-image": "airport-15",
          "icon-rotate": ["get", "bearing"],
          "icon-rotation-alignment": "map",
          "icon-allow-overlap": true,
          "icon-ignore-placement": true,
        },
      });
      console.log(map, map.getStyle(), "map");
      let that = this;
      var steps = 10000;
      var counter = 0;
      function animate() {
        debugger;
        if (counter == coor.length) {
          cancelAnimationFrame(requestAnimationFrame(animate));
          point.features[0].geometry.coordinates = [];
          point.features[0].geometry.coordinates = origin;
          map.getSource("point").setData(point);
          counter = -1;
        } else {
          point.features[0].geometry.coordinates = coor[counter];
          if (counter < coor.length - 1) {
            point.features[0].properties.bearing = turf.bearing(
              turf.point(coor[counter >= steps ? counter - 1 : counter]),
              turf.point(coor[counter >= steps ? counter : counter + 1])
            );
          } else {
            point.features[0].properties.bearing = turf.bearing(
              turf.point(coor[counter >= steps ? counter - 3 : counter - 2]),
              turf.point(coor[counter >= steps ? counter - 2 : counter - 1])
            );
          }
          if (point.features[0].properties.bearing != 0) {
            console.log(map, map.getSource("point"), "map", point);
            console.log(map.getStyle(), map.getSource("point"), "map", point);
            map.getSource("point").setData(point);
          }
        }
        counter++;
        requestAnimationFrame(animate);
      }
      animate(counter);
    });
  },
};
</script>
 
<style scoped>
.hello {
  width: 100%;
  height: 100%;
}
</style>

是不是很快,原因是我们数据的节点很少,我们需要将线的细化,这里用到的是  turf.lineChunk  转之后发现他不是标准的geometry 线数据

<template>
  <div class="hello">
    <div id="map" style="width: 100%; height: 100%"></div>
  </div>
</template>
 
<script>
export default {
  name: "Map",
  data() {
    return {};
  },
  methods: {
    initmap() {
      mapboxgl.accessToken =
        "pk.eyJ1IjoiMTU5MzU3MyIsImEiOiJjamw3bW85dHkwbXlvM3ZzMm5iZnZ6bWJpIn0.W6_MGVjNaImIybFdMJBMpg";
      let initMap = new mapboxgl.Map({
        container: "map",
        style: "mapbox://styles/mapbox/streets-v11",
        zoom: 3, //缩放层级
        center: [108.420679, 36.772537], //进入后展现的中心点
      });
      return initMap;
    },
  },
  mounted() {
    window.map = this.initmap();
    let coor_old = [
      [74.91932166254529, 43.34799143293915],
      [78.82968043376917, 35.32100587068976],
      [82.20680846345789, 43.283329636323145],
      [84.60634680034286, 35.46590128939705],
      [88.60557736181482, 42.82877118912947],
      [92.07157718176103, 34.07894110138169],
      [100.86988441701243, 42.95898883351077],
      [109.31270449123406, 31.766651099437112],
      [127.53142149351078, 41.17789211364973],
      [135.8853697774751, 33.33965831774536],
      [142.3730104660895, 43.283329636323145],
      [148.94952294496136, 37.39631064993182],
      [152.94875350643326, 44.753129575870986],
    ];
    let route = {
      type: "FeatureCollection",
      features: [
        {
          type: "Feature",
          geometry: {
            type: "LineString",
            coordinates: coor_old,
          },
        },
      ],
    };

    let routelineChunk = turf.lineChunk(route.features[0], 50, {
      units: "miles",
    });
    // 将转好后的geometry拼接成正常的数据
    let coor = [];
    routelineChunk.features.forEach((el) => {
      el.geometry.coordinates.forEach((yo) => {
        coor.push(yo);
      });
    });
    route.features[0].geometry.coordinates = coor;
    let origin = coor[0];
    let point = {
      type: "FeatureCollection",
      features: [
        {
          type: "Feature",
          properties: {},
          geometry: {
            type: "Point",
            coordinates: origin,
          },
        },
      ],
    };

    map.on("load", function () {
      map.addSource("route", {
        type: "geojson",
        data: route,
      });

      map.addSource("point", {
        type: "geojson",
        data: point,
      });

      map.addLayer({
        id: "route",
        source: "route",
        type: "line",
        paint: {
          "line-width": 2,
          "line-color": "#007cbf",
        },
      });

      map.addLayer({
        id: "point",
        source: "point",
        type: "symbol",
        layout: {
          "icon-image": "airport-15",
          "icon-rotate": ["get", "bearing"],
          "icon-rotation-alignment": "map",
          "icon-allow-overlap": true,
          "icon-ignore-placement": true,
        },
      });
      let that = this;
      let steps = 10000;
      let counter = 0;
      function animate() {
        debugger;
        if (counter == coor.length) {
          cancelAnimationFrame(requestAnimationFrame(animate));
          point.features[0].geometry.coordinates = [];
          point.features[0].geometry.coordinates = origin;
          map.getSource("point").setData(point);
          counter = -1;
        } else {
          point.features[0].geometry.coordinates = coor[counter];
          if (counter < coor.length - 1) {
            point.features[0].properties.bearing = turf.bearing(
              turf.point(coor[counter >= steps ? counter - 1 : counter]),
              turf.point(coor[counter >= steps ? counter : counter + 1])
            );
          } else {
            point.features[0].properties.bearing = turf.bearing(
              turf.point(coor[counter >= steps ? counter - 3 : counter - 2]),
              turf.point(coor[counter >= steps ? counter - 2 : counter - 1])
            );
          }
          if (point.features[0].properties.bearing != 0) {
            map.getSource("point").setData(point);
          }
        }
        counter++;
        requestAnimationFrame(animate);
      }
      animate(counter);
    });
  },
};
</script>
 
<style scoped>
.hello {
  width: 100%;
  height: 100%;
}
</style>

线的数据是一样的,移动的数据是空的,我们将每次都push更新数据

最终的代码

<template>
  <div class="hello">
    <div id="map" style="width: 100%; height: 100%"></div>
  </div>
</template>
 
<script>
export default {
  name: "Map",
  data() {
    return {};
  },
  methods: {
    initmap() {
      mapboxgl.accessToken =
        "pk.eyJ1IjoiMTU5MzU3MyIsImEiOiJjamw3bW85dHkwbXlvM3ZzMm5iZnZ6bWJpIn0.W6_MGVjNaImIybFdMJBMpg";
      let initMap = new mapboxgl.Map({
        container: "map",
        style: "mapbox://styles/mapbox/streets-v11",
        zoom: 3, //缩放层级
        center: [108.420679, 36.772537], //进入后展现的中心点
      });
      return initMap;
    },
  },
  mounted() {
    window.map = this.initmap();
    let coor_old = [
      [74.91932166254529, 43.34799143293915],
      [78.82968043376917, 35.32100587068976],
      [82.20680846345789, 43.283329636323145],
      [84.60634680034286, 35.46590128939705],
      [88.60557736181482, 42.82877118912947],
      [92.07157718176103, 34.07894110138169],
      [100.86988441701243, 42.95898883351077],
      [109.31270449123406, 31.766651099437112],
      [127.53142149351078, 41.17789211364973],
      [135.8853697774751, 33.33965831774536],
      [142.3730104660895, 43.283329636323145],
      [148.94952294496136, 37.39631064993182],
      [152.94875350643326, 44.753129575870986],
    ];
    let route = {
      type: "FeatureCollection",
      features: [
        {
          type: "Feature",
          geometry: {
            type: "LineString",
            coordinates: coor_old,
          },
        },
      ],
    };
    let routeMove = {
      type: "FeatureCollection",
      features: [
        {
          type: "Feature",
          geometry: {
            type: "LineString",
            coordinates: [],
          },
        },
      ],
    };
    let speed = 50; // 运行速度
    let routelineChunk = turf.lineChunk(route.features[0], speed, {
      units: "miles",
    });
    // 将转好后的geometry拼接成正常的数据
    let coor = [];
    routelineChunk.features.forEach((el) => {
      el.geometry.coordinates.forEach((yo) => {
        coor.push(yo);
      });
    });
    route.features[0].geometry.coordinates = coor;
    let origin = coor[0];
    let point = {
      type: "FeatureCollection",
      features: [
        {
          type: "Feature",
          properties: {},
          geometry: {
            type: "Point",
            coordinates: origin,
          },
        },
      ],
    };

    map.on("load", function () {
      map.addSource("route", {
        type: "geojson",
        data: route,
      });
      map.addSource("routeMove", {
        type: "geojson",
        data: routeMove,
      });
      map.addSource("point", {
        type: "geojson",
        data: point,
      });
      map.addLayer({
        id: "route",
        source: "route",
        type: "line",
        paint: {
          "line-width": 10,
          "line-color": "#F22C2C",
          "line-opacity": 0.3,
        },
        layout: {
          "line-cap": "round",
          "line-join": "round",
        },
      });
      map.addLayer({
        id: "routeMove",
        source: "routeMove",
        type: "line",
        paint: {
          "line-width": 2,
          "line-color": "#007cbf",
          "line-opacity": 1,
        },
        layout: {
          "line-cap": "round",
          "line-join": "round",
        },
      });
      map.addLayer({
        id: "point",
        source: "point",
        type: "symbol",
        layout: {
          "icon-image": "airport-15",
          "icon-rotate": ["get", "bearing"],
          "icon-rotation-alignment": "map",
          "icon-allow-overlap": true,
          "icon-ignore-placement": true,
        },
      });
      let that = this;
      let steps = 10000;
      let counter = 0;
      function animate() {
        if (counter == coor.length) {
          cancelAnimationFrame(requestAnimationFrame(animate));
          point.features[0].geometry.coordinates = [];
          point.features[0].geometry.coordinates = origin;
          map.getSource("point").setData(point);
          counter = -1;
          routeMove.features[0].geometry.coordinates = [];
        } else {
          // 移动添加点数据
          point.features[0].geometry.coordinates = coor[counter];
          if (counter < coor.length - 1) {
            point.features[0].properties.bearing = turf.bearing(
              turf.point(coor[counter >= steps ? counter - 1 : counter]),
              turf.point(coor[counter >= steps ? counter : counter + 1])
            );
          } else {
            point.features[0].properties.bearing = turf.bearing(
              turf.point(coor[counter >= steps ? counter - 3 : counter - 2]),
              turf.point(coor[counter >= steps ? counter - 2 : counter - 1])
            );
          }
          if (point.features[0].properties.bearing != 0) {
            map.getSource("point").setData(point);
          }
          // 添加线数据
          routeMove.features[0].geometry.coordinates.push(coor[counter]);
          map.getSource("routeMove").setData(routeMove);
        }
        counter++;
        requestAnimationFrame(animate);
      }
      animate(counter);
    });
  },
};
</script>
 
<style scoped>
.hello {
  width: 100%;
  height: 100%;
}
</style>

这个最后可以拓展就可以实现, keep 上面的轨迹了

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

侧耳倾听...

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值