在我們開始學習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 (國際時間服務機構)1984.O定義的協(xié)議地球極(CTP)方向戈钢,X軸指向BIH 1984.0的零子午面和CTP赤道的交點,Y軸與Z軸陋桂、X軸垂直構成右手坐標系逆趣。我們平常手機上的指南針顯示的經(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)緯度角度每窖。
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;
});