SuperMap iClient3D for WebGL教程(Entity)-Cesium中的坐標系及轉(zhuǎn)換

在我們開始學習Entity之前,我們首先需要先學習下Cesium中的坐標系,Cesium中有多個坐標系,在進行添加Entity時經(jīng)常會使用到。

一、坐標系介紹

我們先來列舉下Cesium中的坐標系:WGS84經(jīng)緯度坐標系(沒有實際的對象)、WGS84弧度坐標系(Cartographic)、笛卡爾空間直角坐標系(Cartesian3)、平面坐標系(Cartesian2),4D笛卡爾坐標系(Cartesian4)

1、WGS84坐標系

World Geodetic System 1984,是為GPS全球定位系統(tǒng)使用而建立的坐標系統(tǒng),坐標原點為地球質(zhì)心,其地心空間直角坐標系的Z軸指向BIH (國際時間服務(wù)機構(gòu))1984.O定義的協(xié)議地球極(CTP)方向,X軸指向BIH 1984.0的零子午面和CTP赤道的交點,Y軸與Z軸、X軸垂直構(gòu)成右手坐標系。我們平常手機上的指南針顯示的經(jīng)緯度就是這個坐標系下當前的坐標,進度范圍[-180,180],緯度范圍[-90,90]。
我們都知道Cesium目前支持兩種坐標系WGS84和WebMercator,但是在Cesium中沒有實際的對象來描述WGS84坐標,都是以弧度的方式來進行運用的也就是Cartographic類:new Cesium.Cartographic(longitude, latitude, height),這里的參數(shù)也叫l(wèi)ongitude、latitude,就是經(jīng)度和緯度,計算方法:弧度= π/180×經(jīng)緯度角度。


WGS84坐標系

2、笛卡爾空間直角坐標系(Cartesian3)

笛卡爾空間坐標的原點就是橢球的中心,我們在計算機上進行繪圖時,不方便使用經(jīng)緯度直接進行繪圖,一般會將坐標系轉(zhuǎn)換為笛卡爾坐標系,使用計算機圖形學中的知識進行繪圖。這里的Cartesian3,有點類似于SuperMap iObejcts中的Point3D對象,new Cesium.Cartesian3(x, y, z),里面三個分量xyz。

笛卡爾空間直角坐標系

3、平面坐標系(Cartesian2)

平面坐標系也就是平面直角坐標系,是一個二維笛卡爾坐標系,與Cartesian3相比少了一個z的分量,new Cesium.Cartesian2(x, y)。Cartesian2經(jīng)常用來描述屏幕坐標系,比如鼠標在電腦屏幕上的點擊位置,返回的就是Cartesian2,返回了鼠標點擊位置的xy像素點分量。


平面坐標系

4、4D笛卡爾坐標系(Cartesian4)

到目前來說,還沒有用過,等后續(xù)有用到的時候再更新吧

二、幾種坐標系的使用及轉(zhuǎn)換方法

經(jīng)緯度和弧度的轉(zhuǎn)換

經(jīng)緯度轉(zhuǎn)弧度:var radians=Cesium.CesiumMath.toRadians(degrees);
弧度轉(zhuǎn)經(jīng)緯度:var degrees=Cesium.CesiumMath.toDegrees(radians);
我們來看下Cesium中源碼的轉(zhuǎn)換方法,其實就是:弧度= π/180×經(jīng)緯度角度;經(jīng)緯度角度=180/π×弧度。

CesiumMath.RADIANS_PER_DEGREE = Math.PI / 180.0;
CesiumMath.DEGREES_PER_RADIAN = 180.0 / Math.PI;
CesiumMath.toRadians = function(degrees) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(degrees)) {
            throw new DeveloperError('degrees is required.');
        }
        //>>includeEnd('debug');
        return degrees * CesiumMath.RADIANS_PER_DEGREE;
    };
CesiumMath.toDegrees = function(radians) {
        //>>includeStart('debug', pragmas.debug);
        if (!defined(radians)) {
            throw new DeveloperError('radians is required.');
        }
        //>>includeEnd('debug');
        return radians * CesiumMath.DEGREES_PER_RADIAN;
    };

WGS84經(jīng)緯度坐標和WGS84弧度坐標系(Cartographic)的轉(zhuǎn)換

1.直接轉(zhuǎn)換:通過上面提到的方法,將經(jīng)緯度轉(zhuǎn)換為弧度后,直接new Cesium.Cartographic(longitude弧度, latitude弧度, height米)
2.間接轉(zhuǎn)換:通過var cartographic= Cesium.Cartographic.fromDegrees(longitude, latitude, height)直接轉(zhuǎn)換;
類似的還有var cartographic= Cesium.Cartographic.fromRadians(longitude, latitude, height)方法,傳入的是弧度。

WGS84坐標系和笛卡爾空間直角坐標系(Cartesian3)的轉(zhuǎn)換

