diff --git a/Source/DataSources/SampledPositionProperty.js b/Source/DataSources/SampledPositionProperty.js
index 28da3c99fada..11f65cf42656 100644
--- a/Source/DataSources/SampledPositionProperty.js
+++ b/Source/DataSources/SampledPositionProperty.js
@@ -1,5 +1,6 @@
define([
'../Core/Cartesian3',
+ '../Core/Check',
'../Core/defaultValue',
'../Core/defined',
'../Core/defineProperties',
@@ -11,6 +12,7 @@ define([
'./SampledProperty'
], function(
Cartesian3,
+ Check,
defaultValue,
defined,
defineProperties,
@@ -210,12 +212,8 @@ define([
*/
SampledPositionProperty.prototype.getValueInReferenceFrame = function(time, referenceFrame, result) {
//>>includeStart('debug', pragmas.debug);
- if (!defined(time)) {
- throw new DeveloperError('time is required.');
- }
- if (!defined(referenceFrame)) {
- throw new DeveloperError('referenceFrame is required.');
- }
+ Check.defined('time', time);
+ Check.defined('referenceFrame', referenceFrame);
//>>includeEnd('debug');
result = this._property.getValue(time, result);
@@ -277,6 +275,25 @@ define([
this._property.addSamplesPackedArray(packedSamples, epoch);
};
+ /**
+ * Removes a sample at the given time, if present.
+ *
+ * @param {JulianDate} time The sample time.
+ * @returns {Boolean} true
if a sample at time was removed, false
otherwise.
+ */
+ SampledPositionProperty.prototype.removeSample = function(time) {
+ this._property.removeSample(time);
+ };
+
+ /**
+ * Removes all samples for the given time interval.
+ *
+ * @param {TimeInterval} time The time interval for which to remove all samples.
+ */
+ SampledPositionProperty.prototype.removeSamples = function(timeInterval) {
+ this._property.removeSamples(timeInterval);
+ };
+
/**
* Compares this property to the provided property and returns
* true
if they are equal, false
otherwise.
diff --git a/Source/DataSources/SampledProperty.js b/Source/DataSources/SampledProperty.js
index 469f10815c79..b4aa7424cd44 100644
--- a/Source/DataSources/SampledProperty.js
+++ b/Source/DataSources/SampledProperty.js
@@ -1,5 +1,6 @@
define([
'../Core/binarySearch',
+ '../Core/Check',
'../Core/defaultValue',
'../Core/defined',
'../Core/defineProperties',
@@ -10,6 +11,7 @@ define([
'../Core/LinearApproximation'
], function(
binarySearch,
+ Check,
defaultValue,
defined,
defineProperties,
@@ -166,9 +168,7 @@ define([
*/
function SampledProperty(type, derivativeTypes) {
//>>includeStart('debug', pragmas.debug);
- if (!defined(type)) {
- throw new DeveloperError('type is required.');
- }
+ Check.defined('type', type);
//>>includeEnd('debug');
var innerType = type;
@@ -372,9 +372,7 @@ define([
*/
SampledProperty.prototype.getValue = function(time, result) {
//>>includeStart('debug', pragmas.debug);
- if (!defined(time)) {
- throw new DeveloperError('time is required.');
- }
+ Check.defined('time', time);
//>>includeEnd('debug');
var times = this._times;
@@ -531,7 +529,7 @@ define([
};
/**
- * Adds a new sample
+ * Adds a new sample.
*
* @param {JulianDate} time The sample time.
* @param {Packable} value The value at the provided time.
@@ -542,14 +540,10 @@ define([
var hasDerivatives = defined(innerDerivativeTypes);
//>>includeStart('debug', pragmas.debug);
- if (!defined(time)) {
- throw new DeveloperError('time is required.');
- }
- if (!defined(value)) {
- throw new DeveloperError('value is required.');
- }
- if (hasDerivatives && !defined(derivatives)) {
- throw new DeveloperError('derivatives is required.');
+ Check.defined('time', time);
+ Check.defined('value', value);
+ if (hasDerivatives) {
+ Check.defined('derivatives', derivatives);
}
//>>includeEnd('debug');
@@ -570,7 +564,7 @@ define([
};
/**
- * Adds an array of samples
+ * Adds an array of samples.
*
* @param {JulianDate[]} times An array of JulianDate instances where each index is a sample time.
* @param {Packable[]} values The array of values, where each value corresponds to the provided times index.
@@ -584,12 +578,8 @@ define([
var hasDerivatives = defined(innerDerivativeTypes);
//>>includeStart('debug', pragmas.debug);
- if (!defined(times)) {
- throw new DeveloperError('times is required.');
- }
- if (!defined(values)) {
- throw new DeveloperError('values is required.');
- }
+ Check.defined('times', times);
+ Check.defined('values', values);
if (times.length !== values.length) {
throw new DeveloperError('times and values must be the same length.');
}
@@ -627,9 +617,7 @@ define([
*/
SampledProperty.prototype.addSamplesPackedArray = function(packedSamples, epoch) {
//>>includeStart('debug', pragmas.debug);
- if (!defined(packedSamples)) {
- throw new DeveloperError('packedSamples is required.');
- }
+ Check.defined('packedSamples', packedSamples);
//>>includeEnd('debug');
mergeNewSamples(epoch, this._times, this._values, packedSamples, this._packedLength);
@@ -637,6 +625,60 @@ define([
this._definitionChanged.raiseEvent(this);
};
+ /**
+ * Removes a sample at the given time, if present.
+ *
+ * @param {JulianDate} time The sample time.
+ * @returns {Boolean} true
if a sample at time was removed, false
otherwise.
+ */
+ SampledProperty.prototype.removeSample = function(time) {
+ //>>includeStart('debug', pragmas.debug);
+ Check.defined('time', time);
+ //>>includeEnd('debug');
+
+ var index = binarySearch(this._times, time, JulianDate.compare);
+ if (index < 0) {
+ return false;
+ }
+ removeSamples(this, index, 1);
+ return true;
+ };
+
+ function removeSamples(property, startIndex, numberToRemove) {
+ var packedLength = property._packedLength;
+ property._times.splice(startIndex, numberToRemove);
+ property._values.splice(startIndex * packedLength, numberToRemove * packedLength);
+ property._updateTableLength = true;
+ property._definitionChanged.raiseEvent(property);
+ }
+
+ /**
+ * Removes all samples for the given time interval.
+ *
+ * @param {TimeInterval} time The time interval for which to remove all samples.
+ */
+ SampledProperty.prototype.removeSamples = function(timeInterval) {
+ //>>includeStart('debug', pragmas.debug);
+ Check.defined('timeInterval', timeInterval);
+ //>>includeEnd('debug');
+
+ var times = this._times;
+ var startIndex = binarySearch(times, timeInterval.start, JulianDate.compare);
+ if (startIndex < 0) {
+ startIndex = ~startIndex;
+ } else if (!timeInterval.isStartIncluded) {
+ ++startIndex;
+ }
+ var stopIndex = binarySearch(times, timeInterval.stop, JulianDate.compare);
+ if (stopIndex < 0) {
+ stopIndex = ~stopIndex;
+ } else if (timeInterval.isStopIncluded) {
+ ++stopIndex;
+ }
+
+ removeSamples(this, startIndex, stopIndex - startIndex);
+ };
+
/**
* Compares this property to the provided property and returns
* true
if they are equal, false
otherwise.
diff --git a/Specs/DataSources/SampledPositionPropertySpec.js b/Specs/DataSources/SampledPositionPropertySpec.js
index 90b750cdc01b..8528eef8c0fa 100644
--- a/Specs/DataSources/SampledPositionPropertySpec.js
+++ b/Specs/DataSources/SampledPositionPropertySpec.js
@@ -6,6 +6,7 @@ defineSuite([
'Core/LagrangePolynomialApproximation',
'Core/LinearApproximation',
'Core/ReferenceFrame',
+ 'Core/TimeInterval',
'DataSources/PositionProperty'
], function(
SampledPositionProperty,
@@ -15,6 +16,7 @@ defineSuite([
LagrangePolynomialApproximation,
LinearApproximation,
ReferenceFrame,
+ TimeInterval,
PositionProperty) {
'use strict';
@@ -110,8 +112,8 @@ defineSuite([
});
it('addSample works', function() {
- var values = [new Cartesian3(7, 8, 9), new Cartesian3(8, 9, 10), new Cartesian3(9, 10, 11)];
var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)];
+ var values = [new Cartesian3(7, 8, 9), new Cartesian3(8, 9, 10), new Cartesian3(9, 10, 11)];
var property = new SampledPositionProperty();
property.addSample(times[0], values[0]);
@@ -125,8 +127,8 @@ defineSuite([
});
it('addSamples works', function() {
- var values = [new Cartesian3(7, 8, 9), new Cartesian3(8, 9, 10), new Cartesian3(9, 10, 11)];
var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)];
+ var values = [new Cartesian3(7, 8, 9), new Cartesian3(8, 9, 10), new Cartesian3(9, 10, 11)];
var property = new SampledPositionProperty();
property.addSamples(times, values);
@@ -136,6 +138,50 @@ defineSuite([
expect(property.getValue(new JulianDate(0.5, 0))).toEqual(new Cartesian3(7.5, 8.5, 9.5));
});
+ it('can remove a sample at a date', function() {
+ var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)];
+ var values = [new Cartesian3(7, 8, 9), new Cartesian3(18, 19, 110), new Cartesian3(9, 10, 11)];
+
+ var property = new SampledPositionProperty();
+ property.addSamples(times, values);
+
+ var listener = jasmine.createSpy('listener');
+ property.definitionChanged.addEventListener(listener);
+
+ property.removeSample(times[1]);
+
+ expect(listener).toHaveBeenCalledWith(property);
+
+ expect(property.getValue(times[0])).toEqual(values[0]);
+ // removing the sample at times[1] causes the property to interpolate
+ expect(property.getValue(times[1])).toEqual(new Cartesian3(8, 9, 10));
+ expect(property.getValue(times[2])).toEqual(values[2]);
+ });
+
+ it('can remove samples for a time interval', function() {
+ var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0), new JulianDate(3, 0)];
+ var values = [new Cartesian3(7, 8, 9), new Cartesian3(18, 19, 110), new Cartesian3(19, 20, 110), new Cartesian3(10, 11, 12)];
+
+ var property = new SampledPositionProperty();
+ property.addSamples(times, values);
+
+ var listener = jasmine.createSpy('listener');
+ property.definitionChanged.addEventListener(listener);
+
+ property.removeSamples(new TimeInterval({
+ start: times[1],
+ stop: times[2]
+ }));
+
+ expect(listener).toHaveBeenCalledWith(property);
+
+ expect(property.getValue(times[0])).toEqual(values[0]);
+ // removing the samples causes the property to interpolate
+ expect(property.getValue(times[1])).toEqual(new Cartesian3(8, 9, 10));
+ expect(property.getValue(times[2])).toEqual(new Cartesian3(9, 10, 11));
+ expect(property.getValue(times[3])).toEqual(values[3]);
+ });
+
it('addSamplesPackedArray works with derivatives', function() {
var data = [0, 7, 8, 9, 1, 0, 0, 1, 8, 9, 10, 0, 1, 0, 2, 9, 10, 11, 0, 0, 1];
var epoch = new JulianDate(0, 0);
diff --git a/Specs/DataSources/SampledPropertySpec.js b/Specs/DataSources/SampledPropertySpec.js
index 06617facf84d..763d123cced9 100644
--- a/Specs/DataSources/SampledPropertySpec.js
+++ b/Specs/DataSources/SampledPropertySpec.js
@@ -8,7 +8,8 @@ defineSuite([
'Core/LagrangePolynomialApproximation',
'Core/LinearApproximation',
'Core/Math',
- 'Core/Quaternion'
+ 'Core/Quaternion',
+ 'Core/TimeInterval'
], function(
SampledProperty,
Cartesian3,
@@ -19,7 +20,8 @@ defineSuite([
LagrangePolynomialApproximation,
LinearApproximation,
CesiumMath,
- Quaternion) {
+ Quaternion,
+ TimeInterval) {
'use strict';
it('constructor sets expected defaults', function() {
@@ -70,8 +72,8 @@ defineSuite([
});
it('addSample works', function() {
- var values = [7, 8, 9];
var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)];
+ var values = [7, 8, 9];
var property = new SampledProperty(Number);
var listener = jasmine.createSpy('listener');
@@ -96,8 +98,8 @@ defineSuite([
});
it('addSamples works', function() {
- var values = [7, 8, 9];
var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)];
+ var values = [7, 8, 9];
var property = new SampledProperty(Number);
var listener = jasmine.createSpy('listener');
@@ -111,6 +113,169 @@ defineSuite([
expect(property.getValue(new JulianDate(0.5, 0))).toEqual(7.5);
});
+ it('can remove a sample at a date', function() {
+ var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)];
+ var values = [1, 8, 3];
+
+ var property = new SampledProperty(Number);
+ property.addSamples(times, values);
+ expect(property.getValue(times[0])).toEqual(values[0]);
+ expect(property.getValue(times[1])).toEqual(values[1]);
+ expect(property.getValue(times[2])).toEqual(values[2]);
+
+ var listener = jasmine.createSpy('listener');
+ property.definitionChanged.addEventListener(listener);
+
+ property.removeSample(times[1]);
+
+ expect(listener).toHaveBeenCalledWith(property);
+
+ expect(property._times.length).toEqual(2);
+ expect(property._values.length).toEqual(2);
+
+ expect(property.getValue(times[0])).toEqual(values[0]);
+ // by deleting the sample at times[1] we now linearly interpolate from the remaining samples
+ expect(property.getValue(times[1])).toEqual((values[0] + values[2]) / 2);
+ expect(property.getValue(times[2])).toEqual(values[2]);
+ });
+
+ function arraySubset(array, startIndex, count) {
+ array = array.slice();
+ array.splice(startIndex, count);
+ return array;
+ }
+
+ it('can remove samples for a time interval', function() {
+ var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0), new JulianDate(3, 0), new JulianDate(4, 0)];
+ var values = [1, 8, 13, 1, 3];
+
+ function createProperty() {
+ var property = new SampledProperty(Number);
+ property.addSamples(times, values);
+ expect(property.getValue(times[0])).toEqual(values[0]);
+ expect(property.getValue(times[1])).toEqual(values[1]);
+ expect(property.getValue(times[2])).toEqual(values[2]);
+ expect(property.getValue(times[3])).toEqual(values[3]);
+ expect(property.getValue(times[4])).toEqual(values[4]);
+ return property;
+ }
+
+ var property = createProperty();
+ var listener = jasmine.createSpy('listener');
+ property.definitionChanged.addEventListener(listener);
+
+ property.removeSamples(new TimeInterval({
+ start: times[1],
+ stop: times[3]
+ }));
+
+ expect(listener).toHaveBeenCalledWith(property);
+ expect(property._times.length).toEqual(2);
+ expect(property._values.length).toEqual(2);
+ expect(property._times).toEqual(arraySubset(times, 1, 3));
+ expect(property._values).toEqual(arraySubset(values, 1, 3));
+
+ expect(property.getValue(times[0])).toEqual(values[0]);
+ // by deleting the samples we now linearly interpolate from the remaining samples
+ expect(property.getValue(times[2])).toEqual((values[0] + values[4]) / 2);
+ expect(property.getValue(times[4])).toEqual(values[4]);
+
+ property = createProperty();
+ listener = jasmine.createSpy('listener');
+ property.definitionChanged.addEventListener(listener);
+
+ // remove using a start time just after a sample
+ property.removeSamples(new TimeInterval({
+ start: JulianDate.addSeconds(times[1], 4, new JulianDate()),
+ stop: times[3]
+ }));
+
+ expect(listener).toHaveBeenCalledWith(property);
+ expect(property._times.length).toEqual(3);
+ expect(property._values.length).toEqual(3);
+ expect(property._times).toEqual(arraySubset(times, 2, 2));
+ expect(property._values).toEqual(arraySubset(values, 2, 2));
+
+ property = createProperty();
+ listener = jasmine.createSpy('listener');
+ property.definitionChanged.addEventListener(listener);
+
+ // remove using a stop time just before a sample
+ property.removeSamples(new TimeInterval({
+ start: JulianDate.addSeconds(times[1], 4, new JulianDate()),
+ stop: JulianDate.addSeconds(times[3], -4, new JulianDate())
+ }));
+
+ expect(listener).toHaveBeenCalledWith(property);
+ expect(property._times.length).toEqual(4);
+ expect(property._values.length).toEqual(4);
+ expect(property._times).toEqual(arraySubset(times, 2, 1));
+ expect(property._values).toEqual(arraySubset(values, 2, 1));
+ });
+
+ it('can remove samples for a time interval with start or stop not included', function() {
+ var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0), new JulianDate(3, 0), new JulianDate(4, 0)];
+ var values = [1, 8, 13, 1, 3];
+
+ function createProperty() {
+ var property = new SampledProperty(Number);
+ property.addSamples(times, values);
+ expect(property.getValue(times[0])).toEqual(values[0]);
+ expect(property.getValue(times[1])).toEqual(values[1]);
+ expect(property.getValue(times[2])).toEqual(values[2]);
+ expect(property.getValue(times[3])).toEqual(values[3]);
+ expect(property.getValue(times[4])).toEqual(values[4]);
+ return property;
+ }
+
+ var property = createProperty();
+ var listener = jasmine.createSpy('listener');
+ property.definitionChanged.addEventListener(listener);
+
+ property.removeSamples(new TimeInterval({
+ start: times[1],
+ stop: times[3],
+ isStartIncluded: false,
+ isStopIncluded: true
+ }));
+
+ expect(listener).toHaveBeenCalledWith(property);
+ expect(property._times).toEqual(arraySubset(times, 2, 2));
+ expect(property._values).toEqual(arraySubset(values, 2, 2));
+
+ property = createProperty();
+
+ listener = jasmine.createSpy('listener');
+ property.definitionChanged.addEventListener(listener);
+
+ property.removeSamples(new TimeInterval({
+ start: times[1],
+ stop: times[3],
+ isStartIncluded: true,
+ isStopIncluded: false
+ }));
+
+ expect(listener).toHaveBeenCalledWith(property);
+ expect(property._times).toEqual(arraySubset(times, 1, 2));
+ expect(property._values).toEqual(arraySubset(values, 1, 2));
+
+ property = createProperty();
+
+ listener = jasmine.createSpy('listener');
+ property.definitionChanged.addEventListener(listener);
+
+ property.removeSamples(new TimeInterval({
+ start: times[1],
+ stop: times[3],
+ isStartIncluded: false,
+ isStopIncluded: false
+ }));
+
+ expect(listener).toHaveBeenCalledWith(property);
+ expect(property._times).toEqual(arraySubset(times, 2, 1));
+ expect(property._values).toEqual(arraySubset(values, 2, 1));
+ });
+
it('works with PackableForInterpolation', function() {
function CustomType(value) {
this.x = value;
@@ -143,8 +308,8 @@ defineSuite([
return result;
};
- var values = [new CustomType(0), new CustomType(2), new CustomType(4)];
var times = [new JulianDate(0, 0), new JulianDate(1, 0), new JulianDate(2, 0)];
+ var values = [new CustomType(0), new CustomType(2), new CustomType(4)];
var property = new SampledProperty(CustomType);
property.addSample(times[0], values[0]);