Cesium中匀速飞行的实现,漫游(weixin公众号【图说GIS】)

前言

飞行的主要实现思路是通过轨迹点计算空中飞行距离,然后计算每段匀速飞行的时间,当然你也可以变速。本文就是匀速飞行的实现,希望能对你有所帮助。

数据制作可参考《使用QGIS制作航线数据,用Cesium加载查看》
代码实现参考文章

代码实现

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <link href="../../Cesium/Widgets/widgets.css" rel="stylesheet">
    <script type="text/javascript" src="../../Cesium/Cesium.js"></script>
    <title>飞行</title>
</head>

<body style="margin: 0px;width:100%;height:100%;">
    <div id="cesiumContainer" style="width:100%;height:100%;position:absolute;"></div>
    <div style="top:10px;left:10px;position:absolute;">
        <div style="background: #fff;padding:10px;" id="play">飞行</div>
        <div style="background: #fff;padding:10px;" id="pause">暂停</div>
        <div style="background: #fff;padding:10px;" id="time">设置当前时间</div>
    </div>
</body>
<script>
    //created by onegiser at 2021-10-30
    const key='天地图key'
    const viewer = new Cesium.Viewer('cesiumContainer', {
        imageryProviderViewModels: [
            new Cesium.ProviderViewModel({
                name: "天地图影像",
                iconUrl: "/imgs/map/tdt_img.jpg",
                tooltip: "",
                creationFunction: () => {
                    const imgImageryProvider = new Cesium.WebMapTileServiceImageryProvider({
                        url: "http://t{s}.tianditu.com/img_c/wmts?service=wmts&request=GetTile&version=1.0.0&LAYER=img&tileMatrixSet=c&TileMatrix={TileMatrix}&TileRow={TileRow}&TileCol={TileCol}&style=default&format=tiles&tk=" + key,
                        subdomains: ['0', '1', '2', '3', '4', '5', '6', '7'],
                        tilingScheme: new Cesium.GeographicTilingScheme(),
                        tileMatrixLabels: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19"]
                    })
                    return [imgImageryProvider]
                }
            }),
        ]
    })


    let inter, entity, start, stop

    //飞行数据
    const flyDatas = {
        "properties": {
            "id": "fad07e10-1854-11ec-90a2-97310cdff148"
        },
        "geometry": {
            "type": "LineString",
            "coordinates": [
                [
                    84.26606989058006,
                    28.893720619299657,
                    6518.704454870537
                ],
                [
                    84.5499583941043,
                    28.75363498215204,
                    6036.864577931667
                ],
                [
                    84.92774603698726,
                    28.572093371042484,
                    4776.540165893245
                ],
                [
                    85.57643103471693,
                    28.310271180323234,
                    5333.176522423159
                ]
            ]
        }
    }

    const createPosition = (datas, time, height) => {
        let totalDistance = 0//总的距离
        const distances = []
        const positions = []
        const times = []
        const property = new Cesium.SampledPositionProperty()
        if (datas) {
            for (let i in datas.geometry.coordinates) {
                const coordinates = datas.geometry.coordinates[i]
                const position = Cesium.Cartesian3.fromDegrees(coordinates[0], coordinates[1], height ? height : coordinates[2])
                positions.push(position)
                if (Number(i) === 0) {

                } else {
                    const lastPosition = positions[Number(i) - 1]
                    const geoPositions = [Cesium.Ellipsoid.WGS84.cartesianToCartographic(lastPosition), Cesium.Ellipsoid.WGS84.cartesianToCartographic(position)]
                    const ellipsoidGeodesic = new Cesium.EllipsoidGeodesic(geoPositions[0], geoPositions[1])
                    const distance = ellipsoidGeodesic.surfaceDistance//表面距离
                    distances.push(distance)
                    totalDistance += distance
                }
            }
            const speed = totalDistance / time
            let start, stop
            for (let i in positions) {
                const position = positions[i]
                if (Number(i) === 0) {
                    start = Cesium.JulianDate.now()
                    // stop = Cesium.JulianDate.addSeconds(start, time, new Cesium.JulianDate())
                    property.addSample(start, position)
                    times.push(start.clone())
                } else {
                    const _time = distances[Number(i) - 1] / speed//根据速度计算本线段的时间
                    const tempTime = Cesium.JulianDate.addSeconds(times[Number(i) - 1], _time, new Cesium.JulianDate())
                    times.push(tempTime)
                    property.addSample(tempTime, position)
                }
            }
        }
        return { property, times, totalDistance }
    }

    const viewFly = (viewer, datas) => {
        const id = "router-fly-line"
        const time = 60
        const { property, times, totalDistance } = createPosition(datas, time)
        if (times && times.length > 1) {
            start = times[0]
            stop = times[times.length - 1]
            const availability = new Cesium.TimeIntervalCollection([new Cesium.TimeInterval({
                start,
                stop
            })])
            const entityOption = {
                id,
                name: id,
                availability,
                position: property,
                orientation: new Cesium.VelocityOrientationProperty(property),
            }
            const model = {
                show: true,
                uri: "/imgs/models/feiji.glb",
                scale: 1,
                minimumPixelSize: 100,
                heightReference: Cesium.HeightReference.NONE,
            }
            entityOption.model = model

            entity = viewer.entities.add(entityOption)

            viewer.clock.startTime = start.clone()
            viewer.clock.currentTime = start.clone()
            viewer.clock.stopTime = stop.clone()
            viewer.clock.clockRange = Cesium.ClockRange.CLAMPED
            viewer.clock.shouldAnimate = false
        }
    }

    function setClockCurrentTime(time) {
        viewer.clock.currentTime = Cesium.JulianDate.addSeconds(start, time, new Cesium.JulianDate())
    }

    viewFly(viewer, flyDatas)

    let t = 0
    function interFun() {
        inter = setInterval(() => {
            t++
            console.log(t)
            if (t === 1) {
                console.log(viewer.camera)
            }
            if (t === 30) {
                console.log(viewer.camera)
            }
        }, 1000)
    }


    function setViewer() {
        viewer.scene.camera.setView({
            destination: Cesium.Cartesian3.fromDegrees(84.26606989058006,
                28.893720619299657,
                20000), // 点的坐标
            orientation: {
                heading: 6.273949775088365,
                pitch: -0.7857772222180337,
                roll: 6.283148089310608,
            }
        })
    }
    document.getElementById("play").onclick = () => {
        viewer.trackedEntity = entity
        setTimeout(()=>{
             setViewer()
        },5000)
       
        viewer.clock.shouldAnimate = true
        interFun()
    }

    document.getElementById("pause").onclick = () => {
        viewer.clock.shouldAnimate = false
        if (inter) {
            clearInterval(inter)
        }
    }


    document.getElementById("time").onclick = () => {
        setClockCurrentTime(30)
    }
</script>

</html>
  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
实现Cesium的三维漫游飞行效果可以通过以下步骤实现: 1. 创建一个Cesium Viewer对象: ``` var viewer = new Cesium.Viewer('cesiumContainer'); ``` 2. 通过Camera控制视角和位置: ``` viewer.camera.setView({ destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height), orientation: { heading: Cesium.Math.toRadians(heading), pitch: Cesium.Math.toRadians(pitch), roll: Cesium.Math.toRadians(roll) } }); ``` 3. 为视角添加动画效果: ``` var duration = 5.0; // 动画时间,单位为秒 Cesium.CameraFlightPath.createAnimationCartographic(viewer.scene, { destination: Cesium.Cartographic.fromDegrees(longitude, latitude, height), orientation: { heading: Cesium.Math.toRadians(heading), pitch: Cesium.Math.toRadians(pitch), roll: Cesium.Math.toRadians(roll) }, duration: duration }); ``` 4. 添加键盘和鼠标事件: ``` // 飞行到指定位置 function flyTo(longitude, latitude, height, heading, pitch, roll) { viewer.camera.flyTo({ destination: Cesium.Cartesian3.fromDegrees(longitude, latitude, height), orientation: { heading: Cesium.Math.toRadians(heading), pitch: Cesium.Math.toRadians(pitch), roll: Cesium.Math.toRadians(roll) } }); } // 监听键盘和鼠标事件 document.addEventListener('keydown', function(event) { switch (event.keyCode) { case 87: // W viewer.camera.moveForward(1000.0); break; case 83: // S viewer.camera.moveBackward(1000.0); break; case 65: // A viewer.camera.moveLeft(1000.0); break; case 68: // D viewer.camera.moveRight(1000.0); break; case 38: // Up arrow viewer.camera.lookUp(0.1); break; case 40: // Down arrow viewer.camera.lookDown(0.1); break; case 37: // Left arrow viewer.camera.lookLeft(0.1); break; case 39: // Right arrow viewer.camera.lookRight(0.1); break; default: return; } event.preventDefault(); }, false); ``` 通过以上步骤,即可实现Cesium的三维漫游飞行效果。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值