WGS84轉(zhuǎn)為笛卡爾空間直角坐標系
1.通過經(jīng)緯度或弧度進行轉(zhuǎn)換:
var c3= Cesium.Cartesian3.fromDegrees(longitude, latitude, height) ;高度height可不填寫。
var c3s=Cesium.Cartesian3.fromDegreesArray(coordinates);coordinates格式為不帶高度的數(shù)組。例如:[-115.0, 37.0, -107.0, 33.0]
var c3s=Cesium.Cartesian3.fromDegreesArrayHeights(coordinates);coordinates格式為帶有高度的數(shù)組。例如:[-115.0, 37.0, 100000.0, -107.0, 33.0, 150000.0]
同理將度轉(zhuǎn)化為弧度,然后再進行轉(zhuǎn)換,
和上面一樣有Cesium.Cartesian3.fromRadians,Cesium.Cartesian3.fromRadiansArray,Cesium.Cartesian3.fromRadiansArrayHeights等方法,用法和上面一樣,只是度需要轉(zhuǎn)換為弧度,這里不再講這些方法。

其實fromDegrees內(nèi)部也是用的fromRadians方法,這點大家可以了解下,另外WGS84坐標系轉(zhuǎn)笛卡爾空間直角坐標系代碼如下,大家可以了解下轉(zhuǎn)換過程:

Cartesian3.fromRadians = function(longitude, latitude, height, ellipsoid, result) {
        //>>includeStart('debug', pragmas.debug);
        Check.typeOf.number('longitude', longitude);
        Check.typeOf.number('latitude', latitude);
        //>>includeEnd('debug');

        height = defaultValue(height, 0.0);
        var radiiSquared = defined(ellipsoid) ? ellipsoid.radiiSquared : wgs84RadiiSquared;

        var cosLatitude = Math.cos(latitude);
        scratchN.x = cosLatitude * Math.cos(longitude);
        scratchN.y = cosLatitude * Math.sin(longitude);
        scratchN.z = Math.sin(latitude);
        scratchN = Cartesian3.normalize(scratchN, scratchN);

        Cartesian3.multiplyComponents(radiiSquared, scratchN, scratchK);
        var gamma = Math.sqrt(Cartesian3.dot(scratchN, scratchK));
        scratchK = Cartesian3.divideByScalar(scratchK, gamma, scratchK);
        scratchN = Cartesian3.multiplyByScalar(scratchN, height, scratchN);

        if (!defined(result)) {
            result = new Cartesian3();
        }
        return Cartesian3.add(scratchK, scratchN, result);
    };

2.通過度來進行轉(zhuǎn)換
var position = Cesium.Cartographic.fromDegrees(longitude, latitude, height);
var c3 = Cesium.Ellipsoid.WGS84.cartographicToCartesian(position);
var c3s=Cesium.Ellipsoid.WGS84.cartographicArrayToCartesianArray([position1,position2,position3])
弧度同理
笛卡爾空間直角坐標系轉(zhuǎn)換為WGS84
1.直接轉(zhuǎn)換
var cartographic= Cesium.Cartographic.fromCartesian(cartesian3)
轉(zhuǎn)換得到WGS84弧度坐標系后再使用經(jīng)緯度和弧度的轉(zhuǎn)換,進行轉(zhuǎn)換到目標值
2、間接轉(zhuǎn)換
var cartographic= Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian3)
var cartographics= Cesium.Ellipsoid.WGS84.cartesianArrayToCartographicArray([cartesian1,cartesian2,cartesian3])

平面坐標系(Cartesian2)和笛卡爾空間直角坐標系(Cartesian3)的轉(zhuǎn)換

平面坐標系轉(zhuǎn)笛卡爾空間直角坐標系
這里需要說明的是當前的點必須在三維球上,否則返回的是undefined,我們在ScreenSpaceEventHandler回調(diào)會取到的坐標都是Cartesian2,大家可以測試觀察下。
1.屏幕坐標轉(zhuǎn)場景WGS84坐標,這里的場景坐標是包含了地形、傾斜、模型的坐標。
轉(zhuǎn)換方法為:var cartesian3= viewer.scene.pickPosition(Cartesian2),目前IE瀏覽器不支持深度拾取,所以用不了這個方法。
2.屏幕坐標轉(zhuǎn)地表坐標,這里是地球表面的WGS84坐標,包含地形,不包括模型、傾斜攝影表面。
轉(zhuǎn)換方法為:var cartesian3= viewer.scene.globe.pick(viewer.camera.getPickRay(Cartesian2),viewer.scene);
3.屏幕坐標轉(zhuǎn)橢球面坐標,這里的橢球面坐標是參考橢球的WGS84坐標,不包含地形、模型、傾斜攝影表面。
轉(zhuǎn)換方法為:var cartesian3= viewer.scene.camera.pickEllipsoid(Cartesian2)
笛卡爾空間直角坐標系轉(zhuǎn)平面坐標系
var cartesian2= Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene,cartesian3)
4、使用sampleTerrain進行轉(zhuǎn)換

var positions = [Cesium.Cartographic.fromDegrees(115.879223859066, 40.6326683199771)];
var promise = Cesium.sampleTerrain(viewer.terrainProvider, 8, positions);
Cesium.when(promise, function(updatedPositions) {
    var height = updatedPositions[0].height;
});
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容