Best way of visualizing 4D data in Cesium?

Hi all,

I am working on a project of creating an interface to visualize spatio-temporal data.
I have hourly data for buildings in different areas for a whole year, meaning 8760 data! and these are Postgis data.
I initially converted 3D data to GeoJSON to be viewed in Cesium, but now with the 4D it is too much and doesn't seem to work

Would CZML be a better choice? and is there a way to convert to it from postgis data through Python libraries?
or are there better alternatives?

Thank you
Ayah

Hi Ayah,

CZML is an excellent choice for storing time-dynamic spatial data! That in fact was one of its main design considerations. Here’s a nice example: http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=CZML%20Point%20-%20Time%20Dynamic.html&label=CZML

For more info on CZML, see here: https://github.com/AnalyticalGraphicsInc/czml-writer/wiki/CZML-Guide

As for writing CZML, here’s a nice open source project that a community member was kind enough to share: https://github.com/cleder/czml

Hope that helps,

  • Rachel

Hi Rachel,

Thank you for the reply, but my problem is that all czml data are of position changing properties, my data is attribute changing, Buildings with different values of energy every hour, could it be set to take values from the attributes information of the czml and connect colors to those values with the timeslider?

thank you
-Ayah

Ayah,

I’m not entirely sure of all the properties that can be time dynamic in CZML, but I know that you can make color properties time
dynamic in CZML. I use this with points, and it looks like this:

“color”: {“epoch”: “2017-07-30T13:41:39.649Z”,
“rgba”: [0.000,171.000,217.000,233.000,255.000,
56.502,171.000,217.000,233.000,255.000,
58.252,116.000,173.000,209.000,255.000]
}

The values are as follows: seconds since epoch, red, green, blue, alpha. Each color represents a range of values for precipitation rate or brightness temperature. This might be useful for your purposes?

Hi Matt,

Thank you, I think I need to explain my question further.
The color values should not only depend on the time (seconds since the epoch), but it should depend on the value of energy which the time has in the attribute data, does that make sense?

example:

at 3:00am of 20-07-2017 the energy value for the building is 49watt
at 4:00am of 20-07-2017 the energy value for the building is 30watt

so the color should change from e.g. light green to green.
same settings for all features in the dataset as well.

because what I understand from your code is that
from 0.00 to 56.502 the color will be 171.000,217.000,233.000,255.000. is that correct?

Thank you again, I'm really stuck -_-

-Ayah

Ayah,

I guess I should have clarified that my colors are representative of
a value (in my case, precipitation rate). You could come up with a color scale that lines up with the energy values, and then when you are generating your CZML files, represent those changes in energy values with changes in color - for example:

“color”: {“epoch”: “2017-07-20T03:00:00Z”,

      "rgba": [0.000,0.000,255.000,0.000,

255.000,

               3600.000,0.000,155.000,0.000,255.000]

     }

In this case, at 3am, you have a lighter green color for the building, which represents 49 watts, and at 4am (3600 seconds later), you have a darker green color for the building, which represents 30 watts.

Note that this will by default linearly interpolate colors between the two as time passes. If you want hard breaks between colors, I think you’re supposed to use “interval” notation in CZML:

