前言:cesium 的基本介绍
-
概念:CesiumJS 是一套开源、基于 WebGL 的三维地球/地理空间可视化 JavaScript 库,专门用来在浏览器里搭建三维数字地球、GIS 三维场景;
-
使用场景:航天航空、智能城市、无人机,使用cesium创建交互式Web应用程序,共享地理空间数据;
-
核心标准:3D Tiles(三维瓦片,倾斜摄影、BIM、点云主流格式);
-
特点:支持全球地形、影像、3D 模型、轨迹、管线、倾斜摄影;
1.初始化 cesium 应用与基础设置;
xml
<template>
<div ref="cesiumContainer" class="cesium-container"></div>
</template>
<script setup>
import { ref, onMounted, onBeforeUnmount } from 'vue'
// 导入 Cesium 所有 API
import * as Cesium from 'cesium'
// 自带控件样式(缩放按钮、比例尺、时间轴样式),不引入会按钮样式错乱
import 'cesium/Build/Cesium/Widgets/widgets.css'
// 创建容器
const cesiumContainer = ref(null);
// 创建三维场景
let viewer = null;
onMounted(() => {
// 01.设置cesium的Token
Cesium.Ion.defaultAccessToken = "";
// 02.设置cesium默认视角
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(
// 西边的经度、南边纬度、东边经度、北边纬度
89.5, 20.4, 110.4, 61.2
);
// 03.初始化cesium程序
var viewer = new Cesium.Viewer(cesiumContainer.value, {
// 03.1.是否显示信息窗口
infoBox: true,
// 03.2.是否显示查询按钮
geocoder: false,
// 03.3.不显示home按钮
homeButton: false,
// 03.4.控制查看器的显示模式
sceneModePicker: false,
// 03.5.是否显示图层选择
baseLayerPicker: false,
// 03.6.是否显示帮助按钮
navigationHelpButton: false,
// 03.7.是否播放动画
animation: false,
// 03.8.是否显示时间轴
timeline: false,
// 03.9.是否显示全屏按钮
fullscreenButton: false,
// 03.10.设置天空盒子
skyBox: new Cesium.SkyBox({
sources: {
positiveX: "public/texture/sky/px.jpg",
negativeX: "public/texture/sky/nx.jpg",
positiveY: "public/texture/sky/ny.jpg",
negativeY: "public/texture/sky/py.jpg",
positiveZ: "public/texture/sky/pz.jpg",
negativeZ: "public/texture/sky/nz.jpg"
},
})
});
// 04.高德矢量地图
let gdUrl = "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=8&x={x}&y={y}&z={z}";
const amap = new Cesium.UrlTemplateImageryProvider({
url: gdUrl,
minimumLevel: 1,
maximumLevel: 18,
layer: "tdtVecBasicLayer",
style: "default",
format: "image/png",
tileMatrixSetID: "GoogleMapsCompatible"
});
viewer.imageryLayers.addImageryProvider(amap);
// 05.隐藏logo
viewer.cesiumWidget.creditContainer.style.display = "none";
})
onBeforeUnmount(() => {
if (viewer) {
viewer.destroy()
viewer = null
}
})
</script>
2.添加图层 - 高德地图
php
/**
* 高德地图:http://webrd02.is.autonavi.com/appmaptile?style=8&lang=zh_cn&size=1&scale=1&x={x}&y={y}&z={z}
*
* style=8 标准矢量街道图 白底、灰色道路、省市 / 街道文字、POI 点位,日常导航普通电子地图
* style=7 深色夜间矢量地图 黑底暗色地图,数字孪生大屏最常用
* style=6 卫星航拍影像图 实景航拍照片,纯地面画面,不带文字
*
* lang=zh_cn 语言:中文
* size=1 瓦片尺寸:256×256像素
* scale=1 清晰度倍率:1倍(常规分辨率)
* x={x}&y={y}&z={z} 瓦片行列、缩放层级占位符
**/
const amap6 = new Cesium.UrlTemplateImageryProvider({
url: "https://webst02.is.autonavi.com/appmaptile?style=6&x={x}&y={y}&z={z}",
minimumLevel: 1,
maximumLevel: 18,
layer: "tdtVecBasicLayer",
style: "default",
format: "image/png",
tileMatrixSetID: "GoogleMapsCompatible"
});
const amap7 = new Cesium.UrlTemplateImageryProvider({
url: "http://webrd02.is.autonavi.com/appmaptile?lang=zh_cn&size=1&scale=1&style=7&x={x}&y={y}&z={z}",
minimumLevel: 1,
maximumLevel: 18,
layer: "tdtVecBasicLayer",
style: "default",
format: "image/png",
tileMatrixSetID: "GoogleMapsCompatible"
});
const labelLayer6 = viewer.imageryLayers.addImageryProvider(amap6);
const labelLayer7 = viewer.imageryLayers.addImageryProvider(amap7);
labelLayer7.alpha = 0.5;
3.添加地形与添加自定义地形
php
// 01.添加cesium的地形
Cesium.createWorldTerrainAsync({
// 设置山脉的空间效果
requestVertexNormals: true,
// 设置水纹效果
requestWaterMask: true
}).then(terrainProvider => {
viewer.terrainProvider = terrainProvider;
}).catch(e => {
console.log("地形加载异常", e);
});
// 02.添加自定义地形数据
const terrainProvider = new Cesium.CesiumTerrainProvider({
url: "/public/terrains/gz",
requestVertexNormals: true,
requestWaterMask: true,
});
viewer.terrainProvider = terrainProvider;
4.坐标系与坐标系数值转换
javascript
// 06.坐标系数值转换
// 06.1.屏幕坐标系统:二维的笛卡尔坐标系 Cartesian2类型
// 06.2.地理坐标系统:WGS-84坐标系 Cartographic类型:经度 纬度 高度
// 06.3.笛卡尔空间直角坐标系: Cartesian3类型
// 1.角度与弧度的转换
var radians = Cesium.Math.toRadians(90);
console.log("1.角度 - 弧度" ,radians);
// 2.弧度转角度
var degrees = Cesium.Math.toDegrees(2 * Math.PI);
console.log("2.弧度 - 角度" , degrees);
// 3.将经纬度转为笛卡尔坐标
var cartesian3 = Cesium.Cartesian3.fromDegrees(
// 经度
89.5,
// 纬度
20.4,
// 高度
100
);
console.log("3.经纬度 - 笛卡尔空间" , cartesian3);
// 4.将笛卡尔坐标转为经纬度
var cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
console.log("4.笛卡尔空间 - 经纬度" , cartographic);
5.相机的方向和位置
- setView:瞬间到达指定位置和视角
- flyto:让相机飞往某个地方
less
// 05.1.设置相机的视角位置
// 05.1.天安门广场的经纬度位置信息
var position = Cesium.Cartesian3.fromDegrees(116.393428, 39.90923, 100);
// 05.2.设置天安门广场的视角
// viewer.camera.setView({
// // 指定相机位置
// destination: position,
// // 指定相机视角
// orientation: {
// // 指定相机的朝向,偏航角
// heading: Cesium.Math.toRadians(0),
// // 指定相机的俯仰角,0度是竖直向上,-90度是向下
// pitch: Cesium.Math.toRadians(-20),
// // 指定相机的滚转角,翻滚角
// roll: 0
// }
// });
// 05.3.flyto让相机飞往某个地方
viewer.camera.flyTo({
destination: position,
orientation: {
heading: Cesium.Math.toRadians(0),
pitch: Cesium.Math.toRadians(-20),
roll: 0
}
});
// 05.4.通过按键移动相机
document.addEventListener("keydown", (e) => {
// 获取相机离地面的高度
var height = viewer.camera.positionCartographic.height;
// 移动距离
var moveRate = height / 100;
if (e.key == "w") {
// 设置相机向前移动
viewer.camera.moveForward(moveRate);
} else if (e.key == "s") {
// 设置相机向后移动
viewer.camera.moveBackward(moveRate);
} else if (e.key == "a") {
// 设置相机向左移动
viewer.camera.moveLeft(moveRate);
} else if (e.key == "d") {
// 设置相机向右移动
viewer.camera.moveRight(moveRate);
} else if (e.key == "q") {
// 设置相机向左旋转相机
viewer.camera.lookLeft(Cesium.Math.toRadians(0.1));
} else if (e.key == "e") {
// 设置相机向右旋转相机
viewer.camera.lookRight(Cesium.Math.toRadians(0.1));
} else if (e.key == "r") {
// 设置相机向上旋转相机
viewer.camera.lookUp(Cesium.Math.toRadians(0.1));
} else if (e.key == "f") {
// 设置相机向下旋转相机
viewer.camera.lookDown(Cesium.Math.toRadians(0.1));
} else if (e.key == "g") {
// 向左逆时针翻滚
viewer.camera.twistLeft(Cesium.Math.toRadians(0.1));
} else if (e.key == "h") {
// 向右顺时针翻滚
viewer.camera.twistRight(Cesium.Math.toRadians(0.1));
}
});