1.cesium中坐标系介绍
1. 笛卡尔坐标系(Cartesian):
笛卡尔坐标系是最常见的三维坐标系,用于描述物体的空间位置。在Cesium中,笛卡尔坐标系使用Cartesian3
类型表示,其中单位是米。 Cesium中的绝对坐标系为笛卡儿空间直角坐标系(Cartesian3)。笛卡儿空间直角坐标系的原点就是椭球体的中心点。由于我们在计算机上绘图时不方便参照经纬度直接进行绘制,所以通常会先将坐标系转换为笛卡儿空间直角坐标系,再进行绘制,笛卡儿空间直角坐标系的3个分量x、y、z,可以被看作以椭球体中心点为原点的空间直角坐标系中的某一个点的坐标。在Cesium中,使用Cartesian3类,通过new Cesium.Cartesian3(x,y,z)创建对象,其中的(x,y,z)代表笛卡儿空间直角坐标系中的坐标。

2. 弧度经纬度坐标系(Longitude and Latitude):
经纬度坐标系用于描述地球表面的位置。经度表示东西方向的位置,而纬度表示南北方向的位置。在Cesium中,经纬度坐标系使用Cartographic
类型表示。经度的单位是弧度,纬度的单位也是弧度。
3. 角度经纬度坐标:
我们日常说的经纬度都是角度单位,但是cesium中使用的弧度单位,所以从用户到cesium需要从角度转化到角度,反之亦然。
4 WGS84(World Geodetic System 1984)
是一种地理坐标系统,它使用度(°)作为单位,而不是弧度。 WGS84定义了地球上任意点的经度和纬度的度数值。例如,纬度的范围从-90°到+90°,经度的范围从-180°到+180°。
要将WGS84坐标转换为弧度坐标,可以使用如下公式: 弧度经度 = 经度 * (π / 180) 弧度纬度 = 纬度 * (π / 180); 由于Cesium中并没有实际的对象用来描述WGS-84坐标,所以都是以弧度的形式来运用的,也就是使用Cartographic类,通过new Cesium.Cartographic(longitude,latitude,height)创建对象,其中的longitude、latitude、height分别对应经度、纬度和高度。

5.平面坐标系:
平面坐标系就是平面直角坐标系(Cartesian2),是一个二维的笛卡儿直角坐标系,与笛卡儿空间直角坐标系(Cartesian3)相比少了一个分量z。一般来说,平面坐标系用来描述屏幕坐标系,例如,我们通过鼠标单击计算机屏幕的某一点,这一点就是屏幕坐标,可以获取该位置的x、y像素点分量, 在Cesium中,使用Cartesian2类,通过new Cesium.Cartesian2(x,y)创建对象,其中的(x,y)代表平面坐标系中的坐标。
在浏览器中的dom事件获取的坐标就是平面坐标,在cesium中,通常需要将dom事件获取的平面像素坐标转化为世界坐标。
2.不同坐标系的使用场景和转化
1)dom事件获取window二位平面像素坐标
js
var handler = new Cesium.ScreenSpaceEventHandler(viewer.scene.canvas);
handler.setInputAction(function (movement) {
//屏幕坐标
console.log('屏幕坐标:', movement.position);
}, Cesium.ScreenSpaceEventType.LEFT_CLICK);
js
{
"x": 590,
"y": 400
}
2)window二维平面像素坐标转世界坐标
js
//屏幕坐标 转 世界坐标(场景坐标,包括地形、倾斜摄影模型等的坐标)
var cartesian3= viewer.scene.pickPosition(movement.position); //注意此处的屏幕坐标一定要在球上,否则结果为undefined
console.log('屏幕坐标转世界坐标(场景):', cartesian3);
//屏幕坐标 转 世界坐标(地表坐标,包括地形但不包括模型、倾斜摄影等)
var ray = viewer.camera.getPickRay(movement.position);
var cartesian3 = viewer.scene.globe.pick(ray, viewer.scene);
console.log('屏幕坐标转世界坐标(地表):', cartesian3);
//屏幕坐标 转 世界坐标(椭球面坐标,不包括地形、模型、倾斜摄影等)
var cartesian3= viewer.scene.camera.pickEllipsoid(movement.position)
console.log('屏幕坐标转世界坐标(椭球面):', cartesian3);

3.世界坐标转二维平面像素坐标转世界坐标
js
//世界坐标 转 屏幕坐标,wgs84ToWindowCoordinates输入的是一个世界坐标,而不是上边介绍的wgs84度坐标。
var cartesian2 = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, cartesian3)
console.log('世界坐标转屏幕坐标:',cartesian3, cartesian2);
//世界坐标 转 WGS84坐标,结果为弧度形式
var cartographic = Cesium.Cartographic.fromCartesian(cartesian3);
console.log('世界坐标转WGS84弧度坐标:', cartographic);

4.弧度,度,世界坐标转化
js
//WGS84弧度坐标 转 经纬度坐标
longitude = Cesium.Math.toDegrees(cartographic.longitude);
latitude = Cesium.Math.toDegrees(cartographic.latitude);
height = cartographic.height;
console.log('WGS84弧度坐标转WGS84经纬度坐标:' + longitude + ',' + latitude + ',' + height);
//WGS84经纬度坐标 转 弧度坐标
var radians = Cesium.Cartographic.fromDegrees(longitude, latitude, height);
console.log('WGS84经纬度转WGS84弧度坐标', radians);
//WGS84经纬度坐标 转 世界坐标
var position = Cesium.Cartesian3.fromDegrees(longitude, latitude, height);
console.log('WGS84经纬度转世界坐标', position);
//WGS84弧度坐标 转 世界坐标
var position2 = Cesium.Cartesian3.fromRadians(cartographic.longitude, cartographic.latitude, cartographic.height);
console.log('WGS84弧度转世界坐标', position2);

5.在绘制点,线,面,模型等entity的时候,使用世界坐标系
那么用户输入一般是将直观的经纬度(度)转世界坐标(米)
js
// 线
var addLine = viewer.entities.add({
id: 'line',
name: '线',
show: true, //显示
polyline: {
positions: Cesium.Cartesian3.fromDegreesArray([111, 40, 116, 45]),
width: 6, //线条粗细
followSurface: false, //取消弯曲
material: Cesium.Color.RED, //线条材质
},
})
6.在要对模型进行高度变化的时候,最好使用幅度单位
其中的height单位是米,高度变化使用米作为单位比较直观,但是在做矩阵变化的时候,需要转化为世界坐标。 存在过程:获得当前的笛卡尔世界坐标点----经纬度弧度------两个高度不同的经纬度弧度坐标-----笛卡尔分量的差异-----笛卡尔世界坐标变化矩阵
js
//将3D Tiles外包围球中心点从笛卡尔空间直角坐标转换为弧度表示
const cartographic = Cesium.Cartographic.fromCartesian(
tileset.boundingSphere.center //3D Tiles外包围球中心
);
//3D Tiles外包围球中心点原始坐标
const surface = Cesium.Cartesian3.fromRadians(
cartographic.longitude,
cartographic.latitude
);
//3D Tiles外包围球中心点坐标偏移
const offset = Cesium.Cartesian3.fromRadians(
cartographic.longitude,
cartographic.latitude,
height
);
console.log("offset世界", offset, "cartographic幅度", cartographic);
//计算两个笛卡尔分量的差异
const translation = Cesium.Cartesian3.subtract(
offset,
surface,
new Cesium.Cartesian3()
);
//创建一个表示转换的Matrix4
tileset.modelMatrix = Cesium.Matrix4.fromTranslation(translation);