前言
Cesium項目中常常涉及到模型加載、瀏覽以及不一樣數據之間的座標轉換,弄明白Cesium中採用的座標系以及各個座標系之間的轉換,是咱們邁向三維GIS大門的前提,本文詳細的介紹了Cesium中採用的兩大座標系以及之間轉換的各類方法。html
Cesium中的座標系
Cesium中經常使用的座標有兩種WGS84地理座標系和笛卡爾空間座標系,咱們平時經常使用的以經緯度來指明一個地點就是用的WGS84座標,笛卡爾空間座標系經常使用來作一些空間位置變換如平移旋轉縮放等等。兩者的聯繫以下圖。git
其中,WGS84地理座標系包括 WGS84經緯度座標系(沒有實際的對象)和 WGS84弧度座標系(Cartographic);canvas
笛卡爾空間座標系包括 笛卡爾空間直角座標系(Cartesian3)、平面座標系(Cartesian2),4D笛卡爾座標系(Cartesian4)。數組
WGS84座標系
World Geodetic System 1984,是爲GPS全球定位系統使用而創建的座標系統,座標原點爲地球質心,其地心空間直角座標系的Z軸指向BIH (國際時間服務機構)1984.O定義的協議地球極(CTP)方向,X軸指向BIH 1984.0的零子午面和CTP赤道的交點,Y軸與Z軸、X軸垂直構成右手座標系。咱們日常手機上的指南針顯示的經緯度就是這個座標系下當前的座標,進度範圍[-180,180],緯度範圍[-90,90]。函數
![](http://static.javashuo.com/static/loading.gif)
Cesium目前支持兩種座標系WGS84和WebMercator,可是在Cesium中沒有實際的對象來描述WGS84座標,都是以弧度的方式來進行運用的也就是Cartographic類:工具
new Cesium.Cartographic(longitude, latitude, height),這裏的參數也叫longitude、latitude,就是經度和緯度,計算方法:弧度= π/180×經緯度角度。測試
笛卡爾空間直角座標系(Cartesian3)
笛卡爾空間座標的原點就是橢球的中心,咱們在計算機上進行繪圖時,不方便使用經緯度直接進行繪圖,通常會將座標系轉換爲笛卡爾座標系,使用計算機圖形學中的知識進行繪圖。這裏的Cartesian3,有點相似於三維繫統中的Point3D對象,new Cesium.Cartesian3(x, y, z),裏面三個份量x、y、z。spa
![](http://static.javashuo.com/static/loading.gif)
平面座標系(Cartesian2)
平面座標系也就是平面直角座標系,是一個二維笛卡爾座標系,與Cartesian3相比少了一個z的份量,new Cesium.Cartesian2(x, y)。Cartesian2常常用來描述屏幕座標系,好比鼠標在電腦屏幕上的點擊位置,返回的就是Cartesian2,返回了鼠標點擊位置的xy像素點份量。code
![](http://static.javashuo.com/static/loading.gif)
座標轉換
經緯度和弧度的轉換
var radians=Cesium.Math.toRadians(degrees);//經緯度轉弧度 var degrees=Cesium.Math.toDegrees(radians);//弧度轉經緯度
WGS84經緯度座標和WGS84弧度座標系(Cartographic)的轉換
//方法一: var longitude = Cesium.Math.toRadians(longitude1); //其中 longitude1爲角度 var latitude= Cesium.Math.toRadians(latitude1); //其中 latitude1爲角度 var cartographic = new Cesium.Cartographic(longitude, latitude, height); //方法二: var cartographic= Cesium.Cartographic.fromDegrees(longitude, latitude, height);//其中,longitude和latitude爲角度 //方法三: var cartographic= Cesium.Cartographic.fromRadians(longitude, latitude, height);//其中,longitude和latitude爲弧度
WGS84座標系和笛卡爾空間直角座標系(Cartesian3)的轉換
經過經緯度或弧度進行轉換
var position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);//其中,高度默認值爲0,能夠不用填寫;longitude和latitude爲角度 var positions = Cesium.Cartesian3.fromDegreesArray(coordinates);//其中,coordinates格式爲不帶高度的數組。例如:[-115.0, 37.0, -107.0, 33.0] var positions = Cesium.Cartesian3.fromDegreesArrayHeights(coordinates);//coordinates格式爲帶有高度的數組。例如:[-115.0, 37.0, 100000.0, -107.0, 33.0, 150000.0] //同理,經過弧度轉換,用法相同,具體有Cesium.Cartesian3.fromRadians,Cesium.Cartesian3.fromRadiansArray,Cesium.Cartesian3.fromRadiansArrayHeights等方法
注意:上述轉換函數中最後均有一個默認參數ellipsoid(默認值爲Ellipsoid.WGS84)。orm
經過過分進行轉換
具體過分原理能夠參考上邊的注意事項。
var position = Cesium.Cartographic.fromDegrees(longitude, latitude, height); var positions = Cesium.Ellipsoid.WGS84.cartographicToCartesian(position); var positions = Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray([position1,position2,position3]);
笛卡爾空間直角座標系轉換爲WGS84
直接轉換
var cartographic= Cesium.Cartographic.fromCartesian(cartesian3);
轉換獲得WGS84弧度座標系後再使用經緯度和弧度的轉換,進行轉換到目標值
間接轉換
var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian3); var cartographics = Cesium.Ellipsoid.WGS84.cartesianArrayToCartographicArray([cartesian1,cartesian2,cartesian3]);
平面座標系(Cartesian2)和笛卡爾空間直角座標系(Cartesian3)的轉換
平面座標系轉笛卡爾空間直角座標系
這裏注意的是當前的點(Cartesian2)必須在三維球上,不然返回的是undefined;經過ScreenSpaceEventHandler回調會取到的座標都是Cartesian2。
屏幕座標轉場景座標-獲取傾斜攝影或模型點擊處的座標
這裏的場景座標是包含了地形、傾斜攝影表面、模型的座標。
經過viewer.scene.pickPosition(movement.position)獲取,根據窗口座標,從場景的深度緩衝區中拾取相應的位置,返回笛卡爾座標。
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); handler.setInputAction(function (movement) { var position = viewer.scene.pickPosition(movement.position); console.log(position); }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
注:若屏幕座標處沒有傾斜攝影表面、模型時,獲取的笛卡爾座標不許,此時要開啓地形深度檢測(viewer.scene.globe.depthTestAgainstTerrain = true; //默認爲false)。
屏幕座標轉地表座標-獲取加載地形後對應的經緯度和高程
這裏是地球表面的世界座標,包含地形,不包括模型、傾斜攝影表面。
經過viewer.scene.globe.pick(ray, scene)獲取,其中ray=viewer.camera.getPickRay(movement.position)。
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); handler.setInputAction(function (movement) { var ray = viewer.camera.getPickRay(movement.position); var position = viewer.scene.globe.pick(ray, viewer.scene); console.log(position); }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
注:經過測試,此處獲得的座標經過轉換成wgs84後,height的爲該點的地形高程值。
屏幕座標轉橢球面座標-獲取鼠標點的對應橢球面位置
這裏的橢球面座標是參考橢球的WGS84座標(Ellipsoid.WGS84),不包含地形、模型、傾斜攝影表面。
經過 viewer.scene.camera.pickEllipsoid(movement.position, ellipsoid)獲取,能夠獲取當前點擊視線與橢球面相交處的座標,其中ellipsoid是當前地球使用的橢球對象:viewer.scene.globe.ellipsoid,默認爲Ellipsoid.WGS84。
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas); handler.setInputAction(function (movement) { var position = viewer.scene.camera.pickEllipsoid(movement.position, viewer.scene.globe.ellipsoid); console.log(position); }, Cesium.ScreenSpaceEventType.LEFT_CLICK);
注:經過測試,此處獲得的座標經過轉換成wgs84後,height的爲0(此值應該爲地表座標減去地形的高程)。
笛卡爾空間直角座標系轉平面座標系
var cartesian2= Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene,cartesian3)
空間位置變換
經緯度轉換到笛卡爾座標系後就能運用計算機圖形學中的仿射變換知識進行空間位置變換如平移旋轉縮放。
Cesium爲咱們提供了頗有用的變換工具類:Cesium.Cartesian3(至關於Point3D)Cesium.Matrix3(3x3矩陣,用於描述旋轉變換)Cesium.Matrix4(4x4矩陣,用於描述旋轉加平移變換),Cesium.Quaternion(四元數,用於描述圍繞某個向量旋轉必定角度的變換)。
下面舉個例子:
一個局部座標爲p1(x,y,z)的點,將它的局部座標原點放置到loc(lng,lat,alt)上,局部座標的z軸垂直於地表,局部座標的y軸指向正北,並圍繞這個z軸旋轉d度,求此時p1(x,y,z)變換成全局座標笛卡爾坐p2(x1,y1,z1)是多少?
var rotate = Cesium.Math.toRadians(d);//轉成弧度 var quat = Cesium.Quaternion.fromAxisAngle(Cesium.Cartesian3.UNIT_Z, rotate); //quat爲圍繞這個z軸旋轉d度的四元數 var rot_mat3 = Cesium.Matrix3.fromQuaternion(quat);//rot_mat3爲根據四元數求得的旋轉矩陣 var v = new Cesium.Cartesian3(x, y, z);//p1的局部座標 var m = Cesium.Matrix4.fromRotationTranslation(rot_mat3, Cesium.Cartesian3.ZERO);//m爲旋轉加平移的4x4變換矩陣,這裏平移爲(0,0,0),故填個Cesium.Cartesian3.ZERO m = Cesium.Matrix4.multiplyByTranslation(m, v);//m = m X v var cart3 = ellipsoid.cartographicToCartesian(Cesium.Cartographic.fromDegrees(lng, lat, alt)); //獲得局部座標原點的全局座標 var m1 = Cesium.Transforms.eastNorthUpToFixedFrame(cart3);//m1爲局部座標的z軸垂直於地表,局部座標的y軸指向正北的4x4變換矩陣 m = Cesium.Matrix4.multiplyTransformation(m, m1);//m = m X m1 var p2 = Cesium.Matrix4.getTranslation(m);//根據最終變換矩陣m獲得p2 console.log('x=' + p2.x + ',y=' + p2.y + ',z=' + p2.z );
總結
經過本文,介紹了各個座標系間的轉換問題,在具體項目中,可結合實際需求,靈活組合解決具體的實際問題。注意,博文是參照網上相關博客及結合本身的實踐總結得來,但願本文對你有所幫助,後續會更新更多內容,感興趣的朋友能夠加關注,歡迎留言交流!
原文出處:https://www.cnblogs.com/aizai846/p/11846929.html