| name | cesiumjs-entities |
| description | CesiumJS entities and data sources - Entity, EntityCollection, DataSource, GeoJsonDataSource, KmlDataSource, CzmlDataSource, Graphics types, Visualizers. Use when adding points, labels, models, polygons, or polylines to the map, loading GeoJSON/KML/CZML/GPX data, or working with the high-level Entity API. |
CesiumJS Entities & DataSources
Version baseline: CesiumJS 1.142 -- ES module imports: import { ... } from "cesium";
Ownership rule: *Graphics classes belong here; *Geometry classes belong in cesiumjs-primitives. Properties (SampledProperty, CallbackProperty, MaterialProperty subtypes) belong in cesiumjs-time-properties.
Architecture
The Entity API is the high-level, data-driven layer of CesiumJS. Entities combine position, orientation, and one or more Graphics types into a single object managed by an EntityCollection. DataSources load external formats (GeoJSON, KML, CZML, GPX) and populate an EntityCollection automatically. Visualizers and GeometryUpdaters translate Entity descriptions into Primitives each frame.
DataSource --> EntityCollection --> Entity
|-- position / orientation
|-- billboard / point / label / model / polygon / polyline / ...
|-- properties (PropertyBag)
viewer.entities is a shortcut to the default DataSource's EntityCollection
viewer.dataSources holds all loaded DataSources; each owns an EntityCollection
Entity Basics
Point
import { Viewer, Cartesian3, Color, HeightReference } from "cesium";
const viewer = new Viewer("cesiumContainer");
const entity = viewer.entities.add({
id: "my-point",
name: "Sample Point",
position: Cartesian3.fromDegrees(-75.59777, 40.03883),
point: {
pixelSize: 10,
color: Color.YELLOW,
outlineColor: Color.BLACK,
outlineWidth: 2,
heightReference: HeightReference.CLAMP_TO_GROUND,
},
});
viewer.zoomTo(entity);
Billboard with Label
import { Viewer, Cartesian3, Cartesian2, Color, VerticalOrigin, HeightReference, LabelStyle } from "cesium";
const viewer = new Viewer("cesiumContainer");
viewer.entities.add({
position: Cartesian3.fromDegrees(-122.4175, 37.7749),
billboard: {
image: "/assets/marker.png",
scale: 0.5,
verticalOrigin: VerticalOrigin.BOTTOM,
heightReference: HeightReference.CLAMP_TO_GROUND,
},
label: {
text: "San Francisco",
font: "14px sans-serif",
fillColor: Color.WHITE,
outlineColor: Color.BLACK,
outlineWidth: 2,
style: LabelStyle.FILL_AND_OUTLINE,
pixelOffset: new Cartesian2(0, -36),
heightReference: HeightReference.CLAMP_TO_GROUND,
},
});
Polygon (flat, extruded, with holes)
import { Viewer, Cartesian3, Color, PolygonHierarchy } from "cesium";
const viewer = new Viewer("cesiumContainer");
viewer.entities.add({
polygon: {
hierarchy: Cartesian3.fromDegreesArray([-115, 37, -115, 32, -107, 33, -102, 31, -102, 35]),
material: Color.RED.withAlpha(0.5),
outline: true,
outlineColor: Color.BLACK,
},
});
viewer.entities.add({
polygon: {
hierarchy: new PolygonHierarchy(
Cartesian3.fromDegreesArray([-99, 30, -85, 30, -85, 40, -99, 40]),
[new PolygonHierarchy(Cartesian3.fromDegreesArray([-97, 32, -87, 32, -87, 38, -97, 38]))]
),
extrudedHeight: 300000,
material: Color.BLUE.withAlpha(0.6),
closeTop: true,
closeBottom: true,
},
});
Polyline
import { Viewer, Cartesian3, Color, ArcType } from "cesium";
const viewer = new Viewer("cesiumContainer");
viewer.entities.add({
polyline: {
positions: Cartesian3.fromDegreesArray([-75, 35, -125, 35]),
width: 5,
material: Color.RED,
arcType: ArcType.GEODESIC,
clampToGround: true,
},
});
3D Model
import { Viewer, Cartesian3, HeadingPitchRoll, Transforms, Math as CesiumMath, Color } from "cesium";
const viewer = new Viewer("cesiumContainer");
const position = Cartesian3.fromDegrees(-123.075, 44.045, 5000);
const hpr = new HeadingPitchRoll(CesiumMath.toRadians(135), 0, 0);
viewer.entities.add({
position,
orientation: Transforms.headingPitchRollQuaternion(position, hpr),
model: {
uri: "/assets/CesiumAir/Cesium_Air.glb",
minimumPixelSize: 64,
maximumScale: 20000,
silhouetteColor: Color.RED,
silhouetteSize: 2,
},
});
Box, Cylinder, Ellipsoid, Ellipse
import { Viewer, Cartesian3, Color } from "cesium";
const viewer = new Viewer("cesiumContainer");
viewer.entities.add({
position: Cartesian3.fromDegrees(-107, 40, 300000),
box: { dimensions: new Cartesian3(400000, 300000, 500000), material: Color.BLUE.withAlpha(0.5) },
});
viewer.entities.add({
position: Cartesian3.fromDegrees(-100, 40, 200000),
cylinder: { length: 400000, topRadius: 200000, bottomRadius: 200000, material: Color.GREEN.withAlpha(0.5) },
});
viewer.entities.add({
position: Cartesian3.fromDegrees(-93, 40, 300000),
ellipsoid: { radii: new Cartesian3(200000, 200000, 300000), material: Color.RED.withAlpha(0.5) },
});
viewer.entities.add({
position: Cartesian3.fromDegrees(-86, 40),
ellipse: { semiMajorAxis: 300000, semiMinorAxis: 300000, material: Color.PURPLE.withAlpha(0.5) },
});
Corridor, Rectangle, Wall
import { Viewer, Cartesian3, Color, Rectangle, CornerType } from "cesium";
const viewer = new Viewer("cesiumContainer");
viewer.entities.add({
corridor: { positions: Cartesian3.fromDegreesArray([-80, 40, -90, 40, -90, 35]), width: 200000, material: Color.ORANGE.withAlpha(0.6), cornerType: CornerType.ROUNDED },
});
viewer.entities.add({
rectangle: { coordinates: Rectangle.fromDegrees(-110, 20, -80, 25), material: Color.GREEN.withAlpha(0.5), extrudedHeight: 50000 },
});
viewer.entities.add({
wall: { positions: Cartesian3.fromDegreesArrayHeights([-115, 44, 200000, -90, 44, 200000]), minimumHeights: [100000, 100000], material: Color.CYAN.withAlpha(0.7) },
});
EntityCollection Operations
viewer.entities.getById("my-point");
viewer.entities.getOrCreateEntity("some-id");
viewer.entities.values;
viewer.entities.remove(entity);
viewer.entities.removeById("my-point");
viewer.entities.removeAll();
viewer.entities.suspendEvents();
for (let i = 0; i < 1000; i++) viewer.entities.add({ });
viewer.entities.resumeEvents();
viewer.entities.collectionChanged.addEventListener((collection, added, removed, changed) => {
console.log(`Added: ${added.length}, Removed: ${removed.length}`);
});
DataSources
GeoJSON / TopoJSON
import { Viewer, GeoJsonDataSource, Color } from "cesium";
const viewer = new Viewer("cesiumContainer");
const ds = await GeoJsonDataSource.load("/data/counties.geojson", {
stroke: Color.HOTPINK, fill: Color.PINK.withAlpha(0.5), strokeWidth: 3, clampToGround: true,
});
viewer.dataSources.add(ds);
viewer.zoomTo(ds);
for (const entity of ds.entities.values) {
if (entity.polygon) entity.polygon.material = Color.fromRandom({ alpha: 0.8 });
}
GeoJsonDataSource.load() also accepts an inline GeoJSON object instead of a URL.
Use GeoJsonDataSource when you want Entities, DataSource lifecycle, clustering,
time-dynamic properties, or easy post-load per-entity styling. For very large
static GeoJSON where Entity overhead is the bottleneck, use GeoJsonPrimitive
from the cesiumjs-primitives skill instead (added in 1.142).
KML / KMZ
import { KmlDataSource } from "cesium";
const ds = await KmlDataSource.load("/data/sample.kml", {
camera: viewer.scene.camera, canvas: viewer.scene.canvas, clampToGround: true,
});
viewer.dataSources.add(ds);
viewer.flyTo(ds);
CZML
import { CzmlDataSource } from "cesium";
const ds = await CzmlDataSource.load("/data/vehicle.czml");
viewer.dataSources.add(ds);
await ds.process("/data/vehicle-update.czml");
GPX
import { GpxDataSource } from "cesium";
const ds = await GpxDataSource.load("/data/trail.gpx");
viewer.dataSources.add(ds);
viewer.zoomTo(ds);
CustomDataSource
import { CustomDataSource, Cartesian3, Color } from "cesium";
const customDs = new CustomDataSource("sensors");
customDs.entities.add({
position: Cartesian3.fromDegrees(-95, 40),
point: { pixelSize: 8, color: Color.LIME },
});
viewer.dataSources.add(customDs);
customDs.show = false;
Entity Clustering
import { GeoJsonDataSource, Color, VerticalOrigin, PinBuilder } from "cesium";
const ds = await GeoJsonDataSource.load("/data/facilities.geojson");
viewer.dataSources.add(ds);
ds.clustering.enabled = true;
ds.clustering.pixelRange = 40;
ds.clustering.minimumClusterSize = 3;
const pinBuilder = new PinBuilder();
ds.clustering.clusterEvent.addEventListener((entities, cluster) => {
cluster.label.show = false;
cluster.billboard.show = true;
cluster.billboard.verticalOrigin = VerticalOrigin.BOTTOM;
cluster.billboard.image = pinBuilder.fromText(`${entities.length}`, Color.VIOLET, 48).toDataURL();
});
Parent-Child Visibility
Setting parent.show = false hides all descendants without changing their individual show flags.
const parent = viewer.entities.add({ name: "Group" });
viewer.entities.add({ parent, position: Cartesian3.fromDegrees(-90, 35), point: { pixelSize: 6, color: Color.RED } });
viewer.entities.add({ parent, position: Cartesian3.fromDegrees(-91, 36), point: { pixelSize: 6, color: Color.BLUE } });
parent.show = false;
parent.show = true;
Entity Description and Custom Properties
viewer.entities.add({
name: "Station Alpha",
position: Cartesian3.fromDegrees(-75.17, 39.95),
point: { pixelSize: 12, color: Color.CYAN },
description: `<table class="cesium-infoBox-defaultTable"><tr><th>Status</th><td>Active</td></tr></table>`,
properties: { population: 500000, category: "metro" },
});
Export to KML
import { exportKml } from "cesium";
const result = await exportKml({ entities: viewer.entities, kmz: true });
const url = URL.createObjectURL(result.kmz);
All 17 Graphics Types
| Graphics | Key Properties |
|---|
PointGraphics | pixelSize, color, outlineColor, outlineWidth |
BillboardGraphics | image, scale, rotation, sizeInMeters, heightReference |
LabelGraphics | text, font, fillColor, style, showBackground |
ModelGraphics | uri, scale, silhouetteColor, runAnimations, colorBlendMode |
PolygonGraphics | hierarchy, height, extrudedHeight, material, perPositionHeight |
PolylineGraphics | positions, width, material, clampToGround, arcType |
EllipseGraphics | semiMajorAxis, semiMinorAxis, rotation, extrudedHeight |
RectangleGraphics | coordinates (Rectangle), height, extrudedHeight |
BoxGraphics | dimensions (Cartesian3), material, outline |
CylinderGraphics | length, topRadius, bottomRadius |
EllipsoidGraphics | radii (Cartesian3) |
CorridorGraphics | positions, width, cornerType |
WallGraphics | positions, minimumHeights, maximumHeights |
PolylineVolumeGraphics | positions, shape (Cartesian2[]) |
PlaneGraphics | plane (Plane), dimensions (Cartesian2) |
PathGraphics | resolution, leadTime, trailTime, width, relativeTo (experimental, 1.140+) |
Cesium3DTilesetGraphics | uri |
PathGraphics.relativeTo (experimental, 1.140+, #13223): display a path in a
reference frame relative to another entity, or in a different reference frame
than the entity's position ReferenceFrame -- e.g. draw a drone's track
relative to a moving vehicle rather than ECEF. Marked experimental; the signature
may change.
Key Enums
| Enum | Values |
|---|
HeightReference | NONE, CLAMP_TO_GROUND, RELATIVE_TO_GROUND |
HorizontalOrigin | LEFT, CENTER, RIGHT |
VerticalOrigin | TOP, CENTER, BOTTOM, BASELINE |
LabelStyle | FILL, OUTLINE, FILL_AND_OUTLINE |
ColorBlendMode | HIGHLIGHT, REPLACE, MIX |
ShadowMode | DISABLED, ENABLED, CAST_ONLY, RECEIVE_ONLY |
Performance Tips
- Use
suspendEvents()/resumeEvents() when bulk-adding entities to batch change notifications.
- Prefer constant properties for static data -- CesiumJS optimizes non-changing entities.
- Use
DistanceDisplayCondition to hide entities beyond a useful range.
- Switch to Primitives for 10k+ static shapes; Primitives avoid per-entity overhead.
- Enable clustering on DataSources with many point-like entities.
- Set
disableDepthTestDistance on billboards/labels to prevent terrain occlusion.
- Minimize outlines on ground-clamped polygons -- extra rendering passes required.
- Use
clampToGround only when needed -- requires terrain-conforming subdivision.
- Batch CZML updates with
process() to append, not load() which replaces all.
- Cache PinBuilder canvases -- reuse results to avoid regenerating identical images.
See Also
- cesiumjs-time-properties -- SampledProperty, CallbackProperty, MaterialProperty types for time-dynamic entity attributes
- cesiumjs-primitives -- Low-level Primitive API for performance-critical static geometry (
*Geometry classes)
- cesiumjs-interaction -- ScreenSpaceEventHandler, Scene.pick, entity selection and hover patterns