learning_cesium/全景漫游.html

376 lines
12 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>全景漫游</title>
<link
href="https://cdn.jsdelivr.net/npm/cesium@1.85.0/Build/Cesium/Widgets/widgets.css"
rel="stylesheet"
/>
<!-- <script src="https://cdn.jsdelivr.net/npm/cesium@1.85.0/Build/Cesium/Cesium.js"></script> -->
<script src="./Build168/Cesium/Cesium.js"></script>
<!-- 添加天地图的cesium的扩展插件目前支持cesuim1.52、1.58、1.63.1。 -->
<script src="http://api.tianditu.gov.cn/cdn/plugins/cesium/cesiumTdt.js"></script>
<style>
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
#infobox {
position: absolute;
top: 20px;
left: 30px;
font-size: 14px;
z-index: 99;
padding: 10px 20px;
background-color: white;
border: 1px solid #cccccc;
}
.toolbox {
position: absolute;
top: 49%;
left: 30px;
z-index: 99;
display: flex;
flex-direction: column;
justify-content: space-around;
}
.tool-item {
background-color: #303336;
cursor: pointer;
}
.playbox {
position: absolute;
top: 30px;
left: 49%;
z-index: 99;
display: flex;
justify-content: space-around;
}
</style>
</head>
<body>
<div class="toolbox">
<button id="zoomIn" class="tool-item">
<img class="tool-image" src="../SampleData/zoomIn.png" alt="" />
</button>
<button id="zoomOut" class="tool-item">
<img class="tool-image" src="../SampleData/zoomOut.png" alt="" />
</button>
</div>
<div id="infobox"></div>
<div class="playbox">
<button id="start">播放</button>
<button id="quit">停止</button>
</div>
<div id="cesiumContainer"></div>
</body>
<script>
Cesium.Ion.defaultAccessToken =
"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI5ZjRjNTZkNC01NDYxLTRhMjQtOGEwZC1kZjA3YzQ5YTJlZDkiLCJpZCI6MjYwODQsInNjb3BlcyI6WyJhc3IiLCJnYyJdLCJpYXQiOjE1ODcxOTMwODN9.prGsSKyAW_9Ow5zHYPhbm3LsQL-ApQw5-5PNJkDaHi8";
var token = "bf156eb3c72350d62b008dc8a4ae1016";
// 服务域名
var tdtUrl = "https://t{s}.tianditu.gov.cn/";
// 服务负载子域,天地图地图服务二级域名包括t0-t7可以随机选择使用如http://t2.tianditu.gov.cn/vec_c/wmts?tk=您的密钥
var subdomains = ["0", "1", "2", "3", "4", "5", "6", "7"];
var viewer = new Cesium.Viewer("cesiumContainer", {
shouldAnimate: true,
timeline: true,
animation: false,
});
// 叠加影像服务
var imgMap = new Cesium.UrlTemplateImageryProvider({
url: tdtUrl + "DataServer?T=img_w&x={x}&y={y}&l={z}&tk=" + token,
subdomains: subdomains,
tilingScheme: new Cesium.WebMercatorTilingScheme(),
maximumLevel: 18,
});
viewer.imageryLayers.addImageryProvider(imgMap);
viewer._cesiumWidget._creditContainer.style.display = "none"; // 隐藏版权
viewer.scene.globe.show = true;
viewer.scene.debugShowFramesPerSecond = true;
// var tilesets = new Cesium.Cesium3DTileset({
// url: './SampleData/Cesium3DTiles/Tilesets/Tileset/tileset.json',
// skipLevelOfDetail: true,
// maximumMemoryUsage: 1500,
// maximumScreenSpaceError: 16,
// // cullRequestsWhileMovingMultiplier: 100,
// dynamicScreenSpaceError: false,
// preferLeaves: true,
// debugShowContentBoundingVolume: false,
// debugShowViewerRequestVolume: false,
// debugShowBoundingVolume: false,
// });
// tilesets.readyPromise
// .then(function (tileset) {
// viewer.scene.primitives.add(tileset);
// viewer.flyTo(tileset);
// })
// .otherwise(function (error) {
// console.log(error);
// });
var myPositions = [
[109.05832893717263, 37.441496598851096],
[109.05855416786699, 37.44130123438769],
[109.05870506545179, 37.44117238850958],
[109.05846290755761, 37.441001906200626],
[109.05874862898264, 37.440730473795476],
[109.0591362027828, 37.4403901883947],
[109.05955264270231, 37.4400282830198],
[109.05976466627452, 37.43986533373868],
[109.06019447304337, 37.43953151809137],
[109.06050060518912, 37.439282109667204],
[109.06073920090172, 37.43909640541291],
[109.06102095626935, 37.43887990938909],
[109.06126114614219, 37.43905268010351],
[109.0615923854886, 37.43932891714282],
[109.06114978051788, 37.43970657237644],
[109.06078572833964, 37.44000168113979],
[109.06027780474928, 37.44042583498669],
[109.0598968978716, 37.440729305287476],
[109.05936770987917, 37.441168572826626],
[109.05904603542216, 37.44142781800953],
[109.0587449465546, 37.44119249116668],
[109.05845600554856, 37.441396645980845],
];
// var point = viewer.entities.add({
// position: Cesium.Cartesian3.fromDegrees(
// 109.05845600554856,
// 37.441396645980845,
// 100
// ),
// point: {
// show: false,
// },
// });
viewer.camera.flyTo({
destination: Cesium.Cartesian3.fromDegrees(
109.05845600554856,
37.441396645980845,
400.0
),
});
console.log(viewer.animation);
function trackView() {
//Set bounds of our simulation time
var start = Cesium.JulianDate.fromDate(new Date(2015, 2, 25, 16));
var stop = Cesium.JulianDate.addSeconds(
start,
myPositions.length - 1,
new Cesium.JulianDate()
);
//Make sure viewer is at the desired time.
viewer.clock.startTime = start.clone();
viewer.clock.stopTime = stop.clone();
viewer.clock.currentTime = start.clone();
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; //Loop at the end
viewer.clock.multiplier = 0.3;
//Set timeline to simulation bounds
viewer.timeline.zoomTo(start, stop);
//Generate a random circular pattern with varying heights.
function computeCirclularFlight() {
var property = new Cesium.SampledPositionProperty();
//设置插入选项
property.setInterpolationOptions({
// interpolationDegree: 1,
// interpolationAlgorithm: Cesium.LinearApproximation,
// interpolationDegree: 5,
// interpolationAlgorithm:
// Cesium.LagrangePolynomialApproximation,
interpolationDegree: 2,
interpolationAlgorithm: Cesium.HermitePolynomialApproximation,
});
for (var i = 0; i < myPositions.length; i++) {
var time = Cesium.JulianDate.addSeconds(
start,
i,
new Cesium.JulianDate()
);
var position = Cesium.Cartesian3.fromDegrees(
myPositions[i][0],
myPositions[i][1],
5
);
property.addSample(time, position);
}
return property;
}
var position = computeCirclularFlight();
//Actually create the entity
var entity = viewer.entities.add({
//Set the entity availability to the same interval as the simulation time.
availability: new Cesium.TimeIntervalCollection([
new Cesium.TimeInterval({
start: start,
stop: stop,
}),
]),
//Use our computed positions
position: position,
//Automatically compute orientation based on position movement.
orientation: new Cesium.VelocityOrientationProperty(position),
model: {
uri: "../SampleData/models/CesiumAir/Cesium_Air.glb",
minimumPixelSize: 64,
},
//Show the path as a pink line sampled in 1 second increments.
path: {
resolution: 1,
material: new Cesium.PolylineGlowMaterialProperty({
glowPower: 0.1,
color: Cesium.Color.GREEN,
}),
width: 16,
},
});
viewer.trackedEntity = entity;
}
//视角变换
var matrix3Scratch = new Cesium.Matrix3();
function getModelMatrix(entity, time, result) {
var position = Cesium.Property.getValueOrUndefined(
entity.position,
time,
new Cesium.Cartesian3()
);
if (!Cesium.defined(position)) {
return undefined;
}
var orientation = Cesium.Property.getValueOrUndefined(
entity.orientation,
time,
new Cesium.Quaternion()
);
if (!Cesium.defined(orientation)) {
result = Cesium.Transforms.eastNorthUpToFixedFrame(
position,
undefined,
result
);
} else {
result = Cesium.Matrix4.fromRotationTranslation(
Cesium.Matrix3.fromQuaternion(orientation, matrix3Scratch),
position,
result
);
}
return result;
}
var scratch = new Cesium.Matrix4();
var renderListener = function (e) {
//viewer.camera.positionCartographic.height = 2000 + $this.limitCamera(f_property);
if (viewer.trackedEntity) {
getModelMatrix(viewer.trackedEntity, viewer.clock.currentTime, scratch);
var transformX = 90; //距离运动点的距离(后方)
var transformZ = 55; //距离运动点的高度(上方)
var transformY = 0; //距离运动点的高度(侧方)
viewer.scene.camera.lookAtTransform(
scratch,
new Cesium.Cartesian3(-transformX, transformY, transformZ)
);
}
};
viewer.scene.preRender.addEventListener(renderListener);
document.getElementById("start").onclick = function () {
viewer.clock.shouldAnimate = true;
trackView();
};
document.getElementById("quit").onclick = function () {
viewer.trackedEntity = undefined;
viewer.clock.shouldAnimate = false;
};
// 放大缩小
document.getElementById("zoomIn").onclick = function () {
// 获取当前镜头位置的笛卡尔坐标
let cameraPos = viewer.camera.position;
// 获取当前坐标系标准
let ellipsoid = viewer.scene.globe.ellipsoid;
// 根据坐标系标准,将笛卡尔坐标转换为地理坐标
let cartographic = ellipsoid.cartesianToCartographic(cameraPos);
// 获取镜头的高度
let height = cartographic.height;
// if (height < 40) {
// return
// }
// 镜头拉近
viewer.camera.zoomIn(height / 3);
};
document.getElementById("zoomOut").onclick = function () {
// 获取当前镜头位置的笛卡尔坐标
let cameraPos = viewer.camera.position;
// 获取当前坐标系标准
let ellipsoid = viewer.scene.globe.ellipsoid;
// 根据坐标系标准,将笛卡尔坐标转换为地理坐标
let cartographic = ellipsoid.cartesianToCartographic(cameraPos);
// 获取镜头的高度
let height = cartographic.height;
// if (height < 40) {
// return
// }
// 镜头拉近
viewer.camera.zoomOut(height * 1.2);
};
//经纬度显示
viewer.screenSpaceEventHandler.setInputAction(function (event) {
var earthPosition = viewer.camera.pickEllipsoid(
event.position,
viewer.scene.globe.ellipsoid
);
var cartographic = Cesium.Cartographic.fromCartesian(
earthPosition,
viewer.scene.globe.ellipsoid,
new Cesium.Cartographic()
);
var lat = Cesium.Math.toDegrees(cartographic.latitude);
var lng = Cesium.Math.toDegrees(cartographic.longitude);
var height = viewer.camera.positionCartographic.height;
document.getElementById("infobox").innerHTML =
"<span>经度:" +
lng.toFixed(3) +
"</span>" +
"<span> 纬度:" +
lat.toFixed(3) +
"</span>" +
"<span> 相机高度:" +
height +
"</span>";
console.log(lat, lng, height);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
</script>
</html>