开发之前设置步骤:
访问Cesium Viewer确保您的系统与Cesium兼容
安装Node.js的。
克隆或下载zip并提取内容。
在控制台中,导航到根cesium-workshop
目录。
运行npm install
。
运行npm start
,点击控制台上的http://localhost:8080
Source/ : 我们项目的代码。
ThirdParty/ : 外部js库,目前只包含cesium。
LICENSE.md : 我们项目的说明条款。
index.html : 主页,包含项目程序代码和页面结构。
server.js : 简单的基于nodejs的http服务器。
CesiumJS完全兼容现代javascript 库和框架,下面是一些示例:
点击 http://localhost:8080/ 出现的页面:
Documentation
里面是Cesium的完整的API说明,里面可以找到:
1、某一个模块的所有函数、属性
2、部分效果截图
3、部分函数,属性调用代码示例
Sandcastle
一个沙盒,你可以在里面浏览当前版本的一些功能特性:
1、一个可运行的代码库
2、新建一个页面,进行代码测试
3、导出测试代码
创建文件夹 cesium-test
引入编译成果 ,将cesium源码中的Build文件夹,拷入cesium-test
创建html ,将cesium源码中Apps/ 中的HelloWorld.html 拷入cesium-test
修改js和css的文件路径
发布
界面上默认的小控件可以通过在初始化Viewer的时候设置相应的属性来关闭
var viewer = new Cesium.Viewer('cesiumContainer',{
geocoder:false,
homeButton:false,
sceneModePicker:false,
baseLayerPicker:false,
navigationHelpButton:false,
animation:false,
creditContainer:"credit",
timeline:false,
fullscreenButton:false,
vrButton:false,
});
//界面默认的小控件的关闭方法,还有很多额外的属性,可以查看帮助文档
/* 不占据空间,无法点击 */
.cesium-viewer-toolbar, /* 右上角按钮组 */
.cesium-viewer-animationContainer, /* 左下角动画控件 */
.cesium-viewer-timelineContainer, /* 时间线 */
.cesium-viewer-bottom /* logo信息 */
{
display: none;
}
.cesium-viewer-fullscreenContainer /* 全屏按钮 */
{
position: absolute; top: -999em; }
/*注:全屏按钮不能通过display:none的方式来达到隐藏的目的,这是因为生成的按钮控件的行内样式设置了display属性,会覆盖引入的css属性*/
viewer.scene.debugShowFramesPerSecond = true;
案例:添加立方体
var viewer = new Cesium.Viewer('cesiumContainer');
var redBox = viewer.entities.add({
name : 'Models', //名字,非唯一
position: Cesium.Cartesian3.fromDegrees(-107.0, 40.0, 300000.0), //位置
// 边框
box : {
dimensions : new Cesium.Cartesian3(400000.0, 300000.0, 500000.0),
material : Cesium.Color.RED.withAlpha(0.5),
outline : true,
outlineColor : Cesium.Color.BLACK
}
});
viewer.zoomTo(viewer.entities);
官方说明:CZML是一种JSON格式的字符串,用于描述与时间有关的动画场景,CZML包含点、线、地标、模型、和其他的一些图形元素,并指明了这些元素如何随时间而变化。某种程度上说, Cesium 和 CZML的关系就像 Google Earth 和 KML
var czml = [{
"id" : "document",
"name" : "box",
"version" : "1.0"
},{
"id" : "shape2",
"name" : "Red box with black outline",
"position" : {
"cartographicDegrees" : [-107.0, 40.0, 300000.0]
},
"box" : {
"dimensions" : {
"cartesian": [400000.0, 300000.0, 500000.0]
},
"material" : {
"solidColor" : {
"color" : {
"rgba" : [255, 0, 0, 128]
}
}
},
"outline" : true,
"outlineColor" : {
"rgba" : [0, 0, 0, 255]
}
}
}];
var viewer = new Cesium.Viewer('cesiumContainer');
var dataSourcePromise = Cesium.CzmlDataSource.load(czml);
viewer.dataSources.add(dataSourcePromise);
viewer.zoomTo(dataSourcePromise);
3D Tiles是一种开放式规范,用于跨桌面,Web和移动应用程序共享,可视化,融合以及与大量异构3D地理空间内容交互。
3D Tiles将用于流式传输3D内容,包括建筑物,树木,点云和矢量数据。
参考[官网 3dtiles 介绍 ][https://cesium.com/blog/2015/08/10/introducing-3d-tiles/]
//contextCapture 可以将无人机成果转换成Cesium支持的倾斜摄影成果 ,数据的加载比较简单
//但是问题在于生成的数据不一定是落在地面上,有可能是浮在空中的
var tileset = viewer.scene.primitives.add(new Cesium.Cesium3DTileset({
url: url, //数据路径
maximumScreenSpaceError: 2, //最大的屏幕空间误差
maximumNumberOfLoadedTiles: 1000, //最大加载瓦片个数
modelMatrix: m //形状矩阵
}))
希望拍摄的成果能贴到地面上,和地图能很好的融合在一起
Cesium3DTile里面的一个属性:可以更改位置
自己获取偏移量
目标位置 = 平移矩阵 * 原始位置 (参考《WebGl编程指南》的第三章第四章)
//Tx,Ty,Tz就是我们需要设置的 x,y,z方向上的平移距离
//由于Cesium的矩阵是列主序的,所以这里写成:
//创建平移矩阵方法一
/*m = Cesium.Matrix4.fromArray([
1.0, 0.0, 0.0, 0.0,
0.0, 1.0, 0.0, 0.0,
0.0, 0.0, 1.0, 0.0,
x, y, z, 1.0
])*/
//创建平移矩阵方法二
var translation=Cesium.Cartesian3.fromArray([x, y, z]);
m= Cesium.Matrix4.fromTranslation(translation);
//生效
tileset._modelMatrix = m;
/*这里我们只需要不断的修改 x,y,z,就可以调整物体的位置了
获取 x,y,z 之后,在加载3D Tiles 时将modelMatrix 设置成目标 x,y,z值,就完成了*/
计算偏移量
[官方示例 ][https://cesiumjs.org/Cesium/Build/Apps/Sandcastle/index.html?src=3D Tiles Adjust Height.html]
//直接调用函数,调整高度,height表示物体离地面的高度
function changeHeight(height) {
height = Number(height);
if (isNaN(height)) {
return;
}
var cartographic = Cesium.Cartographic.fromCartesian(tileset.boundingSphere.center);
var surface = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height);
var offset = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude,height);
var translation = Cesium.Cartesian3.subtract(offset, surface, new Cesium.Cartesian3());
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);
}
cesium中常用的坐标有两种WGS84地理坐标系和笛卡尔空间坐标系(世界坐标)。
WGS84坐标一般以经纬度来指明一个地点,原点在椭球的质心 。
笛卡尔空间坐标系常用来做一些空间位置变换如平移旋转缩放等等,坐标原点在椭球的中心 。
偏航(yaw)/俯仰(pitch)/滚动(roll)
屏幕坐标----------------------------------------------->Pick
世界坐标----------------------------------------------->Cartesian
地理坐标(弧度) ---------------------------------->cartographic
经纬度坐标-------------------------------------------->Point
说明:以经纬度固定模型位置,要先将经纬度转换为世界坐标
new Cesium.Cartesian2(1,1) //表示一个二维笛卡尔坐标系,也就是直角坐标系(屏幕坐标系)
new Cesium.Cartesian3(1,1,1) //表示一个三维笛卡尔坐标系,也是直角坐标系(真实世界的坐标系)
var pick1= scene.globe.pick(viewer.camera.getPickRay(pt1), scene)
//其中pt1为一个二维屏幕坐标。
var geoPt1= scene.globe.ellipsoid.cartesianToCartographic(pick1)
//其中pick1是一个Cesium.Cartesian3对象。
var point1=[geoPt1.longitude / Math.PI * 180,geoPt1.latitude / Math.PI * 180];
//其中geoPt1是一个地理坐标。
var cartographic = Cesium.Cartographic.fromDegree(point) //point是经纬度值
var coord_wgs84 = Cesium.Cartographic.fromDegrees(lng, lat, alt);//单位:度,度,米
var cartesian = Cesium.Cartesian3.fromDegree(point)
var d = Cesium.Cartesian3.distance(
new Cesium.Cartesian3(pick1.x, pick1.y, pick1.z),
new Cesium.Cartesian3(pick3.x, pick3.y, pick3.z)
);
//pick1、pick3都是三维坐标系
Cesium默认支持使用鼠标和触摸事件控制相机 :
camera.setView({
destination : new Cesium.Cartesian3(x, y, z),
orientation: {
//heading/pitch/roll 的单位是弧度
heading : headingAngle, //方向向量以正东方向为轴的旋转角度
pitch : pitchAngle, //方向和水平平面的夹角
roll : rollAngle //方向向量指向水平平面上方,反之表示方向向量指向平面下方
}
});```
##### 方法二、Rectangle
> 设置为一个矩形区域
```js
viewer.camera.setView({
///西,南,东,北
destination : Cesium.Rectangle.fromDegrees(west, south, east, north),
orientation: {
heading : headingAngle,
pitch : pitchAngle,
roll : rollAngle
}
})
//参数为可选参数,如果不设置默认以当前的相机去计算对应的属性
跳转镜头到指定位置
//lookAt(target, offect)
//target目标位置在世界坐标,offect以目标为中心的当地东北向参考系中的目标的偏移量。
view.camera.flyTo({
destination : Cesium.Cartesian3.fromDegrees(116.435314,39.960521, 15000.0), // 设置位置
orientation: {
heading : Cesium.Math.toRadians(20.0), // 方向
pitch : Cesium.Math.toRadians(-90.0),// 倾斜角度
roll : 0
},
duration:5, // 设置飞行持续时间,默认会根据距离来计算
complete: function () {
// 到达位置后执行的回调函数
console.log('到达位置');
},
cancle: function () {
// 如果取消飞行则会调用此函数
console.log('取消飞行')
},
// 如果摄像机飞越高于该值,则调整俯仰俯仰的俯仰角度,并将地球保持在视口中。
pitchAdjustHeight: -90,
maximumHeight:5000, // 相机最大飞行高度
flyOverLongitude: 100, // 如果到达目的地有2种方式,设置具体值后会强制选择方向飞过这个经度
});
lookAt会将视角固定在设置的点上
var center = Cesium.Cartesian3.fromDegrees(-72.0, 40.0);
var heading = Cesium.Math.toRadians(50.0);
var pitch = Cesium.Math.toRadians(-20.0);
var range = 5000.0;
view.camera.lookAt(center, new Cesium.HeadingPitchRange(heading, pitch, range));
//相机的高度的最小值
viewer.scene.screenSpaceCameraController.minimumZoomDistance = 250000;
//相机高度的最大值
viewer.scene.screenSpaceCameraController.maximumZoomDistance = 22000000;
//设置相机缩小时的速率
viewer.scene.screenSpaceCameraController._minimumZoomRate = 30000;
//设置相机放大时的速率
viewer.scene.screenSpaceCameraController._maximumZoomRate=5906376272000
this.viewer.scene.globe.depthTestAgainsTerrain = true
var viewer = new Cesium.Viewer('cesiumDemo',{
baseLayerPicker: false,
imageryProvider: new Cesium.ArcGisMapServerImageryProvider({
url: 'http://server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'
})
});
var scene = viewer.scene;
var canvas = viewer.canvas; // 获取画布
canvas.setAttribute('tabindex', '0'); // 获取焦点
canvas.onclick = function() {
canvas.focus();
};
var ellipsoid = viewer.scene.globe.ellipsoid; // 获取地球球体对象
// 禁用默认的事件处理程序
// 如果为真,则允许用户旋转相机。如果为假,相机将锁定到当前标题。此标志仅适用于2D和3D。
scene.screenSpaceCameraController.enableRotate = false;
// 如果为true,则允许用户平移地图。如果为假,相机将保持锁定在当前位置。此标志仅适用于2D和Columbus视图模式。
scene.screenSpaceCameraController.enableTranslate = false;
// 如果为真,允许用户放大和缩小。如果为假,相机将锁定到距离椭圆体的当前距离
scene.screenSpaceCameraController.enableZoom = false;
// 如果为真,则允许用户倾斜相机。如果为假,相机将锁定到当前标题。这个标志只适用于3D和哥伦布视图。
scene.screenSpaceCameraController.enableTilt = false;
// 如果为true,则允许用户使用免费外观。如果错误,摄像机视图方向只能通过转换或旋转进行更改。此标志仅适用于3D和哥伦布视图模式。
scene.screenSpaceCameraController.enableLook = false;
// 鼠标开始位置
var startMousePosition;
// 鼠标位置
var mousePosition;
// 鼠标状态标志
var flags = {
looking : false,
moveForward : false, // 向前
moveBackward : false, // 向后
moveUp : false,// 向上
moveDown : false,// 向下
moveLeft : false,// 向左
moveRight : false// 向右
};
var handler = new Cesium.ScreenSpaceEventHandler(canvas);
// 接收用户鼠标(手势)事件
handler.setInputAction(function(movement) {
// 处理鼠标按下事件
// movement: 接收值为一个对象,含有鼠标单击的x,y坐标
flags.looking = true;
// 设置鼠标当前位置
mousePosition = startMousePosition = Cesium.Cartesian3.clone(movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_DOWN);
handler.setInputAction(function(movement) {
// 处理鼠标移动事件
// 更新鼠标位置
mousePosition = movement.endPosition;
}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);
handler.setInputAction(function(position) {
// 处理鼠标左键弹起事件
flags.looking = false;
}, Cesium.ScreenSpaceEventType.LEFT_UP);
// 根据键盘按键返回标志
function getFlagForKeyCode(keyCode) {
switch (keyCode) {
case 'W'.charCodeAt(0):
return 'moveForward';
case 'S'.charCodeAt(0):
return 'moveBackward';
case 'Q'.charCodeAt(0):
return 'moveUp';
case 'E'.charCodeAt(0):
return 'moveDown';
case 'D'.charCodeAt(0):
return 'moveRight';
case 'A'.charCodeAt(0):
return 'moveLeft';
default:
return undefined;
}
}
// 监听键盘按下事件
document.addEventListener('keydown', function(e) {
// 获取键盘返回的标志
var flagName = getFlagForKeyCode(e.keyCode);
if (typeof flagName !== 'undefined') {
flags[flagName] = true;
}
}, false);
// 监听键盘弹起时间
document.addEventListener('keyup', function(e) {
// 获取键盘返回的标志
var flagName = getFlagForKeyCode(e.keyCode);
if (typeof flagName !== 'undefined') {
flags[flagName] = false;
}
}, false);
// 对onTick事件进行监听
// onTick事件:根据当前配置选项,从当前时间提前计时。应该每个帧都调用tick,而不管动画是否发生。
// 简单的说就是每过一帧都会执行这个事件
viewer.clock.onTick.addEventListener(function(clock) {
// 获取实例的相机对象
var camera = viewer.camera;
if (flags.looking) {
// 获取画布的宽度
var width = canvas.clientWidth;
// 获取画布的高度
var height = canvas.clientHeight;
// Coordinate (0.0, 0.0) will be where the mouse was clicked.
var x = (mousePosition.x - startMousePosition.x) / width;
var y = -(mousePosition.y - startMousePosition.y) / height;
var lookFactor = 0.05;
camera.lookRight(x * lookFactor);
camera.lookUp(y * lookFactor);
}
// 获取相机高度
// cartesianToCartographic(): 将笛卡尔坐标转化为地图坐标,方法返回Cartographic对象,包含经度、纬度、高度
var cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
var moveRate = cameraHeight / 100.0;
// 如果按下键盘就移动
if (flags.moveForward) {
camera.moveForward(moveRate);
}
if (flags.moveBackward) {
camera.moveBackward(moveRate);
}
if (flags.moveUp) {
camera.moveUp(moveRate);
}
if (flags.moveDown) {
camera.moveDown(moveRate);
}
if (flags.moveLeft) {
camera.moveLeft(moveRate);
}
if (flags.moveRight) {
camera.moveRight(moveRate);
}
});