刚来公司的时候跟我讲要用 Cesium 框架开发三维地图,我是一脸懵逼,说实话,之前完全没接触过这类地图框架,想着去百度看看吧,发现这玩意用的人其实不多,遇到很多问题都百度不到,加了很多群,也是效果甚微。在此做个学习的记录吧,记录一些心得和遇到的问题。如有不对的地方希望大伙指正。
Cesium是什么的
说白了点就是做三维可视化的,其实在项目中无非就是这样,先把地图展示出来,然后加载些模型,或是地形,或是图层等等,当然还会有地图交互操作,一步步的来,会简单很多。
HelloWorld
一步步的来,首先是下载 Cesium 包,官网的下载是真有够慢的,可以复制链接,到迅雷下载,还蛮快的
下载解压好的目录就是这个样子了,vsCode 打开文件夹,打开 index.html,Cesium 加载地图需要服务环境,可以使用 Live Server 插件打开
ok,废话不多说,直接看看如何引用 Cesium 创建地球
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="./cesium-1.90/Build/Cesium/Widgets/widgets.css">
<style>
html,
body,
#myMap {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
<script src="./cesium-1.90/Build/CesiumUnminified/Cesium.js"></script>
</head>
<body>
<div id="myMap"></div>
</body>
<script>
// Cesium 官网注册获取
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI2NTRiZTg1OC0yMWQ5LTQ3ZjEtYjIzZC0yYWIwNWJkY2NlNzQiLCJpZCI6ODIwNDQsImlhdCI6MTY0NDQ4MjUyMX0.DYdh5Jvf7yAEQ2LqiBCeFq36x0aLJ3v2uG8uqDOX39E'
// 基于 div 实例化一个 Cesium 地球窗口
let viewer = new Cesium.Viewer('myMap')
</script>
</html>
Cesium在开发中的使用开发
创建纯净的地球
开发中很少使用到自带的控件,总觉得不太好看,所以先来说说如何创建一颗纯净的地球。这里就要用到 new Cesium Viewer 的第二个参数了
// 基于 div 实例化一个 Cesium 地球窗口
let viewer = new Cesium.Viewer('myMap', {
selectionIndicator: false, // 是否获取选择周指示器
animation: false, // 是否显示动画控件
baseLayerPicker: false, // 是否显示图层选择控件
geocoder: false, // 是否显示地名查找控件
timeline: false, // 是否显示时间线控件
sceneModePicker: false, // 是否显示投影方式控件
navigationHelpButton: false, // 是否显示帮助信息控件
infoBox: false, // 是否显示点击要素之后显示的信息
homeButton: false, // 是否显示主页控件
fullscreenButton: false // 是否显示全屏控件
})
// 去掉版权信息
viewer._cesiumWidget._creditContainer.style.display = "none";
设置视角
看着一颗光秃秃的地球也不太好看,有时候需要我们展现模型或者单个省、县的图层,此时就可以设置视角,将视角拉到某个区域
viewer.camera.setView({
// 相机在 WGS84坐标 中的最终位置
destination: Cesium.Cartesian3.fromDegrees(119.57160055699248, 25.70102836786316, 383.6698647688256),
// 视角的朝向
orientation: {
heading: Cesium.Math.toRadians(340.0876405649615),
pitch: Cesium.Math.toRadians(-9.965309016806488),
roll: Cesium.Math.toRadians(359.94808234298637),
},
})
飞行
飞行到某地,其实和设置视角是一个效果,但飞行添加了动画,更加生动,用户体验感会好很多
// 飞行
viewer.camera.flyTo({
// 相机在 WGS84坐标 中的最终位置
destination: Cesium.Cartesian3.fromDegrees(-122.19, 46.25, 5000.0),
// 视角的朝向
orientation: {
heading: Cesium.Math.toRadians(175.0),
pitch: Cesium.Math.toRadians(-35.0),
roll: 0.0
}
})
Cesium事件
Canvas事件
左键事件
| 事件 | 含义 |
|---|---|
| Cesium.ScreenSpaceEventType.LEFT_CLICK | 鼠标左键单击事件 |
| Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK | 鼠标左键双击事件 |
| Cesium.ScreenSpaceEventType.LEFT_DOWN | 鼠标左键按下事件 |
| Cesium.ScreenSpaceEventType.LEFT_UP | 鼠标左键弹起事件 |
右键事件
| 事件 | 含义 | |
|---|---|---|
| Cesium.ScreenSpaceEventType.RIGHT_CLICK | 鼠标右键单击事件 | |
| Cesium.ScreenSpaceEventType.RIGHT_DOWN | 鼠标右键按下事件 | |
| Cesium.ScreenSpaceEventType.RIGHT_UP | 鼠标右键弹起事件 |
触摸事件
| 事件 | 含义 |
|---|---|
| Cesium.ScreenSpaceEventType.PINCH_START | 双指开始触摸事件 |
| Cesium.ScreenSpaceEventType.PINCH_END | 双指结束触摸事件 |
| Cesium.ScreenSpaceEventType.PINCH_MOVE | 双指更改事件 |
其他
| 事件 | 含义 |
|---|---|
| Cesium.ScreenSpaceEventType.MOUSE_MOVE | 鼠标移动事件 |
| Cesium.ScreenSpaceEventType.WHEEL | 鼠标滚轮事件 |
相机事件
| 事件 | 含义 |
|---|---|
| Cesium.CameraEventType.LEFT_DRAG | 按住鼠标左键,然后移动鼠标并释放按钮 |
| Cesium.CameraEventType.MIDDLE_DRAG | 按住鼠标中键,然后移动鼠标并释放按钮 |
| Cesium.CameraEventType.PINCH | 触摸表面上的双指触摸 |
| Cesium.CameraEventType.RIGHT_DRAG | 按住鼠标右键,然后移动鼠标并释放按钮 |
| Cesium.CameraEventType.WHEEL | 滚动鼠标中键 |
这是一段监听鼠标点击事件并获取经纬度的代码,其他事件更改 handler.setInputAction 第二个参数即可
let scene = viewer.scene
var handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);
// 监听地图点击事件
handler.setInputAction(function (movement) {
// 经纬度
let cartesian = scene.pickPosition(movement.position);
let cartographic = Cesium.Cartographic.fromCartesian(cartesian);
let lng = Cesium.Math.toDegrees(cartographic.longitude);
let lat = Cesium.Math.toDegrees(cartographic.latitude);
console.log(`经度:${lng},纬度:${lat}`);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);