import ArcType from "../Core/ArcType.js"; import BoundingRectangle from "../Core/BoundingRectangle.js"; import Cartesian2 from "../Core/Cartesian2.js"; import Cartesian3 from "../Core/Cartesian3.js"; import Cartographic from "../Core/Cartographic.js"; import ClockRange from "../Core/ClockRange.js"; import ClockStep from "../Core/ClockStep.js"; import Color from "../Core/Color.js"; import CornerType from "../Core/CornerType.js"; import Credit from "../Core/Credit.js"; import createGuid from "../Core/createGuid.js"; import defaultValue from "../Core/defaultValue.js"; import defined from "../Core/defined.js"; import DeveloperError from "../Core/DeveloperError.js"; import DistanceDisplayCondition from "../Core/DistanceDisplayCondition.js"; import Ellipsoid from "../Core/Ellipsoid.js"; import Event from "../Core/Event.js"; import ExtrapolationType from "../Core/ExtrapolationType.js"; import getFilenameFromUri from "../Core/getFilenameFromUri.js"; import HermitePolynomialApproximation from "../Core/HermitePolynomialApproximation.js"; import Iso8601 from "../Core/Iso8601.js"; import JulianDate from "../Core/JulianDate.js"; import LagrangePolynomialApproximation from "../Core/LagrangePolynomialApproximation.js"; import LinearApproximation from "../Core/LinearApproximation.js"; import CesiumMath from "../Core/Math.js"; import NearFarScalar from "../Core/NearFarScalar.js"; import PolygonHierarchy from "../Core/PolygonHierarchy.js"; import Quaternion from "../Core/Quaternion.js"; import Rectangle from "../Core/Rectangle.js"; import ReferenceFrame from "../Core/ReferenceFrame.js"; import Resource from "../Core/Resource.js"; import RuntimeError from "../Core/RuntimeError.js"; import Spherical from "../Core/Spherical.js"; import TimeInterval from "../Core/TimeInterval.js"; import TimeIntervalCollection from "../Core/TimeIntervalCollection.js"; import ClassificationType from "../Scene/ClassificationType.js"; import ColorBlendMode from "../Scene/ColorBlendMode.js"; import HeightReference from "../Scene/HeightReference.js"; import HorizontalOrigin from "../Scene/HorizontalOrigin.js"; import LabelStyle from "../Scene/LabelStyle.js"; import ShadowMode from "../Scene/ShadowMode.js"; import VerticalOrigin from "../Scene/VerticalOrigin.js"; import Uri from "urijs"; import BillboardGraphics from "./BillboardGraphics.js"; import BoxGraphics from "./BoxGraphics.js"; import CallbackProperty from "./CallbackProperty.js"; import CheckerboardMaterialProperty from "./CheckerboardMaterialProperty.js"; import ColorMaterialProperty from "./ColorMaterialProperty.js"; import CompositeMaterialProperty from "./CompositeMaterialProperty.js"; import CompositePositionProperty from "./CompositePositionProperty.js"; import CompositeProperty from "./CompositeProperty.js"; import ConstantPositionProperty from "./ConstantPositionProperty.js"; import ConstantProperty from "./ConstantProperty.js"; import CorridorGraphics from "./CorridorGraphics.js"; import CylinderGraphics from "./CylinderGraphics.js"; import DataSource from "./DataSource.js"; import DataSourceClock from "./DataSourceClock.js"; import EllipseGraphics from "./EllipseGraphics.js"; import EllipsoidGraphics from "./EllipsoidGraphics.js"; import EntityCluster from "./EntityCluster.js"; import EntityCollection from "./EntityCollection.js"; import GridMaterialProperty from "./GridMaterialProperty.js"; import ImageMaterialProperty from "./ImageMaterialProperty.js"; import LabelGraphics from "./LabelGraphics.js"; import ModelGraphics from "./ModelGraphics.js"; import NodeTransformationProperty from "./NodeTransformationProperty.js"; import PathGraphics from "./PathGraphics.js"; import PointGraphics from "./PointGraphics.js"; import PolygonGraphics from "./PolygonGraphics.js"; import PolylineArrowMaterialProperty from "./PolylineArrowMaterialProperty.js"; import PolylineDashMaterialProperty from "./PolylineDashMaterialProperty.js"; import PolylineGlowMaterialProperty from "./PolylineGlowMaterialProperty.js"; import PolylineGraphics from "./PolylineGraphics.js"; import PolylineOutlineMaterialProperty from "./PolylineOutlineMaterialProperty.js"; import PolylineVolumeGraphics from "./PolylineVolumeGraphics.js"; import PositionPropertyArray from "./PositionPropertyArray.js"; import Property from "./Property.js"; import PropertyArray from "./PropertyArray.js"; import PropertyBag from "./PropertyBag.js"; import RectangleGraphics from "./RectangleGraphics.js"; import ReferenceProperty from "./ReferenceProperty.js"; import Rotation from "./Rotation.js"; import SampledPositionProperty from "./SampledPositionProperty.js"; import SampledProperty from "./SampledProperty.js"; import StripeMaterialProperty from "./StripeMaterialProperty.js"; import StripeOrientation from "./StripeOrientation.js"; import TimeIntervalCollectionPositionProperty from "./TimeIntervalCollectionPositionProperty.js"; import TimeIntervalCollectionProperty from "./TimeIntervalCollectionProperty.js"; import VelocityOrientationProperty from "./VelocityOrientationProperty.js"; import VelocityVectorProperty from "./VelocityVectorProperty.js"; import WallGraphics from "./WallGraphics.js"; import Cesium3DTilesetGraphics from "./Cesium3DTilesetGraphics.js"; // A marker type to distinguish CZML properties where we need to end up with a unit vector. // The data is still loaded into Cartesian3 objects but they are normalized. function UnitCartesian3() {} UnitCartesian3.packedLength = Cartesian3.packedLength; UnitCartesian3.unpack = Cartesian3.unpack; UnitCartesian3.pack = Cartesian3.pack; // As a side note, for the purposes of CZML, Quaternion always indicates a unit quaternion. let currentId; function createReferenceProperty(entityCollection, referenceString) { if (referenceString[0] === "#") { referenceString = currentId + referenceString; } return ReferenceProperty.fromString(entityCollection, referenceString); } function createSpecializedProperty(type, entityCollection, packetData) { if (defined(packetData.reference)) { return createReferenceProperty(entityCollection, packetData.reference); } if (defined(packetData.velocityReference)) { const referenceProperty = createReferenceProperty( entityCollection, packetData.velocityReference ); switch (type) { case Cartesian3: case UnitCartesian3: return new VelocityVectorProperty( referenceProperty, type === UnitCartesian3 ); case Quaternion: return new VelocityOrientationProperty(referenceProperty); } } throw new RuntimeError(`${JSON.stringify(packetData)} is not valid CZML.`); } function createAdapterProperty(property, adapterFunction) { return new CallbackProperty(function (time, result) { return adapterFunction(property.getValue(time, result)); }, property.isConstant); } const scratchCartesian = new Cartesian3(); const scratchSpherical = new Spherical(); const scratchCartographic = new Cartographic(); const scratchTimeInterval = new TimeInterval(); const scratchQuaternion = new Quaternion(); function unwrapColorInterval(czmlInterval) { let rgbaf = czmlInterval.rgbaf; if (defined(rgbaf)) { return rgbaf; } const rgba = czmlInterval.rgba; if (!defined(rgba)) { return undefined; } const length = rgba.length; if (length === Color.packedLength) { return [ Color.byteToFloat(rgba[0]), Color.byteToFloat(rgba[1]), Color.byteToFloat(rgba[2]), Color.byteToFloat(rgba[3]), ]; } rgbaf = new Array(length); for (let i = 0; i < length; i += 5) { rgbaf[i] = rgba[i]; rgbaf[i + 1] = Color.byteToFloat(rgba[i + 1]); rgbaf[i + 2] = Color.byteToFloat(rgba[i + 2]); rgbaf[i + 3] = Color.byteToFloat(rgba[i + 3]); rgbaf[i + 4] = Color.byteToFloat(rgba[i + 4]); } return rgbaf; } function unwrapUriInterval(czmlInterval, sourceUri) { const uri = defaultValue(czmlInterval.uri, czmlInterval); if (defined(sourceUri)) { return sourceUri.getDerivedResource({ url: uri, }); } return Resource.createIfNeeded(uri); } function unwrapRectangleInterval(czmlInterval) { let wsen = czmlInterval.wsen; if (defined(wsen)) { return wsen; } const wsenDegrees = czmlInterval.wsenDegrees; if (!defined(wsenDegrees)) { return undefined; } const length = wsenDegrees.length; if (length === Rectangle.packedLength) { return [ CesiumMath.toRadians(wsenDegrees[0]), CesiumMath.toRadians(wsenDegrees[1]), CesiumMath.toRadians(wsenDegrees[2]), CesiumMath.toRadians(wsenDegrees[3]), ]; } wsen = new Array(length); for (let i = 0; i < length; i += 5) { wsen[i] = wsenDegrees[i]; wsen[i + 1] = CesiumMath.toRadians(wsenDegrees[i + 1]); wsen[i + 2] = CesiumMath.toRadians(wsenDegrees[i + 2]); wsen[i + 3] = CesiumMath.toRadians(wsenDegrees[i + 3]); wsen[i + 4] = CesiumMath.toRadians(wsenDegrees[i + 4]); } return wsen; } function convertUnitSphericalToCartesian(unitSpherical) { const length = unitSpherical.length; scratchSpherical.magnitude = 1.0; if (length === 2) { scratchSpherical.clock = unitSpherical[0]; scratchSpherical.cone = unitSpherical[1]; Cartesian3.fromSpherical(scratchSpherical, scratchCartesian); return [scratchCartesian.x, scratchCartesian.y, scratchCartesian.z]; } const result = new Array((length / 3) * 4); for (let i = 0, j = 0; i < length; i += 3, j += 4) { result[j] = unitSpherical[i]; scratchSpherical.clock = unitSpherical[i + 1]; scratchSpherical.cone = unitSpherical[i + 2]; Cartesian3.fromSpherical(scratchSpherical, scratchCartesian); result[j + 1] = scratchCartesian.x; result[j + 2] = scratchCartesian.y; result[j + 3] = scratchCartesian.z; } return result; } function convertSphericalToCartesian(spherical) { const length = spherical.length; if (length === 3) { scratchSpherical.clock = spherical[0]; scratchSpherical.cone = spherical[1]; scratchSpherical.magnitude = spherical[2]; Cartesian3.fromSpherical(scratchSpherical, scratchCartesian); return [scratchCartesian.x, scratchCartesian.y, scratchCartesian.z]; } const result = new Array(length); for (let i = 0; i < length; i += 4) { result[i] = spherical[i]; scratchSpherical.clock = spherical[i + 1]; scratchSpherical.cone = spherical[i + 2]; scratchSpherical.magnitude = spherical[i + 3]; Cartesian3.fromSpherical(scratchSpherical, scratchCartesian); result[i + 1] = scratchCartesian.x; result[i + 2] = scratchCartesian.y; result[i + 3] = scratchCartesian.z; } return result; } function convertCartographicRadiansToCartesian(cartographicRadians) { const length = cartographicRadians.length; if (length === 3) { scratchCartographic.longitude = cartographicRadians[0]; scratchCartographic.latitude = cartographicRadians[1]; scratchCartographic.height = cartographicRadians[2]; Ellipsoid.WGS84.cartographicToCartesian( scratchCartographic, scratchCartesian ); return [scratchCartesian.x, scratchCartesian.y, scratchCartesian.z]; } const result = new Array(length); for (let i = 0; i < length; i += 4) { result[i] = cartographicRadians[i]; scratchCartographic.longitude = cartographicRadians[i + 1]; scratchCartographic.latitude = cartographicRadians[i + 2]; scratchCartographic.height = cartographicRadians[i + 3]; Ellipsoid.WGS84.cartographicToCartesian( scratchCartographic, scratchCartesian ); result[i + 1] = scratchCartesian.x; result[i + 2] = scratchCartesian.y; result[i + 3] = scratchCartesian.z; } return result; } function convertCartographicDegreesToCartesian(cartographicDegrees) { const length = cartographicDegrees.length; if (length === 3) { scratchCartographic.longitude = CesiumMath.toRadians( cartographicDegrees[0] ); scratchCartographic.latitude = CesiumMath.toRadians(cartographicDegrees[1]); scratchCartographic.height = cartographicDegrees[2]; Ellipsoid.WGS84.cartographicToCartesian( scratchCartographic, scratchCartesian ); return [scratchCartesian.x, scratchCartesian.y, scratchCartesian.z]; } const result = new Array(length); for (let i = 0; i < length; i += 4) { result[i] = cartographicDegrees[i]; scratchCartographic.longitude = CesiumMath.toRadians( cartographicDegrees[i + 1] ); scratchCartographic.latitude = CesiumMath.toRadians( cartographicDegrees[i + 2] ); scratchCartographic.height = cartographicDegrees[i + 3]; Ellipsoid.WGS84.cartographicToCartesian( scratchCartographic, scratchCartesian ); result[i + 1] = scratchCartesian.x; result[i + 2] = scratchCartesian.y; result[i + 3] = scratchCartesian.z; } return result; } function unwrapCartesianInterval(czmlInterval) { const cartesian = czmlInterval.cartesian; if (defined(cartesian)) { return cartesian; } const cartesianVelocity = czmlInterval.cartesianVelocity; if (defined(cartesianVelocity)) { return cartesianVelocity; } const unitCartesian = czmlInterval.unitCartesian; if (defined(unitCartesian)) { return unitCartesian; } const unitSpherical = czmlInterval.unitSpherical; if (defined(unitSpherical)) { return convertUnitSphericalToCartesian(unitSpherical); } const spherical = czmlInterval.spherical; if (defined(spherical)) { return convertSphericalToCartesian(spherical); } const cartographicRadians = czmlInterval.cartographicRadians; if (defined(cartographicRadians)) { return convertCartographicRadiansToCartesian(cartographicRadians); } const cartographicDegrees = czmlInterval.cartographicDegrees; if (defined(cartographicDegrees)) { return convertCartographicDegreesToCartesian(cartographicDegrees); } throw new RuntimeError( `${JSON.stringify(czmlInterval)} is not a valid CZML interval.` ); } function normalizePackedCartesianArray(array, startingIndex) { Cartesian3.unpack(array, startingIndex, scratchCartesian); Cartesian3.normalize(scratchCartesian, scratchCartesian); Cartesian3.pack(scratchCartesian, array, startingIndex); } function unwrapUnitCartesianInterval(czmlInterval) { const cartesian = unwrapCartesianInterval(czmlInterval); if (cartesian.length === 3) { normalizePackedCartesianArray(cartesian, 0); return cartesian; } for (let i = 1; i < cartesian.length; i += 4) { normalizePackedCartesianArray(cartesian, i); } return cartesian; } function normalizePackedQuaternionArray(array, startingIndex) { Quaternion.unpack(array, startingIndex, scratchQuaternion); Quaternion.normalize(scratchQuaternion, scratchQuaternion); Quaternion.pack(scratchQuaternion, array, startingIndex); } function unwrapQuaternionInterval(czmlInterval) { const unitQuaternion = czmlInterval.unitQuaternion; if (defined(unitQuaternion)) { if (unitQuaternion.length === 4) { normalizePackedQuaternionArray(unitQuaternion, 0); return unitQuaternion; } for (let i = 1; i < unitQuaternion.length; i += 5) { normalizePackedQuaternionArray(unitQuaternion, i); } } return unitQuaternion; } function getPropertyType(czmlInterval) { // The associations in this function need to be kept in sync with the // associations in unwrapInterval. // Intentionally omitted due to conficts in CZML property names: // * Image (conflicts with Uri) // * Rotation (conflicts with Number) // // cartesianVelocity is also omitted due to incomplete support for // derivative information in CZML properties. // (Currently cartesianVelocity is hacked directly into the position processing code) if (typeof czmlInterval === "boolean") { return Boolean; } else if (typeof czmlInterval === "number") { return Number; } else if (typeof czmlInterval === "string") { return String; } else if (czmlInterval.hasOwnProperty("array")) { return Array; } else if (czmlInterval.hasOwnProperty("boolean")) { return Boolean; } else if (czmlInterval.hasOwnProperty("boundingRectangle")) { return BoundingRectangle; } else if (czmlInterval.hasOwnProperty("cartesian2")) { return Cartesian2; } else if ( czmlInterval.hasOwnProperty("cartesian") || czmlInterval.hasOwnProperty("spherical") || czmlInterval.hasOwnProperty("cartographicRadians") || czmlInterval.hasOwnProperty("cartographicDegrees") ) { return Cartesian3; } else if ( czmlInterval.hasOwnProperty("unitCartesian") || czmlInterval.hasOwnProperty("unitSpherical") ) { return UnitCartesian3; } else if ( czmlInterval.hasOwnProperty("rgba") || czmlInterval.hasOwnProperty("rgbaf") ) { return Color; } else if (czmlInterval.hasOwnProperty("arcType")) { return ArcType; } else if (czmlInterval.hasOwnProperty("classificationType")) { return ClassificationType; } else if (czmlInterval.hasOwnProperty("colorBlendMode")) { return ColorBlendMode; } else if (czmlInterval.hasOwnProperty("cornerType")) { return CornerType; } else if (czmlInterval.hasOwnProperty("heightReference")) { return HeightReference; } else if (czmlInterval.hasOwnProperty("horizontalOrigin")) { return HorizontalOrigin; } else if (czmlInterval.hasOwnProperty("date")) { return JulianDate; } else if (czmlInterval.hasOwnProperty("labelStyle")) { return LabelStyle; } else if (czmlInterval.hasOwnProperty("number")) { return Number; } else if (czmlInterval.hasOwnProperty("nearFarScalar")) { return NearFarScalar; } else if (czmlInterval.hasOwnProperty("distanceDisplayCondition")) { return DistanceDisplayCondition; } else if ( czmlInterval.hasOwnProperty("object") || czmlInterval.hasOwnProperty("value") ) { return Object; } else if (czmlInterval.hasOwnProperty("unitQuaternion")) { return Quaternion; } else if (czmlInterval.hasOwnProperty("shadowMode")) { return ShadowMode; } else if (czmlInterval.hasOwnProperty("string")) { return String; } else if (czmlInterval.hasOwnProperty("stripeOrientation")) { return StripeOrientation; } else if ( czmlInterval.hasOwnProperty("wsen") || czmlInterval.hasOwnProperty("wsenDegrees") ) { return Rectangle; } else if (czmlInterval.hasOwnProperty("uri")) { return Uri; } else if (czmlInterval.hasOwnProperty("verticalOrigin")) { return VerticalOrigin; } // fallback case return Object; } function unwrapInterval(type, czmlInterval, sourceUri) { // The associations in this function need to be kept in sync with the // associations in getPropertyType switch (type) { case ArcType: return ArcType[defaultValue(czmlInterval.arcType, czmlInterval)]; case Array: return czmlInterval.array; case Boolean: return defaultValue(czmlInterval["boolean"], czmlInterval); case BoundingRectangle: return czmlInterval.boundingRectangle; case Cartesian2: return czmlInterval.cartesian2; case Cartesian3: return unwrapCartesianInterval(czmlInterval); case UnitCartesian3: return unwrapUnitCartesianInterval(czmlInterval); case Color: return unwrapColorInterval(czmlInterval); case ClassificationType: return ClassificationType[ defaultValue(czmlInterval.classificationType, czmlInterval) ]; case ColorBlendMode: return ColorBlendMode[ defaultValue(czmlInterval.colorBlendMode, czmlInterval) ]; case CornerType: return CornerType[defaultValue(czmlInterval.cornerType, czmlInterval)]; case HeightReference: return HeightReference[ defaultValue(czmlInterval.heightReference, czmlInterval) ]; case HorizontalOrigin: return HorizontalOrigin[ defaultValue(czmlInterval.horizontalOrigin, czmlInterval) ]; case Image: return unwrapUriInterval(czmlInterval, sourceUri); case JulianDate: return JulianDate.fromIso8601( defaultValue(czmlInterval.date, czmlInterval) ); case LabelStyle: return LabelStyle[defaultValue(czmlInterval.labelStyle, czmlInterval)]; case Number: return defaultValue(czmlInterval.number, czmlInterval); case NearFarScalar: return czmlInterval.nearFarScalar; case DistanceDisplayCondition: return czmlInterval.distanceDisplayCondition; case Object: return defaultValue( defaultValue(czmlInterval.object, czmlInterval.value), czmlInterval ); case Quaternion: return unwrapQuaternionInterval(czmlInterval); case Rotation: return defaultValue(czmlInterval.number, czmlInterval); case ShadowMode: return ShadowMode[ defaultValue( defaultValue(czmlInterval.shadowMode, czmlInterval.shadows), czmlInterval ) ]; case String: return defaultValue(czmlInterval.string, czmlInterval); case StripeOrientation: return StripeOrientation[ defaultValue(czmlInterval.stripeOrientation, czmlInterval) ]; case Rectangle: return unwrapRectangleInterval(czmlInterval); case Uri: return unwrapUriInterval(czmlInterval, sourceUri); case VerticalOrigin: return VerticalOrigin[ defaultValue(czmlInterval.verticalOrigin, czmlInterval) ]; default: throw new RuntimeError(type); } } const interpolators = { HERMITE: HermitePolynomialApproximation, LAGRANGE: LagrangePolynomialApproximation, LINEAR: LinearApproximation, }; function updateInterpolationSettings(packetData, property) { const interpolationAlgorithm = packetData.interpolationAlgorithm; const interpolationDegree = packetData.interpolationDegree; if (defined(interpolationAlgorithm) || defined(interpolationDegree)) { property.setInterpolationOptions({ interpolationAlgorithm: interpolators[interpolationAlgorithm], interpolationDegree: interpolationDegree, }); } const forwardExtrapolationType = packetData.forwardExtrapolationType; if (defined(forwardExtrapolationType)) { property.forwardExtrapolationType = ExtrapolationType[forwardExtrapolationType]; } const forwardExtrapolationDuration = packetData.forwardExtrapolationDuration; if (defined(forwardExtrapolationDuration)) { property.forwardExtrapolationDuration = forwardExtrapolationDuration; } const backwardExtrapolationType = packetData.backwardExtrapolationType; if (defined(backwardExtrapolationType)) { property.backwardExtrapolationType = ExtrapolationType[backwardExtrapolationType]; } const backwardExtrapolationDuration = packetData.backwardExtrapolationDuration; if (defined(backwardExtrapolationDuration)) { property.backwardExtrapolationDuration = backwardExtrapolationDuration; } } const iso8601Scratch = { iso8601: undefined, }; function intervalFromString(intervalString) { if (!defined(intervalString)) { return undefined; } iso8601Scratch.iso8601 = intervalString; return TimeInterval.fromIso8601(iso8601Scratch); } function wrapPropertyInInfiniteInterval(property) { const interval = Iso8601.MAXIMUM_INTERVAL.clone(); interval.data = property; return interval; } function convertPropertyToComposite(property) { // Create the composite and add the old property, wrapped in an infinite interval. const composite = new CompositeProperty(); composite.intervals.addInterval(wrapPropertyInInfiniteInterval(property)); return composite; } function convertPositionPropertyToComposite(property) { // Create the composite and add the old property, wrapped in an infinite interval. const composite = new CompositePositionProperty(property.referenceFrame); composite.intervals.addInterval(wrapPropertyInInfiniteInterval(property)); return composite; } function processProperty( type, object, propertyName, packetData, constrainedInterval, sourceUri, entityCollection ) { let combinedInterval = intervalFromString(packetData.interval); if (defined(constrainedInterval)) { if (defined(combinedInterval)) { combinedInterval = TimeInterval.intersect( combinedInterval, constrainedInterval, scratchTimeInterval ); } else { combinedInterval = constrainedInterval; } } let packedLength; let unwrappedInterval; let unwrappedIntervalLength; // CZML properties can be defined in many ways. Most ways represent a structure for // encoding a single value (number, string, cartesian, etc.) Regardless of the value type, // if it encodes a single value it will get loaded into a ConstantProperty eventually. // Alternatively, there are ways of defining a property that require specialized // client-side representation. Currently, these are ReferenceProperty, // and client-side velocity computation properties such as VelocityVectorProperty. const isValue = !defined(packetData.reference) && !defined(packetData.velocityReference); const 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); } let isSampled = false; if (isValue) { unwrappedInterval = unwrapInterval(type, packetData, sourceUri); if (!defined(unwrappedInterval)) { // not a known value type, bail return; } 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. const needsUnpacking = typeof type.unpack === "function" && type !== Rotation; // 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 ); } else { object[propertyName] = createSpecializedProperty( type, entityCollection, packetData ); } return; } let property = object[propertyName]; let epoch; const packetEpoch = packetData.epoch; if (defined(packetEpoch)) { epoch = JulianDate.fromIso8601(packetEpoch); } // 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)) { object[propertyName] = property = new SampledProperty(type); } property.addSamplesPackedArray(unwrappedInterval, epoch); updateInterpolationSettings(packetData, property); return; } let 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. 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 (!defined(property)) { object[propertyName] = property = isValue ? new TimeIntervalCollectionProperty() : new CompositeProperty(); } if (isValue && property instanceof TimeIntervalCollectionProperty) { // If we created a collection, or it already was one, use it. property.intervals.addInterval(combinedInterval); } else if (property instanceof CompositeProperty) { // 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. object[propertyName] = property = convertPropertyToComposite(property); // Change the new data to a ConstantProperty and add it. if (isValue) { combinedInterval.data = new ConstantProperty(combinedInterval.data); } property.intervals.addInterval(combinedInterval); } return; } // isSampled && hasInterval if (!defined(property)) { object[propertyName] = property = new CompositeProperty(); } // Create a CompositeProperty but preserve the existing data. if (!(property instanceof CompositeProperty)) { object[propertyName] = property = convertPropertyToComposite(property); } // Check if the interval already exists in the composite. const intervals = property.intervals; interval = intervals.findInterval(combinedInterval); if (!defined(interval) || !(interval.data instanceof SampledProperty)) { // If not, create a SampledProperty for it. interval = combinedInterval.clone(); interval.data = new SampledProperty(type); intervals.addInterval(interval); } interval.data.addSamplesPackedArray(unwrappedInterval, epoch); 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) { const intervals = property.intervals; for (let i = 0; i < intervals.length; ++i) { const 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; } if (Array.isArray(packetData)) { for (let i = 0, len = packetData.length; i < len; ++i) { processProperty( type, object, propertyName, packetData[i], interval, sourceUri, entityCollection ); } } else { processProperty( type, object, propertyName, packetData, interval, sourceUri, entityCollection ); } } function processPositionProperty( object, propertyName, packetData, constrainedInterval, sourceUri, entityCollection ) { let combinedInterval = intervalFromString(packetData.interval); if (defined(constrainedInterval)) { if (defined(combinedInterval)) { combinedInterval = TimeInterval.intersect( combinedInterval, constrainedInterval, scratchTimeInterval ); } else { combinedInterval = constrainedInterval; } } const numberOfDerivatives = defined(packetData.cartesianVelocity) ? 1 : 0; const packedLength = Cartesian3.packedLength * (numberOfDerivatives + 1); let unwrappedInterval; let unwrappedIntervalLength; const isValue = !defined(packetData.reference); const 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); } let referenceFrame; let isSampled = false; if (isValue) { if (defined(packetData.referenceFrame)) { referenceFrame = ReferenceFrame[packetData.referenceFrame]; } referenceFrame = defaultValue(referenceFrame, ReferenceFrame.FIXED); unwrappedInterval = unwrapCartesianInterval(packetData); unwrappedIntervalLength = defaultValue(unwrappedInterval.length, 1); isSampled = unwrappedIntervalLength > packedLength; } // 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 ); } else { object[propertyName] = createReferenceProperty( entityCollection, packetData.reference ); } return; } let property = object[propertyName]; let epoch; const packetEpoch = packetData.epoch; if (defined(packetEpoch)) { epoch = JulianDate.fromIso8601(packetEpoch); } // 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) ) { object[propertyName] = property = new SampledPositionProperty( referenceFrame, numberOfDerivatives ); } property.addSamplesPackedArray(unwrappedInterval, epoch); updateInterpolationSettings(packetData, property); return; } let 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. 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 (!defined(property)) { if (isValue) { property = new TimeIntervalCollectionPositionProperty(referenceFrame); } else { property = new CompositePositionProperty(referenceFrame); } object[propertyName] = property; } if ( isValue && property instanceof TimeIntervalCollectionPositionProperty && defined(referenceFrame) && property.referenceFrame === referenceFrame ) { // 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 (isValue) { combinedInterval.data = new ConstantPositionProperty( combinedInterval.data, referenceFrame ); } property.intervals.addInterval(combinedInterval); } else { // Otherwise, create a CompositePositionProperty but preserve the existing data. object[propertyName] = property = convertPositionPropertyToComposite( property ); // Change the new data to a ConstantPositionProperty and add it. if (isValue) { combinedInterval.data = new ConstantPositionProperty( combinedInterval.data, referenceFrame ); } property.intervals.addInterval(combinedInterval); } return; } // isSampled && hasInterval if (!defined(property)) { object[propertyName] = property = new CompositePositionProperty( referenceFrame ); } else if (!(property instanceof CompositePositionProperty)) { // Create a CompositeProperty but preserve the existing data. object[propertyName] = property = convertPositionPropertyToComposite( property ); } // Check if the interval already exists in the composite. const intervals = property.intervals; interval = intervals.findInterval(combinedInterval); if ( !defined(interval) || !(interval.data instanceof SampledPositionProperty) || (defined(referenceFrame) && interval.data.referenceFrame !== referenceFrame) ) { // If not, create a SampledPositionProperty for it. interval = combinedInterval.clone(); interval.data = new SampledPositionProperty( referenceFrame, numberOfDerivatives ); intervals.addInterval(interval); } interval.data.addSamplesPackedArray(unwrappedInterval, epoch); 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) { const intervals = property.intervals; for (let i = 0; i < intervals.length; ++i) { const 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; } if (Array.isArray(packetData)) { for (let i = 0, len = packetData.length; i < len; ++i) { processPositionProperty( object, propertyName, packetData[i], interval, sourceUri, entityCollection ); } } else { processPositionProperty( object, propertyName, packetData, interval, sourceUri, entityCollection ); } } function processShapePacketData( object, propertyName, packetData, entityCollection ) { if (defined(packetData.references)) { processReferencesArrayPacketData( object, propertyName, packetData.references, packetData.interval, entityCollection, PropertyArray, CompositeProperty ); } else { if (defined(packetData.cartesian2)) { packetData.array = Cartesian2.unpackArray(packetData.cartesian2); } else if (defined(packetData.cartesian)) { // for backwards compatibility, also accept `cartesian` packetData.array = Cartesian2.unpackArray(packetData.cartesian); } if (defined(packetData.array)) { processPacketData( Array, object, propertyName, packetData, undefined, undefined, entityCollection ); } } } function processMaterialProperty( object, propertyName, packetData, constrainedInterval, sourceUri, entityCollection ) { let combinedInterval = intervalFromString(packetData.interval); if (defined(constrainedInterval)) { if (defined(combinedInterval)) { combinedInterval = TimeInterval.intersect( combinedInterval, constrainedInterval, scratchTimeInterval ); } else { combinedInterval = constrainedInterval; } } let property = object[propertyName]; let existingMaterial; let existingInterval; if (defined(combinedInterval)) { if (!(property instanceof CompositeMaterialProperty)) { property = new CompositeMaterialProperty(); object[propertyName] = property; } //See if we already have data at that interval. const thisIntervals = property.intervals; existingInterval = thisIntervals.findInterval({ start: combinedInterval.start, stop: combinedInterval.stop, }); if (defined(existingInterval)) { //We have an interval, but we need to make sure the //new data is the same type of material as the old data. existingMaterial = existingInterval.data; } else { //If not, create it. existingInterval = combinedInterval.clone(); thisIntervals.addInterval(existingInterval); } } else { existingMaterial = property; } let materialData; if (defined(packetData.solidColor)) { if (!(existingMaterial instanceof ColorMaterialProperty)) { existingMaterial = new ColorMaterialProperty(); } materialData = packetData.solidColor; processPacketData( Color, existingMaterial, "color", materialData.color, undefined, undefined, entityCollection ); } else if (defined(packetData.grid)) { if (!(existingMaterial instanceof GridMaterialProperty)) { existingMaterial = new GridMaterialProperty(); } materialData = packetData.grid; processPacketData( Color, existingMaterial, "color", materialData.color, undefined, sourceUri, entityCollection ); processPacketData( Number, existingMaterial, "cellAlpha", materialData.cellAlpha, undefined, sourceUri, entityCollection ); processPacketData( Cartesian2, existingMaterial, "lineCount", materialData.lineCount, undefined, sourceUri, entityCollection ); processPacketData( Cartesian2, existingMaterial, "lineThickness", materialData.lineThickness, undefined, sourceUri, entityCollection ); processPacketData( Cartesian2, existingMaterial, "lineOffset", materialData.lineOffset, undefined, sourceUri, entityCollection ); } else if (defined(packetData.image)) { if (!(existingMaterial instanceof ImageMaterialProperty)) { existingMaterial = new ImageMaterialProperty(); } materialData = packetData.image; processPacketData( Image, existingMaterial, "image", materialData.image, undefined, sourceUri, entityCollection ); processPacketData( Cartesian2, existingMaterial, "repeat", materialData.repeat, undefined, sourceUri, entityCollection ); processPacketData( Color, existingMaterial, "color", materialData.color, undefined, sourceUri, entityCollection ); processPacketData( Boolean, existingMaterial, "transparent", materialData.transparent, undefined, sourceUri, entityCollection ); } else if (defined(packetData.stripe)) { if (!(existingMaterial instanceof StripeMaterialProperty)) { existingMaterial = new StripeMaterialProperty(); } materialData = packetData.stripe; processPacketData( StripeOrientation, existingMaterial, "orientation", materialData.orientation, undefined, sourceUri, entityCollection ); processPacketData( Color, existingMaterial, "evenColor", materialData.evenColor, undefined, sourceUri, entityCollection ); processPacketData( Color, existingMaterial, "oddColor", materialData.oddColor, undefined, sourceUri, entityCollection ); processPacketData( Number, existingMaterial, "offset", materialData.offset, undefined, sourceUri, entityCollection ); processPacketData( Number, existingMaterial, "repeat", materialData.repeat, undefined, sourceUri, entityCollection ); } else if (defined(packetData.polylineOutline)) { if (!(existingMaterial instanceof PolylineOutlineMaterialProperty)) { existingMaterial = new PolylineOutlineMaterialProperty(); } materialData = packetData.polylineOutline; processPacketData( Color, existingMaterial, "color", materialData.color, undefined, sourceUri, entityCollection ); processPacketData( Color, existingMaterial, "outlineColor", materialData.outlineColor, undefined, sourceUri, entityCollection ); processPacketData( Number, existingMaterial, "outlineWidth", materialData.outlineWidth, undefined, sourceUri, entityCollection ); } else if (defined(packetData.polylineGlow)) { if (!(existingMaterial instanceof PolylineGlowMaterialProperty)) { existingMaterial = new PolylineGlowMaterialProperty(); } materialData = packetData.polylineGlow; processPacketData( Color, existingMaterial, "color", materialData.color, undefined, sourceUri, entityCollection ); processPacketData( Number, existingMaterial, "glowPower", materialData.glowPower, undefined, sourceUri, entityCollection ); processPacketData( Number, existingMaterial, "taperPower", materialData.taperPower, undefined, sourceUri, entityCollection ); } else if (defined(packetData.polylineArrow)) { if (!(existingMaterial instanceof PolylineArrowMaterialProperty)) { existingMaterial = new PolylineArrowMaterialProperty(); } materialData = packetData.polylineArrow; processPacketData( Color, existingMaterial, "color", materialData.color, undefined, undefined, entityCollection ); } else if (defined(packetData.polylineDash)) { if (!(existingMaterial instanceof PolylineDashMaterialProperty)) { existingMaterial = new PolylineDashMaterialProperty(); } materialData = packetData.polylineDash; processPacketData( Color, existingMaterial, "color", materialData.color, undefined, undefined, entityCollection ); processPacketData( Color, existingMaterial, "gapColor", materialData.gapColor, undefined, undefined, entityCollection ); processPacketData( Number, existingMaterial, "dashLength", materialData.dashLength, undefined, sourceUri, entityCollection ); processPacketData( Number, existingMaterial, "dashPattern", materialData.dashPattern, undefined, sourceUri, entityCollection ); } else if (defined(packetData.checkerboard)) { if (!(existingMaterial instanceof CheckerboardMaterialProperty)) { existingMaterial = new CheckerboardMaterialProperty(); } materialData = packetData.checkerboard; processPacketData( Color, existingMaterial, "evenColor", materialData.evenColor, undefined, sourceUri, entityCollection ); processPacketData( Color, existingMaterial, "oddColor", materialData.oddColor, undefined, sourceUri, entityCollection ); processPacketData( Cartesian2, existingMaterial, "repeat", materialData.repeat, undefined, sourceUri, entityCollection ); } if (defined(existingInterval)) { existingInterval.data = existingMaterial; } else { object[propertyName] = existingMaterial; } } function processMaterialPacketData( object, propertyName, packetData, interval, sourceUri, entityCollection ) { if (!defined(packetData)) { return; } if (Array.isArray(packetData)) { for (let i = 0, len = packetData.length; i < len; ++i) { processMaterialProperty( object, propertyName, packetData[i], interval, sourceUri, entityCollection ); } } else { processMaterialProperty( object, propertyName, packetData, interval, sourceUri, entityCollection ); } } function processName(entity, packet, entityCollection, sourceUri) { const nameData = packet.name; if (defined(nameData)) { entity.name = packet.name; } } function processDescription(entity, packet, entityCollection, sourceUri) { const descriptionData = packet.description; if (defined(descriptionData)) { processPacketData( String, entity, "description", descriptionData, undefined, sourceUri, entityCollection ); } } function processPosition(entity, packet, entityCollection, sourceUri) { const positionData = packet.position; if (defined(positionData)) { processPositionPacketData( entity, "position", positionData, undefined, sourceUri, entityCollection ); } } function processViewFrom(entity, packet, entityCollection, sourceUri) { const viewFromData = packet.viewFrom; if (defined(viewFromData)) { processPacketData( Cartesian3, entity, "viewFrom", viewFromData, undefined, sourceUri, entityCollection ); } } function processOrientation(entity, packet, entityCollection, sourceUri) { const orientationData = packet.orientation; if (defined(orientationData)) { processPacketData( Quaternion, entity, "orientation", orientationData, undefined, sourceUri, entityCollection ); } } function processProperties(entity, packet, entityCollection, sourceUri) { const propertiesData = packet.properties; if (defined(propertiesData)) { if (!defined(entity.properties)) { entity.properties = new PropertyBag(); } // We cannot simply call processPacketData(entity, 'properties', propertyData, undefined, sourceUri, entityCollection) // because each property of "properties" may vary separately. // The properties will be accessible as entity.properties.myprop.getValue(time). for (const key in propertiesData) { if (propertiesData.hasOwnProperty(key)) { if (!entity.properties.hasProperty(key)) { entity.properties.addProperty(key); } const propertyData = propertiesData[key]; if (Array.isArray(propertyData)) { for (let i = 0, len = propertyData.length; i < len; ++i) { processProperty( getPropertyType(propertyData[i]), entity.properties, key, propertyData[i], undefined, sourceUri, entityCollection ); } } else { processProperty( getPropertyType(propertyData), entity.properties, key, propertyData, undefined, sourceUri, entityCollection ); } } } } } function processReferencesArrayPacketData( object, propertyName, references, interval, entityCollection, PropertyArrayType, CompositePropertyArrayType ) { const properties = references.map(function (reference) { return createReferenceProperty(entityCollection, reference); }); if (defined(interval)) { interval = intervalFromString(interval); let property = object[propertyName]; if (!(property instanceof CompositePropertyArrayType)) { // If the property was not already a CompositeProperty, // create a CompositeProperty but preserve the existing data. // Create the composite and add the old property, wrapped in an infinite interval. const composite = new CompositePropertyArrayType(); composite.intervals.addInterval(wrapPropertyInInfiniteInterval(property)); object[propertyName] = property = composite; } interval.data = new PropertyArrayType(properties); property.intervals.addInterval(interval); } else { object[propertyName] = new PropertyArrayType(properties); } } function processArrayPacketData( object, propertyName, packetData, entityCollection ) { const references = packetData.references; if (defined(references)) { processReferencesArrayPacketData( object, propertyName, references, packetData.interval, entityCollection, PropertyArray, CompositeProperty ); } else { processPacketData( Array, object, propertyName, packetData, undefined, undefined, entityCollection ); } } function processArray(object, propertyName, packetData, entityCollection) { if (!defined(packetData)) { return; } if (Array.isArray(packetData)) { for (let i = 0, length = packetData.length; i < length; ++i) { processArrayPacketData( object, propertyName, packetData[i], entityCollection ); } } else { processArrayPacketData(object, propertyName, packetData, entityCollection); } } function processPositionArrayPacketData( object, propertyName, packetData, entityCollection ) { const references = packetData.references; if (defined(references)) { processReferencesArrayPacketData( object, propertyName, references, packetData.interval, entityCollection, PositionPropertyArray, CompositePositionProperty ); } else { if (defined(packetData.cartesian)) { packetData.array = Cartesian3.unpackArray(packetData.cartesian); } else if (defined(packetData.cartographicRadians)) { packetData.array = Cartesian3.fromRadiansArrayHeights( packetData.cartographicRadians ); } else if (defined(packetData.cartographicDegrees)) { packetData.array = Cartesian3.fromDegreesArrayHeights( packetData.cartographicDegrees ); } if (defined(packetData.array)) { processPacketData( Array, object, propertyName, packetData, undefined, undefined, entityCollection ); } } } function processPositionArray( object, propertyName, packetData, entityCollection ) { if (!defined(packetData)) { return; } if (Array.isArray(packetData)) { for (let i = 0, length = packetData.length; i < length; ++i) { processPositionArrayPacketData( object, propertyName, packetData[i], entityCollection ); } } else { processPositionArrayPacketData( object, propertyName, packetData, entityCollection ); } } function unpackCartesianArray(array) { return Cartesian3.unpackArray(array); } function unpackCartographicRadiansArray(array) { return Cartesian3.fromRadiansArrayHeights(array); } function unpackCartographicDegreesArray(array) { return Cartesian3.fromDegreesArrayHeights(array); } function processPositionArrayOfArraysPacketData( object, propertyName, packetData, entityCollection ) { const references = packetData.references; if (defined(references)) { const properties = references.map(function (referenceArray) { const tempObj = {}; processReferencesArrayPacketData( tempObj, "positions", referenceArray, packetData.interval, entityCollection, PositionPropertyArray, CompositePositionProperty ); return tempObj.positions; }); object[propertyName] = new PositionPropertyArray(properties); } else { if (defined(packetData.cartesian)) { packetData.array = packetData.cartesian.map(unpackCartesianArray); } else if (defined(packetData.cartographicRadians)) { packetData.array = packetData.cartographicRadians.map( unpackCartographicRadiansArray ); } else if (defined(packetData.cartographicDegrees)) { packetData.array = packetData.cartographicDegrees.map( unpackCartographicDegreesArray ); } if (defined(packetData.array)) { processPacketData( Array, object, propertyName, packetData, undefined, undefined, entityCollection ); } } } function processPositionArrayOfArrays( object, propertyName, packetData, entityCollection ) { if (!defined(packetData)) { return; } if (Array.isArray(packetData)) { for (let i = 0, length = packetData.length; i < length; ++i) { processPositionArrayOfArraysPacketData( object, propertyName, packetData[i], entityCollection ); } } else { processPositionArrayOfArraysPacketData( object, propertyName, packetData, entityCollection ); } } function processShape(object, propertyName, packetData, entityCollection) { if (!defined(packetData)) { return; } if (Array.isArray(packetData)) { for (let i = 0, length = packetData.length; i < length; i++) { processShapePacketData( object, propertyName, packetData[i], entityCollection ); } } else { processShapePacketData(object, propertyName, packetData, entityCollection); } } function processAvailability(entity, packet, entityCollection, sourceUri) { const packetData = packet.availability; if (!defined(packetData)) { return; } let intervals; if (Array.isArray(packetData)) { for (let i = 0, len = packetData.length; i < len; ++i) { if (!defined(intervals)) { intervals = new TimeIntervalCollection(); } intervals.addInterval(intervalFromString(packetData[i])); } } else { intervals = new TimeIntervalCollection(); intervals.addInterval(intervalFromString(packetData)); } entity.availability = intervals; } function processAlignedAxis( billboard, packetData, interval, sourceUri, entityCollection ) { if (!defined(packetData)) { return; } processPacketData( UnitCartesian3, billboard, "alignedAxis", packetData, interval, sourceUri, entityCollection ); } function processBillboard(entity, packet, entityCollection, sourceUri) { const billboardData = packet.billboard; if (!defined(billboardData)) { return; } const interval = intervalFromString(billboardData.interval); let billboard = entity.billboard; if (!defined(billboard)) { entity.billboard = billboard = new BillboardGraphics(); } processPacketData( Boolean, billboard, "show", billboardData.show, interval, sourceUri, entityCollection ); processPacketData( Image, billboard, "image", billboardData.image, interval, sourceUri, entityCollection ); processPacketData( Number, billboard, "scale", billboardData.scale, interval, sourceUri, entityCollection ); processPacketData( Cartesian2, billboard, "pixelOffset", billboardData.pixelOffset, interval, sourceUri, entityCollection ); processPacketData( Cartesian3, billboard, "eyeOffset", billboardData.eyeOffset, interval, sourceUri, entityCollection ); processPacketData( HorizontalOrigin, billboard, "horizontalOrigin", billboardData.horizontalOrigin, interval, sourceUri, entityCollection ); processPacketData( VerticalOrigin, billboard, "verticalOrigin", billboardData.verticalOrigin, interval, sourceUri, entityCollection ); processPacketData( HeightReference, billboard, "heightReference", billboardData.heightReference, interval, sourceUri, entityCollection ); processPacketData( Color, billboard, "color", billboardData.color, interval, sourceUri, entityCollection ); processPacketData( Rotation, billboard, "rotation", billboardData.rotation, interval, sourceUri, entityCollection ); processAlignedAxis( billboard, billboardData.alignedAxis, interval, sourceUri, entityCollection ); processPacketData( Boolean, billboard, "sizeInMeters", billboardData.sizeInMeters, interval, sourceUri, entityCollection ); processPacketData( Number, billboard, "width", billboardData.width, interval, sourceUri, entityCollection ); processPacketData( Number, billboard, "height", billboardData.height, interval, sourceUri, entityCollection ); processPacketData( NearFarScalar, billboard, "scaleByDistance", billboardData.scaleByDistance, interval, sourceUri, entityCollection ); processPacketData( NearFarScalar, billboard, "translucencyByDistance", billboardData.translucencyByDistance, interval, sourceUri, entityCollection ); processPacketData( NearFarScalar, billboard, "pixelOffsetScaleByDistance", billboardData.pixelOffsetScaleByDistance, interval, sourceUri, entityCollection ); processPacketData( BoundingRectangle, billboard, "imageSubRegion", billboardData.imageSubRegion, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, billboard, "distanceDisplayCondition", billboardData.distanceDisplayCondition, interval, sourceUri, entityCollection ); processPacketData( Number, billboard, "disableDepthTestDistance", billboardData.disableDepthTestDistance, interval, sourceUri, entityCollection ); } function processBox(entity, packet, entityCollection, sourceUri) { const boxData = packet.box; if (!defined(boxData)) { return; } const interval = intervalFromString(boxData.interval); let box = entity.box; if (!defined(box)) { entity.box = box = new BoxGraphics(); } processPacketData( Boolean, box, "show", boxData.show, interval, sourceUri, entityCollection ); processPacketData( Cartesian3, box, "dimensions", boxData.dimensions, interval, sourceUri, entityCollection ); processPacketData( HeightReference, box, "heightReference", boxData.heightReference, interval, sourceUri, entityCollection ); processPacketData( Boolean, box, "fill", boxData.fill, interval, sourceUri, entityCollection ); processMaterialPacketData( box, "material", boxData.material, interval, sourceUri, entityCollection ); processPacketData( Boolean, box, "outline", boxData.outline, interval, sourceUri, entityCollection ); processPacketData( Color, box, "outlineColor", boxData.outlineColor, interval, sourceUri, entityCollection ); processPacketData( Number, box, "outlineWidth", boxData.outlineWidth, interval, sourceUri, entityCollection ); processPacketData( ShadowMode, box, "shadows", boxData.shadows, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, box, "distanceDisplayCondition", boxData.distanceDisplayCondition, interval, sourceUri, entityCollection ); } function processCorridor(entity, packet, entityCollection, sourceUri) { const corridorData = packet.corridor; if (!defined(corridorData)) { return; } const interval = intervalFromString(corridorData.interval); let corridor = entity.corridor; if (!defined(corridor)) { entity.corridor = corridor = new CorridorGraphics(); } processPacketData( Boolean, corridor, "show", corridorData.show, interval, sourceUri, entityCollection ); processPositionArray( corridor, "positions", corridorData.positions, entityCollection ); processPacketData( Number, corridor, "width", corridorData.width, interval, sourceUri, entityCollection ); processPacketData( Number, corridor, "height", corridorData.height, interval, sourceUri, entityCollection ); processPacketData( HeightReference, corridor, "heightReference", corridorData.heightReference, interval, sourceUri, entityCollection ); processPacketData( Number, corridor, "extrudedHeight", corridorData.extrudedHeight, interval, sourceUri, entityCollection ); processPacketData( HeightReference, corridor, "extrudedHeightReference", corridorData.extrudedHeightReference, interval, sourceUri, entityCollection ); processPacketData( CornerType, corridor, "cornerType", corridorData.cornerType, interval, sourceUri, entityCollection ); processPacketData( Number, corridor, "granularity", corridorData.granularity, interval, sourceUri, entityCollection ); processPacketData( Boolean, corridor, "fill", corridorData.fill, interval, sourceUri, entityCollection ); processMaterialPacketData( corridor, "material", corridorData.material, interval, sourceUri, entityCollection ); processPacketData( Boolean, corridor, "outline", corridorData.outline, interval, sourceUri, entityCollection ); processPacketData( Color, corridor, "outlineColor", corridorData.outlineColor, interval, sourceUri, entityCollection ); processPacketData( Number, corridor, "outlineWidth", corridorData.outlineWidth, interval, sourceUri, entityCollection ); processPacketData( ShadowMode, corridor, "shadows", corridorData.shadows, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, corridor, "distanceDisplayCondition", corridorData.distanceDisplayCondition, interval, sourceUri, entityCollection ); processPacketData( ClassificationType, corridor, "classificationType", corridorData.classificationType, interval, sourceUri, entityCollection ); processPacketData( Number, corridor, "zIndex", corridorData.zIndex, interval, sourceUri, entityCollection ); } function processCylinder(entity, packet, entityCollection, sourceUri) { const cylinderData = packet.cylinder; if (!defined(cylinderData)) { return; } const interval = intervalFromString(cylinderData.interval); let cylinder = entity.cylinder; if (!defined(cylinder)) { entity.cylinder = cylinder = new CylinderGraphics(); } processPacketData( Boolean, cylinder, "show", cylinderData.show, interval, sourceUri, entityCollection ); processPacketData( Number, cylinder, "length", cylinderData.length, interval, sourceUri, entityCollection ); processPacketData( Number, cylinder, "topRadius", cylinderData.topRadius, interval, sourceUri, entityCollection ); processPacketData( Number, cylinder, "bottomRadius", cylinderData.bottomRadius, interval, sourceUri, entityCollection ); processPacketData( HeightReference, cylinder, "heightReference", cylinderData.heightReference, interval, sourceUri, entityCollection ); processPacketData( Boolean, cylinder, "fill", cylinderData.fill, interval, sourceUri, entityCollection ); processMaterialPacketData( cylinder, "material", cylinderData.material, interval, sourceUri, entityCollection ); processPacketData( Boolean, cylinder, "outline", cylinderData.outline, interval, sourceUri, entityCollection ); processPacketData( Color, cylinder, "outlineColor", cylinderData.outlineColor, interval, sourceUri, entityCollection ); processPacketData( Number, cylinder, "outlineWidth", cylinderData.outlineWidth, interval, sourceUri, entityCollection ); processPacketData( Number, cylinder, "numberOfVerticalLines", cylinderData.numberOfVerticalLines, interval, sourceUri, entityCollection ); processPacketData( Number, cylinder, "slices", cylinderData.slices, interval, sourceUri, entityCollection ); processPacketData( ShadowMode, cylinder, "shadows", cylinderData.shadows, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, cylinder, "distanceDisplayCondition", cylinderData.distanceDisplayCondition, interval, sourceUri, entityCollection ); } function processDocument(packet, dataSource) { const version = packet.version; if (defined(version)) { if (typeof version === "string") { const tokens = version.split("."); if (tokens.length === 2) { if (tokens[0] !== "1") { throw new RuntimeError("Cesium only supports CZML version 1."); } dataSource._version = version; } } } if (!defined(dataSource._version)) { throw new RuntimeError( "CZML version information invalid. It is expected to be a property on the document object in the . version format." ); } const documentPacket = dataSource._documentPacket; if (defined(packet.name)) { documentPacket.name = packet.name; } const clockPacket = packet.clock; if (defined(clockPacket)) { const clock = documentPacket.clock; if (!defined(clock)) { documentPacket.clock = { interval: clockPacket.interval, currentTime: clockPacket.currentTime, range: clockPacket.range, step: clockPacket.step, multiplier: clockPacket.multiplier, }; } else { clock.interval = defaultValue(clockPacket.interval, clock.interval); clock.currentTime = defaultValue( clockPacket.currentTime, clock.currentTime ); clock.range = defaultValue(clockPacket.range, clock.range); clock.step = defaultValue(clockPacket.step, clock.step); clock.multiplier = defaultValue(clockPacket.multiplier, clock.multiplier); } } } function processEllipse(entity, packet, entityCollection, sourceUri) { const ellipseData = packet.ellipse; if (!defined(ellipseData)) { return; } const interval = intervalFromString(ellipseData.interval); let ellipse = entity.ellipse; if (!defined(ellipse)) { entity.ellipse = ellipse = new EllipseGraphics(); } processPacketData( Boolean, ellipse, "show", ellipseData.show, interval, sourceUri, entityCollection ); processPacketData( Number, ellipse, "semiMajorAxis", ellipseData.semiMajorAxis, interval, sourceUri, entityCollection ); processPacketData( Number, ellipse, "semiMinorAxis", ellipseData.semiMinorAxis, interval, sourceUri, entityCollection ); processPacketData( Number, ellipse, "height", ellipseData.height, interval, sourceUri, entityCollection ); processPacketData( HeightReference, ellipse, "heightReference", ellipseData.heightReference, interval, sourceUri, entityCollection ); processPacketData( Number, ellipse, "extrudedHeight", ellipseData.extrudedHeight, interval, sourceUri, entityCollection ); processPacketData( HeightReference, ellipse, "extrudedHeightReference", ellipseData.extrudedHeightReference, interval, sourceUri, entityCollection ); processPacketData( Rotation, ellipse, "rotation", ellipseData.rotation, interval, sourceUri, entityCollection ); processPacketData( Rotation, ellipse, "stRotation", ellipseData.stRotation, interval, sourceUri, entityCollection ); processPacketData( Number, ellipse, "granularity", ellipseData.granularity, interval, sourceUri, entityCollection ); processPacketData( Boolean, ellipse, "fill", ellipseData.fill, interval, sourceUri, entityCollection ); processMaterialPacketData( ellipse, "material", ellipseData.material, interval, sourceUri, entityCollection ); processPacketData( Boolean, ellipse, "outline", ellipseData.outline, interval, sourceUri, entityCollection ); processPacketData( Color, ellipse, "outlineColor", ellipseData.outlineColor, interval, sourceUri, entityCollection ); processPacketData( Number, ellipse, "outlineWidth", ellipseData.outlineWidth, interval, sourceUri, entityCollection ); processPacketData( Number, ellipse, "numberOfVerticalLines", ellipseData.numberOfVerticalLines, interval, sourceUri, entityCollection ); processPacketData( ShadowMode, ellipse, "shadows", ellipseData.shadows, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, ellipse, "distanceDisplayCondition", ellipseData.distanceDisplayCondition, interval, sourceUri, entityCollection ); processPacketData( ClassificationType, ellipse, "classificationType", ellipseData.classificationType, interval, sourceUri, entityCollection ); processPacketData( Number, ellipse, "zIndex", ellipseData.zIndex, interval, sourceUri, entityCollection ); } function processEllipsoid(entity, packet, entityCollection, sourceUri) { const ellipsoidData = packet.ellipsoid; if (!defined(ellipsoidData)) { return; } const interval = intervalFromString(ellipsoidData.interval); let ellipsoid = entity.ellipsoid; if (!defined(ellipsoid)) { entity.ellipsoid = ellipsoid = new EllipsoidGraphics(); } processPacketData( Boolean, ellipsoid, "show", ellipsoidData.show, interval, sourceUri, entityCollection ); processPacketData( Cartesian3, ellipsoid, "radii", ellipsoidData.radii, interval, sourceUri, entityCollection ); processPacketData( Cartesian3, ellipsoid, "innerRadii", ellipsoidData.innerRadii, interval, sourceUri, entityCollection ); processPacketData( Number, ellipsoid, "minimumClock", ellipsoidData.minimumClock, interval, sourceUri, entityCollection ); processPacketData( Number, ellipsoid, "maximumClock", ellipsoidData.maximumClock, interval, sourceUri, entityCollection ); processPacketData( Number, ellipsoid, "minimumCone", ellipsoidData.minimumCone, interval, sourceUri, entityCollection ); processPacketData( Number, ellipsoid, "maximumCone", ellipsoidData.maximumCone, interval, sourceUri, entityCollection ); processPacketData( HeightReference, ellipsoid, "heightReference", ellipsoidData.heightReference, interval, sourceUri, entityCollection ); processPacketData( Boolean, ellipsoid, "fill", ellipsoidData.fill, interval, sourceUri, entityCollection ); processMaterialPacketData( ellipsoid, "material", ellipsoidData.material, interval, sourceUri, entityCollection ); processPacketData( Boolean, ellipsoid, "outline", ellipsoidData.outline, interval, sourceUri, entityCollection ); processPacketData( Color, ellipsoid, "outlineColor", ellipsoidData.outlineColor, interval, sourceUri, entityCollection ); processPacketData( Number, ellipsoid, "outlineWidth", ellipsoidData.outlineWidth, interval, sourceUri, entityCollection ); processPacketData( Number, ellipsoid, "stackPartitions", ellipsoidData.stackPartitions, interval, sourceUri, entityCollection ); processPacketData( Number, ellipsoid, "slicePartitions", ellipsoidData.slicePartitions, interval, sourceUri, entityCollection ); processPacketData( Number, ellipsoid, "subdivisions", ellipsoidData.subdivisions, interval, sourceUri, entityCollection ); processPacketData( ShadowMode, ellipsoid, "shadows", ellipsoidData.shadows, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, ellipsoid, "distanceDisplayCondition", ellipsoidData.distanceDisplayCondition, interval, sourceUri, entityCollection ); } function processLabel(entity, packet, entityCollection, sourceUri) { const labelData = packet.label; if (!defined(labelData)) { return; } const interval = intervalFromString(labelData.interval); let label = entity.label; if (!defined(label)) { entity.label = label = new LabelGraphics(); } processPacketData( Boolean, label, "show", labelData.show, interval, sourceUri, entityCollection ); processPacketData( String, label, "text", labelData.text, interval, sourceUri, entityCollection ); processPacketData( String, label, "font", labelData.font, interval, sourceUri, entityCollection ); processPacketData( LabelStyle, label, "style", labelData.style, interval, sourceUri, entityCollection ); processPacketData( Number, label, "scale", labelData.scale, interval, sourceUri, entityCollection ); processPacketData( Boolean, label, "showBackground", labelData.showBackground, interval, sourceUri, entityCollection ); processPacketData( Color, label, "backgroundColor", labelData.backgroundColor, interval, sourceUri, entityCollection ); processPacketData( Cartesian2, label, "backgroundPadding", labelData.backgroundPadding, interval, sourceUri, entityCollection ); processPacketData( Cartesian2, label, "pixelOffset", labelData.pixelOffset, interval, sourceUri, entityCollection ); processPacketData( Cartesian3, label, "eyeOffset", labelData.eyeOffset, interval, sourceUri, entityCollection ); processPacketData( HorizontalOrigin, label, "horizontalOrigin", labelData.horizontalOrigin, interval, sourceUri, entityCollection ); processPacketData( VerticalOrigin, label, "verticalOrigin", labelData.verticalOrigin, interval, sourceUri, entityCollection ); processPacketData( HeightReference, label, "heightReference", labelData.heightReference, interval, sourceUri, entityCollection ); processPacketData( Color, label, "fillColor", labelData.fillColor, interval, sourceUri, entityCollection ); processPacketData( Color, label, "outlineColor", labelData.outlineColor, interval, sourceUri, entityCollection ); processPacketData( Number, label, "outlineWidth", labelData.outlineWidth, interval, sourceUri, entityCollection ); processPacketData( NearFarScalar, label, "translucencyByDistance", labelData.translucencyByDistance, interval, sourceUri, entityCollection ); processPacketData( NearFarScalar, label, "pixelOffsetScaleByDistance", labelData.pixelOffsetScaleByDistance, interval, sourceUri, entityCollection ); processPacketData( NearFarScalar, label, "scaleByDistance", labelData.scaleByDistance, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, label, "distanceDisplayCondition", labelData.distanceDisplayCondition, interval, sourceUri, entityCollection ); processPacketData( Number, label, "disableDepthTestDistance", labelData.disableDepthTestDistance, interval, sourceUri, entityCollection ); } function processModel(entity, packet, entityCollection, sourceUri) { const modelData = packet.model; if (!defined(modelData)) { return; } const interval = intervalFromString(modelData.interval); let model = entity.model; if (!defined(model)) { entity.model = model = new ModelGraphics(); } processPacketData( Boolean, model, "show", modelData.show, interval, sourceUri, entityCollection ); processPacketData( Uri, model, "uri", modelData.gltf, interval, sourceUri, entityCollection ); processPacketData( Number, model, "scale", modelData.scale, interval, sourceUri, entityCollection ); processPacketData( Number, model, "minimumPixelSize", modelData.minimumPixelSize, interval, sourceUri, entityCollection ); processPacketData( Number, model, "maximumScale", modelData.maximumScale, interval, sourceUri, entityCollection ); processPacketData( Boolean, model, "incrementallyLoadTextures", modelData.incrementallyLoadTextures, interval, sourceUri, entityCollection ); processPacketData( Boolean, model, "runAnimations", modelData.runAnimations, interval, sourceUri, entityCollection ); processPacketData( Boolean, model, "clampAnimations", modelData.clampAnimations, interval, sourceUri, entityCollection ); processPacketData( ShadowMode, model, "shadows", modelData.shadows, interval, sourceUri, entityCollection ); processPacketData( HeightReference, model, "heightReference", modelData.heightReference, interval, sourceUri, entityCollection ); processPacketData( Color, model, "silhouetteColor", modelData.silhouetteColor, interval, sourceUri, entityCollection ); processPacketData( Number, model, "silhouetteSize", modelData.silhouetteSize, interval, sourceUri, entityCollection ); processPacketData( Color, model, "color", modelData.color, interval, sourceUri, entityCollection ); processPacketData( ColorBlendMode, model, "colorBlendMode", modelData.colorBlendMode, interval, sourceUri, entityCollection ); processPacketData( Number, model, "colorBlendAmount", modelData.colorBlendAmount, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, model, "distanceDisplayCondition", modelData.distanceDisplayCondition, interval, sourceUri, entityCollection ); let i, len; const nodeTransformationsData = modelData.nodeTransformations; if (defined(nodeTransformationsData)) { if (Array.isArray(nodeTransformationsData)) { for (i = 0, len = nodeTransformationsData.length; i < len; ++i) { processNodeTransformations( model, nodeTransformationsData[i], interval, sourceUri, entityCollection ); } } else { processNodeTransformations( model, nodeTransformationsData, interval, sourceUri, entityCollection ); } } const articulationsData = modelData.articulations; if (defined(articulationsData)) { if (Array.isArray(articulationsData)) { for (i = 0, len = articulationsData.length; i < len; ++i) { processArticulations( model, articulationsData[i], interval, sourceUri, entityCollection ); } } else { processArticulations( model, articulationsData, interval, sourceUri, entityCollection ); } } } function processNodeTransformations( model, nodeTransformationsData, constrainedInterval, sourceUri, entityCollection ) { let combinedInterval = intervalFromString(nodeTransformationsData.interval); if (defined(constrainedInterval)) { if (defined(combinedInterval)) { combinedInterval = TimeInterval.intersect( combinedInterval, constrainedInterval, scratchTimeInterval ); } else { combinedInterval = constrainedInterval; } } let nodeTransformations = model.nodeTransformations; const nodeNames = Object.keys(nodeTransformationsData); for (let i = 0, len = nodeNames.length; i < len; ++i) { const nodeName = nodeNames[i]; if (nodeName === "interval") { continue; } const nodeTransformationData = nodeTransformationsData[nodeName]; if (!defined(nodeTransformationData)) { continue; } if (!defined(nodeTransformations)) { model.nodeTransformations = nodeTransformations = new PropertyBag(); } if (!nodeTransformations.hasProperty(nodeName)) { nodeTransformations.addProperty(nodeName); } let nodeTransformation = nodeTransformations[nodeName]; if (!defined(nodeTransformation)) { nodeTransformations[ nodeName ] = nodeTransformation = new NodeTransformationProperty(); } processPacketData( Cartesian3, nodeTransformation, "translation", nodeTransformationData.translation, combinedInterval, sourceUri, entityCollection ); processPacketData( Quaternion, nodeTransformation, "rotation", nodeTransformationData.rotation, combinedInterval, sourceUri, entityCollection ); processPacketData( Cartesian3, nodeTransformation, "scale", nodeTransformationData.scale, combinedInterval, sourceUri, entityCollection ); } } function processArticulations( model, articulationsData, constrainedInterval, sourceUri, entityCollection ) { let combinedInterval = intervalFromString(articulationsData.interval); if (defined(constrainedInterval)) { if (defined(combinedInterval)) { combinedInterval = TimeInterval.intersect( combinedInterval, constrainedInterval, scratchTimeInterval ); } else { combinedInterval = constrainedInterval; } } let articulations = model.articulations; const keys = Object.keys(articulationsData); for (let i = 0, len = keys.length; i < len; ++i) { const key = keys[i]; if (key === "interval") { continue; } const articulationStageData = articulationsData[key]; if (!defined(articulationStageData)) { continue; } if (!defined(articulations)) { model.articulations = articulations = new PropertyBag(); } if (!articulations.hasProperty(key)) { articulations.addProperty(key); } processPacketData( Number, articulations, key, articulationStageData, combinedInterval, sourceUri, entityCollection ); } } function processPath(entity, packet, entityCollection, sourceUri) { const pathData = packet.path; if (!defined(pathData)) { return; } const interval = intervalFromString(pathData.interval); let path = entity.path; if (!defined(path)) { entity.path = path = new PathGraphics(); } processPacketData( Boolean, path, "show", pathData.show, interval, sourceUri, entityCollection ); processPacketData( Number, path, "leadTime", pathData.leadTime, interval, sourceUri, entityCollection ); processPacketData( Number, path, "trailTime", pathData.trailTime, interval, sourceUri, entityCollection ); processPacketData( Number, path, "width", pathData.width, interval, sourceUri, entityCollection ); processPacketData( Number, path, "resolution", pathData.resolution, interval, sourceUri, entityCollection ); processMaterialPacketData( path, "material", pathData.material, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, path, "distanceDisplayCondition", pathData.distanceDisplayCondition, interval, sourceUri, entityCollection ); } function processPoint(entity, packet, entityCollection, sourceUri) { const pointData = packet.point; if (!defined(pointData)) { return; } const interval = intervalFromString(pointData.interval); let point = entity.point; if (!defined(point)) { entity.point = point = new PointGraphics(); } processPacketData( Boolean, point, "show", pointData.show, interval, sourceUri, entityCollection ); processPacketData( Number, point, "pixelSize", pointData.pixelSize, interval, sourceUri, entityCollection ); processPacketData( HeightReference, point, "heightReference", pointData.heightReference, interval, sourceUri, entityCollection ); processPacketData( Color, point, "color", pointData.color, interval, sourceUri, entityCollection ); processPacketData( Color, point, "outlineColor", pointData.outlineColor, interval, sourceUri, entityCollection ); processPacketData( Number, point, "outlineWidth", pointData.outlineWidth, interval, sourceUri, entityCollection ); processPacketData( NearFarScalar, point, "scaleByDistance", pointData.scaleByDistance, interval, sourceUri, entityCollection ); processPacketData( NearFarScalar, point, "translucencyByDistance", pointData.translucencyByDistance, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, point, "distanceDisplayCondition", pointData.distanceDisplayCondition, interval, sourceUri, entityCollection ); processPacketData( Number, point, "disableDepthTestDistance", pointData.disableDepthTestDistance, interval, sourceUri, entityCollection ); } function PolygonHierarchyProperty(polygon) { this.polygon = polygon; this._definitionChanged = new Event(); } Object.defineProperties(PolygonHierarchyProperty.prototype, { isConstant: { get: function () { const positions = this.polygon._positions; const holes = this.polygon._holes; return ( (!defined(positions) || positions.isConstant) && (!defined(holes) || holes.isConstant) ); }, }, definitionChanged: { get: function () { return this._definitionChanged; }, }, }); PolygonHierarchyProperty.prototype.getValue = function (time, result) { let positions; if (defined(this.polygon._positions)) { positions = this.polygon._positions.getValue(time); } let holes; if (defined(this.polygon._holes)) { holes = this.polygon._holes.getValue(time); if (defined(holes)) { holes = holes.map(function (holePositions) { return new PolygonHierarchy(holePositions); }); } } if (!defined(result)) { return new PolygonHierarchy(positions, holes); } result.positions = positions; result.holes = holes; return result; }; PolygonHierarchyProperty.prototype.equals = function (other) { return ( this === other || (other instanceof PolygonHierarchyProperty && Property.equals(this.polygon._positions, other.polygon._positions) && Property.equals(this.polygon._holes, other.polygon._holes)) ); }; function processPolygon(entity, packet, entityCollection, sourceUri) { const polygonData = packet.polygon; if (!defined(polygonData)) { return; } const interval = intervalFromString(polygonData.interval); let polygon = entity.polygon; if (!defined(polygon)) { entity.polygon = polygon = new PolygonGraphics(); } processPacketData( Boolean, polygon, "show", polygonData.show, interval, sourceUri, entityCollection ); // adapt 'position' property producing Cartesian[] // and 'holes' property producing Cartesian[][] // to a single property producing PolygonHierarchy processPositionArray( polygon, "_positions", polygonData.positions, entityCollection ); processPositionArrayOfArrays( polygon, "_holes", polygonData.holes, entityCollection ); if (defined(polygon._positions) || defined(polygon._holes)) { polygon.hierarchy = new PolygonHierarchyProperty(polygon); } processPacketData( Number, polygon, "height", polygonData.height, interval, sourceUri, entityCollection ); processPacketData( HeightReference, polygon, "heightReference", polygonData.heightReference, interval, sourceUri, entityCollection ); processPacketData( Number, polygon, "extrudedHeight", polygonData.extrudedHeight, interval, sourceUri, entityCollection ); processPacketData( HeightReference, polygon, "extrudedHeightReference", polygonData.extrudedHeightReference, interval, sourceUri, entityCollection ); processPacketData( Rotation, polygon, "stRotation", polygonData.stRotation, interval, sourceUri, entityCollection ); processPacketData( Number, polygon, "granularity", polygonData.granularity, interval, sourceUri, entityCollection ); processPacketData( Boolean, polygon, "fill", polygonData.fill, interval, sourceUri, entityCollection ); processMaterialPacketData( polygon, "material", polygonData.material, interval, sourceUri, entityCollection ); processPacketData( Boolean, polygon, "outline", polygonData.outline, interval, sourceUri, entityCollection ); processPacketData( Color, polygon, "outlineColor", polygonData.outlineColor, interval, sourceUri, entityCollection ); processPacketData( Number, polygon, "outlineWidth", polygonData.outlineWidth, interval, sourceUri, entityCollection ); processPacketData( Boolean, polygon, "perPositionHeight", polygonData.perPositionHeight, interval, sourceUri, entityCollection ); processPacketData( Boolean, polygon, "closeTop", polygonData.closeTop, interval, sourceUri, entityCollection ); processPacketData( Boolean, polygon, "closeBottom", polygonData.closeBottom, interval, sourceUri, entityCollection ); processPacketData( ArcType, polygon, "arcType", polygonData.arcType, interval, sourceUri, entityCollection ); processPacketData( ShadowMode, polygon, "shadows", polygonData.shadows, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, polygon, "distanceDisplayCondition", polygonData.distanceDisplayCondition, interval, sourceUri, entityCollection ); processPacketData( ClassificationType, polygon, "classificationType", polygonData.classificationType, interval, sourceUri, entityCollection ); processPacketData( Number, polygon, "zIndex", polygonData.zIndex, interval, sourceUri, entityCollection ); } function adaptFollowSurfaceToArcType(followSurface) { return followSurface ? ArcType.GEODESIC : ArcType.NONE; } function processPolyline(entity, packet, entityCollection, sourceUri) { const polylineData = packet.polyline; if (!defined(polylineData)) { return; } const interval = intervalFromString(polylineData.interval); let polyline = entity.polyline; if (!defined(polyline)) { entity.polyline = polyline = new PolylineGraphics(); } processPacketData( Boolean, polyline, "show", polylineData.show, interval, sourceUri, entityCollection ); processPositionArray( polyline, "positions", polylineData.positions, entityCollection ); processPacketData( Number, polyline, "width", polylineData.width, interval, sourceUri, entityCollection ); processPacketData( Number, polyline, "granularity", polylineData.granularity, interval, sourceUri, entityCollection ); processMaterialPacketData( polyline, "material", polylineData.material, interval, sourceUri, entityCollection ); processMaterialPacketData( polyline, "depthFailMaterial", polylineData.depthFailMaterial, interval, sourceUri, entityCollection ); processPacketData( ArcType, polyline, "arcType", polylineData.arcType, interval, sourceUri, entityCollection ); processPacketData( Boolean, polyline, "clampToGround", polylineData.clampToGround, interval, sourceUri, entityCollection ); processPacketData( ShadowMode, polyline, "shadows", polylineData.shadows, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, polyline, "distanceDisplayCondition", polylineData.distanceDisplayCondition, interval, sourceUri, entityCollection ); processPacketData( ClassificationType, polyline, "classificationType", polylineData.classificationType, interval, sourceUri, entityCollection ); processPacketData( Number, polyline, "zIndex", polylineData.zIndex, interval, sourceUri, entityCollection ); // for backwards compatibility, adapt CZML followSurface to arcType. if (defined(polylineData.followSurface) && !defined(polylineData.arcType)) { const tempObj = {}; processPacketData( Boolean, tempObj, "followSurface", polylineData.followSurface, interval, sourceUri, entityCollection ); polyline.arcType = createAdapterProperty( tempObj.followSurface, adaptFollowSurfaceToArcType ); } } function processPolylineVolume(entity, packet, entityCollection, sourceUri) { const polylineVolumeData = packet.polylineVolume; if (!defined(polylineVolumeData)) { return; } const interval = intervalFromString(polylineVolumeData.interval); let polylineVolume = entity.polylineVolume; if (!defined(polylineVolume)) { entity.polylineVolume = polylineVolume = new PolylineVolumeGraphics(); } processPositionArray( polylineVolume, "positions", polylineVolumeData.positions, entityCollection ); processShape( polylineVolume, "shape", polylineVolumeData.shape, entityCollection ); processPacketData( Boolean, polylineVolume, "show", polylineVolumeData.show, interval, sourceUri, entityCollection ); processPacketData( CornerType, polylineVolume, "cornerType", polylineVolumeData.cornerType, interval, sourceUri, entityCollection ); processPacketData( Boolean, polylineVolume, "fill", polylineVolumeData.fill, interval, sourceUri, entityCollection ); processMaterialPacketData( polylineVolume, "material", polylineVolumeData.material, interval, sourceUri, entityCollection ); processPacketData( Boolean, polylineVolume, "outline", polylineVolumeData.outline, interval, sourceUri, entityCollection ); processPacketData( Color, polylineVolume, "outlineColor", polylineVolumeData.outlineColor, interval, sourceUri, entityCollection ); processPacketData( Number, polylineVolume, "outlineWidth", polylineVolumeData.outlineWidth, interval, sourceUri, entityCollection ); processPacketData( Number, polylineVolume, "granularity", polylineVolumeData.granularity, interval, sourceUri, entityCollection ); processPacketData( ShadowMode, polylineVolume, "shadows", polylineVolumeData.shadows, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, polylineVolume, "distanceDisplayCondition", polylineVolumeData.distanceDisplayCondition, interval, sourceUri, entityCollection ); } function processRectangle(entity, packet, entityCollection, sourceUri) { const rectangleData = packet.rectangle; if (!defined(rectangleData)) { return; } const interval = intervalFromString(rectangleData.interval); let rectangle = entity.rectangle; if (!defined(rectangle)) { entity.rectangle = rectangle = new RectangleGraphics(); } processPacketData( Boolean, rectangle, "show", rectangleData.show, interval, sourceUri, entityCollection ); processPacketData( Rectangle, rectangle, "coordinates", rectangleData.coordinates, interval, sourceUri, entityCollection ); processPacketData( Number, rectangle, "height", rectangleData.height, interval, sourceUri, entityCollection ); processPacketData( HeightReference, rectangle, "heightReference", rectangleData.heightReference, interval, sourceUri, entityCollection ); processPacketData( Number, rectangle, "extrudedHeight", rectangleData.extrudedHeight, interval, sourceUri, entityCollection ); processPacketData( HeightReference, rectangle, "extrudedHeightReference", rectangleData.extrudedHeightReference, interval, sourceUri, entityCollection ); processPacketData( Rotation, rectangle, "rotation", rectangleData.rotation, interval, sourceUri, entityCollection ); processPacketData( Rotation, rectangle, "stRotation", rectangleData.stRotation, interval, sourceUri, entityCollection ); processPacketData( Number, rectangle, "granularity", rectangleData.granularity, interval, sourceUri, entityCollection ); processPacketData( Boolean, rectangle, "fill", rectangleData.fill, interval, sourceUri, entityCollection ); processMaterialPacketData( rectangle, "material", rectangleData.material, interval, sourceUri, entityCollection ); processPacketData( Boolean, rectangle, "outline", rectangleData.outline, interval, sourceUri, entityCollection ); processPacketData( Color, rectangle, "outlineColor", rectangleData.outlineColor, interval, sourceUri, entityCollection ); processPacketData( Number, rectangle, "outlineWidth", rectangleData.outlineWidth, interval, sourceUri, entityCollection ); processPacketData( ShadowMode, rectangle, "shadows", rectangleData.shadows, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, rectangle, "distanceDisplayCondition", rectangleData.distanceDisplayCondition, interval, sourceUri, entityCollection ); processPacketData( ClassificationType, rectangle, "classificationType", rectangleData.classificationType, interval, sourceUri, entityCollection ); processPacketData( Number, rectangle, "zIndex", rectangleData.zIndex, interval, sourceUri, entityCollection ); } function processTileset(entity, packet, entityCollection, sourceUri) { const tilesetData = packet.tileset; if (!defined(tilesetData)) { return; } const interval = intervalFromString(tilesetData.interval); let tileset = entity.tileset; if (!defined(tileset)) { entity.tileset = tileset = new Cesium3DTilesetGraphics(); } processPacketData( Boolean, tileset, "show", tilesetData.show, interval, sourceUri, entityCollection ); processPacketData( Uri, tileset, "uri", tilesetData.uri, interval, sourceUri, entityCollection ); processPacketData( Number, tileset, "maximumScreenSpaceError", tilesetData.maximumScreenSpaceError, interval, sourceUri, entityCollection ); } function processWall(entity, packet, entityCollection, sourceUri) { const wallData = packet.wall; if (!defined(wallData)) { return; } const interval = intervalFromString(wallData.interval); let wall = entity.wall; if (!defined(wall)) { entity.wall = wall = new WallGraphics(); } processPacketData( Boolean, wall, "show", wallData.show, interval, sourceUri, entityCollection ); processPositionArray(wall, "positions", wallData.positions, entityCollection); processArray( wall, "minimumHeights", wallData.minimumHeights, entityCollection ); processArray( wall, "maximumHeights", wallData.maximumHeights, entityCollection ); processPacketData( Number, wall, "granularity", wallData.granularity, interval, sourceUri, entityCollection ); processPacketData( Boolean, wall, "fill", wallData.fill, interval, sourceUri, entityCollection ); processMaterialPacketData( wall, "material", wallData.material, interval, sourceUri, entityCollection ); processPacketData( Boolean, wall, "outline", wallData.outline, interval, sourceUri, entityCollection ); processPacketData( Color, wall, "outlineColor", wallData.outlineColor, interval, sourceUri, entityCollection ); processPacketData( Number, wall, "outlineWidth", wallData.outlineWidth, interval, sourceUri, entityCollection ); processPacketData( ShadowMode, wall, "shadows", wallData.shadows, interval, sourceUri, entityCollection ); processPacketData( DistanceDisplayCondition, wall, "distanceDisplayCondition", wallData.distanceDisplayCondition, interval, sourceUri, entityCollection ); } function processCzmlPacket( packet, entityCollection, updaterFunctions, sourceUri, dataSource ) { let objectId = packet.id; if (!defined(objectId)) { objectId = createGuid(); } currentId = objectId; if (!defined(dataSource._version) && objectId !== "document") { throw new RuntimeError( "The first CZML packet is required to be the document object." ); } if (packet["delete"] === true) { entityCollection.removeById(objectId); } else if (objectId === "document") { processDocument(packet, dataSource); } else { const entity = entityCollection.getOrCreateEntity(objectId); const parentId = packet.parent; if (defined(parentId)) { entity.parent = entityCollection.getOrCreateEntity(parentId); } for (let i = updaterFunctions.length - 1; i > -1; i--) { updaterFunctions[i](entity, packet, entityCollection, sourceUri); } } currentId = undefined; } function updateClock(dataSource) { let clock; const clockPacket = dataSource._documentPacket.clock; if (!defined(clockPacket)) { if (!defined(dataSource._clock)) { const availability = dataSource._entityCollection.computeAvailability(); if (!availability.start.equals(Iso8601.MINIMUM_VALUE)) { const startTime = availability.start; const stopTime = availability.stop; const totalSeconds = JulianDate.secondsDifference(stopTime, startTime); const multiplier = Math.round(totalSeconds / 120.0); clock = new DataSourceClock(); clock.startTime = JulianDate.clone(startTime); clock.stopTime = JulianDate.clone(stopTime); clock.clockRange = ClockRange.LOOP_STOP; clock.multiplier = multiplier; clock.currentTime = JulianDate.clone(startTime); clock.clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; dataSource._clock = clock; return true; } } return false; } if (defined(dataSource._clock)) { clock = dataSource._clock.clone(); } else { clock = new DataSourceClock(); clock.startTime = Iso8601.MINIMUM_VALUE.clone(); clock.stopTime = Iso8601.MAXIMUM_VALUE.clone(); clock.currentTime = Iso8601.MINIMUM_VALUE.clone(); clock.clockRange = ClockRange.LOOP_STOP; clock.clockStep = ClockStep.SYSTEM_CLOCK_MULTIPLIER; clock.multiplier = 1.0; } const interval = intervalFromString(clockPacket.interval); if (defined(interval)) { clock.startTime = interval.start; clock.stopTime = interval.stop; } if (defined(clockPacket.currentTime)) { clock.currentTime = JulianDate.fromIso8601(clockPacket.currentTime); } if (defined(clockPacket.range)) { clock.clockRange = defaultValue( ClockRange[clockPacket.range], ClockRange.LOOP_STOP ); } if (defined(clockPacket.step)) { clock.clockStep = defaultValue( ClockStep[clockPacket.step], ClockStep.SYSTEM_CLOCK_MULTIPLIER ); } if (defined(clockPacket.multiplier)) { clock.multiplier = clockPacket.multiplier; } if (!clock.equals(dataSource._clock)) { dataSource._clock = clock.clone(dataSource._clock); return true; } return false; } function load(dataSource, czml, options, clear) { //>>includeStart('debug', pragmas.debug); if (!defined(czml)) { throw new DeveloperError("czml is required."); } //>>includeEnd('debug'); options = defaultValue(options, defaultValue.EMPTY_OBJECT); let promise = czml; let sourceUri = options.sourceUri; // User specified credit let credit = options.credit; if (typeof credit === "string") { credit = new Credit(credit); } dataSource._credit = credit; // If the czml is a URL if (typeof czml === "string" || czml instanceof Resource) { czml = Resource.createIfNeeded(czml); promise = czml.fetchJson(); sourceUri = defaultValue(sourceUri, czml.clone()); // Add resource credits to our list of credits to display const resourceCredits = dataSource._resourceCredits; const credits = czml.credits; if (defined(credits)) { const length = credits.length; for (let i = 0; i < length; i++) { resourceCredits.push(credits[i]); } } } sourceUri = Resource.createIfNeeded(sourceUri); DataSource.setLoading(dataSource, true); return Promise.resolve(promise) .then(function (czml) { return loadCzml(dataSource, czml, sourceUri, clear); }) .catch(function (error) { DataSource.setLoading(dataSource, false); dataSource._error.raiseEvent(dataSource, error); console.log(error); return Promise.reject(error); }); } function loadCzml(dataSource, czml, sourceUri, clear) { DataSource.setLoading(dataSource, true); const entityCollection = dataSource._entityCollection; if (clear) { dataSource._version = undefined; dataSource._documentPacket = new DocumentPacket(); entityCollection.removeAll(); } CzmlDataSource._processCzml( czml, entityCollection, sourceUri, undefined, dataSource ); let raiseChangedEvent = updateClock(dataSource); const documentPacket = dataSource._documentPacket; if ( defined(documentPacket.name) && dataSource._name !== documentPacket.name ) { dataSource._name = documentPacket.name; raiseChangedEvent = true; } else if (!defined(dataSource._name) && defined(sourceUri)) { dataSource._name = getFilenameFromUri(sourceUri.getUrlComponent()); raiseChangedEvent = true; } DataSource.setLoading(dataSource, false); if (raiseChangedEvent) { dataSource._changed.raiseEvent(dataSource); } return dataSource; } function DocumentPacket() { this.name = undefined; this.clock = undefined; } /** * @typedef {object} CzmlDataSource.LoadOptions * * Initialization options for the load method. * * @property {Resource|string} [sourceUri] Overrides the url to use for resolving relative links. * @property {Credit|string} [credit] A credit for the data source, which is displayed on the canvas. */ /** * A {@link DataSource} which processes {@link https://github.com/AnalyticalGraphicsInc/czml-writer/wiki/CZML-Guide|CZML}. * @alias CzmlDataSource * @constructor * * @param {string} [name] An optional name for the data source. This value will be overwritten if a loaded document contains a name. * * @demo {@link https://sandcastle.cesium.com/index.html?src=CZML.html|Cesium Sandcastle CZML Demo} */ function CzmlDataSource(name) { this._name = name; this._changed = new Event(); this._error = new Event(); this._isLoading = false; this._loading = new Event(); this._clock = undefined; this._documentPacket = new DocumentPacket(); this._version = undefined; this._entityCollection = new EntityCollection(this); this._entityCluster = new EntityCluster(); this._credit = undefined; this._resourceCredits = []; } /** * Creates a Promise to a new instance loaded with the provided CZML data. * * @param {Resource|string|object} czml A url or CZML object to be processed. * @param {CzmlDataSource.LoadOptions} [options] An object specifying configuration options * * @returns {Promise} A promise that resolves to the new instance once the data is processed. */ CzmlDataSource.load = function (czml, options) { return new CzmlDataSource().load(czml, options); }; Object.defineProperties(CzmlDataSource.prototype, { /** * Gets a human-readable name for this instance. * @memberof CzmlDataSource.prototype * @type {string} */ name: { get: function () { return this._name; }, }, /** * Gets the clock settings defined by the loaded CZML. If no clock is explicitly * defined in the CZML, the combined availability of all objects is returned. If * only static data exists, this value is undefined. * @memberof CzmlDataSource.prototype * @type {DataSourceClock} */ clock: { get: function () { return this._clock; }, }, /** * Gets the collection of {@link Entity} instances. * @memberof CzmlDataSource.prototype * @type {EntityCollection} */ entities: { get: function () { return this._entityCollection; }, }, /** * Gets a value indicating if the data source is currently loading data. * @memberof CzmlDataSource.prototype * @type {boolean} */ isLoading: { get: function () { return this._isLoading; }, }, /** * Gets an event that will be raised when the underlying data changes. * @memberof CzmlDataSource.prototype * @type {Event} */ changedEvent: { get: function () { return this._changed; }, }, /** * Gets an event that will be raised if an error is encountered during processing. * @memberof CzmlDataSource.prototype * @type {Event} */ errorEvent: { get: function () { return this._error; }, }, /** * Gets an event that will be raised when the data source either starts or stops loading. * @memberof CzmlDataSource.prototype * @type {Event} */ loadingEvent: { get: function () { return this._loading; }, }, /** * Gets whether or not this data source should be displayed. * @memberof CzmlDataSource.prototype * @type {boolean} */ show: { get: function () { return this._entityCollection.show; }, set: function (value) { this._entityCollection.show = value; }, }, /** * Gets or sets the clustering options for this data source. This object can be shared between multiple data sources. * * @memberof CzmlDataSource.prototype * @type {EntityCluster} */ clustering: { get: function () { return this._entityCluster; }, set: function (value) { //>>includeStart('debug', pragmas.debug); if (!defined(value)) { throw new DeveloperError("value must be defined."); } //>>includeEnd('debug'); this._entityCluster = value; }, }, /** * Gets the credit that will be displayed for the data source * @memberof CzmlDataSource.prototype * @type {Credit} */ credit: { get: function () { return this._credit; }, }, }); /** * @callback CzmlDataSource.UpdaterFunction * * A CZML processing function that adds or updates entities in the provided * collection based on the provided CZML packet. * * @param {Entity} entity * @param {object} packet * @param {EntityCollection} entityCollection * @param {string} sourceUri */ /** * Gets the array of CZML processing functions. * @memberof CzmlDataSource * @type {CzmlDataSource.UpdaterFunction[]} */ CzmlDataSource.updaters = [ processBillboard, // processBox, // processCorridor, // processCylinder, // processEllipse, // processEllipsoid, // processLabel, // processModel, // processName, // processDescription, // processPath, // processPoint, // processPolygon, // processPolyline, // processPolylineVolume, // processProperties, // processRectangle, // processPosition, // processTileset, // processViewFrom, // processWall, // processOrientation, // processAvailability, ]; /** * Processes the provided url or CZML object without clearing any existing data. * * @param {Resource|string|object} czml A url or CZML object to be processed. * @param {CzmlDataSource.LoadOptions} [options] An object specifying configuration options * * @returns {Promise} A promise that resolves to this instances once the data is processed. */ CzmlDataSource.prototype.process = function (czml, options) { return load(this, czml, options, false); }; /** * Loads the provided url or CZML object, replacing any existing data. * * @param {Resource|string|object} czml A url or CZML object to be processed. * @param {CzmlDataSource.LoadOptions} [options] An object specifying configuration options * * @returns {Promise} A promise that resolves to this instances once the data is processed. */ CzmlDataSource.prototype.load = function (czml, options) { return load(this, czml, options, true); }; /** * Updates the data source to the provided time. This function is optional and * is not required to be implemented. It is provided for data sources which * retrieve data based on the current animation time or scene state. * If implemented, update will be called by {@link DataSourceDisplay} once a frame. * * @param {JulianDate} time The simulation time. * @returns {boolean} True if this data source is ready to be displayed at the provided time, false otherwise. */ CzmlDataSource.prototype.update = function (time) { return true; }; /** * A helper function used by custom CZML updater functions * which creates or updates a {@link Property} from a CZML packet. * @function * * @param {Function} type The constructor function for the property being processed. * @param {object} object The object on which the property will be added or updated. * @param {string} propertyName The name of the property on the object. * @param {object} packetData The CZML packet being processed. * @param {TimeInterval} interval A constraining interval for which the data is valid. * @param {string} sourceUri The originating uri of the data being processed. * @param {EntityCollection} entityCollection The collection being processsed. */ CzmlDataSource.processPacketData = processPacketData; /** * A helper function used by custom CZML updater functions * which creates or updates a {@link PositionProperty} from a CZML packet. * @function * * @param {object} object The object on which the property will be added or updated. * @param {string} propertyName The name of the property on the object. * @param {object} packetData The CZML packet being processed. * @param {TimeInterval} interval A constraining interval for which the data is valid. * @param {string} sourceUri The originating uri of the data being processed. * @param {EntityCollection} entityCollection The collection being processsed. */ CzmlDataSource.processPositionPacketData = processPositionPacketData; /** * A helper function used by custom CZML updater functions * which creates or updates a {@link MaterialProperty} from a CZML packet. * @function * * @param {object} object The object on which the property will be added or updated. * @param {string} propertyName The name of the property on the object. * @param {object} packetData The CZML packet being processed. * @param {TimeInterval} interval A constraining interval for which the data is valid. * @param {string} sourceUri The originating uri of the data being processed. * @param {EntityCollection} entityCollection The collection being processsed. */ CzmlDataSource.processMaterialPacketData = processMaterialPacketData; CzmlDataSource._processCzml = function ( czml, entityCollection, sourceUri, updaterFunctions, dataSource ) { updaterFunctions = defaultValue(updaterFunctions, CzmlDataSource.updaters); if (Array.isArray(czml)) { for (let i = 0, len = czml.length; i < len; ++i) { processCzmlPacket( czml[i], entityCollection, updaterFunctions, sourceUri, dataSource ); } } else { processCzmlPacket( czml, entityCollection, updaterFunctions, sourceUri, dataSource ); } }; export default CzmlDataSource;