前言
????????在Cesium的學習中,學會讀文檔十分重要!!!在這里附上Cesium中英文文檔1.117。
? ? ? ? 在Cesium項目中,在平坦坦地球中加入三維地形不僅可以增強真實感與可視化效果,還可以??提升用戶體驗與交互性,今天,我們來學習一下如何將dem/tif格式的地形數據進行分塊和加載。
一、dem/tif格式數據下載
? ? ? ? DEM(??Digital Elevation Model??)是描述地表高程信息的數字模型,通過規則網格或點云數據記錄地形起伏,廣泛應用于地理信息系統(GIS)、遙感、三維可視化(如Cesium)等領域。
1.1、DEM常見數據格式
- GeoTIFF(.tif)?????:地理參考的柵格格式,高程值存儲為像素值,元數據(坐標、投影)嵌入文件頭。其兼容性強,QGIS、ArcGIS、Python GDAL均支持。 如NASA SRTM數據(30米分辨率)常以GeoTIFF分發。
- ASCII Grid(.asc):純文本格式,以行列數、網格尺寸、高程值矩陣定義地形。
- ??HGT(.hgt):SRTM任務專用格式,每文件覆蓋1°×1°區域。
- DEM(.dem):USGS標準格式,含頭文件(坐標、分辨率)和二進制高程數據。
- ??Point Cloud(.las/.laz):離散點云記錄高程,精度極高但需柵格化生成DEM。
1.2、DEM數據的獲取
? ? ? ? 在國內,我們可以使用地理空間數據云來獲取DEM數據。
????????地理空間數據云(GSCloud)旨在通過云計算、大數據等技術,解決科研人員在地理空間數據全流程(搜索、獲取、分析等)中的需求,推動數據開放共享與高效利用。其服務理念為“開放共享、創新服務”,已發展成為國內最具影響力的地學數據平臺之一。
????????在左上角的數據集中,我們可以選擇想要的DEM類型,然后選擇其空間位置,將其下載下來,一般這里的格式為dem或tif,如果是其他格式如img,可以在gis軟件中將其轉換,方便后續切片的處理。
? ? ? ? 下載好的數據直接預覽可能一片漆黑,要專業的gis軟件預覽的效果會好一點。
二、數據切片
? ? ? ? 切片是指將??原始DEM數據??(如整塊GeoTIFF或HGT文件)切割成??多層級瓦片金字塔??(Tile Pyramid),每個瓦片(Tile)覆蓋特定地理范圍和分辨率,按需動態加載,提升性能。
? ? ? ? 而全球30米分辨率DEM未經切片的原始數據可能高達數十GB,直接加載會耗盡內存和網絡帶寬。
? ? ? ? 這里,我們使用cesiumlab來進行切片(也可以用gdal+python)。CesiumLab?是一個基于WebGL技術的3D地理信息系統(GIS)平臺,主要用于在瀏覽器中呈現和分析地理空間數據。它由Cesium平臺設計,旨在最大化提升三維數據可視化效率?。最重要的是,其基礎功能基本上免費。
????????
????????這里,存儲類型記得改成散列,在提交處理時,有可能會讓你登錄,若未登錄,點擊上面的網站注冊一下就好了,然后第一次登錄的賬號密碼就是注冊的賬號密碼,默認密碼是手機號后8位。
? ? ? ? 切片好的文件夾如下,其中meta是其元數據,我們可以從中獲取此DEM的范圍等信息。
{"bounds": {"east": 117.00018882751465,"north": 30.00014305114746,"south": 28.99970054626465,"west": 115.99974632263184},"contentType": "quantizedmesh","latLonBounds": {"east": 117.00018882751465,"north": 30.00014305114746,"south": 28.99970054626465,"west": 115.99974632263184},"maxzoom": 14,"minzoom": 0,"proj": 4326,"tiletrans": "tms","type": "terrain","ziped": false
}
三、TerrainProvider的介紹
? ? ? ? 在Cesium中,一般使用Cesium.TerrainProvider來加載地形。TerrainProvider是Cesium的一個接口,負責從服務器或本地獲取地形瓦片數據。
? ? ? ? 它有幾個子類,EllipsoidTerrainProvider,CesiumTerrainProvider VRTheWorldTerrainProvider,GoogleEarthEnterpriseTerrainProvider,ArcGISTiledElevationTerrainProvider。其中EllipsoidTerrainProvider是用來加載橢球模型(無真實的地形),CesiumTerrainProvider可以用來加載cesium自帶的地形或者是用戶的地形,VRTheWorldTerrainProvider支持從VT MAK VR-TheWorld Server服務器請求的高度地圖地形圖,最后兩個是谷歌和ArcGIS的地形。
? ? ? ? 這里,我們主要學習用CesiumTerrainProvider加載地形。
四、CesiumTerrainProvider加載默認地形
????????在這個文檔中,CesiumTerrainProvider不能直接構造地形對象(可能其他的版本不一樣),其支持兩種格式的地形
- Quantized Mesh
- Height Map
? ? ? ? 我們上面的切片地形是第一種格式的。
? ? ? ??CesiumTerrainProvider提供了兩種加載地形的方法CesiumTerrainProvider.fromIonAssetId 和?CesiumTerrainProvider.fromUrl,其中第一種可以用來加載Cesium的資源,但在這之前,記得先申請一個Ion。Cesium.Ion.defaultAccessToken =‘你的Ion’
? ? ? ? 其有兩個參數,第一個是資源id,比如說地形是1,第二個是對象,其有如下參數,第一個是真實的地球光照,第二個是水的渲染,但是需要從服務器獲取。
let terrainProvider1 = Cesium.CesiumTerrainProvider.fromIonAssetId(1, {requestVertexNormals: true,requestWaterMask: true,});viewer.terrainProvider = terrainProvider1;
? ? ? ? 效果如下,但是默認的地形受網絡影響大,有時候加載不出來。
五、CesiumTerrainProvider加載本地地形
5.1、直接加載
? ? ? ? 本地地形則是通過CesiumTerrainProvider.fromUrl函數來加載。它的參數也和上面的類似,但是第一個路徑需要是相對路徑,在本地Cesium無法讀取絕對路徑。
? ? ? ? 注意這個路徑所在文件夾terrain是打開里面一個有json文件的文件夾,這里我把terrain放在public里。
let terrainProvider = Cesium.CesiumTerrainProvider.fromUrl('/terrain',);viewer.terrainProvider = terrainProvider;
5.2、服務器代理加載?
? ? ? ? 但是上面那種方法無法用于實際生產,因為我們切片的目的就是提高性能,減少頁面體積,如果直接放在public里,這些地形切片會直接和前端頁面一起全部發送給瀏覽器,相當于沒有解決問題。
? ? ? ? 而且,這些地形通常是不變的靜態數據,因此我們可以用一個服務器來進行發布。這里,我用nginx,也可以用python,tomcat等。
? ? ? ? 我們先去nginx官網下載一個nginx。下載好后,其目錄結構如下。terrain是我們的切片地形,需要我們復制過來(terrain1是我的另一個)。
? ? ? ? 接下來,我們要對其進行代理配置,進入第一個文件夾,里面有一個nginx.conf文件,這是其配置文件。其配置內容大概如下。
- ?全局塊(main)?:設置工作進程數(worker_processes auto;匹配CPU核心數)、錯誤日志路徑及級別(建議生產環境用warn級別)?
- events塊?:定義連接處理模型(如use epoll;優化Linux性能)、單個進程最大連接數(高并發場景需調高worker_connections)
- http塊?:包含全局HTTP設置(如MIME類型、日志格式)、多個server虛擬主機配置? ?
- server塊?:定義監聽端口(listen 80;)、域名(server_name)、訪問控制規則,內部嵌套location路徑匹配規則
????????這里,我們要配置的是server這一塊,其默認端口號為 80,這里我改成了9999。
????????然后就是location路徑匹配規則,root里面的是根路徑,如何不修改,nginx默認訪問的就是這個文件夾,這里要改成我們代理的文件夾terrain。
????????atuoindex on在Nginx配置中用于開啟目錄瀏覽功能。當設置autoindex on時,Nginx會在訪問指定目錄時顯示該目錄下的文件列表,類似于文件管理器中的目錄瀏覽功能,這里我們要開啟才能訪問我們的資源。
? ? ? ? 最后就是一些跨域請求問題,全部允許。
server {listen 9999;server_name localhost;#charset koi8-r;#access_log logs/host.access.log main;location / {root terrain;autoindex on;# 支持跨域add_header Access-Control-Allow-Origin *;add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';add_header 'Access-Control-Allow-Headers' 'DNT,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type,Range';add_header 'Access-Control-Expose-Headers' 'Content-Length,Content-Range';}
? ? ? ? ?最后點擊nginx.exe啟動,瀏覽器訪問http://localhost:9999/就可以訪問到文件里面的內容。
? ? ? ? 最后,將這個路徑填入即可。
let terrainProvider = Cesium.CesiumTerrainProvider.fromUrl('http://localhost:9999/',);viewer.terrainProvider = terrainProvider;
? ? ? ? 最后效果如下,如果大家喜歡我的文章的話,請點一個免費的贊和關注吧!