1. 程式人生 > >Cesium中的地形和座標轉換說明 Cesium基礎使用介紹

Cesium中的地形和座標轉換說明 Cesium基礎使用介紹

轉自miaosen原文 Cesium基礎使用介紹

1 Cesium中的地形

 

Cesium中的地形系統是一種由流式瓦片資料生成地形mesh的技術,厲害指出在於其可以自動模擬出地面、海洋的三維效果。建立地形圖層的方式如下:

var terrainProvider = new Cesium.CesiumTerrainProvider({
    url : 'https://assets.agi.com/stk-terrain/v1/tilesets/world/tiles', // 預設立體地表
    // 請求照明
    requestVertexNormals: true,
    // 請求水波紋效果
    requestWaterMask: true
});
viewer.terrainProvider = terrainProvider;

 Cesium支援兩種型別的地形,STK World Terrain和Small Terrain。

1.1 STK世界地形

STK世界地形(STK World Terrain),其是高解析度, 基於quantized mesh的地形。這是一種基於網格的地形,可充分利用GL中的Shader來渲染,效果相當逼真。該地形使用了多種資料來源,分別適應不同地區和不同精度時的情形,如,美國本土使用美國國家高程資料集(National Elevation Dataset,NED)的高程,精度3-30米;對於歐洲使用EU-DEM高程,精度30米;對於澳洲使用Australia SRTM-derived 1 Second DEM高程,精度30米;對於-60至60緯度段使用CGIAR SRTM高程,精度90米;對於整個地球使用GTOPO30,精度1000米。該地形的生成方式尚未公開,對於封閉的區域網應用時,則需購買AGI的STK terrain server。但是AGI提供了一個webapi可供因特網上呼叫,並提供了這種地形的格式細節。

1.2 Small Terrain

Small Terrain是中等高解析度基於heightmap的地形,渲染出的地形效果不如quantized mesh的地形,但也基本能接受。
可以由DEM資料生成這種規範的.terrain檔案。生成工具見https://groups.google.com/forum/#!topic/cesium-dev/rBieaEBJHi,需要gdal庫和numpy。

2 座標轉換

Cesium其實是一個封裝好的WebGL庫,當然這裡面就牽扯到好幾套座標問題:螢幕座標、三維空間座標、投影座標。而且座標轉換肯定是我們在開發任何地理資訊系統中經常會碰到的問題,也比較複雜,簡單總結了幾種轉換方式:

2.1 座標系

new Cesium.Cartesian2(1,1) //表示一個二維笛卡爾座標系,也就是直角座標系(螢幕座標系)
new Cesium.Cartesian3(1,1,1) //表示一個三維笛卡爾座標系,也是直角座標系(就是真實世界的座標系)

2.2 二維螢幕座標系到三維座標系的轉換

var pick1= scene.globe.pick(viewer.camera.getPickRay(pt1), scene) //其中pt1為一個二維螢幕座標。

2.3 三維座標到地理座標的轉換

var geoPt1= scene.globe.ellipsoid.cartesianToCartographic(pick1) //其中pick1是一個Cesium.Cartesian3物件。

2.4 地理座標到經緯度座標的轉換

var point1=[geoPt1.longitude / Math.PI * 180,geoPt1.latitude / Math.PI * 180]; //其中geoPt1是一個地理座標。

2.5 經緯度座標轉地理座標(弧度)

var cartographic = Cesium.Cartographic.fromDegree(point) //point是經緯度值
var coord_wgs84 = Cesium.Cartographic.fromDegrees(lng, lat, alt);//單位:度,度,米

2.6 經緯度座標轉世界座標

var cartesian = Cesium.Cartesian3.fromDegree(point)

2.7 計算兩個三維座標系之間的距離

var d = Cesium.Cartesian3.distance(
    new Cesium.Cartesian3(pick1.x, pick1.y, pick1.z), 
    new Cesium.Cartesian3(pick3.x, pick3.y, pick3.z) ); //pick1、pick3都是三維座標系