CZML dynamic interpolation

150 views
Skip to first unread message

andrea...@gmail.com

unread,
Feb 1, 2019, 12:49:37 PM2/1/19
to cesium-dev
Hello!

We have a live data feed which creates CZML and feeds the globe.
Each data point is created with interpolation set to LINEAR, but we would like to disable the interpolation when the data points are, let's say, more than 1 hour separated from each other.

We've thought on using 'availability' to solve this, but it will not work because the feed may not send the data points sorted and also does not have the knowledge of the full picture (it's live data).

We are currently thinking on a solution which would evaluate each new point on a CzmlDataSource updater by getting its neighbors and disable, or not, accordingly to their time delta:
- if the data points delta it's bigger than 1 hour do not interpolate
- else use interpolation

The question is: is it possible to, efficiently, get the next and previous data point of an entity at a given time and change the interpolation value?

Many Thanks
Regards,

andrea...@gmail.com

unread,
Feb 5, 2019, 8:51:56 AM2/5/19
to cesium-dev
I meant 'interval' not availability.

Can anyone help with this one?
What I only need is to get the next and previous Property at a given moment.

Regards.

Omar Shehata

unread,
Feb 11, 2019, 9:35:50 AM2/11/19
to cesium-dev
Cesium doesn't hold onto the packets so unless you're keeping track of them yourself I don't think there'd be a way to do that.

Just to make sure I understand, what you're trying to do is push updates to an entity's position (using something like SampledProperty?) but once a new update comes in, if it's been more than hour since the last, don't interpolate, start a new "segment" of the entity's path.

If so, you should be able to do this with the TimeIntervalCollection property whose intervals contain SampledProperty instances. So you would be pushing positions into the current SampledProperty, unless a new updates comes in after an hour, in which case you would start a new interval and push that into the collection. This new interval would end at infinity and start at the new data point. This way, a single Entity instance can store multiple segments that aren't interpolated in between.

Another way to do this would be to create multiple entities instead of re-using the same entity and show/hide the appropriate one. 

Let me know if that helps. It might also be helpful to put together a simple Sandcastle of how you have your entity/update step setup that I can look at to see if there's an easier way to do this as well. 

andrea...@gmail.com

unread,
Feb 11, 2019, 12:28:11 PM2/11/19
to cesium-dev
Thanks for the reply!

Yes that's it, but there's an extra catch: the data will not be sorted on receive. This means that I need to rebuild the related SampledProperties accordingly.

Anyway, regarding your suggestion, you mean TimeIntervalCollectionProperty right? And what do you mean by "current SampledProperty"?
Can I get an existing SampledProperty by time, I mean, get the "nearest" SampledProperty on a given moment so I can decide what to do with the received position?

Thanks again,
Message has been deleted

andrea...@gmail.com

unread,
Feb 12, 2019, 4:59:52 AM2/12/19
to cesium-dev
Hi again,

I am not being able to use SampledPositionProperty on TimeIntervalCollectionPositionProperty. It let me add, but then it fails when retrieving the value.

here's my code:
<code>

entity.position = new Cesium.TimeIntervalCollectionPositionProperty();

var samplePositionProperty = new Cesium.SampledPositionProperty();
samplePositionProperty.setInterpolationOptions({
interpolationDegree : 1,
interpolationAlgorithm : Cesium.LinearApproximation
});
samplePositionProperty.backwardExtrapolationType = Cesium.ExtrapolationType.HOLD;
samplePositionProperty.forwardExtrapolationType = Cesium.ExtrapolationType.HOLD;

samplePositionProperty.addSample(timeJulianDate, positionCartesian3);

var stop = new Cesium.JulianDate();
stop = Cesium.JulianDate.addHours(timeJulianDate, 1, stop);
var timeInterval = new Cesium.TimeInterval({
start : timeJulianDate,
stop : stop,
isStartIncluded : false,
isStopIncluded : false,
data : samplePositionProperty
});
entity.position.intervals.addInterval(timeInterval);
</code>

Cesium seems to expect a Cartesian3 on data, not a SampledProperty.
Here's the error:
<code>
Cesium.js:243802 An error occurred while rendering. Rendering has stopped.
undefined
DeveloperError: Expected value to be typeof number, actual typeof was undefined
Error
at new DeveloperError (http://localhost:8080/GeoC2/libs/cesium_unminified/Cesium.js:540:19)
at Object.Check.typeOf.number (http://localhost:8080/GeoC2/libs/cesium_unminified/Cesium.js:1793:19)
at Function.EncodedCartesian3.encode (http://localhost:8080/GeoC2/libs/cesium_unminified/Cesium.js:39390:30)
at Function.EncodedCartesian3.fromCartesian (http://localhost:8080/GeoC2/libs/cesium_unminified/Cesium.js:39443:27)
at writePositionSizeAndOutline (http://localhost:8080/GeoC2/libs/cesium_unminified/Cesium.js:123245:27)
at writePointPrimitive (http://localhost:8080/GeoC2/libs/cesium_unminified/Cesium.js:123391:9)
at PointPrimitiveCollection.update (http://localhost:8080/GeoC2/libs/cesium_unminified/Cesium.js:123505:21)
at EntityCluster.update (http://localhost:8080/GeoC2/libs/cesium_unminified/Cesium.js:124764:35)
at PrimitiveCollection.update (http://localhost:8080/GeoC2/libs/cesium_unminified/Cesium.js:131873:27)
at PrimitiveCollection.update (http://localhost:8080/GeoC2/libs/cesium_unminified/Cesium.js:131873:27)
</code>

Omar Shehata

unread,
Feb 13, 2019, 3:34:11 PM2/13/19
to cesium-dev
My bad, it looks like TimeIntervalCollectionPositionProperty does indeed expect the data to be Cartesian3. Using CompositePositionProperty instead will allow you to compose properties this way.

Here's a Sandcastle example I just put together to test this.
Reply all
Reply to author
Forward
0 new messages