SuperMap-WebGL-坐標系及轉換說明


轉載自:https://blog.csdn.net/supermapsupport/article/details/89519310

 

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

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

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

4、4D笛卡爾坐標系(Cartesian4)
到目前來說,還沒有用過,等后續有用到的時候再更新吧
二、幾種坐標系的使用及轉換方法
經緯度和弧度的轉換
**經緯度轉弧度:**var radians=Cesium.CesiumMath.toRadians(degrees);
**弧度轉經緯度:**var degrees=Cesium.CesiumMath.toDegrees(radians);
我們來看下Cesium中源碼的轉換方法,其實就是:弧度= π/180×經緯度角度;經緯度角度=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經緯度坐標和WGS84弧度坐標系(Cartographic)的轉換
**1.直接轉換:**通過上面提到的方法,將經緯度轉換為弧度后,直接new Cesium.Cartographic(longitude弧度, latitude弧度, height米)
**2.間接轉換:**通過var cartographic= Cesium.Cartographic.fromDegrees(longitude, latitude, height)直接轉換;
類似的還有var cartographic= Cesium.Cartographic.fromRadians(longitude, latitude, height)方法,傳入的是弧度。
WGS84坐標系和笛卡爾空間直角坐標系(Cartesian3)的轉換
WGS84轉為笛卡爾空間直角坐標系
1.通過經緯度或弧度進行轉換:
var c3= Cesium.Cartesian3.fromDegrees(longitude, latitude, height) ;高度height可不填寫。
var c3s=Cesium.Cartesian3.fromDegreesArray(coordinates);coordinates格式為不帶高度的數組。例如:[-115.0, 37.0, -107.0, 33.0]
var c3s=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等方法,用法和上面一樣,只是度需要轉換為弧度,這里不再講這些方法。

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

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

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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM