232 lines
8.2 KiB
Markdown
232 lines
8.2 KiB
Markdown
|
---
|
|||
|
title: 坐标系统
|
|||
|
author: ac
|
|||
|
date: 2022-01-22
|
|||
|
tags:
|
|||
|
- CesiumJS
|
|||
|
- 坐标系
|
|||
|
categories:
|
|||
|
- GIS
|
|||
|
---
|
|||
|
|
|||
|
## Cesium 坐标系
|
|||
|
|
|||
|
`Cesium` 具有真实地理坐标的三维球体,用户通过二维屏幕与 `Cesium` 进行操作,如果要将三维模型绘制到球体上,需要在地理坐标和屏幕坐标之间进行换算。 `Cesium` 中有以下五种坐标系:
|
|||
|
|
|||
|
- WGS84 经纬度坐标系(没有实际的对象)
|
|||
|
- WGS84 弧度坐标系(Cartographic)
|
|||
|
- 笛卡尔空间直角坐标系(Cartesian3)
|
|||
|
- 屏幕坐标系(Cartesian2)
|
|||
|
- 4D 笛卡尔坐标系(Cartesian4)
|
|||
|
|
|||
|
---
|
|||
|
|
|||
|
### 1. WGS84 经纬度坐标系
|
|||
|
|
|||
|
> 参考椭球体:将地球抽象城一个规则逼近原始自然地球表面的球体,成为参考椭球体。
|
|||
|
|
|||
|
在大地测量中,通过以参考椭球面为基准面,再确定其大小,给其定位和定向就可以建立一个大地坐标系。大地坐标系是一种伪地理坐标系。
|
|||
|
|
|||
|

|
|||
|
|
|||
|
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 src="./images/dadi.jpeg" alt="img" style="zoom: 25%;" />
|
|||
|
|
|||
|
大地坐标系中点的位置,通过大地经度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 src="./images/img20.jpeg" alt="img" style="zoom:33%;" />
|
|||
|
|
|||
|
`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. 屏幕坐标系
|
|||
|
|
|||
|

|
|||
|
|
|||
|
屏幕坐标系也叫平面直角坐标系,它是一个二维的笛卡尔坐标系。 `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
|
|||
|
|