卫星科普互动展示系统

This commit is contained in:
2026-03-18 16:38:50 +08:00
parent 267462fc3f
commit 6cca66434b
17 changed files with 86 additions and 19117 deletions

15583
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -24,19 +24,19 @@
},
"devDependencies": {
"@babel/types": "^7.28.1",
"@types/node": "^24.2.1",
"@types/node": "^25.2.3",
"@vitejs/plugin-vue": "^1.1.5",
"@vue/compiler-sfc": "^3.2.26",
"autoprefixer": "^10.2.5",
"cross-env": "^7.0.3",
"electron": "^22.3.27",
"electron": "^40.3.0",
"electron-builder": "^25.0.5",
"postcss": "^8.4.47",
"rimraf": "^3.0.2",
"rollup-plugin-copy": "^3.4.0",
"tailwindcss": "^2.1.1",
"ts-node": "^10.9.2",
"typescript": "^5.8.3",
"typescript": "^5.9.3",
"vite": "^2.0.5"
},
"build": {

View File

@@ -217,6 +217,7 @@ const showRSMC = (model) => {
const handleSatelliteSystemSelect = (value) => {
satelliteSystemName.value = value;
earthViewRef.value.firstClick = true;
earthViewRef.value.resetSceneMode();
};
const handleElementsFly = () => {

View File

@@ -93,8 +93,6 @@
</template>
<script setup>
// import TrackSvg from "../../TrackSvg.vue";
const props = defineProps({
satelliteArr: Array,
allShow: Boolean
@@ -106,7 +104,6 @@ const emit = defineEmits([
"modifySatellitePanel",
"onShowSatelliteControlPanel",
"onShowSatellite",
// "onTrackSatellite",
"clearSatellite",
"showSubSatelliteTable",
"createSubSatellite"
@@ -132,10 +129,6 @@ const onShowSatellite = (index, model) => {
emit("onShowSatellite", index, model);
};
// const onTrackSatellite = (index, model) => {
// emit("onTrackSatellite", index, model);
// };
const clearSatellite = (index, model) => {
emit("clearSatellite", index, model);
};

View File

@@ -619,7 +619,6 @@ const resetData = () => {
satelliteNameData.value = "";
trueAnomalyData.value = "";
beamWidthData.value = "";
satelliteNameCheck.value = true;
nearPointLengthCheck.value = true;
farPointLengthCheck.value = true;
@@ -630,7 +629,6 @@ const resetData = () => {
argumentOfPeriapsisCheck.value = true;
trueAnomalyCheck.value = true;
beamWidthCheck.value = true;
nearPointSelectedData.value = "ORANGE";
farPointSelectedData.value = "PINK";
orbitSelectedData.value = "BLUE";
@@ -672,9 +670,11 @@ const nearPointLengthDataCheck = () => {
} else {
nearPointLengthCheck.value = true;
}
if (nearPointLengthCheck.value == 1 && farPointLengthCheck.value == 1 && farPointLengthData.value !== "" && farPointLengthData.value !== undefined && nearPointLengthData.value > farPointLengthData.value) {
if (nearPointLengthCheck.value == 1 && farPointLengthData.value !== "" && farPointLengthData.value !== undefined && nearPointLengthData.value > farPointLengthData.value) {
nearPointLengthCheck.value = false;
farPointLengthCheck.value = false;
} else {
farPointLengthCheck.value = true;
}
};
@@ -684,9 +684,11 @@ const farPointLengthDataCheck = () => {
} else {
farPointLengthCheck.value = true;
}
if (nearPointLengthCheck.value == 1 && farPointLengthCheck.value == 1 && nearPointLengthData.value !== "" && nearPointLengthData.value !== undefined && nearPointLengthData.value > farPointLengthData.value) {
if (farPointLengthCheck.value == 1 && nearPointLengthData.value !== "" && nearPointLengthData.value !== undefined && nearPointLengthData.value > farPointLengthData.value) {
nearPointLengthCheck.value = false;
farPointLengthCheck.value = false;
} else {
nearPointLengthCheck.value = true;
}
};

View File

@@ -32,7 +32,7 @@
<div class="w-full text-center" style="font-size: 2rem; height: 4rem; line-height: 4rem;">
轨道控制面板
</div>
<div class="text-white text-center flex justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="text-white text-center flex flex-wrap justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="option">
<label>卫星近地点颜色:</label>
<select v-model="nearPointSelected" style="cursor: pointer; color: black;">

View File

@@ -45,7 +45,7 @@
<div class="w-full text-center" style="font-size: 2rem; height: 4rem; line-height: 4rem;">
添加轨道
</div>
<div class="text-white text-center flex justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="text-white text-center flex flex-wrap justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="option">
<label :style="satelliteNameCheck ? '' : 'color: red;'">轨道名称:</label>
<input
@@ -576,9 +576,11 @@ const nearPointLengthDataCheck = () => {
} else {
nearPointLengthCheck.value = true;
}
if (nearPointLengthCheck.value == 1 && farPointLengthCheck.value == 1 && farPointLengthData.value !== "" && farPointLengthData.value !== undefined && nearPointLengthData.value > farPointLengthData.value) {
if (nearPointLengthCheck.value == 1 && farPointLengthData.value !== "" && farPointLengthData.value !== undefined && nearPointLengthData.value > farPointLengthData.value) {
nearPointLengthCheck.value = false;
farPointLengthCheck.value = false;
} else {
farPointLengthCheck.value = true;
}
};
@@ -588,9 +590,11 @@ const farPointLengthDataCheck = () => {
} else {
farPointLengthCheck.value = true;
}
if (nearPointLengthCheck.value == 1 && farPointLengthCheck.value == 1 && nearPointLengthData.value !== "" && nearPointLengthData.value !== undefined && nearPointLengthData.value > farPointLengthData.value) {
if (farPointLengthCheck.value == 1 && nearPointLengthData.value !== "" && nearPointLengthData.value !== undefined && nearPointLengthData.value > farPointLengthData.value) {
nearPointLengthCheck.value = false;
farPointLengthCheck.value = false;
} else {
nearPointLengthCheck.value = true;
}
};

View File

@@ -30,7 +30,7 @@
</el-icon>
</div>
<div class="w-full text-center" style="font-size: 2rem; height: 4rem; line-height: 4rem;">修改轨道数据</div>
<div class="text-white text-center flex justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="text-white text-center flex flex-wrap justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="option">
<label :style="satelliteNameCheck ? '' : 'color: red;'">轨道名称:</label>
<input
@@ -458,9 +458,11 @@ const nearPointLengthModifyCheck = () => {
} else {
nearPointLengthCheck.value = true;
}
if (nearPointLengthCheck.value == 1 && farPointLengthCheck.value == 1 && farPointLengthModify.value !== "" && farPointLengthModify.value !== undefined && nearPointLengthModify.value > farPointLengthModify.value) {
if (nearPointLengthCheck.value == 1 && farPointLengthModify.value !== "" && farPointLengthModify.value !== undefined && nearPointLengthModify.value > farPointLengthModify.value) {
nearPointLengthCheck.value = false;
farPointLengthCheck.value = false;
} else {
farPointLengthCheck.value = true;
}
};
@@ -470,9 +472,11 @@ const farPointLengthModifyCheck = () => {
} else {
farPointLengthCheck.value = true;
}
if (nearPointLengthCheck.value == 1 && farPointLengthCheck.value == 1 && nearPointLengthModify.value !== "" && nearPointLengthModify.value !== undefined && nearPointLengthModify.value > farPointLengthModify.value) {
if (farPointLengthCheck.value == 1 && nearPointLengthModify.value !== "" && nearPointLengthModify.value !== undefined && nearPointLengthModify.value > farPointLengthModify.value) {
nearPointLengthCheck.value = false;
farPointLengthCheck.value = false;
} else {
nearPointLengthCheck.value = true;
}
};

View File

@@ -405,6 +405,8 @@ const generateSubSatellite = (systemModelValue) => {
generateModel.value = "createSub";
generateOrbitSwitch.value = !generateOrbitSwitch.value;
subSatelliteCreatePanelRef.value.show = false;
let subScript = satelliteId.value - 1;
showSubSatelliteTable(subScript);
}
setTimeout(() => {
satelliteArr[satelliteId.value - 1].createSub = true;
@@ -652,9 +654,11 @@ const showSubSatelliteTable = (index) => {
satelliteId.value = index + 1;
if (satelliteArr.length > 0 && satelliteArr[index].subSatelliteArr.length > 0) {
let item = subSatelliteId.value.split("-")[1] - 1;
satelliteArr[index].subSatelliteArr[item].modify = false;
satelliteArr[index].subSatelliteArr[item].control = false;
subSatelliteControlPanelRef.value.show = false;
if (satelliteArr[index].subSatelliteArr[item] !== undefined) {
satelliteArr[index].subSatelliteArr[item].modify = false;
satelliteArr[index].subSatelliteArr[item].control = false;
subSatelliteControlPanelRef.value.show = false;
}
}
subSatelliteModifyPanelRef.value.show = false;
satelliteArr.forEach((element, items) => {
@@ -878,6 +882,9 @@ watch(satelliteId, (value) => {
satelliteControlPanelRef.value.data.orbitSelected.value = satelliteArr[value - 1].controlData.orbitSelected;
satelliteControlPanelRef.value.data.orbitShow.value = satelliteArr[value - 1].controlData.orbitShow;
satelliteControlPanelRef.value.data.satelliteShow.value = satelliteArr[value - 1].controlData.satelliteShow;
if (satelliteArr[value - 1].subSatelliteArr.length > 0) {
subSatelliteId.value = `${value}-${1}`;
}
}
});
@@ -1693,36 +1700,7 @@ const onViewerReady = ({ Cesium, viewer }) => {
viewer.entities.values.find((e) => {
const semiMajorAxis = satelliteArr[satelliteId.value - 1].generateData.semiMajorAxis;
let distanceInfo, velocityInfo, angularVelocityRadPerSecInfo, angularVelocityDegPerSecInfo;
if (e.customId == satelliteId.value && satelliteId.value !== undefined && satelliteArr.length > 0) {
const position = satelliteArr[satelliteId.value - 1].satelliteModel.position.position;
if (position !== undefined && semiMajorAxis !== undefined) {
const { distance, velocity, angularVelocityRadPerSec, angularVelocityDegPerSec } = this._calculateSatelliteData(position, semiMajorAxis);
distanceInfo = distance;
velocityInfo = velocity;
angularVelocityRadPerSecInfo = angularVelocityRadPerSec;
angularVelocityDegPerSecInfo = angularVelocityDegPerSec;
}
satelliteArr[satelliteId.value - 1].satelliteModel.description = `
<ul style="font-size: 1rem; list-style-type: none;">
<li><strong>近地点高度(千米):</strong> ${ Number(satelliteArr[satelliteId.value - 1].generateData.nearPointLength).toFixed(3) }(㎞)</li>
<li><strong>远地点高度(千米):</strong> ${ Number(satelliteArr[satelliteId.value - 1].generateData.farPointLength).toFixed(3) }(㎞)</li>
<li><strong>轨道半长轴(千米):</strong> ${ Number(satelliteArr[satelliteId.value - 1].generateData.semiMajorAxis).toFixed(3) }(㎞)</li>
<li><strong>轨道偏心率:</strong> ${ Number(satelliteArr[satelliteId.value - 1].generateData.eccentricity).toFixed(6) }</li>
<li><strong>轨道周期(秒):</strong> ${ Number(satelliteArr[satelliteId.value - 1].generateData.orbitalPeriod).toFixed(3) }(s)</li>
<li><strong>平均角速度(弧度/秒):</strong> ${ Number(satelliteArr[satelliteId.value - 1].generateData.angularVelocityRad).toFixed(6) }(rad/s)</li>
<li><strong>平均角速度(度/秒):</strong> ${ Number(satelliteArr[satelliteId.value - 1].generateData.angularVelocityDeg).toFixed(6) }(°/s)</li>
<li><strong>轨道倾角(度):</strong> ${ Number(satelliteArr[satelliteId.value - 1].generateData.inclination).toFixed(6) }(°)</li>
<li><strong>升交点赤经(度):</strong> ${ Number(satelliteArr[satelliteId.value - 1].generateData.ascendantRightAscension).toFixed(6) }(°)</li>
<li><strong>近地点角距(度):</strong> ${ Number(satelliteArr[satelliteId.value - 1].generateData.argumentOfPeriapsis).toFixed(6) }(°)</li>
<li><strong>真近点角(度):</strong> ${ Number(satelliteArr[satelliteId.value - 1].generateData.trueAnomaly).toFixed(6) }(°)</li>
<li><strong>波束宽度(度):</strong> ${ Number(satelliteArr[satelliteId.value - 1].generateData.beamWidth).toFixed(6) }(°)</li>
<li><strong>卫星当前位置距地表高度(千米):</strong> ${ Number(distanceInfo).toFixed(3) }(㎞)</li>
<li><strong>卫星当前位置线速度(千米/秒):</strong> ${ Number(velocityInfo).toFixed(3) }(㎞/s)</li>
<li><strong>卫星当前位置角速度(弧度/秒):</strong> ${ Number(angularVelocityRadPerSecInfo).toFixed(6) }(rad/s)</li>
<li><strong>卫星当前位置角速度(度/秒):</strong> ${ Number(angularVelocityDegPerSecInfo).toFixed(6) }(°/s)</li>
</ul>
`;
} else if (e.customId == subSatelliteId.value && subSatelliteId.value !== undefined && satelliteArr.length > 0 && satelliteArr[satelliteId.value - 1].subSatelliteArr.length > 0) {
if (e.customId == subSatelliteId.value && subSatelliteId.value !== undefined && satelliteArr.length > 0 && satelliteArr[satelliteId.value - 1].subSatelliteArr.length > 0) {
let index = Number(subSatelliteId.value.split("-")[1]) - 1;
const position = satelliteArr[satelliteId.value - 1].subSatelliteArr[index].satelliteModel.position.position;
if (position !== undefined && semiMajorAxis !== undefined) {

View File

@@ -32,7 +32,7 @@
<div class="w-full text-center" style="font-size: 2rem; height: 4rem; line-height: 4rem;">
卫星控制面板
</div>
<div class="text-white text-center flex justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="text-white text-center flex flex-wrap justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="option">
<label>显示/隐藏卫星模型:</label>
<input type="checkbox" v-model="subSatelliteModelShow" class="w-6 h-6 cursor-pointer" />

View File

@@ -32,7 +32,7 @@
<div class="w-full text-center" style="font-size: 2rem; height: 4rem; line-height: 4rem;">
添加卫星
</div>
<div class="text-white text-center flex justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="text-white text-center flex flex-wrap justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="option">
<label :style="satelliteNameCheck ? '' : 'color: red;'">卫星名称:</label>
<input
@@ -152,8 +152,22 @@ const data = {
subCylinderSelectedData,
};
const resetData = () => {
subSatelliteNameData.value = "";
subTrueAnomalyData.value = "";
subBeamWidthData.value = "";
satelliteNameCheck.value = true;
trueAnomalyCheck.value = true;
beamWidthCheck.value = true;
satelliteName.value = "BeidouGEO";
satelliteGif.value = "/image/gif/BeidouGEO.gif";
};
const close = () => {
show.value = false;
setTimeout(() => {
resetData();
}, 0);
emit("closeSubSatelliteCreatePanel");
};
@@ -246,6 +260,9 @@ const selectSatelliteModel = () => {
const generateSubSatellite = () => {
if (generateCheck()) {
setTimeout(() => {
resetData();
}, 0);
emit("generateSubSatellite", "subSatellite");
}
};

View File

@@ -30,7 +30,7 @@
</el-icon>
</div>
<div class="w-full text-center" style="font-size: 2rem; height: 4rem; line-height: 4rem;">修改卫星数据</div>
<div class="text-white text-center flex justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="text-white text-center flex flex-wrap justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="option">
<label :style="satelliteNameCheck ? '' : 'color: red;'">卫星名称:</label>
<input

View File

@@ -28,7 +28,7 @@
<div class="w-full text-center" style="font-size: 2rem; height: 4rem; line-height: 4rem;">
场景控制面板
</div>
<div class="text-white text-center flex justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="text-white text-center flex flex-wrap justify-center items-center" style="height: 80%; font-size: 1rem;">
<div class="option">
<label>显示/隐藏地球:</label>
<input

View File

@@ -58,7 +58,20 @@ const showModelTour = () => {
}, 0);
};
defineExpose({ animationShow, firstClick, flyfunc, singleBeamShow, dualBeamShow, showModelTour });
const resetSceneMode = () => {
if(window.document.getElementsByClassName("cesium-toolbar-button")[8]) {
if (window.document.getElementsByClassName("cesium-toolbar-button")[8].children[0].classList[2] == 'cesium-sceneModePicker-button2D') {
firstClick.value = false;
secondClick.value = false;
window.document.getElementsByClassName("cesium-toolbar-button")[8].children[1].click();
setTimeout(() => {
window.document.getElementsByClassName("cesium-toolbar-button")[8].children[2].click();
}, 100);
}
}
};
defineExpose({ animationShow, firstClick, flyfunc, singleBeamShow, dualBeamShow, showModelTour, resetSceneMode });
// 初始化视图参数
const onViewerReady = ({ Cesium, viewer }) => {
@@ -2598,7 +2611,7 @@ const onViewerReady = ({ Cesium, viewer }) => {
setTimeout(() => {
secondClick.value = false;
window.document.getElementsByClassName("cesium-toolbar-button")[8].children[2].click();
}, 0);
}, 100);
return;
}
}

View File

@@ -2465,24 +2465,30 @@ const onDataSourceReady = ({ viewer, cesiumObject }) => {
viewer.scene.primitives._primitives.forEach((element, index) => {
if (element.constructor.name == "CustomPolyline") {
viewer.scene.primitives._primitives.splice(index, 2);
mypolylines = element;
}
if (element.constructor.name == "PolylineCollection") {
// 4K适配版本后将造成列表第一颗卫星模型不显示的bug,故注释掉
// viewer.scene.primitives._primitives.splice(index, 1);
mypolylines = element;
}
// 打包后进行系统切换以及先进行视图切换后进行系统切换时对象名称可能会发生改变,具体名称需要在重装或更新打包依赖库后重新获取
// 2025/12/30 打包后直接进行系统切换时对象名称发生改变 CustomPolyline --> jn
// 2025/12/30 打包后先进行视图切换(3D -> 2D)后进行系统切换时对象名称发生改变 jn --> gt
// 2025/12/30 打包后先进行视图切换(3D -> 哥伦布图)后进行系统切换时对象名称发生改变 jn --> gt
// 2025/12/30 打包后先进行视图切换(3D -> 2D)后进行系统切换时对象名称发生改变 CustomPolyline --> jn
// 2025/12/30 打包后先进行视图切换(3D -> 哥伦布图)后进行系统切换时对象名称发生改变 CustomPolyline --> le
// console.log(element.constructor.name);
if (element.constructor.name == "jn" || element.constructor.name == "gt") {
if (element.constructor.name == "jn" || element.constructor.name == "le") {
viewer.scene.primitives._primitives.splice(index, 2);
mypolylines = element;
}
// 2025/12/30 打包后直接进行系统切换时对象名称未发生改变 PolylineCollection --> PolylineCollection
// 2025/12/30 打包后先进行视图切换(3D -> 2D)后进行系统切换时对象名称未发生改变 PolylineCollection --> PolylineCollection
// 2025/12/30 打包后先进行视图切换(3D -> 哥伦布图)后进行系统切换时对象名称未发生改变 PolylineCollection --> PolylineCollection
if (element.constructor.name == "PolylineCollection") {
// 打包后进行系统切换以及先进行视图切换后进行系统切换时对象名称可能会发生改变,具体名称需要在重装或更新打包依赖库后重新获取
// 2025/12/30 打包后直接进行系统切换时对象名称未发生改变 PolylineCollection --> fn
// 2025/12/30 打包后先进行视图切换(3D -> 2D)后进行系统切换时对象名称未发生改变 PolylineCollection --> S
// 2025/12/30 打包后先进行视图切换(3D -> 哥伦布图)后进行系统切换时对象名称未发生改变 PolylineCollection --> S
if (element.constructor.name == "fn" || element.constructor.name == "S") {
// 4K适配版本后将造成列表第一颗卫星模型不显示的bug,故注释掉
// viewer.scene.primitives._primitives.splice(index, 1);
mypolylines = element;
}
});
viewer.scene.primitives.show = false;

View File

@@ -130,7 +130,7 @@ const changeName = (newName) => {
if (newName !== undefined) {
softwareName.value = newName;
}
}
};
defineExpose({ show, onTrackButtonClicked });

3466
yarn.lock

File diff suppressed because it is too large Load Diff