cesium中坐标系变化及使用场景介绍

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);
相关推荐
中微子42 分钟前
React状态管理最佳实践
前端
烛阴1 小时前
void 0 的奥秘:解锁 JavaScript 中 undefined 的正确打开方式
前端·javascript
中微子1 小时前
JavaScript 事件与 React 合成事件完全指南:从入门到精通
前端
Hexene...1 小时前
【前端Vue】如何实现echarts图表根据父元素宽度自适应大小
前端·vue.js·echarts
天天扭码2 小时前
《很全面的前端面试题》——HTML篇
前端·面试·html
xw52 小时前
我犯了错,我于是为我的uni-app项目引入环境标志
前端·uni-app
!win !2 小时前
被老板怼后,我为uni-app项目引入环境标志
前端·小程序·uni-app
Burt2 小时前
tsdown vs tsup, 豆包回答一坨屎,还是google AI厉害
前端
群联云防护小杜3 小时前
构建分布式高防架构实现业务零中断
前端·网络·分布式·tcp/ip·安全·游戏·架构
ohMyGod_1234 小时前
React16,17,18,19新特性更新对比
前端·javascript·react.js