“color”: [{“interval”: “2017-07-20T03:00:00Z/04:00:00Z”,

       "rgba": [0.000,255.000,0.000,255.000]

      },

      {"interval": "2017-07-20T04:00:00Z/05:00:00Z",

       "rgba": [0.000,155.000,0.000,255.000]

     ]

I am sure that you can create a custom property in CZML for the energy value, but then I think you’d have to write some further code to convert the changes in that value to a color, while just generating your
CZML files based on pre-converting values to colors seems much easier. One final note: if you still want to include the energy values, you can put them in the “description” field of the CZML entities, which is a time-dynamic property and can be tied to intervals like color or position.

Matt,

Thank you, and I'm sorry to be asking so frequently.
I understood what you meant, but still that does not serve my purpose.
an example of my data:
"hour_1" : 0.0, "hour_2" : 0.0, "hour_3" : 0.0, "hour_4" : 0.0, "hour_5" : 0.0, "hour_6" : 0.0, "hour_7" : 0.0, "hour_8" : 0.0, "hour_9" : 1.0, "hour_10" : 29.1265, "hour_11" : 55.0334, "hour_12" : 68.0527

(Where Hour_1 : is the epoch 0.0000 - 3600.00
and the number following is the value of energy)

So I need, lets say, "a condition", that reads the value for each hour and then assigns the color accordingly. because the values are constantly set with time.

is that possible?

Thank you for your time.

Hi there,

Yes, it’s definitely possible with the Entity Property system. Check out http://cesiumjs.org/Cesium/Apps/Sandcastle/index.html?src=Hello%20World.html&label=Showcases&gist=de4e010c54af2141b74665c42117ee2c

Hope that helps,

  • Rachel

Hi,

So I have finally been able to write a python script to extract czml data!
and everything is okay ... except that I need to customize it now within JavaScript.
a sample of my czml :
[{
"id" : "document",
"version" : "1.0"
},
{
"id" : 32,
"availability":"2014-01-01T00:00:00Z/2014-12-31T00:00:00Z",
"polygon" : {
"positions" : {
"cartographicDegrees" : [ 54.7162360431897, 24.4519912715277, 0 , 54.716219612921, 24.4519754832587, 0 , 54.7162501395131, 24.4519488635358, 0 , 54.7162465684811, 24.4519454316688, 0 , 54.7162670831639, 24.4519275432238, 0 , 54.7162707308589, 24.4519310439514, 0 , 54.7163022563025, 24.4519035537608, 0 , 54.7161962974502, 24.4518018819532, 0 , 54.7161647729823, 24.4518293730395, 0 , 54.7161875723132, 24.4518512505868, 0 , 54.7161671187314, 24.4518690866852, 0 , 54.716160270381, 24.4518625054177, 0 , 54.7161297437778, 24.4518891260253, 0 , 54.7161143478115, 24.4518743319037, 0 , 54.7160818585064, 24.4519026632471, 0 , 54.7161310319716, 24.4519499143818, 0 , 54.716123259296, 24.4519566926509, 0 , 54.7161418802557, 24.4519745857322, 0 , 54.7161496529153, 24.4519678083645, 0 , 54.7162035538772, 24.4520196028966, 0 , 54.7162360431897, 24.4519912715277, 0
]
},
"someProperty" : [
{
"interval" : "2014-00-01T00:00:00Z/2014-01-01T00:00:00Z",
"En_C_need" : 0.7
}, {
"interval" : "2014-01-01T00:00:00Z/2014-02-01T00:00:00Z",
"En_C_need" : 1.0
}, {
"interval" : "2014-02-01T00:00:00Z/2014-03-01T00:00:00Z",
"En_C_need" : 2.6
}, {
"interval" : "2014-03-01T00:00:00Z/2014-04-01T00:00:00Z",
"En_C_need" : 12.1
}, {
"interval" : "2014-04-01T00:00:00Z/2014-05-01T00:00:00Z",
"En_C_need" : 30.2
}, {
"interval" : "2014-05-01T00:00:00Z/2014-06-01T00:00:00Z",
"En_C_need" : 37.8
}, {
"interval" : "2014-06-01T00:00:00Z/2014-07-01T00:00:00Z",
"En_C_need" : 44.0
}],"extrudedHeight" : 6.0}
}]

I have almost 7190 packets like that one

My code:

var test2 = Cesium.CzmlDataSource.load ('Data/czml/example_8.czml');
  
  test2.then(function (dataSource) {
    viewer.dataSources.add(test2);
    viewer.zoomTo (test2);
  var entities = dataSource.entities.values; //extracting the entities from the attribute table
  
        var colorHash = {};
        var Energy = ;
        for (var i = 0; i < entities.length; i++) {
            var entity = entities[i];
            Energy = entity.someProperty.En_C_need;
      var color = colorHash [Energy];
      if(!color ) {
        if (Energy < 5 ) {
        color = Cesium.Color.DARKSALMON.withAlpha (0.95);
      } else if (Energy < 10) {
                    color = Cesium.Color.BURLYWOOD.withAlpha (0.95);
      } else if (Energy < 20) {
                    color = Cesium.Color.PINK.withAlpha (0.95);
      } else {
                    color = Cesium.Color.PINK.withAlpha (0.95);
      };
      colorHash[Energy] = color;
      };
      entity.polygon.fill = true;
            entity.polygon.material = color;
            entity.polygon.outline = false;
    };
});

Is there anyway I could make this work?
I mean change the color of the building by extracting the En_C_need (which refers to the Energy_Cooling_Need).

Thank you

Hi,

To get the property value, you’ll need to use Property.getValue() (https://cesiumjs.org/Cesium/Build/Documentation/Property.html?classFilter=property#getValue) and pass it a JulianDate time object at the time you want to evaluate.

Thanks,

Gabby

Hi Gabby,

Do you mean that the color cannot change dynamically? I should only specify a certain time that I want to be evaluated?
is there a way to get a viewer.clock.currentTime variable that really changes and retrieves a new value on the fly?

to be clear, here is the code I have now, It only takes the first time interval of the datasource. I was able to extrude building heights with time...
can't I change color too?

for (var i = 0; i < dataSource.entities.values.length; i++) {
    var entity = dataSource.entities.values[i];
    //console.log (entity);
    //var New = dataSource.entities.getById(entity.id);
    // console.log (viewer.clock.currentTime);
    var time = Cesium.JulianDate.addSeconds(new Cesium.JulianDate());
    Energy = entity.properties.getValue(viewer.clock.currentTime).energy_intervals.Value;
    // console.info (Energy);
    var color = colorHash[Energy];
    //console.info('#1 ', color);
    if (!color) {
        if (Energy < 1.0) {
            color = Cesium.Color.PINK.withAlpha(0.95);
            console.log('##');
        } else if (Energy < 15) {
            color = Cesium.Color.BURLYWOOD.withAlpha(0.95);
            console.log('###');
        } else if (Energy < 21) {
            color = Cesium.Color.RED.withAlpha(0.95);
        } else {
            color = Cesium.Color.HOTPINK.withAlpha(0.95);
        };
        //console.info('#2 ',color);
        colorHash[Energy] = color;
    };
    //New.polygon.extrudedHeight = Energy;
    entity.polygon.fill = true;
    entity.polygon.material = color;
    entity.polygon.outline = false;

};

Hi,

If I understand what you need correctly, you can use a CallbackProperty. See this sandcastle example, starting at line 93. It will update that value accordingly over time based on the property value.

Thanks,

Gabby

Thank you very much.