翻譯地址:https://cesiumjs.org/tutorials/Cesium-Workshop/
翻譯者:嬴渠梁
概述
歡迎來到cesuim社區!很高興你的到來。為了發展你自己的網絡地圖應用成為可能,本教程將會從頭到尾的介紹一個簡單的cesium開發過程。本教程將提及大部分重要的cesium API,但是它並不意味着全面(cesium 有很多特征)。我們的目的是介紹一下基本原理和工具,剩下由你自己探索cesium!
我們將要創建一個簡單的應用程序來可視化紐約的地貌,我們將要加載多種2d和3d數據並且創建幾個攝像頭和顯示選項讓用戶交互,最后,我們將加載3D模型的無人機偵察地理緩存的位置,我們充分利用我們的三維可視化。
最后,你將了解cesium工作原理和如何配置cesium、加載數據集、創建有風格的幾何圖形、創建3d瓦片、控制照相機、並將鼠標交互添加到應用中。
安裝
只需要幾步就可以搭建出開發環境
1、通過訪問helloworld這個示例來確保你的瀏覽器跟cesium兼容,如果不兼容,請查看故障
2、安裝 node.js
3、提取代碼https://github.com/AnalyticalGraphicsInc/cesium-workshop,克隆或下載zip都行
4、通過cmd導航到cesium項目的根路徑
5、執行 npm install
6、執行 npm start
控制台就會顯示Cesium development server running locally. Connect to http://localhost:8080/,不要關閉控制台
然后,通過瀏覽器訪問 http://localhost:8080,你應該看到項目啟動和運行,卡住了?入門教程更深入的介紹了cesium的設置。
應用目錄
現在參觀我們的應用目錄吧!注意這個應用目錄盡可能設計的簡單,並且忽略了今天各種不同的現代js框架,但是一旦你掌握了cesium,就可以自由使用它!
source: 我們的應用代碼和數據
ThirdParty: 外部庫,只是cesium庫
LICENSE.md:項目使用的條款或協議
index.html: 項目主頁
server.js: 服務啟動文件
現在看一下index.html,里面有一個div和幾個input,觀察一下cesium只是一個div,跟其他div沒什么兩樣
首先,在head標簽里引入cesium.js庫,它定義了cesium對象,該對象包含了cesium所有的庫
<script src="ThirdParty/Cesium/Cesium.js"></script>
cesium附帶了一組需要此CSS的小部件。
<style>@import url(ThirdParty/Cesium/Widgets/widgets.css);</style>
在body標簽里面創建一個div存放cesium小部件。
<div id="cesiumContainer"></div>
最后,我們在body最底下創建script標簽引入App.js
<script src="Source/App.js"></script>
就是這樣,剩下的html用來收集用戶數據,我們一會用到
開發資源
對於本概要和貫穿剩下的cesium的開發生涯,我們鼓勵你依賴下列資源:
referenceDocument(參考文檔):包含許多代碼段的cesium API的完整指南
SandCastle(沙塔):具有大量代碼庫的實時編譯環境
Tutorials(教程):cesium開發領域的詳細介紹
Cesium Forum(cesium討論):cesium相關問題的討論問答資源
無論何時你陷入困境,這些資源或許會給你答案
工作流程
跟着這個教程學:
1、用你最喜歡的編輯器打開 Source/App.js ,編輯和修改內容
2、把Source/AppSkeleton.js的代碼復制到Source/App.js期內容注釋的版本代碼
3、確定你的服務器仍然運行在根目錄,如安裝所述
4、導航到http://localhost:8080,你應該看到一個黑色的頁面
5、按照指導,代碼注釋掉,保存Source/App.js,刷新頁面,你將看到新變化
又卡主了?你可以通過沙塔和應用程序的簡化版本來在線查看(不過沒有UI)
The complete code(完整的代碼)
The commented code(注釋掉的代碼)
好了現在讓我們開始吧
創建一個觀察者(查看器)
cesium應用的基礎就是觀察者,這是一個3d交互式的球體,他有很多功能。添加觀察者到 id 為 cesiumContainer 的div里面,通過取消注釋第一行。
var viewer = Cesium.viewer('cesiumContainer')
備注:你這發現上面這行代碼不能顯示出來地球儀,因為你需要有一個bingmap的key:我的key給大家用一下吧,代碼如下:
//設置key值
Cesium.BingMapsApi.defaultKey = 'SHHFsraTruJW1WlBZo4W~Voo0XWCy1Zt2-2iAVLxvFQ~Ai_3AucRsH-FTKgfBT34iPCl128DNCGslmWLM0Hplg9UgMZoftwZFkKbhHu_RAo8' var viewer = new Cesium.Viewer('cesiumContainer');
如果大家要注冊自己的key,注冊地址如下:https://www.bingmapsportal.com/Application ,當然你得先注冊賬號並且登錄進去
這一行中有很多事情發生,你將會看到像這樣的一個地球儀:
默認情況下場景處理鼠標和輸入事件,現在可以嘗試用默認的相機來控制地球儀吧:
1、鼠標單擊左鍵並拖動鼠標,將相機移到地球表面
2、鼠標右鍵單擊並拖動鼠標,放大和縮小相機
3、鼠標中間輪滾動,也能放大和縮小相機
4、鼠標中間輪點擊和拖動,旋轉相機周圍的點在地球表面。
除了地球儀之外,Viewer還附帶一些默認的有用的小部件,在上面的圖片中標出。
圖片數字1、Geocoder(地圖編碼器):一個位置搜索工具,用照相飛機查詢位置。默認使用bingMap地圖數據
圖片數字2、Home Button(主頁按鈕):返回默認視圖
圖片數字3、Scene Mode Picker(場景模式選擇器):在3D、2D、哥倫布圖、CV模式之間來回切換
圖片數字4、Basic Layer Picer(基礎層顯示器):選擇圖像和地形顯示在地球上
圖片數字5、Naviagtion Help Button(導航幫助按鈕):顯示默認攝像頭的控價
圖片數字6、Animation(動畫):顯示視圖的播放數度
圖片數字7、Timeline(時間軸):指示當前時間,並允許用戶使用洗刷器跳轉到特定時間
圖片數字8、Credits Display(顯示器):數據分配點,幾乎總是用到
圖片數字9、Fullscreen Button(全屏):全屏
我們可以配置我們的查看器來包含或排除這些功能,而更多的是通過在創建選項對象時作為參數。 對於這個應用程序,刪除第一行並通過取消注釋接下來的幾行來配置新的查看器:
var viewer = new Cesium.Viewer('cesiumContainer', { scene3DOnly: true, //只使用3D(圖片數字3消失) selectionIndicator: false, //選擇指示符 baseLayerPicker: false //基礎層拾取器(圖片數字4消失) });
這將創建一個沒有選擇指示器,基礎層選取器或場景模式選擇器小部件的查看器,因為這些對於我們的應用程序來說是不必要的。 有關完整的Viewer選項,請參閱Viewer文檔。
添加圖像
cesium應用程序下一個關鍵元素就是添加圖像,在不同分辨率下我們將圖像集平鋪到虛擬球上,為了提供最佳性能,Cesium只請求和渲染在當前視圖中可見並且分辨率(也稱為縮放比例)適合攝像機與地球表面的距離以及地球儀的maximumScreenSpaceError的圖像塊。
為了更直觀地了解圖像如何工作,請查看Cesium Inspector。
cesium提供了很多工具來處理圖像層,如顏色調整和圖層混合。 一些代碼示例:
1、add basic imagery; 添加基本圖像
2、Adjusting imagery colors; 修改圖像顏色
3、Manipulating and ordering imagery layers; 操作和訂購圖層
4、Splitting imagery layers; 分割圖層
Cesium提供了許多不同提供商提供的圖像支持。
支持的圖像格式如下:
利用具有地理空間位置信息的數據制作地圖。其中將地圖定義為地理數據可視的表現。這個規范定義了三個操作:
(1)GetCapabitities 返回服務級元數據,它是對服務信息內容和要求參數的一種描述;
(2)GetMap 返回一個地圖影像,其地理空間參考和大小參數是明確定義了的;
(3) GetFeatureInfo(可選)返回顯示在地圖上的某些特殊要素的信息。
- TMS
- WMTS (with time dynamic imagery)
- ArcGIS
- Bing Maps
- Google Earth
- Mapbox
- Open Street Map servers
- Single tile 單一瓦片
默認情況下,Cesium將Bing地圖用於圖像。 要小心,不同的數據提供者具有不同的歸因要求 - 確保您有權使用來自特定提供者的數據,並將其歸入信用容器(如果適用)。 與查看器一起打包的圖像主要用於演示目的。 為了在我們的應用程序中使用Bing圖像集,我們需要獲取我們自己的Bing key。 用這樣的一行設置Bing鍵(在我們的應用程序的頂部,在創建查看器之前):
Cesium.BingMapsApi.defaultKey = 'AsarFiDvISunWhi137V7l5Bu80baB73npU98oTyjqKOb7NbrkiuBPZfDxgXTrGtQ'; // For use in this application only. Do not reuse!
同樣,不同的圖像提供商對使用的要求也會有所不同。 現在我們有權使用這個圖像集,我們實際上可以添加圖像層。 首先,我們創建一個ImageryProvider,傳入一個數據url和一些配置選項,然后將ImageryProvider添加到viewer.imageryLayers。
// Add Bing imagery viewer.imageryLayers.addImageryProvider(new Cesium.BingMapsImageryProvider({ url : 'https://dev.virtualearth.net', mapStyle: Cesium.BingMapsStyle.AERIAL // Can also use Cesium.BingMapsStyle.ROADS 參數如下:AERIAL_WITH_LABELS 、ROAD 、CANVAS_DARK 、CANVAS_LIGHT 、CANVAS_GRAY 、ORDNANCE_SURVEY 、COLLINS_BART }));
隨着上面的代碼添加,我們的應用程序應該看起來像這樣,當你放大:
這實際上與默認圖像樣式相同,但可以隨意使用 BingMapsStyle 來查看差異。
有關圖像的更多信息,請參閱我們的圖像圖層教程。
添加地形
cesium支持對海洋,湖泊和河流的全球高分辨率地形和水影響進行流式傳輸和可視化。 與2D地圖相比,山峰,山谷和其他地形特征確實顯示出3D地球的優勢。 像圖像一樣,cesium引擎將從服務器傳輸地形數據,只根據當前攝像機的位置請求和渲染瓦片。
以下是地形數據集和配置選項的一些演示:
- ArcticDEM : 高分辨率的北極地形
- PATerrain : 高分辨率賓夕法尼亞地形
- Terrain display options : 一些地形配置選項和格式
- Terrain exaggeration : 使地形高程差異更加顯着
支持的地形格式:
- Our own quantized-mesh format 我們自己量化的網格格式
- Heightmap 高度圖
- Google Earth Enterprise 谷歌地球企業版
為了添加地形數據,我們創建一個 CesiumTerrainProvider,,指定一個數據url和一些配置選項,然后將這個提供者添加為viewer.terrainProvider。
viewer.terrainProvider = new Cesium.CesiumTerrainProvider({ url : 'https://assets.agi.com/stk-terrain/world', requestWaterMask : true, // required for water effects requestVertexNormals : true // required for terrain lighting });
requestWaterMask和requestVertexNormals是配置選項,告訴Cesium為水和燈光效果請求額外的數據。 默認情況下,這些設置為false。
最后,現在我們已經有地形了,我們只需要再多一行來確保地形背后的物體被正確地遮擋。 只有最前面的對象才可見。
我們現在有地形和生氣的水。 紐約是相當平坦的,所以隨時探索,以便看到新的地形在行動。 舉一個特別明顯的例子,您可以導航到更加崎嶇的地區,如大峽谷或舊金山。
配置場景
現在只需稍微安裝一下,即可在適當的位置和時間啟動查看器。 這涉及與viewer.scene交互,這是查看器中所有圖形元素的容器。
首先,我們可以配置我們的場景,以根據太陽的位置使用此線來選擇性地啟用照明。
// Enable lighting based on sun/moon positions (根據太陽/月亮位置啟用照明) viewer.scene.globe.enableLighting = true;
這將使我們的場景中的照明隨着時間的變化而變化,這樣當太陽不能看的時候,你可以看到地球的一部分變暗。
接下來,在我們開始設置初始視圖之前,讓我們回顧一下幾個基本的Cesium類型:
- Cartesian3 : a 3D Cartesian point – when used as a position it is relative to the center of the globe in meters using the Earth fixed-frame (ECR)
- 三維笛卡爾點 - 當用作位置時,它使用地球固定框架(ECR)以米為單位,相對於地球的中心
- Cartographic : a position defined by latitude/longitude (in radians) and height off the globe’s surface
- 由緯度/經度(弧度)和地球表面的高度定義的位置
- Heading Pitch Roll : A rotation (in radians) about the local axes in the East-North-Up frame. Heading is the rotation about the negative z axis. Pitch is the rotation about the negative y axis. Roll is the rotation about the positive x axis.
- 幀中圍繞本地軸的旋轉(以弧度表示)。 標題是圍繞負z軸的旋轉。 間距是圍繞負y軸的旋轉。 滾動是圍繞正x軸的旋轉。
- Quaternion : A 3D rotation represented as 4D coordinates.
- 3D旋轉表示為4D坐標。
這些是在場景中定位和定位銫物體所需的基本類型,並且有許多有用的轉換方法。
現在讓我們把我們的場景放在我們的數據所在的紐約市。
相機控制
Camera是viewer.scene 的一個屬性,並控制當前可見的內容。 我們可以通過直接設置攝像機的位置和方向來控制攝像機,也可以使用Cesium攝像機API來設置攝像機的位置和方向。
一些最常用的方法是:
- Camera.setView(options) : set camera at specific position and orientation immediately
- 立即將相機置於特定的位置和方向
- Camera.zoomIn(amount) : move camera forward along the view vector
- 沿相機向前移動相機
- Camera.zoomOut(amount) : move camera backwards along the view vector
- 沿相機向后移動相機
- Camera.flyTo(options) : animates movement from current position to a new position
- 將動作從當前位置移動到新的位置
- Camera.lookAt(target, offset) : orient and position the camera to look at target point with given offset
- 定位和定位相機以給定偏移量來查看目標點
- Camera.move(direction, amount) : move the camera in any direction
- 向任何方向移動相機
- Camera.rotate(axis, angle) : rotate the camera about any axis
- 圍繞任何軸旋轉相機
要了解API可以做什么,請查看這些相機演示:
- Camera API Demo 相機API演示
- Custom Camera Controls Demo 定制相機控制演示
現在讓我們通過將相機移動到紐約來嘗試其中的一種方法。 使用camera.setView()設置初始視圖,使用Cartesian3和HeadingPitchRoll作為位置和方向:
// Create an initial camera view var initialPosition = new Cesium.Cartesian3.fromDegrees(-73.998114468289017509, 40.674512895646692812, 2631.082799425431); var initialOrientation = new Cesium.HeadingPitchRoll.fromDegrees(7.1077496389876024807, -31.987223091598949054, 0.025883251314954971306); var homeCameraView = { destination : initialPosition, orientation : { heading : initialOrientation.heading, pitch : initialOrientation.pitch, roll : initialOrientation.roll } }; // Set the initial view viewer.scene.camera.setView(homeCameraView);
攝像機現在定位和定位,以低頭曼哈頓,我們的視圖參數保存在一個對象,我們可以傳遞給其他相機的方法。
實際上,我們可以使用這個相同的視圖來更新按下主頁按鈕的效果。 而不是讓我們從遠處返回到地球的默認視圖,我們可以覆蓋按鈕,使我們能夠看到曼哈頓的初始視圖。 我們可以通過添加更多選項來調整動畫,然后添加一個取消默認航班的事件偵聽器,並調用flyTo()我們的新主視圖:
// Add some camera flight animation options homeCameraView.duration = 2.0; homeCameraView.maximumHeight = 2000; homeCameraView.pitchAdjustHeight = 2000; homeCameraView.endTransform = Cesium.Matrix4.IDENTITY; // Override the default home button viewer.homeButton.viewModel.command.beforeExecute.addEventListener(function (e) { e.cancel = true; viewer.scene.camera.flyTo(homeCameraView); });
有關基本相機控件的更多信息,請查看我們的相機教程。
時鍾控制
接下來,我們可以配置觀看者時鍾和時間線來控制場景中的時間流逝。
這里是時鍾API的行動。
在特定時間工作時,Cesium使用JulianDate類型,該類型存儲自公元前4712年1月1日(公元前4713年)中午以來的天數。 為了提高精確度,該類將日期的整數部分和日期的秒部分存儲在單獨的組件中,為了算術安全並表示閏秒,日期總是存儲在國際原子時間標准中。
以下是我們如何設置場景時間選項的示例:
// Set up clock and timeline. viewer.clock.shouldAnimate = true; // default viewer.clock.startTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:00:00Z"); viewer.clock.stopTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:20:00Z"); viewer.clock.currentTime = Cesium.JulianDate.fromIso8601("2017-07-11T16:00:00Z"); viewer.clock.multiplier = 2; // sets a speedup viewer.clock.clockStep = Cesium.ClockStep.SYSTEM_CLOCK_MULTIPLIER; // tick computation mode viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP; // loop at the end viewer.timeline.zoomTo(viewer.clock.startTime, viewer.clock.stopTime); // set visible range
這將設置場景動畫的速率,開始和結束時間,並告訴時鍾在到達結束時間時循環。 它還將時間線設置為適當的時間范圍。 看看這個時鍾的例子代碼來試驗時鍾設置。
這就是我們最初的場景配置! 現在,當您運行應用程序時,您應該看到以下內容: