Flatlogic Bot 055d24df95 WORKING
2025-10-14 02:37:44 +00:00

5172 lines
121 KiB
JavaScript

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";
import SensorVolumePortionToDisplay from "../Scene/SensorVolumePortionToDisplay.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 SensorVolumePortionToDisplay:
return SensorVolumePortionToDisplay[
defaultValue(czmlInterval.portionToDisplay, 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(`Unknown CzmlDataSource interval type: ${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,
Ellipsoid.WGS84
);
} else if (defined(packetData.cartographicDegrees)) {
packetData.array = Cartesian3.fromDegreesArrayHeights(
packetData.cartographicDegrees,
Ellipsoid.WGS84
);
}
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, Ellipsoid.WGS84);
}
function unpackCartographicDegreesArray(array) {
return Cartesian3.fromDegreesArrayHeights(array, Ellipsoid.WGS84);
}
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 <Major>.<Minor> 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 <code>load</code> 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<CzmlDataSource>} 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,
];
/**
* Add the provided updater to the list of updaters if not already included
* @private
* @param {CzmlDataSource.UpdaterFunction} updater
*/
CzmlDataSource.registerUpdater = function (updater) {
if (!CzmlDataSource.updaters.includes(updater)) {
CzmlDataSource.updaters.push(updater);
}
};
/**
* Remove the provided updater from the list of updaters if already included
* @private
* @param {CzmlDataSource.UpdaterFunction} updater
*/
CzmlDataSource.unregisterUpdater = function (updater) {
if (CzmlDataSource.updaters.includes(updater)) {
const index = CzmlDataSource.updaters.indexOf(updater);
CzmlDataSource.updaters.splice(index, 1);
}
};
/**
* 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<CzmlDataSource>} 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<CzmlDataSource>} 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;