当前位置: 首页 > news >正文

Cesium快速入门到精通系列教程十二:Cesium1.74中环绕地球生成​​经线环​​

使用Cesium1.74来实现环绕地球的经线环​​,效果如下:

一、普通实现:

  // 初始化Cesium Viewerconst viewer = new Cesium.Viewer("cesiumContainer", {terrainProvider: Cesium.createWorldTerrain(),shouldAnimate: true,});const drawSpaceLine = spaceLineArr => {const positions = Cesium.Cartesian3.fromDegreesArrayHeights(spaceLineArr);viewer.entities.add({polyline: {positions,width: 2,material: new Cesium.PolylineGlowMaterialProperty({glowPower: 0.1,color: Cesium.Color.CYAN,arcTYPE: Cesium.ArcType.GEODESIC,}),},});};drawSpaceLine([116.2330, -90, 1000000, 116.2330, 90, 1000000]);drawSpaceLine([296.2330, -90, 1000000, 296.2330, 90, 1000000]);

二、优化:通过检查 spaceLineEntity 是否存在来避免重复创建实体

  // 初始化Cesium Viewerconst viewer = new Cesium.Viewer("cesiumContainer", {terrainProvider: Cesium.createWorldTerrain(),shouldAnimate: true,});// 初始化一个线条实体let spaceLineEntity = null;/*** 绘制或更新空间线* @param {Array} spaceLineArr - 线条的经度、纬度和高度数组*/const drawOrUpdateSpaceLine = (spaceLineArr) => {// 如果实体不存在,则创建一个新的if (!spaceLineEntity) {const positions = Cesium.Cartesian3.fromDegreesArrayHeights(spaceLineArr);spaceLineEntity = viewer.entities.add({polyline: {positions: positions,width: 2,arcType: Cesium.ArcType.GEODESIC,material: new Cesium.PolylineGlowMaterialProperty({glowPower: 0.1,color: Cesium.Color.CYAN,}),},});} else {// 如果实体已存在,更新其positionsconst positions = Cesium.Cartesian3.fromDegreesArrayHeights(spaceLineArr);spaceLineEntity.polyline.positions = positions;}};// 示例:绘制一条线条drawOrUpdateSpaceLine([116.233, -90, 1000000, 116.233, 90, 1000000]);// 如果需要不断更新线条,可以这样调用:setInterval(() => {const newSpaceLineArr1 = [116.233 + Math.random() * 10,-90,1000000,116.233 + Math.random() * 10,90,1000000,];drawOrUpdateSpaceLine(newSpaceLineArr1);}, 2000);

三、进一步优化:​​只有当传入的数据(spaceLineArr)发生变化时才更新线条的位置,否则不进行重绘​​。

如何判断数据是否变化?​​

由于 spaceLineArr 是一个数组,直接比较 spaceLineArr 是否变化不能简单地用 === 或 ==,因为 JavaScript 中数组是引用类型,即使内容相同,只要不是同一个引用,=== 也会返回 false。

解决方案​​

缓存上一次的 spaceLineArr​​,每次调用 drawOrUpdateSpaceLine 时,先比较当前传入的 spaceLineArr 和缓存的 spaceLineArr 是否​​深度相等​​(即每个元素都相同)。

如果数据相同,则不更新​​;如果不同,则更新 positions 并缓存新的 spaceLineArr。

