diff --git a/frontend/public/earth/js/cables.js b/frontend/public/earth/js/cables.js index 436c2805..7bee206d 100644 --- a/frontend/public/earth/js/cables.js +++ b/frontend/public/earth/js/cables.js @@ -9,6 +9,7 @@ import { updateCableDetails, updateEarthStats, showStatusMessage } from './ui.js export let cableLines = []; export let landingPoints = []; export let lockedCable = null; +let cableIdMap = new Map(); function getCableColor(properties) { if (properties.color) { @@ -46,8 +47,10 @@ function createCableLine(points, color, properties, earthObj) { }); const cableLine = new THREE.Line(lineGeometry, lineMaterial); + const cableId = properties.cable_id || properties.id || properties.Name || Math.random().toString(36); cableLine.userData = { type: 'cable', + cableId: cableId, name: properties.Name || properties.cableName || 'Unknown', owner: properties.owner || properties.owners || '-', status: properties.status || '-', @@ -58,6 +61,11 @@ function createCableLine(points, color, properties, earthObj) { }; cableLine.renderOrder = 1; + if (!cableIdMap.has(cableId)) { + cableIdMap.set(cableId, []); + } + cableIdMap.get(cableId).push(cableLine); + return cableLine; } @@ -332,6 +340,10 @@ export function getCableLines() { return cableLines; } +export function getCablesById(cableId) { + return cableIdMap.get(cableId) || []; +} + export function getLandingPoints() { return landingPoints; } diff --git a/frontend/public/earth/js/main.js b/frontend/public/earth/js/main.js index b94b4b9b..2da69e73 100644 --- a/frontend/public/earth/js/main.js +++ b/frontend/public/earth/js/main.js @@ -14,7 +14,7 @@ import { hideTooltip } from './ui.js'; import { createEarth, createClouds, createTerrain, createStars, createGridLines, toggleTerrain, getEarth } from './earth.js'; -import { loadGeoJSONFromPath, loadLandingPoints, handleCableClick, clearCableSelection, getCableLines } from './cables.js'; +import { loadGeoJSONFromPath, loadLandingPoints, handleCableClick, clearCableSelection, getCableLines, getCablesById } from './cables.js'; import { setupControls, getAutoRotate, getShowTerrain, zoomLevel, setAutoRotate, toggleAutoRotate } from './controls.js'; export let scene, camera, renderer; @@ -23,6 +23,7 @@ let isDragging = false; let previousMousePosition = { x: 0, y: 0 }; let hoveredCable = null; let lockedCable = null; +let lockedCableData = null; window.addEventListener('error', (e) => { console.error('全局错误:', e.error); @@ -149,17 +150,27 @@ function onMouseMove(event, camera) { const intersects = raycaster.intersectObjects(frontCables); if (hoveredCable && hoveredCable !== lockedCable) { - if (hoveredCable.userData.originalColor !== undefined) { - hoveredCable.material.color.setHex(hoveredCable.userData.originalColor); - } + const prevCableId = hoveredCable.userData.cableId; + const prevSameCables = getCablesById(prevCableId); + prevSameCables.forEach(c => { + if (c.userData.originalColor !== undefined) { + c.material.color.setHex(c.userData.originalColor); + } + }); hoveredCable = null; } if (intersects.length > 0) { const cable = intersects[0].object; + const cableId = cable.userData.cableId; + const sameCables = getCablesById(cableId); + if (cable !== lockedCable) { - cable.material.color.setHex(0xffffff); - cable.material.opacity = 1; + sameCables.forEach(c => { + c.material.color.setHex(0xffffff); + c.material.opacity = 1; + }); + hoveredCable = cable; hoveredCable = cable; } @@ -174,7 +185,15 @@ function onMouseMove(event, camera) { hideTooltip(); } else { - if (!lockedCable) { + if (lockedCable && lockedCableData) { + document.getElementById('cable-name').textContent = + lockedCableData.name || lockedCableData.shortname || '未命名电缆'; + document.getElementById('cable-owner').textContent = lockedCableData.owner || '-'; + document.getElementById('cable-status').textContent = lockedCableData.status || '-'; + document.getElementById('cable-length').textContent = lockedCableData.length || '-'; + document.getElementById('cable-coords').textContent = '-'; + document.getElementById('cable-rfs').textContent = lockedCableData.rfs || '-'; + } else { document.getElementById('cable-name').textContent = '点击电缆查看详情'; document.getElementById('cable-owner').textContent = '-'; document.getElementById('cable-status').textContent = '-'; @@ -236,23 +255,41 @@ function onClick(event, camera, renderer) { const intersects = raycaster.intersectObjects(frontCables); if (intersects.length > 0) { - if (lockedCable && lockedCable !== intersects[0].object) { - if (lockedCable.userData.originalColor !== undefined) { - lockedCable.material.color.setHex(lockedCable.userData.originalColor); - } + if (lockedCable) { + const prevCableId = lockedCable.userData.cableId; + const prevSameCables = getCablesById(prevCableId); + prevSameCables.forEach(c => { + if (c.userData.originalColor !== undefined) { + c.material.color.setHex(c.userData.originalColor); + } + }); } - lockedCable = intersects[0].object; - lockedCable.material.color.setHex(0xffffff); + const clickedCable = intersects[0].object; + const cableId = clickedCable.userData.cableId; + const sameCables = getCablesById(cableId); + + sameCables.forEach(c => { + c.material.color.setHex(0xffffff); + c.material.opacity = 1; + }); + + lockedCable = clickedCable; + lockedCableData = { ...clickedCable.userData }; setAutoRotate(false); - handleCableClick(intersects[0].object); + handleCableClick(clickedCable); } else { if (lockedCable) { - if (lockedCable.userData.originalColor !== undefined) { - lockedCable.material.color.setHex(lockedCable.userData.originalColor); - } + const prevCableId = lockedCable.userData.cableId; + const prevSameCables = getCablesById(prevCableId); + prevSameCables.forEach(c => { + if (c.userData.originalColor !== undefined) { + c.material.color.setHex(c.userData.originalColor); + } + }); lockedCable = null; + lockedCableData = null; } setAutoRotate(true); clearCableSelection(); @@ -270,9 +307,13 @@ function animate() { if (lockedCable) { const pulse = (Math.sin(Date.now() * 0.003) + 1) * 0.5; - lockedCable.material.opacity = 0.6 + pulse * 0.4; const glowIntensity = 0.7 + pulse * 0.3; - lockedCable.material.color.setRGB(glowIntensity, glowIntensity, glowIntensity); + const cableId = lockedCable.userData.cableId; + const sameCables = getCablesById(cableId); + sameCables.forEach(c => { + c.material.opacity = 0.6 + pulse * 0.4; + c.material.color.setRGB(glowIntensity, glowIntensity, glowIntensity); + }); } renderer.render(scene, camera); @@ -280,11 +321,16 @@ function animate() { window.clearLockedCable = function() { if (lockedCable) { - if (lockedCable.userData.originalColor !== undefined) { - lockedCable.material.color.setHex(lockedCable.userData.originalColor); - lockedCable.material.opacity = 1.0; - } + const cableId = lockedCable.userData.cableId; + const sameCables = getCablesById(cableId); + sameCables.forEach(c => { + if (c.userData.originalColor !== undefined) { + c.material.color.setHex(c.userData.originalColor); + c.material.opacity = 1.0; + } + }); lockedCable = null; + lockedCableData = null; } clearCableSelection(); };