首页 > 编程学习 > Cesium学习七:使用CallbackProperty更新entity

Cesium学习七:使用CallbackProperty更新entity

发布时间:2022/10/1 2:25:51

一、前言

本学习流程到目前为止已经学习了点、线、多边形、棱柱、椭球等几何体的绘制,这些都是比较常见的,当然Cesium提供的几何体不止上述几种,还有很多,使用方式基本相同,参数除了几何数据外,绘制参数大同小异,所以其他的几何体可以参考官方文档学习。
从本篇开始学习一些和entity相关的功能函数,使用这些函数可以实现一些特别的效果以及实际应用的效果。

二、CallbackProperty

2.1 从需求与问题切入

在之前的很多篇中,我们为各种类型的entity设置了很多参数,现实工作中,我们经常需要去修改它们,如修改点的坐标、修改颜色、修改大小等。
要实现参数的修改最直接的方法是从内存中拿到entity对象,并对其参数重新赋值,这种方法是可行的,但是有可能会导致更新闪烁的问题,下图展示了通过赋值的方式来显示或隐藏多边形边框时出现的闪烁问题。
闪烁

使用CallbackProperty可解决闪烁问题,如下图所示
无闪烁

2.2 函数介绍

Cesium提供了CallbackProperty函数来让我们构建动态变化的参数。该函数的官方文档说明如下,包含两个参数,callback是一个返回参数变量的函数,isConstant表示不同时刻的值是否一致,为布尔值,对于变化的情况为false
官方说明

2.3 使用方法

该函数的使用方法如下图所示(图中代码只用做解释说明,不能运行),对于entity的参数,将以前直接赋值的方式改为用new Cesium.CallbackProperty替换即可,其中第1个参数我们需要定义一个函数,该函数的返回值就是我们用于直接赋值的变量,当我们改变这个变量时,对应的参数值会自动变化,比如下图中如果要改变position参数,我们只需要修改pt变量就可以了。

let pt = new Cesium.Cartesian3();

//直接赋值的方式1
position: new Cesium.Cartesian3()

//直接赋值的方式2
position: pt

//CallbackProperty方式
position: new Cesium.CallbackProperty(()=>{
    return pt;
}, false)

三、 函数应用

使用CallbackProperty让我们可以定义时变的参数,不同时变的参数可实现不同的应用效果。本篇就介绍两种简单的应用,其他也都类似,完整代码如下

3.1 点移动-实时跟踪

pointposition应用CallbackProperty,可以实现点的移动效果,在数字孪生应用中,可结合GPS等数据实现物体运动轨迹实时追踪显示的效果,如下图所示
position修改

3.2 点闪烁-预警

pointcolor应用CallbackProperty,可以实现点的颜色变化效果,在数字孪生应用中,可实现闪烁预警的功能,如下图所示
point闪烁

3.3 完整代码

完整代码如下(别忘了使用你自己的Token,基础环境不知道怎么布置的请参考开发环境搭建),代码包含了直接赋值和使用CallbackProperty两种方法,上述的图在下面的代码中需要对部分进行注释,如把position的变动注释,color运行,可以达到3.2的效果。代码默认是都变化的,即点边运动边闪烁,如下图所示。
完整

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8">
    <!-- Include the CesiumJS JavaScript and CSS files -->
    <script src="https://cesium.com/downloads/cesiumjs/releases/1.96/Build/Cesium/Cesium.js"></script>
    <link href="https://cesium.com/downloads/cesiumjs/releases/1.96/Build/Cesium/Widgets/widgets.css" rel="stylesheet">
