Styling a 3D CityGML tileset

Hi everybody,

I am quite new to developing web maps with HTML/Javascript and Cesium ION, so sorry if what I ask sounds too easy.

I am trying to define a function that would take an attribute of my CityGML 3D data and color my buildings according to classes defined based on this attribute.
The problem is not all my buildings have this attribute, some of them are missing it. As a result, when I check the type of this attribute I get “number” for those buildings that have the attribute and “object” for those that do not have it (value is “null” in this case). The function that I defined is not working I think exactly because of this, so my thinking was to include a condition to exclude the objects with no attribute. How could I do this?

I have tried a compound condition, but it also does not do anything.

This is what the console returns for the attribute that I am using:


That is what I initially tried:

> function styleByStromBedarf() {
> = new Cesium.Cesium3DTileStyle ({
>           color: {            
>             conditions: [
>                 ["${Strom Gesamtbedarf} >= 200000", "color('purple')"],
>                 ["${Strom Gesamtbedarf} >= 100000", "color('red')"],
>                 ["${Strom Gesamtbedarf} >= 50000", "color('cyan')"],
>                 ["${Strom Gesamtbedarf} < 10000", "color('yellow')"]
>             ]} 
>     });
> }

That would be with the compound condition that also does not work, nothing happens:

function styleByStromBedarf() { = new Cesium.Cesium3DTileStyle ({
          show : "${Strom Gesamtbedarf} !== null",
          color: {            
            conditions: [
                ["(${Strom Gesamtbedarf} !== null) && (${Strom Gesamtbedarf} >= 200000)", "color('purple')"],
                ["(${Strom Gesamtbedarf} !== null) && (${Strom Gesamtbedarf} >= 100000)", "color('red')"],
                ["(${Strom Gesamtbedarf} !== null) && (${Strom Gesamtbedarf} >= 50000)", "color('cyan')"],
                ["(${Strom Gesamtbedarf} !== null) && (${Strom Gesamtbedarf} < 10000)", "color('yellow')"]

Many thanks for your ideas.


Welcome to the Cesium community! And not at all - we very recently ran into this problem just a few months ago. You’ll find some discussion of this issue here:

It has a few suggestions there. Like you can check for “null” as your first condition, like this:

['${Year} === null', 'color("blue")'],
['${Year} === undefined', 'color("blue")'],
['${Year} <= 50', 'color("purple", 0.5)'],
['true', 'color("blue")']

Let me know if this helps.

1 Like

Hey there,

Some time ago you (Omar) mentioned in a solution to 3D tileset styling;

[…] you can check for “null” as your first condition, like this:

['${Year} === null', 'color("blue")'],
['${Year} === undefined', 'color("blue")'],
['${Year} <= 50', 'color("purple", 0.5)'],
['true', 'color("blue")']

What’s the current state for something similar for pointclouds? We’re currently doing pre-processing and metadata in seperate files for testing if pointclouds have properties, and there’s some older threads that talks about updates to the rendering engine that would help us supress Cesium exploding if a property wasn’t in a pointcloud?



@Alexander_Johannesen the latest update is here ( which was actually the discussion from the thread you brought up, that for point clouds there only workaround right now is to extract the properties from the tile payload itself to determine if the properties exist before applying the style.


Thanks for that. So there’s no way around it at the moment, apart from backend snooping. Are there any plans for those property exposures mentioned in that thread? Or if the underlying engine at some point will support null/undefined?



I think we definitely want to support this - it’s just a question of whether the right approach here is to expose a way to get the defined properties in a tile (which may not be ideal since one tile may be missing some properties that causes the style to crash), or whether the 3D Tileset itself can have this metadata.

This is all to work around the fact that the GLSL backend that allows for efficiently styling millions of points at runtime doesn’t support undefined checks. This may be something that can be supported when moving to WebGL 2 but I’m not sure.

1 Like