|
// 销毁动画控件、时间轴控件
|
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();
|
// }
|
// });
|