// 销毁动画控件、时间轴控件 viewerC.animation.destroy(); viewerC.timeline.destroy(); //禁用鹰眼地图的操作 let control = viewerC.scene.screenSpaceCameraController; control.enableRotate = false; control.enableTranslate = false; control.enableZoom = false; control.enableTilt = false; control.enableLook = false; // 设置初始视图(中国) viewerC.camera.setView({ destination: Cesium.Cartesian3.fromDegrees(125.1438, 46.5469, 1000), orientation: { heading: Cesium.Math.toRadians(38.24), // 方向 pitch: Cesium.Math.toRadians(-35), // 俯角 roll: Cesium.Math.toRadians(0.0), } }); // 相机移动速度 let moveSpeed = 1; // 默认移动速度 const speedMultiplier = 5; // Shift加速倍数 const slowMultiplier = 0.2; // Ctrl减速倍数 // 键盘状态 const keyState = { w: false, s: false, a: false, d: false, q: false, e: false, up: false, down: false, left: false, right: false, shift: false, ctrl: false, space: false }; // 注册键盘事件 document.addEventListener('keydown', (event) => { const key = event.key.toLowerCase(); switch (key) { case 'w': keyState.w = true; break; case 's': keyState.s = true; break; case 'a': keyState.a = true; break; case 'd': keyState.d = true; break; case 'q': keyState.q = true; break; case 'e': keyState.e = true; break; case ' ': keyState.space = true; break; case 'shift': keyState.shift = true; break; case 'control': keyState.ctrl = true; break; } // 特殊处理箭头键 switch (event.key) { case 'ArrowUp': keyState.up = true; break; case 'ArrowDown': keyState.down = true; break; case 'ArrowLeft': keyState.left = true; break; case 'ArrowRight': keyState.right = true; break; case '1': viewerC.scene.mode = Cesium.SceneMode.SCENE3D; break; case '2': viewerC.scene.mode = Cesium.SceneMode.SCENE2D; break; case '3': viewerC.scene.mode = Cesium.SceneMode.COLUMBUS_VIEW; break; } // 阻止空格键滚动页面 if (key === ' ') { event.preventDefault(); } if (key === 'ctrl') { event.preventDefault(); } }); document.addEventListener('keyup', (event) => { const key = event.key.toLowerCase(); switch (key) { case 'w': keyState.w = false; break; case 's': keyState.s = false; break; case 'a': keyState.a = false; break; case 'd': keyState.d = false; break; case 'q': keyState.q = false; break; case 'e': keyState.e = false; break; case ' ': keyState.space = false; resetView(); break; case 'shift': keyState.shift = false; break; case 'control': keyState.ctrl = false; break; } console.log(event.key); // 特殊处理箭头键 switch (event.key) { case 'ArrowUp': keyState.up = false; break; case 'ArrowDown': keyState.down = false; break; case 'ArrowLeft': keyState.left = false; break; case 'ArrowRight': keyState.right = false; break; case 'r': resetPitch(30) break; case 'f': resetPitch() break; case 'v': resetPitch(-30) break; } }); // 动画循环,处理相机移动 function updateCameraMovement() { // 根据Shift和Ctrl调整速度 let currentSpeed = moveSpeed; if (keyState.shift) currentSpeed *= speedMultiplier; if (keyState.ctrl) currentSpeed *= slowMultiplier; const camera = viewerC.camera; const deltaTime = 1.0; // 简化的时间增量 // 前后左右移动 if (keyState.w) uavMoveForward(1); // camera.moveForward(currentSpeed * deltaTime); if (keyState.s) uavMoveForward(-1);;//camera.moveBackward(currentSpeed * deltaTime); if (keyState.a) camera.moveLeft(currentSpeed * deltaTime); if (keyState.d) camera.moveRight(currentSpeed * deltaTime); if (keyState.q) camera.moveUp(currentSpeed * deltaTime); if (keyState.e) camera.moveDown(currentSpeed * deltaTime); // 旋转视角 let rotatSpeed = 1; if (keyState.shift) rotatSpeed *= speedMultiplier; if (keyState.ctrl) rotatSpeed *= slowMultiplier; const rotateAmount = Cesium.Math.toRadians(0.5 * rotatSpeed); if (keyState.up) camera.lookUp(rotateAmount); if (keyState.down) camera.lookDown(rotateAmount); if (keyState.left) camera.lookLeft(rotateAmount); if (keyState.right) camera.lookRight(rotateAmount); resetRoll(); // 下一帧继续更新 requestAnimationFrame(updateCameraMovement); } /** * 根据已知点的经纬度、方向角和距离,计算另一点的经纬度 * @param {number} lon1 - 已知点的经度(单位:度) * @param {number} lat1 - 已知点的纬度(单位:度) * @param {number} bearing - 方向角(单位:度,以北为0度,顺时针增加) * @param {number} distance - 距离(单位:米) * @param {number} [radius=6371000] - 地球半径(单位:米,默认为地球平均半径) * @returns {Object} - 返回新点的经纬度 {lon: 新经度, lat: 新纬度}(单位:度) */ function calculateDestinationPoint(lon1, lat1, bearing, distance, radius = 6371000) { // 将角度转换为弧度 const toRadians = (degrees) => degrees * Math.PI / 180; const toDegrees = (radians) => radians * 180 / Math.PI; const lat1Rad = toRadians(lat1); const lon1Rad = toRadians(lon1); const bearingRad = bearing; // 计算新点的纬度 const angularDistance = distance / radius; const lat2Rad = Math.asin( Math.sin(lat1Rad) * Math.cos(angularDistance) + Math.cos(lat1Rad) * Math.sin(angularDistance) * Math.cos(bearingRad) ); // 计算新点的经度 const lon2Rad = lon1Rad + Math.atan2( Math.sin(bearingRad) * Math.sin(angularDistance) * Math.cos(lat1Rad), Math.cos(angularDistance) - Math.sin(lat1Rad) * Math.sin(lat2Rad) ); // 处理经度的范围 [-π, π] const lon2RadNormalized = ((lon2Rad + 3 * Math.PI) % (2 * Math.PI)) - Math.PI; // 转换回度数 const lat2 = toDegrees(lat2Rad); const lon2 = toDegrees(lon2RadNormalized); return { lon: lon2, lat: lat2 }; } function uavMoveForward(speed) { const camera = viewerC.camera; var cartographic = Cesium.Cartographic.fromCartesian(camera.position); var longitude = Cesium.Math.toDegrees(cartographic.longitude); // 经度,转换为度 var latitude = Cesium.Math.toDegrees(cartographic.latitude); // 纬度,转换为度 var height = cartographic.height; // 高度 let newLonLat = calculateDestinationPoint(longitude, latitude, camera.heading, speed); let newPosition = Cesium.Cartesian3.fromDegrees(newLonLat.lon,newLonLat.lat,height); camera.setView({ destination: newPosition, orientation: { heading: camera.heading, pitch: camera.pitch, roll: 0.0 } }); } function resetRoll() { const camera = viewerC.camera; camera.setView({ destination: camera.destination, orientation: { heading: camera.heading, pitch: camera.pitch, roll: 0.0 } }); } function resetPitch(amount) { if (amount === undefined) { amount = 0.1; } const camera = viewerC.camera; camera.setView({ destination: camera.destination, orientation: { heading: camera.heading, pitch: Cesium.Math.toRadians(amount), roll: 0 } }); } // 启动动画循环 updateCameraMovement(); // helpBtn.addEventListener('click', openHelpModal); // closeHelpBtn.addEventListener('click', closeHelpModal); // gotItBtn.addEventListener('click', closeHelpModal); // 点击模态框背景关闭 // helpModal.addEventListener('click', (e) => { // if (e.target === helpModal) { // closeHelpModal(); // } // });