开始调用模拟飞行:(viewer是初始化地图容器对象,具体可参考文章:Cesium初始化地图对象容器配置项汇总_cesium 初始化容器大小-CSDN博客)
import flyModelRoam from "../utils/GISRoam";// 开始模拟飞行let flyModel = flyModelRoam.flyInit(viewer,allPoints,8,);
暂停飞行:
flyModelRoam.stopFly();
继续飞行:
flyModelRoam.keepFly();
结束飞行:
flyModelRoam.endFly();
控制速度:(如果要回退路径则输入-1)
flyModelRoam.speed();
假数据:
// 所有的飞行轨迹中途点
let allPoints = [{longitude: 121.478,latitude: 31.2356,height: 104},{longitude: 121.477,latitude: 31.2363,height: 120.1},{longitude: 121.477,latitude: 31.237,height: 90.5},{longitude: 121.476,latitude: 31.2377,height: 120.8},{longitude: 121.476,latitude: 31.2384,height: 111.2},{longitude: 121.475,latitude: 31.2391,height: 101.5},{longitude: 121.475,latitude: 31.2398,height: 141.9},{longitude: 121.474,latitude: 31.2405,height: 102.2},{longitude: 121.474,latitude: 31.2412,height: 98.6},{longitude: 121.473,latitude: 31.2419,height: 102.9},{longitude: 121.473,latitude: 31.2426,height: 103.3},{longitude: 121.472,latitude: 31.2433,height: 103.6},{longitude: 121.472,latitude: 31.244,height: 104.0},{longitude: 121.471,latitude: 31.2447,height: 104.3},{longitude: 121.471,latitude: 31.2454,height: 104.7},{longitude: 121.470,latitude: 31.2461,height: 105.0},{longitude: 121.470,latitude: 31.2468,height: 175.4},{longitude: 121.469,latitude: 31.2475,height: 155.7}
]
在utils文件夹中新建GISRoam.js文件,输入如下代码:
import * as Cesium from "cesium";let flyModel = {times: "",startTime: "",stopTime: "",gisModel: [],// 地图容器,点集合,初始速度flyInit(viewer, myPoints, speed) {if (myPoints.length > 0) {// 时间速率倍率,数字越大时间过的越快viewer.clock.multiplier = speed;let sourceCopy = new Array();for (let i = 0; i < myPoints.length; i++) {let obj = {log: myPoints[i].longitude,lat: myPoints[i].latitude,alt: myPoints[i].height,};sourceCopy.push(obj);}// 起始时间this.startTime = Cesium.JulianDate.fromDate(new Date("2023-2-13 11:00:00"));//获取每个杆塔对应的时间点this.times = this.getTimes(sourceCopy, viewer.clock.multiplier);let property = this.computeFlight(sourceCopy);let orientProperty = this.computeOrient(sourceCopy);//添加模型let velocityOrientationProperty = new Cesium.VelocityOrientationProperty(orientProperty);let planeModel = this.addFlyModel(property, velocityOrientationProperty);window.planmodel = planeModel;viewer.flyTo(planeModel, {duration: 1,offset: {heading: Cesium.Math.toRadians(0.0),pitch: Cesium.Math.toRadians(-25),range: 230,},});this.keepFly();return planeModel;}},// 计算点坐标顺便加载点到地图computeFlight(source) {// 取样位置 相当于一个集合let property = new Cesium.SampledPositionProperty();let lineArray = [];for (let i = 0; i < source.length; i++) {let time = Cesium.JulianDate.addSeconds(this.startTime,this.times[i],new Cesium.JulianDate());lineArray.push(source[i].log);lineArray.push(source[i].lat);lineArray.push(source[i].alt);let position = Cesium.Cartesian3.fromDegrees(parseFloat(source[i].log),parseFloat(source[i].lat),parseFloat(source[i].alt));// 添加位置,和时间对应property.addSample(time, position);//同时为我们生成的每个样本创建一个点this.gisModel.push(viewer.entities.add({id: "点" + i,position: position, //定位billboard: {image: "SampleData/fire.png",width: 10,height: 15,verticalOrigin: Cesium.VerticalOrigin.BOTTOM,disableDepthTestDistance: Number.POSITIVE_INFINITY,},}));}this.gisModel.push(viewer.entities.add({id: "线",polyline: {positions: Cesium.Cartesian3.fromDegreesArrayHeights(lineArray),width: 2,material: Cesium.Color.WHITE,show: true,},}));return property;},// 计算插值时间的方位角computeOrient(position) {let property = new Cesium.SampledPositionProperty();this.times = this.getTimes(position, viewer.clock.multiplier);for (let i = 0; i < position.length; i++) {let time = Cesium.JulianDate.addSeconds(this.startTime,this.times[i],new Cesium.JulianDate());// 定死hprlet heading = 20;let pitch = -90;let roll = 45;let hpr = new Cesium.HeadingPitchRoll(heading, pitch, roll);let orientation = Cesium.Quaternion.fromHeadingPitchRoll(hpr);// 添加位置,和时间对应property.addSample(time, orientation);}return property;},// 添加模型addFlyModel(positionProperty, orientProperty) {// 结束时间this.stopTime = Cesium.JulianDate.addDays(this.startTime,3,new Cesium.JulianDate());// 运动轨迹运动一遍后停止viewer.clock.clockRange = Cesium.ClockRange.CLAMPED;// 设置始时钟始时间viewer.clock.startTime = this.startTime.clone();// 设置时钟当前时间viewer.clock.currentTime = this.startTime.clone();// 设置时钟停止时间viewer.clock.stopTime = this.stopTime.clone();let planeModel = viewer.entities.add({// 和时间轴关联availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({start: this.startTime,stop: this.stopTime,}),]),position: positionProperty,// 根据所提供的速度计算点相机角度// orientation: orientProperty,//默认移动方向orientation: new Cesium.VelocityOrientationProperty(positionProperty),// 模型数据model: {uri: "SampleData/models/CesiumAir/Cesium_Air.glb",// 模型最小刻度minimumPixelSize: 80,// 模型最大刻度maximumPixelSize: 100,// 模型是否可见show: true,},// 将路径显示为以1秒为增量采样线path: {material: new Cesium.PolylineGlowMaterialProperty({color: new Cesium.Color.fromAlpha(Cesium.Color.BLUE, 0.9),}),width: 5,show: true,leadTime: 0,loop: false, //是否循环},});this.gisModel.push(planeModel);return planeModel;},// 继续飞行keepFly() {viewer.clock.shouldAnimate = true;},// 停止飞行stopFly() {viewer.clock.shouldAnimate = false;},// 结束飞行endFly() {this.gisModel.forEach((item, e) => {viewer.entities.remove(item);});this.gisModel = [];},// 控制运动速度speed(val) {// 控制时间速率viewer.clockViewModel.multiplier = val;},// 根据速度获取两个点之间的时间getTime(point1, point2, speed) {if (point1 === point2) {return 0.0;}// 计算两个点的空间直角坐标系直线距离let distance = Math.sqrt((point1.x - point2.x) * (point1.x - point2.x) +(point1.y - point2.y) * (point1.y - point2.y) +(point1.z - point2.z) * (point1.z - point2.z)).toFixed(2);if (!speed || speed <= 0) {speed = 4;}// 计算两点之间的时间let time = distance / speed;return time;},getTimes(points, speed) {let _this = this;if (!points || !points.length) {return null;}let times = [];times.push(0.0);if (points.length < 2) {return;}for (let i = 1; i < points.length; i++) {let position = Cesium.Cartesian3.fromDegrees(points[i].log,points[i].lat,points[i].alt);let position1 = Cesium.Cartesian3.fromDegrees(points[i - 1].log,points[i - 1].lat,points[i - 1].alt);let timeSpan1 = _this.getTime(position, position1, speed);// 计算到达每个点的时刻times.push(times[i - 1] + timeSpan1);}return times;},
};
export default flyModel;