cesium轨道双行数(tle)

2023-10-17 15:50
文章标签 cesium tle 轨道 双行

本文主要是介绍cesium轨道双行数(tle),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

在项目中需要用到卫星绕地球实时观测,查找了很多czml的资料,发现基于cmzl再扩展一些其他的交互(比如实时变换全向光度)非常费劲,于是退而求其次的使用实体(Entity) 来实现,数据量不是特别大的情况下效果还是比较ok的,下面我们来一起实现这个功能吧,先看看下面这张实现的效果图

开始编码之前请确保cesium的版本不低于1.95,本案例就是基于cesium1.95版本实现

1:引入如下库

        Cesium195/Widgets/widgets.css,

        Cesium195/Cesium.js

        satellite.min.js  这个js可以通过npm安装得来

2: 先封装一个卫星类(SatelliteEntity.js),代码如下

class SatelliteEntity {constructor(tle = "", options = {}) {let name = tle[0];let tleLine1 = tle[1];let tleLine2 = tle[2];let circle = tleLine2.slice(52, 64);this.name = name.trim();this.tleLine1 = tleLine1.trim();this.tleLine2 = tleLine2.trim();this.satrec = satellite.twoline2satrec(this.tleLine1, this.tleLine2);this.totalSeconds = 86400;// 24小时this.stepSeconds = 100;this.leadTime = parseInt(24 * 3600 / circle);this.trailTime = 0;}// 获取地心惯性坐标系坐标getPositionEci(time) {return satellite.propagate(this.satrec, time).position;}// 创建PositionProperty_getPositionProperty() {const start = Cesium.JulianDate.fromIso8601(new Date().toISOString());const positionProperty = new Cesium.SampledPositionProperty(Cesium.ReferenceFrame.INERTIAL);let now = Date.now();for (let i = 0; i < this.totalSeconds / this.stepSeconds; i++) {let sateTime = new Date(now + i * this.stepSeconds * 1000);let sateCoord = this.getPositionEci(sateTime);if (!sateCoord) continue;const cesiumTime = Cesium.JulianDate.addSeconds(start, i * this.stepSeconds, new Cesium.JulianDate());const cesiumPosition = { x: sateCoord.x * 1000, y: sateCoord.y * 1000, z: sateCoord.z * 1000 };positionProperty.addSample(cesiumTime, cesiumPosition);}return positionProperty;}// cartesian2转经纬度cartesian2lnglat(viewer,cartesian3){var ellipsoid=viewer.scene.globe.ellipsoid;var cartographic=ellipsoid.cartesianToCartographic(cartesian3);var lat=Cesium.Math.toDegrees(cartographic.latitude);var lng=Cesium.Math.toDegrees(cartographic.longitude);var alt=cartographic.height;return { lng, lat, alt }}// 创建卫星实例createSatelliteEntity(viewer,model) {const start = Cesium.JulianDate.fromIso8601(new Date().toISOString());const stop = Cesium.JulianDate.addSeconds(start, this.totalSeconds, new Cesium.JulianDate());let property = this._getPositionProperty();let satelliteEntity =  viewer.entities.add({name: this.name,description: this.name,availability: new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({ start: start, stop: stop })]),position: property,point: {pixelSize: 8,color: Cesium.Color.fromRandom({ alpha: 1.0 }),// scaleByDistance: new Cesium.NearFarScalar(1.5e3, 1, 8.0e8, 0.5),},model:model,path: new Cesium.PathGraphics({width: 1,show: true,leadTime: this.leadTime,trailTime: this.trailTime,material: Cesium.Color.fromRandom({ alpha: 1.0 }),}),label: {text: this.name,font: '12px sans-serif',showBackground: true,backgroundColor: new Cesium.Color(0.165, 0.165, 0.165, 0.5),backgroundPadding: new Cesium.Cartesian2(4, 4),outlineWidth: 1,verticalOrigin: Cesium.VerticalOrigin.TOP,horizontalOrigin: Cesium.VerticalOrigin.LEFT,pixelOffset: new Cesium.Cartesian2(0, 5),fillColor: Cesium.Color.WHITE,distanceDisplayCondition: new Cesium.DistanceDisplayCondition(10.0, 5000000),}});satelliteEntity.cylinder = {show:true,length: new Cesium.CallbackProperty(() => {let cartesian = satelliteEntity.position.getValue(viewer.clock.currentTime)if(cartesian){let pos = this.cartesian2lnglat(viewer,cartesian)return Cesium.Cartesian3.distance(Cesium.Cartesian3.fromDegrees(pos.lng, pos.lat, pos.alt), Cesium.Cartesian3.fromDegrees(pos.lng, pos.lat, 0))}}, false),topRadius: 0.0,bottomRadius: 400000.0,heightReference:Cesium.HeightReference.CLAMP_TO_GROUND,material: Cesium.Color.fromRandom({ alpha: 0.6 }),outline:false,// outlineColor:color.withAlpha(0.3),// outlineWidth:1,slices:128,// distanceDisplayCondition: new Cesium.DistanceDisplayCondition(0,50000000),}return satelliteEntity;}
}export default SatelliteEntity

3:找到自己的需要的TLE(双行)轨道数据,参考网站:https://celestrak.org/NORAD/elements/,可以在页面通过axios发送请求获取,获取方式如下

//解析
function parseTle(data) {if (data.length === 0) return;let result = data.split("\r\n");let tles = [], i = 0, tem = [];result.forEach(item => {i++;tem.push(item)if (i === 3) {tles.push(tem.join("\r\n"));tem = [];i = 0;}});return tles;
}axios.get('https://celestrak.org/NORAD/elements/gp.php?GROUP=last-30-days&FORMAT=tle').then((response)=> {let tleResult = parseTle(response.data);
})

此处为了演示我就写死了3条tle数据

let tleData = [['aaa','1 11962U 80073A   80253.44930232  .00000016  00000-0  00000+0 0    12','2 11962  81.2400 177.7389 0060506 293.5174  65.9686 14.13684653    07'],['bbb','1 11962U 80073A   80253.52032942  .00000015  00000-0  00000+0 0    22','2 11962  81.2574 177.6557 0031206 251.7983 107.9348 14.06430944    11'],['ccc','1 11962U 80073A   80254.01808565  .00000844  00000-0  48489-3 0    37    22','2 11962  81.2459 177.2133 0031790 270.5020  89.2378 14.07089367    80'],['ddd','1 11962U 80073A   80258.42677503  .00000503  00000-0  28139-3 0    90','2 11962  81.2445 172.9469 0031840 257.9790 101.7807 14.07098597   709']]

数组中的第1个参数代表tle名称

数组中的第2个参数代表第一行,

数组中的第3个参数代表第二行,

两行根数的定义与解析请参考

航天器轨道根数/两行根数的定义/TLE | 李小波

数据准备好了,然后开始码代码咯!

4.先初始化cesium视图

// 引入上面封装的SatelliteEntity类
import SatelliteEntity from './tle/SatelliteEntity.js'// 格式化时间轴Cesium.Timeline.prototype.makeLabel = function (time) {let minutes = 0 - new Date().getTimezoneOffset();let dataZone8 = Cesium.JulianDate.addMinutes(time, minutes, new Cesium.JulianDate());return Cesium.JulianDate.toIso8601(dataZone8).slice(0, 19);}// 加载本地瓦片,没有瓦片资源的请注释掉let buildBaseImageryProvider = new Cesium.UrlTemplateImageryProvider({url: "./map/tile/{z}/{x}/{y}.png",maximumLevel: 3 // 最大级别})const viewer = new Cesium.Viewer("map", {infoBox: false,selectionIndicator: false,navigation: false,animation: true,shouldAnimate: true,timeline: true,baseLayerPicker: false,geocoder: false,homeButton: false,sceneModePicker: false,navigationHelpButton: false,imageryProvider:buildBaseImageryProvider});//取消左键双击事件viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); //去除版权信息viewer._cesiumWidget._creditContainer.style.display = "none";viewer.scene.fxaa = true;viewer.scene.postProcessStages.fxaa.enabled = true;// 地面变灰const currentLayer = viewer.imageryLayers.get(0)currentLayer.brightness = 0.7// 昼夜viewer.scene.globe.enableLighting = true;viewer.shadows = trueviewer.clock.clockRange = Cesium.ClockRange.CLAMPED 

5:循环添加双根数

let tleData = [['aaa','1 11962U 80073A   80253.44930232  .00000016  00000-0  00000+0 0    12','2 11962  81.2400 177.7389 0060506 293.5174  65.9686 14.13684653    07'],['bbb','1 11962U 80073A   80253.52032942  .00000015  00000-0  00000+0 0    22','2 11962  81.2574 177.6557 0031206 251.7983 107.9348 14.06430944    11'],['ccc','1 11962U 80073A   80254.01808565  .00000844  00000-0  48489-3 0    37    22','2 11962  81.2459 177.2133 0031790 270.5020  89.2378 14.07089367    80'],['ddd','1 11962U 80073A   80258.42677503  .00000503  00000-0  28139-3 0    90','2 11962  81.2445 172.9469 0031840 257.9790 101.7807 14.07098597   709']]let modelEntity = viewer.entities.add({model: {show: true,uri: "../satellite/scene.gltf",minimumPixelSize: 105,// 超过5000000米就显示卫星模型distanceDisplayCondition: new Cesium.DistanceDisplayCondition(5000000)}})let model = Cesium.clone(modelEntity.model)tleData.forEach(tle => {let satellite = new SatelliteEntity(tle);satellite.createSatelliteEntity(viewer,model);});

这样就可以成功的添加tle轨道到视图中了

完整代码如下

<html lang="en">
<head><meta charset="UTF-8"/><title>卫星TLE两行数生成轨道跟实体</title><link rel="stylesheet" href="Build/Cesium195/Widgets/widgets.css"><style>*{padding: 0;margin: 0;list-style: none;}.actions{position: absolute;left: 10px;top:20px;z-index: 9;display: flex;}.actions li{padding: 10px;background-color: #00a1ff;color:#fff;cursor: pointer;transition: all;margin-right: 10px;}.actions li:hover{background-color: #0089ff;}</style><script src="Build/Cesium195/Cesium.js"></script><script src="./tle/satellite.min.js"></script></head>
<body ><div id="map" class="fullSize"></div><script type="module">import SatelliteEntity from './tle/SatelliteEntity.js'// 格式化时间轴Cesium.Timeline.prototype.makeLabel = function (time) {let minutes = 0 - new Date().getTimezoneOffset();let dataZone8 = Cesium.JulianDate.addMinutes(time, minutes, new Cesium.JulianDate());return Cesium.JulianDate.toIso8601(dataZone8).slice(0, 19);}let buildBaseImageryProvider = new Cesium.UrlTemplateImageryProvider({url: "./map/tile/{z}/{x}/{y}.png",maximumLevel: 3 // 最大级别})const viewer = new Cesium.Viewer("map", {infoBox: false,selectionIndicator: false,navigation: false,animation: true,shouldAnimate: true,timeline: true,baseLayerPicker: false,geocoder: false,homeButton: false,sceneModePicker: false,navigationHelpButton: false,imageryProvider:buildBaseImageryProvider});// viewer.imageryLayers.addImageryProvider(//     new Cesium.ArcGisMapServerImageryProvider({//         url: "https://services.arcgisonline.com/ArcGIS/rest/services/World_Imagery/MapServer"//     })// )//取消左键双击事件viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK); //去除版权信息viewer._cesiumWidget._creditContainer.style.display = "none";viewer.scene.fxaa = true;viewer.scene.postProcessStages.fxaa.enabled = true;// 地面变灰const currentLayer = viewer.imageryLayers.get(0)currentLayer.brightness = 0.7// 昼夜viewer.scene.globe.enableLighting = true;viewer.shadows = trueviewer.clock.clockRange = Cesium.ClockRange.CLAMPED let tleData = [['aaa','1 11962U 80073A   80253.44930232  .00000016  00000-0  00000+0 0    12','2 11962  81.2400 177.7389 0060506 293.5174  65.9686 14.13684653    07'],['bbb','1 11962U 80073A   80253.52032942  .00000015  00000-0  00000+0 0    22','2 11962  81.2574 177.6557 0031206 251.7983 107.9348 14.06430944    11'],['ccc','1 11962U 80073A   80254.01808565  .00000844  00000-0  48489-3 0    37    22','2 11962  81.2459 177.2133 0031790 270.5020  89.2378 14.07089367    80'],['ddd','1 11962U 80073A   80258.42677503  .00000503  00000-0  28139-3 0    90','2 11962  81.2445 172.9469 0031840 257.9790 101.7807 14.07098597   709']]let modelEntity = viewer.entities.add({model: {show: true,uri: "../satellite/scene.gltf",minimumPixelSize: 105,// 超过5000000米就显示卫星模型distanceDisplayCondition: new Cesium.DistanceDisplayCondition(5000000)}})let model = Cesium.clone(modelEntity.model)tleData.forEach(tle => {let satellite = new SatelliteEntity(tle);satellite.createSatelliteEntity(viewer,model);});</script>
</body>
</html>

这只是一个基本版本,还可以在此基础上添加一些其他的交互功能,比较灵活,有兴趣的朋友可以将扫描的圆锥用传感器来代替,实现的效果更加真实!!!

这篇关于cesium轨道双行数(tle)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/226413

相关文章

poj 2175 最小费用最大流TLE

题意: 一条街上有n个大楼,坐标为xi,yi,bi个人在里面工作。 然后防空洞的坐标为pj,qj,可以容纳cj个人。 从大楼i中的人到防空洞j去避难所需的时间为 abs(xi - pi) + (yi - qi) + 1。 现在设计了一个避难计划,指定从大楼i到防空洞j避难的人数 eij。 判断如果按照原计划进行,所有人避难所用的时间总和是不是最小的。 若是,输出“OPETIMAL",若

我成功在本地打开了Cesium啦!

1首先下载Node.js,我是跟着这篇下载的,https://zhuanlan.zhihu.com/p/77594251,不过这后面的我没弄对Cesium环境配置也没影响。 另外:我看其他推文说,在终端写node -v和npm-v查node和npm的版本可以检测node和npm是否下载成功。 2然后我在CesiumB站官号看的教学视频,跟着下载Cesium源代码。 Cesium基础入门1-零

GIS圈大事件!Cesium被收购了,是好是坏?

大家好,我是日拱一卒的攻城师不浪,致力于技术与艺术的融合。这是2024年输出的第34/100篇文章。 Cesium开发交流群+V:brown_7778(备注来意) 一觉醒来,突然看到Cesium官方发的消息,宣布通过收购的方式加入Bentley软件公司。 可能小伙伴们对Bentley公司还不是很了解。 Bentley 是数字孪生领域的长期合作伙伴,也是开放生态系统的真正支持者。

Cesium 展示——实现昼夜交替

文章目录 需求分析1. 添加2. 移除 需求 Cesium 展示——实现昼夜交替 分析 1. 添加 <

cesium 使用异步函数 getHeightAtPoint,获取指定经纬度点的地形高度。

这个函数使用 CesiumJS 库的 sampleTerrain 方法来获取地形数据。下面是代码的详细解释: async getHeightAtPoint(LngLat) {// 将经纬度转为 Cartographic 对象let cartographics = [Cesium.Cartographic.fromDegrees(LngLat[0], LngLat[1])];// console.

磁吸轨道灯的优缺点深度解析:为你的家居照明提供新选择

在现代家居装修中,照明设计已成为提升居住品质的重要一环。磁吸轨道灯作为一种新兴的照明解决方案,以其独特的灵活性和美观性逐渐受到市场的青睐。然而,任何产品都有其两面性,磁吸轨道灯也不例外。本文将深入探讨磁吸轨道灯的优缺点,并为你种草与无主灯设计相关的灵感,同时确保内容遵循各大平台的规范,避免任何违规营销行为。 磁吸轨道灯的优点 1. 高度灵活性 磁吸轨道灯的最大亮点在于其高度的灵活性。用户可

Cesium中的pick

参考地址–cesium 中的cpupick 和 gpupick 总结: pick ray 射线是利用场景求交集,cpupick,所以可以每次把不需要的mesh 给排除scene pick 基于canvas 二维反算 三维世界坐标的是gpupick 效率会更高

Cesium 展示——绘制等值线图

文章目录 需求分析1. 在指定经纬度范围内进行绘制(两点之间的矩形)2. 在自定义范围内进行绘制(多点之间的不规则范围)升级版 资料 需求 分析 下载安装 引入 npm install cesiumnpm install @turf/turf import *

【GIS开发小课堂】vue3+Cesium.js三维WebGIS项目实战(一)

随着市场对数字孪生的需求日益增多,对于前端从业者的能力从对框架vue、react的要求,逐步扩展到2D、3D空间的交互,为用户提供更紧密的立体交互。近年来前端对GIS的需求日益增多。 本文档详细介绍了使用Vue3和Cesium.js构建三维WebGIS项目的步骤,涵盖Cesium的基础知识、项目搭建、坐标转换、相机系统、地图与地形加载、空间数据管理和交互等内容,旨在为前端开发者提供一个立体交互的

Cesium加载高速公路样式线图层和利用CSS撰写高速公路样式

在ArcGIS软件中是将多个线图层叠加(宽的叠加在下方防止遮盖其他图层)    依照此想法在Cesium中加载高速公路线图层时 在 Cesium 中,直接设置线(如 Polyline)的样式为“高速公路样式”并不直接支持,因为 Cesium 没有内置的特定于高速公路的样式选项。不过,你可以通过自定义线的样式来模拟高速公路的外观,包括在线的外边界添加黑色描边。 要在 Cesium 中实现