Cesium是一款面向三维地球和地图的,世界级的JavaScript开源产品。它提供了基于JavaScript语言的开发包,方便用户快速搭建一款零插件的虚拟地球Web应用,并在性能,精度,渲染质量以及多平台,易用性上都有高质量的保证。
通过Cesium提供的JS API,可以实现以下功能:
https://github.com/AnalyticalGraphicsInc/cesium
const viewer new Viewer('viewport',{
sceneMode: SceneMode.SCENE2D, //设置场景模式为2D,默认为3D
selectionIndicator : false, //隐藏选择控件
infoBox : false, //隐藏信息框控件
animation : false, //隐藏动画速度控制控件
fullscreenButton : false, //隐藏全屏控件
sceneModePicker : false, //隐藏场景模式选择控件
timeline : false, //隐藏时间轴控件
navigationHelpButton : false, //隐藏控制帮助控件
homeButton : false, //隐藏返回Home控件
geocoder : false, //隐藏定位搜索控件
navigationInstructionsInitiallyVisible: false, //navigationHelp初始不显示
skyBox : false, //天空设置,undefined则显示默认星空
skyAtmosphere : false, //不显示蓝色的大气层
selectedImageryProviderViewModel : undefined, //不显示地图图像
selectedTerrainProviderViewModel : undefined, //不显示地形图像
globe : false, //不要地球
shadows : false //不显示阳光照射下的阴影效果
})
viewer.cesiumWidget.creditContainer.style.display = "none" //去cesium logo 水印
viewer.resolutionScale = window.devicePixelRatio //dpr优化
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(ScreenSpaceEventType.LEFT_DOUBLE_CLICK) //取消双击默认操作
const tileset = new Cesium3DTileset({
url : uri, //3D Tiles json数据文件
maximumScreenSpaceError : 500, //最大屏幕控件误差,随着相机高度的下降,该值越大,渲染更精细图片的时机越晚
cullWithChildrenBounds : false, //优化项
})
tileset.readyPromise.then(function(tileset) {
const boundingSphere = tileset.boundingSphere //模型的包围球
const radius = boundingSphere.radius //包围球的半径
viewer.zoomTo(tileset, new HeadingPitchRange(0, -90, 700)) //视角转至该模型,相机以该模型为中心,以北为前方,垂直地表向下,高度为700m
})
//相机高度限制
screenSpaceCameraController.minimumZoomDistance = MinimumZoomDistance
screenSpaceCameraController.maximumZoomDistance = MaximumZoomDistance
screenSpaceCameraController.enableTilt = false //限时相机无法倾斜
screenSpaceCameraController.enableZoom = false //限制相机无法缩放
screenSpaceCameraController.enableRotate = false //限制相机无法上下左右移动(3D模式下,2D模式下相机的平行移动是translate)
const eventHandler = new ScreenSpaceEventHandler(viewer.canvas)
//左键点击绑定操作
eventHandler.setInputAction(function(movement) {
const {x, y} = movement.position
console.log("click at [x: " + x + ",y: " + y + "]")
}, ScreenSpaceEventType.LEFT_CLICK)
//鼠标移动绑定操作
eventHandler.setInputAction(function(movement) {
const {x1, y1} = movement.startPosition
const {x2, y2} = movement.endPosition
console.log("start at [x: " + x1 + ",y: " + y1 + "]")
console.log("start at [x: " + x2 + ",y: " + y2 + "]")
}, ScreenSpaceEventType.MOUSE_MOVE)
更多鼠标及手势类型参看文档
https://cesiumjs.org/Cesium/Build/Documentation/ScreenSpaceEventType.html?classFilter=ScreenSpaceEventType
viewer.scene.camera.percentageChanged = 0.05 //设置相机变化的识别精度
//设置相机变化的监听事件
const removeChanged = camera.changed.addEventListener(percentage => {
console.log("camera moved " + percentage + "%")
})
removeChanged() // 移除监听事件
let count = 0
//每帧都会调用的函数,可以在这里写动画控制
viewer.clock.onTick.addEventListener(clock => {
console.log("tick × " + count++)
})
Cartesian3:笛卡尔空间直角坐标系
new Cesium.Cartesian3(x, y, z)
Cartesian3.fromDegrees(longitude, latitude,height) //经纬度(角度)转笛卡尔坐标
Cartesian3.fromRadians(longitude, latitude, height) //经纬度(弧度)转笛卡尔坐标
viewer.camera.pickEllipsoid(movement.position) //屏幕位置转笛卡尔坐标,取与球面相交的点,默认球面为WGS84为时 高度一定为0
viewer.scene.pickPosition(movement.position) //屏幕位置转笛卡尔坐标,取与模型相交的点
可看作以椭球体中心为原点建立的xyz空间直角坐标系,描述点在世界中的位置
Cartographic: 经纬度坐标系
以地球经纬度和高度来描述点的位置
经度:参考椭球面上某点的大地子午面与本初子午面间的两面角。东正西负。
纬度 :参考椭球面上某点的法线与赤道平面的夹角。北正南负。
Cesium中为弧度单位,注意角度与弧度的转换
new Cesium.Cartographic(longitude, latitude, height)
//角度与弧度互相转换
Cesium.Math.toDegrees(radians)
Cesium.Math.toRadians(degrees)
Cartographic.fromCartesian(cartesian3) //笛卡尔坐标转经纬度(弧度)坐标
canvas坐标(屏幕坐标)
鼠标监听事件获得的位置坐标,为{x, y}格式的二维坐标
new Cartesian2(x,y)
SceneTransforms.wgs84ToWindowCoordinates(scene, entityCartesian3Position, position) //将笛卡尔坐标转为屏幕坐标
viewer.scene.cartesianToCanvasCoordinates(cartesian3Position, position) //转为屏幕坐标
const entityCartesian3Position = entity.position.getValue(JulianDate.now()) // 获取实体当前的位置,与时间点相关,为笛卡尔坐标
entity.position = newCartesian3Position // 设置实体的位置
camera.position // 获取相机的位置,为笛卡尔坐标
camera.setView({ // 改变相机的位置
destination: newCartesian3Position
})
//添加一个billboard实体
const entity = new Entity({
id: 0,
name: "一个billboard实体",
position: cartesian3Position
billboard: {
img: "../images/Cesium_Logo_overlay.png",
width: 30,
height: 30,
}
})
viewer.entities.add(entity)
4.2 更多
5.1 基本
5.2 自定义几何体
视锥指的是一个实体形状,看起来像是一个顶部被平行于地基切除的金字塔。这就是一个透视相机渲染时能看到区域的形状。下面的思考实验有助于解释这个情况的成因。
想象拿着一根直棍子(比如扫帚把手或者铅笔)的一端对着相机并拍照。如果棍子正对着照片的中心,垂直于相机镜片,那么相机上只会看到一个圆;除了棍子的断点其它部分会被遮挡。如果将棍子向上移,慢慢能看见棍子的远端,但是将棍子向上翘起又会将远端隐藏起来。继续向上移动并向上调整棍子角度,圆形的断电最终会到达照片的边缘。在这个点上,现实世界中所有在棍子所在线上方的物体在照片中都不会出现。
棍子也可以简单的像左、右、下或者水平垂直移动的任意组合。相应调整棍子的角度都可以将棍子在相机中隐藏起来。
这个思考实验的意义在于,相机图片中的任何一个点最终对应于现实世界中的一条线,并且只会显示这条线上的一个点,这条线上所有在这个显示的点后面的物体都会被遮挡。图片的外边界由四个顶点对应的发散线定义。这四条线最终相交于相机位置所在的点。Unity中这个点就是相机的transform位置,被称为透视视图的中心。屏幕顶部和底部中心点汇集到透视视图中心点的连线形成的角度被称为视野(field of view FOV)。
如上面介绍的,所有落在照片边界对应的发散线以外的事物在相机上是不可见的,同时还有两外两个限制。远近裁切平面平行于相机的XY平面,分别在相机的中心线上设置了一个确定的距离。所有于相机的距离小于近平面的距离或者大于远平面的距离的物体都不会被渲染。