</head>
<body>
    <div id="cesiumContainer" style="position:fixed;left:0px;top:0px;width:100%;height:100%;"></div>
    <script>
    // Your access token can be found at: https://cesium.com/ion/tokens.
    // Replace `your_access_token` with your Cesium ion access token.

    Cesium.Ion.defaultAccessToken = '你的Token'; //替换成你的Token
    Cesium.Camera.DEFAULT_VIEW_RECTANGLE = Cesium.Rectangle.fromDegrees(100, -20, 120, 90);

    // Initialize the Cesium Viewer in the HTML element with the `cesiumContainer` ID.
    const viewer = new Cesium.Viewer('cesiumContainer', {
        geocoder:true,//控制右上角第一个位置的查找工具
        homeButton:true,//控制右上角第二个位置的home图标
        sceneModePicker:true,//控制右上角第三个位置的选择视角模式,2d,3d
        baseLayerPicker:true,//控制右上角第四个位置的图层选择器
        navigationHelpButton:true,//控制右上角第五个位置的导航帮助按钮
        animation:false,//控制左下角的动画器件
        timeline:false,//控制下方时间线
        fullscreenButton:false,//右下角全屏按钮
        vrButton:false,//右下角vr按钮
        shouldAnimate: true,//允许动画同步
        infoBox : true, //不显示点击要素之后显示的信息
        terrainProvider: Cesium.createWorldTerrain()
    });

    viewer._cesiumWidget._creditContainer.style.display="none";//取消版权信息
    
    // 定义第一个点,该点使用常规方法赋参数值
    let position1 = new Cesium.Cartesian3.fromDegrees(120, 25, 10000);
    let color1 = new Cesium.Color(1, 1, 0, 1); //黄色
    let point1 = viewer.entities.add({
        name: "point1",
        position: position1, // 点的经纬度坐标
        point: {
            show: true, //是否显示,默认显示
            pixelSize: 20, //点的大小(像素),默认为1
            color: color1, //颜色,默认为白色
        },
    })

    // 定义第二个点,该点使用回调函数赋参数值
    let position2 = new Cesium.Cartesian3.fromDegrees(120, 30, 100000);
    let color2 = new Cesium.Color(1, 0, 0, 1); //红色
    let point2 = viewer.entities.add({
        name: "point2",
        position: new Cesium.CallbackProperty(()=>{
            return position2;
        }, false), // 点的经纬度坐标
        point: {
            show: true, //是否显示,默认显示
            pixelSize: 20, //点的大小(像素),默认为1
            color: new Cesium.CallbackProperty(()=>{
                return color2;
            }, false), //颜色,默认为白色
        },
    })

    // let polygon1 = viewer.entities.add({
    //     name: "polygon1",
    //     polygon: {
    //         show: true,
    //         hierarchy: Cesium.Cartesian3.fromDegreesArray([
    //             120.0,
    //             40.0,
    //             124.0,
    //             40.0,
    //             122.0,
    //             42.0,
    //         ]),
    //         height: 50000,
    //         extrudedHeight: 100000,
    //         fill: true,
    //         material: Cesium.Color.RED,

    //         outline: true,
    //         outlineColor: Cesium.Color.BLACK,
    //         outlineWidth: 5.0,
    //     }
    // })

    let outline = true;
    let polygon2 = viewer.entities.add({
        name: "polygon2",
        polygon: {
            show: true,
            hierarchy: Cesium.Cartesian3.fromDegreesArray([
                120.0,
                35.0,
                124.0,
                35.0,
                122.0,
                37.0,
            ]),
            height: 50000,
            extrudedHeight: 100000,
            fill: true,
            material: Cesium.Color.YELLOW,

            outline: new Cesium.CallbackProperty(()=>{
                return outline;
            }, false),
            outlineColor: Cesium.Color.BLACK,
            outlineWidth: 5.0,
        }
    })

    // 用于控制的变量
    let i = 0;
    let j = 1;

    // 每隔100毫秒修改一次参数
    setInterval(()=>{
        // 方法1:直接给entity的参数赋新值
        point1.position = new Cesium.Cartesian3.fromDegrees(120-1*i, 25, 100000);
        point1.point.color = new Cesium.Color(1, 1, 0, 0.1*i);
        // polygon1.polygon.outline = i%2 == 0? true:false;

        // 方法2: 修改参数对应的回调函数中的变量
        position2 = new Cesium.Cartesian3.fromDegrees(120-1*i, 30, 10000);
        color2 = new Cesium.Color(1, 0, 0, 0.1*i);
        outline = !outline;

        // 使变量间隔2秒重复
        if(i>=10){
            j = -1;
        }
        if(i<=0){
            j = 1;
        }

        i += j;
    }, 100) //博客中point用100,polygon用1000

    </script>
</body>
</html>
Copyright © 2010-2022 mfbz.cn 版权所有 |关于我们| 联系方式|豫ICP备15888888号