This is the fourth day of my participation in Gwen Challenge.

preface

In recent days, I have studied how to realize the function of flying or roaming along the line in Cesium. I searched online and found that many bloggers’ solutions contain Property of whatever kind… Aroused my strong curiosity, so I went to the official website of Cesium to have a look, I was shocked by the first sentence.

All values we define for our entities are stored as Property objects.

All the values of the entity are maintained as Property objects, which forced me to look down, but the more I looked at it, the more angry I was that you didn’t say anything about something so important. You know what? I’ll do my own research.

What is the Property mechanism

Cesium’s Property is essentially similar to Object.defineProperties, which directly encapsulates the base type or, if Object, the reference form. Property encapsulation gives the designer the power to reference or copy, while providing some special functionality to meet the requirements.

Why Property

Let’s start with an example to briefly show what Property can do.

// Create the box
var box = viewer.entities.add({
    name: "box".position: Cesium.Cartesian3.fromDegrees(121.54035.38.92146.2000),
    box: {
        dimensions: new Cesium.Cartesian3(1000.0.1000.0.1000.0),}});Copy the code

If we want to change the size of the box over time, the first thought should be to use setInterval to change the dimensions of the box, but this is not a small performance challenge. Cesium provides a mechanism for it to automatically change and assign values over time, called Property. The following code changes the box size in 5 seconds.

var property = new Cesium.SampledProperty(Cesium.Cartesian3);

property.addSample(
    Cesium.JulianDate.fromDate(new Date()),
    new Cesium.Cartesian3(1000.0.1000.0.1000.0)); property.addSample( Cesium.JulianDate.addSeconds( Cesium.JulianDate.fromDate(new Date()),
        5.new Cesium.JulianDate()
    ),
    new Cesium.Cartesian3(2000.0.2000.0.2000.0)); box.box.dimensions = property;Copy the code

We use addSample to add a keyframe to the Property instance and define the properties we want to modify. Finally, we assign the value to dimensions of the box, which looks like this

So, Property can be associated with a timeline and return the corresponding Property value based on time, while Entity can dynamically change the location, size, etc., by returning the value.

Property classification and use method

The SampledProperty example we used above provides interpolation, and there are many Property types. We can search the API documentation for properties. There are 29 of them.

A simple classification can be divided into several categories:

  • Basic types:ConstantProperty.SampledProperty.TimeIntervalCollectionProperty.CompositeProperty
  • Other types:CallbackProperty.ReferenceProperty.PropertyArray.PropertyBag.VelocityOrientationProperty.VelocityVectorProperty
  • Material type:MaterialPropertyAnd those with the word material
  • Position type: with Position

Cesium also provides a Property class as a base class for all types and defines several common properties and interfaces.

– > Cartesian3 getValue (time, the result)

Gets the value of the property at a specific point in time

Name Type Description
time JulianDate The time to retrieve the value
result Cartesian3 The object to which values are stored. By default, a new instance is created and returned

equal

Used to determine whether attribute values are equal.

Next, let’s explain some common properties and code implementation.

Basic types of

SampledProperty

That’s what we used in the first example, to interpolate linearly between two points in time by adding samples at different points in time. I won’t do the demo here, the code and the effects are in the first example.

TimeIntervalCollectionProperty

This parameter specifies the value of an attribute in a specific time range. The value of an attribute in each time range remains unchanged. So unlike SampledProperty, it jumps.

var property = new Cesium.TimeIntervalCollectionProperty(
    Cesium.Cartesian3
);


property.intervals.addInterval(
    new Cesium.TimeInterval({
        start: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            2.new Cesium.JulianDate()
        ),
        stop: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            20.new Cesium.JulianDate()
        ),
        isStartIncluded:true.isStopIncluded:false.data: new Cesium.Cartesian3(1000.0.1000.0.1000.0),})); property.intervals.addInterval(new Cesium.TimeInterval({
        start: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            6.new Cesium.JulianDate()
        ),
        stop: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            20.new Cesium.JulianDate()
        ),
        isStartIncluded:true.isStopIncluded:false.data: new Cesium.Cartesian3(2000.0.2000.0.2000.0),})); property.intervals.addInterval(new Cesium.TimeInterval({
        start: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            10.new Cesium.JulianDate()
        ),
        stop: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            20.new Cesium.JulianDate()
        ),
        isStartIncluded:true.isStopIncluded:true.data: new Cesium.Cartesian3(3000.0.3000.0.3000.0),})); box.box.dimensions = property;Copy the code

ConstantProperty

A property that does not change over time.

A ConstantProperty is usually set as follows:

box.box.dimensions = new Cesium.Cartesian3(100.100.100);
Copy the code

But actually the full version would be:

box.box.dimensions = new ConstantProperty(new Cesium.Cartesian3(100.100.100));
Copy the code

We can see that the dismensions Property in box is actually a Property type, secretly converting Cartesian3 we passed into a ConstantProperty type inside Cesium.

ConstantProperty is not immutable. It provides a setValue method to modify the property value. Using setValue will modify the existing property value, rather than creating a new ConstantProperty.

CompositeProperty

As the name suggests, this is a compound Property that can be used to combine multiple properties, such as a jump over a period of time and then a smooth change. Look at the code:

var lineProperty = new Cesium.SampledProperty(Cesium.Cartesian3);

lineProperty.addSample(
    Cesium.JulianDate.fromDate(new Date()),
    new Cesium.Cartesian3(1000.0.1000.0.1000.0)); lineProperty.addSample( Cesium.JulianDate.addSeconds( Cesium.JulianDate.fromDate(new Date()),
        5.new Cesium.JulianDate()
    ),
    new Cesium.Cartesian3(3000.0.3000.0.3000.0));var timeProperty = new Cesium.TimeIntervalCollectionProperty(
    Cesium.Cartesian3
);

