[GIS] Cesium – Camera.computeViewRectangle to get current view bounds

cesium

I'm trying to get custom west-south-east-north bounds in Cesium's HelloWorld.html example, using Camera.computeViewRectangle, as suggested in this answer and its elaboration.

Perhaps I misunderstand the purpose of the function, but which input parameter should I provide, if I'm trying to obtain the rectangle bounds of the view currently displayed?

As illustration here is the adapted HelloWorld.html example embedded in a custom web application:

<script src="cesium-app/Build/Cesium/Cesium.js"></script>
<style>
    @import url(cesium-app/Build/Cesium/Widgets/widgets.css);
    #cesiumContainer {
        width: 640px; height: 360px; margin: 0; padding: 0; overflow: hidden;
    }
</style>

<div id="cesiumContainer">cesiumContainer</div>
<script>
  var extent = Cesium.Rectangle.fromDegrees(46.176235, 6.120418);
  Cesium.Camera.DEFAULT_VIEW_RECTANGLE = extent;
  Cesium.Camera.DEFAULT_VIEW_FACTOR = 0;

  var viewer = new Cesium.Viewer('cesiumContainer');

  console.log("Test from cesium")
  Cesium.Camera.computeViewRectangle(ellipsoid, result) //how to use this to get the bounds of the current view?
</script> 

Best Answer

You've got a couple issues in your code. On the first line, Rectangle.fromDegrees needs 4 input parameters, not 2. Next, computeViewRectangle is not a static function, you have to call it on a real instance of the camera, not just the camera class in general. You also didn't pass in valid references to the ellipsoid or the optional result parameter. And finally, you're not saving the return value, which has the answer you want.

The presence of the "result" parameter among the input arguments is one technique Cesium uses to reduce pressure on JavaScript's garbage collector (GC) system. If you end up calling this function frequently, such as every animation frame or ~60 times/sec, you don't want memory allocations happening at 60 times/sec. So, you can pre-allocate a structure to hold the result, and pass it in for overwriting every time.

Here's a Sandcastle demo of the above code with fixes applied.

var extent = Cesium.Rectangle.fromDegrees(46.176235, 6.120418, 47.176235, 7.120418);
Cesium.Camera.DEFAULT_VIEW_RECTANGLE = extent;
Cesium.Camera.DEFAULT_VIEW_FACTOR = 0;

// Scractch memory allocation, happens only once.
var scratchRectangle = new Cesium.Rectangle();

var viewer = new Cesium.Viewer('cesiumContainer');

var toolbar = document.getElementById('toolbar');

viewer.clock.onTick.addEventListener(function() {
    var rect = viewer.camera.computeViewRectangle(viewer.scene.globe.ellipsoid,
        scratchRectangle);

    toolbar.innerHTML = '<pre>' +
        'West: ' + Cesium.Math.toDegrees(rect.west).toFixed(4) + '<br/>' +
        'South: ' + Cesium.Math.toDegrees(rect.south).toFixed(4) + '<br/>' +
        'East: ' + Cesium.Math.toDegrees(rect.east).toFixed(4) + '<br/>' +
        'North: ' + Cesium.Math.toDegrees(rect.north).toFixed(4) + '</pre>';
});
Related Question