Skip to content

Commit

Permalink
Add syntax to to delete data from properties via CZML.
Browse files Browse the repository at this point in the history
Specifying delete: true for any property will delete data for that property, depending on the type of property, for the specified interval (or if no interval is specified, then for all time).

This deletes samples for sampled properties, or removes intervals for interval properties.
  • Loading branch information
shunter committed May 6, 2019
1 parent a35f010 commit 2a46171
Show file tree
Hide file tree
Showing 3 changed files with 757 additions and 151 deletions.
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ Change Log

##### Additions :tada:
* Added support for new `BingMapsStyle` values `ROAD_ON_DEMAND` and `AERIAL_WITH_LABELS_ON_DEMAND`. The older versions of these, `ROAD` and `AERIAL_WITH_LABELS`, have been deprecated by Bing. [#7808](https://github.com/AnalyticalGraphicsInc/cesium/pull/7808)
* Added syntax to delete data from existing properties via CZML. [#7818](https://github.com/AnalyticalGraphicsInc/cesium/pull/7818)

### 1.57 - 2019-05-01

Expand Down
165 changes: 116 additions & 49 deletions Source/DataSources/CzmlDataSource.js
Original file line number Diff line number Diff line change
Expand Up @@ -671,7 +671,6 @@ define([
}

var packedLength;
var isSampled;
var unwrappedInterval;
var unwrappedIntervalLength;

Expand All @@ -684,18 +683,31 @@ define([
var isValue = !defined(packetData.reference) && !defined(packetData.velocityReference);
var hasInterval = defined(combinedInterval) && !combinedInterval.equals(Iso8601.MAXIMUM_INTERVAL);

if (packetData.delete === true) {
// If deleting this property for all time, we can simply set to undefined and return.
if (!hasInterval) {
object[propertyName] = undefined;
return;
}

// Deleting depends on the type of property we have.
return removePropertyData(object[propertyName], combinedInterval);
}

var isSampled = false;

if (isValue) {
unwrappedInterval = unwrapInterval(type, packetData, sourceUri);
packedLength = defaultValue(type.packedLength, 1);
unwrappedIntervalLength = defaultValue(unwrappedInterval.length, 1);
isSampled = !defined(packetData.array) && (typeof unwrappedInterval !== 'string') && (unwrappedIntervalLength > packedLength) && (type !== Object);
}

//Rotation is a special case because it represents a native type (Number)
//and therefore does not need to be unpacked when loaded as a constant value.
// Rotation is a special case because it represents a native type (Number)
// and therefore does not need to be unpacked when loaded as a constant value.
var needsUnpacking = typeof type.unpack === 'function' && type !== Rotation;

//Any time a constant value is assigned, it completely blows away anything else.
// Any time a constant value is assigned, it completely blows away anything else.
if (!isSampled && !hasInterval) {
if (isValue) {
object[propertyName] = new ConstantProperty(needsUnpacking ? type.unpack(unwrappedInterval, 0) : unwrappedInterval);
Expand All @@ -713,8 +725,8 @@ define([
epoch = JulianDate.fromIso8601(packetEpoch);
}

//Without an interval, any sampled value is infinite, meaning it completely
//replaces any non-sampled property that may exist.
// Without an interval, any sampled value is infinite, meaning it completely
// replaces any non-sampled property that may exist.
if (isSampled && !hasInterval) {
if (!(property instanceof SampledProperty)) {
property = new SampledProperty(type);
Expand All @@ -727,19 +739,19 @@ define([

var interval;

//A constant value with an interval is normally part of a TimeIntervalCollection,
//However, if the current property is not a time-interval collection, we need
//to turn it into a Composite, preserving the old data with the new interval.
// A constant value with an interval is normally part of a TimeIntervalCollection,
// However, if the current property is not a time-interval collection, we need
// to turn it into a Composite, preserving the old data with the new interval.
if (!isSampled && hasInterval) {
//Create a new interval for the constant value.
// Create a new interval for the constant value.
combinedInterval = combinedInterval.clone();
if (isValue) {
combinedInterval.data = needsUnpacking ? type.unpack(unwrappedInterval, 0) : unwrappedInterval;
} else {
combinedInterval.data = createSpecializedProperty(type, entityCollection, packetData);
}

//If no property exists, simply use a new interval collection
// If no property exists, simply use a new interval collection
if (!defined(property)) {
if (isValue) {
property = new TimeIntervalCollectionProperty();
Expand All @@ -750,29 +762,28 @@ define([
}

if (isValue && property instanceof TimeIntervalCollectionProperty) {
//If we create a collection, or it already existed, use it.
// If we create a collection, or it already existed, use it.
property.intervals.addInterval(combinedInterval);
} else if (property instanceof CompositeProperty) {
//If the collection was already a CompositeProperty, use it.
// If the collection was already a CompositeProperty, use it.
if (isValue) {
combinedInterval.data = new ConstantProperty(combinedInterval.data);
}
property.intervals.addInterval(combinedInterval);
} else {
//Otherwise, create a CompositeProperty but preserve the existing data.

//Put the old property in an infinite interval.
// Otherwise, create a CompositeProperty but preserve the existing data.
// Put the old property in an infinite interval.
interval = Iso8601.MAXIMUM_INTERVAL.clone();
interval.data = property;

//Create the composite.
// Create the composite.
property = new CompositeProperty();
object[propertyName] = property;

//add the old property interval
// Add the old property interval.
property.intervals.addInterval(interval);

//Change the new data to a ConstantProperty and add it.
// Change the new data to a ConstantProperty and add it.
if (isValue) {
combinedInterval.data = new ConstantProperty(combinedInterval.data);
}
Expand All @@ -788,25 +799,25 @@ define([
object[propertyName] = property;
}

//create a CompositeProperty but preserve the existing data.
// Create a CompositeProperty but preserve the existing data.
if (!(property instanceof CompositeProperty)) {
//Put the old property in an infinite interval.
// Put the old property in an infinite interval.
interval = Iso8601.MAXIMUM_INTERVAL.clone();
interval.data = property;

//Create the composite.
// Create the composite.
property = new CompositeProperty();
object[propertyName] = property;

//add the old property interval
// Add the old property interval.
property.intervals.addInterval(interval);
}

//Check if the interval already exists in the composite
// Check if the interval already exists in the composite.
var intervals = property.intervals;
interval = intervals.findInterval(combinedInterval);
if (!defined(interval) || !(interval.data instanceof SampledProperty)) {
//If not, create a SampledProperty for it.
// If not, create a SampledProperty for it.
interval = combinedInterval.clone();
interval.data = new SampledProperty(type);
intervals.addInterval(interval);
Expand All @@ -815,6 +826,28 @@ define([
updateInterpolationSettings(packetData, interval.data);
}

function removePropertyData(property, interval) {
if (property instanceof SampledProperty) {
property.removeSamples(interval);
return;
} else if (property instanceof TimeIntervalCollectionProperty) {
property.intervals.removeInterval(interval);
return;
} else if (property instanceof CompositeProperty) {
var intervals = property.intervals;
for (var i = 0; i < intervals.length; ++i) {
var intersection = TimeInterval.intersect(intervals.get(i), interval, scratchTimeInterval);
if (!intersection.isEmpty) {
// remove data from the contained properties
removePropertyData(intersection.data, interval);
}
}
// remove the intervals from the composite
intervals.removeInterval(interval);
return;
}
}

function processPacketData(type, object, propertyName, packetData, interval, sourceUri, entityCollection) {
if (!defined(packetData)) {
return;
Expand Down Expand Up @@ -842,15 +875,27 @@ define([
combinedInterval = constrainedInterval;
}

var referenceFrame;
var unwrappedInterval;
var isSampled = false;
var unwrappedIntervalLength;
var numberOfDerivatives = defined(packetData.cartesianVelocity) ? 1 : 0;
var packedLength = Cartesian3.packedLength * (numberOfDerivatives + 1);
var unwrappedInterval;
var unwrappedIntervalLength;
var isValue = !defined(packetData.reference);
var hasInterval = defined(combinedInterval) && !combinedInterval.equals(Iso8601.MAXIMUM_INTERVAL);

if (packetData.delete === true) {
// If deleting this property for all time, we can simply set to undefined and return.
if (!hasInterval) {
object[propertyName] = undefined;
return;
}

// Deleting depends on the type of property we have.
return removePositionPropertyData(object[propertyName], combinedInterval);
}

var referenceFrame;
var isSampled = false;

if (isValue) {
if (defined(packetData.referenceFrame)) {
referenceFrame = ReferenceFrame[packetData.referenceFrame];
Expand All @@ -861,7 +906,7 @@ define([
isSampled = unwrappedIntervalLength > packedLength;
}

//Any time a constant value is assigned, it completely blows away anything else.
// Any time a constant value is assigned, it completely blows away anything else.
if (!isSampled && !hasInterval) {
if (isValue) {
object[propertyName] = new ConstantPositionProperty(Cartesian3.unpack(unwrappedInterval), referenceFrame);
Expand All @@ -879,8 +924,8 @@ define([
epoch = JulianDate.fromIso8601(packetEpoch);
}

//Without an interval, any sampled value is infinite, meaning it completely
//replaces any non-sampled property that may exist.
// Without an interval, any sampled value is infinite, meaning it completely
// replaces any non-sampled property that may exist.
if (isSampled && !hasInterval) {
if (!(property instanceof SampledPositionProperty) || (defined(referenceFrame) && property.referenceFrame !== referenceFrame)) {
property = new SampledPositionProperty(referenceFrame, numberOfDerivatives);
Expand All @@ -893,19 +938,19 @@ define([

var interval;

//A constant value with an interval is normally part of a TimeIntervalCollection,
//However, if the current property is not a time-interval collection, we need
//to turn it into a Composite, preserving the old data with the new interval.
// A constant value with an interval is normally part of a TimeIntervalCollection,
// However, if the current property is not a time-interval collection, we need
// to turn it into a Composite, preserving the old data with the new interval.
if (!isSampled && hasInterval) {
//Create a new interval for the constant value.
// Create a new interval for the constant value.
combinedInterval = combinedInterval.clone();
if (isValue) {
combinedInterval.data = Cartesian3.unpack(unwrappedInterval);
} else {
combinedInterval.data = createReferenceProperty(entityCollection, packetData.reference);
}

//If no property exists, simply use a new interval collection
// If no property exists, simply use a new interval collection
if (!defined(property)) {
if (isValue) {
property = new TimeIntervalCollectionPositionProperty(referenceFrame);
Expand All @@ -916,29 +961,29 @@ define([
}

if (isValue && property instanceof TimeIntervalCollectionPositionProperty && (defined(referenceFrame) && property.referenceFrame === referenceFrame)) {
//If we create a collection, or it already existed, use it.
// If we create a collection, or it already existed, use it.
property.intervals.addInterval(combinedInterval);
} else if (property instanceof CompositePositionProperty) {
//If the collection was already a CompositePositionProperty, use it.
// If the collection was already a CompositePositionProperty, use it.
if (isValue) {
combinedInterval.data = new ConstantPositionProperty(combinedInterval.data, referenceFrame);
}
property.intervals.addInterval(combinedInterval);
} else {
//Otherwise, create a CompositePositionProperty but preserve the existing data.
// Otherwise, create a CompositePositionProperty but preserve the existing data.

//Put the old property in an infinite interval.
// Put the old property in an infinite interval.
interval = Iso8601.MAXIMUM_INTERVAL.clone();
interval.data = property;

//Create the composite.
// Create the composite.
property = new CompositePositionProperty(property.referenceFrame);
object[propertyName] = property;

//add the old property interval
// Add the old property interval.
property.intervals.addInterval(interval);

//Change the new data to a ConstantPositionProperty and add it.
// Change the new data to a ConstantPositionProperty and add it.
if (isValue) {
combinedInterval.data = new ConstantPositionProperty(combinedInterval.data, referenceFrame);
}
Expand All @@ -953,20 +998,20 @@ define([
property = new CompositePositionProperty(referenceFrame);
object[propertyName] = property;
} else if (!(property instanceof CompositePositionProperty)) {
//create a CompositeProperty but preserve the existing data.
//Put the old property in an infinite interval.
// Create a CompositeProperty but preserve the existing data.
// Put the old property in an infinite interval.
interval = Iso8601.MAXIMUM_INTERVAL.clone();
interval.data = property;

//Create the composite.
// Create the composite.
property = new CompositePositionProperty(property.referenceFrame);
object[propertyName] = property;

//add the old property interval
// Add the old property interval.
property.intervals.addInterval(interval);
}

//Check if the interval already exists in the composite
//Check if the interval already exists in the composite.
var intervals = property.intervals;
interval = intervals.findInterval(combinedInterval);
if (!defined(interval) || !(interval.data instanceof SampledPositionProperty) || (defined(referenceFrame) && interval.data.referenceFrame !== referenceFrame)) {
Expand All @@ -979,6 +1024,28 @@ define([
updateInterpolationSettings(packetData, interval.data);
}

function removePositionPropertyData(property, interval) {
if (property instanceof SampledPositionProperty) {
property.removeSamples(interval);
return;
} else if (property instanceof TimeIntervalCollectionPositionProperty) {
property.intervals.removeInterval(interval);
return;
} else if (property instanceof CompositePositionProperty) {
var intervals = property.intervals;
for (var i = 0; i < intervals.length; ++i) {
var intersection = TimeInterval.intersect(intervals.get(i), interval, scratchTimeInterval);
if (!intersection.isEmpty) {
// remove data from the contained properties
removePositionPropertyData(intersection.data, interval);
}
}
// remove the intervals from the composite
intervals.removeInterval(interval);
return;
}
}

function processPositionPacketData(object, propertyName, packetData, interval, sourceUri, entityCollection) {
if (!defined(packetData)) {
return;
Expand Down
Loading

0 comments on commit 2a46171

Please sign in to comment.