Obtain only in-view entities based on current view/zoom

Hello,

I would like to be able to get all entities that would be visible (all or partially) within a view and zoom level.

In general, how does Cesium handle entities that are no longer visible because the user zooms to an area where entities are out-of-view? Are out-of-view entities not rendered for performance?

Thank you.

Hello,

I don’t think there is anything built into Cesium that will get all entities in view. If you really needed to know this, you could try doing something with Camera.computeViewRectangle to get the current view, then compare that to the position of the entities.

But yes, entities that are not in view are not rendered.

Best,

Hannah

Hi, Hannah…

I’m running this in Cesium v1.19 Sandcastle:

var czmlDocument = [{

“id” : “document”,

“name” : “CZML Point”,

“version” : “1.0”

}];

var czml = [

{

“id” : “point1”,

“name”: “point”,

“position” : {

“cartesian” : [1864828.93,3364932.93,5070208.06]

},

“label” : {

“fillColor” : {

“rgba” : [255, 255, 255, 255]

},

“font” : “12pt Lucida Console”,

“horizontalOrigin” : “LEFT”,

“pixelOffset” : {

“cartesian2” : [8, 0]

},

“style” : “FILL”,

“text” : “point1”,

“showBackground” : true,

“backgroundColor” : {

“rgba” : [112, 89, 57, 200]

}

},

“point”: {

“color”: {

“rgba”: [255, 255, 255, 255]

},

“outlineColor”: {

“rgba”: [255, 0, 0, 255]

},

“outlineWidth” : 4,

“pixelSize”: 20

}

}

];

var czmlDelete = [

{

“id”:“point1”,

“delete”:true

}

];

var inView = function(_position, _viewer) {

try {

var camera = _viewer.scene.camera;

var frustum = camera.frustum;

var cullingVolume = frustum.computeCullingVolume(camera.position, camera.direction, camera.up);

return cullingVolume.computeVisibility(new Cesium.BoundingSphere(_position, 0.0)) === Cesium.Intersect.INSIDE;

} catch (e) {

console.log(e);

return false;

}

};

var viewRectangle = function(_viewer) {

var ellipsoid = _viewer.scene.globe.ellipsoid;

return _viewer.scene.camera.computeViewRectangle(ellipsoid);

};

var viewer = new Cesium.Viewer(‘cesiumContainer’);

var dataSource = new Cesium.CzmlDataSource(‘test’);

viewer.dataSources.add(dataSource);

dataSource.load(czmlDocument);

Sandcastle.addToolbarButton(‘Process Point’, function() {

dataSource.process(czml).then(function(ds) {

var rect = viewRectangle(viewer);

console.log(‘Entities (processed): ’ + ds.entities.values.length + ’ viewRect: [w:’ + rect.west + ’ s:’ + rect.south + ’ e:’ + rect.east + ’ n:’ + rect.north + ‘]’);

for(var i = 0; i < ds.entities.values.length; i++) {

var e = ds.entities.values[i];

var position = e.position.getValue(viewer.clock.currentTime);

var screen = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, position);

console.log(e.id + ’ ’ + position + ’ screen:’ + screen + ', visible: ’ + inView(position, viewer));

}

});

});

Sandcastle.addToolbarButton(‘Delete Point’, function() {

dataSource.process(czmlDelete).then(function(ds) {

console.log('Entities (processed): ’ + ds.entities.values.length);

});

});

``

Initially, I wanted to see screen position of the point from the console. Seems to work great. Then, I ‘Delete Point’ and rotated the Earth to the opposite side so that the point would not be visible when I ‘Process Point’ – after processing the point, I still get a screen position even when the point is behind the Earth. Is this the position of the point on the screen if it were to be projected to the front?

I’m also logging to the console the view rectangle as you suggested and I’m seeing that the coordinates are the same every time I hit ‘Process Point’ even after zooming in and out and changing the view.

I’ve also added an inView function that doesn’t seem to be behaving as expected because the screen position is always returning a value that is within the view.

Hello! We are doing something similar (but with billboards), and we are using a combination of the code you have in your inView function, and the following code which tells us if it’s on the visible side of the globe (ie: not behind it). There’s probably a better way to do this, but this has been working for us so far in 3D view:

var occluderEllipsoid = Cesium.Ellipsoid.WGS84;
var occluder = new Cesium.EllipsoidalOccluder(occluderEllipsoid, cameraPosition);
var isPointVisible = occluder.isPointVisible(billboard.position);

Note that we aren’t hiding entities that are out of view, since they’re not rendered anyway, but we needed to detect how many billboards were in the current view, and if there are fewer than a certain amount, we change the image on those billboards.

Hello, Running 1.40 Version.
I've wrote the same code.
Although it runs with no errors, I'm always getting true from the function occluder.isPointVisible(billboard.position).

p.s.
EllipsoidalOccluder is not available in https://cesiumjs.org/Cesium/Build/Documentation/
only at
https://cesiumjs.org/releases/b30/Build/Documentation/index.html

Hi there,

EllipsodalOccluder is not available in the most recent documentation because it was deprecated in Cesium 1.0, so you should try to find a solution using the newer API which is being maintained. Are you able to use the Occuluder class?

Thanks,

Gabby