Visualization with Cesium
In STK Components, the Cesium Library provides the ability to generate CZML content from Platforms and other DefinitionalObjects, as well as analysis derived from them. CZML is a JSON-based data format designed by AGI to load static and time-dynamic data into Cesium.
This topic assumes basic familiarity with Cesium. Cesium documentation, tutorials, and code samples are available separately from the Cesium site.
The Cesium Library is built upon the same design patterns used throughout STK Components. It provides ObjectExtensions that describe how CZML properties are defined over time. These extensions are then added to individual Platforms and other ExtensibleObjects. Effectively, these extensions add CZML visualization information to your existing objects, after which they can be added to a CzmlDocument and serialized to CZML.
To understand how this works in practice, the following code sample demonstrates how to draw a label at the location of the International Space Station, and draw its orbit.
CentralBody earth = CentralBodiesFacet.getFromContext().getEarth(); TwoLineElementSet issTle = new TwoLineElementSet("1 25544U 98067A 10172.34241898 .00007451 00000-0 60420-4 0 3627\r\n" + "2 25544 51.6459 209.3399 0009135 352.3227 186.5240 15.71934500664129"); Point issPoint = new Sgp4Propagator(issTle).createPoint(); Platform iss = new Platform(); iss.setName("ISS"); iss.setLocationPoint(issPoint); iss.setOrientationAxes(new AxesVehicleVelocityLocalHorizontal(earth.getFixedFrame(), issPoint)); LabelGraphics issLabel = new LabelGraphics(); issLabel.setText(new ConstantCesiumProperty<>(iss.getName())); issLabel.setFillColor(new ConstantCesiumProperty<>(Color.WHITE)); LabelGraphicsExtension labelExtension = new LabelGraphicsExtension(issLabel); iss.getExtensions().add(labelExtension); PolylineOutlineMaterialGraphics issPathMaterial = new PolylineOutlineMaterialGraphics(); issPathMaterial.setColor(new ConstantCesiumProperty<>(Color.WHITE)); issPathMaterial.setOutlineWidth(new ConstantCesiumProperty<>(1.0)); issPathMaterial.setOutlineColor(new ConstantCesiumProperty<>(Color.BLACK)); PathGraphics issPath = new PathGraphics(); issPath.setMaterial(new ConstantCesiumProperty<>(issPathMaterial)); issPath.setWidth(new ConstantCesiumProperty<>(2.0)); issPath.setLeadTime(new ConstantCesiumProperty<>(60.0 * 44.0)); // 44 minutes issPath.setTrailTime(new ConstantCesiumProperty<>(60.0 * 44.0)); iss.getExtensions().add(new PathGraphicsExtension(issPath)); TimeInterval interval = new TimeInterval(new JulianDate(new GregorianDate(2009, 1, 1)), new JulianDate(new GregorianDate(2009, 1, 2))); CzmlDocument czmlDocument = new CzmlDocument(); czmlDocument.setName("SimpleExample"); czmlDocument.setDescription("A simple example"); czmlDocument.setPrettyFormatting(true); czmlDocument.setRequestedInterval(interval); Clock clock = new Clock(); clock.setInterval(interval); clock.setCurrentTime(interval.getStart()); czmlDocument.setClock(clock); czmlDocument.getObjectsToWrite().add(iss); FileWriter streamWriter = new FileWriter(new File(outputDirectory, "Example.czml")); czmlDocument.writeDocument(streamWriter); streamWriter.close();
First, we create a Platform to represent the ISS, with its location determined by a TLE. We then add a LabelGraphicsExtension and a PathGraphicsExtension. These extensions define various graphical properties that determine how the object will be displayed in Cesium. Then, to write the CZML, we create a CzmlDocument, provide a name and description for the document, configure the time interval over which we want to write data for, add the ISS platform to the list of objects to write, and then finally write the CZML file to disk. If you were to load this file into Cesium, you would see something like the below:
In the code above, we configure the graphical properties using instances of ConstantCesiumProperty<T>. In CZML, almost every value can be defined to vary over time, so graphical properties, such as FillColor (get / set), are actually instances of the abstract base class CesiumProperty<T>. ConstantCesiumProperty<T> is merely the simplest implementation, for cases where a value is constant with respect to time.
CesiumProperty<T> is a means to define how a particular graphical property of an object in your Cesium scene changes over time. This allows you to associate the results of your analysis with the desired appearance of the display and is a fundamental concept in the Cesium Library.
The following additional types of CesiumProperty<T> are available:
TimeIntervalCesiumProperty<T> - A property that has different values over various intervals. The value will change instantaneously at the boundaries of the time intervals. These properties will be written using CZML interval syntax. The data is stored in a TimeIntervalCollection1<T>.
CompositeCesiumProperty<T> - A property that defines its value differently over different intervals. This property associates other properties with time intervals. Data is stored in a TimeIntervalCollection1<CesiumProperty<T>>.
VelocityVectorDirectionCesiumProperty - This property indicates that a UnitCartesian property will be computed on the client to be the direction of the velocity vector of a particular object. For example, a BillboardGraphics.AlignedAxis (get / set) can be configured to be the velocity vector.
As an example, suppose we wanted the text of the ISS label to be green before January 1st, 2009, and red any time after that. The following example shows how to accomplish this using a TimeIntervalCesiumProperty<Color>:
TimeIntervalCollection1<Color> intervals = new TimeIntervalCollection1<>(); Color green = new Color(0x008000); intervals.add(new TimeInterval1<>(JulianDate.getMinValue(), new JulianDate(new GregorianDate(2009, 1, 1)), green, true, false)); intervals.add(new TimeInterval1<>(new JulianDate(new GregorianDate(2009, 1, 1)), JulianDate.getMaxValue(), Color.RED, false, true)); labelExtension.getLabelGraphics().setFillColor(new TimeIntervalCesiumProperty<>(intervals));
By default, the identifiers for each CZML object will be auto-generated, but if you need more control, you can add an IdentifierExtension to configure the identifier for that object.
So far we have mainly been using color, but the same model applies to all other CZML properties. Suppose we wanted to visualize when the ISS had line of sight to a point on the ground, for example, AGI headquarters. In Components, we model this as an Access problem, using LinkInstantaneous and a CentralBodyObstructionConstraint.
Point facilityPoint = new PointCartographic(earth, new Cartographic(-1.3191780323141054, 0.69871349190638687, 0.0)); Platform facility = new Platform("AGI HQ"); facility.setLocationPoint(facilityPoint); facility.setOrientationAxes(new AxesEastNorthUp(earth, facilityPoint)); LabelGraphics facilityLabel = new LabelGraphics(); facilityLabel.setText(new ConstantCesiumProperty<>(facility.getName())); facilityLabel.setFillColor(new ConstantCesiumProperty<>(Color.WHITE)); facility.getExtensions().add(new LabelGraphicsExtension(facilityLabel)); LinkInstantaneous link = new LinkInstantaneous(facility, iss); CentralBodyObstructionConstraint constraint = new CentralBodyObstructionConstraint(link, earth);
We can then use these analysis types directly to visualize the results in Cesium. First, we create an LinkGraphicsExtension to describe the graphical properties of our link, which will be represented using a polyline in CZML. In our example, we make the link yellow by configuring the link's material. See the next section for more information on materials. Next, we want to only show the link when the constraint is satisfied. Since CentralBodyObstructionConstraint is an AccessQuery, we define the Show (get / set) property as an AccessQueryCesiumProperty<Boolean>, indicating that the link graphics should be shown when access exists, and not otherwise. The following code sample shows this:
AccessQueryCesiumProperty<Boolean> showProperty = new AccessQueryCesiumProperty<>(); showProperty.setQuery(constraint); showProperty.setAccessExists(true); showProperty.setAccessUnknown(false); showProperty.setNoAccess(false); LinkGraphics linkGraphics = new LinkGraphics(); linkGraphics.setShow(showProperty); linkGraphics.setMaterial(new ConstantCesiumProperty<>(new SolidColorMaterialGraphics(Color.YELLOW))); linkGraphics.setFollowSurface(new ConstantCesiumProperty<>(false)); link.getExtensions().add(new LinkGraphicsExtension(linkGraphics));
In the above examples, we configured both PathGraphics and LinkGraphics using materials. A material defines how the surface of many Cesium graphical types will be rendered. For example, Cesium (and therefore CZML) defines a PolylineOutline material which renders an outlined polyline. In Components, this corresponds to the PolylineOutlineMaterialGraphics type. Alternatively, we could use a SolidColorMaterialGraphics, or any other material instead. Each material defines its own set of specialized graphical properties. For example, the PolylineGlowMaterialGraphics provides Color (get / set) and GlowPower (get / set) properties.
In addition to polyline material types, which implement the IPolylineMaterialGraphics interface, there are also more general material types, which implement the IMaterialGraphics interface. These materials are used for shape and volume rendering, such as CentralBodySurfaceRegionGraphics and SensorFieldOfViewGraphics. In fact, sensor visualization allows different materials to be used for different parts of the sensor volume. For example, the following code sample adds a sensor to our facility representing AGI, pointing at the ISS as it passes overhead. We make the primary sensor volume green, but we use a white grid material to represent the sensor dome.
Platform sensor = new Platform(); sensor.setLocationPoint(new ServiceProviderPoint(facility)); VectorFixed referenceVector = new VectorFixed(iss.getOrientationAxes(), Cartesian.toCartesian(UnitCartesian.getUnitZ())); sensor.setOrientationAxes(new AxesTargetingLink(link, LinkRole.TRANSMITTER, referenceVector)); RectangularPyramid rectangularPyramid = new RectangularPyramid(); rectangularPyramid.setXHalfAngle(Trig.degreesToRadians(8.0)); rectangularPyramid.setYHalfAngle(Trig.degreesToRadians(4.5)); rectangularPyramid.setRadius(500000.0); sensor.getExtensions().add(new FieldOfViewExtension(rectangularPyramid)); SensorFieldOfViewGraphics fieldOfViewGraphics = new SensorFieldOfViewGraphics(); GridMaterialGraphics gridMaterial = new GridMaterialGraphics(); gridMaterial.setColor(new ConstantCesiumProperty<>(Color.WHITE)); gridMaterial.setCellAlpha(new ConstantCesiumProperty<>(0.0)); fieldOfViewGraphics.setDomeSurfaceMaterial(new ConstantCesiumProperty<>(gridMaterial)); Color transparentGreen = new Color(0x80008000, true); SolidColorMaterialGraphics lateralSurfaceMaterial = new SolidColorMaterialGraphics(transparentGreen); fieldOfViewGraphics.setLateralSurfaceMaterial(new ConstantCesiumProperty<>(lateralSurfaceMaterial)); sensor.getExtensions().add(new FieldOfViewGraphicsExtension(fieldOfViewGraphics));
When loaded in Cesium, this looks like:
The Code Sample topic puts each of the pieces described above into one complete example.
The table below provides a list of all services and related extensions involved in writing CZML. While most generated CZML is compatible with open-source Cesium, some features are only supported by STK Web Visualization Library. Loading a CZML file with STK Web Visualization Library features into open-source Cesium will simply cause the unsupported features to be ignored.
STK Web Visualization Library
Visualizes a 2D marker at the object's position.
Visualizes a surface curve on an central body. The geometry of the curve will be defined by the ICentralBodySurfaceCurveService service.
Visualizes the outline, interior and boundary wall of a surface region on an central body. The geometry of the region will be defined by the ICentralBodySurfaceRegionService service.
Overrides the auto-detected availability of a CZML object with the specified interval.
Indicates that a CZML object with the associated identifier should be deleted from the client.
Customizes details about how an object's orientation will be written to CZML.
Customizes details about how an object's position will be written to CZML.
Allows a CZML object's position to be written in the inertial frame.
Specifies the HTML description of an object.
Visualizes a 3D ellipsoid at the object's position, oriented using the object's orientation.
Defines graphical properties for sensor volumes and footprints projected onto a central body, at the object's position, oriented using the object's orientation. The geometry of the sensor volume will be defined by the IFieldOfViewService service.
agi_conicSensor, agi_customPatternSensor, agi_rectangularSensor
STK Web Visualization Library
Specifies the identifier of the object, which must be unique. If not provided, a unique identifier will be generated automatically.
Visualizes text at the object's position.
Visualizes a polyline drawn connecting the two end points of a link. The geometry of the polyline will be defined by the ILinkService service.
Specifies the position for an object. Most graphical extensions require this information.
Visualizes a 3D model in glTF format at the object's position, oriented using the object's orientation. See the glTF repository for more details on the glTF format.
The name of the object, which does not have to be unique and is intended for user consumption.
Specifies the orientation of an object over time. Some 3D graphical extensions require this information.
The parent object of the object.
A path of an object as it moves over time.
Visualizes a 2D point at the object's position.
STK Web Visualization Library
Specifies the suggested initial camera view offset when tracking an object.