fix: make earth satellite and cable toggles fully unload
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "planet-frontend",
|
||||
"version": "0.21.7",
|
||||
"version": "0.21.8",
|
||||
"private": true,
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^5.2.6",
|
||||
|
||||
45
frontend/public/earth/js/controls.js
vendored
45
frontend/public/earth/js/controls.js
vendored
@@ -3,14 +3,18 @@
|
||||
import { CONFIG, EARTH_CONFIG } from "./constants.js";
|
||||
import { updateZoomDisplay, showStatusMessage } from "./ui.js";
|
||||
import { toggleTerrain } from "./earth.js";
|
||||
import { reloadData, clearLockedObject } from "./main.js";
|
||||
import {
|
||||
toggleSatellites,
|
||||
reloadData,
|
||||
clearLockedObject,
|
||||
setCablesEnabled,
|
||||
setSatellitesEnabled,
|
||||
} from "./main.js";
|
||||
import {
|
||||
toggleTrails,
|
||||
getShowSatellites,
|
||||
getSatelliteCount,
|
||||
} from "./satellites.js";
|
||||
import { toggleCables, getShowCables } from "./cables.js";
|
||||
import { getShowCables } from "./cables.js";
|
||||
import { toggleBGP, getShowBGP, getBGPCount } from "./bgp.js";
|
||||
|
||||
export let autoRotate = true;
|
||||
@@ -324,19 +328,24 @@ function setupTerrainControls() {
|
||||
showStatusMessage(showTerrain ? "地形已显示" : "地形已隐藏", "info");
|
||||
});
|
||||
|
||||
bindListener(satellitesBtn, "click", function () {
|
||||
bindListener(satellitesBtn, "click", async function () {
|
||||
const showSats = !getShowSatellites();
|
||||
if (!showSats) {
|
||||
clearLockedObject();
|
||||
}
|
||||
toggleSatellites(showSats);
|
||||
this.classList.toggle("active", showSats);
|
||||
const tooltip = this.querySelector(".tooltip");
|
||||
if (tooltip) tooltip.textContent = showSats ? "隐藏卫星" : "显示卫星";
|
||||
const satelliteCountEl = document.getElementById("satellite-count");
|
||||
if (satelliteCountEl)
|
||||
satelliteCountEl.textContent = getSatelliteCount() + " 颗";
|
||||
showStatusMessage(showSats ? "卫星已显示" : "卫星已隐藏", "info");
|
||||
try {
|
||||
await setSatellitesEnabled(showSats);
|
||||
if (!showSats) {
|
||||
showStatusMessage("卫星已隐藏", "info");
|
||||
} else {
|
||||
const satelliteCountEl = document.getElementById("satellite-count");
|
||||
if (satelliteCountEl) {
|
||||
satelliteCountEl.textContent = `${getSatelliteCount()} 颗`;
|
||||
}
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("切换卫星显示失败:", error);
|
||||
}
|
||||
});
|
||||
|
||||
bindListener(bgpBtn, "click", function () {
|
||||
@@ -365,16 +374,16 @@ function setupTerrainControls() {
|
||||
showStatusMessage(nextShowTrails ? "轨迹已显示" : "轨迹已隐藏", "info");
|
||||
});
|
||||
|
||||
bindListener(cablesBtn, "click", function () {
|
||||
bindListener(cablesBtn, "click", async function () {
|
||||
const showNextCables = !getShowCables();
|
||||
if (!showNextCables) {
|
||||
clearLockedObject();
|
||||
}
|
||||
toggleCables(showNextCables);
|
||||
this.classList.toggle("active", showNextCables);
|
||||
const tooltip = this.querySelector(".tooltip");
|
||||
if (tooltip) tooltip.textContent = showNextCables ? "隐藏线缆" : "显示线缆";
|
||||
showStatusMessage(showNextCables ? "线缆已显示" : "线缆已隐藏", "info");
|
||||
try {
|
||||
await setCablesEnabled(showNextCables);
|
||||
} catch (error) {
|
||||
console.error("切换线缆显示失败:", error);
|
||||
}
|
||||
});
|
||||
|
||||
bindListener(reloadBtn, "click", async () => {
|
||||
|
||||
@@ -38,6 +38,8 @@ import {
|
||||
resetLandingPointVisualState,
|
||||
getShowCables,
|
||||
clearCableData,
|
||||
getLandingPoints,
|
||||
toggleCables,
|
||||
} from "./cables.js";
|
||||
import {
|
||||
createSatellites,
|
||||
@@ -126,6 +128,10 @@ let initialized = false;
|
||||
let destroyed = false;
|
||||
let isDataLoading = false;
|
||||
let currentLoadToken = 0;
|
||||
let cablesEnabled = true;
|
||||
let satellitesEnabled = true;
|
||||
let cableToggleToken = 0;
|
||||
let satelliteToggleToken = 0;
|
||||
|
||||
const clock = new THREE.Clock();
|
||||
const interactionRaycaster = new THREE.Raycaster();
|
||||
@@ -344,6 +350,124 @@ function buildLoadErrorMessage(errors) {
|
||||
.join(";");
|
||||
}
|
||||
|
||||
function updateSatelliteToggleUi(enabled, satelliteCount = getSatelliteCount()) {
|
||||
const satBtn = document.getElementById("toggle-satellites");
|
||||
if (satBtn) {
|
||||
satBtn.classList.toggle("active", enabled);
|
||||
const tooltip = satBtn.querySelector(".tooltip");
|
||||
if (tooltip) tooltip.textContent = enabled ? "隐藏卫星" : "显示卫星";
|
||||
}
|
||||
|
||||
const satelliteCountEl = document.getElementById("satellite-count");
|
||||
if (satelliteCountEl) {
|
||||
satelliteCountEl.textContent = `${enabled ? satelliteCount : 0} 颗`;
|
||||
}
|
||||
}
|
||||
|
||||
function updateCableToggleUi(enabled) {
|
||||
const cableBtn = document.getElementById("toggle-cables");
|
||||
if (cableBtn) {
|
||||
cableBtn.classList.toggle("active", enabled);
|
||||
const tooltip = cableBtn.querySelector(".tooltip");
|
||||
if (tooltip) tooltip.textContent = enabled ? "隐藏线缆" : "显示线缆";
|
||||
}
|
||||
|
||||
const cableCountEl = document.getElementById("cable-count");
|
||||
if (cableCountEl) {
|
||||
cableCountEl.textContent = `${enabled ? getCableLines().length : 0}个`;
|
||||
}
|
||||
|
||||
const landingPointCountEl = document.getElementById("landing-point-count");
|
||||
if (landingPointCountEl) {
|
||||
landingPointCountEl.textContent = `${enabled ? getLandingPoints().length : 0}个`;
|
||||
}
|
||||
|
||||
const statusEl = document.getElementById("cable-status-summary");
|
||||
if (statusEl && !enabled) {
|
||||
statusEl.textContent = "0/0 运行中";
|
||||
}
|
||||
}
|
||||
|
||||
async function ensureCablesEnabled() {
|
||||
if (!scene || !camera || !renderer || destroyed) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
const earth = getEarth();
|
||||
if (!earth) return 0;
|
||||
|
||||
cablesEnabled = true;
|
||||
const requestToken = ++cableToggleToken;
|
||||
|
||||
clearCableData(earth);
|
||||
const [cableCount] = await Promise.all([
|
||||
loadGeoJSONFromPath(scene, earth),
|
||||
loadLandingPoints(scene, earth),
|
||||
]);
|
||||
|
||||
if (requestToken !== cableToggleToken || !cablesEnabled || destroyed) {
|
||||
clearCableData(earth);
|
||||
return 0;
|
||||
}
|
||||
|
||||
toggleCables(true);
|
||||
updateCableToggleUi(true);
|
||||
setLegendItems("cables", getCableLegendItems());
|
||||
refreshLegend();
|
||||
return cableCount;
|
||||
}
|
||||
|
||||
function disableCables() {
|
||||
cablesEnabled = false;
|
||||
cableToggleToken += 1;
|
||||
clearCableData(getEarth());
|
||||
updateCableToggleUi(false);
|
||||
setLegendItems("cables", getCableLegendItems());
|
||||
refreshLegend();
|
||||
}
|
||||
|
||||
async function ensureSatellitesEnabled() {
|
||||
if (!scene || !camera || !renderer || destroyed) return 0;
|
||||
|
||||
const earth = getEarth();
|
||||
if (!earth) return 0;
|
||||
|
||||
satellitesEnabled = true;
|
||||
const requestToken = ++satelliteToggleToken;
|
||||
|
||||
if (!getSatellitePoints()) {
|
||||
createSatellites(scene, earth);
|
||||
}
|
||||
|
||||
clearSatelliteData();
|
||||
const satelliteCount = await loadSatellites();
|
||||
|
||||
if (
|
||||
requestToken !== satelliteToggleToken ||
|
||||
!satellitesEnabled ||
|
||||
destroyed
|
||||
) {
|
||||
resetSatelliteState();
|
||||
return 0;
|
||||
}
|
||||
|
||||
updateSatellitePositions(POSITION_UPDATE_FORCE_DELTA, true);
|
||||
toggleSatellites(true);
|
||||
updateSatelliteToggleUi(true, satelliteCount);
|
||||
setLegendItems("satellites", getSatelliteLegendItems());
|
||||
refreshLegend();
|
||||
return satelliteCount;
|
||||
}
|
||||
|
||||
function disableSatellites() {
|
||||
satellitesEnabled = false;
|
||||
satelliteToggleToken += 1;
|
||||
resetSatelliteState();
|
||||
updateSatelliteToggleUi(false, 0);
|
||||
setLegendItems("satellites", getSatelliteLegendItems());
|
||||
refreshLegend();
|
||||
}
|
||||
|
||||
function updateStatsSummary() {
|
||||
updateEarthStats({
|
||||
cableCount: getCableLines().length,
|
||||
@@ -479,25 +603,8 @@ async function loadData(showWhiteSphere = false) {
|
||||
}
|
||||
|
||||
const results = await Promise.allSettled([
|
||||
loadGeoJSONFromPath(scene, earth),
|
||||
loadLandingPoints(scene, earth),
|
||||
(async () => {
|
||||
clearSatelliteData();
|
||||
const satelliteCount = await loadSatellites();
|
||||
const satelliteCountEl = document.getElementById("satellite-count");
|
||||
if (satelliteCountEl) {
|
||||
satelliteCountEl.textContent = `${satelliteCount} 颗`;
|
||||
}
|
||||
updateSatellitePositions(POSITION_UPDATE_FORCE_DELTA, true);
|
||||
toggleSatellites(true);
|
||||
const satBtn = document.getElementById("toggle-satellites");
|
||||
if (satBtn) {
|
||||
satBtn.classList.add("active");
|
||||
const tooltip = satBtn.querySelector(".tooltip");
|
||||
if (tooltip) tooltip.textContent = "隐藏卫星";
|
||||
}
|
||||
return satelliteCount;
|
||||
})(),
|
||||
cablesEnabled ? ensureCablesEnabled() : Promise.resolve(0),
|
||||
satellitesEnabled ? ensureSatellitesEnabled() : Promise.resolve(0),
|
||||
(async () => {
|
||||
clearBGPData(earth);
|
||||
const bgpResult = await loadBGPAnomalies(scene, earth);
|
||||
@@ -526,13 +633,10 @@ async function loadData(showWhiteSphere = false) {
|
||||
errors.push({ label: "电缆", reason: results[0].reason });
|
||||
}
|
||||
if (results[1].status === "rejected") {
|
||||
errors.push({ label: "登陆点", reason: results[1].reason });
|
||||
errors.push({ label: "卫星", reason: results[1].reason });
|
||||
}
|
||||
if (results[2].status === "rejected") {
|
||||
errors.push({ label: "卫星", reason: results[2].reason });
|
||||
}
|
||||
if (results[3].status === "rejected") {
|
||||
errors.push({ label: "BGP异常", reason: results[3].reason });
|
||||
errors.push({ label: "BGP异常", reason: results[2].reason });
|
||||
}
|
||||
|
||||
if (errors.length > 0) {
|
||||
@@ -545,6 +649,8 @@ async function loadData(showWhiteSphere = false) {
|
||||
}
|
||||
|
||||
updateStatsSummary();
|
||||
updateCableToggleUi(cablesEnabled);
|
||||
updateSatelliteToggleUi(satellitesEnabled);
|
||||
setLegendItems("cables", getCableLegendItems());
|
||||
setLegendItems("satellites", getSatelliteLegendItems());
|
||||
setLegendItems("bgp", getBGPLegendItems());
|
||||
@@ -565,6 +671,75 @@ export async function reloadData() {
|
||||
await loadData(true);
|
||||
}
|
||||
|
||||
export async function setCablesEnabled(enabled) {
|
||||
if (enabled === cablesEnabled) {
|
||||
updateCableToggleUi(enabled);
|
||||
return getCableLines().length;
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
clearLockedObject();
|
||||
hideInfoCard();
|
||||
disableCables();
|
||||
showStatusMessage("线缆已隐藏", "info");
|
||||
return 0;
|
||||
}
|
||||
|
||||
setLoadingMessage("正在加载线缆数据...", "重建海缆与登陆点对象");
|
||||
setLoading(true);
|
||||
hideError();
|
||||
|
||||
try {
|
||||
const cableCount = await ensureCablesEnabled();
|
||||
showStatusMessage("线缆已显示", "info");
|
||||
return cableCount;
|
||||
} catch (error) {
|
||||
cablesEnabled = false;
|
||||
clearCableData(getEarth());
|
||||
updateCableToggleUi(false);
|
||||
const message = `线缆加载失败: ${error?.message || String(error)}`;
|
||||
showError(message);
|
||||
showStatusMessage(message, "error");
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
export async function setSatellitesEnabled(enabled) {
|
||||
if (enabled === satellitesEnabled) {
|
||||
updateSatelliteToggleUi(enabled);
|
||||
return getSatelliteCount();
|
||||
}
|
||||
|
||||
if (!enabled) {
|
||||
clearLockedObject();
|
||||
hideInfoCard();
|
||||
disableSatellites();
|
||||
return 0;
|
||||
}
|
||||
|
||||
setLoadingMessage("正在加载卫星数据...", "重建卫星点位与轨迹缓存");
|
||||
setLoading(true);
|
||||
hideError();
|
||||
|
||||
try {
|
||||
const satelliteCount = await ensureSatellitesEnabled();
|
||||
showStatusMessage("卫星已显示", "info");
|
||||
return satelliteCount;
|
||||
} catch (error) {
|
||||
satellitesEnabled = false;
|
||||
resetSatelliteState();
|
||||
updateSatelliteToggleUi(false, 0);
|
||||
const message = `卫星加载失败: ${error?.message || String(error)}`;
|
||||
showError(message);
|
||||
showStatusMessage(message, "error");
|
||||
throw error;
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
}
|
||||
|
||||
function setupEventListeners() {
|
||||
const handleResize = () => onWindowResize();
|
||||
const handleMouseMove = (event) => onMouseMove(event);
|
||||
|
||||
Reference in New Issue
Block a user