Detecting when all static rendering is complete

The data source that I am using is CzmlDataSource and the streamed CZMLs are just static objects with a unique identifier. I tried using CzmlDataSource.changedEvent and CzmlDataSource.loadingEvent to see when in the processing flow things are invoked. On a scenario where there are a significant amount of polygons, the both events’ callbacks seem to complete then about 5-10 seconds later, the polygons would appear.

Is there a way to detect when all rendering is complete and registering a callback function? In the scenario above, I want to perform a task when all polygons are shown in the scene.

Hello,

The polygons appear later because they are being drawn asynchronously (so they don’t bog down the visualization while they are being drawn)

I don’t know of a way to detect when everything has finished drawing,

Best,

Hannah

Same issue here:
As Thin.., i'm trying to filter information stored in some CZML files.
The problem is that i'm not able to see those information since the files are completely loaded in the viewer.
I've also tryied with "isLoading" attribute, but it doesn't works properly (or at least, i don't know how to use it).

What i want to do is something like AGI's SpaceBook, a loading dialog that prevents any action until the CZMLs are loaded.

Thank you,
Federico.

I figured it was because of asynchronous rendering. Maybe some fancy web worker implementation may help (?)… still experimenting.

On the same topic, I noticed that if we send a CZML delete, the polygon is never deleted visually. The EntityCollection seem to be cleared from the datasource but the polygon still exists on the globe. Any suggestions?

Thanks again!

So it turned out exposing a flag for when things are ready was really trivial. I submitted a pull request here: https://github.com/AnalyticalGraphicsInc/cesium/pull/3634
Once that is merged, you’ll be able to check when viewer.dataSourceDisplay.ready === true, and proceed with whatever you wanted to do from there.

Thinh, regarding “the polygon is never deleted visually”, can you please post a short code example? That sounds like a bug.

Thanks,

Hannah

Cesium 1.13 is where we’re seeing the issue with the polygon is never deleted visually. Codewise, it’s pretty straight forward:

viewer.dataSources.add(czmlDataSource).then(function(result) {

// hook up a callback to result.loadingEvent

// hook up a callback to result.changedEvent

// hook up a callback to result.errorEvent

// hook up a callback to result.entities.collectionChanged

});

The CZML is pretty straight forward as well: a polygon with referenceFrame:FIXED, cartesian:[(~75 points)], material:solidColor with rgba, for example [255,255,0,51]. Image a polygon representing the daynight line with the night part filled in with an alpha. Updates for the same polygon (i.e. daynight area) are coming up close to every minute. The delete CZML contains the unique identifier to that polygon.

Is the pull going to be in v1.19 next month?

Thanks!

Forgot to mention that if the CZML delete comes in and the polygon is still showing with 0 entities in the collection… if we force another update of a different polygon area, then the daynight area is then cleared out.

Sorry, it’s not clear to me, how are you deleting the polygon?

Thanks,

Hannah

That’s my fault…

{id:, delete:true}

is the CZML sent for deleting the polygon entity.

More investigation shows that if updates for the same polygon aren’t coming in every minute, then the delete will remove the polygon as intended. We haven’t hit a threshold to determine if there is a sweet spot in update intervals that would cause the lingering polygon on the map. In any case, forcing an update – not necessarily have to be the same polygon – will clear out the one that was marked in the delete CZML.

Hi, I created a separate discussion for the issue with the lingering polygon not being removed after the czml delete packet.

In regards to the update on detecting with the display is ready… where is an appropriate spot to check viewer.dataSourceDisplay.ready === true? Seems like the Promise returned by CzmlDataSource.process(czml,options) would be done before viewer.dataSourceDisplay is done and ready (from Cesium 1.13).

Thank you.

Below is a scenario setup modified from one of the CZML examples…

The application can have as much as 40 datasources and streamed CZML is coming in tagged and grouped by an identifier that tells the application which datasource needs to process the data. The application takes each group of CZML packets and sequentially process them via czmlDataSource.process (vs. the snippet below that uses czmlDataSource.load).

  1. Where the snippet prints out 'is display ready after loading czml1? ’ - In version Cesium 1.19, viewer.dataSourceDisplay.ready is false in some update cycles in the application although the promise resolved with the list of add/removed/changed entities. Just wanted to confirm that ready=false indicates that not all entities are rendered. So, the promise is just saying “the EntityCollection is updated” not necessarily promising that the display is updated/ready.

  2. The default Cesium.CzmlDataSource.updaters array – Is this where the asynchronous action takes place?

  3. Is there a way to hook up a callback that gets raised when viewer.dataSourceDisplay.ready is true?

var czml1 = [

{

“id” : “document”,

“name” : “CZML Geometries 1: Circles and Ellipses”,

“version” : “1.0”

},

{

“id” : “shape1”,

“name” : “Green circle at height”,

“position” : {

“cartographicDegrees” : [-111.0, 40.0, 150000.0]

},

“ellipse” : {

“semiMinorAxis” : 300000.0,

“semiMajorAxis” : 300000.0,

“height” : 200000.0,

“material” : {

“solidColor” : {

“color” : {

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

}

}

}

}

}

];

var czml2 = [

{

“id” : “document”,

“name” : “CZML Geometries 2: Circles and Ellipses”,

“version” : “1.0”

},

{

“id” : “shape2”,

“name” : “Red ellipse on surface”,

“position” : {

“cartographicDegrees” : [-103.0, 40.0, 0]

},

“ellipse” : {

“semiMinorAxis” : 250000.0,

“semiMajorAxis” : 400000.0,

“height” : 0,

“material” : {

“solidColor” : {

“color” : {

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

}

}

},

“outline” : true,

“outlineColor” : {

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

}

}

},

{

“id” : “shape3”,

“name” : “Blue translucent, rotated, and extruded ellipse with outline”,

“position” : {

“cartographicDegrees” : [-95.0, 40.0, 100000.0]

},

“ellipse” : {

“semiMinorAxis” : 150000.0,

“semiMajorAxis” : 300000.0,

“extrudedHeight” : {

“number” : 200000.0

},

“rotation” : {

“number” : 0.78539

},

“material” : {

“solidColor” : {

“color” : {

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

}

}

},

“outline” : true

}

}

];

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

var ds1 = new Cesium.CzmlDataSource(‘czml1/ds’);

var ds2 = new Cesium.CzmlDataSource(‘czml2/ds’);

ds1.entities.collectionChanged.addEventListener(function(collection,added,removed,changed) {

console.log(‘added:’ + added.length + ‘, ready:’ + viewer.dataSourceDisplay.ready);

});

//

viewer.dataSources.add(ds1).then(function(ds) {

console.log(‘datasource ’ + ds.name + ’ added’);

});

viewer.dataSources.add(ds2).then(function(ds) {

console.log(‘datasource ’ + ds.name + ’ added and attaching callback to collection changed’);

ds.entities.collectionChanged.addEventListener(function(collection,added,removed,changed) {

console.log(‘added:’ + added.length

  • ‘, total:’ + collection.values.length

  • ‘, ready:’ + viewer.dataSourceDisplay.ready);

});

});

console.log(‘ready:’ + viewer.dataSourceDisplay.ready);

console.log(‘please wait…’);

// process later

setTimeout(function() {

ds1.load(czml1).then(function(result) {

console.log('is display ready after loading czml1? ’ + viewer.dataSourceDisplay.ready);

});

ds2.load(czml2).then(function(result) {

console.log('is display ready after loading czml2? ’ + viewer.dataSourceDisplay.ready);

});

// can be up to 40 datasources

}, 5000);

``

Thank you.

Hello,

So, the promise is just saying “the EntityCollection is updated” not necessarily promising that the display is updated/ready.

Yes, that is true. ready will be true once the entities are rendered. For static geometry, that happens asynchronously on a webworker, so it is not tied to the promise.

Is there a way to hook up a callback that gets raised when viewer.dataSourceDisplay.ready is true?

I was hoping to do this, but since you can add more entities to the data source at any time, ready can switch from true to false when you add new data. Having a promise for this wouldn’t make sense because we would need it to have the ability to resolve multiple times. And generally, we try to avoid having callbacks.

Thanks for the great code example!

-Hannah

Thanks for the clarification, Hannah.

The application is getting about 200 CZML packets each second, they get filtered into appropriate CzmlDataSource - about 40 total datasources at the high end. I hooked up a setInterval for every 5 seconds to print out viewer.dataSourceDisplay.ready and when the data stream is “overloaded” (polylines, polygons, points, labels - on and off the Earth), visually, we see some entities not rendered but the entity collection callback indicates that the missing entities were added. The setInterval callback always prints that ‘ready’ is false.

Can’t really reproduce this issue on Sandcastle without an appropriate data stream. Was wondering if you or anyone has run into similar issues.

The application is running with Cesium 1.19 which seem to have fixed an issue that we saw with not having an entity removed when a CZML delete packet comes in… at least, haven’t run into this situation yet. On a related note, probably worth noting that the data stream sends out CZML delete packets in bulk for entities that may not exist in any data sources. Looking at the how the delete packet is processed, seems like it removes the entity by id right off the entity collection which seems to handle non-existing identifiers.

Thank you.

Glad your delete issue seems to be fixed. Let me know if it pops back up.

Regarding the ready flag, I’m thinking it may never be true because you are constantly adding and deleting entities. Ready will only be true once there are no more entities in the datasource that are waiting to be rendered.

What types of entities are you using? Just polylines, polygons, points and labels?

-Hannah

That was my thought as well… the entities are still being rendered. Nothing too fancy coming from the data stream… yes, just polylines, polygons, points and labels. Polylines and polygons may have 100-200 points, filled or not filled depending on the scenario. Another thought was maybe the polygons are too big and is slowing down the rendering and some entities are “dropped” (?)

Pulled out one of the bigger, filled polygons (czml) and plugged it into Sandcastle in our dev environment and rendering took a while as well – close to 1 minute. That’s just with 1 polygon. They can get as big as covering half of the Earth.

We do have an open issue for large polygons not rendering properly: https://github.com/AnalyticalGraphicsInc/cesium/issues/2788
That could be an issue you’re running in to.

As for the long rendering time, it can take a little bit to triangulate a polygon with many points. I wouldn’t expect it to take close to a minute though. Even the more complex datasets I’ve seen haven’t taken longer than 30 seconds to render on my machine. It might depend on your specs. Is that polygon something you could share? I could see if I have the same long rendering time and what the cause might be.

Thanks for the link to the issue.

Unfortunately, the czml is only available in our dev environment. The specs are pretty beefy for the machines used to reproduce this issue in our environment. I’ll see if I write something up later – going to be a filled polygon that covers half the Earth.

General design question: Can Cesium handle 40 CzmlDataSource processing their own data? The logic processes sequentially a set of czml packets for each datasource. Pseudo code below…

var data = (streamed)

if(typeof data[‘ds1’] !== ‘undefined’) {
ds1.process(data[‘ds1’])
}

if(typeof data[‘ds2’] !== ‘undefined’) {
ds2.process(data[‘ds2’])
}

if(typeof data[‘ds3’] !== ‘undefined’) {
ds3.process(data[‘ds3’])
}

… all the way to 40 datasources with a total of ~200 total packets

``

Thanks!

Static points and polygons adding and removing from the datasource and then rendering them seem to be pretty well - almost instantaneous. Is that because of the order of…

/**

  • Gets the array of CZML processing functions.

  • @memberof CzmlDataSource

  • @type Array

*/

CzmlDataSource.updaters = [

processBillboard, //

processEllipse, //

processEllipsoid, //

processLabel, //

processModel, //

processName, //

processDescription, //

processPath, //

processPoint, //

processPolygon, //

processPolyline, //

processRectangle, //

processPosition, //

processViewFrom, //

processWall, //

processOrientation, //

processAvailability];

``

Thank you.

Hmm yeah. Sorry, I’m really not sure what would be causing the issues you’re seeing. Your overall approach seems fine.
Ultimately, the best solution for streaming large datasets like this will be our new 3D Tiles format.

Take a look at this forum post if you’re interested in more information: https://groups.google.com/forum/?hl=en#!searchin/cesium-dev/3d$20tiles/cesium-dev/tCCooBxpZFU/7hxT_E4pGgAJ

Best,

Hannah