iClent3D for Cesium 实现无人机巡检飞行效果

作者:gaogy

1、背景

随着地理信息技术的发展,三维地球技术逐渐成为了许多领域中的核心工具,尤其是在城市规划、环境监测、航空航天以及军事领域。三维地图和场景的应用正在帮助人们更加直观地理解空间数据,提供更高效的决策支持。

iClient3D for Cesium 是由 SuperMap 提供的一款开发工具,旨在将三维地理信息系统 (3D GIS) 技术应用于大规模的地理信息可视化与分析,帮助开发者通过 Web 平台展示三维地图,还提供了强大的数据分析功能,包括对建筑物、地形、设施等的空间分析。

本文将利用 iClient3D for Cesium 实现三维场景下的无人机巡检飞行效果,模拟无人机的飞行,并能将无人机拍摄范围以光源形式实时展示于三维场景之中,为低空经济与发展提供有效的无人机可视化飞行效果。

2、无人机飞行效果演示

iClent3D for Cesium 实现无人机巡检飞行效

3、实现过程

3.1、初始化 viewer 场景

function initViewer(viewerContainer) {window.viewer = new Cesium.Viewer(viewerContainer, {shouldAnimate: true,useDefaultRenderLoop: true,infoBox: false,contextOptions: {webgl: {alpha: false,antialias: true,preserveDrawingBuffer: true,failIfMajorPerformanceCaveat: false,depth: true,stencil: false,anialias: false}}})viewer.imageryLayers.addImageryProvider(new Cesium.BingMapsImageryProvider({url: 'https://dev.virtualearth.net',mapStyle: Cesium.BingMapsStyle.AERIAL,key: 'AiCyZH6DplpqBK5CViec7lYcLq941OtnIAvlcVojsyxBfZwUDvp0CsHzZr--U2KY'}))viewer.scene.open('http://www.supermapol.com/realspace/services/3D-CBD/rest/realspace')
}

3.2、自定义 Cesium 飞行 Entity 的 vue hook 如下:

