Files
vue-ts-example/src/pages/cesium-viewer.page.vue
2025-04-07 09:11:12 +08:00

183 lines
6.6 KiB
Vue
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<route lang="yaml">
meta:
layout: false
</route>
<script setup lang="ts">
import type {
HCesiumManagerSatelliteState,
HCesiumManagerStationState,
} from '@/components/h-cesium-viewer/useHCesiumManager.types';
// 地面站和选中状态
const stationState = reactive<HCesiumManagerStationState>({
stations: [],
selectedIds: new Set<string>(),
});
stationState.stations = [
{ height: 50, id: 'gs-bj', latitude: 39.9042, longitude: 116.4074, name: '北京站' },
{ height: 10, id: 'gs-sh', latitude: 31.2304, longitude: 121.4737, name: '上海站' },
{ height: 20, id: 'gs-gz', latitude: 23.1291, longitude: 113.2644, name: '广州站' },
];
// >>>>>>>>> 卫星状态管理 >>>>>>>>>
const satelliteState = reactive<HCesiumManagerSatelliteState>({
satellites: [],
selectedIds: new Set<string>(),
});
onMounted(async () => {
await new Promise((resolve) => setTimeout(resolve, 1000));
// 初始化卫星列表
satelliteState.satellites = [
{
id: 'STARLINK-11371',
tle: `示例-仅卫星
1 62879U 25024A 25062.93300820 .00003305 00000+0 21841-4 0 9995
2 62879 42.9977 257.3937 0001725 269.2925 90.7748 15.77864921 5143`,
showOrbit: false,
showCoverage: false,
showPath: false,
},
{
id: 'ISS (ZARYA)',
tle: `显示-path
1 25544U 98067A 25091.51178241 .00016717 00000+0 30771-3 0 9997
2 25544 51.6416 247.4627 0006703 130.5360 325.0288 15.72125391587775`,
showOrbit: false,
showCoverage: true,
showPath: true,
},
{
id: 'AATLAS CENTAUR 2',
tle: `显示-轨道
1 00694U 63047A 25092.72647061 .00002208 00000+0 26071-3 0 9990
2 00694 30.3579 298.5470 0554905 319.4291 36.6190 14.10324656 83424`,
showOrbit: true,
showCoverage: false,
showPath: true,
},
];
});
// 计算卫星 Checkbox Group 的 options
const satelliteCheckboxOptions = computed(() =>
satelliteState.satellites.map((sat) => ({
// 从 TLE 字符串的第一行提取名称作为标签
label: sat.tle.split('\n')[0].trim(),
value: sat.id,
})),
);
// 为卫星 a-checkbox-group 创建计算属性,处理 Set 和 Array 的转换
const selectedSatelliteIdsArray = computed({
get: () => [...satelliteState.selectedIds], // 从 Set 转换为 Array
set: (val: string[]) => {
satelliteState.selectedIds = new Set(val); // 从 Array 转换回 Set
},
});
// <<<<<<<<< 卫星状态管理 <<<<<<<<<
// 计算 Checkbox Group 的 options
const stationCheckboxOptions = computed(() =>
stationState.stations.map((station) => ({ label: station.name, value: station.id })),
);
// 添加一个随机站点
const addRandomStation = () => {
const randomId = `gs-random-${Math.random().toString(36).slice(7)}`;
const randomLon = Math.random() * 360 - 180; // -180 to 180
const randomLat = Math.random() * 180 - 90; // -90 to 90
const randomHeight = Math.random() * 1000; // 0 to 1000 meters
stationState.stations.push({
height: randomHeight,
id: randomId,
latitude: randomLat,
longitude: randomLon,
name: `随机站 ${randomId.slice(-4)}`,
});
// 创建新的 Set 以触发响应式更新
stationState.selectedIds = new Set([randomId, ...stationState.selectedIds]); // ESLint: 调整顺序
consola.info('添加随机站点:', stationState.stations.at(-1)); // 使用 .at() 访问最后一个元素
};
// 移除最后一个站点
const removeLastStation = () => {
if (stationState.stations.length > 0) {
const removedStation = stationState.stations.pop();
if (removedStation) {
consola.info('移除站点:', removedStation);
// 同时从选中项中移除
// 创建新的 Set 以触发响应式更新
const newSelectedIds = new Set(stationState.selectedIds);
newSelectedIds.delete(removedStation.id);
stationState.selectedIds = newSelectedIds;
}
}
};
// 清空所有选中项
const clearAllStations = () => {
stationState.stations = [];
stationState.selectedIds = new Set(); // 创建新的空 Set 以触发响应式更新
consola.info('清空所有站点');
};
// 为 a-checkbox-group 创建计算属性,处理 Set 和 Array 的转换
const selectedStationIdsArray = computed({
get: () => [...stationState.selectedIds], // 从 Set 转换为 Array
set: (val: string[]) => {
stationState.selectedIds = new Set(val); // 从 Array 转换回 Set
},
});
</script>
<template>
<div class="h-screen w-screen p-4 flex flex-col">
<div class="flex-shrink-0 mb-4 space-y-4">
<!-- 地面站控制 -->
<a-card title="地面站控制" size="small">
<div class="space-x-2">
<a-button size="small" type="primary" @click="addRandomStation">添加随机站点</a-button>
<a-button size="small" @click="removeLastStation" :disabled="stationState.stations.length === 0"
>移除最后一个</a-button
>
<a-button size="small" danger @click="clearAllStations" :disabled="stationState.stations.length === 0"
>清空所有</a-button
>
<span>当前站点数: {{ stationState.stations.length }}</span>
<span> | 选中站点数: {{ stationState.selectedIds.size }}</span>
</div>
<!-- 站点选择 -->
<div mt-2 v-if="stationState.stations.length > 0">
<span class="mr-2">选择要显示的站点:</span>
<a-checkbox-group v-model:value="selectedStationIdsArray" :options="stationCheckboxOptions" />
</div>
</a-card>
<!-- 卫星控制 -->
<a-card title="卫星控制" size="small">
<div class="flex items-center justify-between">
<div>
<span>当前卫星数: {{ satelliteState.satellites.length }}</span>
<span class="ml-2"> | 选中卫星数: {{ satelliteState.selectedIds.size }}</span>
</div>
<!-- 可以添加其他全局卫星控制例如全部显示/隐藏轨道/覆盖 -->
</div>
<div v-if="satelliteState.satellites.length > 0" class="mt-2 space-y-2">
<span class="mr-2 font-medium">选择要显示的卫星:</span>
<a-checkbox-group v-model:value="selectedSatelliteIdsArray" :options="satelliteCheckboxOptions" />
</div>
</a-card>
</div>
<div class="flex-grow w-full rounded-lg border overflow-hidden">
<!-- 将地面站和卫星状态都传递给组件 -->
<h-cesium-viewer :station-state="stationState" :satellite-state="satelliteState">
<div class="absolute top-0 left-0 z-10 p-2 bg-black/30 rounded-br-lg">
<span class="text-white text-xs">叠加 UI 示例</span>
</div>
</h-cesium-viewer>
</div>
</div>
</template>