Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

地理坐标中的 经纬度 / 弧度 / 世界坐标 / 屏幕坐标转换 #35

Open
ronghaoZHI opened this issue Feb 18, 2020 · 0 comments

Comments

@ronghaoZHI
Copy link
Owner

ronghaoZHI commented Feb 18, 2020

首先介绍一下相关涉及到的 相关坐标系统

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];
    }
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant