cesium实现键盘控制地图场景漫游效果


Cesium实战系列文章总目录传送门

1.实现效果

在这里插入图片描述

2.实现方法

通过监听键盘字符输入来的动态调整相机位置和姿态角。

键盘输入字符和对应的相机操作如下表:

键盘操作含义说明
WmoveForward相机前移
SmoveBackward相机后移
AmoveLeft相机左移
DmoveRight相机右移
QmoveUp相机上移
EmoveDown相机下移
lookUp抬头
lookDown低头
lookLeft左转
lookRight右转
0twistLeft顺时针转
.twistRight逆时针转
+zoomIn放大
-zoomOut缩小

2.1实现思路

(1)设置事件表
设置根据键盘输入的字符修改相机参数的事件表。(具体见下文代码)

当键盘被按下时,执行相机操作,键盘弹起时结束操作,防止误操作等。
(2)监听键盘输入
通过document监听键盘按下keydown和弹出keyup事件。

(3)为每帧渲染添加监听
监听clockonTick事件,在每帧渲染时调用,API:传送门
在这里插入图片描述
(4)修改相机参数
通过Camera相关方法进行设置,API:传送门
在这里插入图片描述

2.2具体代码

(1)代码调用
将核心功能封装成了keyboardMapRoaming.js,引入js后调用,代码如下:

// 键盘控制漫游
keyboardMapRoamingInit(viewer);

(2)具体函数
具体实现功能函数如下:

/*
 * @Description: 使用键盘控制地图漫游
 * @Version: 1.0
 * @Author: Julian
 * @Date: 2022-04-07 16:04:07
 * @LastEditors: Julian
 * @LastEditTime: 2022-04-07 18:40:40
 */


/**
 * @description: 使用键盘控制地图漫游初始化
 * @param {*} _viewer
 * @return {*}
 */
function keyboardMapRoamingInit(_viewer) {
    // 添加键盘监听事件
    document.addEventListener('keydown', keyDown, false);
    document.addEventListener('keyup', keyUp, false);

    // 为每一帧添加监听事件
    _viewer.clock.onTick.addEventListener(function() {
        keyboardMapRoamingRender(_viewer);
    });
}

// 定义事件组
let flags = {
    // 相机位置
    moveForward: false,
    moveBackward: false,
    moveLeft: false,
    moveRight: false,
    moveUp: false,
    moveDown: false,
    // 相机姿态
    lookUp: false,
    lookDown: false,
    lookLeft: false,
    lookRight: false,
    twistLeft: false,
    twistRight: false,
    // 缩放
    zoomIn: false,
    zoomOut: false
}



// 相机位置:W:向前;S:向后;D:向右;A:向左;Q:升高;E:降低;
// 相机姿态:↑:抬头;↓:低头;←:左转;→:右转;0:顺时针;.:逆时针
// 缩放:+:放大,-:缩小;

/**
 * @description: 根据键盘输入字符返回事件信息
 * @param {*} key
 * @return {*}
 */
function getFlagFromKeyboard(key) {
    switch (key) {
        // 按字符的Unicode编码
        // 相机位置
        case 87:
            return 'moveForward';
        case 83:
            return 'moveBackward';
        case 68:
            return 'moveRight';
        case 65:
            return 'moveLeft';
        case 81:
            return 'moveUp';
        case 69:
            return 'moveDown';
        // 相机姿态 
        case 38:
            return 'lookUp';
        case 40:
            return 'lookDown';
        case 37:
            return 'lookLeft';
        case 39:
            return 'lookRight';
        case 96:
            return 'twistLeft';
        case 110:
            return 'twistRight';
        // 缩放
        case 107:
            return 'zoomIn';
        case 109:
            return 'zoomOut';
        default:
            return undefined;
    }
}

/**
 * @description: 键盘按下
 * @param {*} event
 * @return {*}
 */
function keyDown(event) {
    let flagName = getFlagFromKeyboard(event.keyCode);
    if (typeof flagName !== 'undefined') {
        flags[flagName] = true;
    }
}

/**
 * @description: 键盘弹起
 * @param {*} event
 * @return {*}
 */
function keyUp(event) {
    let flagName = getFlagFromKeyboard(event.keyCode);
    if (typeof flagName !== 'undefined') {
        flags[flagName] = false;
    }
}


/**
 * @description: 根据事件调整相机
 * @param {*} _viewer
 * @return {*}
 */
function keyboardMapRoamingRender(_viewer) {
    let camera = _viewer.camera;
    let ellipsoid = _viewer.scene.globe.ellipsoid;
    let cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;

    // 根据相机高度设置移动距离,比默认距离移动效果更好
    let moveRate = cameraHeight / 20.0;

    if (flags.moveForward) {
        camera.moveForward(moveRate);
    }
    if (flags.moveBackward) {
        camera.moveBackward(moveRate);
    }
    if (flags.moveLeft) {
        camera.moveLeft(moveRate);
    }
    if (flags.moveRight) {
        camera.moveRight(moveRate);
    }
    if (flags.moveUp) {
        camera.moveUp(moveRate);
    }
    if (flags.moveDown) {
        camera.moveDown(moveRate);
    }
    if (flags.lookUp) {
        camera.lookUp();
    }
    if (flags.lookDown) {
        camera.lookDown();
    }
    if (flags.lookLeft) {
        camera.lookLeft();
    }
    if (flags.lookRight) {
        camera.lookRight();
    }
    if (flags.twistLeft) {
        camera.twistLeft();
    }
    if (flags.twistRight) {
        camera.twistRight();
    }
    // 根据相机高度设置缩放参数
    if (flags.zoomIn) {
        camera.zoomIn(cameraHeight / 2);
    }
    if (flags.zoomOut) {
        camera.zoomOut(cameraHeight / 2);
    }
}
  • 1
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是使用 Cesium 实现飞行漫游效果的源码示例: ```html <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Cesium Flyover</title> <script src="https://cesium.com/downloads/cesiumjs/releases/1.82/Build/Cesium/Cesium.js"></script> <link rel="stylesheet" href="https://cesium.com/downloads/cesiumjs/releases/1.82/Build/Cesium/Widgets/widgets.css"> <style> html, body, #cesiumContainer { width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden; } </style> </head> <body> <div id="cesiumContainer"></div> <script> Cesium.Ion.defaultAccessToken = 'YOUR_CESIUM_ION_TOKEN'; var viewer = new Cesium.Viewer('cesiumContainer', { terrainProvider: Cesium.createWorldTerrain(), shouldAnimate: true }); var camera = viewer.camera; camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(-75.59777, 40.03883, 200000.0), orientation: { heading: Cesium.Math.toRadians(0.0), pitch: Cesium.Math.toRadians(-90.0), roll: 0.0 }, duration: 5 }); </script> </body> </html> ``` 在这个示例中,我们使用了 Cesium 提供的 `Viewer` 类来创建一个基本的地球场景,并使用 `camera.flyTo()` 方法来实现飞行漫游效果。在 `flyTo()` 中,我们可以指定我们想要去的目的地的经纬度坐标,以及相机的朝向、倾斜度和飞行的持续时间。这个示例中我们使用了一个较简单的目的地坐标(费城),但你可以根据自己的需要修改。 需要注意的是,我们在使用 Cesium 的时候需要提供一个 Cesium Ion 访问令牌(`YOUR_CESIUM_ION_TOKEN`)。你需要在 Cesium Ion 网站上注册账户并获取访问令牌,然后将访问令牌替换到上述代码中的 `YOUR_CESIUM_ION_TOKEN`。 希望这个示例对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

右弦GISer

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值