MapBox历史轨迹

贴个群号

WebGIS学习交流群461555818,欢迎大家。

成果实例

在这里插入图片描述

思路

思路就是取从起点开始一路setdata吧
分三个图层,一个路径图层,一个飞机图层,一个显示名字的图层,遍历路径图层的点,经过显示名字图层的时候就显示图层,飞机图层的点和角度动态计算,跟着路径图层的点走

源码

export const routeDataTest = [
    {
      lat:35,
      lon:110,
      label:'起点'
    },
    {
      lat:35,
      lon:110.1,
      label:''
    },
    {
      lat:35,
      lon:110.2,
      label:''
    },
    {
      lat:35,
      lon:110.3,
      label:''
    },
    {
      lat:35,
      lon:110.34,
      label:''
    },
    {
      lat:35,
      lon:110.5,
      label:''
    },
    {
      lat:35,
      lon:110.8,
      label:''
    },
    {
      lat:35,
      lon:111,
      label:'来了老弟'
    },
    {
      lat:35.1,
      lon:111,
      label:''
    },
    {
      lat:35.5,
      lon:111,
      label:''
    },
    {
      lat:35.8,
      lon:111,
      label:''
    },
    {
      lat:36,
      lon:111,
      label:'给你一拳'
    },
    {
      lat:36,
      lon:111.4,
      label:''
    },
    {
      lat:36,
      lon:111.5,
      label:''
    },
    {
      lat:36.4,
      lon:111.51,
      label:''
    },
    {
      lat:36.4,
      lon:111.54,
      label:''
    },
    {
      lat:36,
      lon:111.58,
      label:''
    },
    {
      lat:36,
      lon:111.6,
      label:''
    },
    {
      lat:36,
      lon:111.8,
      label:''
    },
    {
      lat:36,
      lon:112,
      label:'给你一脚'
    }]

      //传入地图实例、路径数据、时间(从一个路径点到下一个路径点的时间毫秒)
      showRoute(map,routeData,time){
        const self = this
        //存放拐角点,用以组成拐角点的点图层,显示名字
        let routeDataLonLat = []
        //存放所有运动点,用以组成运动点的点图层,显示名字
        let routeRunDataLonLat = []
        //存放路径,用以组成路径显示
        let routerGeojson = {
          type:'FeatureCollection',
          features:[{
              'type': 'Feature',
              'geometry': {
                  'type': 'LineString',
                  'coordinates': []
              }
          }]
        }
        //塞入节点数据
        routeData.forEach(e=>{
          if(e.label!=''){
            routeDataLonLat.push([e.lon,e.lat])
          }
          routeRunDataLonLat.push([e.lon,e.lat])
          routerGeojson.features[0].geometry.coordinates.push([e.lon,e.lat])
        })
        //去除之前的数据
        if(map.getSource('storyRoute')){
          map.removeLayer('storyRoute')
          map.removeSource('storyRoute')
          map.removeLayer('storyPoint')
          map.removeSource('storyPoint')
        }
        //添加路径图层源和路径图层
        map.addSource('storyRoute',{
          type:'geojson',
          data:[]
        })
        map.addLayer({
            'id': 'storyRoute',
            'source': 'storyRoute',
            'type': 'line',
            'paint': {
                'line-width':4,
                'line-blur': 2,
                'line-color': 'red'
            }
        })
        //添加拐点文字图层源和路径图层
        map.addSource('storyPoint',{
          type:'geojson',
          data:[]
        })
        map.addLayer({
            'id': 'storyPoint',
            'source': 'storyPoint',
            'type': 'symbol',
            'layout': {
                "icon-allow-overlap" : true,
                "text-allow-overlap": true,
                //设置图标的名称
                'text-field':['get','id'],
                'text-size':12,
                'text-font': [ 'Microsoft YaHei' ],
                //"text-font": ["Open Sans Semibold", "Arial Unicode MS Bold"],
                'text-offset': [0, 0.5],
                'text-anchor': 'top'
              },'paint': {//绘制类属性
                'text-color':"#1e42a8",
                'text-halo-color':"#fff",
                'text-halo-width':2,
              }
        })
        //加载图标
        let runIcon = 'https://s1.4sai.com/src/img/png/8a/8aba8e9037214e5c8b88f940a1f80fbc.png?e=1735488000&token=1srnZGLKZ0Aqlz6dk7yF4SkiYf4eP-YrEOdM1sob:Ax43nB9MPCuwkuhFwwtJ3UH7u88='
        map.loadImage(runIcon,function(error,image) {
          if(error) throw error;
          if(!map.hasImage('plane-15')){
            map.addImage('plane-15',image);
          }
        })
        //添加移动图层源和路径图层
        map.addSource('storyPointRun',{
          type:'geojson',
          data:[]
        })
        map.addLayer({
            'id': 'storyPointRun',
            'source': 'storyPointRun',
            'type': 'symbol',
            'layout': {
                "icon-allow-overlap" : true,
                //设置图标的名称
                'icon-image': 'plane-15',
                'icon-size':0.2,
                'icon-rotate': ['get', 'bearing'],
                "icon-offset": [0, 0],
              },'paint': {
              }
        })
        //初始化最终路径点geojson
        let storyPoint = {
          type:'FeatureCollection',
          features:[]
        }
        //初始化最终移动点geojson
        let storyPointRun = {
          type:'FeatureCollection',
          features:[]
        }
        //初始化最终路径geojson
        let storyRoute = {
          type:'FeatureCollection',
          features:[{
              'type': 'Feature',
              'geometry': {
                  'type': 'LineString',
                  'coordinates': []
              }
          }]
        }
        let id = ''
        //把插值路径的数据挨个塞到storyRoute中,不断的setdata,形成路径的动画效果
        routerGeojson.features[0].geometry.coordinates.forEach(function(e,index){
          // console.log(e)
          setTimeout(()=>{
            storyRoute.features[0].geometry.coordinates.push(e)
            map.getSource('storyRoute').setData(storyRoute)
            //设置路径中文字描述的点
            if(self.ifArryInclude(routeDataLonLat,e)){
              routeData.forEach(item=>{
                if(item.lat == e[1]&&item.lon == e[0]){
                  id = item.label
                }
              })
              storyPoint.features.push({
                  'type': 'Feature',
                  'geometry': {
                      'type': 'Point',
                      'coordinates': e
                  },
                  'properties':{
                    'id':id,
                  }
              })
              map.getSource('storyPoint').setData(storyPoint)
            }
            //设置运动点图标轨迹
            if(self.ifArryInclude(routeRunDataLonLat,e)){
              routeData.forEach(item=>{
                if(item.lat == e[1]&&item.lon == e[0]){
                  id = item.label
                }
              })
              storyPointRun.features[0]={
                  'type': 'Feature',
                  'geometry': {
                      'type': 'Point',
                      'coordinates': e
                  },
                  'properties':{
                    'id':id,
                    bearing:30
                  }
              }
              // 设置角度
              storyPointRun.features[0].properties.bearing = turf.bearing(
                  turf.point(
                    routerGeojson.features[0].geometry.coordinates[index-1]
                  ),
                  turf.point(
                    routerGeojson.features[0].geometry.coordinates[index]
                  )
              );
              map.getSource('storyPointRun').setData(storyPointRun)
            }
          },time*index)
        })
      },
      //移除路径图层
      removerRoute(map){
        //去除之前的数据
        if(map.getSource('storyRoute')){
          map.removeLayer('storyRoute')
          map.removeSource('storyRoute')
        }
        if(map.getSource('storyPoint')){
          map.removeLayer('storyPoint')
          map.removeSource('storyPoint')
        }
        if(map.getSource('storyPointRun')){
          map.removeLayer('storyPointRun')
          map.removeSource('storyPointRun')
        }
      },
      // 判断数组2是否包含数组1
      ifArryInclude(multiDimensionalArray, targetArray) {
          for (let i = 0; i < multiDimensionalArray.length; i++) {
              const currentArray = multiDimensionalArray[i];
              
              if (Array.isArray(currentArray) && currentArray.length === targetArray.length) {
                  let match = true;
                  for (let j = 0; j < currentArray.length; j++) {
                      if (currentArray[j] !== targetArray[j]) {
                          match = false;
                          break;
                      }
                  }
                  if (match) {
                      return true;
                  }
              }
          }
          return false;
      },
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值