timeProperty.intervals.addInterval(
    new Cesium.TimeInterval({
        start: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            5.new Cesium.JulianDate()
        ),
        stop: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            20.new Cesium.JulianDate()
        ),
        isStartIncluded: true.isStopIncluded: false.data: new Cesium.Cartesian3(3000.0.3000.0.3000.0),})); timeProperty.intervals.addInterval(new Cesium.TimeInterval({
        start: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            10.new Cesium.JulianDate()
        ),
        stop: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            20.new Cesium.JulianDate()
        ),
        isStartIncluded: true.isStopIncluded: false.data: new Cesium.Cartesian3(4000.0.4000.0.4000.0),})); timeProperty.intervals.addInterval(new Cesium.TimeInterval({
        start: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            15.new Cesium.JulianDate()
        ),
        stop: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            20.new Cesium.JulianDate()
        ),
        isStartIncluded: true.isStopIncluded: true.data: new Cesium.Cartesian3(5000.0.5000.0.5000.0),}));var compositeProperty = new Cesium.CompositeProperty();
compositeProperty.intervals.addInterval(
    new Cesium.TimeInterval({
        start: Cesium.JulianDate.fromDate(new Date()),
        stop: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            5.new Cesium.JulianDate()
        ),
        isStartIncluded: false.isStopIncluded: false.data: lineProperty,
    })
);
compositeProperty.intervals.addInterval(
    new Cesium.TimeInterval({
        start: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            5.new Cesium.JulianDate()
        ),
        stop: Cesium.JulianDate.addSeconds(
            Cesium.JulianDate.fromDate(new Date()),
            20.new Cesium.JulianDate()
        ),
        isStartIncluded: false.isStopIncluded: false.data: timeProperty,
    })
);

box.box.dimensions = compositeProperty;
Copy the code

Position type

PositionProperty

Like Property, PositionProperty is a virtual base class that cannot be instantiated directly. It adds a referenceFrame that only represents position.

ReferenceFrame is used to capture the referenceFrame of position. Currently Cesium provides two kinds of reference frames, FIXED and inertialscene. The default FIXED reference frame is used, that is, the position of coordinates on the earth is FIXED.

There are several positionProperty-based types:

  • CompositePositionProperty
  • ConstantPositionProperty
  • PositionProperty
  • PositionPropertyArray
  • SampledPositionProperty
  • TimeIntervalCollectionPositionProperty

The usage is basically the same as the basic types, except that they are specifically used to represent location information. No examples here.

The material type

MaterialProperty

Specifically used to represent materials, extends the getType method to get the material type.

It also has many derived classes, such as ColorMaterialProperty, ImageMaterialProperty and so on, which we use in our demos and projects.

We can use basic types and material types to achieve a dynamic effect of a color.

var colorProperty = new Cesium.SampledProperty(Cesium.Color);

colorProperty.addSample(
    Cesium.JulianDate.fromDate(new Date()),
    new Cesium.Color(0.1.0)); colorProperty.addSample( Cesium.JulianDate.addSeconds( Cesium.JulianDate.fromDate(new Date()),
        5.new Cesium.JulianDate()
    ),
    new Cesium.Color(0.0.1)); box.box.material =new Cesium.ColorMaterialProperty(colorProperty);

Copy the code

Other types of

CallbackProperty

CallbackProperty is one of the most freedom types. We just need to provide a callback function to return the value we need. We can do whatever we want in the callback function. Here we implement a box that randomly changes color and keeps growing.

let l = 2000.0;
box.box.dimensions = new Cesium.CallbackProperty(function (time, result) {
    result = result || new Cesium.Cartesian3(0.0.0);

    l += 20.0;
    if (l > 7000.0) {
        l = 2000.0;
    }

    result.x = 4000.0;
    result.y = 3000.0;
    result.z = l;
    return result;
}, false);
box.box.material = new Cesium.ColorMaterialProperty(
    new Cesium.CallbackProperty(function () {
        return Cesium.Color.fromRandom({
            alpha: 1.0}); },false));Copy the code

ReferenceProperty

This property can be directly linked to another object’s property for reference effect.

parameter type describe
targetCollection EntityCollection The collection of referenced entities that will be used to resolve.
targetId String Id of the referenced entity.
targetPropertyNames Array. The name of the property on the target entity to be used.

PropertyBag

It is used to wrap an object so that each Property of the object can be modified as a dynamic Property. For example, when we changed Dimensions earlier, it was wrapped in Property as a Cartesian3 variable, if we only wanted to change x of Dimensions. This can be done using PropertyBag.

var zp = new Cesium.SampledProperty(Number);
zp.addSample(Cesium.JulianDate.fromDate(new Date()), 2000.0);
zp.addSample(Cesium.JulianDate.addSeconds(
    Cesium.JulianDate.fromDate(new Date()),
    5.new Cesium.JulianDate()
),, 7000.0);

box.box.dimensions = new Cesium.PropertyBag({
    x: 4000.0.y: 3000.0.z: zp
});
Copy the code

VelocityOrientationProperty

This Property is used to change the position of the Entity to calculate the moving direction, and finally output the speed direction into Orientation. There is a Interpolation in the Cesium example, which will not be repeated.

Usage scenarios

The Property mechanism is powerful and can be used in a variety of scenarios, such as implementing some sort of flight along the road, path roaming, or size attributes of entities. We can use it almost anywhere we want to modify properties.