1. 程式人生 > 其它 >mapbox實現載入多條航線,以及點選某條航線實現飛行效果

mapbox實現載入多條航線,以及點選某條航線實現飛行效果

程式碼在VUE中實現,使用ts語法,某些值是state中的值,自行甄別

航線為以某一機場為中心點,隨機取20點目地點得到

  function createAirline(){
        // 隨機取出航線中的任意條航線(用於測試)
        function RandomNumBoth(arr:any[], maxNum) {
          const numArr = [];
          const arrLength = arr.length;
          for (let i = 0; i < arrLength; i++) {
            //取出隨機數 
            const number = Math.floor(Math.random() * arr.length); //生成隨機數num
            numArr.push(arr[number]); //往新建的數組裡面傳入數值
            arr.splice(number, 1); //傳入一個刪除一個,避免重複
            if (arr.length <= arrLength - maxNum) {
              return numArr;
            }
          }
          console.log(1111);
                
        }

        const origin = data.geoCenter;
        const  destination = RandomNumBoth(data.airportList_.geo,20)
        console.log(destination[0],'機場經緯度');

        for(let i=0;i<destination.length;i++){

          let a ={
                'id': "route",
                'type': 'FeatureCollection',
                'features': [
                    {
                        'type': 'Feature',
                        'geometry': {
                            'type': 'LineString',
                            'coordinates': [origin, destination[i]]
                        }
                    }
                ]
              }  

            map.value?.addSource('route'+i, {
                'type': 'geojson',
                'data': a
            });
            map.value?.addLayer({
                'id': 'route'+i,
                'source': 'route'+i,
                'type': 'line',
                'layout': {
                    "line-join": "round",
                    "line-cap": "round",
                },
                'paint': {
                    'line-width':3,
                    // 'line-blur': 3,
                    'line-opacity': 0.6,
                  
                    'line-color': 'red'
                }
            });   



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

            


 
        let counter = 0;

        map.value?.on("click","route"+i,function(){

            map.value?.addSource('point'+i, {
                'type': 'geojson',
                'data': point
            });

            map.value?.addLayer({
                'id': 'point'+i,
                'source': 'point'+i,
                'type': 'symbol',
                'layout': {
                    'icon-image': 'airport-15',
                    'icon-size': 2,
                    'icon-rotate': ['get', 'bearing'],
                    'icon-rotation-alignment': 'map',
                    'icon-allow-overlap': false,
                    'icon-ignore-placement': true
                },
                "paint": {
                    "icon-color" : "#FF0000"
                }
            });

            const lineDistance = turf.lineDistance(a.features[0], 'kilometers');
            const stepArr = [];
            const steps = 500; // 步數(幀) 
            for (let i = 1; i < lineDistance; i += lineDistance / steps) {
              const lnglat = turf.along(a.features[0], i, 'kilometers');
              stepArr.push(lnglat.geometry.coordinates);
            }
            
            a.features[0].geometry.coordinates = stepArr ;

          

            function animate() {
              // Update point geometry to a new position based on counter denoting
              // the index to access the arc.
              point.features[0].geometry.coordinates =
                  a.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(
                      a.features[0].geometry.coordinates[
                          counter >= steps ? counter - 1 : counter
                      ]
                  ),
                  turf.point(
                      a.features[0].geometry.coordinates[
                          counter >= steps ? counter : counter + 1
                      ]
                  )
              );

              // Update the source with this new data.
              map.value?.getSource('point'+i).setData(point);

              // Request the next frame of animation so long the end has not been reached.
              if (counter < steps) {
                  requestAnimationFrame(animate);
              }

              counter = counter + 1;
              console.log("成功沒");
              
          }
            animate();
        })



        }


      }