地理坐标中的 经纬度 / 弧度 / 世界坐标 / 屏幕坐标转换
Opened this issue · 0 comments
ronghaoZHI commented
首先介绍一下相关涉及到的 相关坐标系统
1、平面坐标系(Cartesian2)
cartesian2 = { x: x || 0.0, y: y || 0.0}
/*
* cesium 中表示 , A 2D Cartesian point
*/
new Cesium.Cartesian2(x, y)
2、笛卡尔空间直角坐标系 - 世界坐标(Cartesian3)
cartesian3 = { x: x || 0.0, y: y || 0.0, z: z || 0.0 }
/*
* cesium 中表示 , A 3D Cartesian point.
*/
new Cesium.Cartesian3(x, y, z)
3、地理坐标系 / 经纬度 [longitude,latitude] / 弧度 Cartographic
地理坐标系,坐标原点在椭球的质心。
经度:参考椭球面上某点的大地子午面与本初子午面间的两面角。东正西负。
纬度:参考椭球面上某点的法线与赤道平面的夹角。北正南负。
cartographic = { longitude: longitude || 0.0, latitude: latitude || 0.0, height: height || 0.0 }
/*
* cesium 中表示 , A position defined by longitude, latitude, and height.
* 注:这里的经纬度是用弧度表示的,经纬度其实就是角度。弧度即角度对应弧长是半径的倍数。
*/
new Cesium.Cartographic(longitude, latitude, height)
/*
* 经纬度转弧度:
*/
Cesium.CesiumMath.toRadians(degrees)
// 等同于 (degrees) => degrees * Math.PI / 180
/*
* 弧度转经纬度:
*/
Cesium.CesiumMath.toDegrees(radians)
// 等同于 (radians) => radians * 180 / Math.PI
注:认识与理解 世界坐标(Cartesian3)与 地理坐标(cartographic)与 经纬度 / 弧度 是往下面看的必备基础。
常用的坐标转换
1、 经纬度 转 世界坐标
/*
* cesium 中转换公式
* ellipsoid:
* A quadratic surface defined in Cartesian coordinates by the equation
* <code>(x / a)^2 + (y / b)^2 + (z / c)^2 = 1</code>. Primarily used
* by Cesium to represent the shape of planetary bodies.
* Cartographic:
* A position defined by longitude, latitude, and height.
*/
var ellipsoid = viewer.scene.globe.ellipsoid;
var cartographic = Cesium.Cartographic.fromDegrees(lng, lat, alt);
var cartesian3 = ellipsoid.cartographicToCartesian(cartographic);
2、世界坐标 转 经纬度
/*
* cesium 中转换公式
* @param { cartesian3(x, y, z) }
* @retrun { latitude, longitude }
*/
var ellipsoid = viewer.scene.globe.ellipsoid;
var cartesian3 = new Cesium.cartesian3(x, y, z);
var cartographic = ellipsoid.cartesianToCartographic(cartesian3);
var latitude = Cesium.Math.toDegrees(cartograhphic.latitude);
var longitude = Cesium.Math.toDegrees(cartograhpinc.longitude);
3、屏幕坐标 转 世界坐标
/*
* cesium 中转换公式
* @param { event }
* @return [lng, lat]
*/
// event 鼠标事件
var { clientX, clientY } = event
var cartesian = window.viewer.scene.pickGlobe({
x: clientX,
y: clientY
})
if(cartesian) {
var { longitude, latitude, height } = Cesium.Cartographic.fromCartesian(cartesian)
var lng = Cesium.Math.toDegrees(longitude)
var lat = Cesium.Math.toDegrees(latitude)
return [lng, lat]
}
4、世界坐标 转 屏幕坐标
/*
* cesium 中转换公式
*/
Cesium.SceneTransforms.wgs84ToWindowCoordinates(scene, Cartesian3);
---
### 其他方法
1、 已知经纬度 获取 地表高度 (需要异步执行 ,待地形加载完成)
```js
/*
* cesium 中转换公式
*/
var ellipsoid = viewer.scene.globe.ellipsoid;
var cartographic = Cesium.Cartographic.fromDegrees(lng, lat, alt);
var cartesian3 = ellipsoid.cartographicToCartesian(cartographic);
var cartographic = Cesium.Ellipsoid.WGS84.cartesianToCartographic(cartesian3);
// 经纬度
var [ longitude, latitude ] = [ cartographic.longitude, cartographic.latitude ];
// 地表高度 / 视点高度
var height = Cesium.Cartographic.fromCartesian(viewer.scene.clampToHeight(cartesian3)).height;
// 中心点距离
const distance = Cesium.Cartesian3.distance(result, viewer.scene.camera.position);
var sinAngle = Math.sin(Math.abs(viewer.scene.camera.pitch));
distance = distance /sinAngle;
2、屏幕中心点 转 世界坐标
/*
* cesium 中转换公式
*/
var screenCenter = new Cesium.Cartesian2(viewer.canvas.clientWidth / 2, viewer.canvas.clientHeight / 2);
var cartesian3 = viewer.camera.pickEllipsoid(screenCenter);
2、 经纬度 转换成 度分秒表示法
/*
* @param { longitude }
* @return string
*/
function (longitude) {
var label;
var _long = formatRad(longitude);
longitude > 0 ? (label = 'E') : (label = 'W');
return `${label}${_long[0]}°${_long[1]}'${_long[2]}"`;
function formatRad(v) {
const v0 = Math.abs(+v)
const v1 = Math.floor(v0) //度
const v2 = Math.floor((v0 - v1) * 60) //分
const v3 = Math.round((v0 - v1) * 3600 % 60) //秒
return [v1, v2, v3];
}
}