learning_cesium/全景漫游.html

376 lines
12 KiB
HTML
Raw Normal View History

2024-03-19 18:06:25 +08:00
<!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>