feat(SAT): add CesiumViewer component and utility functions; update dependencies
All checks were successful
/ depcheck (push) Successful in 1m58s
/ build-and-deploy-to-vercel (push) Successful in 2m4s
/ surge (push) Successful in 1m44s
/ playwright (push) Successful in 2m4s

This commit is contained in:
严浩
2025-02-10 17:34:24 +08:00
parent f26342ddfc
commit 19e46190f1
9 changed files with 206 additions and 22 deletions

View File

@ -64,7 +64,7 @@
"taze": "^18.4.0",
"tdesign-icons-vue-next": "^0.3.4",
"ts-enum-util": "^4.1.0",
"utils4u": "^3.3.0",
"utils4u": "^4.0.0",
"vant": "^4.9.16",
"vite-plugin-webfont-dl": "^3.10.4",
"vue": "^3.5.13",

24
pnpm-lock.yaml generated
View File

@ -94,8 +94,8 @@ importers:
specifier: ^4.1.0
version: 4.1.0
utils4u:
specifier: ^3.3.0
version: 3.3.0(@vueuse/core@12.5.0(typescript@5.7.3))(dayjs@1.11.13)(nprogress@0.2.0)(primevue@4.2.5(vue@3.5.13(typescript@5.7.3)))(vant@4.9.16(vue@3.5.13(typescript@5.7.3)))(vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
specifier: ^4.0.0
version: 4.0.0(@vueuse/core@12.5.0(typescript@5.7.3))(dayjs@1.11.13)(nprogress@0.2.0)(primevue@4.2.5(vue@3.5.13(typescript@5.7.3)))(vant@4.9.16(vue@3.5.13(typescript@5.7.3)))(vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
vant:
specifier: ^4.9.16
version: 4.9.16(vue@3.5.13(typescript@5.7.3))
@ -912,6 +912,10 @@ packages:
resolution: {integrity: sha512-DvpNSxiMrFqYMaGSRDDnQgO/L0MqNH4KWw9CUx8LRHHIdWp08En9DpmSRNpauUOxKpHAhyJJxx92BHZk9J84EQ==}
engines: {node: '>= 16'}
'@intlify/shared@11.1.1':
resolution: {integrity: sha512-2kGiWoXaeV8HZlhU/Nml12oTbhv7j2ufsJ5vQaa0VTjzUmZVdd/nmKFRAOJ/FtjO90Qba5AnZDwsrY7ZND5udA==}
engines: {node: '>= 16'}
'@intlify/unplugin-vue-i18n@6.0.3':
resolution: {integrity: sha512-9ZDjBlhUHtgjRl23TVcgfJttgu8cNepwVhWvOv3mUMRDAhjW0pur1mWKEUKr1I8PNwE4Gvv2IQ1xcl4RL0nG0g==}
engines: {node: '>= 18'}
@ -4905,8 +4909,8 @@ packages:
util-deprecate@1.0.2:
resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
utils4u@3.3.0:
resolution: {integrity: sha512-F/x1wa6jzh5Pnpq8epM3jyvVpuPpDkPlz06vrlqOzqsjNwjvDX+YZkazRzGKbpKRfiX73LXkyOcJdHOmojFpcQ==}
utils4u@4.0.0:
resolution: {integrity: sha512-hOEvgmj8Tjy3Y4dHqOhMRTudjUDxeQx++Wk9Q4I7G2ONNgDnWDr9oPLfQLHGbogKMEgMubVDOH5+aEr2rhDaQw==}
peerDependencies:
'@vueuse/core': ^12.3.0
dayjs: ^1.11.13
@ -5818,12 +5822,14 @@ snapshots:
'@intlify/shared@11.1.0': {}
'@intlify/shared@11.1.1': {}
'@intlify/unplugin-vue-i18n@6.0.3(@vue/compiler-dom@3.5.13)(eslint@9.19.0(jiti@2.4.2))(rollup@4.34.4)(typescript@5.7.3)(vue-i18n@11.1.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))':
dependencies:
'@eslint-community/eslint-utils': 4.4.1(eslint@9.19.0(jiti@2.4.2))
'@intlify/bundle-utils': 10.0.0(vue-i18n@11.1.0(vue@3.5.13(typescript@5.7.3)))
'@intlify/shared': 11.1.0
'@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.0)(@vue/compiler-dom@3.5.13)(vue-i18n@11.1.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
'@intlify/shared': 11.1.1
'@intlify/vue-i18n-extensions': 8.0.0(@intlify/shared@11.1.1)(@vue/compiler-dom@3.5.13)(vue-i18n@11.1.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))
'@rollup/pluginutils': 5.1.4(rollup@4.34.4)
'@typescript-eslint/scope-manager': 8.23.0
'@typescript-eslint/typescript-estree': 8.23.0(typescript@5.7.3)
@ -5845,11 +5851,11 @@ snapshots:
- supports-color
- typescript
'@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.0)(@vue/compiler-dom@3.5.13)(vue-i18n@11.1.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))':
'@intlify/vue-i18n-extensions@8.0.0(@intlify/shared@11.1.1)(@vue/compiler-dom@3.5.13)(vue-i18n@11.1.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3))':
dependencies:
'@babel/parser': 7.26.7
optionalDependencies:
'@intlify/shared': 11.1.0
'@intlify/shared': 11.1.1
'@vue/compiler-dom': 3.5.13
vue: 3.5.13(typescript@5.7.3)
vue-i18n: 11.1.0(vue@3.5.13(typescript@5.7.3))
@ -10224,7 +10230,7 @@ snapshots:
util-deprecate@1.0.2: {}
utils4u@3.3.0(@vueuse/core@12.5.0(typescript@5.7.3))(dayjs@1.11.13)(nprogress@0.2.0)(primevue@4.2.5(vue@3.5.13(typescript@5.7.3)))(vant@4.9.16(vue@3.5.13(typescript@5.7.3)))(vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3)):
utils4u@4.0.0(@vueuse/core@12.5.0(typescript@5.7.3))(dayjs@1.11.13)(nprogress@0.2.0)(primevue@4.2.5(vue@3.5.13(typescript@5.7.3)))(vant@4.9.16(vue@3.5.13(typescript@5.7.3)))(vue-router@4.5.0(vue@3.5.13(typescript@5.7.3)))(vue@3.5.13(typescript@5.7.3)):
optionalDependencies:
'@vueuse/core': 12.5.0(typescript@5.7.3)
dayjs: 1.11.13

