当前位置:   article > 正文

Cesium 无人机巡检实时视频投射及模拟数据采集

cesium 无人机

用投射做了两个功能,一个是模拟无人机巡检,展示当前无人机的实时视频流,并且展示当前无人机的拍摄轨迹及范围。 

第二个是直接将无人机的视频投射到拍摄范围面上。

代码都差不多,只是第二个用了实时视频做材质,并且实时计算了视频材质的朝向,不然会出现视频方向和移动方向有差异的情况。

思路:移动使用property来进行设置,让坐标和时间进行关联,视频锥体采用自定义geometry的形式,这部分代码可以参考我的另一篇文章Cesium无人机实时视频投射及关键点拍照展示_easyCesium的博客-CSDN博客

部分代码:

调用代码:

其中做了个视角跟随的效果,即会让视角锁定在飞机正上方

ScanRoam核心代码
1、构建property
 

  1. createProperty(positions, times) {
  2. times = times || 120; // 不设置事件和速度 则默认120s播放完成
  3. var distance = 0;// 总距离
  4. var speed;
  5. for (var i = 0; i < positions.length - 1; i++) {
  6. var oneP = positions[i];
  7. var secP = positions[i + 1];
  8. var dis = Cesium.Cartesian3.distance(oneP, secP);
  9. distance += dis;
  10. }
  11. speed = distance / times; // (米/秒)
  12. this.allDistance = distance;
  13. this.startTime = this.viewer.clock.currentTime;
  14. this.endTime = Cesium.JulianDate.addSeconds(this.startTime, times, new Cesium.JulianDate());
  15. var property = new Cesium.SampledPositionProperty(); // 模型的property
  16. var oldTimes = 0;
  17. for (var i = 1; i < positions.length; i++) {
  18. var nowP = positions[i];
  19. var lastP = positions[i - 1];
  20. if (i == 1) { // 下标从1开始 此处加上第一个点
  21. property.addSample(this.startTime, positions[0]);
  22. }
  23. oldTimes += Cesium.Cartesian3.distance(nowP, lastP) / speed;
  24. var nowTime = Cesium.JulianDate.addSeconds(this.startTime, oldTimes, new Cesium.JulianDate());
  25. property.addSample(nowTime, nowP);
  26. }
  27. return {
  28. property
  29. }
  30. }

2、实时回调:        
 

  1. start() {
  2. this.viewer.clock.currentTime = this.startTime;
  3. this.viewer.clock.shouldAnimate = true;
  4. this.viewer.clock.multiplier = 1;
  5. let last_dis = Number.MAX_VALUE;
  6. // 绑定时间回调
  7. this.viewer.clock.onTick.addEventListener(function () {
  8. let isthan = Cesium.JulianDate.greaterThanOrEquals(this.viewer.clock.currentTime.clone(), this.endTime.clone());
  9. let nowP = this.property.getValue(this.viewer.clock.currentTime.clone());
  10. let nextP = this.positions[this.step + 1];
  11. if (nextP && nowP) {
  12. let dis = Cesium.Cartesian3.distance(nowP.clone(), nextP.clone());
  13. if (dis > last_dis) {
  14. this.step++;
  15. last_dis = Number.MAX_VALUE;
  16. } else {
  17. last_dis = dis;
  18. }
  19. } else {
  20. this.step = this.positions.length - 1;
  21. }
  22. if (isthan) { // 结束
  23. if (this.endFun) this.endFun();
  24. return;
  25. }
  26. let orientation = this.entity.orientation.getValue(this.viewer.clock.currentTime.clone());
  27. let hpr = this.orientation2Hpr(nowP.clone(), orientation)
  28. // 设置模型姿态
  29. if (this.flyingFun) this.flyingFun(nowP, hpr, this.step);
  30. }, this)
  31. }

