在cesium裏面實現飛行漫遊,由於沒有找到合適的案例,自力更生,豐衣足食。
相機的移動主要兩種方式:
setView,flyTo
其中flyTo測試了,感覺不合適,所以用了setView,當然只是自己的淺薄認識,如有錯誤,敬請指正。
廢話不多說了,直接上代碼,基本都能看懂吧,我儘量寫了註釋了。
另外代碼和環境我都上傳了,地址:https://download.csdn.net/download/dragonrxl/11579847
<!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>cisium airplane trip</title>
<script src="Build/Cesium/Cesium.js"></script>
<style>
@import url(Build/Cesium/Widgets/widgets.css);
html, body, #cesiumContainer {
width: 100%; height: 100%; margin: 0; padding: 0; overflow: hidden;
}
.cesium-widget-credits{ display:none} /** 隱藏版權信息 **/
.cesium-viewer .cesium-widget-credits{ display:none }
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script>
var viewer = new Cesium.Viewer('cesiumContainer', {
geocoder: false,//是否顯示geocoder小器件,右上角查詢按鈕
homeButton:false,//是否顯示Home按鈕
sceneModePicker:false,//是否顯示3D/2D選擇器
baseLayerPicker:false,//是否顯示圖層選擇器
navigationHelpButton:false,//是否顯示右上角的幫助按鈕
animation:false,//是否創建動畫小器件,左下角儀表
creditContainer:"cesiumContainer",// 對應上面div的ID
timeline:false,//是否顯示時間軸
fullscreenButtion:false,//是否顯示全屏按鈕
vrButton:false,
selectionIndicator : false,//是否顯示選取指示器組件
});
// 上面配置選項可以控制部分控件是否顯示
viewer.scene.debugShowFramesPerSecond = true;// 顯示幀率
/** 默認使用bing地圖,轉換爲google地圖開始 **/
var google = new Cesium.UrlTemplateImageryProvider({
url : 'http://mt0.google.cn/vt/lyrs=s&hl=zh-CN&x={x}&y={y}&z={z}',
tilingScheme : new Cesium.WebMercatorTilingScheme(),
maximumLevel : 20
});
viewer.imageryLayers.addImageryProvider(google);
/** 默認使用bing地圖,轉換爲google地圖結束 **/
/** 相機視角飛行 開始 **/
var marks = [
{lng: 116.812948,lat:36.550064, height:100, flytime:15},// height:相機高度(單位米) flytime:相機兩個標註點飛行時間(單位秒)
{lng: 116.812948,lat:36.560064, height:100, flytime:15},
{lng: 116.802948,lat:36.560064, height:100, flytime:15},
{lng: 116.802948,lat:36.550064, height:100, flytime:15},
];// 地標集合 根據地標順序來進行漫遊
var marksIndex = 1;
var pitchValue = -20;
viewer.scene.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(marks[0].lng,marks[0].lat, marks[0].height), //定位座標點,建議使用谷歌地球座標位置無偏差
duration:7 //定位的時間間隔
});
setTimeout(function(){
flyExtent();
},7000);
function flyExtent(){
// 相機看點的角度,如果大於0那麼則是從地底往上看,所以要爲負值
var pitch = Cesium.Math.toRadians(pitchValue);
// 時間間隔2秒鐘
setExtentTime(marks[marksIndex].flytime);
var Exection = function TimeExecution() {
var preIndex = marksIndex - 1;
if(marksIndex == 0){
preIndex = marks.length -1;
}
var heading = bearing(marks[preIndex].lat, marks[preIndex].lng, marks[marksIndex].lat, marks[marksIndex].lng);
heading = Cesium.Math.toRadians(heading);
// 當前已經過去的時間,單位s
var delTime = Cesium.JulianDate.secondsDifference(viewer.clock.currentTime, viewer.clock.startTime);
var originLat = marksIndex == 0 ? marks[marks.length - 1].lat : marks[marksIndex-1].lat;
var originLng = marksIndex == 0 ? marks[marks.length - 1].lng : marks[marksIndex-1].lng;
var endPosition = Cesium.Cartesian3.fromDegrees(
(originLng+(marks[marksIndex].lng-originLng)/marks[marksIndex].flytime*delTime),
(originLat+(marks[marksIndex].lat-originLat)/marks[marksIndex].flytime*delTime),
marks[marksIndex].height
);
viewer.scene.camera.setView({
destination: endPosition,
orientation: {
heading: heading,
pitch : pitch,
}
});
if (Cesium.JulianDate.compare(viewer.clock.currentTime, viewer.clock.stopTime) >= 0) {
viewer.clock.onTick.removeEventListener(Exection);
changeCameraHeading();
}
};
viewer.clock.onTick.addEventListener(Exection);
}
// 相機原地定點轉向
function changeCameraHeading(){
var nextIndex = marksIndex + 1;
if(marksIndex == marks.length - 1){
nextIndex = 0;
}
// 計算兩點之間的方向
var heading = bearing(marks[marksIndex].lat, marks[marksIndex].lng, marks[nextIndex].lat, marks[nextIndex].lng);
// 相機看點的角度,如果大於0那麼則是從地底往上看,所以要爲負值
var pitch = Cesium.Math.toRadians(pitchValue);
// 給定飛行一週所需時間,比如10s, 那麼每秒轉動度數
var angle = (heading - Cesium.Math.toDegrees(viewer.camera.heading)) / 2;
// 時間間隔2秒鐘
setExtentTime(2);
// 相機的當前heading
var initialHeading = viewer.camera.heading;
var Exection = function TimeExecution() {
// 當前已經過去的時間,單位s
var delTime = Cesium.JulianDate.secondsDifference(viewer.clock.currentTime, viewer.clock.startTime);
var heading = Cesium.Math.toRadians(delTime * angle) + initialHeading;
viewer.scene.camera.setView({
orientation: {
heading : heading,
pitch : pitch,
}
});
if (Cesium.JulianDate.compare(viewer.clock.currentTime, viewer.clock.stopTime) >= 0) {
viewer.clock.onTick.removeEventListener(Exection);
marksIndex = ++marksIndex >= marks.length ? 0 : marksIndex;
flyExtent();
}
};
viewer.clock.onTick.addEventListener(Exection);
}
// 設置飛行的時間到viewer的時鐘裏
function setExtentTime(time){
var startTime = Cesium.JulianDate.fromDate(new Date());
var stopTime = Cesium.JulianDate.addSeconds(startTime, time, new Cesium.JulianDate());
viewer.clock.startTime = startTime.clone(); // 開始時間
viewer.clock.stopTime = stopTime.clone(); // 結速時間
viewer.clock.currentTime = startTime.clone(); // 當前時間
viewer.clock.clockRange = Cesium.ClockRange.CLAMPED; // 行爲方式
viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK; // 時鐘設置爲當前系統時間; 忽略所有其他設置。
}
/** 相機視角飛行 結束 **/
/** 飛行時 camera的方向調整(heading) 開始 **/
// Converts from degrees to radians.
function toRadians(degrees) {
return degrees * Math.PI / 180;
}
// Converts from radians to degrees.
function toDegrees(radians) {
return radians * 180 / Math.PI;
}
function bearing(startLat, startLng, destLat, destLng){
startLat = this.toRadians(startLat);
startLng = this.toRadians(startLng);
destLat = this.toRadians(destLat);
destLng = this.toRadians(destLng);
let y = Math.sin(destLng - startLng) * Math.cos(destLat);
let x = Math.cos(startLat) * Math.sin(destLat) - Math.sin(startLat) * Math.cos(destLat) * Math.cos(destLng - startLng);
let brng = Math.atan2(y, x);
let brngDgr = this.toDegrees(brng);
return (brngDgr + 360) % 360;
}
/** 飛行時 camera的方向調整(heading) 結束 **/
</script>
</body>
</html>