fix(earth): highlight all cable segments by cable_id
- Add cable_id mapping to group MultiLineString segments - Highlight all segments of same cable on hover - Highlight all segments of same cable on click lock - Reset all segments when clearing lock - Add pulse animation to all locked cable segments - Fix hover/click behavior with cable_id grouping
This commit is contained in:
@@ -9,6 +9,7 @@ import { updateCableDetails, updateEarthStats, showStatusMessage } from './ui.js
|
|||||||
export let cableLines = [];
|
export let cableLines = [];
|
||||||
export let landingPoints = [];
|
export let landingPoints = [];
|
||||||
export let lockedCable = null;
|
export let lockedCable = null;
|
||||||
|
let cableIdMap = new Map();
|
||||||
|
|
||||||
function getCableColor(properties) {
|
function getCableColor(properties) {
|
||||||
if (properties.color) {
|
if (properties.color) {
|
||||||
@@ -46,8 +47,10 @@ function createCableLine(points, color, properties, earthObj) {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const cableLine = new THREE.Line(lineGeometry, lineMaterial);
|
const cableLine = new THREE.Line(lineGeometry, lineMaterial);
|
||||||
|
const cableId = properties.cable_id || properties.id || properties.Name || Math.random().toString(36);
|
||||||
cableLine.userData = {
|
cableLine.userData = {
|
||||||
type: 'cable',
|
type: 'cable',
|
||||||
|
cableId: cableId,
|
||||||
name: properties.Name || properties.cableName || 'Unknown',
|
name: properties.Name || properties.cableName || 'Unknown',
|
||||||
owner: properties.owner || properties.owners || '-',
|
owner: properties.owner || properties.owners || '-',
|
||||||
status: properties.status || '-',
|
status: properties.status || '-',
|
||||||
@@ -58,6 +61,11 @@ function createCableLine(points, color, properties, earthObj) {
|
|||||||
};
|
};
|
||||||
cableLine.renderOrder = 1;
|
cableLine.renderOrder = 1;
|
||||||
|
|
||||||
|
if (!cableIdMap.has(cableId)) {
|
||||||
|
cableIdMap.set(cableId, []);
|
||||||
|
}
|
||||||
|
cableIdMap.get(cableId).push(cableLine);
|
||||||
|
|
||||||
return cableLine;
|
return cableLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,6 +340,10 @@ export function getCableLines() {
|
|||||||
return cableLines;
|
return cableLines;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getCablesById(cableId) {
|
||||||
|
return cableIdMap.get(cableId) || [];
|
||||||
|
}
|
||||||
|
|
||||||
export function getLandingPoints() {
|
export function getLandingPoints() {
|
||||||
return landingPoints;
|
return landingPoints;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
hideTooltip
|
hideTooltip
|
||||||
} from './ui.js';
|
} from './ui.js';
|
||||||
import { createEarth, createClouds, createTerrain, createStars, createGridLines, toggleTerrain, getEarth } from './earth.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';
|
import { setupControls, getAutoRotate, getShowTerrain, zoomLevel, setAutoRotate, toggleAutoRotate } from './controls.js';
|
||||||
|
|
||||||
export let scene, camera, renderer;
|
export let scene, camera, renderer;
|
||||||
@@ -23,6 +23,7 @@ let isDragging = false;
|
|||||||
let previousMousePosition = { x: 0, y: 0 };
|
let previousMousePosition = { x: 0, y: 0 };
|
||||||
let hoveredCable = null;
|
let hoveredCable = null;
|
||||||
let lockedCable = null;
|
let lockedCable = null;
|
||||||
|
let lockedCableData = null;
|
||||||
|
|
||||||
window.addEventListener('error', (e) => {
|
window.addEventListener('error', (e) => {
|
||||||
console.error('全局错误:', e.error);
|
console.error('全局错误:', e.error);
|
||||||
@@ -149,17 +150,27 @@ function onMouseMove(event, camera) {
|
|||||||
const intersects = raycaster.intersectObjects(frontCables);
|
const intersects = raycaster.intersectObjects(frontCables);
|
||||||
|
|
||||||
if (hoveredCable && hoveredCable !== lockedCable) {
|
if (hoveredCable && hoveredCable !== lockedCable) {
|
||||||
if (hoveredCable.userData.originalColor !== undefined) {
|
const prevCableId = hoveredCable.userData.cableId;
|
||||||
hoveredCable.material.color.setHex(hoveredCable.userData.originalColor);
|
const prevSameCables = getCablesById(prevCableId);
|
||||||
}
|
prevSameCables.forEach(c => {
|
||||||
|
if (c.userData.originalColor !== undefined) {
|
||||||
|
c.material.color.setHex(c.userData.originalColor);
|
||||||
|
}
|
||||||
|
});
|
||||||
hoveredCable = null;
|
hoveredCable = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (intersects.length > 0) {
|
if (intersects.length > 0) {
|
||||||
const cable = intersects[0].object;
|
const cable = intersects[0].object;
|
||||||
|
const cableId = cable.userData.cableId;
|
||||||
|
const sameCables = getCablesById(cableId);
|
||||||
|
|
||||||
if (cable !== lockedCable) {
|
if (cable !== lockedCable) {
|
||||||
cable.material.color.setHex(0xffffff);
|
sameCables.forEach(c => {
|
||||||
cable.material.opacity = 1;
|
c.material.color.setHex(0xffffff);
|
||||||
|
c.material.opacity = 1;
|
||||||
|
});
|
||||||
|
hoveredCable = cable;
|
||||||
hoveredCable = cable;
|
hoveredCable = cable;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,7 +185,15 @@ function onMouseMove(event, camera) {
|
|||||||
|
|
||||||
hideTooltip();
|
hideTooltip();
|
||||||
} else {
|
} 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-name').textContent = '点击电缆查看详情';
|
||||||
document.getElementById('cable-owner').textContent = '-';
|
document.getElementById('cable-owner').textContent = '-';
|
||||||
document.getElementById('cable-status').textContent = '-';
|
document.getElementById('cable-status').textContent = '-';
|
||||||
@@ -236,23 +255,41 @@ function onClick(event, camera, renderer) {
|
|||||||
const intersects = raycaster.intersectObjects(frontCables);
|
const intersects = raycaster.intersectObjects(frontCables);
|
||||||
|
|
||||||
if (intersects.length > 0) {
|
if (intersects.length > 0) {
|
||||||
if (lockedCable && lockedCable !== intersects[0].object) {
|
if (lockedCable) {
|
||||||
if (lockedCable.userData.originalColor !== undefined) {
|
const prevCableId = lockedCable.userData.cableId;
|
||||||
lockedCable.material.color.setHex(lockedCable.userData.originalColor);
|
const prevSameCables = getCablesById(prevCableId);
|
||||||
}
|
prevSameCables.forEach(c => {
|
||||||
|
if (c.userData.originalColor !== undefined) {
|
||||||
|
c.material.color.setHex(c.userData.originalColor);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
lockedCable = intersects[0].object;
|
const clickedCable = intersects[0].object;
|
||||||
lockedCable.material.color.setHex(0xffffff);
|
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);
|
setAutoRotate(false);
|
||||||
handleCableClick(intersects[0].object);
|
handleCableClick(clickedCable);
|
||||||
} else {
|
} else {
|
||||||
if (lockedCable) {
|
if (lockedCable) {
|
||||||
if (lockedCable.userData.originalColor !== undefined) {
|
const prevCableId = lockedCable.userData.cableId;
|
||||||
lockedCable.material.color.setHex(lockedCable.userData.originalColor);
|
const prevSameCables = getCablesById(prevCableId);
|
||||||
}
|
prevSameCables.forEach(c => {
|
||||||
|
if (c.userData.originalColor !== undefined) {
|
||||||
|
c.material.color.setHex(c.userData.originalColor);
|
||||||
|
}
|
||||||
|
});
|
||||||
lockedCable = null;
|
lockedCable = null;
|
||||||
|
lockedCableData = null;
|
||||||
}
|
}
|
||||||
setAutoRotate(true);
|
setAutoRotate(true);
|
||||||
clearCableSelection();
|
clearCableSelection();
|
||||||
@@ -270,9 +307,13 @@ function animate() {
|
|||||||
|
|
||||||
if (lockedCable) {
|
if (lockedCable) {
|
||||||
const pulse = (Math.sin(Date.now() * 0.003) + 1) * 0.5;
|
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;
|
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);
|
renderer.render(scene, camera);
|
||||||
@@ -280,11 +321,16 @@ function animate() {
|
|||||||
|
|
||||||
window.clearLockedCable = function() {
|
window.clearLockedCable = function() {
|
||||||
if (lockedCable) {
|
if (lockedCable) {
|
||||||
if (lockedCable.userData.originalColor !== undefined) {
|
const cableId = lockedCable.userData.cableId;
|
||||||
lockedCable.material.color.setHex(lockedCable.userData.originalColor);
|
const sameCables = getCablesById(cableId);
|
||||||
lockedCable.material.opacity = 1.0;
|
sameCables.forEach(c => {
|
||||||
}
|
if (c.userData.originalColor !== undefined) {
|
||||||
|
c.material.color.setHex(c.userData.originalColor);
|
||||||
|
c.material.opacity = 1.0;
|
||||||
|
}
|
||||||
|
});
|
||||||
lockedCable = null;
|
lockedCable = null;
|
||||||
|
lockedCableData = null;
|
||||||
}
|
}
|
||||||
clearCableSelection();
|
clearCableSelection();
|
||||||
};
|
};
|
||||||
|
|||||||
Reference in New Issue
Block a user