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();
})
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南