Entity Collection Rendering

Dear all,

I'm trying to visualize a custom GeoJSON dataset of a big city.

At the moment, I'm able to parse the GeoJSON, to calculate the altitude of each building using the sampleTerrain function (it is not perfect but it works in my case), to create the single entities, to add them to the EntityCollection and visualize them in the scene.

Everything works fine, the issue is the time that the viewer takes to render the entities, more or less 1 minutes, and it displays all the entities in one shot.

I tried to look for a solution in the forum, but I didn't find anything that could help me to figure out my issue.

Is there a way to render the single entities one by one or a method to check if the rendering of the collection is finished?

The main issue is that the user should be notified that something is happening in background and the rendering of single entities would be a good effect.

Any suggestions is more than welcome.

Thank you for your support,
Michele

Hello Michele,

We recently added a ready property to DataSourceDisplay: http://cesiumjs.org/Cesium/Build/Documentation/DataSourceDisplay.html#ready

The value will be true when all added entities are rendered

You can poll viewer.dataSourceDisplay.ready to see when everything is rendered.

Best,

Hannah

Thank you Hannah for your swift reply.

With your suggestion, I'm able to check the render state of my entities and in this way the user will be notify when the viewer is ready.

I have another curiosity for what concern the rendering process.
Before your reply, I tried to implement the buildings with primitives instead of entities. In this case the rendering was not in one shot, but each building appears one after the other, but the performances decrease drastically.

Is the reason imputed to the EntityCollection?

Thank you,
Michele

The Entity API is built on top of the Primitive API, so they should have similar performance. The Entity API does use primitives in an optimal way, it’s possible that you were trying to use primitives a little differently and that effected performance.

Does that answer your question?

-Hannah

Dear Hannah and dear all,

I figured out my previous issue taking into account your suggestions about the DataSourceDisplay, but the performance are not so good…

The loading and the rendering processes are quite slow (we have more ore less 9000 buildings), but this issue is visible only the first time after the geoJSON parsing. I’m able to notify the user when the viewer is ready…

I implemented also the picking on a building and the highlight feature is slow as well… maybe something is wrong in my code.

If you want try and give me a feedback or suggestions in order to improve the performance, just cut and paste in a blank SandCastle page:

var initialExtent = new Cesium.Rectangle.fromDegrees(14.0556,41.717,14.7711,42.3342);

var buildingsCollection3D;

var buildingsMetadata = ;

var buildingHighlighted;

var viewer = new Cesium.Viewer(‘cesiumContainer’, {

selectionIndicator : false,

infoBox : false

});

var scene = viewer.scene;

var handler;

viewer.scene.camera.setView({destination: initialExtent});

Sandcastle.addToolbarButton(‘Load Custom GeoJSON’, function() {

loadBuildingsFromGeoJson();

handler = new Cesium.ScreenSpaceEventHandler(scene.canvas);

//MOUSE MOVE

handler.setInputAction(function (movement){

pickingAction.mousePosition = movement;

}, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

//LEFT CLICK

handler.setInputAction(function(movement) {

pickingAction();

}, Cesium.ScreenSpaceEventType.LEFT_CLICK);

});

function pickingAction(){

var pickedObject = scene.pick(pickingAction.mousePosition.endPosition);

if (Cesium.defined(pickedObject)) {

if(Cesium.defined(buildingHighlighted)){

buildingHighlighted.polygon.material = buildingsMetadata[buildingHighlighted._name].colorRoof;

buildingHighlighted = undefined;

}

pickedObject.id.polygon.material = Cesium.Color.fromCssColorString("#ffc600");

buildingHighlighted = pickedObject.id;

}

}

function loadBuildingsFromGeoJson(){

console.log(“BUILDINGS LOADING -> BEGIN”);

Cesium.loadJson(“http://sparta.sis-ter.it/wg_trignosinello_wip/cesium/Apps/json_edificio.php”).then(function(geojson) {

console.log(“BUILDINGS LOADING -> COMPLETE”);

buildingsCollection3D = new Cesium.EntityCollection();

console.log(“BUILDINGS ENTITIES CREATION -> BEGIN”);

for(var i=0;i<geojson.data.length;i++){

var building = geojson.data[i];

var buildingMetadata = getBuildingsInfo(building);

buildingsMetadata[buildingMetadata.code] = buildingMetadata;

createBuilding(buildingMetadata.code,buildingMetadata.coordinateArray,buildingMetadata.extrudedHeight,buildingMetadata.colorBuilding,buildingMetadata.colorRoof,buildingMetadata.description);

}

buildingsCollection3D.show = true;

console.log(“BUILDINGS ENTITIES CREATION -> COMPLETE”);

}).otherwise(function(error) {

console.log(error);

});

}

function getBuildingsInfo(building){

var colore = building.colore;

var colore_secondario = building.colore_secondario;

var buildingMetadata = {};

buildingMetadata.code = building.id;

buildingMetadata.link = building.cat_partkey;

buildingMetadata.catPartKey = building.cat_partkey;

buildingMetadata.coordinate = JSON.parse(building.coordinate).coordinates[0][0];

buildingMetadata.extrudedHeight = parseFloat(building.altezza);

buildingMetadata.colorBuilding = Cesium.Color.fromCssColorString(colore);

buildingMetadata.colorRoof = Cesium.Color.fromCssColorString(colore_secondario);

buildingMetadata.coordinateArray = .concat.apply(, buildingMetadata.coordinate);

return buildingMetadata;

}

function createBuilding(code,coordinate,extrudedHeight,colorBuilding,colorRoof,description){

var maxhFlat = ;

var minhFlat = ;

for(var i=0;i<coordinate.length/2;i++){

maxhFlat.push(extrudedHeight);

minhFlat.push(0.0);

}

var buildingModelFlat = viewer.entities.add({

name: code,

description: description,

wall : {

positions : Cesium.Cartesian3.fromDegreesArray(coordinate),

maximumHeights : maxhFlat,

minimumHeights : minhFlat,

outline : true,

material: colorBuilding

},

polygon : {

hierarchy : Cesium.Cartesian3.fromDegreesArray(coordinate),

height : extrudedHeight,

outline : true,

material : colorRoof

}

});

buildingsCollection3D.add(buildingModelFlat);

}

``

The building will be displayed on the coast.

Thank you,

Michele

Hi Michele,

Sorry, I don’t have any good suggestions for you.

Ultimately, the best way for handling large data-sets like this will be to use the new 3D Tiles format. We’re currently developing an implementation on a branch in Cesium. If you would like to know more information, check out this forum post: https://groups.google.com/d/msg/cesium-dev/tCCooBxpZFU/7hxT_E4pGgAJ

Best,

Hannah