CesiumJS Imagery Syntax
Overview
Raster imagery on the CesiumJS globe has two layers of objects. An imagery PROVIDER is
the tile source (Bing, ArcGIS, OpenStreetMap, a WMS server). An ImageryLayer wraps
one provider and carries the display settings (alpha, brightness, draw order). The
globe renders an ordered stack of ImageryLayer objects, held in
viewer.imageryLayers, an ImageryLayerCollection.
Core principle: providers that fetch metadata from a server are created with an ASYNC
static factory (fromUrl, fromAssetId, fromBasemapType). NEVER call new on those
classes. Providers that need no metadata fetch use a plain synchronous constructor.
This skill is technology-specific: CesiumJS 1.124+, WebGL2 only.
When to Use This Skill
- Adding a basemap or an overlay layer to the globe.
- The globe renders but shows no imagery, or tiles never appear.
- Tile requests return 401 or 403.
- Imagery layers draw in the wrong order, hiding the layer that should be on top.
- A provider constructor throws or yields an unusable provider.
- Blending two layers with alpha, brightness, or a split.
- Consuming MapTiler, a custom XYZ tile server, WMS, or WMTS.
Quick Reference: Built-in Providers
| Provider |
Source |
Creation |
IonImageryProvider |
Cesium ion asset |
fromAssetId(id) async |
BingMapsImageryProvider |
Bing Maps |
fromUrl(url, {key}) async |
ArcGisMapServerImageryProvider |
ArcGIS MapServer |
fromUrl / fromBasemapType async |
TileMapServiceImageryProvider |
TMS tile set |
fromUrl(url) async |
SingleTileImageryProvider |
one image |
fromUrl(url) async |
OpenStreetMapImageryProvider |
OSM-style XYZ |
new synchronous |
UrlTemplateImageryProvider |
any XYZ template |
new synchronous |
WebMapServiceImageryProvider |
WMS server |
new synchronous |
WebMapTileServiceImageryProvider |
WMTS server |
new synchronous |
Synchronous vs Asynchronous Providers
digraph provider_choice {
"Provider fetches server metadata?" [shape=diamond];
"Use the async factory: fromUrl / fromAssetId / fromBasemapType" [shape=box];
"Use the synchronous constructor: new Provider(options)" [shape=box];
"Provider fetches server metadata?" -> "Use the async factory: fromUrl / fromAssetId / fromBasemapType" [label="yes"];
"Provider fetches server metadata?" -> "Use the synchronous constructor: new Provider(options)" [label="no"];
}
- ALWAYS create
IonImageryProvider, BingMapsImageryProvider,
ArcGisMapServerImageryProvider, TileMapServiceImageryProvider, and
SingleTileImageryProvider through their async factory. The direct constructor on
these classes is documented as not-to-be-called.
- ALWAYS create
OpenStreetMapImageryProvider, UrlTemplateImageryProvider,
WebMapServiceImageryProvider, and WebMapTileServiceImageryProvider with new;
they need no metadata fetch.
- NEVER use
readyPromise or a .ready poll loop; readyPromise was removed in
1.107. The async factory promise resolving IS the readiness signal.
Adding an Imagery Layer
There are three correct patterns. Pick by whether the provider is async.
Pattern A: async provider, wrapped by fromProviderAsync
ALWAYS use ImageryLayer.fromProviderAsync when the provider is async. It accepts the
provider PROMISE directly and manages the pending state.
const layer = Cesium.ImageryLayer.fromProviderAsync(
Cesium.ArcGisMapServerImageryProvider.fromBasemapType(
Cesium.ArcGisBaseMapType.SATELLITE,
{ token: arcGisToken }
)
);
viewer.imageryLayers.add(layer);
Pattern B: await the provider, then construct the layer
const provider = await Cesium.IonImageryProvider.fromAssetId(3954);
const layer = new Cesium.ImageryLayer(provider);
viewer.imageryLayers.add(layer);
Pattern C: synchronous provider via addImageryProvider
ImageryLayerCollection.addImageryProvider(provider, index) builds and adds the layer
in one call. ALWAYS use it for a synchronous provider.
viewer.imageryLayers.addImageryProvider(
new Cesium.OpenStreetMapImageryProvider()
);
NEVER pass an async provider Promise to new Cesium.ImageryLayer(...). That constructor
expects a resolved provider instance; a Promise yields a layer that never draws. Use
fromProviderAsync (Pattern A) or await first (Pattern B).
Default and World Imagery
ImageryLayer.fromWorldImagery(options) creates a layer for Cesium ion global base
imagery. The global helper createWorldImageryAsync() returns a Promise of the same
provider. ion imagery requires Cesium.Ion.defaultAccessToken set before use.
MapTiler and Custom XYZ Servers
There is NO dedicated MapTiler provider class. ALWAYS consume MapTiler through
UrlTemplateImageryProvider with the MapTiler XYZ tile URL, or through
WebMapTileServiceImageryProvider for a WMTS endpoint.
viewer.imageryLayers.addImageryProvider(
new Cesium.UrlTemplateImageryProvider({
url: "https://api.maptiler.com/maps/streets-v2/{z}/{x}/{y}.png?key=" + maptilerKey,
})
);
The URL template understands {z}, {x}, {y}, and {s} (subdomains, default
abc), plus {reverseX}, {reverseY}, and geographic bound tags.
Layer Ordering and Blending
viewer.imageryLayers is an ordered collection. Index 0 is the BOTTOM layer; the
last index is drawn on TOP.
| Operation |
Method |
| Move a layer up one step |
imageryLayers.raise(layer) |
| Move a layer down one step |
imageryLayers.lower(layer) |
| Move a layer to the top |
imageryLayers.raiseToTop(layer) |
| Move a layer to the bottom |
imageryLayers.lowerToBottom(layer) |
| Read a layer by index |
imageryLayers.get(index) |
| Remove a layer |
imageryLayers.remove(layer, destroy) |
Per-layer display settings, with their defaults:
| Member |
Default |
Effect |
alpha |
1.0 |
layer opacity, 0.0 to 1.0 |
brightness |
1.0 |
1.0 is unchanged |
contrast |
1.0 |
1.0 is unchanged |
hue |
0.0 |
hue shift in radians |
saturation |
1.0 |
1.0 is unchanged |
gamma |
1.0 |
gamma correction |
show |
true |
layer visibility |
splitDirection |
SplitDirection.NONE |
left or right side of a slider |
ALWAYS lower alpha on the TOP layer to blend it over the layer beneath. NEVER expect
a bottom layer to show through an opaque layer above it.
Common Mistakes
| Mistake |
Fix |
new BingMapsImageryProvider(...) |
Use BingMapsImageryProvider.fromUrl(...) |
readyPromise or a .ready poll |
Await the factory promise; readyPromise is removed |
Passing a provider Promise to new ImageryLayer |
Use ImageryLayer.fromProviderAsync |
| Tiles return 401 or 403 |
Set the ion, ArcGIS, or Bing access token |
| Layer hidden behind another |
Index 0 is the bottom; raiseToTop the overlay |
Looking for MapTilerImageryProvider |
No such class; use UrlTemplateImageryProvider |
Full root-cause analysis is in references/anti-patterns.md.
Reference Files
references/methods.md : verified factory and constructor signatures for
ImageryLayer, ImageryLayerCollection, and every built-in provider.
references/examples.md : runnable layer-adding patterns, every provider, MapTiler,
WMS, WMTS, ordering, and blending.
references/anti-patterns.md : imagery failure modes, each with symptom, root cause,
prevention, and recovery.
Related Skills
cesium-syntax-viewer : the baseLayer option and Viewer construction.
cesium-syntax-terrain : terrain providers, the elevation counterpart to imagery.
cesium-core-versioning : the async-factory migration and readyPromise removal.
cesium-errors-rendering : blank globe and missing-imagery diagnosis.
1---2name: cesium-syntax-imagery3description: Use when adding, stacking, or styling raster map imagery on the CesiumJS globe, and the globe shows no imagery, tiles return 401 or 403, layers draw in the wrong order, or a provider fails to construct. Prevents the direct-constructor mistake (calling new on a provider that requires an async fromUrl factory), the removed-readyPromise pattern, the unwrapped-promise error (passing a provider Promise to new ImageryLayer), and the layer-order confusion. Covers ImageryLayer, ImageryLayerCollection, every built-in provider, the synchronous versus asynchronous provider split, and layer blending. Keywords: CesiumJS imagery, ImageryLayer, ImageryLayerCollection, imageryLayers, fromProviderAsync, addImageryProvider, IonImageryProvider, BingMapsImageryProvider, ArcGisMapServerImageryProvider, OpenStreetMapImageryProvider, UrlTemplateImageryProvider, WebMapServiceImageryProvider, WebMapTileServiceImageryProvider, TileMapServiceImageryProvider, SingleTileImageryProvider, WMS, WMTS, TMS, MapTiler, basemap, no imagery, map 4license: MIT5---67# CesiumJS Imagery Syntax89## Overview1011Raster imagery on the CesiumJS globe has two layers of objects. An imagery PROVIDER is12the tile source (Bing, ArcGIS, OpenStreetMap, a WMS server). An `ImageryLayer` wraps13one provider and carries the display settings (alpha, brightness, draw order). The14globe renders an ordered stack of `ImageryLayer` objects, held in15`viewer.imageryLayers`, an `ImageryLayerCollection`.1617Core principle: providers that fetch metadata from a server are created with an ASYNC18static factory (`fromUrl`, `fromAssetId`, `fromBasemapType`). NEVER call `new` on those19classes. Providers that need no metadata fetch use a plain synchronous constructor.2021This skill is technology-specific: CesiumJS 1.124+, WebGL2 only.2223## When to Use This Skill2425- Adding a basemap or an overlay layer to the globe.26- The globe renders but shows no imagery, or tiles never appear.27- Tile requests return 401 or 403.28- Imagery layers draw in the wrong order, hiding the layer that should be on top.29- A provider constructor throws or yields an unusable provider.30- Blending two layers with alpha, brightness, or a split.31- Consuming MapTiler, a custom XYZ tile server, WMS, or WMTS.3233## Quick Reference: Built-in Providers3435| Provider | Source | Creation |36|----------|--------|----------|37| `IonImageryProvider` | Cesium ion asset | `fromAssetId(id)` async |38| `BingMapsImageryProvider` | Bing Maps | `fromUrl(url, {key})` async |39| `ArcGisMapServerImageryProvider` | ArcGIS MapServer | `fromUrl` / `fromBasemapType` async |40| `TileMapServiceImageryProvider` | TMS tile set | `fromUrl(url)` async |41| `SingleTileImageryProvider` | one image | `fromUrl(url)` async |42| `OpenStreetMapImageryProvider` | OSM-style XYZ | `new` synchronous |43| `UrlTemplateImageryProvider` | any XYZ template | `new` synchronous |44| `WebMapServiceImageryProvider` | WMS server | `new` synchronous |45| `WebMapTileServiceImageryProvider` | WMTS server | `new` synchronous |4647## Synchronous vs Asynchronous Providers4849```dot50digraph provider_choice {51 "Provider fetches server metadata?" [shape=diamond];52 "Use the async factory: fromUrl / fromAssetId / fromBasemapType" [shape=box];53 "Use the synchronous constructor: new Provider(options)" [shape=box];5455 "Provider fetches server metadata?" -> "Use the async factory: fromUrl / fromAssetId / fromBasemapType" [label="yes"];56 "Provider fetches server metadata?" -> "Use the synchronous constructor: new Provider(options)" [label="no"];57}58```5960- ALWAYS create `IonImageryProvider`, `BingMapsImageryProvider`,61 `ArcGisMapServerImageryProvider`, `TileMapServiceImageryProvider`, and62 `SingleTileImageryProvider` through their async factory. The direct constructor on63 these classes is documented as not-to-be-called.64- ALWAYS create `OpenStreetMapImageryProvider`, `UrlTemplateImageryProvider`,65 `WebMapServiceImageryProvider`, and `WebMapTileServiceImageryProvider` with `new`;66 they need no metadata fetch.67- NEVER use `readyPromise` or a `.ready` poll loop; `readyPromise` was removed in68 1.107. The async factory promise resolving IS the readiness signal.6970## Adding an Imagery Layer7172There are three correct patterns. Pick by whether the provider is async.7374### Pattern A: async provider, wrapped by fromProviderAsync7576ALWAYS use `ImageryLayer.fromProviderAsync` when the provider is async. It accepts the77provider PROMISE directly and manages the pending state.7879```js80const layer = Cesium.ImageryLayer.fromProviderAsync(81 Cesium.ArcGisMapServerImageryProvider.fromBasemapType(82 Cesium.ArcGisBaseMapType.SATELLITE,83 { token: arcGisToken }84 )85);86viewer.imageryLayers.add(layer);87```8889### Pattern B: await the provider, then construct the layer9091```js92const provider = await Cesium.IonImageryProvider.fromAssetId(3954);93const layer = new Cesium.ImageryLayer(provider);94viewer.imageryLayers.add(layer);95```9697### Pattern C: synchronous provider via addImageryProvider9899`ImageryLayerCollection.addImageryProvider(provider, index)` builds and adds the layer100in one call. ALWAYS use it for a synchronous provider.101102```js103viewer.imageryLayers.addImageryProvider(104 new Cesium.OpenStreetMapImageryProvider()105);106```107108NEVER pass an async provider Promise to `new Cesium.ImageryLayer(...)`. That constructor109expects a resolved provider instance; a Promise yields a layer that never draws. Use110`fromProviderAsync` (Pattern A) or `await` first (Pattern B).111112## Default and World Imagery113114`ImageryLayer.fromWorldImagery(options)` creates a layer for Cesium ion global base115imagery. The global helper `createWorldImageryAsync()` returns a Promise of the same116provider. ion imagery requires `Cesium.Ion.defaultAccessToken` set before use.117118## MapTiler and Custom XYZ Servers119120There is NO dedicated MapTiler provider class. ALWAYS consume MapTiler through121`UrlTemplateImageryProvider` with the MapTiler XYZ tile URL, or through122`WebMapTileServiceImageryProvider` for a WMTS endpoint.123124```js125viewer.imageryLayers.addImageryProvider(126 new Cesium.UrlTemplateImageryProvider({127 url: "https://api.maptiler.com/maps/streets-v2/{z}/{x}/{y}.png?key=" + maptilerKey,128 })129);130```131132The URL template understands `{z}`, `{x}`, `{y}`, and `{s}` (subdomains, default133`abc`), plus `{reverseX}`, `{reverseY}`, and geographic bound tags.134135## Layer Ordering and Blending136137`viewer.imageryLayers` is an ordered collection. Index `0` is the BOTTOM layer; the138last index is drawn on TOP.139140| Operation | Method |141|-----------|--------|142| Move a layer up one step | `imageryLayers.raise(layer)` |143| Move a layer down one step | `imageryLayers.lower(layer)` |144| Move a layer to the top | `imageryLayers.raiseToTop(layer)` |145| Move a layer to the bottom | `imageryLayers.lowerToBottom(layer)` |146| Read a layer by index | `imageryLayers.get(index)` |147| Remove a layer | `imageryLayers.remove(layer, destroy)` |148149Per-layer display settings, with their defaults:150151| Member | Default | Effect |152|--------|---------|--------|153| `alpha` | `1.0` | layer opacity, `0.0` to `1.0` |154| `brightness` | `1.0` | `1.0` is unchanged |155| `contrast` | `1.0` | `1.0` is unchanged |156| `hue` | `0.0` | hue shift in radians |157| `saturation` | `1.0` | `1.0` is unchanged |158| `gamma` | `1.0` | gamma correction |159| `show` | `true` | layer visibility |160| `splitDirection` | `SplitDirection.NONE` | left or right side of a slider |161162ALWAYS lower `alpha` on the TOP layer to blend it over the layer beneath. NEVER expect163a bottom layer to show through an opaque layer above it.164165## Common Mistakes166167| Mistake | Fix |168|---------|-----|169| `new BingMapsImageryProvider(...)` | Use `BingMapsImageryProvider.fromUrl(...)` |170| `readyPromise` or a `.ready` poll | Await the factory promise; `readyPromise` is removed |171| Passing a provider Promise to `new ImageryLayer` | Use `ImageryLayer.fromProviderAsync` |172| Tiles return 401 or 403 | Set the ion, ArcGIS, or Bing access token |173| Layer hidden behind another | Index 0 is the bottom; `raiseToTop` the overlay |174| Looking for `MapTilerImageryProvider` | No such class; use `UrlTemplateImageryProvider` |175176Full root-cause analysis is in `references/anti-patterns.md`.177178## Reference Files179180- `references/methods.md` : verified factory and constructor signatures for181 `ImageryLayer`, `ImageryLayerCollection`, and every built-in provider.182- `references/examples.md` : runnable layer-adding patterns, every provider, MapTiler,183 WMS, WMTS, ordering, and blending.184- `references/anti-patterns.md` : imagery failure modes, each with symptom, root cause,185 prevention, and recovery.186187## Related Skills188189- `cesium-syntax-viewer` : the `baseLayer` option and `Viewer` construction.190- `cesium-syntax-terrain` : terrain providers, the elevation counterpart to imagery.191- `cesium-core-versioning` : the async-factory migration and `readyPromise` removal.192- `cesium-errors-rendering` : blank globe and missing-imagery diagnosis.