[CesiumJS]Cesium Intermediate Tutorial 2 - Imagery Layers

Cesium Chinese Website: http://cesiumcn.org/ | China fast access: http://cesium.coinidea.com/

Cesium supports rendering and adding high-resolution imagery (map) layers from several standard services. Layers can be ordered and blended together. The brightness, contrast, gamma, hue, and saturation of each layer can be dynamically changed. This tutorial introduces the concept of imagery layers and the related Cesium APIs.

Quick Start

Let’s skip the details for now and write some code to add imagery layers. Open the Hello World example in Sandcastle. This example creates a Viewer widget, which renders Bing Maps by default. We can specify a different base layer by providing additional parameters to the Viewer constructor. Let’s use a layer from Esri ArcGIS MapServer:

1
2
3
4
5
6
var viewer = new Cesium.Viewer('cesiumContainer', {
    imageryProvider : new Cesium.ArcGisMapServerImageryProvider({
        url : '//services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'
    }),
    baseLayerPicker : false
});

After modifying the example, press F8 to run:

We can scroll the mouse wheel to zoom in and out to see the actual imagery streaming in action.

Next, add another layer: NASA Black Marble imagery based on Tile Map Service (TMS):

1
2
3
4
5
6
var layers = viewer.scene.imageryLayers;
var blackMarble = layers.addImageryProvider(new Cesium.createTileMapServiceImageryProvider({
    url : '//cesiumjs.org/tilesets/imagery/blackmarble',
    maximumLevel : 8,
    credit : 'Black Marble imagery courtesy NASA Earth Observatory'
}));

Because the Black Marble layer was added last and covers the entire globe, it covers the Esri layer. We could move the Black Marble layer to the bottom with layers.lower(blackMarble);, but to better understand the relationship between these two layers, let’s blend it with the Esri layer:

1
blackMarble.alpha = 0.5; // 0.0 is transparent.  1.0 is opaque.

Next, increase the brightness of the lights:

1
blackMarble.brightness = 2.0; // > 1.0 increases brightness.  < 1.0 decreases.

Finally, add a single image as a third layer for a specific extent:

1
2
3
4
layers.addImageryProvider(new Cesium.SingleTileImageryProvider({
    url : '../images/Cesium_Logo_overlay.png',
    rectangle : Cesium.Rectangle.fromDegrees(-75.0, 28.0, -67.0, 29.75)
}));

Complete code:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
var viewer = new Cesium.Viewer('cesiumContainer', {
    imageryProvider : new Cesium.ArcGisMapServerImageryProvider({
        url : '//services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer'
    }),
    baseLayerPicker : false
});

var layers = viewer.scene.imageryLayers;
var blackMarble = layers.addImageryProvider(new Cesium.createTileMapServiceImageryProvider({
    url : '//cesiumjs.org/tilesets/imagery/blackmarble',
    maximumLevel : 8,
    credit : 'Black Marble imagery courtesy NASA Earth Observatory'
}));

blackMarble.alpha = 0.5; // 0.0 is transparent.  1.0 is opaque.

blackMarble.brightness = 2.0; // > 1.0 increases brightness.  < 1.0 decreases.

layers.addImageryProvider(new Cesium.SingleTileImageryProvider({
    url : '../images/Cesium_Logo_overlay.png',
    rectangle : Cesium.Rectangle.fromDegrees(-75.0, 28.0, -67.0, 29.75)
}));

View the complete example in Sandcastle.

Existing Imagery Layers

The ion Assets tab in Sandcastle contains imagery layer applications hosted by Cesium ion, which can be used in Cesium applications by adding just a few lines of code.

ImageryProvider

High-resolution imagery like the first two layers used above is too large to fit in memory or even on a single disk, so the imagery is divided into smaller images called tiles that can be streamed to the client based on the view. Cesium supports requesting tiles using ImageryProvider with several standards. Most ImageryProviders use REST interfaces over HTTP to request tiles. ImageryProviders differ based on the format and organization of the requests. Cesium includes the following built-in ImageryProviders:

We can access other imagery services by implementing the ImageryProvider interface. If you do so and think it’s generally useful, please contribute it to Cesium for everyone’s benefit.

See the reference documentation to learn how to construct a specific imagery provider. Let’s look at SingleTileImageryProvider since many imagery providers share its constructor properties:

  • url - The URL of the image. Like many imagery providers, this is the only required property. In other imagery providers, this URL points to the server or the root URL of the service.
  • extent - Optional. The longitude/latitude rectangle that the image should cover. By default, it covers the entire globe.
  • credit - Optional. A string credit for the data source, displayed on the canvas. Some imagery providers, such as BingMapsImageryProvider and ArcGIS Server REST API, can retrieve credits or logos directly from their services.
  • proxy - Optional. A proxy for requesting the service, which can enable cross-origin resource sharing.

Cross-Origin Resource Sharing

For security reasons, today’s web browsers work hard to prevent JavaScript code from reading image pixels from different sites. In particular, if a WebGL application like Cesium accesses images from a different hostname or port and the server doesn’t explicitly allow the images to be used this way, using those images as textures is prohibited. The server indicates that images don’t contain confidential information and that it’s safe for other sites to read their pixels by including Cross-Origin Resource Sharing (CORS) headers in the HTTP response.

Unfortunately, not all imagery services support CORS. For those that don’t, a proxy server with the same origin as the website hosting Cesium must be used. When using such a proxy, for the web browser and Cesium client, the tiles appear as though they come from the same origin as the Cesium-based website. To use a proxy with an imagery provider, use the proxy property when constructing the imagery provider. Cesium includes a simple proxy written in Node.js for development purposes.

1
2
3
4
layers.addImageryProvider(new Cesium.ArcGisMapServerImageryProvider({
    url : '//server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer',
    proxy : new Cesium.DefaultProxy('/proxy/')
}));

If you’re hosting public imagery, we encourage enabling CORS as described in this article rather than using a proxy.

ImageryProvider vs. Layers

So far, we haven’t explicitly distinguished between ImageryProvider and layers. An ImageryProvider requests imagery using a specific service, while a layer represents the displayed imagery from an ImageryProvider. The code:

1
var layer = layers.addImageryProvider(imageryProvider);

is shorthand for:

1
2
var layer = new ImageryLayer(imageryProvider);
layers.add(layer);

We typically construct an imagery provider only to create a layer, then we use its properties such as show, alpha, brightness, and contrast. See ImageryLayer. Decoupling imagery providers from layers makes it easy to add new imagery providers.

Like the layers variable in the examples above, the layer collection determines the drawing order of layers. Layers are drawn from bottom to top in the order they were added. The layer collection is operated on using functions such as add, remove, and get, like any other collection in Cesium. Additionally, layers can be reordered using raise, raiseToTop, lower, and lowerToBottom. See ImageryLayerCollection.

Resources

Imagery layers examples from Sandcastle:

Additional reference documentation:

Cesium Chinese Community QQ Group: 807482793

Cesium Chinese Website: http://cesiumcn.org/ | China fast access: http://cesium.coinidea.com/