原文地址:https://cesiumjs.org/tutorials/Imagery-Layers-Tutorial/
影像圖層
Cesium支持多種服務來源的高精度影像(地圖)數據的加載和渲染。圖層支持排序和透明混合。每個圖層的 亮度(brightness),對比度( contrast), gamma, hue, and saturation 都可以動態修改。
快速開始
我們忽略細節,直接寫代碼去添加一些影像圖層。打開SandCastle中的 Hello World 示例. 這個示例創建了一個Viewer
控件,並且只包含一個Bing影像圖層。可以在Viewer
的構造函數里設定一個不同類型的底圖圖層。我們用一個 Esri ArcGIS 在線服務圖層:
var viewer = new Cesium.Viewer('cesiumContainer', { imageryProvider : new Cesium.ArcGisMapServerImageryProvider({ url : '//services.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer' }), baseLayerPicker : false });
修改代碼后,按F8運行。

當放大縮小的時候,圖層數據按需漸進加載。
下來,添加另一個圖層: NASA Black Marble 影像 ,它使用 Tile Map Service (TMS)
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' }));

因為它是后添加的並且覆蓋了整個地球, Black Marble 圖層完全蓋住了Esri圖層。我們可以使用layers.lower(blackMarble);
把Black Marble圖層移到下面。我們也可以讓這個圖層和Esri圖層混合,這樣看起來兩個圖層融合在一起了:
blackMarble.alpha = 0.5; // 0.0 全透明. 1.0 不透明.

接着,增加一下亮度:
blackMarble.brightness = 2.0; // > 1.0 增加亮度 < 1.0減少亮度

添加第三個單一圖片的圖層,它只覆蓋某個范圍:
layers.addImageryProvider(new Cesium.SingleTileImageryProvider({ url : '../images/Cesium_Logo_overlay.png', rectangle : Cesium.Rectangle.fromDegrees(-75.0, 28.0, -67.0, 29.75) }));

