Short answer
Reach for CesiumJS when the third dimension or the curvature of the Earth carries real meaning for the decision, and stay on a 2D library (Leaflet, MapLibre GL) when it does not. Cesium renders a true WGS84 ellipsoidal globe with streamed terrain and OGC 3D Tiles, which makes it the right tool for draped geology over relief, subsurface and aerial geometry, line-of-sight and viewshed, drilling or flight paths, and global datasets where Web Mercator distortion is unacceptable. For a thematic choropleth, a point dataset, or a regional vector map, a 3D globe adds GPU cost, complexity, and a steeper learning curve for no analytical gain.
What Cesium is, precisely
CesiumJS is an open-source JavaScript library that renders a 3D virtual globe in WebGL. Three things distinguish it from a 2D slippy map:
- It is a real ellipsoid. Geometry sits on the WGS84 ellipsoid (EPSG:4979 for 3D), not a projected plane. There is no Mercator inflation, so Greenland is the right size and great-circle paths curve correctly.
- It streams terrain. Elevation arrives as quantized-mesh terrain tiles by level of detail, so the surface has true relief that imagery and vectors drape onto.
- It speaks 3D Tiles. The OGC 3D Tiles standard (b3dm batched models, pnts point clouds, i3dm instances, all built on glTF) lets Cesium stream city-scale buildings, billion-point LiDAR clouds, and BIM models with hierarchical level of detail.
A 2D library, by contrast, paints raster or vector tiles onto a flat canvas in a single projection (almost always Web Mercator, EPSG:3857). Fast, simple, and perfectly adequate when height is not part of the question.
When 3D earns its cost
Use Cesium when at least one of these is true:
- Height is the message. Geology draped over terrain, fault planes dipping into the subsurface, ash plume or contaminant volumes, flood depth over a DEM. A 2D map can only symbolize height; Cesium shows it.
- Line of sight, viewshed, or sun position matters. Telecom, defence, solar, and hazard work need true 3D occlusion. Cesium computes visibility against terrain and models directly.
- Trajectories in 3D. Drillholes, mine workings, drone or aircraft flight paths, AUV dives. These are inherently volumetric and read wrong when flattened.
- Global or polar scale. At high latitudes Web Mercator area error becomes severe (an area at 70 degrees north is inflated several-fold). A globe avoids this entirely.
- Time-dynamic 3D. Cesium's CZML format and clock let you animate moving objects (satellites, vehicles, plumes) with interpolated 3D positions over time.
- Massive streamable datasets. A national LiDAR point cloud as a 3D Tileset streams by LOD; the same data is impractical in a 2D vector map.
When a 2D map is the better engineering choice
- Thematic cartography: choropleths, dot density, heat maps, simple symbology.
- Editing and digitizing vectors — far more ergonomic in 2D.
- Lightweight embeds and mobile, where GPU and bandwidth budgets are tight.
- Print and report figures, which are 2D anyway.
For these, MapLibre GL gives vector tiles, smooth styling, and a fraction of Cesium's complexity. Cesium 3D is not a free upgrade; it is a deliberate trade of simplicity for dimensionality.
The data pipeline that makes Cesium work
The most common reason a Cesium project stalls is that the data was never prepared into streamable tiles. The pieces:
- Imagery: standard XYZ or WMTS tiles draped on terrain. No conversion needed for existing tile services.
- Terrain: convert a DEM to quantized-mesh terrain tiles. Open-source tooling (e.g. cesium-terrain-builder / CTB) or Cesium ion ingestion produces a tileset; the DEM should be in a clean metric or geographic CRS and void-filled first.
- Vectors: small datasets load directly as GeoJSON (Cesium reprojects from EPSG:4326); larger or styled-for-3D datasets become 3D Tiles or CZML.
- Buildings / models: glTF for single models, b3dm tilesets for cities, often via Cesium ion or open converters.
- Point clouds: convert LAS/LAZ to a pnts/glTF 3D Tileset (PDAL and several converters support this) so billions of points stream by LOD.
If your DEM, drillholes, or LiDAR are still sitting as GeoTIFFs and CSVs, expect tiling and CRS conditioning to be the real work — Cesium itself is the easy part.
Worked example: drillholes over terrain
You have collar coordinates, downhole survey data, and a regional DEM, and you want stakeholders to see the holes piercing the topography.
- Terrain: void-fill the DEM (
gdal_fillnodata), confirm it is in EPSG:4326 or a clean metric CRS, and build a quantized-mesh terrain tileset. - Drill traces: compute 3D desurveyed XYZ positions from collar + azimuth/dip surveys, then emit them as a CZML or GeoJSON-with-height (or a glTF tube model per hole for thickness).
- Load in Cesium: set the terrain provider, add the imagery provider, then add the drillhole entities; enable depth testing against terrain so holes correctly disappear below the surface.
- Camera and clamping: clamp collar markers to terrain, let traces extend below it, and add a vertical exaggeration toggle (Cesium's
globe.terrainExaggeration) for subtle relief — clearly labeled, since it distorts true geometry.
Measurement and distortion notes
A globe is geometrically honest visually, but you still must measure correctly: distances are geodesic (use Cesium.EllipsoidGeodesic), and areas should be computed on the ellipsoid, not from screen pixels. Terrain exaggeration is a viewing aid only — never measure heights off an exaggerated scene. Because rendering is on the WGS84 ellipsoid, area fidelity is far better than Web Mercator, but it is not a substitute for a proper equal-area calculation when you need true areas.
Common pitfalls and why they happen
- Choosing 3D for a 2D problem. A globe looks impressive in a demo, then costs weeks of tiling and GPU debugging for a map that a choropleth would have served. Pick dimensionality by the question, not the wow factor.
- Skipping tiling. Loading a full LAS file or huge GeoJSON into Cesium freezes the browser; the format exists (3D Tiles) precisely so you stream by LOD.
- CRS surprises. Cesium expects geographic coordinates (EPSG:4326/4979); feeding it projected UTM coordinates without transform places data in the ocean off Africa. Reproject vectors with
ogr2ogr -t_srs EPSG:4326. - Measuring on exaggerated terrain. Exaggeration is for perception; leaving it on while measuring heights produces wrong numbers.
QA checklist
- Confirm the question genuinely needs height, line-of-sight, trajectory, or global scale before committing to 3D.
- Verify all inputs are in (or transformed to) geographic coordinates for Cesium.
- Tile terrain and point clouds into streamable formats; never bulk-load raw files.
- Use geodesic/ellipsoidal measurement, and disable exaggeration before measuring.
- Budget GPU and bandwidth for the target devices.
Bathyl perspective
We choose dimensionality by the decision, not the demo. When height, subsurface geometry, or global scale changes what a stakeholder understands, Cesium with properly tiled terrain and 3D Tiles is the honest tool; when it does not, a 2D vector map ships faster and is easier to maintain. Either way, the underlying data is conditioned and reprojected once, so the same source feeds both.
Related reading
- When to Use MapLibre Instead of Leaflet
- When to Use QGIS, GDAL, and PostGIS Together
- GIS Stack Checklist Before a Project Starts
- When Hillshade Misleads Interpretation
- GIS and spatial analysis