97.在 Vue 3 中使用 OpenLayers 根据两行根数 (TLE) 计算并显示卫星轨迹(EPSG:3857)
前言
在许多卫星应用场景中,我们需要 基于 TLE(Two-Line Element Set, 两行根数)计算卫星轨迹,并在地图上进行可视化。本文将使用 Vue 3 + OpenLayers + satellite.js,实现 实时计算卫星轨迹,并在地图上动态更新卫星位置,最终效果如下:
📌 功能概览:
- 解析 TLE 数据,计算卫星位置和轨迹。
- 使用 OpenLayers 渲染地图,并展示卫星运动轨迹。
- 每秒动态更新卫星位置,显示卫星的实时飞行状态。
1. 依赖安装
首先,我们需要安装以下依赖:
- OpenLayers:用于地图渲染和矢量图层管理。
- satellite.js:用于解析 TLE 并计算卫星轨迹。
- dayjs:用于处理时间。
在 Vue 3 项目中运行以下命令:
npm install ol satellite.js dayjs
2. 代码实现
<!--* @Author: 彭麒* @Date: 2025/3/7* @Email: 1062470959@qq.com* @Description: 此源码版权归吉檀迦俐所有,可供学习和借鉴或商用。-->
<template><div class="container"><div class="w-full flex justify-center flex-wrap"><div class="font-bold text-[24px]">在Vue3中使用OpenLayers根据两行根数计算并显示卫星轨迹(EPSG:3857)</div></div><div id="vue-openlayers"></div></div>
</template><script setup>
import { ref, onMounted, onBeforeUnmount } from "vue";
import "ol/ol.css";
import Map from "ol/Map";
import View from "ol/View";
import OSM from "ol/source/OSM";
import TileLayer from "ol/layer/Tile";
import VectorLayer from "ol/layer/Vector";
import VectorSource from "ol/source/Vector";
import { Point, LineString } from "ol/geom";
import Feature from "ol/Feature";
import Style from "ol/style/Style";
import Stroke from "ol/style/Stroke";
import Icon from "ol/style/Icon";
import { fromLonLat } from "ol/proj";
import * as satellite from 'satellite.js'; // 引入 satellite.js 库
import dayjs from "dayjs";
import utc from "dayjs/plugin/utc";
import satimg from '@/assets/OpenLayers/satellite.png'; // 引入卫星图标
dayjs.extend(utc);const map = ref(null);
// const satimg = new URL("../assets/img/satellite.svg", import.meta.url).href;
const tleLine1 ="1 25544U 98067A 19156.50900463 .00003075 00000-0 59442-4 0 9992";
const tleLine2 ="2 25544 51.6433 59.2583 0008217 16.4489 347.6017 15.51174618173442";
const satelliteSource = new VectorSource({ wrapX: true });
const satelliteTrackSource = new VectorSource({ wrapX: true });
let timerId = null;// 计算卫星轨迹
const getSatTrack = () => {let curTime = new Date();let lineData = [];for (let i = 0; i < 50; i++) {let newTimePoint = dayjs(curTime).add(i, "minute").toDate();lineData.push(onePoint(newTimePoint));}showTrack(lineData);
};// 根据时间获取卫星的坐标点
const onePoint = (timePoint) => {let satrec = satellite.twoline2satrec(tleLine1, tleLine2);let positionAndVelocity = satellite.propagate(satrec, timePoint);let positionEci = positionAndVelocity.position;let gmst = satellite.gstime(timePoint);let positionGd = satellite.eciToGeodetic(positionEci, gmst);let lon = satellite.degreesLong(positionGd.longitude);let lat = satellite.degreesLat(positionGd.latitude);return fromLonLat([lon, lat]);
};// 获取卫星信息
const getSatInfo = () => {let curPoint = onePoint(new Date());let futurePoint = onePoint(dayjs(new Date()).add(5, "minute").toDate());let dx = futurePoint[0] - curPoint[0];let dy = futurePoint[1] - curPoint[1];let rotation = Math.atan2(dy, dx) + 0.887;showPoint(curPoint, -rotation);
};// 显示卫星
const showPoint = (coords, rotation) => {satelliteSource.clear();let pointFeature = new Feature({geometry: new Point(coords),});pointFeature.setStyle(satStyle(rotation));satelliteSource.addFeature(pointFeature);
};// 显示卫星轨迹
const showTrack = (coords) => {satelliteTrackSource.clear();let lineFeature = new Feature({geometry: new LineString(coords),});lineFeature.setStyle(trackStyle());satelliteTrackSource.addFeature(lineFeature);
};// 轨迹样式
const trackStyle = () =>new Style({stroke: new Stroke({width: 2,color: "orange",}),});// 卫星样式
const satStyle = (rotation) =>new Style({image: new Icon({src: satimg,anchor: [0.5, 0.5],color: "#f00",scale: 0.1,rotation: rotation,}),});const initMap = () => {map.value = new Map({target: "vue-openlayers",layers: [new TileLayer({ source: new OSM() }),new VectorLayer({ source: satelliteTrackSource }),new VectorLayer({ source: satelliteSource }),],view: new View({center: fromLonLat([116, 39]),projection: "EPSG:3857",zoom: 2,}),});getSatTrack();timerId = setInterval(getSatInfo, 1000);
};onMounted(initMap);onBeforeUnmount(() => {clearInterval(timerId);
});
</script><style scoped>
.container {width: 840px;height: 520px;margin: 50px auto;border: 1px solid #42b983;
}
#vue-openlayers {width: 800px;height: 400px;margin: 0 auto;border: 1px solid #42b983;position: relative;
}
</style>
3. 运行效果

🌍 实现功能:
- 地图加载后,自动计算卫星轨迹。
- 每秒更新卫星位置,展示实时飞行状态。
- 卫星图标旋转,与飞行方向一致。
📌 优化方向:
- 支持更多 TLE 数据,让用户输入不同的卫星信息。
- 交互优化,点击卫星查看详细参数。
- 动态轨迹,持续绘制最新轨迹点,而不是每次清空重绘。
4. 结语
本文介绍了如何使用 Vue 3 + OpenLayers + satellite.js 计算并展示 卫星轨迹,希望对你有所帮助!🚀 如果觉得有用,欢迎点赞、收藏! 🎉
相关文章:
97.在 Vue 3 中使用 OpenLayers 根据两行根数 (TLE) 计算并显示卫星轨迹(EPSG:3857)
前言 在许多卫星应用场景中,我们需要 基于 TLE(Two-Line Element Set, 两行根数)计算卫星轨迹,并在地图上进行可视化。本文将使用 Vue 3 OpenLayers satellite.js,实现 实时计算卫星轨迹,并在地图上动态更…...
Android Coil总结
文章目录 Android Coil总结概述添加依赖用法基本用法占位图变形自定义ImageLoader取消加载协程支持缓存清除缓存监听 简单封装 Android Coil总结 概述 Coil 是一个用于 Android 的 Kotlin 图像加载库,旨在简化图像加载和显示的过程。它基于 Kotlin 协程࿰…...
fastjson漏洞#不出网#原理#流量特征
原理 本质是java的反序列化漏洞,由于引进了自动检测类型的(autotype)功能,fastjson在对json字符串反序列化的时候,会读取type内容,会试图将json内容反序列化成这个对象,并调用这个类的setter方…...
云计算:虚拟化、容器化与云存储技术详解
在上一篇中,我们深入探讨了网络安全的核心技术,包括加密、认证和防火墙,并通过实际案例和细节帮助读者全面理解这些技术的应用和重要性。今天,我们将转向一个近年来迅速发展的领域——云计算。云计算通过提供按需访问的计算资源,彻底改变了IT基础设施的构建和管理方式。本…...
使用 marked.min.js 实现 Markdown 编辑器 —— 我的博客后台选择之旅
最近,我决定为个人博客后台换一个编辑器。之前的富文本编辑器虽然功能齐全,但生成的 HTML 代码繁杂,维护起来非常麻烦。为了追求更简洁高效的写作体验,我开始研究 Markdown 编辑器,并最终选择了 marked.min.js。 1. 传…...
Linux系统基于ARM平台的LVGL移植
软硬件介绍:Ubuntu 20.04 ARM 和(Cortex-A53架构)开发板 基本原理 LVGL图形库是支持使用Linux系统的Framebuffer帧缓冲设备实现的,如果想要实现在ARM开发板上运行LVGL图形库,那么就需要把LVGL图形库提供的关于帧缓冲设…...
LeetCode 2070.每一个查询的最大美丽值:排序 + 二分查找
【LetMeFly】2070.每一个查询的最大美丽值:排序 二分查找 力扣题目链接:https://leetcode.cn/problems/most-beautiful-item-for-each-query/ 给你一个二维整数数组 items ,其中 items[i] [pricei, beautyi] 分别表示每一个物品的 价格 和…...
电力场景绝缘子缺陷分割数据集labelme格式1585张4类别
数据集格式:labelme格式(不包含mask文件,仅仅包含jpg图片和对应的json文件) 图片数量(jpg文件个数):1585 标注数量(json文件个数):1585 标注类别数:4 标注类别名称:["broken part","broken insulat…...
【计算机网络】深入解析 HTTP 协议的概念、工作原理和通过 Fiddler 抓包查看 HTTP 请求/响应的协议格式
网络原理— HTTP 1. 什么是HTTP? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议: HTTP 往往是基于传输层的 TCP 协议实现的 (HTTP1.0,HTTP1.1,HTTP2.0 均为TCP,HTTP3基于UDP实现) 我们平时打开一个网站,就是通过HTTP协议来…...
IPFS:下一代互联网传输协议
IPFS:下一代互联网传输协议 1. 引言2. IPFS概述3. IPFS的核心优势3.1 去中心化3.2 高效性3.3 安全性3.4 持久性3.5 可扩展性 4. IPFS的工作原理4.1 内容寻址4.2 分布式哈希表(DHT)4.3 文件分块4.4 版本控制4.5 网络协议 5. IPFS的应用场景5.1…...
线上接口tp99突然升高如何排查?
当线上接口的 TP99 突然升高时,意味着该接口在 99% 的情况下响应时间变长,这可能会严重影响系统的性能和用户体验。可以按照下面的步骤进行排查。这里我们先说明一下如何计算tp99:监控系统计算 TP99(第 99 百分位数的响应时间&…...
SpringBoot优雅关机,监听关机事件,docker配置
Spring Boot 提供了多种方法来实现优雅停机(Graceful Shutdown),这意味着在关闭应用程序之前,它会等待当前正在处理的请求完成,并且不再接受新的请求。 一、优雅停机的基本概念 优雅停机的主要步骤如下: …...
在【k8s】中部署Jenkins的实践指南
🐇明明跟你说过:个人主页 🏅个人专栏:《Kubernetes航线图:从船长到K8s掌舵者》 🏅 🔖行路有良友,便是天堂🔖 目录 一、引言 1、Jenkins简介 2、k8s简介 3、什么在…...
Unity DOTS从入门到精通之 C# Job System
文章目录 前言安装 DOTS 包C# 任务系统Mono 环境DOTS 环境运行作业NativeContainer 前言 作为 DOTS 教程,我们将创建一个旋转立方体的简单程序,并将传统的 Unity 设计转换为 DOTS 设计。 Unity 2022.3.52f1Entities 1.3.10 安装 DOTS 包 要安装 DOTS…...
Spring Boot 本地缓存工具类设计与实现
在 Spring Boot 应用中,缓存是提升性能的重要手段之一。为了更方便地使用缓存,我们可以设计一套通用的本地缓存工具类,封装常见的缓存操作,简化开发流程。本文将详细介绍如何设计并实现一套 Spring Boot 本地缓存工具类࿰…...
【Godot4.4】浅尝Godot中的MVC
概述 基于一个Unity的视频。学习了一下基本的MVC概念,并尝试在Godot中实现了一下。 原始的MVC: Godot中的MVC: Model、View和Controller各自应该实现的功能如下: Model: 属性(数据字段)数据存取方法数据更新信号 View: 控…...
如何解决前端的竞态问题
前端的竞态问题通常是指多个异步操作的响应顺序与发起顺序不一致,导致程序出现不可预测的结果。这种问题在分页、搜索、选项卡切换等场景中尤为常见。以下是几种常见的解决方法: 1. 取消过期请求 当用户发起新的请求时,取消之前的请求&…...
Elasticsearch为索引设置自动时间戳,ES自动时间戳
文章目录 0、思路1、配置 ingest pipeline2、在索引映射中启用_source字段的时间戳3、使用 index template 全局设置时间戳4、写入测试数据5、验证结果6、总结 在使用 Elasticsearch 进行数据存储和检索时,时间戳字段是一个非常重要的组成部分。它可以帮助我们追踪数…...
计算机网络:计算机网络的组成和功能
计算机网络的组成: 计算机网络的工作方式: 计算机网络的逻辑功能; 总结: 计算机网络的功能: 1.数据通信 2.资源共享 3.分布式处理:计算机网络的分布式处理是指将计算任务分散到网络中的多个节点(计算机或设备&…...
FPGA设计时序约束用法大全保姆级说明
目录 一、序言 二、时序约束概览 2.1 约束五大类 2.2 约束功能简述 2.3 跨时钟域约束 三、时序约束规范 3.1 时序约束顺序 3.2 约束的优先级 四、约束示例 4.1 设计代码 4.2 时序结果 4.2.1 create_clock 4.2.2 create_generated_clock 4.2.3 Rename_Auto-Derive…...
云服务运维智能时代:阿里云操作系统控制台
阿里云操作系统控制台 引言需求介绍操作系统使用实例获得的帮助与提升建议 引言 阿里云操作系统控制台是一款创新型云服务器运维工具,专为简化用户的运维工作而设计。它采用智能化和可视化的方式,让运维变得更加高效、直观。借助AI技术,控制…...
硬件学习笔记--48 磁保持继电器相关基础知识介绍
目录 1.磁保持继电器工作原理 2.磁保持继电器内部结构及组成部分 3.磁保持继电器主要参数 4.总结 1.磁保持继电器工作原理 磁保持继电器利用永磁体的磁场和线圈通电产生的磁场相互作用,实现触点的切换。其特点在于线圈断电后,触点状态仍能保持&#…...
【云岚到家】-实战问题(上)
【云岚到家】-实战问题(上) 基础架构项目涉及那些角色云岚的业务流程?云岚家政包括那些模块项目采用什么架构如何开发一个接口?RESTful风格的去定义一个接口如何开发一个接口的service方法接口的异常处理怎么实现的?Sp…...
简记_硬件系统设计之需求分析要点
目录 一、 功能需求 二、 整体性能需求 三、 用户接口需求 四、 功耗需求 五、 成本需求 六、 IP和NEMA防护等级需求 七、 认证需求 功能需求 供电方式及防护 供电方式:市电供电、外置直流稳压电源供电、电池供电、PoE(Power Over Ether…...
K8s 1.27.1 实战系列(五)Namespace
Kubernetes 1.27.1 中的 Namespace(命名空间)是集群中实现多租户资源隔离的核心机制。以下从功能、操作、配置及实践角度进行详细解析: 一、核心功能与特性 1、资源隔离 Namespace 将集群资源划分为逻辑组,实现 Pod、Service、Deployment 等资源的虚拟隔离。例如,…...
ubuntu 20.04下ZEDmini安装使用
提前安装好显卡驱动和cuda,如果没有安装可以参考我的这两篇文章进行安装: ubuntu20.04配置YOLOV5(非虚拟机)_ubuntu20.04安装yolov5-CSDN博客 ubuntu20.04安装显卡驱动及问题总结_乌班图里怎么备份显卡驱动-CSDN博客 还需要提前…...
Deepseek可以通过多种方式帮助CAD加速工作
自动化操作:通过Deepseek的AI能力,可以编写脚本来自动化重复性任务。例如,使用Python脚本调用Deepseek API,在CAD中实现自动化操作。 插件开发:结合Deepseek进行二次开发,可以创建自定义的CAD插件。例如&a…...
tauri-plugin-shell插件将_blank的a标签用浏览器打开了,,,解决办法
不要使用这个插件,这个插件默认会将网页中a标签为_blank的使用默认浏览器打开,但是这种做法在我的程序里不是很友好,我需要自定义这种行为,当我点击我自己的链接的时候,使用默认浏览器打开,当点击别的链接的…...
[20250304] 关于 RISC-V芯片 的介绍
[20250304] 关于 RISC-V芯片 的介绍 1. 调研报告 一、RISC-V 芯片结构分析 RISC-V 芯片基于开源指令集架构(ISA),其核心优势在于模块化设计与高度灵活性。 指令集架构 基础指令集:包含 RV32I(32 位)、R…...
C++ 继承(2)
Hello!!大家早上中午晚上好!!今天收尾继承剩余部分内容!! 一、友元不能继承 基类的友元函数不能被子类继承,也就是基类的友元函数访问不了子类的私有或保护成员! 1.1解决方法在子…...
