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 坐標系
2.1 cesium中的坐標系
Cesium中常用的坐標系主要有兩種:
WGS84坐標系和笛卡爾空間直角坐標系。平時我們常見的某個點的經緯度就是在WGS84坐標系下某個點的坐標,它的坐標原點在橢球的質心;
而笛卡爾坐標系主要是用來做空間位置的變化如平移、旋轉和縮放等等,它的坐標原點在橢球的中心。
二者的聯系如下圖, 笛卡爾空間坐標的原點就是橢球的中心。
Pick----屏幕坐標
Cartesian----世界坐標
cartographic-----地理坐標(弧度)
Cesium中的坐標系:
1、平面坐標系(Cartesian2);
2、笛卡爾空間直角坐標系(Cartesian3);
3、Cartesian4(unknown,在應用中幾乎用不到)
4、Cartographic(地理坐標系下經緯度的弧度表示),通常情況下通過它和WGS84坐標系之間互轉。
2.1.1世界坐標
以橢球中心為原點的空間直角坐標系中的一個點的坐標。Cesium中用Cartesian3變量表示,笛卡爾空間直角坐標系,用
new Cesium.Cartesian3(x, y, z)
創建。
2.1.2 地理坐標
就是測繪中的地理經緯度坐標,地理坐標系,坐標原點在橢球的質心。
經度:參考橢球面上某點的大地子午面與本初子午面間的兩面角。東正西負。
緯度 :參考橢球面上某點的法線與赤道平面的夾角。北正南負。
Cesuim中沒有具體的經緯度對象,要得到經緯度首先需要計算為弧度,再進行轉換。
2.1.3 弧度
Cartographic變量表示。
new Cesium.Cartographic(longitude, latitude, height)。
是用弧度表示的經緯度,這里的參數也叫做longitude,latitude,即經度和緯度。弧度即角度對應弧長是半徑的倍數。
角度轉弧度 π/180×角度 ;
弧度變角度 180/π×弧度。
2.2 坐標轉換
Cesium其實是一個封裝好的WebGL庫,當然這里面就牽扯到好幾套坐標問題:屏幕坐標、三維空間坐標、投影坐標。坐標轉換肯定是我們在開發任何地理信息系統中經常會碰到的問題,也比較復雜。
“平面坐標系” 和“笛卡爾空間直角坐標系”和“Cartographic”之間的相互轉換思路如下所示。
坐標的定義:
1:Cartesian2-----new Cesium.Cartesian2(x, y)
2:Cartesian3---- new Cesium.Cartesian3(x, y, z)
3:Cartographic----new Cesium.Cartographic(longitude, latitude, height) 注:經緯度為弧度單位
轉換:
Cartesian3→ Cartesian2, Cesium.Cartesian2.fromCartesian3(cartesian, result)→ Cartesian2
經緯度坐標(WGS84)→ Cartesian3, Cesium.Cartesian3.fromDegrees(longitude, latitude, height, ellipsoid, result) → Cartesian3
弧度坐標 → Cartesian3, Cesium.Cartesian3.fromRadians(longitude, latitude, height, ellipsoid, result) → Cartesian3
Cartesian3→ Cartographic, Cesium.Cartographic.fromCartesian(cartesian, ellipsoid, result) → Cartographic
經緯度坐標(WGS84)→ Cartographic, Cesium.Cartographic.fromDegrees(longitude, latitude, height, result) → Cartographic
單位:
經緯度坐標和弧度坐標也可以通過Cesium.Math來轉換。
Cesium.CesiumMath.toDegrees(radians) → Number
Cesium.CesiumMath.toRadians(degrees) → Number
2.2.1 坐標系
new Cesium.Cartesian2(1,1) //表示一個二維笛卡爾坐標系,也就是直角坐標系(屏幕坐標系) new Cesium.Cartesian3(1,1,1) //表示一個三維笛卡爾坐標系,也是直角坐標系(就是真實世界的坐標系)
2.2.2 二維屏幕坐標系到三維坐標系的轉換
var pick1= scene.globe.pick(viewer.camera.getPickRay(pt1), scene) //其中pt1為一個二維屏幕坐標。
2.2.3 三維坐標到地理坐標的轉換
var geoPt1= scene.globe.ellipsoid.cartesianToCartographic(pick1) //其中pick1是一個Cesium.Cartesian3對象。
2.2.4 地理坐標到經緯度坐標的轉換
var point1=[geoPt1.longitude / Math.PI * 180,geoPt1.latitude / Math.PI * 180]; //其中geoPt1是一個地理坐標。
2.2.5 經緯度坐標轉地理坐標(弧度)
var cartographic = Cesium.Cartographic.fromDegree(point) //point是經緯度值 var coord_wgs84 = Cesium.Cartographic.fromDegrees(lng, lat, alt);//單位:度,度,米
2.2.6 經緯度坐標轉世界坐標
var cartesian = Cesium.Cartesian3.fromDegree(point)
2.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都是三維坐標系
轉換到笛卡爾坐標系后就能運用計算機圖形學中的仿射變換知識進行空間位置變換如平移旋轉縮放。cesium.js為我們提供了很有用的變換工具類,
Cesium.Cartesian3(相當於Point3D)Cesium.Matrix3(3x3矩陣,用於描述旋轉變換)Cesium.Matrix4(4x4矩陣,用於描述旋轉
加平移變換),Cesium.Quaternion(四元數,用於描述圍繞某個向量旋轉一定角度的變換)。下面舉個例子:
一個局部坐標為p1(x,y,z)的點,將它的局部坐標原點放置到loc(lng,lat,alt)上,局部坐標的z軸垂直於地表,局部坐標的y軸指向正北,
並圍繞這個z軸旋轉angle度,求此時p1(x,y,z)變換成全局坐標笛卡爾坐標p2(x1,y1,z1)是多少?
var rotate = Cesium.Math.toRadians(angle);//轉成弧度 var quat = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, rotate); //quat為圍繞這個z軸旋轉d度的四元數 var rot_mat3 = Cesium.Matrix3.fromQuaternion(quat);//rot_mat3為根據四元數求得的旋轉矩陣 var pt = new Cesium.Cartesian3(x, y, z);//p1的局部坐標 // m2為旋轉加平移的4x4變換矩陣,這里平移為(0,0,0),故填個Cesium.Cartesian3.ZERO var m = Cesium.Matrix4.fromRotationTranslation(rot_mat3, Cesium.Cartesian3.ZERO); m = Cesium.Matrix4.multiplyByTranslation(m, pt);//m = m X v //得到局部坐標原點的全局坐標 var cart3 = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(lng, lat, alt)); //m1為局部坐標的z軸垂直於地表,局部坐標的y軸指向正北的4x4變換矩陣 var m1 = Cesium.Transforms.eastNorthUpToFixedFrame(cart3); m = Cesium.Matrix4.multiplyTransformation(m, m1);//m = m X m1 var p2 = Cesium.Matrix4.getTranslation(m);//根據最終變換矩陣m得到p2
參考文章
龍之吻number7,關於Cesium中的常用坐標系及說明。