--- title: 坐标系统 author: ac date: 2022-01-22 tags: - CesiumJS - 坐标系 categories: - GIS --- ## Cesium 坐标系 `Cesium` 具有真实地理坐标的三维球体,用户通过二维屏幕与 `Cesium` 进行操作,如果要将三维模型绘制到球体上,需要在地理坐标和屏幕坐标之间进行换算。 `Cesium` 中有以下五种坐标系: - WGS84 经纬度坐标系(没有实际的对象) - WGS84 弧度坐标系(Cartographic) - 笛卡尔空间直角坐标系(Cartesian3) - 屏幕坐标系(Cartesian2) - 4D 笛卡尔坐标系(Cartesian4) --- ### 1. WGS84 经纬度坐标系 > 参考椭球体:将地球抽象城一个规则逼近原始自然地球表面的球体,成为参考椭球体。 在大地测量中,通过以参考椭球面为基准面,再确定其大小,给其定位和定向就可以建立一个大地坐标系。大地坐标系是一种伪地理坐标系。 ![img](./images/img1.jpeg) WGS-84坐标系(World Geodetic System一1984 Coordinate System)是一种国际上采用的[地心坐标系](https://baike.baidu.com/item/地心坐标系/5155013)。坐标原点为[地球质心](https://baike.baidu.com/item/地球质心/7013007),其地心[空间直角坐标系](https://baike.baidu.com/item/空间直角坐标系/10743618)的Z轴指向BIH (国际时间服务机构)1984.0定义的协议地球极(CTP)方向,X轴指向BIH 1984.0的零[子午面](https://baike.baidu.com/item/子午面/9688202)和CTP赤道的交点,Y轴与Z轴、X轴垂直构成[右手坐标系](https://baike.baidu.com/item/右手坐标系/2562697),称为1984年世界[大地坐标系统](https://baike.baidu.com/item/大地坐标系统/6131526)。 > GPS[广播星历](https://baike.baidu.com/item/广播星历/1365627)是以WGS-84坐标系为根据的。 **基于椭球体表示空间点的位置** img 大地坐标系中点的位置,通过大地经度L、大地纬度B和[大地高](https://baike.baidu.com/item/大地高)H这3个坐标分量表示。 在 `Cesium` 中没有实际的对象来描述 WGS84 经纬度坐标系的,都是以弧度的方式来进行运用的。 ### 2. WGS84 弧度坐标系 > 因为度不是标准的长度单位,不可以直接测量长度和面积。方便计算, Cesium都是以弧度来描述点位坐标的。 `Cartographic` 类就是 `Cesium` 用来表示 `WGS84` 点位的。 ```javascript new Cesium.Cartographic(longitude, latitude, height) ``` | Name | Type | Default | Description | | :---------- | :----- | :------ | :--------------------------------------------------- | | `longitude` | Number | `0.0` | optional The longitude, in radians. | | `latitude` | Number | `0.0` | optional The latitude, in radians. | | `height` | Number | `0.0` | optional The height, in meters, above the ellipsoid. | 例如:一个经纬度为[21,78],大地高为5000的点。 ```javascript const position = new Cesium.Cartographic( Cesium.Math.toRadians(21), Cesium.Math.toRadians(78), 5000 ); ``` ### 3. 笛卡尔空间直角坐标系 img `Cesium` 中笛卡尔空间直角坐标系的原点就是椭球的中心,以 `Cartesian3` 类来表示笛卡尔空间中的点位。 ```javascript new Cesium.Cartesian3(x, y, z) ``` | Name | Type | Default | Description | | :--- | :----- | :------ | :------------------------ | | `x` | Number | `0.0` | optional The X component. | | `y` | Number | `0.0` | optional The Y component. | | `z` | Number | `0.0` | optional The Z component. | ### 4. 屏幕坐标系 ![img](./images/2026842-af2319653d68d64e.png) 屏幕坐标系也叫平面直角坐标系,它是一个二维的笛卡尔坐标系。 `Cesium` 中使用 `Cartesian2`类来表示其点位,构造函数为: ```javascript new Cesium.Cartesian2(x, y) ``` `Cartesian2` 的实例表示鼠标点击位置距离**canvas左上角**的像素值。 ### 5. 坐标之间的转换 **经纬度和弧度的相互转换** 1. 通过 Math 类中的函数进行转换 ```javascript // 经纬度转弧度 var radians = Cesium.Math.toRadians(degree) // 弧度转经纬度 var degree = Cesium.Math.toDegrees(radians) ``` 2. 直接计算 弧度 = Math.PI/180 * 经纬度 经纬度 = 180/Math.PI * 弧度 **WGS84坐标和笛卡尔空间直角坐标系的转换** 1. 构造函数法 ```javascript // --------------WGS84弧度 转 笛卡尔空间坐标-------- // Cesium.Cartesian3.fromDegrees(longitude, latitude, ?height, ?ellipsoid, ?result) // height为大地高 const position = Cesium.Cartesian3.fromDegrees(-115.0, 37.0); // Cesium.Cartesian3.fromDegreesArray(coordinates, ?ellipsoid, ?result) // coordinates 格式为不带大地高的数组:[112.11 ,22.71 ,12.21 ,22.9] const positions = Cesium.Cartesian3.fromDegreesArray([-115.0, 37.0, -107.0, 33.0]); // Cesium.Cartesian3.fromDegreesArrayHeights(coordinates, ?ellipsoid, ?result) // coordinates 格式为带大地高的数组 const positions = Cesium.Cartesian3.fromDegreesArrayHeights([-115.0, 37.0, 100000.0, -107.0, 33.0, 150000.0]); // --------------笛卡尔空间坐标 转 WGS84弧度-------- //Cesium.Cartographic.fromCartesian(cartesian, ?ellipsoid, ?result) → Cartographic ``` 2. 通过椭球体进行转换 根据椭球体参数将WGS84经纬度坐标或其他地理坐标转为笛卡尔空间直角坐标。 ```javascript const ellipsoid84 = Cesium.Ellipsoid.wgs84 //笛卡尔空间坐标转WGS84弧度. const position = new Cesium.Cartesian3(17832.12, 83234.52, 952313.73); const cartographicPosition = ellipsoid84.cartesianToCartographic(position); // WGS84 转 笛卡尔空间坐标 const position = new Cesium.Cartographic(Cesium.Math.toRadians(21), Cesium.Math.toRadians(78), 5000); const cartesianPosition = ellipsoid84.cartographicToCartesian(position); ``` **屏幕坐标和笛卡尔空间直角坐标的转换** > 屏幕坐标与笛卡尔空间直角坐标常用与三维场景开发中。 屏幕坐标转笛卡尔坐标 cesium根据不同的场景设定了三类屏幕坐标转笛卡尔坐标: 1. 屏幕坐标转**场景**空间直角坐标。包含地形、倾斜摄影测量模型等三维模型坐标。 ```javascript // cartesian2 ==> cartesian3 let cartesian3 = viewer.scene.pickPosition(cartesian2) ``` 2. 屏幕坐标转**地表**笛卡尔空间坐标。包含地形,不包含三维模型。 ```javascript let cartesian3 = viewer.scene.globe.pick(viewer.camera.getPickRay(cartesian2),viewer.scene) ``` 3. 屏幕坐标转**椭球面**笛卡尔空间坐标。不包含地形和三维模型。 ```javascript let cartesian3 = viewer.scene.camera.pickEllipsoid(cartesian2) ``` 笛卡尔坐标转屏幕坐标 ```javascript Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, position, ?result) → Cartesian2 ``` 常用的点击事件中还有: - `viewer.scene.drillPick(cartesian2)`:根据屏幕坐标返回,该位置的所有primitive实例的集合。 - `viewer.scene.pick(cartesian2)`:返回最上面的primitive > 点击事件的事件源中`position`属性是屏幕坐标`cartesian2`。 ```javascript // On mouse over, color the feature yellow. handler.setInputAction(function(evt) { //Returns a list of objects, each containing a `primitive` property, for all primitives at a particular window coordinate position. var picks = viewer.scene.drillPick(evt.position); //Returns an object with a `primitive` property that contains the first (top) primitive in the scene at a particular window coordinate or undefined if nothing is at the location. const feature = scene.pick(evt.endPosition); if (feature instanceof Cesium.Cesium3DTileFeature) { feature.color = Cesium.Color.YELLOW; } }, Cesium.ScreenSpaceEventType.MOUSE_MOVE); ``` ## 参考文章 [1] cesium-坐标系统 https://jackie-sun.blog.csdn.net/article/details/122769126 [2] WGS-84坐标系 https://baike.baidu.com/item/WGS-84%E5%9D%90%E6%A0%87%E7%B3%BB/730443 [3] Cesium的坐标与转换 https://www.bilibili.com/video/BV16R4y1M7xc?p=6