feat(earth): Modularize 3D Earth page with ES Modules
## Changelog ### New Features - Modularized 3D earth HTML page from single 1918-line file into ES Modules - Split CSS into separate module files (base, info-panel, coordinates-display, legend, earth-stats) - Split JS into separate modules (constants, utils, ui, earth, cables, controls, main) ### 3D Earth Rendering - Use Three.js r128 (via esm.sh CDN) for color consistency with original - Earth with 8K satellite texture and proper material settings - Cloud layer with transparency and additive blending - Starfield background (8000 stars) - Latitude/longitude grid lines that rotate with Earth ### Cable System - Load cable data from geo.json with great circle path calculation - Support for MultiLineString and LineString geometry types - Cable color from geo.json properties.color field - Landing points loading from landing-point-geo.geojson ### User Interactions - Mouse hover: highlight cable and show details - Mouse click: lock cable with pulsing glow effect - Click cable to pause rotation, click elsewhere to resume - Click rotation toggle button to resume rotation and clear highlight - Reset view with smooth animation (800ms cubic ease-out) - Mouse wheel zoom support - Drag to rotate Earth ### UI/UX Improvements - Tooltip shows latitude, longitude, and altitude - Prevent tooltip text selection during drag - Hide tooltip during drag operation - Blue border tooltip styling matching original - Cursor changes to grabbing during drag - Front-facing cable detection (only detect cables facing camera) ### Bug Fixes - Grid lines now rotate with Earth (added as Earth child) - Reset view button now works correctly - Fixed camera reference in reset view - Fixed autoRotate state management when clearing locked cable ### Original HTML - Copied original 3dearthmult.html to public folder for reference
This commit is contained in:
@@ -1009,50 +1009,51 @@ function calculateDistance(lat1, lon1, lat2, lon2) {
|
||||
);
|
||||
}
|
||||
|
||||
// 从后端API加载GeoJSON数据
|
||||
async function loadGeoJSONFromPath() {
|
||||
try {
|
||||
const API_PATH = '/api/v1/visualization/geo/cables';
|
||||
console.log(`正在从 ${API_PATH} 加载GeoJSON数据...`);
|
||||
showStatusMessage('正在加载电缆数据...', 'warning');
|
||||
|
||||
const response = await fetch(API_PATH);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP错误: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
const geoJsonData = await response.json();
|
||||
|
||||
if (geoJsonData.features && Array.isArray(geoJsonData.features)) {
|
||||
loadCablesFromGeoJSON(geoJsonData);
|
||||
showStatusMessage(`成功加载 ${geoJsonData.features.length} 条电缆数据`, 'success');
|
||||
} else {
|
||||
throw new Error('无效的GeoJSON格式: 缺少features数组');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载GeoJSON数据失败:', error);
|
||||
|
||||
const errorEl = document.getElementById('error-message');
|
||||
errorEl.textContent = `无法加载API数据: ${error.message}`;
|
||||
errorEl.style.display = 'block';
|
||||
|
||||
showStatusMessage('数据加载失败,请检查后端服务', 'error');
|
||||
|
||||
setTimeout(() => {
|
||||
loadFallbackData();
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function loadLandingPoints() {
|
||||
try {
|
||||
const API_PATH = '/api/v1/visualization/geo/landing-points';
|
||||
console.log(`正在从 ${API_PATH} 加载登陆点数据...`);
|
||||
|
||||
const response = await fetch(API_PATH);
|
||||
// 从固定路径加载GeoJSON数据
|
||||
async function loadGeoJSONFromPath() {
|
||||
try {
|
||||
console.log(`正在从 ${GEOJSON_PATH} 加载GeoJSON数据...`);
|
||||
showStatusMessage('正在加载电缆数据...', 'warning');
|
||||
|
||||
// 使用fetch API加载本地文件
|
||||
const response = await fetch(GEOJSON_PATH);
|
||||
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP错误: ${response.status} ${response.statusText}`);
|
||||
}
|
||||
|
||||
const geoJsonData = await response.json();
|
||||
|
||||
if (geoJsonData.features && Array.isArray(geoJsonData.features)) {
|
||||
loadCablesFromGeoJSON(geoJsonData);
|
||||
showStatusMessage(`成功加载 ${geoJsonData.features.length} 条电缆数据`, 'success');
|
||||
} else {
|
||||
throw new Error('无效的GeoJSON格式: 缺少features数组');
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
console.error('加载GeoJSON数据失败:', error);
|
||||
|
||||
// 显示错误信息
|
||||
const errorEl = document.getElementById('error-message');
|
||||
errorEl.textContent = `无法加载文件 ${GEOJSON_PATH}: ${error.message}`;
|
||||
errorEl.style.display = 'block';
|
||||
|
||||
showStatusMessage('数据加载失败,请检查文件路径', 'error');
|
||||
|
||||
// 加载示例数据作为后备
|
||||
setTimeout(() => {
|
||||
loadFallbackData();
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
async function loadLandingPoints() {
|
||||
try {
|
||||
console.log(`正在从 ${GEOJSON_PATH} 加载GeoJSON数据...`);
|
||||
// 方式1:从本地文件加载(如果你下载了landing_points.geojson)
|
||||
const response = await fetch('./landing-point-geo.geojson');
|
||||
|
||||
// 方式2:或者直接从API加载(取消下面注释)
|
||||
// const response = await fetch('https://services.arcgis.com/6DIQcwlPy8knb6sg/arcgis/rest/services/SubmarineCables/FeatureServer/0/query?where=1%3D1&outFields=*&returnGeometry=true&f=geojson');
|
||||
|
||||
Reference in New Issue
Block a user