View File

@ -9,7 +9,7 @@
</template>
<script setup lang="ts">
const { countdownTime, triggerCountdown, isCounting } = useCountdown($__DEV__ ? 5 : 60);
const { remaining: countdownTime, start: startCountdown, isActive: isCounting } = useCountdown($__DEV__ ? 3 : 60);
const isSending = ref(false);
const sendSms = async () => {
@ -17,7 +17,7 @@ const sendSms = async () => {
isSending.value = true;
try {
await new Promise((resolve) => setTimeout(resolve, 1000));
triggerCountdown();
startCountdown();
ToastService.add({ severity: 'info', summary: '提示', life: 3000, detail: '验证码发送成功' });
} finally {
isSending.value = false;

View File

@ -11,12 +11,16 @@ import {
ImageryLayer,
// VERSION,
EmbeddedTileServiceImageryProvider,
DynamicTimeline,
SpaceEntity,
} from 'orbpro';
// let viewer: Viewer;
import { demoOrbitGeneration } from './fns';
let viewer: Viewer;
onMounted(() => {
new Viewer('cesiumContainer', {
viewer = new Viewer('cesiumContainer', {
// globe: false, //
baseLayerPicker: true,
homeButton: true, // Home
@ -26,10 +30,10 @@ onMounted(() => {
navigationHelpButton: !true, //
projectionPicker: !true, //
sceneModePicker: true, // (2D/3D)
animation: !true, //
animation: true, //
animationContainer: !true,
timeline: !true, // If set to false, the Timeline widget will not be created.
timelineContainer: !true,
timelineContainer: true,
selectionIndicator: true,
requestRenderMode: !true, // CPU/GPU使使{@link Scene#requestRender}API{@link https://cesium.com/blog/2018/01/24/cesium-scene-rendering-performance/|使}
showRenderLoopErrors: true, // HTML
@ -37,11 +41,24 @@ onMounted(() => {
orderIndependentTranslucency: false, //
shadows: true, // Determines if shadows are cast by light sources.
});
viewer.scene.debugShowFramesPerSecond = true;
new DynamicTimeline(viewer.timeline.container, viewer);
// @ts-expect-error Open console to debug app
globalThis.viewer = viewer;
/* if ($__DEV__) */ demoOrbitGeneration(viewer);
});
</script>
<template>
<div id="cesiumContainer" />
<div class="h-full flex flex-col gap-2">
<div class="shrink-0">
<Button @click="demoOrbitGeneration(viewer)">轨道生成</Button>
</div>
<div id="cesiumContainer" class="flex-1" />
</div>
<!--
{#if $selectedEntity}
<SelectionWidget {viewer} />
@ -51,7 +68,6 @@ onMounted(() => {
<style>
#cesiumContainer {
height: 100%;
width: 100%;
}
</style>

148
src/pages/SAT/fns/demo.ts Normal file
View File

@ -0,0 +1,148 @@
import { PromiseConfirmationService } from '@/utils';
import {
Cartesian2,
Cartesian3,
Color,
MakeBillboardLabel,
NearFarScalar,
SpaceCatalogDataSource,
SpaceEntity,
VerticalOrigin,
viewerReferenceFrameMixin,
type Viewer,
} from 'orbpro';
declare global {
interface Window {
spaceCatalog: SpaceCatalogDataSource;
}
}
export async function demoOrbitGeneration(viewer: Viewer) {
window.spaceCatalog = new SpaceCatalogDataSource({ name: 'celestrak' });
viewer.extend(viewerReferenceFrameMixin);
viewer.referenceFrame = 1;
// https://spacedatastandards.org/#/standards?search=OMM
const ISS = new SpaceEntity({
id: '25544',
name: 'ISS',
point: {
pixelSize: 1,
},
label: {
show: false,
font: `1rem Helvetica`,
showBackground: true,
backgroundColor: new Color(0.1, 0.1, 0.1, 0.9),
pixelOffset: new Cartesian2(10, 0),
scaleByDistance: new NearFarScalar(1.5e2, 1.5, 13.0e7, 0.0),
pixelOffsetScaleByDistance: new NearFarScalar(1.5e2, 3.0, 1.5e7, 0.5),
},
viewFrom: new Cartesian3(-1678500.7493507154, -17680994.63403464, 24667690.486357275),
});
ISS.position.loadOMM({
/* CCSDS OMM版本 */ CCSDS_OMM_VERS: 0.0,
/* 创建日期(ISO 8601 UTC格式) */ CREATION_DATE: null,
/* 创建者 */ ORIGINATOR: null,
/* 卫星名称 */ OBJECT_NAME: 'ISS (ZARYA)',
/* 国际标识符(YYYY-NNNAAA) */ OBJECT_ID: '1998-067A',
/* 中心名称(例如:EARTH, MARS) */ CENTER_NAME: null,
/* 参考坐标系 */ REFERENCE_FRAME: 2,
/* 参考坐标系历元(ISO 8601 UTC格式) */ REFERENCE_FRAME_EPOCH: null,
/* 时间系统[M, UTC] */ TIME_SYSTEM: 11,
/* 平均元素理论 */ MEAN_ELEMENT_THEORY: 0,
/* 注释 */ COMMENT: null,
/* 平均开普勒根数的历元(ISO 8601 UTC格式) */ EPOCH: '2024-05-08T19:52:52.426848',
/* 半长轴(km) */ SEMI_MAJOR_AXIS: 0,
/* 平均运动(圈/天) */ MEAN_MOTION: 15.51025615,
/* 偏心率(无量纲) */ ECCENTRICITY: 0.0003349,
/* 轨道倾角(度) */ INCLINATION: 51.6355,
/* 升交点赤经(度) */ RA_OF_ASC_NODE: 150.5366,
/* 近地点幅角(度) */ ARG_OF_PERICENTER: 149.2285,
/* 平近点角(度) */ MEAN_ANOMALY: 210.8902,
/* 引力常数(km³/s²) */ GM: 0,
/* 质量(kg) */ MASS: 0,
/* 太阳辐射面积(m²) */ SOLAR_RAD_AREA: 0,
/* 太阳辐射压系数(无量纲) */ SOLAR_RAD_COEFF: 0,
/* 大气阻力面积(m²) */ DRAG_AREA: 0,
/* 大气阻力系数(无量纲) */ DRAG_COEFF: 0,
/* 星历类型(SGP,SGP4等) */ EPHEMERIS_TYPE: 0,
/* 分类类型,默认'U' */ CLASSIFICATION_TYPE: 'U',
/* NORAD编号 */ NORAD_CAT_ID: 25544,
/* 根数组编号 */ ELEMENT_SET_NO: 999,
/* 历元时的圈次 */ REV_AT_EPOCH: 45244,
/* 气阻系数(1/地球半径) */ BSTAR: 0.00028217,
/* 平均运动一阶导数(圈/天²) */ MEAN_MOTION_DOT: 0.00016275,
/* 平均运动二阶导数(圈/天³) */ MEAN_MOTION_DDOT: 0,
/* 协方差矩阵参考坐标系 */ COV_REFERENCE_FRAME: 23,
/* --- 位置/速度协方差矩阵(6x6下三角) --- */
/* 位置协方差矩阵元素(km²) */ CX_X: 0,
/* 位置协方差矩阵元素(km²) */ CY_X: 0,
/* 位置协方差矩阵元素(km²) */ CY_Y: 0,
/* 位置协方差矩阵元素(km²) */ CZ_X: 0,
/* 位置协方差矩阵元素(km²) */ CZ_Y: 0,
/* 位置协方差矩阵元素(km²) */ CZ_Z: 0,
/* 速度-位置协方差矩阵元素(km²/s) */ CX_DOT_X: 0,
/* 速度-位置协方差矩阵元素(km²/s) */ CX_DOT_Y: 0,
/* 速度-位置协方差矩阵元素(km²/s) */ CX_DOT_Z: 0,
/* 速度协方差矩阵元素(km²/s²) */ CX_DOT_X_DOT: 0,
/* 速度-位置协方差矩阵元素(km²/s) */ CY_DOT_X: 0,
/* 速度-位置协方差矩阵元素(km²/s) */ CY_DOT_Y: 0,
/* 速度-位置协方差矩阵元素(km²/s) */ CY_DOT_Z: 0,
/* 速度协方差矩阵元素(km²/s²) */ CY_DOT_X_DOT: 0,
/* 速度协方差矩阵元素(km²/s²) */ CY_DOT_Y_DOT: 0,
/* 速度-位置协方差矩阵元素(km²/s) */ CZ_DOT_X: 0,
/* 速度-位置协方差矩阵元素(km²/s) */ CZ_DOT_Y: 0,
/* 速度-位置协方差矩阵元素(km²/s) */ CZ_DOT_Z: 0,
/* 速度协方差矩阵元素(km²/s²) */ CZ_DOT_X_DOT: 0,
/* 速度协方差矩阵元素(km²/s²) */ CZ_DOT_Y_DOT: 0,
/* 速度协方差矩阵元素(km²/s²) */ CZ_DOT_Z_DOT: 0,
/* --- 用户自定义字段 --- */
/* 用户自定义BIP-0044类型 */ USER_DEFINED_BIP_0044_TYPE: 0,
/* 用户自定义对象标识符 */ USER_DEFINED_OBJECT_DESIGNATOR: null,
/* 用户自定义地球模型 */ USER_DEFINED_EARTH_MODEL: null,
/* 用户自定义历元时间戳 */ USER_DEFINED_EPOCH_TIMESTAMP: 0,
/* 用户自定义微秒数 */ USER_DEFINED_MICROSECONDS: 0,
});
ISS.point!.pixelSize = 10 as any;
ISS.point!.color = Color.WHITE as any;
MakeBillboardLabel({
entity: ISS,
text: 'ISS-text',
fontSize: 36,
verticalOrigin: VerticalOrigin.CENTER,
});
const issDataSource = new SpaceCatalogDataSource({ name: 'issSource' });
issDataSource.entities.add(ISS);
await viewer.dataSources.add(issDataSource);
// await new Promise((_r) => setTimeout(_r, 1000));
// viewer.camera.flyTo({
// destination: ISS.position.getValue(viewer.clock.currentTime)!,
// orientation: {
// heading: 0.0,
// pitch: -Math.PI / 2,
// roll: 0.0,
// },
// duration: 2,
// });
viewer.extend(viewerReferenceFrameMixin);
viewer.referenceFrame = 1;
const shshowOrbitow = await PromiseConfirmationService({ message: '要显示轨道吗?' });
ISS.showOrbit({ show: shshowOrbitow });
const showCoverage = await PromiseConfirmationService({ message: '要显示覆盖区吗?' });
ISS.showCoverage({ show: showCoverage });
// /* let dynamicTimeline = */ new DynamicTimeline(viewer.timeline.container, viewer);
const track = await PromiseConfirmationService({ message: '要追踪卫星吗?' });
if (track) viewer.trackedEntity = ISS;
}

View File

@ -0,0 +1 @@
export * from './demo.ts';

View File

@ -1,5 +1,5 @@
<script setup lang="ts">
import Viewer from './Viewer.vue';
import CesiumViewer from './CesiumViewer.vue';
const $datatableShow = ref(false);
</script>
@ -8,7 +8,7 @@ const $datatableShow = ref(false);
<div class="relative w-full h-full SAT">
<div id="container" class="absolute w-full h-full select-none">
<div class="viewer" :style="$datatableShow ? 'height:70%' : 'height: 100%'">
<Viewer />
<CesiumViewer />
</div>
<div
:class="[$datatableShow ? 'visible' : 'hidden', 'datatable absolute w-full b-0 l-0']"
@ -33,9 +33,9 @@ const $datatableShow = ref(false);
flex: 1;
}
</style>
<!--
<style scoped>
#container {
background-color: pink;
}
</style>
</style> -->

12
src/utils/index.ts Normal file
View File

@ -0,0 +1,12 @@
export async function PromiseConfirmationService({ message }: { message: string }) {
return await new Promise<boolean>((reslove) => {
ConfirmationService.require({
position: 'bottomright',
modal: false,
header: '提示',
message: message,
accept: () => reslove(true),
reject: () => reslove(false),
});
});
}

View File

@ -87,6 +87,7 @@ export function Plugins() {
dirs: [
// 'src/composables',
'src/stores',
'src/utils',
],
vueTemplate: true,
}),