CesiumJS providers for interactive 2D and 3D visualization of environmental geospatial data stored in Zarr.
- Documentation: https://noc-oi.github.io/zarr-cesium/docs
- Demo: https://noc-oi.github.io/zarr-cesium/
The Zarr-Cesium Visualization Toolkit provides CesiumJS data providers for rendering n-dimensional datasets stored in the Zarr format — streamed directly from cloud object stores (HTTP/S3/GCS) without preprocessing, conversion, or a backend server.
-
Zarr v2 and v3 compatibility Read datasets from any Zarr store, including public cloud object storage.
-
Multiscale or single-scale datasets Handles legacy ndpyramid and GeoZarr layouts with automatic resolution selection.
-
Icechunk and custom stores All 2D and 3D providers accept Zarrita-compatible readable stores, including
IcechunkStore. -
Private datasets Supports static request credentials and dynamic per-object headers, proxies, or signed URLs.
-
2D & 3D visualization Render gridded scalar, vector, and volumetric data directly in CesiumJS.
-
CRS-aware Supports EPSG:4326 (Geographic) and EPSG:3857 (Web Mercator) coordinate systems with automatic detection and transformation.
-
On-demand streaming Tiles and slices are fetched and decoded dynamically — no conversion to imagery tiles required.
-
GPU-accelerated rendering Uses WebGL and Cesium primitives for fast visualization of large datasets.
-
Style and animation controls Programmatic control of color maps, opacity, scale range, slice spacing, and vertical exaggeration.
-
Scientific data queries Point, time-series, vertical-profile, transect, and full-depth transect APIs with cancellation support.
The toolkit provides three Cesium provider classes, each specialized for a different data type:
| Provider Class | Purpose | Description |
|---|---|---|
ZarrLayerProvider |
2D scalar fields | Renders single-level variables as Cesium imagery layers (e.g., temperature, chlorophyll). |
ZarrCubeProvider |
3D volumetric fields | Renders volumetric cubes with horizontal and vertical slices (e.g., ocean temperature). |
ZarrCubeVelocityProvider |
3D vector fields | Visualizes vector flow (u/v components) using animated particle advection. |
The 2D data pipeline is shared with OpenLayers and Leaflet through
zarr-maps-tiling. Palette definitions and color-ramp helpers are provided by
the separate zarr-maps-colormap package and re-exported by zarr-cesium.
The two 3D providers share ZarrCubeDataProvider, an exported non-rendering loader that applies
selectors and geographic bounds, reads the cube once, normalizes longitude ordering, and exposes
both full coordinate axes and the loaded subset coordinates.
npm install zarr-cesiumzarr-cesium supports CesiumJS 1.119 and newer, including CesiumJS 1.142+.
To run the demo website locally, clone the repository:
git clone https://github.com/noc-oi/zarr-cesium.git
cd zarr-cesium/demoCreate a .env file in the demo directory with your Cesium access token:
VITE_CESIUM_TOKEN=your_cesium_access_token_hereInstall dependencies and start the development server:
npm install
npm run devThe demo site will be available at http://localhost:5173 by default.
If you want to use your own Zarr datasets, you can modify the demo code in demo/src/application/data/layers-json.ts to point to your data URLs. You may need to adjust variable names, bounds, and other parameters accordingly.
Renders 2D scalar fields as Cesium imagery overlays using WebGL. It supports both single-scale and multiscale Zarr datasets, and provides GPU-accelerated color mapping.
Example:
import { ZarrLayerProvider } from 'zarr-cesium';
import { Viewer } from 'cesium';
const viewer = new Viewer('cesiumContainer');
const options = {
url: 'https://example.com/data.zarr',
variable: 'salinity',
colormap: 'viridis',
scale: [30, 40]
};
const layer = await ZarrLayerProvider.createLayer(viewer, options);
viewer.imageryLayers.add(layer);For Icechunk or another custom storage backend, pass any Zarrita-compatible readable store:
import { IcechunkStore } from 'icechunk-js';
const store = await IcechunkStore.open('https://example.com/data.icechunk', {
branch: 'main',
formatVersion: 'v1'
});
const layer = await ZarrLayerProvider.createLayer(viewer, {
store,
variable: 'temperature',
scale: [0, 30]
});Private HTTP Zarr stores can use requestOverrides for static credentials and headers, or
transformRequest for per-object headers, proxy URLs, and signed URLs. Use onAuthError to
refresh credentials when a transformed request returns HTTP 400 or 401.
For more details, see the Zarr-Cesium documentation.
layer_provider.mp4
Example of visualizing a Zarr dataset in a CesiumJS map using Zarr-Cesium. You can easily change the timestamp, colormap, and scale.
Renders 3D volumetric Zarr cubes as Cesium primitives — including vertical and horizontal slices. It supports both Zarr v2/v3 and multiscale datasets, with adjustable color mapping and vertical exaggeration.
Example:
import { ZarrCubeProvider } from 'zarr-cesium';
import { Viewer } from 'cesium';
const viewer = new Viewer('cesiumContainer');
const cube = new ZarrCubeProvider(viewer, {
url: 'https://example.com/ocean_temp.zarr',
variable: 'temperature',
bounds: { west: -20, south: 30, east: 10, north: 60 },
colormap: 'plasma',
verticalExaggeration: 50
});
await cube.load();Like the 2D provider, cubes accept a custom Zarrita Readable store for Icechunk data, or requestOverrides/transformRequest for private HTTP stores.
For more details, see the Zarr-Cesium documentation.
cube_provider.mp4
Example of visualizing a 4D Zarr dataset in a CesiumJS map as a 3D cube using Zarr-Cesium. You can easily change slices and view the cube in different ways, styles, and scales.
Renders 3D velocity fields from U/V components as animated wind/current layers using cube-cesium-wind-layer, the NOC-OI fork of the original cesium-wind-layer.
Zarr-Cesium installs the NOC-OI fork from npm as cube-cesium-wind-layer. The fork adds cube-aware rendering and minVisibleRatio to bound camera-driven particle width, trail-length, and speed scaling. It also restores the full data bounds and overview particle styling when zooming back out, avoiding particles remaining at the previous regional-view scale. The original project remains credited in the fork package and documentation.
It supports both Zarr v2/v3 and multiscale datasets, with configurable slice spacing and particle animation parameters.
Example:
import { ZarrCubeVelocityProvider } from 'zarr-cesium';
import { Viewer } from 'cesium';
const viewer = new Viewer('cesiumContainer');
const velocity = new ZarrCubeVelocityProvider(viewer, {
urls: {
u: 'https://example.com/uo.zarr',
v: 'https://example.com/vo.zarr'
},
variables: { u: 'uo', v: 'vo' },
bounds: { west: -50, south: -20, east: 10, north: 20 },
colormap: 'plasma'
});
await velocity.load();Velocity fields support custom stores through stores.u and stores.v. URL-backed U/V stores share the same requestOverrides, transformRequest, and onAuthError configuration.
For more details, see the Zarr-Cesium documentation.
wind_speed.mp4
Example of visualizing wind-speed vector data from Zarr in a CesiumJS map using Zarr-Cesium. This dataset is from Hurricane Florence, which occurred in 2018. You can easily change the timestamp, colormap, and particle speed.
The providers expose values directly from the underlying Zarr arrays:
const point = await layer.imageryProvider.queryData({
type: 'Point',
coordinates: [-4.2, 50.1]
});
const timeSeries = await layer.imageryProvider.getTimeSeries([-4.2, 50.1]);
const profile = await cube.getVerticalProfile([-4.2, 50.1]);
const transect = await cube.getTransect([-5, 50], [-3, 51], undefined, {
samples: 100
});Query positions use WGS84 longitude/latitude. Query options support abort signals, coordinate omission, resolution selection, transect sample count, and concurrency limits.
For more details on how to contribute to the development of this toolkit, please refer to the DEV-README.md file.
This tool is built with:
- CesiumJS
- Zarrita
zarr-maps-tilingzarr-maps-colormapcube-cesium-wind-layer(NOC-OI source, forked from hongfaqiu/cesium-wind-layer)- jscolormaps
This work is part of the Atlantis project, a UK initiative supporting long-term ocean observations and marine science in the Atlantic. The project is led by the National Oceanography Centre (NOC).