ConePrimitive核心代码:

  1. getGeometry(dis, fov, aspect) {
  2. let positions = new Float64Array(5 * 3);
  3. fov = Cesium.Math.toRadians(fov / 2);
  4. const tanfov = Math.tan(fov);
  5. const halfw = tanfov * dis;
  6. const halfh = halfw / aspect;
  7. //0 坐标
  8. positions[0] = 0.0;
  9. positions[1] = 0.0;
  10. positions[2] = 0.0;
  11. //1 坐标
  12. positions[3] = 1.0 * halfw;
  13. positions[4] = 1.0 * dis;
  14. positions[5] = 1.0 * halfh;
  15. //2 坐标
  16. positions[6] = -1.0 * halfw;
  17. positions[7] = 1.0 * dis;
  18. positions[8] = 1.0 * halfh;
  19. //3 坐标
  20. positions[9] = -1.0 * halfw;
  21. positions[10] = 1.0 * dis;
  22. positions[11] = -1.0 * halfh;
  23. //4 坐标
  24. positions[12] = 1.0 * halfw;
  25. positions[13] = 1.0 * dis;
  26. positions[14] = -1.0 * halfh;
  27. // 创建顶点属性中的坐标
  28. const attributes = new Cesium.GeometryAttributes({
  29. position: new Cesium.GeometryAttribute({
  30. componentDatatype: Cesium.ComponentDatatype.DOUBLE,
  31. componentsPerAttribute: 3,
  32. values: positions
  33. })
  34. });
  35. // 点的索引
  36. const indices = new Uint16Array(18);
  37. indices[0] = 0;
  38. indices[1] = 4;
  39. indices[2] = 0;
  40. indices[3] = 1;
  41. indices[4] = 0;
  42. indices[5] = 2;
  43. indices[6] = 0;
  44. indices[7] = 3;
  45. indices[8] = 1;
  46. indices[9] = 4;
  47. indices[10] = 4;
  48. indices[11] = 1;
  49. indices[12] = 1;
  50. indices[13] = 2;
  51. indices[14] = 2;
  52. indices[15] = 3;
  53. indices[16] = 3;
  54. indices[17] = 4;
  55. let geometry = new Cesium.Geometry({
  56. attributes: attributes,
  57. indices: indices,
  58. primitiveType: Cesium.PrimitiveType.LINES,
  59. boundingSphere: Cesium.BoundingSphere.fromVertices(positions)
  60. });
  61. return geometry;
  62. }
  63. update(context, frameState, commandList) {
  64. var geometry = this.getGeometry(this.distance, this.fov, this.aspect);
  65. if (!geometry) {
  66. return;
  67. }
  68. if (this._primitive) {
  69. this._primitive.destroy();
  70. this._primitive = undefined;
  71. }
  72. let headingPitchRoll = new Cesium.HeadingPitchRoll(
  73. Cesium.Math.toRadians((this.heading || 0)),
  74. Cesium.Math.toRadians(0),
  75. Cesium.Math.toRadians(this.pitch || 0)
  76. );
  77. var hprmtx = Cesium.Transforms.headingPitchRollToFixedFrame(this.position.clone(), headingPitchRoll);
  78. this._primitive = new Cesium.Primitive({
  79. geometryInstances: new Cesium.GeometryInstance({
  80. geometry: geometry,
  81. attributes: {
  82. color: Cesium.ColorGeometryInstanceAttribute.fromColor(this.outlineColor)
  83. }
  84. }),
  85. appearance: new Cesium.PerInstanceColorAppearance({
  86. translucent: false,
  87. flat: true
  88. }),
  89. modelMatrix: hprmtx,
  90. asynchronous: false,
  91. show: this.coneVisible
  92. });
  93. this.updateRectangle(hprmtx);
  94. this._primitive.update(context, frameState, commandList);
  95. }

功能体验:在线体验

 


 

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/凡人多烦事01/article/detail/583159
推荐阅读
相关标签
  

闽ICP备14008679号