下面是完整代碼:
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; blackMarble.brightness = 2.0; layers.addImageryProvider(new Cesium.SingleTileImageryProvider({ url : '../images/Cesium_Logo_overlay.png', rectangle : Cesium.Rectangle.fromDegrees(-75.0, 28.0, -67.0, 29.75) }));
可以查看Sandcastle的 完整示例 .
接着,我們會看到更詳細的更重要的影像圖層功能。首先,我們來看看提供了影像圖層訪問數據標准的各種Provider。
可以使用的影像圖層
使用CesiumLab可以很方便的把你的影像圖層切片,並且它自帶了加載示例代碼,很容易就添加到你的Cesium項目里了。
影像providers
像前面兩個高精度影像數據非常大,大到甚至占用一整塊硬盤。所以為了客戶端能依據當前視野范圍漸進加載,影像經常被切分成很多小的圖片,這個過程叫 切片(tiles)。 Cesium使用imagery providers屬性支持若干種切片請求標准。大部分影像providers使用HTTP協議 REST 接口方式請求數據。依據切片的組織形式和請求形式不同,影像數據分為幾種providers。Cesium支持下列標准:
- Web Map Service (WMS) - 一種OGC標准,從分布式地理數據庫中通過地圖的地理范圍來請求切片。 Cesium使用 WebMapServiceImageryProvider去支持這種。
- Tile Map Service (TMS) - 一種訪問地圖切片的REST接口。 可以用CesiumLab, MapTiler 或者 GDAL2Tiles . Cesium中使用TileMapServiceImageryProvider.
- OpenGIS Web Map Tile Service (WMTS) - 一種OGC標准,主要是為預渲染的地圖切片形式. Cesium中使用 WebMapTileServiceImageryProvider.
- OpenStreetMap - 訪問 OpenStreetMap 切片 或者 任意 Slippy map tiles.有很多方法 發布這種服務 .Cesium中使用createOpenStreetMapImageryProvider.
- Bing 地圖 - 使用Bing 地圖 REST 服務訪問切片. 在這里 https://www.bingmapsportal.com/創建Bing地圖的key. Cesium中使用 BingMapsImageryProvider.
- Esri ArcGIS MapServer - 使用 ArcGIS Server REST API 訪問存儲在ArcGIS Server上的切片。Cesium中使用ArcGisMapServerImageryProvider.
- Google Earth Enterprise - 訪問Google Earth 企業版服務器發布的影像切片。Cesium中 GoogleEarthImageryProvider.
- Mapbox - 使用 Mapbox API訪問切片. 在這里新建用戶,並且創建一個 access token. Cesium中使用 MapboxImageryProvider.
- 普通圖片文件 - 使用一張普通圖片創建影像圖層. Cesium中使用 SingleTileImageryProvider.
- 自定義切片機制 - 使用UrlTemplateImageryProvider, 可以通過 URL 模板連接各種影像資源 。比如TMS服務的URL模板是:
//cesiumjs.org/tilesets/imagery/naturalearthii/{z}/{x}/{reverseY}.jpg
. - 切片坐標 - 用來顯示全球是如何被切片的,支持多種切片規則,畫出每個切片的地理邊界,並且用文字標注每個切片的level,x,y坐標。
- 百度地圖 - 用來加載百度默認地圖或者自定義樣式地圖,請聯系我們。
也可以通過實現 ImageryProvider 接口支持其他類型的影像服務。如果你這么做了,那么肯定非常有用,請 貢獻給Cesium,每個人都能使用。
如何去創建某種特定的影像provider,看一下詳細文檔 。因為很多影像provider都有這些屬性,所以我們重點看下 SingleTileImageryProvider。
-
url
- 圖片地址。對於大部分影像provider,這個屬性是唯一必須的屬性。其他影像provider,這個url一般指的是影像服務的根路徑。 -
extent
- 可選屬性,影像覆蓋的經緯度范圍 ,默認是全球。 -
credit
- 可選屬性,數據源的版權信息,它會在地圖上顯示出來。一些影像provider,像 BingMapsImageryProvider 和ArcGIS Server REST API, 會自動從服務獲取版權信息。 -
proxy
-可選屬性,請求服務的代理服務器,一般用來解決跨域問題。
跨域資源訪問
基於安全性考慮,當今的瀏覽器煞費苦心的去防止javascipt代碼讀取來自其他網站的圖片像素信息。像Cesium這樣的基於WebGL的項目,在一些條件下是不能把圖片轉成紋理 ,這個條件是:圖片來自其他服務器或者其他端口,並且服務器也沒有明確聲明允許跨域訪問。為了解決這個問題:服務器通過設置HTTP響應的 Cross-Origin Resource Sharing (CORS) 頭(header)來明確表示圖片里不包含機密信息,因此被其他網站讀取像素值是安全的。
很可惜,不是所有的影像服務器都支持CORS。如果沒有這個頭,那么應該設置一個Cesium所在服務器的代理服務器地址。當使用這個代理,圖片就像來源於這個基於Cesium的網站,最終到達瀏覽器和Cesium客戶端中。當創建一個影像Provider的時候,填充proxy
屬性。Cesium包含一個簡單的代理服務器 ,基於Node.js,開發方便大家開發調試。
layers.addImageryProvider(new Cesium.ArcGisMapServerImageryProvider({ url : '//server.arcgisonline.com/ArcGIS/rest/services/World_Street_Map/MapServer', proxy : new Cesium.DefaultProxy('/proxy/') }));
如果你架設了一個公開影像服務,我們鼓勵你啟用CORS,就像這里 ,而不是使用一個代理服務器。
影像providers 和 . layers 對比
至此,我們還不是太清楚影像provider和圖層的差異。一個影像Provider使用某種特定服務去請求切片。同時一個layer把影像provider里的影響切片顯示出來。
var layer = layers.addImageryProvider(imageryProvider);
可以簡略寫為:
var layer = new ImageryLayer(imageryProvider); layers.add(layer);
我們通常創建一個影像provider是為了創建一個影像圖層,使用圖層的 show
, alpha
, brightness
, 和contrast
等屬性可以修改可視化效果。影像圖層。把影像provider和圖層解耦,有助於去更簡單的去實現各種新的影像provider。
一個像上面示例里的影像圖層集合,決定了圖層的渲染順序。圖層默認根據圖層的添加順序,從下到上去繪制。影像圖層結合像Cesim的其他集合一樣,也有 add
, remove
, and get
等方法。額外的,該集合可以使用 raise
, raiseToTop
, lower
, 和lowerToBottom
去重新排序。 ImageryLayerCollection。
資源
Sandcastle的示例一定要看:
- 影像圖層 - 這篇教程的示例代碼.
- 影像圖層集合 - 各種來源的影像數據,獨立的調整透明度。
- 影像效果調整 - 調整圖層的亮度( brightness),對比度( contrast), gamma, hue, and saturation。
另外,最好看下幫助文檔:
