Cesium 实战 - OD 通信线 - 移动连接线

2023-12-20 15:00:11

Cesium 实战 - OD 通信线 - 移动连接线

在项目中,实现完卫星通信线之后,又有一个新需求,需要通信线根据火箭移动而移动,相当于追踪效果,思考之后通过 Entity CallbackProperty 实现。

实际上是通过自定义材质类,通过着色器代码实现

本文包含移动连接线核心代码、完整代码以及在线示例三部分。


OD 通信线 - 移动连接线核心代码


// 获取火箭模型实体
const entity = dataSource.entities.getById("Vulcan");

// 模型视角跟随
viewer.trackedEntity = entity;

// 设置观察角度
entity.viewFrom = new Cesium.Cartesian3(-1000, 100,-1000);

// 添加通信线
viewer.entities.add({
    polyline: {
        // 回调更新连接线.
        positions: new Cesium.CallbackProperty(function (time, result) {
            const position1 = entity.position.getValue(time);
            return [position,position1];
        }, false),
        width: 5,
        material: new SatelliteMaterialProperty({
            color: new Cesium.Color(1.0, 0.0, 1.0, 0.1),
            speed: 50,
            count: 10,
            gradient: 0.2
        }),
    },
});


完整代码



<!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>Cesium dynamic line</title>
    <script src="http://openlayers.vip/examples/csdn/Cesium.js"></script>
    <script src="./cesium_init.js"></script>
    <script src="http://www.openlayers.vip/examples/resources/jquery-3.5.1.min.js"></script>
    <style>
        @import url(./Widgets/widgets.css);

        html,
        body,
        #cesiumContainer {
            width: 100%;
            height: 100%;
            margin: 0;
            padding: 0;
            overflow: hidden;
        }
    </style>

    <script>
        var _hmt = _hmt || [];
        (function () {
            var hm = document.createElement("script");
            hm.src = "https://hm.baidu.com/hm.js?f80a36f14f8a73bb0f82e0fdbcee3058";
            var s = document.getElementsByTagName("script")[0];
            s.parentNode.insertBefore(hm, s);
        })();
    </script>
</head>
<body>
<div id="cesiumContainer"></div>
<script>

    // 创建三维球
    const viewer = init();

    // 火箭模拟发射数据
    const czml = [
        {
            "id": "document",
            "name": "SpaceX",
            "version": "1.0",
            "clock": {
                "interval": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z",
                "currentTime": "2023-06-14T10:00:00Z",
                "multiplier": 10,
                "range": "CLAMPED",
                "step": "SYSTEM_CLOCK_MULTIPLIER"
            }
        },
        {
            "id": "Vulcan",
            "availability": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z",
            "name": "Vulcan",
            "billboard": {
                "show": true,
                "image": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAgAAAAICAYAAADED76LAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAAEnQAABJ0Ad5mH3gAAAAjSURBVChTYyAa/EcDUGEIgIphAKg0XRSAAFQMDqDChAADAwDC13+BJ+0oDwAAAABJRU5ErkJgggAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==",
                "scale": 1,
                "pixelOffset": {
                    "cartesian2": [
                        0, 0
                    ]
                },
                "eyeOffset": {
                    "cartesian": [
                        0, 0, 0
                    ]
                },
                "horizontalOrigin": "CENTER",
                "verticalOrigin": "CENTER",
                "color": [
                    {
                        "interval": "2023-06-14T10:00:00Z/2023-06-14T10:10:00Z",
                        "rgba": [
                            0, 255, 0, 255
                        ]
                    },
                    {
                        "interval": "2023-06-14T10:10:00Z/2023-06-14T10:13:20Z",
                        "rgba": [
                            255, 255, 0, 255
                        ]
                    },
                    {
                        "interval": "2023-06-14T10:13:20Z/9999-12-31T23:59:59.9999999Z",
                        "rgba": [
                            255, 0, 255, 255
                        ]
                    }
                ]
            },
            "label": {
                "show": false,
                "text": "Vulcan",
                "font": "21pt Lucida Console",
                "style": "FILL_AND_OUTLINE",
                "scale": 0.5,
                "pixelOffset": {
                    "cartesian2": [
                        5, -4
                    ]
                },
                "horizontalOrigin": "LEFT",
                "verticalOrigin": "CENTER",
                "fillColor": [
                    {
                        "interval": "2023-06-14T10:00:00Z/2023-06-14T10:10:00Z",
                        "rgba": [
                            0, 255, 0, 255
                        ]
                    },
                    {
                        "interval": "2023-06-14T10:10:00Z/2023-06-14T10:13:20Z",
                        "rgba": [
                            255, 255, 0, 255
                        ]
                    },
                    {
                        "interval": "2023-06-14T10:13:20Z/9999-12-31T23:59:59.9999999Z",
                        "rgba": [
                            255, 0, 255, 255
                        ]
                    }
                ],
                "outlineColor": {
                    "rgba": [
                        0, 0, 0, 255
                    ]
                },
                "outlineWidth": 2
            },
            "path": {
                "show": [
                    {
                        "interval": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z",
                        "boolean": true
                    }
                ],
                "width": 5,
                "resolution": 1,
                "leadTime": [
                    {
                        "interval": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z",
                        "epoch": "2023-06-14T10:00:00Z",
                        "number": [
                            0, 1053,
                            1053, 0
                        ]
                    }
                ],
                "trailTime": [
                    {
                        "interval": "2023-06-14T10:00:00Z/2023-06-14T10:17:33Z",
                        "epoch": "2023-06-14T10:00:00Z",
                        "number": [
                            0, 0,
                            1053, 1053
                        ]
                    }
                ],
                "material": {
                    polylineGlow: {
                        color: [{
                            "interval": "2023-06-14T10:00:00Z/2023-06-14T10:10:00Z",
                            rgba: [255, 0, 0, 255],
                        },
                            {
                                "interval": "2023-06-14T10:10:00Z/2023-06-14T10:13:20Z",
                                rgba: [0, 0, 255, 255],
                            },
                            {
                                "interval": "2023-06-14T10:13:20Z/9999-12-31T23:59:59.9999999Z",
                                rgba: [255, 0, 255, 255],
                            }
                        ],
                        glowPower: 0.25,
                        // taperPower: 0.5,
                    },
                },
            },
            "model": {
                "show": true,
                "gltf": [
                    {
                        "interval": "2023-06-14T10:00:00Z/9999-12-31T23:59:59.9999999Z",
                        "uri": "https://cesium.com/public/SandcastleSampleData/launchvehicle.glb"
                    }
                ],
                "minimumPixelSize": 128,
                "scale": 3,
                "runAnimations": false,
            },
            "position": {
                "interpolationAlgorithm": "LAGRANGE",
                "interpolationDegree": 2,
                "referenceFrame": "FIXED",
                "epoch": "2023-06-14T10:00:00Z",
                "cartesian": [
                    0.000, -2174195.199042614, 4389988.019058515, 4070606.7900844226,
                    250.000, -2828836.74243954, 4527941.384141082, 4322899.592600973,
                    750.000, -3812052.7676919936, 3910960.7948377975, 4168079.0591541207,
                    1053.000, -3929362.40133975, 3277792.786767426, 3795371.463871257,
                ]
            },
            "orientation": {
                "velocityReference": "#position"
            },
        },
    ];

    // 添加火箭车
    const launchCar = viewer.entities.add({
        position: Cesium.Cartesian3.fromDegrees(
            127.69435837574487,38.808381761124146,0.0
        ),
        model: {
            uri: "https://openlayers.vip/examples/resources/model/car.glb",
            scale: 3.0,
            minimumPixelSize: 128
        },
    });

    const clock = viewer.clock;

    // 获取当前时刻位置
    const position = launchCar.position.getValue(clock.currentTime);

    const dataSourcePromise = viewer.dataSources.add(
        Cesium.CzmlDataSource.load(czml)
    );

    dataSourcePromise
        .then(function (dataSource) {

            // 获取火箭模型实体
            const entity = dataSource.entities.getById("Vulcan");

            // 模型视角跟随
            viewer.trackedEntity = entity;

            // 设置观察角度
            entity.viewFrom = new Cesium.Cartesian3(-1000, 100,-1000);

            // 添加通信线
            viewer.entities.add({
                polyline: {
                    // 回调更新连接线.
                    positions: new Cesium.CallbackProperty(function (time, result) {
                        const position1 = entity.position.getValue(time);
                        return [position,position1];
                    }, false),
                    width: 5,
                    material: new SatelliteMaterialProperty({
                        color: new Cesium.Color(1.0, 0.0, 1.0, 0.1),
                        speed: 50,
                        count: 10,
                        gradient: 0.2
                    }),
                },
            });

            viewer.zoomTo(viewer.entities);

        })
        .catch(function (error) {
            console.error(error);
        });


    /**
     * @description:卫星通信材质
     * @date: 2023年6月17日10:43:18
     */
    function SatelliteMaterialProperty(options) {
        // 默认参数设置
        this._definitionChanged = new Cesium.Event();
        this.color = options.color;
    }

    Object.defineProperties(SatelliteMaterialProperty.prototype, {
        isConstant: {
            get: function() {
                return false;
            }
        },
        definitionChanged: {
            get: function() {
                return this._definitionChanged;
            }
        },
        color: Cesium.createPropertyDescriptor('color')
    });

    SatelliteMaterialProperty.prototype.getType = function(time) {
        return 'SatelliteMaterial';
    };

    SatelliteMaterialProperty.prototype.getValue = function(time, result) {
        if (!Cesium.defined(result)) {
            result = {};
        }
        result.color = Cesium.Property.getValueOrClonedDefault(this._color, time, Cesium.Color.WHITE, result.color);
        viewer.scene.requestRender();
        return result;
    };

    SatelliteMaterialProperty.prototype.equals = function(other) {
        return this === other ||
            (other instanceof SatelliteMaterialProperty &&
                Cesium.Property.equals(this._color, other._color));
    };

    Cesium.Material.SatelliteType = 'SatelliteMaterial';
    Cesium.Material.SatelliteSource = `
	    uniform vec4 color;
	    uniform float speed;
	    uniform float percent;
	    uniform float gradient;
	    uniform float count;

	    czm_material czm_getMaterial(czm_materialInput materialInput){
	      czm_material material = czm_getDefaultMaterial(materialInput);
	      vec2 st = materialInput.st;
	      float t =fract(czm_frameNumber * speed / 1000.0);
	      float v = 1.0-(1.0-smoothstep(gradient,0.0,fract(st.x*count-t)))*0.95;
	      material.diffuse = color.rgb/10.0 + vec3(v)*9.0;
	      material.alpha = color.a;
	      return material;
	    }
	    `;
    Cesium.Material._materialCache.addMaterial(Cesium.Material.SatelliteType, {
        fabric: {
            type: Cesium.Material.SatelliteType,
            uniforms: {
                color: new Cesium.Color(1.0, 0.0, 1.0, 0.1),
                speed: 30.0,
                gradient: 0.2,
                count: 15,
            },
            source: Cesium.Material.SatelliteSource
        },
        translucent: function(material) {
            return true;
        }
    });

</script>
</body>
</html>

示例创建小车模型以及火箭发射,模拟小车追踪火箭通信效果。

在这里插入图片描述


在线示例

Cesium OD 通信线 - 移动连接线

文章来源:https://blog.csdn.net/linzi19900517/article/details/134912511
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。