Is there a good way to get the visible extent of the globe based on the current position of the camera? I know I can set the extent for the camera, but how can I get the extent from the camera?
This is difficult to do across all scene modes, but we have a Github issue for it. Keep your eye on https://github.com/AnalyticalGraphicsInc/cesium/issues/871
There are some past forum threads (with some code) that might help you as well
Hey Ashley, it might be worth talking a bit about what you’re trying to do as well. For top-down views, a camera extent can be useful, but for horizon views it tends to be huge and not very representative of what the viewer can actually see.
I am laying a canvas on the current viewport in order to draw a heatmap. The canvas moves as the globe visible extent changes. I had just made the canvas be the extent of the entire world but that limited the resolution of our heatmap when I was really zoomed in.
My current solution is a brute force calculation which works fairly well no matter where your camera is:
- calculate the lat/lon of 8 points around the screen (top-left, top-center, top-right, middle-left, middle-right, bottom-left, bottom-center, bottom-right)
– if any of those screen points are not on the globe, move towards the center by 100px until we hit the globe and use that value. if we never hit the globe then throw out that point.
- use the min/max lat/lons to calculate our visible extent
Does your heatmap change with time or is it more or less static? If it’s static, it sounds like a perfect case for a custom ImageryProvider. If it changes, it’s still a good use-case for an ImageryProvider but Cesium needs some changes to make that work smoothly.
It changes over time but not that frequently. If it were an ImageryProvider could we manually ‘update’ the layer without changing the extent of the map?
Yes, that should be doable as long as the update rate is fairly low.
Imagery providers work in terms of a quadtree of tiles. The entire globe is covered by two images. Then, each of those images has four children covering the same extent but with twice the resolution. This continues to a depth of your choosing. Cesium figures out which tiles are visible in the current view, and requests them from the imagery provider, which can either request them from a remote server or generate them on the fly. The request happens asynchronously, and until a tile is ready, that tile’s parent (or grandparent, etc.) tile is shown instead. So the globe always shows your heatmap, it just improves in resolution as better data is loaded.
When the images change with time, the challenge with this approach is keeping the various tiles in sync. But if your data changes slowly, you’re probably in good shape.
The easiest way to update the tiles is to just remove the imagery provider layer and re-add it. That will refresh all the tiles, but will have the probably-unwanted side effect of making your heatmap disappear and then reappear incrementally as new tiles are loaded.
You could also add a new copy of the imagery provider on top of the existing one, and remove the old one once the new one is sufficiently loaded. That should avoid the flickering.
Better things are possible, like updating the images in-place, but it’s not straightforward. We hope to have better support for this sort of thing eventually.
Has there been any additional getExtent functionality added to Cesium? If not, are there any plans to?
No, there’s still no ‘getExtent’ function in Cesium, and as far as I know there are no plans to add one. The main reason is that horizon views in Cesium can and will have truly massive extents. We suggest people try to get away from thinking in terms of extent because it doesn’t make much sense in a 3D view where the camera can look out toward the horizon.