CesiumGS / cesium

An open-source JavaScript library for world-class 3D globes and maps :earth_americas:
https://cesium.com/cesiumjs/
Apache License 2.0
12.86k stars 3.47k forks source link

Extend Sytling to allow check for existing of a property #4637

Open SunBlack opened 7 years ago

SunBlack commented 7 years ago

Currenlty you have to make sure a property exists if you use it in Cesium3DTileStyle. But if you have a generic UI sometimes you don't know if a Tileset as has property, because its depend on conent of each tile.

So following code can cause a crash if MYPORPERTY does not exists:

    var tileset = new Cesium3DTileset({url : 'data'});
    tileset.style = new Cesium3DTileStyle({
        "color" : {
            "conditions" : [
                ["(${MYPORPERTY} === 0)", "rgb(196, 196, 196)"],
                ["(${MYPORPERTY} === 1)", "rgb(128, 128, 128)"],
                ["true", "rgb(255, 255, 255)"],
            ]
        }
    });

So it would be nice if you could write something like this:

    var tileset = new Cesium3DTileset({url : 'data'});
    tileset.style = new Cesium3DTileStyle({
        "color" : {
            "conditions" : [
                ["(defined(${MYPORPERTY}) && ${MYPORPERTY} === 0)", "rgb(196, 196, 196)"],
                ["(defined(${MYPORPERTY}) && ${MYPORPERTY} === 1)", "rgb(128, 128, 128)"],
                ["true", "rgb(255, 255, 255)"],
            ]
        }
    });

In case this is to complex another suggestion would be to extent it to

var tileset = new Cesium3DTileset({url : 'data'});
tileset.style = new Cesium3DTileStyle({
    "color" : [
        {
            "required_properties" : [
                "MYPORPERTY", "MYPORPERTY2", 
            ],
            "conditions" : [
                ["(${MYPORPERTY} === 0 && ${MYPORPERTY2} === 0)", "rgb(196, 196, 196)"],
                ["(${MYPORPERTY} === 0 && ${MYPORPERTY2} === 1)", "rgb(164, 164, 164)"],
                ["(${MYPORPERTY} === 1 && ${MYPORPERTY2} === 0)", "rgb(128, 128, 128)"],
                ["(${MYPORPERTY} === 1 && ${MYPORPERTY2} === 1)", "rgb(92, 92, 92)"],
                ["true", "rgb(255, 255, 255)"],
            ],
        },
        {
            "required_properties" : [
                "MYPORPERTY"
            ],
            "conditions" : [
                ["(${MYPORPERTY} === 0)", "rgb(196, 196, 196)"],
                ["(${MYPORPERTY} === 1)", "rgb(128, 128, 128)"],
                ["true", "rgb(255, 255, 255)"],
            ],
        },
        {
            "rgb(255, 255, 255)"
        }
    }
});
lilleyse commented 7 years ago

Yes this is a good point for the point cloud styling engine, which won't work if a style references a non-existent property. We should be smarter about detecting non-existent properties ahead of time.

Adding defined may not be needed since {MYPORPERTY} !== undefined is valid. It might be a good idea though.

pjcozzi commented 7 years ago

CC #3241

Also added link from https://github.com/AnalyticalGraphicsInc/3d-tiles/issues/140 where it is suggested that undefined may be able to evaluate to 0 or false with the GLSL backend.

VolodKu commented 4 years ago

So what is the solution for this case? It shows error below Error generating style shader: undefined is not supported.

VolodKu commented 4 years ago

Before applying how can I check with undefined? If you can provide, it's much appreciated. Thanks