2015-03-25 5 views
2

Я бы хотел, чтобы каждый раз, когда положение камеры, заголовка, высоты тона или качки на экране Цезия, я могу обновить отображение этих значений. После довольно многого поиска я в конце концов обнаружил, что я могу добавить обработчик событий к неинтересным событиям preRender или postRender объекта Scene для виджета. Тем не менее, эти события срабатывают непрерывно, сотни раз в секунду. Я бы предположил, что они стреляют один раз за такт. Есть ли еще одно событие, которое я могу зарегистрировать, потому что он просто выстрелит после того, как будет изменен вид карты? Я ищу что-то близко к событию Leaflet moveend и preRender и postRender не так ли.Как получить события смены сцены в цезие?

Несоблюдение этого, есть ли способ получить preRender или postRender, чтобы стрелять только тогда, когда что-то действительно изменилось?

ответ

1

Я рекомендовал бы одно из следующих решений:

  • установить интервал, который опрашивает положение камеры на любой частоте имеет смысл для вашего приложения.

    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 
    ... 
    
  • Прикрепите триггер события к инициатору изменения. Если мышь, то на мыши. Если клавиатура, прикрепите к клавиатуре.

    Объект CameraEventAggregator имеет член, называемый «anyButtonDown», который будет полезен для изменений состояния мыши.

  • Вы также можете использовать FlightCompleteCallback камеры. Это должно срабатывать всякий раз, когда камера движется, если вы использовали вспомогательные методы для ее перемещения.

7

Другим решением, которое не использует таймер, является прослушивание движения камер и перемещение конечных событий.

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; 
+0

Это не работает, когда пользователь вращает земной шар, то есть с инерцией, он кажется только срабатывающим с чистой мышью вниз, перемещением, мышью вверх ... – Adam

+0

В этом выпуске есть ошибка в их gitHub , В настоящее время у меня такая же проблема. https://github.com/AnalyticalGraphicsInc/cesium/issues/2839 Надеюсь, они исправит это в ближайшее время. – Zac

+0

@Adam Смотрите мое редактирование, если вам не нужна инерционная спина, это работает очень хорошо. – Zac

1

Использование v1.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) 
}) 
0

В дополнение к ответу https://stackoverflow.com/a/42044819/3092437 вы, вероятно, хотите установить viewer.camera.percentageChanged в некоторой малой величины, близкой к 0 (но с 0 значением camera имеет тенденцию генерировать change событий все время). Я использую 0.001, он дает довольно хорошую частоту событий на всех уровнях масштабирования.