CZML
What it is
CZML is a JSON format describing a scene that changes over time. It is what the globe viewer consumes.
It is a visualization format. It carries positions, but it also carries labels, colors, and path styling, and it does not declare a time system the way CCSDS OEM does. Do not hand it to another organization as a trajectory.
Structure
A CZML document is an array of packets. The first is always the document packet; the rest are entities.
[
{
"id": "document",
"name": "fmt",
"version": "1.0",
"clock": {
"currentTime": "2026-01-01T00:00:00Z",
"interval": "2026-01-01T00:00:00Z/2026-01-01T01:00:00Z",
"multiplier": 60.0,
"range": "LOOP_STOP",
"step": "SYSTEM_CLOCK_MULTIPLIER"
}
}
]| Parameter | Type | Unit | Default | Required | Description |
|---|---|---|---|---|---|
currentTime | string | RFC 3339 UTC | — | No | Where the viewer clock starts. |
interval | string | n/a | — | No | Scenario span as `start/stop`. The viewer will not play outside it. |
multiplier | number | n/a | — | No | Playback rate. 60.0 means one minute of scenario per second of wall clock. |
range | string | n/a | — | No | `LOOP_STOP` replays the interval when it ends. |
If the globe renders but nothing moves, the viewer clock is almost always outside
interval. Reset it to currentTime rather than looking for a problem in the data.
Entity packets
One packet per satellite, keyed by the satellite identifier:
{
"id": "fmt-s0-p00-sat00",
"name": "fmt-s0-p00-sat00",
"availability": "2026-01-01T00:00:00Z/2026-01-01T01:00:00Z",
"position": {
"epoch": "2026-01-01T00:00:00Z",
"referenceFrame": "INERTIAL",
"cartesian": [
0.0, 6928137.0, 0.0, 0.0, 600.0, 5486340.609293676, 2546122.041969697,
3378818.0710094706
]
},
"label": {},
"path": {},
"point": {}
}label, path, and point carry styling: text, font, trail color, and marker
appearance. They affect how the entity looks, not where it is.
Position samples are interleaved
The cartesian array is not a list of positions. It is a flat sequence of
four-value groups:
[ t0, x0, y0, z0, t1, x1, y1, z1, ... ]t is seconds from epoch, not an absolute time. In the example above the
first group is 0.0, 6928137.0, 0.0, 0.0 and the second begins at 600.0,
matching the 600-second step the run used.
A 7-sample export therefore produces 28 values. Reading the array as
[x, y, z, x, y, z, ...] yields positions that are wrong and time values
interpreted as coordinates.
Positions are in meters
CZML positions are in meters. Every other format here uses kilometers.
The same state exported both ways from one run:
CZML : 6928137.0
OEM : 6928.137Nothing in either file announces the difference. Converting the wrong way produces a factor-of-1000 error, which is far enough to place a low Earth orbit satellite beyond the Moon or inside the Earth.
The unit is meters because that is the CesiumJS convention, not a choice made here.
referenceFrame is coarse
INERTIAL tells the viewer not to rotate the positions with the Earth. It does
not identify which inertial frame, in the way CCSDS OEM’s
REF_FRAME = EME2000 does.
That is adequate for visualization, where a small frame difference is invisible, and inadequate for interchange. If a recipient needs to know precisely which frame the states are in, send them OEM.
Producing CZML
orbitforge simulate \
--constellation fmt.json \
--duration-hours 1 --step-seconds 600 \
--czml fmt.czmlSimulated 4 satellites over 1.0 h at 600 s steps (7 samples each) using two_body.
Wrote CZML -> fmt.czmlOver HTTP, a scenario’s CZML is fetched rather than passed as a flag:
curl -s http://127.0.0.1:8080/scenarios/scenario-demo/czml > demo.czmlSeveral analyses attach extra CZML. simulate with include_eclipse adds shadow
shading, and link produces its own CZML with station footprints.
Step size drives file size
CZML carries one four-value group per satellite per step. Halving the step doubles the file, and a fine step over a long window on a large constellation produces a document a browser will struggle to load.
For visualization, a coarse step is usually enough: the viewer interpolates between samples, and the eye cannot resolve the difference. Reserve fine steps for the analysis that needs them and export CZML separately.
See also
- CCSDS OEM for precise interchange.
orbitforge simulateto produce a scenario.
main (pre-release)