jihongshun
7 小时以前 307db148645230afc780a3d5d16ffb97aa32c189
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
 
// 销毁动画控件、时间轴控件
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();
//     }
// });