【问题标题】:How to get scene change events in cesium?如何在铯中获得场景变化事件?
【发布时间】:2015-03-25 18:03:41
【问题描述】:

我想检测相机位置、航向、俯仰或滚动在 Cesium 视图上的每次变化,以便我可以更新显示这些值的显示。经过一番搜索,我最终发现我可以将事件处理程序添加到小部件的 Scene 对象上的不直观的 preRenderpostRender 事件。然而,这些事件都连续触发,每秒数百次。我猜他们每个时钟滴答都会发射一次。是否有另一个我可以注册的事件会在地图视图更改后简单地触发?我正在寻找与 Leaflet 的moveend 事件和preRenderpostRender 接近的东西,不是吗。

如果做不到这一点,有什么方法可以让preRenderpostRender 仅在实际发生变化时触发?

【问题讨论】:

    标签: javascript cesium


    【解决方案1】:

    另一个不使用计时器的解决方案是监听摄像机移动开始和移动结束事件。

    viewer.camera.moveStart.addEventListener(function() { 
         // the camera started to move
    });
    viewer.camera.moveEnd.addEventListener(function() { 
         // the camera stopped moving
    });
    

    这些听起来更像是您正在寻找的事件。

    [编辑]: 虽然惯性旋转和缩放默认启用并且看起来很酷,但它们可以很容易地禁用。这将使 moveEnd 事件按预期触发。以下是禁用惯性的方法。

    var viewer = new Cesium.Viewer();
    
    viewer.scene.screenSpaceCameraController.inertiaSpin = 0;
    viewer.scene.screenSpaceCameraController.inertiaTranslate = 0;
    viewer.scene.screenSpaceCameraController.inertiaZoom = 0;
    

    【讨论】:

    • 这在用户旋转地球时不起作用,即惯性,它似乎只能通过干净的鼠标向下、移动、鼠标向上触发...
    • 他们的 gitHub 上有一个针对这个问题的开放错误。我目前有同样的问题。 github.com/AnalyticalGraphicsInc/cesium/issues/2839希望他们尽快解决。
    • @Adam 看看我的编辑,如果你不需要惯性旋转,这个效果很好。
    【解决方案2】:

    使用cesium v​​1.30,可以使用这个代码:

    viewer.camera.changed.addEventListener(function() {
      var deg = Math.round( Cesium.Math.toDegrees(viewer.camera.heading))
      console.log('Heading:', deg)
    
      var deg = Math.round( Cesium.Math.toDegrees(viewer.camera.pitch))
      console.log('Pitch:', deg)
    })
    

    【讨论】:

      【解决方案3】:

      除了答案https://stackoverflow.com/a/42044819/3092437 之外,您可能还想将viewer.camera.percentageChanged 设置为接近0 的某个小值(但0camera 往往会一直生成change 事件)。我使用0.001,它在所有缩放级别都提供了相当不错的事件频率。

      【讨论】:

        【解决方案4】:

        实际答案:

        viewer.scene.morphStart.addEventListener(function(ignore, previousMode, newMode) {
        
        });
        

        还有morphComplete

        https://www.cesium.com/docs/cesiumjs-ref-doc/Scene.html?classFilter=scene#morphComplete

        【讨论】:

          【解决方案5】:

          我会推荐以下解决方案之一:

          • 设置一个间隔,以对您的应用程序有意义的任何频率轮询相机位置。

            var intervalHandle = setInterval(function() {
              var camera = viewer.scene.camera,
                store = {  position: camera.position.clone(),
                           direction: camera.direction.clone(),
                           up: camera.up.clone(),
                           right: camera.right.clone(),
                           transform: camera.transform.clone(),
                           frustum: camera.frustum.clone()
                        };
              //update UI elements
              ...
             }, 1000); // every 1 second whatever is best for your application
            ...
            
          • 在更改的发起者上附加一个事件触发器。如果是鼠标,则在 mouseup 上。如果是键盘,则附加在 keyup 上。

            CameraEventAggregator 对象有一个名为“anyButtonDown”的成员,该成员对鼠标状态更改很有用。

          • 您也可以使用相机的 FlightCompleteCallback。如果您使用辅助方法来移动它,那么只要相机完成移动,它就会触发。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-02-18
            • 1970-01-01
            • 1970-01-01
            • 2020-06-02
            • 2014-05-07
            • 2016-03-05
            相关资源
            最近更新 更多