您现在的位置是:首页 > 技术教程 正文

Cesium实现动态绘制轨迹线

admin 阅读: 2024-03-29
后台-插件-广告管理-内容页头部广告(手机)

需求就是一个飞机动画,飞机飞到哪里,轨迹线就画到哪里。

我的轨迹线非常长,从我国出发一直到欧洲那边,光是经过的点就有7000多个。

刚开始的时候想要使用的是entity的画线方法进行轨迹线的绘制,如果数据量不大,应该是可以实现的。

整体思路就是:先创建一个PolyLine对象,然后监听时间,每一帧都对实体线对象进行position的更换。伪代码如下:

  1. // 定义折线实体
  2. var polylineEntity = viewer.entities.add({
  3. polyline: {
  4. positions: positions,
  5. width: 5,
  6. material: new Cesium.PolylineGlowMaterialProperty({
  7. glowPower: 0.1,
  8. color: Cesium.Color.YELLOW
  9. })
  10. }
  11. });
  12. viewer.clock.onTick.addEventListener(function() {
  13.     ...
  14.     // 其它操作
  15.     positions进行更新操作
  16. polylineEntity.polyline.positions = positions;
  17. });

但是我使用这种方法的话,虽然代码层面并不会报错,但是不要说轨迹线的绘制了,整个模型的动画都会卡死。

于是开始转变使用primitive对轨迹线进行绘制,总体思路跟entity保持不变,唯一改变的就是我暂时还没找到像polylineEntity.polyline.positions = positions;这样的一句代码,能够直接改变线的位置和经过的点。

所以我采取了比较笨的方法:每一次添加线之前先将前面一条删去,然后再添加一条。听起来似乎对性能要求更高了,但由于primitive使用更底层的方法进行绘制,就算这样进行绘制,对性能的要求也要远远低于之前使用entity的那种方法。至少我现在可以让我的轨迹线正常绘制,只是在距离比较长后还是有一点点的卡帧,不过也还处在可接受的范围内。

代码如下:

  1. // 动态绘制飞机的轨迹线
  2. updatePolyLine(positions, viewer) {
  3.     // 最开始的时候没有线,后面点肯定就不止2个,所以也可以正常移除。
  4. if (positions.length>=2) {
  5. viewer.scene.primitives.remove(window.line);
  6. }
  7. if (positions.length < 2) {
  8.     // 这个地方我是为了在刚开始的时候不要报错,因为primitive绘制线要求至少有两个点
  9. positions = [
  10. new Cesium.Cartesian3.fromDegrees(
  11. 108.89080568,
  12. 34.22720682,
  13. 9997.06879914
  14. ),
  15. new Cesium.Cartesian3.fromDegrees(
  16. 108.86996023,
  17. 34.22265071,
  18. 9994.60869058
  19. ),
  20. ];
  21. }
  22. let LineInstanceArr = [];
  23. //定义折线几何
  24. let polyline = new Cesium.PolylineGeometry({
  25. positions: positions,
  26. width: 5.0,
  27. vertexFormat: Cesium.PolylineColorAppearance.VERTEX_FORMAT,
  28. });
  29. var LineInstance = new Cesium.GeometryInstance({
  30. geometry: polyline,
  31. attributes: {
  32. color: Cesium.ColorGeometryInstanceAttribute.fromColor(
  33. Cesium.Color.RED
  34. ),
  35. },
  36. });
  37. LineInstanceArr.push(LineInstance);
  38.    
  39.   // 这里使用window.line的原因是我不想让vue组件对我的cesium绘制的任何实体进行监控,以免出现效率问题,这在我的另外一篇博客中有提到
  40. window.line = new Cesium.Primitive({
  41. geometryInstances: LineInstanceArr,
  42. //折线外观
  43. appearance: new Cesium.PolylineColorAppearance({
  44. translucent: false,
  45. }),
  46. asynchronous: false,
  47. });
  48. viewer.scene.primitives.add(line);
  49. },

positions就是跟之前entity的positions一个意思,也就是一个列表,里面存放了所有的点的经纬度。

下面演示一下绘制效果:

标签:
声明

1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,请转载时务必注明文章作者和来源,不尊重原创的行为我们将追究责任;3.作者投稿可能会经我们编辑修改或补充。

在线投稿:投稿 站长QQ:1888636

后台-插件-广告管理-内容页尾部广告(手机)
关注我们

扫一扫关注我们,了解最新精彩内容

搜索