You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
cesium/path-reply.html

349 lines
15 KiB
HTML

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!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>
<script type="text/javascript" cesium="true" src="https://api.tianditu.gov.cn/cdn/demo/sanwei/static/cesium/Cesium.js"></script>
<script type="text/javascript" cesium="true" src="https://api.tianditu.gov.cn/cdn/plugins/cesium/Cesium_ext_min.js"></script>
<link rel="stylesheet" cesium="true" href="https://api.tianditu.gov.cn/cdn/demo/sanwei/static/cesium/Widgets/widgets.css">
<link href="https://services.arcgisonline.com/arcgis/rest/static/jsapi-template-main.css" rel="stylesheet" type="text/css">
<link href="https://js.arcgis.com/4.14/esri/css/main.css" rel="stylesheet" type="text/css">
<script type="text/javascript" src="https://js.arcgis.com/4.14/dojo/dojo.js"></script>
<script type="text/javascript" src="/Public/js/datasource.js"></script>
<script src="/Public/js/jquery-1.10.2.min.js"></script>
<style>
html,
body,
#cesiumContainer {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
overflow: hidden;
}
</style>
</head>
<body>
<div id="cesiumContainer"></div>
<script>
// var viewer = new Cesium.Viewer("cesiumContainer");
// viewer.baseLayerPicker.viewModel.selectedImagery = viewer.baseLayerPicker.viewModel.imageryProviderViewModels[12];
var token = "72e2e7be836401af7e79c232285a552e";
var tdtUrl = 'http://t{s}.tianditu.gov.cn/';
var subdomains = ['0', '1', '2', '3', '4', '5', '6', '7'];
Cesium.Ion.defaultAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI3NzI3MDQwMS05M2MxLTQ1MDAtOWYxOS0wZDg0MmI5Zjc2NTUiLCJpZCI6MjMxNzM1LCJpYXQiOjE3MjIzODk2ODB9.zy6rmwWtDzF2890HZR6XGlDxxMImZ8v_Erfnz3gyti4';
// cesium 初始化
var viewer = new Cesium.Viewer('cesiumContainer', {
shouldAnimate: true, //是否允许动画
selectionIndicator: false,
baseLayerPicker: true,
fullscreenButton: false,
geocoder: false,
homeButton: false,
infoBox: false,
sceneModePicker: false,
timeline: true,
navigationHelpButton: false,
navigationInstructionsInitiallyVisible: false,
showRenderLoopErrors: false,
shadows: false,
});
viewer.baseLayerPicker.viewModel.selectedImagery = viewer.baseLayerPicker.viewModel.imageryProviderViewModels[12];
viewer.baseLayerPicker.container.style.display = "none";
let positionDisplay = addComponent('div', 'absolute', '10px', '10px', '5px', 'white', 1000);
let buttonNorth = addComponent('button', 'absolute', '50px', '10px', '5px', 'white', 1000, '朝北视角');
let buttonEast = addComponent('button', 'absolute', '50px', '80px', '5px', 'white', 1000, '朝东视角');
let buttonSouth = addComponent('button', 'absolute', '50px', '150px', '5px', 'white', 1000, '朝南视角');
let buttonWest = addComponent('button', 'absolute', '50px', '220px', '5px', 'white', 1000, '朝西视角');
let buttonCenter = addComponent('button', 'absolute', '50px', '290px', '5px', 'white', 1000, '座舱视角');
buttonNorth.addEventListener('click', function () {
switchCameraView(0);
})
buttonEast.addEventListener('click', function () {
switchCameraView(90);
})
buttonSouth.addEventListener('click', function () {
switchCameraView(180);
})
buttonWest.addEventListener('click', function () {
switchCameraView(270);
})
let postUpdateEventListener = null;
buttonCenter.addEventListener('click', function () {
viewer.trackedEntity.model.uri = plan;
viewer.trackedEntity.model.scale=2;
let prePoint = null;
viewer.scene.postUpdate.addEventListener(
postUpdateEventListener = () => {
let curPoint = viewer.trackedEntity.position.getValue(viewer.clock.currentTime);
if (prePoint) {
// 计算heading-代表 Z 轴旋转
let heading = getHeading(prePoint, curPoint);
//let heading = - Cesium.Math.PI_OVER_TWO;
// 计算pitch-代表 Y 轴朝向
//let pitch = Cesium.Math.toRadians(-150);
let pitch = Cesium.Math.toRadians(-15);
let range = 20
viewer.scene.camera.lookAt(curPoint, new Cesium.HeadingPitchRange(heading, pitch, range));
}
// 当前点在下一次渲染时为前一个点
prePoint = Cesium.Cartesian3.clone(curPoint)
});
})
//viewer.animation.container.style.display = "none";
// 抗锯齿
viewer.scene.fxaa = true;
viewer.scene.postProcessStages.fxaa.enabled = false;
// 水雾特效
viewer.scene.globe.showGroundAtmosphere = true;
// 设置最大俯仰角,[-90,0]区间内,默认为-30单位弧度
// viewer.scene.screenSpaceCameraController.constrainedPitch = Cesium.Math.toRadians(-20);
// viewer.scene.screenSpaceCameraController.autoResetHeadingPitch = false;
// viewer.scene.screenSpaceCameraController.inertiaZoom = 0.5;
// viewer.scene.screenSpaceCameraController.minimumZoomDistance = 50;
// viewer.scene.screenSpaceCameraController.maximumZoomDistance = 20000000;
// viewer.scene.screenSpaceCameraController.zoomEventTypes = [
// Cesium.CameraEventType.RIGHT_DRAG,
// Cesium.CameraEventType.WHEEL,
// Cesium.CameraEventType.PINCH,
// ];
// viewer.scene.screenSpaceCameraController.tiltEventTypes = [
// Cesium.CameraEventType.MIDDLE_DRAG,
// Cesium.CameraEventType.PINCH,
// {
// eventType: Cesium.CameraEventType.LEFT_DRAG,
// modifier: Cesium.KeyboardEventModifier.CTRL,
// },
// {
// eventType: Cesium.CameraEventType.RIGHT_DRAG,
// modifier: Cesium.KeyboardEventModifier.CTRL,
// },
// ];
// 取消默认的双击事件
viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
var esriImg = new Cesium.ArcGisMapServerImageryProvider({
url: 'https://services.arcgisonline.com/arcgis/rest/services/World_Imagery/MapServer',
});
viewer.imageryLayers.addImageryProvider(esriImg);
// 叠加影像服务
// var imgMap = new Cesium.UrlTemplateImageryProvider({
// url: tdtUrl + 'img_w/wmts?SERVICE=WMTS&REQUEST=GetTile&VERSION=1.0.0&LAYER=img&STYLE=default&TILEMATRIXSET=w&FORMAT=tiles&TILEMATRIX={z}&TILEROW={y}&TILECOL={x}&tk=' + token,
// subdomains: subdomains,
// tilingScheme : new Cesium.WebMercatorTilingScheme(),
// maximumLevel : 18
// });
// viewer.imageryLayers.addImageryProvider(imgMap);
//将三维球定位到中国
// viewer.camera.flyTo({
// destination: Cesium.Cartesian3.fromDegrees(116.40375810947471, 39.908597112062225, 17850000),
// orientation: {
// heading: Cesium.Math.toRadians(348.4202942851978),
// pitch: Cesium.Math.toRadians(-89.74026687972041),
// roll: Cesium.Math.toRadians(0)
// },
// complete: function callback() {
// // 定位完成之后的回调函数
// }
// });
let date = new Date('2024-08-06 13:22:04');
const start = Cesium.JulianDate.fromDate(date);
const end = 7000;
var plan = "../Public/Cesium_Air.glb"
const czml = [
{
id: "document",
version: "1.0",
clock: {
interval: `${Cesium.JulianDate.toIso8601(start, 0)}/${Cesium.JulianDate.toIso8601(Cesium.JulianDate.addSeconds(start, end, new Cesium.JulianDate()), 0)}`,
currentTime: `${Cesium.JulianDate.toIso8601(start, 0)}`,
multiplier: 6,
}
},
{
id: "plane",
availability: `${Cesium.JulianDate.toIso8601(start, 0)}/${Cesium.JulianDate.toIso8601(Cesium.JulianDate.addSeconds(start, end, new Cesium.JulianDate()), 0)}`,
model: {
gltf: plan,
scale: 2.0,
minimumPixelSize: 48,
maximumScale: 2000,
},
// viewFrom: {
// cartesian: [-2080, -1715, 779]
// },
orientation: {velocityReference: "#position"},
path: {
material: {
solidColor: {
color: {
interval: `${Cesium.JulianDate.toIso8601(start, 0)}/${Cesium.JulianDate.toIso8601(Cesium.JulianDate.addSeconds(start, end, new Cesium.JulianDate()), 0)}`,
rgba: [0, 205, 255, 255]
}
}
},
width: [
{
interval: `${Cesium.JulianDate.toIso8601(start, 0)}/${Cesium.JulianDate.toIso8601(Cesium.JulianDate.addSeconds(start, end, new Cesium.JulianDate()), 0)}`,
number: 3
}
],
show: [
{
interval: `${Cesium.JulianDate.toIso8601(start, 0)}/${Cesium.JulianDate.toIso8601(Cesium.JulianDate.addSeconds(start, end, new Cesium.JulianDate()), 0)}`,
boolean: true
}
]
},
position: {
interpolationAlgorithm: "LAGRANGE",
interpolationDegree: 5,
epoch: `${Cesium.JulianDate.toIso8601(start, 0)}`,
cartographicDegrees:ds
}
}
];
let dataSource = viewer.dataSources.add(Cesium.CzmlDataSource.load(czml));
viewer.zoomTo(dataSource);
dataSource.then(part => {
// 根据id获取czml中的模型
let e = part.entities.getById("plane");
// 相机跟随模型
viewer.trackedEntity = e;
//++++++++++++++// 视角跟随模型
let prePoint = null;
// 前一个点
viewer.scene.postRender.addEventListener(() => {
if (e && viewer.clock.shouldAnimate) {
// 获取当前时间的位置
let curPoint = e.position.getValue(viewer.clock.currentTime);
if (prePoint) {
// 计算heading-代表 Z 轴旋转
let heading = getHeading(prePoint, curPoint);
//let heading = - Cesium.Math.PI_OVER_TWO;
// 计算pitch-代表 Y 轴朝向
//let pitch = Cesium.Math.toRadians(-150);
let pitch = Cesium.Math.toRadians(-10);
let range = 10;
//viewer.camera.lookAt(curPoint, new Cesium.HeadingPitchRange(heading, pitch, range));
let cartographicPosition = Cesium.Cartographic.fromCartesian(curPoint);
let longitude = Cesium.Math.toDegrees(cartographicPosition.longitude);
let latitude = Cesium.Math.toDegrees(cartographicPosition.latitude);
let headingDegrees = Cesium.Math.toDegrees(heading);
let height = cartographicPosition.height;
positionDisplay.textContent =
//"Longitude: " + longitude + "\u00B0" + "\n" +
//"Latitude: " + latitude + "\u00B0" + "\n" +
"Height: " + height.toFixed(2) + "M" + "\n" +
"航向:" + headingDegrees.toFixed(2) + "\u00B0";
}
// 当前点在下一次渲染时为前一个点
prePoint = Cesium.Cartesian3.clone(curPoint)
}
})
});
function getHeading(pointA, pointB) {
//建立以点A为原点X轴为east,Y轴为north,Z轴朝上的坐标系
const transform = Cesium.Transforms.eastNorthUpToFixedFrame(pointA);
//向量AB
const positionvector = Cesium.Cartesian3.subtract(pointB, pointA, new Cesium.Cartesian3());
//因transform是将A为原点的eastNorthUp坐标系中的点转换到世界坐标系的矩阵
//AB为世界坐标中的向量
//因此将AB向量转换为A原点坐标系中的向量需乘以transform的逆矩阵。
const vector = Cesium.Matrix4.multiplyByPointAsVector(Cesium.Matrix4.inverse(transform, new Cesium.Matrix4()), positionvector, new Cesium.Cartesian3());
//归一化
const direction = Cesium.Cartesian3.normalize(vector, new Cesium.Cartesian3());
//heading
const heading = Math.atan2(direction.y, direction.x) - Cesium.Math.PI_OVER_TWO;
//console.log(direction.y, direction.x,Math.atan2(direction.y, direction.x),heading,Cesium.Math.TWO_PI - Cesium.Math.zeroToTwoPi(heading));
//return Cesium.Math.TWO_PI - Cesium.Math.zeroToTwoPi(heading) - Cesium.Math.PI_OVER_TWO;
return Cesium.Math.TWO_PI - Cesium.Math.zeroToTwoPi(heading);
}
function updatePosition() {
var camera = viewer.scene.camera;
var ellipsoid = viewer.scene.globe.ellipsoid;
var cartesian = camera.position;
var height = ellipsoid.cartesianToCartographic(cartesian).height;
var text = "Latitude: " + camera.positionCartographic.latitude.toDegrees() + "\u00B0" + "\n" +
"Longitude: " + camera.positionCartographic.longitude.toDegrees() + "\u00B0" + "\n" +
"Height: " + height + "m";
positionDisplay.textContent = text;
}
function addComponent(name, position, top, left, padding, backgroundColor, zindex, text = '') {
let component = document.createElement(name);
component.style.position = position;
if (text !== undefined || text !== '') {
component.innerHTML = text;
}
component.style.top = top;
component.style.left = left;
component.style.zIndex = zindex;
component.style.backgroundColor = backgroundColor;
component.style.padding = padding;
document.body.appendChild(component);
return component;
}
function switchCameraView(heading)
{
viewer.scene.postUpdate.removeEventListener(postUpdateEventListener);
viewer.trackedEntity.model.uri = plan;
viewer.trackedEntity.model.scale=3;
heading = Cesium.Math.toRadians(heading);
// 计算pitch-代表 Y 轴朝向
//let pitch = Cesium.Math.toRadians(-150);
let pitch = Cesium.Math.toRadians(-10);
let range = 200;
let point = viewer.scene.camera.position
viewer.scene.camera.lookAt(point, new Cesium.HeadingPitchRange(heading, pitch, range));
}
</script>
</body>
</html>