Hi,
I’m not sure I explained this too well so I’ve tried to set some examples up in Sandcastle. These have a lot of data in them to try and exaggerate what I’m seeing so they are slow to load.
Each example loads in a lot of regions, sets their colour to change each month and displays some buttons to change the filter, that keeps regions visible.
The first example uses a TimeInterval with a CallbackProperty and this seems smooth enough but surely it is querying the CallbackProperty a lot of times, which won’t be efficient.
HTML Body (button added):
@import url(../templates/bucket.css);
Loading...
``
Javascript:
var viewer = new Cesium.Viewer(‘cesiumContainer’);
// Lock clock to 2016
viewer.clock.currentTime = Cesium.JulianDate.fromIso8601(“2016-01-01”);
viewer.clock.startTime = Cesium.JulianDate.fromIso8601(“2016-01-01”);
viewer.clock.stopTime = Cesium.JulianDate.fromIso8601(“2016-12-31”);
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
viewer.timeline.updateFromClock();
viewer.timeline.zoomTo(viewer.clock.startTime, viewer.clock.stopTime);
// Load regions
var datasource = new Cesium.GeoJsonDataSource(“Regions”);
var topojson = datasource.load(“https://raw.githubusercontent.com/martinjc/UK-GeoJSON/master/json/electoral/eng/topo_wards.json”, {
stroke: Cesium.Color.WHITE
});
var gradientValue = function(value) {
var red = 255;
var green = 255;
if(value < 0.5) {
// 255,0,0>255,255,0
var gRatio = value * 2;
green = 255 * gRatio;
} else {
// 255,255,0>0,255,0
var rRatio = (1.0 - value) * 2;
red = 255 * rRatio;
}
return Cesium.Color.fromBytes(red, green, 0, 128);
};
var filter = 1;
// Add temporal values to entities
topojson.then(function(datasource) {
viewer.dataSources.add(datasource).then(function(datasource) {
datasource.entities.values.forEach(function(entity) {
var values = [
[‘2016-01-01T00:00:00.00Z/2016-02-01T00:00:00.00Z’, Math.random()],
[‘2016-02-01T00:00:00.00Z/2016-03-01T00:00:00.00Z’, Math.random()],
[‘2016-03-01T00:00:00.00Z/2016-04-01T00:00:00.00Z’, Math.random()],
[‘2016-04-01T00:00:00.00Z/2016-05-01T00:00:00.00Z’, Math.random()],
[‘2016-05-01T00:00:00.00Z/2016-06-01T00:00:00.00Z’, Math.random()],
[‘2016-06-01T00:00:00.00Z/2016-07-01T00:00:00.00Z’, Math.random()],
[‘2016-07-01T00:00:00.00Z/2016-08-01T00:00:00.00Z’, Math.random()],
[‘2016-08-01T00:00:00.00Z/2016-09-01T00:00:00.00Z’, Math.random()],
[‘2016-09-01T00:00:00.00Z/2016-10-01T00:00:00.00Z’, Math.random()],
[‘2016-10-01T00:00:00.00Z/2016-11-01T00:00:00.00Z’, Math.random()],
[‘2016-11-01T00:00:00.00Z/2016-12-01T00:00:00.00Z’, Math.random()],
[‘2016-12-01T00:00:00.00Z/2017-01-01T00:00:00.00Z’, Math.random()]
];
var colourProperty = new Cesium.TimeIntervalCollectionProperty();
var showProperty = new Cesium.CompositeProperty();
values.forEach(function(entry) {
colourProperty.intervals.addInterval(Cesium.TimeInterval.fromIso8601({
iso8601: entry[0],
isStartIncluded: true,
isStopIncluded: false,
data: gradientValue(entry[1])
}));
showProperty.intervals.addInterval(Cesium.TimeInterval.fromIso8601({
iso8601: entry[0],
isStartIncluded: true,
isStopIncluded: false,
data: new Cesium.CallbackProperty(function() {
return entry[1] <= filter;
}, false)
}));
});
entity.polygon.material = new Cesium.ColorMaterialProperty(colourProperty);
entity.polygon.outlineColor = colourProperty;
entity.polygon.show = showProperty;
});
});
});
var setx = function(x) {
return function() {
console.log(x);
filter = x / 100;
};
};
var i;
for(i = 0; i !== 110; i += 10) {
var myButton = document.createElement(“input”);
myButton.type = “button”;
myButton.value = i + “%”;
myButton.onclick = setx(i);
document.getElementById(“button”).appendChild(myButton);
}
``
The second example uses a TimeInterval with a ConstantProperty and while this works when going through the timeline, clicking a button to change the filter takes a really long time before it has any effect. I expected this approach to be more efficient because there wouldn’t be a change to the data unless setValue() is called but it seems much less efficient. My guess would be that the setValue() event takes time to propagate up through the TimeIntervals but I didn’t think it would be how it is.
HTML Body (button added):
@import url(../templates/bucket.css);
Loading...
``
Javascript:
var viewer = new Cesium.Viewer(‘cesiumContainer’);
// Lock clock to 2016
viewer.clock.currentTime = Cesium.JulianDate.fromIso8601(“2016-01-01”);
viewer.clock.startTime = Cesium.JulianDate.fromIso8601(“2016-01-01”);
viewer.clock.stopTime = Cesium.JulianDate.fromIso8601(“2016-12-31”);
viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
viewer.timeline.updateFromClock();
viewer.timeline.zoomTo(viewer.clock.startTime, viewer.clock.stopTime);
// Load regions
var datasource = new Cesium.GeoJsonDataSource(“Regions”);
var topojson = datasource.load(“https://raw.githubusercontent.com/martinjc/UK-GeoJSON/master/json/electoral/eng/topo_wards.json”, {
stroke: Cesium.Color.WHITE
});
var gradientValue = function(value) {
var red = 255;
var green = 255;
if(value < 0.5) {
// 255,0,0>255,255,0
var gRatio = value * 2;
green = 255 * gRatio;
} else {
// 255,255,0>0,255,0
var rRatio = (1.0 - value) * 2;
red = 255 * rRatio;
}
return Cesium.Color.fromBytes(red, green, 0, 128);
};
var filterCallbacks = {};
var createShowData = function(value) {
var boundedValue = Math.floor(value * 100);
if(boundedValue in filterCallbacks) {
return filterCallbacks[boundedValue];
} else {
var newCallback = new Cesium.ConstantProperty(true);
filterCallbacks[boundedValue] = newCallback;
return newCallback;
}
};
// Add temporal values to entities
topojson.then(function(datasource) {
viewer.dataSources.add(datasource).then(function(datasource) {
datasource.entities.values.forEach(function(entity) {
var values = [
[‘2016-01-01T00:00:00.00Z/2016-02-01T00:00:00.00Z’, Math.random()],
[‘2016-02-01T00:00:00.00Z/2016-03-01T00:00:00.00Z’, Math.random()],
[‘2016-03-01T00:00:00.00Z/2016-04-01T00:00:00.00Z’, Math.random()],
[‘2016-04-01T00:00:00.00Z/2016-05-01T00:00:00.00Z’, Math.random()],
[‘2016-05-01T00:00:00.00Z/2016-06-01T00:00:00.00Z’, Math.random()],
[‘2016-06-01T00:00:00.00Z/2016-07-01T00:00:00.00Z’, Math.random()],
[‘2016-07-01T00:00:00.00Z/2016-08-01T00:00:00.00Z’, Math.random()],
[‘2016-08-01T00:00:00.00Z/2016-09-01T00:00:00.00Z’, Math.random()],
[‘2016-09-01T00:00:00.00Z/2016-10-01T00:00:00.00Z’, Math.random()],
[‘2016-10-01T00:00:00.00Z/2016-11-01T00:00:00.00Z’, Math.random()],
[‘2016-11-01T00:00:00.00Z/2016-12-01T00:00:00.00Z’, Math.random()],
[‘2016-12-01T00:00:00.00Z/2017-01-01T00:00:00.00Z’, Math.random()]
];
var colourProperty = new Cesium.TimeIntervalCollectionProperty();
var showProperty = new Cesium.CompositeProperty();
values.forEach(function(entry) {
colourProperty.intervals.addInterval(Cesium.TimeInterval.fromIso8601({
iso8601: entry[0],
isStartIncluded: true,
isStopIncluded: false,
data: gradientValue(entry[1])
}));
showProperty.intervals.addInterval(Cesium.TimeInterval.fromIso8601({
iso8601: entry[0],
isStartIncluded: true,
isStopIncluded: false,
data: createShowData(entry[1])
}));
});
entity.polygon.material = new Cesium.ColorMaterialProperty(colourProperty);
entity.polygon.outlineColor = colourProperty;
entity.polygon.show = showProperty;
});
});
});
var setx = function(x) {
return function() {
console.log(x);
Object.keys(filterCallbacks).forEach(function(key) {
filterCallbacks[key].setValue(x >= key);
});
};
};
var i;
for(i = 0; i <= 100; i += 10) {
var myButton = document.createElement(“input”);
myButton.type = “button”;
myButton.value = i + “%”;
myButton.onclick = setx(i);
document.getElementById(“button”).appendChild(myButton);
}
``
So I guess my question is… is that expected behaviour from the ComponentProperty, and is there a better way I can get the same sort of effect?
Matthew