Possible bug in TimeIntervalCollection

So, I’m using a TimeIntervalCollectionPositionProperty for an Entity.

Since I only need the last 10 intervals, after reaching that limit, each added interval, I want to remove the first interval, but once

the first ever interval is removed, subsequent calls to this line won’t remove the first element since it becomes empty

timeIntervalCollection.removeInterval(timeIntervalCollection.get(0)); // Works only once

``

I think that somewhere around here, the interval created wrong, but I don’t get it. Maybe the stop and start times are wrong?

My sandcastle example creates ten intervals and then tries to remove the first until the collection would become empty. But the second interval

becomes empty once the first removed.

Sandcastle code :

var viewer = new Cesium.Viewer(‘cesiumContainer’);

// For the example, I will use 10 intervals

var INTERVALS_LIMIT = 10;

var timeIntervalCollection = new Cesium.TimeIntervalCollection();

var index =0;

// A function to create stub intervals data -

// adds ten intervals, one hour apart of each other.

function initData(){

var now = Cesium.JulianDate.now();

var startTime = new Cesium.JulianDate();

var endTime = new Cesium.JulianDate();

Cesium.JulianDate.addHours(startTime,2,endTime);

// Add 10 intervals, one hour apart of eachother

for (index = 0; index < INTERVALS_LIMIT; index++){

// Notice, the interval duration is two hours, but when the next added,

// all the magic sets stop time of the previous to the start time of the new one.

Cesium.JulianDate.addHours(now, index,startTime);

Cesium.JulianDate.addHours(now,index+2,endTime);

// Create the interval - data is not important

var interval = new Cesium.TimeInterval({

start : startTime,

stop : endTime,

data : Cesium.Cartesian3.fromDegrees(39, -75)

});

// Add the interval to my collection

timeIntervalCollection.addInterval(interval);

}

}

initData();

// Now, after some time in my application, I want to remove the oldest intervals, since they are no longer

for (index = 0; index < INTERVALS_LIMIT; index++){

// Each iteration, I want to remove the first interval

var firstInterval = timeIntervalCollection.get(0);

var isRemoved = timeIntervalCollection.removeInterval(firstInterval);

if (!isRemoved){

console.error("failed to remove at index 0 because the interval’s isEmpty === " + firstInterval.isEmpty );

} else {

console.log("successfully removed leading interval, left : " + timeIntervalCollection.length);

}

}

console.log("expected to be 0, but actual length is " + timeIntervalCollection.length);

``

If something is unclear I can clarify.

Thanks,

Mati

Hello Mati,

This isn’t how removeInterval is supposed to work. It’s meant to eliminate an interval of time from the collection, and that interval doesn’t necessarily have to be one of the intervals in the collection. removeInterval will change the start and stop values of the intervals in the collection such that none of them include the interval removed.

Instead, you should keep a separate array of intervals you added to keep track of what you want to remove.

Best,

Hannah

Hey Hanna, thanks for making this clear, however something else now behaves strange to me.

So let’s I have these intervals ( [start–stop] ) :

[0–1][1–2][2–3][3–4][4–5]

at some point I want to delete the first 3, so I call removeInterval with a new TimeInterval like this [0–3] to overlap the whole first 3 intervals, and

the whole collection is emptied. I see that there’s a while loop that removing overlapping intervals, however nothing updates the instance of

indexInterval, so it refers always to the first instance ever, even after it was removed :

https://github.com/AnalyticalGraphicsInc/cesium/blob/1.18/Source/Core/TimeIntervalCollection.js#L528

// Remove any intervals that are completely overlapped by the input interval.
while (index < intervals.length &&

JulianDate.greaterThan(intervalStop, indexInterval.stop)) {

result = true;

intervals.splice(index, 1);

}

``

Should you update indexInterval to the new interval at the end of that loop? Something like

// Remove any intervals that are completely overlapped by the input interval.
while (index < intervals.length &&

JulianDate.greaterThan(intervalStop, indexInterval.stop)) {

result = true;

intervals.splice(index, 1);
indexInterval = interval[index];

}

``

Here’s my updated sandcastle example

var viewer = new Cesium.Viewer(‘cesiumContainer’);

// For the example, I will use 10 intervals

var INTERVALS_LIMIT = 10;

var timeIntervalCollection = new Cesium.TimeIntervalCollection();

var index =0;

// A function to create stub intervals data -

// adds ten intervals, one hour apart of each other.

function initData(){

var now = Cesium.JulianDate.now();

var startTime = new Cesium.JulianDate();

var endTime = new Cesium.JulianDate();

Cesium.JulianDate.addHours(startTime,2,endTime);

// Add 10 intervals, one hour apart of eachother

for (index = 0; index < INTERVALS_LIMIT; index++){

// Notice, the interval duration is two hours, but when the next added,

// all the magic sets stop time of the previous to the start time of the new one.

Cesium.JulianDate.addHours(now, index,startTime);

Cesium.JulianDate.addHours(now,index+2,endTime);

// Create the interval - data is not important

var interval = new Cesium.TimeInterval({

start : startTime,

stop : endTime,

data : Cesium.Cartesian3.fromDegrees(39, -75)

});

// Add the interval to my collection

timeIntervalCollection.addInterval(interval);

}

}

function removeInterval(num){

debugger;

var firstInterval = timeIntervalCollection.get(0);

var lastInterval = timeIntervalCollection.get(num - 1);



var interval = new Cesium.TimeInterval({

    start : firstInterval.start,

    stop : lastInterval.stop

});



timeIntervalCollection.removeInterval(interval);

}

initData();

removeInterval(3);

console.log(timeIntervalCollection.length);

``

I’ve added a function removeInterval(num) that should take the start time of the first interval and the stop time of the interval at given index and trim the collection until then, but

the result is that the whole collection is emptied due to that while loop.

Hmm, yeah, that loop does look a little suspect. I’ll take a closer look at it and get back to you.

Thanks,

Hannah

Hannah - you may also want to compare the Cesium implementation against the implementation in STK Components, which should be correct. It’s possible an error was introduced when it was originally ported to JavaScript.

Hi Mati,

I finally had a chance to look into this, and you were right. There was a line missing from this code.

I submitted a fix here: https://github.com/AnalyticalGraphicsInc/cesium/pull/3660

Thanks for digging into the code and finding this! I’m surprised it didn’t come up as an issue before now.

Best,

Hannah

Thanks Hannah!
I was happy to help

בתאריך 2 במרץ 2016 21:04,‏ “Hannah Pinkos” pinkos.hannah@gmail.com כתב: