learning_cesium/Camera相机系统.html

341 lines
13 KiB
HTML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="en">
<head>
<!-- Use correct character set. -->
<meta charset="utf-8">
<!-- Tell IE to use the latest, best version. -->
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<!-- Make the application on mobile take up the full browser screen and disable user scaling. -->
<meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, minimum-scale=1, user-scalable=no">
<title>Learning Cesium!</title>
<script src="./Build/Cesium/Cesium.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<style>
@import url(./Build/Cesium/Widgets/widgets.css);
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#credit {
display: none;
}
#btnContainer {
position: absolute;
top: 50px;
left: 150px;
z-index: 99999999;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<div id="credit"></div>
<div id="btnContainer">
<el-row>
<el-button @click="setView">setView</el-button>
<el-button @click="flyTo">flyTo</el-button>
<el-button @click="flyToPosition">flyToPosition</el-button>
<el-button @click="flyToRectangle">flyToRectangle</el-button>
<el-button @click="flyToEasing">flyToEasing</el-button>
<el-button @click="lookAt">lookAt</el-button>
<el-button @click="lookAtTransform">lookAtTransform</el-button>
</el-row>
</div>
<script>
/**
三维的GIS中移动视域范围不仅要确定视点的位置还要确定视线的方向
Cesium通过相机控制场景中的视域旋转、缩放、平移
主要用两个参数设置相机的状态:
1.position位置使用一个三维的笛卡尔空间坐标点x,y,z
2.orientation方向(heading水平方向、pitch俯仰角、roll翻滚角)欧拉角
操作相机的常用方法有:
1.setView:通过定义相机的位置和实现方向来控制,没有过渡动画,适合快速切换视角。
2.viewBoundingSphere:也没有过渡动画,区别在于该方法必须设定模型的外接圆,适合室内浏览,因为室内空间较小,相机移动的幅度不易控制
视点位于外接球的球心,可以设置偏移。
3.flyTo:具有空中飞行的过渡动画效果可以设置飞行时间。如果场景secne中添加了矢量数据模型或几何对象可以使用该方法进行聚焦如Entity, EntityCollection, DataSource, Cesium3DTilset, and much more.
4.lookAt:将视角固定在所设置的目的点上,用户可以通过鼠标任意旋转视角方向,但不会改变其位置,同时缩放会失效,中轮滚动事件也会失效。
5.lookAtTransform:将相机锁定在某个点上
*/
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5ZjRjNTZkNC01NDYxLTRhMjQtOGEwZC1kZjA3YzQ5YTJlZDkiLCJpZCI6MjYwODQsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1ODcxOTMwODN9.prGsSKyAW_9Ow5zHYPhbm3LsQL-ApQw5-5PNJkDaHi8';
new Vue({
el: '#btnContainer',
data: function () {
return {
viewer: null,
directions:{
forward:false,
backward:false,
up:false,
down:false,
left:false,
right:false,
twistLeft:false,
twistRight:false
}
}
},
mounted:function(){
this.initCesium();
this.initEvent();
},
methods:{
initCesium:function(){
/**
* Viewer对象
* 用于构建应用程序的基本小部件。它将所有标准的Cesium部件组合到一个可重用的包中。
* 小部件可以通过使用mixin来扩展来添加对各种应用程序有用的功能
*/
//Initialize the viewer widget with several custom options and mixins.
this.viewer = new Cesium.Viewer('cesiumContainer', {
/**
* 场景模式,默认SceneMode.SCENE3D
* SceneMode:指定场景是3D/2D/2.5D,可选值:
* MORPHING在模式之间变形如3D转2D
* COLUMBUS_VIEW2.5D视角,地图会被平铺,高度为非零的对象被绘制在上面。
* SCENE2D:2D模式地图会被自顶向下正射投影
* SCENE3D3D模式一个传统的三维视角的全球。
*/
// sceneMode : Cesium.SceneMode.COLUMBUS_VIEW,
sceneMode: Cesium.SceneMode.SCENE3D,
//指定椭球面提供地形或其他几何图形数据,
terrainProvider: Cesium.createWorldTerrain(),
//指定影像数据的数据源,该选项只有在baseLayerPicker设置为false时生效
imageryProvider : new Cesium.OpenStreetMapImageryProvider({
url : 'https://a.tile.openstreetmap.org/'
}),
// imageryProvider: new Cesium.WebMapTileServiceImageryProvider({
// url: 'http://t0.tianditu.gov.cn/img_w/wmts?tk=ebf64362215c081f8317203220f133eb',
// layer: 'img',
// style: 'default',
// tileMatrixSetID: 'w',
// format: 'tiles',
// maximumLevel: 18
// }),
//设置背景,如果为false则星星/月亮/太阳都不会渲染
// skyBox : new Cesium.SkyBox({
// sources : {
// positiveX : 'stars/100_BK.jpg',
// negativeX : 'stars/100_BK.jpg',
// positiveY : 'stars/100_BK.jpg',
// negativeY : 'stars/100_BK.jpg',
// positiveZ : 'stars/100_BK.jpg',
// negativeZ : 'stars/100_BK.jpg'
// }
// }),
// Show Columbus View map with Web Mercator projection
mapProjection: new Cesium.WebMercatorProjection(),
geocoder: false,//位置查找
homeButton: false,//视图返回初始位置
sceneModePicker: false,//视角选择器
baseLayerPicker: false,//底图选择器
navigationHelpButton: false,//导航帮助按钮
animation: false,//动画控制器
creditContainer: "credit",//版权显示,指定dom对象的id,再通过id样式可以隐藏CESIUM 版本图标
timeline: false,//时间线
fullscreenButton: false,//全屏控件
vrButton: false,
infoBox:false,
shouldAnimate:true,
scene3DOnly: true,//默认false若为true,所有几何体实例将仅会在3D模式中渲染(在GPU内存中)
});
//Add basic drag and drop functionality
this.viewer.extend(Cesium.viewerDragDropMixin);
//Show a pop-up alert if we encounter an error when processing a dropped file
this.viewer.dropError.addEventListener(function (dropHandler, name, error) {
console.log(error);
window.alert(error);
});
},
setView:function(){
var position = Cesium.Cartesian3.fromDegrees(113.331875,23.110038,10000000);
this.viewer.camera.setView({
destination: position,
orientation: {
heading: Cesium.Math.toRadians(0.0),//使用弧度的形式
pitch: Cesium.Math.toRadians(-70.0),
roll: 0.0
}
})
},
flyTo:function(){
var position = Cesium.Cartesian3.fromDegrees(-113.331875,19.110038,10000000);
this.viewer.camera.flyTo({
destination: position,
orientation: {//使用欧拉角
heading: Cesium.Math.toRadians(0.0),//使用弧度的形式
pitch: Cesium.Math.toRadians(-60.0),
roll: 0.0
},
duration:3,//设置飞行时间,单位为秒
complete:function(){
console.log("动画完成后的回调!")
},
cancel:function(){
console.log("动画被取消后的回调!")
},
maximumHeight:5000,//最大的飞行高度
})
},
flyToPosition :function(){
this.viewer.camera.flyTo({
destination : Cesium.Cartesian3.fromDegrees(-117.16, 32.71, 15000.0)
});
},
flyToRectangle:function(){
var west = -90.0;
var south = 38.0;
var east = -87.0;
var north = 40.0;
var rectangle = this.viewer.entities.add({
rectangle: {
coordinates: Cesium.Rectangle.fromDegrees(west, south, east, north),
},
});
this.viewer.flyTo(rectangle);
// this.viewer.camera.flyTo({
// destination :Cesium.Rectangle.fromDegrees(west, south, east, north)
// });
},
flyToEasing:function(){
var that = this;
that.viewer.camera.flyTo({
destination : new Cesium.Cartesian3(-3961951.575572026, 3346492.0945766014, 3702340.5336036095),
orientation : {
direction : new Cesium.Cartesian3(0.8982074415844437, -0.4393530288745287, 0.013867512433959908),
up : new Cesium.Cartesian3(0.12793638617798253, 0.29147314437764565, 0.9479850669701113),
},
complete: function () {
// setTimeout(function () {
// that.viewer.camera.flyTo({
// destination : new Cesium.Cartesian3(-2304817.2435183465, -3639113.128132953, 4688495.013644141),
// orientation : {
// direction : new Cesium.Cartesian3(0.3760550186878076, 0.9007147395506565, 0.21747547189489164),
// up : new Cesium.Cartesian3(-0.20364591529594356, -0.14862471084230877, 0.9676978022659334),
// },
// easingFunction: Cesium.EasingFunction.QUADRATIC_IN_OUT,
// duration: 5
// });
// }, 1000);
},
});
},
lookAt:function(){
var center = Cesium.Cartesian3.fromDegrees(113.331875,19.110038,5000000);
var heading = Cesium.Math.toRadians(0);
var pitch = Cesium.Math.toRadians(-90.0);
var range = 50;
this.viewer.camera.lookAt(center,new Cesium.HeadingPitchRange(heading,pitch,range));
},
lookAtTransform:function(){
// 1. Using a cartesian offset
// var center = Cesium.Cartesian3.fromRadians(2.4213211833389243, 0.6171926869414084, 3626.0426275055174);
// var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center);
// this.viewer.camera.lookAtTransform(transform, new Cesium.Cartesian3(0.0, -4790000.0, 3930000.0));
// 2. Using a HeadingPitchRange offset
var center = Cesium.Cartesian3.fromRadians(2.4213211833389243, 0.6171926869414084, 3626.0426275055174);
var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center);
this.viewer.scene.camera.lookAtTransform(transform, new Cesium.HeadingPitchRange(0, -Math.PI/4, 2900));
},
initEvent:function(){
var that = this;
/**
* 绑定键盘事件,实现使用键盘操作相机的视域移动
*/
document.addEventListener("keydown",function(e){
var direction = that.getDirectionForKeyCode(e.keyCode);
if(typeof direction !== 'undefined'){
that.directions[direction] = true;
}
})
document.addEventListener("keyup",function(e){
var direction = that.getDirectionForKeyCode(e.keyCode);
if(typeof direction !== 'undefined'){
that.directions[direction] = false;
}
})
this.viewer.clock.onTick.addEventListener(function(clock){
var camera = that.viewer.camera;
var ellipsoid = that.viewer.scene.globe.ellipsoid;
var cameraHeight = ellipsoid.cartesianToCartographic(camera.position).height;
var moveRate = cameraHeight/100.0;
that.directions.forward&&camera.moveForward(moveRate);
that.directions.backward&&camera.moveBackward(moveRate);
that.directions.up&&camera.moveUp(moveRate);
that.directions.down&&camera.moveDown(moveRate);
that.directions.left&&camera.moveLeft(moveRate);
that.directions.right&&camera.moveRight(moveRate);
that.directions.twistLeft&&camera.twistLeft(moveRate);
that.directions.twistRight&&camera.twistRight(moveRate);
})
},
getDirectionForKeyCode:function(keyCode){
switch(keyCode){
case "W".charCodeAt(0):
return "forward";
case "S".charCodeAt(0):
return "backward";
case "A".charCodeAt(0):
return "left";
case "D".charCodeAt(0):
return "right";
case "Q".charCodeAt(0):
return "up";
case "E".charCodeAt(0):
return "down";
case "F".charCodeAt(0):
return "twistLeft";
case "G".charCodeAt(0):
return "twistRight";
}
}
}
})
//Secne场景中执行调用图层、3D Tiles数据加载、场景交互等功能以及一些场景数据加载Primitivew API
//Secne中的camera属性与Scene中的camera属性相同。
// var scene = viewer.scene;
// //加载3D tiles格式的三维模型
// var tileset = new Cesium.Cesium3DTileset({
// url:"./SampleData/Cesium3DTiles/Tilesets/Tileset/tileset.json"
// });
// tileset.readyPromise.then(function(tileset){
// viewer.scene.primitives.add(tileset);
// viewer.camera.viewBoundingSphere(tileset.boundingSphere,new Cesium.HeadingPitchRange(-1.57,0,2))
// })
</script>
</body>
</html>