123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712 |
- define([
- '../Core/binarySearch',
- '../Core/defaultValue',
- '../Core/defined',
- '../Core/defineProperties',
- '../Core/DeveloperError',
- '../Core/Event',
- '../Core/ExtrapolationType',
- '../Core/JulianDate',
- '../Core/LinearApproximation'
- ], function(
- binarySearch,
- defaultValue,
- defined,
- defineProperties,
- DeveloperError,
- Event,
- ExtrapolationType,
- JulianDate,
- LinearApproximation) {
- "use strict";
- var PackableNumber = {
- packedLength : 1,
- pack : function(value, array, startingIndex) {
- startingIndex = defaultValue(startingIndex, 0);
- array[startingIndex] = value;
- },
- unpack : function(array, startingIndex, result) {
- startingIndex = defaultValue(startingIndex, 0);
- return array[startingIndex];
- }
- };
-
-
- function arrayInsert(array, startIndex, items) {
- var i;
- var arrayLength = array.length;
- var itemsLength = items.length;
- var newLength = arrayLength + itemsLength;
- array.length = newLength;
- if (arrayLength !== startIndex) {
- var q = arrayLength - 1;
- for (i = newLength - 1; i >= startIndex; i--) {
- array[i] = array[q--];
- }
- }
- for (i = 0; i < itemsLength; i++) {
- array[startIndex++] = items[i];
- }
- }
- function convertDate(date, epoch) {
- if (date instanceof JulianDate) {
- return date;
- }
- if (typeof date === 'string') {
- return JulianDate.fromIso8601(date);
- }
- return JulianDate.addSeconds(epoch, date, new JulianDate());
- }
- var timesSpliceArgs = [];
- var valuesSpliceArgs = [];
- var mergeNewSamples = function(epoch, times, values, newData, packedLength) {
- var newDataIndex = 0;
- var i;
- var prevItem;
- var timesInsertionPoint;
- var valuesInsertionPoint;
- var currentTime;
- var nextTime;
- while (newDataIndex < newData.length) {
- currentTime = convertDate(newData[newDataIndex], epoch);
- timesInsertionPoint = binarySearch(times, currentTime, JulianDate.compare);
- var timesSpliceArgsCount = 0;
- var valuesSpliceArgsCount = 0;
- if (timesInsertionPoint < 0) {
-
- timesInsertionPoint = ~timesInsertionPoint;
- valuesInsertionPoint = timesInsertionPoint * packedLength;
- prevItem = undefined;
- nextTime = times[timesInsertionPoint];
- while (newDataIndex < newData.length) {
- currentTime = convertDate(newData[newDataIndex], epoch);
- if ((defined(prevItem) && JulianDate.compare(prevItem, currentTime) >= 0) || (defined(nextTime) && JulianDate.compare(currentTime, nextTime) >= 0)) {
- break;
- }
- timesSpliceArgs[timesSpliceArgsCount++] = currentTime;
- newDataIndex = newDataIndex + 1;
- for (i = 0; i < packedLength; i++) {
- valuesSpliceArgs[valuesSpliceArgsCount++] = newData[newDataIndex];
- newDataIndex = newDataIndex + 1;
- }
- prevItem = currentTime;
- }
- if (timesSpliceArgsCount > 0) {
- valuesSpliceArgs.length = valuesSpliceArgsCount;
- arrayInsert(values, valuesInsertionPoint, valuesSpliceArgs);
- timesSpliceArgs.length = timesSpliceArgsCount;
- arrayInsert(times, timesInsertionPoint, timesSpliceArgs);
- }
- } else {
-
- for (i = 0; i < packedLength; i++) {
- newDataIndex++;
- values[(timesInsertionPoint * packedLength) + i] = newData[newDataIndex];
- }
- newDataIndex++;
- }
- }
- };
-
- var SampledProperty = function(type, derivativeTypes) {
-
- if (!defined(type)) {
- throw new DeveloperError('type is required.');
- }
-
- var innerType = type;
- if (innerType === Number) {
- innerType = PackableNumber;
- }
- var packedLength = innerType.packedLength;
- var packedInterpolationLength = defaultValue(innerType.packedInterpolationLength, packedLength);
- var inputOrder = 0;
- var innerDerivativeTypes;
- if (defined(derivativeTypes)) {
- var length = derivativeTypes.length;
- innerDerivativeTypes = new Array(length);
- for (var i = 0; i < length; i++) {
- var derivativeType = derivativeTypes[i];
- if (derivativeType === Number) {
- derivativeType = PackableNumber;
- }
- var derivativePackedLength = derivativeType.packedLength;
- packedLength += derivativePackedLength;
- packedInterpolationLength += defaultValue(derivativeType.packedInterpolationLength, derivativePackedLength);
- innerDerivativeTypes[i] = derivativeType;
- }
- inputOrder = length;
- }
- this._type = type;
- this._innerType = innerType;
- this._interpolationDegree = 1;
- this._interpolationAlgorithm = LinearApproximation;
- this._numberOfPoints = 0;
- this._times = [];
- this._values = [];
- this._xTable = [];
- this._yTable = [];
- this._packedLength = packedLength;
- this._packedInterpolationLength = packedInterpolationLength;
- this._updateTableLength = true;
- this._interpolationResult = new Array(packedInterpolationLength);
- this._definitionChanged = new Event();
- this._derivativeTypes = derivativeTypes;
- this._innerDerivativeTypes = innerDerivativeTypes;
- this._inputOrder = inputOrder;
- this._forwardExtrapolationType = ExtrapolationType.NONE;
- this._forwardExtrapolationDuration = 0;
- this._backwardExtrapolationType = ExtrapolationType.NONE;
- this._backwardExtrapolationDuration = 0;
- };
- defineProperties(SampledProperty.prototype, {
-
- isConstant : {
- get : function() {
- return this._values.length === 0;
- }
- },
-
- definitionChanged : {
- get : function() {
- return this._definitionChanged;
- }
- },
-
- type : {
- get : function() {
- return this._type;
- }
- },
-
- derivativeTypes : {
- get : function() {
- return this._derivativeTypes;
- }
- },
-
- interpolationDegree : {
- get : function() {
- return this._interpolationDegree;
- }
- },
-
- interpolationAlgorithm : {
- get : function() {
- return this._interpolationAlgorithm;
- }
- },
-
- forwardExtrapolationType : {
- get : function() {
- return this._forwardExtrapolationType;
- },
- set : function(value) {
- if (this._forwardExtrapolationType !== value) {
- this._forwardExtrapolationType = value;
- this._definitionChanged.raiseEvent(this);
- }
- }
- },
-
- forwardExtrapolationDuration : {
- get : function() {
- return this._forwardExtrapolationDuration;
- },
- set : function(value) {
- if (this._forwardExtrapolationDuration !== value) {
- this._forwardExtrapolationDuration = value;
- this._definitionChanged.raiseEvent(this);
- }
- }
- },
-
- backwardExtrapolationType : {
- get : function() {
- return this._backwardExtrapolationType;
- },
- set : function(value) {
- if (this._backwardExtrapolationType !== value) {
- this._backwardExtrapolationType = value;
- this._definitionChanged.raiseEvent(this);
- }
- }
- },
-
- backwardExtrapolationDuration : {
- get : function() {
- return this._backwardExtrapolationDuration;
- },
- set : function(value) {
- if (this._backwardExtrapolationDuration !== value) {
- this._backwardExtrapolationDuration = value;
- this._definitionChanged.raiseEvent(this);
- }
- }
- }
- });
-
- SampledProperty.prototype.getValue = function(time, result) {
-
- if (!defined(time)) {
- throw new DeveloperError('time is required.');
- }
-
- var timeout;
- var innerType = this._innerType;
- var times = this._times;
- var values = this._values;
- var index = binarySearch(times, time, JulianDate.compare);
- if (index < 0) {
- index = ~index;
- if (index === 0) {
- var startTime = times[index];
- timeout = this._backwardExtrapolationDuration;
- if (this._backwardExtrapolationType === ExtrapolationType.NONE || (timeout !== 0 && JulianDate.secondsDifference(startTime, time) > timeout)) {
- return undefined;
- }
- if (this._backwardExtrapolationType === ExtrapolationType.HOLD) {
- return innerType.unpack(this._values, 0, result);
- }
- }
- if (index >= times.length) {
- index = times.length - 1;
- var endTime = times[index];
- timeout = this._forwardExtrapolationDuration;
- if (this._forwardExtrapolationType === ExtrapolationType.NONE || (timeout !== 0 && JulianDate.secondsDifference(time, endTime) > timeout)) {
- return undefined;
- }
- if (this._forwardExtrapolationType === ExtrapolationType.HOLD) {
- index = times.length - 1;
- return innerType.unpack(this._values, index * innerType.packedLength, result);
- }
- }
- var xTable = this._xTable;
- var yTable = this._yTable;
- var interpolationAlgorithm = this._interpolationAlgorithm;
- var packedInterpolationLength = this._packedInterpolationLength;
- var inputOrder = this._inputOrder;
- if (this._updateTableLength) {
- this._updateTableLength = false;
- var numberOfPoints = Math.min(interpolationAlgorithm.getRequiredDataPoints(this._interpolationDegree, inputOrder), times.length);
- if (numberOfPoints !== this._numberOfPoints) {
- this._numberOfPoints = numberOfPoints;
- xTable.length = numberOfPoints;
- yTable.length = numberOfPoints * packedInterpolationLength;
- }
- }
- var degree = this._numberOfPoints - 1;
- if (degree < 1) {
- return undefined;
- }
- var firstIndex = 0;
- var lastIndex = times.length - 1;
- var pointsInCollection = lastIndex - firstIndex + 1;
- if (pointsInCollection < degree + 1) {
-
- } else {
- var computedFirstIndex = index - ((degree / 2) | 0) - 1;
- if (computedFirstIndex < firstIndex) {
- computedFirstIndex = firstIndex;
- }
- var computedLastIndex = computedFirstIndex + degree;
- if (computedLastIndex > lastIndex) {
- computedLastIndex = lastIndex;
- computedFirstIndex = computedLastIndex - degree;
- if (computedFirstIndex < firstIndex) {
- computedFirstIndex = firstIndex;
- }
- }
- firstIndex = computedFirstIndex;
- lastIndex = computedLastIndex;
- }
- var length = lastIndex - firstIndex + 1;
-
- for (var i = 0; i < length; ++i) {
- xTable[i] = JulianDate.secondsDifference(times[firstIndex + i], times[lastIndex]);
- }
- if (!defined(innerType.convertPackedArrayForInterpolation)) {
- var destinationIndex = 0;
- var packedLength = this._packedLength;
- var sourceIndex = firstIndex * packedLength;
- var stop = (lastIndex + 1) * packedLength;
- while (sourceIndex < stop) {
- yTable[destinationIndex] = values[sourceIndex];
- sourceIndex++;
- destinationIndex++;
- }
- } else {
- innerType.convertPackedArrayForInterpolation(values, firstIndex, lastIndex, yTable);
- }
-
- var x = JulianDate.secondsDifference(time, times[lastIndex]);
- var interpolationResult;
- if (inputOrder === 0 || !defined(interpolationAlgorithm.interpolate)) {
- interpolationResult = interpolationAlgorithm.interpolateOrderZero(x, xTable, yTable, packedInterpolationLength, this._interpolationResult);
- } else {
- var yStride = Math.floor(packedInterpolationLength / (inputOrder + 1));
- interpolationResult = interpolationAlgorithm.interpolate(x, xTable, yTable, yStride, inputOrder, inputOrder, this._interpolationResult);
- }
- if (!defined(innerType.unpackInterpolationResult)) {
- return innerType.unpack(interpolationResult, 0, result);
- }
- return innerType.unpackInterpolationResult(interpolationResult, values, firstIndex, lastIndex, result);
- }
- return innerType.unpack(this._values, index * this._packedLength, result);
- };
-
- SampledProperty.prototype.setInterpolationOptions = function(options) {
-
- if (!defined(options)) {
- throw new DeveloperError('options is required.');
- }
-
- var valuesChanged = false;
- var interpolationAlgorithm = options.interpolationAlgorithm;
- var interpolationDegree = options.interpolationDegree;
- if (this._interpolationAlgorithm !== interpolationAlgorithm) {
- this._interpolationAlgorithm = interpolationAlgorithm;
- valuesChanged = true;
- }
- if (this._interpolationDegree !== interpolationDegree) {
- this._interpolationDegree = interpolationDegree;
- valuesChanged = true;
- }
- if (valuesChanged) {
- this._updateTableLength = true;
- this._definitionChanged.raiseEvent(this);
- }
- };
-
- SampledProperty.prototype.addSample = function(time, value, derivatives) {
- var innerDerivativeTypes = this._innerDerivativeTypes;
- var hasDerivatives = defined(innerDerivativeTypes);
-
- 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.');
- }
-
- var innerType = this._innerType;
- var data = [];
- data.push(time);
- innerType.pack(value, data, data.length);
- if (hasDerivatives) {
- var derivativesLength = innerDerivativeTypes.length;
- for (var x = 0; x < derivativesLength; x++) {
- innerDerivativeTypes[x].pack(derivatives[x], data, data.length);
- }
- }
- mergeNewSamples(undefined, this._times, this._values, data, this._packedLength);
- this._updateTableLength = true;
- this._definitionChanged.raiseEvent(this);
- };
-
- SampledProperty.prototype.addSamples = function(times, values, derivativeValues) {
- var innerDerivativeTypes = this._innerDerivativeTypes;
- var hasDerivatives = defined(innerDerivativeTypes);
-
- if (!defined(times)) {
- throw new DeveloperError('times is required.');
- }
- if (!defined(values)) {
- throw new DeveloperError('values is required.');
- }
- if (times.length !== values.length) {
- throw new DeveloperError('times and values must be the same length.');
- }
- if (hasDerivatives && (!defined(derivativeValues) || derivativeValues.length !== times.length)) {
- throw new DeveloperError('times and derivativeValues must be the same length.');
- }
-
- var innerType = this._innerType;
- var length = times.length;
- var data = [];
- for (var i = 0; i < length; i++) {
- data.push(times[i]);
- innerType.pack(values[i], data, data.length);
- if (hasDerivatives) {
- var derivatives = derivativeValues[i];
- var derivativesLength = innerDerivativeTypes.length;
- for (var x = 0; x < derivativesLength; x++) {
- innerDerivativeTypes[x].pack(derivatives[x], data, data.length);
- }
- }
- }
- mergeNewSamples(undefined, this._times, this._values, data, this._packedLength);
- this._updateTableLength = true;
- this._definitionChanged.raiseEvent(this);
- };
-
- SampledProperty.prototype.addSamplesPackedArray = function(packedSamples, epoch) {
-
- if (!defined(packedSamples)) {
- throw new DeveloperError('packedSamples is required.');
- }
-
- mergeNewSamples(epoch, this._times, this._values, packedSamples, this._packedLength);
- this._updateTableLength = true;
- this._definitionChanged.raiseEvent(this);
- };
-
- SampledProperty.prototype.equals = function(other) {
- if (this === other) {
- return true;
- }
- if (!defined(other)) {
- return false;
- }
- if (this._type !== other._type ||
- this._interpolationDegree !== other._interpolationDegree ||
- this._interpolationAlgorithm !== other._interpolationAlgorithm) {
- return false;
- }
- var derivativeTypes = this._derivativeTypes;
- var hasDerivatives = defined(derivativeTypes);
- var otherDerivativeTypes = other._derivativeTypes;
- var otherHasDerivatives = defined(otherDerivativeTypes);
- if (hasDerivatives !== otherHasDerivatives) {
- return false;
- }
- var i;
- var length;
- if (hasDerivatives) {
- length = derivativeTypes.length;
- if (length !== otherDerivativeTypes.length) {
- return false;
- }
- for (i = 0; i < length; i++) {
- if (derivativeTypes[i] !== otherDerivativeTypes[i]) {
- return false;
- }
- }
- }
- var times = this._times;
- var otherTimes = other._times;
- length = times.length;
- if (length !== otherTimes.length) {
- return false;
- }
- for (i = 0; i < length; i++) {
- if (!JulianDate.equals(times[i], otherTimes[i])) {
- return false;
- }
- }
- var values = this._values;
- var otherValues = other._values;
- for (i = 0; i < length; i++) {
- if (values[i] !== otherValues[i]) {
- return false;
- }
- }
- return true;
- };
-
- SampledProperty._mergeNewSamples = mergeNewSamples;
- return SampledProperty;
- });
|