When building a geospatial application, one of the most common tasks is to display moving objects such as aircraft, ships, or vehicles on a 3D globe. In CesiumJS, you can visualize these tracks using either 2D billboards (icons) or 3D models (glTF/GLB).
This article will walk you through both approaches with working code snippets.
Displaying 2D Billboards
Billboards are simple icons or images placed at a geographic position. They are lightweight, fast to render, and suitable when you need to display hundreds or thousands of entities.
// Create a fighter jet billboard
const entity = viewer.entities.add({
position: Cesium.Cartesian3.fromDegrees(77.6, 12.9, 1000), // lon, lat, alt
billboard: {
image: './images/fighter.png', // custom icon
width: 32,
height: 32,
rotation: Cesium.Math.toRadians(90), // heading rotation
verticalOrigin: Cesium.VerticalOrigin.CENTER,
horizontalOrigin: Cesium.HorizontalOrigin.CENTER
},
label: {
text: "Fighter-101",
font: 'bold 14px sans-serif',
fillColor: Cesium.Color.YELLOW,
style: Cesium.LabelStyle.FILL_AND_OUTLINE,
outlineColor: Cesium.Color.BLACK,
outlineWidth: 2,
verticalOrigin: Cesium.VerticalOrigin.TOP,
pixelOffset: new Cesium.Cartesian2(0, -40),
showBackground: true
}
});
✅ When to use billboards
- You need performance for large numbers of tracks.
- You want to quickly show status using custom icons.
- You don’t need full 3D realism.
Displaying 3D Models
For realistic visualization, CesiumJS supports 3D models in glTF/GLB format. These can be oriented with heading, pitch, and roll to reflect the direction of movement.
// Create a 3D aircraft model
const position = Cesium.Cartesian3.fromDegrees(77.6, 12.9, 5000);
const orientation = Cesium.Transforms.headingPitchRollQuaternion(
position,
new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(45), // heading in degrees
0, // pitch
0 // roll
)
);
const entity = viewer.entities.add({
position: position,
orientation: orientation,
model: {
uri: './models/Cesium_Air.glb', // 3D aircraft model
scale: 500,
minimumPixelSize: 64,
color: Cesium.Color.BLUE,
colorBlendMode: Cesium.ColorBlendMode.MIX,
colorBlendAmount: 0.3,
shadows: Cesium.ShadowMode.DISABLED
}
});
✅ When to use 3D models
- You want realism and richer visualization.
- You need entities to match heading and orientation.
- Track counts are moderate (dozens to hundreds).
Hybrid Approach (Best Practice)
A common optimization is to use billboards when zoomed out (for performance) and switch to 3D models when zoomed in (for detail).
viewer.scene.postRender.addEventListener(function() {
viewer.entities.values.forEach(entity => {
const cameraHeight = viewer.camera.positionCartographic.height;
if (cameraHeight > 200000) {
entity.billboard.show = true;
if (entity.model) entity.model.show = false;
} else {
entity.billboard.show = false;
if (entity.model) entity.model.show = true;
}
});
});
This ensures smooth performance at scale while giving users an immersive 3D experience at close zoom levels.
Adding Dynamic Heading
Moving tracks usually need a direction arrow or proper model orientation. This can be achieved using HeadingPitchRoll:
function getOrientation(lon, lat, alt, headingDeg) {
const position = Cesium.Cartesian3.fromDegrees(lon, lat, alt);
const hpr = new Cesium.HeadingPitchRoll(
Cesium.Math.toRadians(headingDeg), 0, 0
);
return Cesium.Transforms.headingPitchRollQuaternion(position, hpr);
}
Call this function whenever you update your entity’s heading.
Conclusion
CesiumJS gives you powerful options for visualizing moving entities:
- 2D Billboards for lightweight, high-performance tracking.
- 3D Models for immersive, realistic representation.
- Hybrid techniques to balance performance and detail.
By combining these approaches, you can build scalable, visually appealing 3D geospatial applications.
If you’re interested in a full-fledged GIS solution, check out our flagship product PrithviGIS – a powerful QGIS-based platform for real-time geospatial visualization. PrithviGIS is an indigenous GIS development in India.
Check out our Live Aircraft Simulation using CesiumJS.