import { onMounted } from 'vue'function getDirection(tagPosition, position) {return Cesium.Cartesian3.normalize(Cesium.Cartesian3.subtract(tagPosition, position, new Cesium.Cartesian3()),new Cesium.Cartesian3())
}function getModelGraphics(options) {if (options) {return new Cesium.ModelGraphics({uri: options.m_url,scale: options.m_scale || 28,minimumPixelSize: options.m_minimumPixelSize || 30,color: options.m_color || Cesium.Color.WHITE})}
}function getLabelGraphics(options) {if (options && options.l_text) {return new Cesium.LabelGraphics({text: options.l_text,font: options.l_font || '14px sans-serif',fillColor: options.l_fillColor || Cesium.Color.GOLD,style: options.l_style || Cesium.LabelStyle.FILL_AND_OUTLINE,outlineWidth: options.l_outlineWidth || 2,outlineColor: options.l_outlineColor || undefined,showBackground: options.l_showBackground || false,backgroundColor: options.l_backgroundColor || new Cesium.Color(0.165, 0.165, 0.165, 0.8),verticalOrigin: options.l_verticalOrigin || Cesium.VerticalOrigin.BOTTOM,pixelOffset: options.l_pixelOffset || new Cesium.Cartesian2(0, -30)//heightReference:Cesium.HeightReference.RELATIVE_TO_GROUND})}
}function getBillboardGraphics(options) {if (options && options.b_img) {return new Cesium.BillboardGraphics({image: options.b_img,width: options.b_width || 35,height: options.b_height || 35,clampToGround: options.b_clampToGround || true,scale: options.b_scale || 1,// eyeOffset :new Cesium.Cartesian2(0, -20),pixelOffset: options.b_pixelOffset || new Cesium.Cartesian2(0, -20),scaleByDistance: options.b_scaleByDistance || undefined// heightReference:Cesium.HeightReference.RELATIVE_TO_GROUND})}
}export default function useCustomEntity(options) {if (window.viewer && options && options.paths) {const _paths = options.pathsconst _positionProperty = new Cesium.SampledPositionProperty()const _rEntity = new Cesium.Entity()const _directionProperty = new Cesium.SampledPositionProperty()const _startTime = new Cesium.JulianDate()let _direction = nulllet _stopTime = nulllet _increment = nulllet _time = nullif (options.times) {let _times = options.times - (options.times % (_paths.length - 1));(_stopTime = Cesium.JulianDate.addSeconds(_startTime, _times, new Cesium.JulianDate())),(_increment = _times / (_paths.length - 1))} else {_stopTime = Cesium.JulianDate.addSeconds(_startTime,(_paths.length - 1) * (options.step || 120),new Cesium.JulianDate())}const startTime = options.startTime || _startTimeconst stopTime = options.stopTime || _stopTimewindow.viewer.clock.startTime = startTime.clone()window.viewer.clock.currentTime = startTime.clone()window.viewer.clock.stopTime = stopTime.clone()window.viewer.clock.multiplier = options.multiplier || 10window.viewer.clock.clockRange = options.clockRange || Cesium.ClockRange.LOOP_STOPfor (let i = 0; i < _paths.length; i++) {const cartesian = Cesium.Cartesian3.fromDegrees(_paths[i].lon, _paths[i].lat, _paths[i].alt)if (options.times) _time = Cesium.JulianDate.addSeconds(startTime, i * _increment, new Cesium.JulianDate())else _time = Cesium.JulianDate.addSeconds(startTime, _paths[i].time, new Cesium.JulianDate())_positionProperty.addSample(_time, cartesian)let directionCartesian = nullif (i === _paths.length - 1) {_directionProperty.addSample(_time, _direction)continue} else {directionCartesian = Cesium.Cartesian3.fromDegrees(_paths[i + 1].lon, _paths[i + 1].lat, _paths[i + 1].alt)}_direction = getDirection(directionCartesian, cartesian)_directionProperty.addSample(_time, _direction)}_rEntity.name = options.name || '漫游Entity'_rEntity.availability = new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start: startTime, stop: stopTime })])_rEntity.position = _positionProperty_rEntity.orientation = new Cesium.VelocityOrientationProperty(_positionProperty)_rEntity.direction = _directionPropertyif (options.model) _rEntity.model = getModelGraphics(options)if (options.label) _rEntity.label = getLabelGraphics(options)if (options.billboard) _rEntity.billboard = getBillboardGraphics(options)onMounted(() => window.viewer.entities.add(_rEntity))return { _rEntity }}
}

3.3、自定义 Cesium 的移动光源的 vue hook 如下:

import { onMounted } from 'vue'export default function useCustomLight(position, options) {if (window.viewer && position) {const DEF_OPTS = {color: options.color || new Cesium.Color(1, 1, 2, 0.8),cutoffDistance: options.cutoffDistance || 1000,decay: options.decay || 0.5,intensity: options.intensity || 1}const _options = options || DEF_OPTSconst customLight = new Cesium.PointLight(position, _options)onMounted(() => window.viewer.scene.addLightSource(customLight))return { customLight }}
}

3.4、向场景添加飞行无人机 Entity

const { _rEntity: flyEntity } = useCustomEntity({paths: [{ lon: 116.44596605973072, lat: 39.90275976224633, alt: 400, time: 0 },{ lon: 116.470769862146, lat: 39.90961660773017, alt: 400, time: 120 },{ lon: 116.44621270736882, lat: 39.912427615595874, alt: 400, time: 240 },{ lon: 116.45867843557505, lat: 39.92072065356812, alt: 400, time: 360 },{ lon: 116.469697344222, lat: 39.91736853889283, alt: 400, time: 480 },{ lon: 116.46625570699818, lat: 39.91100981903596, alt: 400, time: 600 }],model: true,m_url: '/model/CesiumDrone.gltf',label: true,l_text: '无人机一号',l_outlineWidth: 3,l_fillColor: Cesium.Color.CYAN
})

3.5、向场景添加移动光源

const { customLight: light } = useCustomLight(flyEntity.position.getValue(viewer.clock.currentTime), {color: new Cesium.Color(0, 140, 140, 0.8),cutoffDistance: 500,decay: 2,intensity: 5
})

3.6、设置光源跟随无人机 Entity 移动

window.viewer.clock.onTick.addEventListener(() => {light.position = flyEntity.position.getValue(viewer.clock.currentTime)
})

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/494077.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【Qt】显示类控件:QLabel、QLCDNumber、QProgressBar、QCalendarWidget

目录 QLabel QFrame 例子&#xff1a; textFormat pixmap、scaledContents alignment wordWrap、indent、margin buddy QLCDNumber 例子&#xff1a; QTimer QProgressBar 例子&#xff1a; QCalendarWidget 例子&#xff1a; QLabel 标签控件&#xff0c;用来显示…

UVM 验证方法学之interface学习系列文章(十二)virtual interface 终结篇

一 双向和三态问题 任何具有多个驱动器的信号,都需要使用网(net)来建模。网是唯一能够同时解决不同状态和强度驱动同一信号效果的构造。net的行为由内置解析函数定义,该函数使用net上所有驱动器的值和强度。每当其中一个驱动器发生变化时,就会调用该函数来生成解析值。该…

【游戏设计原理】22 - 石头剪刀布

一、游戏基础&#xff1a;拳头、掌心、分指 首先&#xff0c;石头剪刀布&#xff08;又名“Roshambo”&#xff09;看似简单&#xff0c;实际上可是个“深藏玄机”的零和博弈&#xff08;听起来很高深&#xff0c;其实就是输赢相抵消的意思&#xff09;。游戏中有三种手势&…

iterm2 focus时灰色蒙层出现的解决办法

问题描述&#xff1a; 当前我的iterm2版本是3.5.10&#xff0c;是我最近才更新的&#xff0c;然后就出现以下页面显示问题&#xff0c;如图所示&#xff1a; 我个人对终端、编辑器等使用存在洁癖&#xff0c;尤其是页面显示效果不满意更是不能忍受&#xff0c;之前找了很久没有…

如何在window 使用 conda 环境下载大模型

最近开始学习 变形金刚&#xff0c;最大的问题就是 huggingface 无法访问&#xff0c;无论是翻墙还是通过本地镜像网站HF-Mirror&#xff0c;然后再通过git下载都很慢&#xff0c;影响学习进度&#xff0c;后面看了如下文章&#xff0c;Huggingface配置镜像_huggingface镜像-CS…

Linux 网络维护相关命令简介

目录 零. 概要一. ping二. ip命令2.1 ip address2.2 ip route2.3 ip neighbour 三. traceroute四. DNS查询4.1 nslookup4.2 dig 五. ss 查看网络连接状态 零. 概要 ⏹在Linux系统中有2套用于网络管理的工具集 net-tools 早期网络管理的主要工具集&#xff0c;缺乏对 IPv6、网…

Liveweb视频融合共享平台在果园农场等项目中的视频监控系统搭建方案

一、背景介绍 在我国的大江南北遍布着各种各样的果园&#xff0c;针对这些地处偏僻的果园及农场等环境&#xff0c;较为传统的安全防范方式是建立围墙&#xff0c;但是仅靠围墙仍然无法阻挡不法分子的有意入侵和破坏&#xff0c;因此为了及时发现和处理一些难以察觉的问题&…

Ubuntu vi(vim)编辑器配置一键补全main函数

1.打开对应的配置文件 vi ~/.vim/snippets/c.snippets 2.按G将光标定位到文件末尾 3.按i进入插入模式 以tab键开头插入下的内容&#xff0c;空行也要加 tab键 4.:wq保存退出 5.再打开任意一个新的 .c文件后&#xff0c;插入模式输入 main 然后按tal键就能补全了

javaEE-线程的常用方法-4

目录 一.start():启动一个线程 调用start()方法 start()方法只能调用一次&#xff1a; java中的API: start()和run()的区别: 二.中断一个线程 中断线程方法1:引入标志位 中断线程方法2:调⽤interrupt()⽅法 抛出的异常: 三.等待一个线程 join() 四、获取线程引用 五…

服务器数据恢复—V7000存储中多块磁盘出现故障导致业务中断的数据恢复案例

服务器存储数据恢复环境&#xff1a; 一台V7000存储上共12块SAS机械硬盘&#xff08;其中1块是热备盘&#xff09;&#xff0c;组建了2组Mdisk&#xff0c;创建了一个pool。挂载在小型机上作为逻辑盘使用&#xff0c;小型机上安装的AIXSybase。 服务器存储故障&#xff1a; V7…

2024年图像处理、多媒体技术与机器学习

重要信息 官网&#xff1a;www.ipmml.org 时间&#xff1a;2024年12月27-29日 地点&#xff1a;中国-大理 简介 2024年图像处理、多媒体技术与机器学习&#xff08;CIPMT 2024&#xff09;将于2024年12月27-29日于中国大理召开。将围绕图像处理与多媒体技术、机器学习等在…

linux----文件访问(c语言)

linux文件访问相关函数 打开文件函数 - open 函数原型&#xff1a;int open(const char *pathname, int flags, mode_t mode);参数说明&#xff1a; pathname&#xff1a;这是要打开的文件的路径名&#xff0c;可以是绝对路径或者相对路径。例如&#xff0c;"/home/user/…

Redis 集群实操:强大的数据“分身术”

目录 Redis Cluster集群模式 1、介绍 2、架构设计 3、集群模式实操 4、故障转移 5、常用命令 Redis Cluster集群模式 1、介绍 redis3.0版本推出的Redis Cluster 集群模式&#xff0c;每个节点都可以保存数据和整个集群状态&#xff0c;每个节点都和其他所有节点连接。Cl…

探索 Seaborn Palette 的奥秘:为数据可视化增色添彩

一、引言 在数据科学的世界里&#xff0c;视觉传达是不可或缺的一环。一个好的数据可视化不仅能传递信息&#xff0c;还能引发共鸣。Seaborn 是 Python 中一款广受欢迎的可视化库&#xff0c;而它的调色板&#xff08;palette&#xff09;功能&#xff0c;则为我们提供了调配绚…

多模态医学图像融合概述

Part1: Summary 实际应用中&#xff0c;我们常用到多种来源不同数据进行融合&#xff1b; 包括图像分解、重建、融合规则及质量评估。如&#xff1a;MRI、CT、PET、SPECT、US等成像方式; 也可能有点云数据融合 CT&#xff0c;或MR 进行定位等&#xff1b; Part2: 融合数据的…

STM32F103 | Embedded IDE03 - 使用OpenOCD在STM32F103项目时出现下载固件失败

导言 在上一篇备忘录介绍使用OpenOCD的stlink-v2.cfg接口下载固件&#xff0c;在STM32F407的项目上很顺利。但是&#xff0c;在stm32f103上会出现下载失败。 在网上搜了一下&#xff0c;这位博主的文章解决了这个问题: https://www.iotword.com/26738.html 一、修改stm32f1x.c…

Android Studio IDE环境配置

​需要安装哪些东西&#xff1a; Java jdk Java Downloads | OracleAndroid Studio 下载 Android Studio 和应用工具 - Android 开发者 | Android DevelopersAndroid Sdk 现在的Android Studio版本安装时会自动安装&#xff0c;需要注意下安装的路径Android Studio插件…

人工智能ACA(四)--机器学习基础

零、参考资料 一篇文章完全搞懂正则化&#xff08;Regularization&#xff09;-CSDN博客 一、 机器学习概述 0. 机器学习的层次结构 学习范式&#xff08;最高层&#xff09; 怎么学 监督学习 无监督学习 半监督学习 强化学习 学习任务&#xff08;中间层&#xff0…

Qt之QML应用程序开发:给应用程序添加图标文件

开发环境: 1、Qt Creator 14.0.1 2、windows10 先看下面的步骤,不明白再返回来看下面官方指导链接。 先看下面的步骤,不明白再返回来看下面官方指导链接。 先看下面的步骤,不明白再返回来看下面官方指导链接。 --------------------------------------------------------…

代码随想录D24-25 回溯算法03-04 Python

目录 93. 复原 IP 地址 78. 子集 子集问题 90. 子集 II 491. 非递减子序列 46. 全排列 排列问题 47. 全排列 II 332. 重新安排行程 利用字典实现图 51. N 皇后 多维问题入门 37. 解数独 93. 复原 IP 地址 要点&#xff1a; 本质上和上一期的回文字串切分是相似的&am…