// 初始化Cesium Viewer
const viewer = new Cesium.Viewer("cesiumContainer", {terrainProvider: Cesium.createWorldTerrain(),shouldAnimate: true,
});// 初始化一个线条实体
let spaceLineEntity = null;// 缓存上一次的 spaceLineArr
let lastSpaceLineArr = null;/*** 绘制或更新空间线* @param {Array} spaceLineArr - 线条的经度、纬度和高度数组*/
const drawOrUpdateSpaceLine = (spaceLineArr) => {// 如果数据没有变化,则直接返回,不进行重绘if (arraysAreEqual(lastSpaceLineArr, spaceLineArr)) {return;}// 更新缓存的 spaceLineArrlastSpaceLineArr = [...spaceLineArr]; // 使用展开运算符复制数组,避免引用问题// 如果实体不存在,则创建一个新的if (!spaceLineEntity) {const positions = Cesium.Cartesian3.fromDegreesArrayHeights(spaceLineArr);spaceLineEntity = viewer.entities.add({polyline: {positions: positions,width: 2,arcType: Cesium.ArcType.GEODESIC,material: new Cesium.PolylineGlowMaterialProperty({glowPower: 0.1,color: Cesium.Color.CYAN,}),},});} else {// 如果实体已存在,更新其positionsconst positions = Cesium.Cartesian3.fromDegreesArrayHeights(spaceLineArr);spaceLineEntity.polyline.positions = positions;}
};/*** 深度比较两个数组是否相等* @param {Array} arr1 * @param {Array} arr2 * @returns {Boolean}*/
function arraysAreEqual(arr1, arr2) {// 如果两个数组都是 null 或 undefined,认为相等if (arr1 === arr2) return true;if (arr1 == null || arr2 == null) return false;if (arr1.length !== arr2.length) return false;// 逐个比较数组元素for (let i = 0; i < arr1.length; i++) {if (arr1[i] !== arr2[i]) {return false;}}return true;
}// 示例:绘制一条线条
drawOrUpdateSpaceLine([116.233, -90, 1000000, 116.233, 90, 1000000]);// 如果需要不断更新线条,可以这样调用:
setInterval(() => {const newSpaceLineArr1 = [116.233 + Math.random() * 10,-90,1000000,116.233 + Math.random() * 10,90,1000000,];drawOrUpdateSpaceLine(newSpaceLineArr1);
}, 2000);

​优化点​​

  • arraysAreEqual 函数​​:用于深度比较两个数组是否相等,避免不必要的重绘。
  • lastSpaceLineArr 缓存​​:存储上一次传入的 spaceLineArr,每次调用时先比较是否变化。
  • ​​[...spaceLineArr] 复制数组​​:避免直接引用传入的数组,防止外部修改影响缓存判断。

最终效果​​

​​数据变化时​​:更新线条位置。

​​数据不变时​​:跳过重绘,减少 Cesium 的计算开销,提高性能。

http://www.lqws.cn/news/566353.html

相关文章:

  • Javaweb - 7 xml
  • 【智能协同云图库】智能协同云图库第三弹:基于腾讯云 COS 对象存储—开发图片模块
  • 日常 AI 工具汇总
  • Oracle 递归 + Decode + 分组函数实现复杂树形统计进阶(第二课)
  • 深入剖析 Linux 内核网络核心:sock.c 源码解析
  • 阿里云ACP-数据湖和机器学习
  • 解锁Ubuntu安装:从新手到高手的通关秘籍
  • Java 大视界 -- 基于 Java 的大数据分布式存储在科研大数据归档与长期保存中的应用(328)
  • 从UI设计到数字孪生实战演练:打造智慧交通的综合管理平台
  • 鸿蒙 Swiper 组件解析:轮播交互与动画效果全指南
  • 基于STM32的数字频率计设计
  • LoRA训练-理论基础
  • 大模型在恶性心律失常预测及治疗方案制定中的应用研究
  • 智慧水务:未来城市水务管理的创新实践与科技飞跃
  • Go 中的 range 表达式详解:遍历数组、切片、字符串与 Map
  • Docker错误问题解决方法
  • Wpf布局之Canvas面板!
  • 使用 em 单位的好处,以及 em、rem、px 的区别
  • Django ORM 2. 模型(Model)操作
  • 【记录】服务器多用户共享Conda环境——Ubuntu24.04
  • 利用imx6ull板学习裸机arm板开发(6.22-6.24)
  • 商业秘密保护新焦点:企业如何守护核心经营信息?
  • Python商务数据分析——Matplotlib 数据可视化学习笔记
  • Windows环境下C语言汇编语言编辑器及环境安装
  • Windows 环境下设置 RabbitMQ 的 consumer_timeout 参数
  • NoSQL与Redis、HBase、分布式系统详解
  • 深入理解 Dubbo 负载均衡:原理、源码与实践
  • C++文件操作
  • 测试第六讲-开发测试阶段划分
  • 学习记录:DAY35